Rendered from the shared Frontfriend stories with React Base, the same
preview Studio shows. Styling comes from your Design System; the code below
is native to Reka UI.
Installation
Complete project setup first. Your configuration
must select vue/reka and include your Design System ID.
pnpm exec frontfriend download item -f vue --primitive reka
Review dependencies reported by the downloader and keep your source
changes in version control.
Usage
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import { ItemActions } from "@/components/ui/item";
import { Button } from "@/components/ui/button";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
"variant": "outline",
"size": "default",
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown> & {
variant?: "default" | "outline" | "muted";
size?: "default" | "sm";
};
</script>
<template>
<div class="w-[28rem] max-w-full">
<Item v-bind="args"
><ItemContent
><ItemTitle>Basic Item</ItemTitle
><ItemDescription
>A simple item with title and description.</ItemDescription
></ItemContent
><ItemActions
><Button variant="outline" size="sm">Action</Button></ItemActions
></Item
>
</div>
</template>
Examples
Default
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import { ItemActions } from "@/components/ui/item";
import { Button } from "@/components/ui/button";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
"variant": undefined,
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<div class="w-[28rem] max-w-full">
<Item v-bind="args" :variant="args.variant ?? 'outline'"
><ItemContent
><ItemTitle>Basic Item</ItemTitle
><ItemDescription
>A simple item with title and description.</ItemDescription
></ItemContent
><ItemActions
><Button variant="outline" size="sm">Action</Button></ItemActions
></Item
>
</div>
</template>
Variant
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemMedia } from "@/components/ui/item";
import { InboxIcon } from "lucide-vue-next";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<div class="flex w-[28rem] max-w-full flex-col gap-6">
<Item
><ItemMedia variant="icon"><InboxIcon /></ItemMedia
><ItemContent
><ItemTitle>Default Variant</ItemTitle
><ItemDescription
>Transparent background with no border.</ItemDescription
></ItemContent
></Item
><Item variant="outline"
><ItemMedia variant="icon"><InboxIcon /></ItemMedia
><ItemContent
><ItemTitle>Outline Variant</ItemTitle
><ItemDescription
>Outlined style with a visible border.</ItemDescription
></ItemContent
></Item
><Item variant="muted"
><ItemMedia variant="icon"><InboxIcon /></ItemMedia
><ItemContent
><ItemTitle>Muted Variant</ItemTitle
><ItemDescription
>Muted background for secondary content.</ItemDescription
></ItemContent
></Item
>
</div>
</template>
Size
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<div class="flex w-[28rem] max-w-full flex-col gap-6">
<Item variant="outline"
><ItemContent
><ItemTitle>Default Size</ItemTitle
><ItemDescription
>Comfortable padding and spacing.</ItemDescription
></ItemContent
></Item
><Item variant="outline" size="sm"
><ItemContent
><ItemTitle>Small Size</ItemTitle
><ItemDescription
>Compact padding and spacing.</ItemDescription
></ItemContent
></Item
>
</div>
</template>
Icon
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemMedia } from "@/components/ui/item";
import { ShieldAlertIcon } from "lucide-vue-next";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import { ItemActions } from "@/components/ui/item";
import { Button } from "@/components/ui/button";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<div class="w-[32rem] max-w-full">
<Item variant="outline"
><ItemMedia variant="icon"><ShieldAlertIcon /></ItemMedia
><ItemContent
><ItemTitle>Security Alert</ItemTitle
><ItemDescription
>New login detected from unknown device.</ItemDescription
></ItemContent
><ItemActions
><Button size="sm" variant="outline">Review</Button></ItemActions
></Item
>
</div>
</template>
Group
<script setup lang="ts">
import { ItemGroup } from "@/components/ui/item";
import { Item } from "@/components/ui/item";
import { ItemMedia } from "@/components/ui/item";
import { Avatar } from "@/components/ui/avatar";
import { AvatarImage } from "@/components/ui/avatar";
import { AvatarFallback } from "@/components/ui/avatar";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import { ItemActions } from "@/components/ui/item";
import { Button } from "@/components/ui/button";
import { PlusIcon } from "lucide-vue-next";
import { ItemSeparator } from "@/components/ui/item";
import * as UI from "@/components/ui/item";
const people = [
{
username: "shadcn",
avatar: "https://github.com/shadcn.png",
email: "shadcn@vercel.com",
},
{
username: "maxleiter",
avatar: "https://github.com/maxleiter.png",
email: "maxleiter@vercel.com",
},
{
username: "evilrabbit",
avatar: "https://github.com/evilrabbit.png",
email: "evilrabbit@vercel.com",
},
];
const Component = UI.Item;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<ItemGroup class="w-sm max-w-full"
><template v-for="(person, index) in people" :key="person.username"
><Item variant="outline"
><ItemMedia
><Avatar
><AvatarImage
:src="person.avatar"
class="grayscale" /><AvatarFallback
:name="person.username" /></Avatar></ItemMedia
><ItemContent class="gap-1"
><ItemTitle>{{ person.username }}</ItemTitle
><ItemDescription>{{ person.email }}</ItemDescription></ItemContent
><ItemActions
><Button variant="ghost" size="icon" class="rounded-full"
><PlusIcon /></Button></ItemActions></Item
><ItemSeparator v-if="index < people.length - 1" /></template
></ItemGroup>
</template>
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemHeader } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { Button } from "@/components/ui/button";
import { ItemContent } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<div class="w-[28rem] max-w-full">
<Item variant="outline"
><ItemHeader
><ItemTitle>Notifications</ItemTitle
><Button variant="ghost" size="sm">Mark all read</Button></ItemHeader
><ItemContent
><ItemDescription
>You have 3 unread messages in your inbox.</ItemDescription
></ItemContent
></Item
>
</div>
</template>
Link
<script setup lang="ts">
import { Item } from "@/components/ui/item";
import { ItemContent } from "@/components/ui/item";
import { ItemTitle } from "@/components/ui/item";
import { ItemDescription } from "@/components/ui/item";
import { ItemActions } from "@/components/ui/item";
import { ChevronRightIcon } from "lucide-vue-next";
import { ExternalLinkIcon } from "lucide-vue-next";
import * as UI from "@/components/ui/item";
const Component = UI.Item;
const args = {
} satisfies Partial<
InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
Record<string, unknown>;
</script>
<template>
<div class="flex w-[28rem] max-w-full flex-col gap-4">
<Item as-child
><a href="#"
><ItemContent
><ItemTitle>Visit our documentation</ItemTitle
><ItemDescription
>Learn how to get started with our components.</ItemDescription
></ItemContent
><ItemActions
><ChevronRightIcon class="size-4" /></ItemActions></a></Item
><Item variant="outline" as-child
><a href="#" target="_blank" rel="noopener noreferrer"
><ItemContent
><ItemTitle>External resource</ItemTitle
><ItemDescription
>Opens in a new tab with security attributes.</ItemDescription
></ItemContent
><ItemActions><ExternalLinkIcon class="size-4" /></ItemActions></a
></Item>
</div>
</template>
API reference
Frontfriend-owned props. Native HTML and inherited primitive props
remain documented by Reka UI.
Item
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
size | ItemVariants["size"] | — | |
variant | ItemVariants["variant"] | — | |
ItemActions
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemContent
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemDescription
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemFooter
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemGroup
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemHeader
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemMedia
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
variant | ItemMediaVariants["variant"] | — | |
ItemSeparator
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
ItemTitle
| Prop | Type | Default | Description |
class | HTMLAttributes["class"] | — | |
Configuration determines the actual classes and available styling hooks.
See Theming & component configuration before introducing
a repeated local override.