ZaidanHomeDocsComponentsBlocksChartsTypesetCreate

Command Palette

Search for a command to run...

GitHub
New
Sections
  • Introduction
  • Components
  • Blocks
  • Installation
  • Customization
  • Dark Mode
  • Typeset
  • Zaidan Skills
  • FAQ
  • Roadmap
  • Changelog
Installation
  • Astro
  • Manual
  • Solid Start
  • TanStack Router
  • TanStack Start
  • Vite
Blocks
  • Data Grid
  • Event Calendar
  • Filters
  • Gantt
  • Image Crop
  • Kanban
  • Message Scroller
  • Questionnaire
  • Sortable
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Attachment
  • Avatar
  • Badge
  • Breadcrumb
  • Bubble
  • Button
  • Button Group
  • Calendar
  • Card
  • Carousel
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Command
  • Context Menu
  • Dialog
  • Drawer
  • Dropdown Menu
  • Empty
  • Field
  • Hover Card
  • Input
  • Input Group
  • Input OTP
  • Item
  • Kbd
  • Label
  • Marker
  • Menubar
  • Message
  • Native Select
  • Navigation Menu
  • Pagination
  • Popover
  • Progress
  • Radio Group
  • Resizable
  • Scroll Area
  • Select
  • Separator
  • Sheet
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toggle Group
  • Tooltip

Item

A versatile component for displaying content with media, title, description, and actions.

Kobalte
Kobalte

The ItemSeparator component is built on top of Kobalte Separator, which provides the accessible separator primitive.

Basic Item

A simple item with title and description.

Your profile has been verified.
1
import { BadgeCheck, ChevronRight } from "lucide-solid";
2
3
import { Button } from "~/components/ui/button";
4
import {
5
Item,
6
ItemActions,
7
ItemContent,
8
ItemDescription,
9
ItemMedia,
10
ItemTitle,
11
} from "~/components/ui/item";
12
13
export default function ItemDemo() {
14
return (
15
<div class="flex w-full max-w-md flex-col gap-6">
16
<Item variant="outline">
17
<ItemContent>
18
<ItemTitle>Basic Item</ItemTitle>
19
<ItemDescription>A simple item with title and description.</ItemDescription>
20
</ItemContent>
21
<ItemActions>
22
<Button variant="outline" size="sm">
23
Action
24
</Button>
25
</ItemActions>
26
</Item>
27
<Item as="a" href="#item-demo" variant="outline" size="sm">
28
<ItemMedia>
29
<BadgeCheck class="size-5" />
30
</ItemMedia>
31
<ItemContent>
32
<ItemTitle>Your profile has been verified.</ItemTitle>
33
</ItemContent>
34
<ItemActions>
35
<ChevronRight class="size-4" />
36
</ItemActions>
37
</Item>
38
</div>
39
);
40
}

The Item component is a straightforward flex container that can house nearly any type of content. Use it to display a title, description, and actions. Group it with ItemGroup to create a list of items.

Installation

pnpm dlx shadcn@latest add @zaidan/item
npx shadcn@latest add @zaidan/item
yarn dlx shadcn@latest add @zaidan/item
bunx --bun shadcn@latest add @zaidan/item

Usage

1
import {
2
Item,
3
ItemActions,
4
ItemContent,
5
ItemDescription,
6
ItemMedia,
7
ItemTitle,
8
} from "~/components/ui/item";
1
<Item>
2
<ItemMedia variant="icon">
3
<Icon />
4
</ItemMedia>
5
<ItemContent>
6
<ItemTitle>Title</ItemTitle>
7
<ItemDescription>Description</ItemDescription>
8
</ItemContent>
9
<ItemActions>
10
<Button>Action</Button>
11
</ItemActions>
12
</Item>

Composition

Use the following composition to build an Item:

ItemGroup
└── Item
├── ItemHeader
├── ItemMedia
├── ItemContent
│ ├── ItemTitle
│ └── ItemDescription
├── ItemActions
└── ItemFooter

Item vs Field

Use Field if you need to display a form input such as a checkbox, input, radio, or select.

If you only need to display content such as a title, description, and actions, use Item.

Variant

Use the variant prop to change the visual style of the item.

Default Variant

Transparent background with no border.

Outline Variant

Outlined style with a visible border.

Muted Variant

Muted background for secondary content.

1
import { Inbox } from "lucide-solid";
2
3
import {
4
Item,
5
ItemContent,
6
ItemDescription,
7
ItemMedia,
8
ItemTitle,
9
} from "~/components/ui/item";
10
11
export default function ItemVariant() {
12
return (
13
<div class="flex w-full max-w-md flex-col gap-6">
14
<Item>
15
<ItemMedia variant="icon">
16
<Inbox />
17
</ItemMedia>
18
<ItemContent>
19
<ItemTitle>Default Variant</ItemTitle>
20
<ItemDescription>Transparent background with no border.</ItemDescription>
21
</ItemContent>
22
</Item>
23
<Item variant="outline">
24
<ItemMedia variant="icon">
25
<Inbox />
26
</ItemMedia>
27
<ItemContent>
28
<ItemTitle>Outline Variant</ItemTitle>
29
<ItemDescription>Outlined style with a visible border.</ItemDescription>
30
</ItemContent>
31
</Item>
32
<Item variant="muted">
33
<ItemMedia variant="icon">
34
<Inbox />
35
</ItemMedia>
36
<ItemContent>
37
<ItemTitle>Muted Variant</ItemTitle>
38
<ItemDescription>Muted background for secondary content.</ItemDescription>
39
</ItemContent>
40
</Item>
41
</div>
42
);
43
}

Size

Use the size prop to change the size of the item. Available sizes are default, sm, and xs.

Default Size

The standard size for most use cases.

Small Size

A compact size for dense layouts.

Extra Small Size

The most compact size available.

1
import { Inbox } from "lucide-solid";
2
3
import {
4
Item,
5
ItemContent,
6
ItemDescription,
7
ItemMedia,
8
ItemTitle,
9
} from "~/components/ui/item";
10
11
export default function ItemSize() {
12
return (
13
<div class="flex w-full max-w-md flex-col gap-6">
14
<Item variant="outline">
15
<ItemMedia variant="icon">
16
<Inbox />
17
</ItemMedia>
18
<ItemContent>
19
<ItemTitle>Default Size</ItemTitle>
20
<ItemDescription>The standard size for most use cases.</ItemDescription>
21
</ItemContent>
22
</Item>
23
<Item variant="outline" size="sm">
24
<ItemMedia variant="icon">
25
<Inbox />
26
</ItemMedia>
27
<ItemContent>
28
<ItemTitle>Small Size</ItemTitle>
29
<ItemDescription>A compact size for dense layouts.</ItemDescription>
30
</ItemContent>
31
</Item>
32
<Item variant="outline" size="xs">
33
<ItemMedia variant="icon">
34
<Inbox />
35
</ItemMedia>
36
<ItemContent>
37
<ItemTitle>Extra Small Size</ItemTitle>
38
<ItemDescription>The most compact size available.</ItemDescription>
39
</ItemContent>
40
</Item>
41
</div>
42
);
43
}

Icon

Use ItemMedia with variant="icon" to display an icon.

Security Alert

New login detected from unknown device.

1
import { ShieldAlert } from "lucide-solid";
2
3
import { Button } from "~/components/ui/button";
4
import {
5
Item,
6
ItemActions,
7
ItemContent,
8
ItemDescription,
9
ItemMedia,
10
ItemTitle,
11
} from "~/components/ui/item";
12
13
export default function ItemIcon() {
14
return (
15
<div class="flex w-full max-w-lg flex-col gap-6">
16
<Item variant="outline">
17
<ItemMedia variant="icon">
18
<ShieldAlert />
19
</ItemMedia>
20
<ItemContent>
21
<ItemTitle>Security Alert</ItemTitle>
22
<ItemDescription>New login detected from unknown device.</ItemDescription>
23
</ItemContent>
24
<ItemActions>
25
<Button size="sm" variant="outline">
26
Review
27
</Button>
28
</ItemActions>
29
</Item>
30
</div>
31
);
32
}

Avatar

Wrap an Avatar in ItemMedia to display an avatar.

ER
Evil Rabbit

Last seen 5 months ago

CRCNER
No Team Members

Invite your team to collaborate on this project.

1
import { Plus } from "lucide-solid";
2
3
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
4
import { Button } from "~/components/ui/button";
5
import {
6
Item,
7
ItemActions,
8
ItemContent,
9
ItemDescription,
10
ItemMedia,
11
ItemTitle,
12
} from "~/components/ui/item";
13
14
export default function ItemAvatar() {
15
return (
16
<div class="flex w-full max-w-lg flex-col gap-6">
17
<Item variant="outline">
18
<ItemMedia>
19
<Avatar class="size-10">
20
<AvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
21
<AvatarFallback>ER</AvatarFallback>
22
</Avatar>
23
</ItemMedia>
24
<ItemContent>
25
<ItemTitle>Evil Rabbit</ItemTitle>
26
<ItemDescription>Last seen 5 months ago</ItemDescription>
27
</ItemContent>
28
<ItemActions>
29
<Button size="icon-sm" variant="outline" class="rounded-full" aria-label="Invite">
30
<Plus />
31
</Button>
32
</ItemActions>
33
</Item>
34
<Item variant="outline">
35
<ItemMedia>
36
<div class="flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background *:data-[slot=avatar]:grayscale">
37
<Avatar class="hidden sm:flex">
38
<AvatarImage src="https://github.com/carere.png" alt="@carere" />
39
<AvatarFallback>CR</AvatarFallback>
40
</Avatar>
41
<Avatar class="hidden sm:flex">
42
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
43
<AvatarFallback>CN</AvatarFallback>
44
</Avatar>
45
<Avatar>
46
<AvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
47
<AvatarFallback>ER</AvatarFallback>
48
</Avatar>
49
</div>
50
</ItemMedia>
51
<ItemContent>
52
<ItemTitle>No Team Members</ItemTitle>
53
<ItemDescription>Invite your team to collaborate on this project.</ItemDescription>
54
</ItemContent>
55
<ItemActions>
56
<Button size="sm" variant="outline">
57
Invite
58
</Button>
59
</ItemActions>
60
</Item>
61
</div>
62
);
63
}

Image

Use ItemMedia with variant="image" to display an image.

Midnight City Lights
Midnight City Lights - Electric Nights

Neon Dreams

3:45

Coffee Shop Conversations
Coffee Shop Conversations - Urban Stories

The Morning Brew

4:05

Digital Rain
Digital Rain - Binary Beats

Cyber Symphony

3:30

1
import { For } from "solid-js";
2
3
import {
4
Item,
5
ItemContent,
6
ItemDescription,
7
ItemGroup,
8
ItemMedia,
9
ItemTitle,
10
} from "~/components/ui/item";
11
12
const music = [
13
{
14
title: "Midnight City Lights",
15
artist: "Neon Dreams",
16
album: "Electric Nights",
17
duration: "3:45",
18
},
19
{
20
title: "Coffee Shop Conversations",
21
artist: "The Morning Brew",
22
album: "Urban Stories",
23
duration: "4:05",
24
},
25
{ title: "Digital Rain", artist: "Cyber Symphony", album: "Binary Beats", duration: "3:30" },
26
];
27
28
export default function ItemImage() {
29
return (
30
<div class="flex w-full max-w-md flex-col gap-6">
31
<ItemGroup class="gap-4">
32
<For each={music}>
33
{(song) => (
34
<Item as="a" href="#item-image" variant="outline" role="listitem">
35
<ItemMedia variant="image">
36
<img
37
src={`https://avatar.vercel.sh/${song.title}`}
38
alt={song.title}
39
width="32"
40
height="32"
41
class="object-cover grayscale"
42
/>
43
</ItemMedia>
44
<ItemContent>
45
<ItemTitle class="line-clamp-1">
46
{song.title} - <span class="text-muted-foreground">{song.album}</span>
47
</ItemTitle>
48
<ItemDescription>{song.artist}</ItemDescription>
49
</ItemContent>
50
<ItemContent class="flex-none text-center">
51
<ItemDescription>{song.duration}</ItemDescription>
52
</ItemContent>
53
</Item>
54
)}
55
</For>
56
</ItemGroup>
57
</div>
58
);
59
}

Group

Use ItemGroup to group related items together.

c
carere

carere@example.com

s
shadcn

shadcn@vercel.com

e
evilrabbit

evilrabbit@vercel.com

1
import { Plus } from "lucide-solid";
2
import { For } from "solid-js";
3
4
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
5
import { Button } from "~/components/ui/button";
6
import {
7
Item,
8
ItemActions,
9
ItemContent,
10
ItemDescription,
11
ItemGroup,
12
ItemMedia,
13
ItemTitle,
14
} from "~/components/ui/item";
15
16
const people = [
17
{ username: "carere", avatar: "https://github.com/carere.png", email: "carere@example.com" },
18
{ username: "shadcn", avatar: "https://github.com/shadcn.png", email: "shadcn@vercel.com" },
19
{
20
username: "evilrabbit",
21
avatar: "https://github.com/evilrabbit.png",
22
email: "evilrabbit@vercel.com",
23
},
24
];
25
26
export default function ItemGroupDemo() {
27
return (
28
<ItemGroup class="max-w-sm">
29
<For each={people}>
30
{(person) => (
31
<Item variant="outline" role="listitem">
32
<ItemMedia>
33
<Avatar>
34
<AvatarImage src={person.avatar} alt={`@${person.username}`} class="grayscale" />
35
<AvatarFallback>{person.username.charAt(0)}</AvatarFallback>
36
</Avatar>
37
</ItemMedia>
38
<ItemContent class="gap-1">
39
<ItemTitle>{person.username}</ItemTitle>
40
<ItemDescription>{person.email}</ItemDescription>
41
</ItemContent>
42
<ItemActions>
43
<Button
44
variant="ghost"
45
size="icon"
46
class="rounded-full"
47
aria-label={`Add ${person.username}`}
48
>
49
<Plus />
50
</Button>
51
</ItemActions>
52
</Item>
53
)}
54
</For>
55
</ItemGroup>
56
);
57
}

Header

Use ItemHeader to add a header above the item content.

v0-1.5-sm
v0-1.5-sm

Everyday tasks and UI generation.

v0-1.5-lg
v0-1.5-lg

Advanced thinking or reasoning.

v0-2.0-mini
v0-2.0-mini

Open Source model for everyone.

1
import { For } from "solid-js";
2
3
import {
4
Item,
5
ItemContent,
6
ItemDescription,
7
ItemGroup,
8
ItemHeader,
9
ItemTitle,
10
} from "~/components/ui/item";
11
12
const models = [
13
{
14
name: "v0-1.5-sm",
15
description: "Everyday tasks and UI generation.",
16
image:
17
"https://images.unsplash.com/photo-1650804068570-7fb2e3dbf888?q=80&w=640&auto=format&fit=crop",
18
},
19
{
20
name: "v0-1.5-lg",
21
description: "Advanced thinking or reasoning.",
22
image:
23
"https://images.unsplash.com/photo-1610280777472-54133d004c8c?q=80&w=640&auto=format&fit=crop",
24
},
25
{
26
name: "v0-2.0-mini",
27
description: "Open Source model for everyone.",
28
image:
29
"https://images.unsplash.com/photo-1602146057681-08560aee8cde?q=80&w=640&auto=format&fit=crop",
30
},
31
];
32
33
export default function ItemHeaderDemo() {
34
return (
35
<div class="flex w-full max-w-xl flex-col gap-6">
36
<ItemGroup class="grid grid-cols-3 gap-4">
37
<For each={models}>
38
{(model) => (
39
<Item variant="outline" role="listitem">
40
<ItemHeader>
41
<img
42
src={model.image}
43
alt={model.name}
44
width="128"
45
height="128"
46
class="aspect-square w-full rounded-sm object-cover"
47
/>
48
</ItemHeader>
49
<ItemContent>
50
<ItemTitle>{model.name}</ItemTitle>
51
<ItemDescription>{model.description}</ItemDescription>
52
</ItemContent>
53
</Item>
54
)}
55
</For>
56
</ItemGroup>
57
</div>
58
);
59
}

Link

Set as="a" to render the item as a link. The hover and focus states apply to the anchor element.

Visit our documentation

Learn how to get started with our components.

External resource

Opens in a new tab with security attributes.

1
import { ChevronRight, ExternalLink } from "lucide-solid";
2
3
import {
4
Item,
5
ItemActions,
6
ItemContent,
7
ItemDescription,
8
ItemTitle,
9
} from "~/components/ui/item";
10
11
export default function ItemLink() {
12
return (
13
<div class="flex w-full max-w-md flex-col gap-4">
14
<Item as="a" href="#item-link">
15
<ItemContent>
16
<ItemTitle>Visit our documentation</ItemTitle>
17
<ItemDescription>Learn how to get started with our components.</ItemDescription>
18
</ItemContent>
19
<ItemActions>
20
<ChevronRight class="size-4" />
21
</ItemActions>
22
</Item>
23
<Item
24
as="a"
25
href="https://zaidan.dev"
26
target="_blank"
27
rel="noopener noreferrer"
28
variant="outline"
29
>
30
<ItemContent>
31
<ItemTitle>External resource</ItemTitle>
32
<ItemDescription>Opens in a new tab with security attributes.</ItemDescription>
33
</ItemContent>
34
<ItemActions>
35
<ExternalLink class="size-4" />
36
</ItemActions>
37
</Item>
38
</div>
39
);
40
}
1
<Item as="a" href="/dashboard">
2
<ItemMedia variant="icon">
3
<Home />
4
</ItemMedia>
5
<ItemContent>
6
<ItemTitle>Dashboard</ItemTitle>
7
<ItemDescription>Overview of your account and activity.</ItemDescription>
8
</ItemContent>
9
</Item>

Dropdown

1
import { ChevronDown } from "lucide-solid";
2
import { For } from "solid-js";
3
4
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
5
import { buttonVariants } from "~/components/ui/button";
6
import {
7
DropdownMenu,
8
DropdownMenuContent,
9
DropdownMenuGroup,
10
DropdownMenuItem,
11
DropdownMenuTrigger,
12
} from "~/components/ui/dropdown-menu";
13
import {
14
Item,
15
ItemContent,
16
ItemDescription,
17
ItemMedia,
18
ItemTitle,
19
} from "~/components/ui/item";
20
21
const people = [
22
{ username: "carere", avatar: "https://github.com/carere.png", email: "carere@example.com" },
23
{ username: "shadcn", avatar: "https://github.com/shadcn.png", email: "shadcn@vercel.com" },
24
{
25
username: "evilrabbit",
26
avatar: "https://github.com/evilrabbit.png",
27
email: "evilrabbit@vercel.com",
28
},
29
];
30
31
export default function ItemDropdown() {
32
return (
33
<DropdownMenu placement="bottom-end">
34
<DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
35
Select <ChevronDown />
36
</DropdownMenuTrigger>
37
<DropdownMenuContent class="w-48">
38
<DropdownMenuGroup>
39
<For each={people}>
40
{(person) => (
41
<DropdownMenuItem textValue={person.username}>
42
<Item size="xs" class="w-full p-2">
43
<ItemMedia>
44
<Avatar class="size-[--spacing(6.5)]">
45
<AvatarImage
46
src={person.avatar}
47
alt={`@${person.username}`}
48
class="grayscale"
49
/>
50
<AvatarFallback>{person.username.charAt(0)}</AvatarFallback>
51
</Avatar>
52
</ItemMedia>
53
<ItemContent class="gap-0">
54
<ItemTitle>{person.username}</ItemTitle>
55
<ItemDescription class="leading-none">{person.email}</ItemDescription>
56
</ItemContent>
57
</Item>
58
</DropdownMenuItem>
59
)}
60
</For>
61
</DropdownMenuGroup>
62
</DropdownMenuContent>
63
</DropdownMenu>
64
);
65
}

API Reference

Item

The main component for displaying content with media, title, description, and actions.

PropTypeDefault
variant"default" | "outline" | "muted""default"
size"default" | "sm" | "xs""default"
asValidComponent"div"
classstring-

ItemGroup

A container that groups related items together with consistent styling.

<ItemGroup>
<Item />
<ItemSeparator />
<Item />
</ItemGroup>

ItemSeparator

A separator between items in a group. It accepts Kobalte Separator props.

ItemMedia

Use ItemMedia to display media content such as icons, images, or avatars.

PropTypeDefault
variant"default" | "icon" | "image""default"
classstring-
<ItemMedia variant="icon">
<Icon />
</ItemMedia>

ItemContent

Wraps the title and description of the item.

<ItemContent>
<ItemTitle>Title</ItemTitle>
<ItemDescription>Description</ItemDescription>
</ItemContent>

ItemTitle

Displays the title of the item.

ItemDescription

Displays the description of the item.

ItemActions

Container for action buttons or other interactive elements.

ItemHeader

Displays a header above the item content.

ItemFooter

Displays a footer below the item content.

On This Page

  • Installation
  • Usage
  • Composition
  • Item vs Field
  • Variant
  • Size
  • Icon
  • Avatar
  • Image
  • Group
  • Header
  • Link
  • Dropdown
  • API Reference
    • Item
    • ItemGroup
    • ItemSeparator
    • ItemMedia
    • ItemContent
    • ItemTitle
    • ItemDescription
    • ItemActions
    • ItemHeader
    • ItemFooter
Built by Kevin Abatan. The source code is available on GitHub.