A versatile component for displaying content with media, title, description, and actions.
A simple item with title and description.
import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
import { Button } from "@/components/ui/button"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 the ItemGroup component to create a list of items.
Installation#
pnpm dlx shadcn@latest add https://ui.tyap.me/r/styles/base/item.jsonnpx shadcn@latest add https://ui.tyap.me/r/styles/base/item.jsonyarn dlx shadcn@latest add https://ui.tyap.me/r/styles/base/item.jsonbunx --bun shadcn@latest add https://ui.tyap.me/r/styles/base/item.json
Copy and paste the following code into your project.
import * as React from "react"
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { Separator } from "@/components/ui/separator"
function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
role="list"
data-slot="item-group"
className={cn(
"group/item-group flex w-full flex-col",
className
)}
{...props}
/>
)
}
function ItemSeparator({
className,
...props
}: React.ComponentProps<typeof Separator>) {
return (
<Separator
data-slot="item-separator"
orientation="horizontal"
className={cn(className)}
{...props}
/>
)
}
const itemVariants = cva(
"group/item flex w-full flex-wrap items-center transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors",
{
variants: {
variant: {
default: "",
outline: "",
muted: "",
},
size: {
default: "",
sm: "",
xs: "",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function Item({
className,
variant = "default",
size = "default",
render,
...props
}: useRender.ComponentProps<"div"> & VariantProps<typeof itemVariants>) {
return useRender({
defaultTagName: "div",
props: mergeProps<"div">(
{
className: cn(itemVariants({ variant, size, className })),
},
props
),
render,
state: {
slot: "item",
variant,
size,
},
})
}
const itemMediaVariants = cva(
"flex shrink-0 items-center justify-center [&_svg]:pointer-events-none",
{
variants: {
variant: {
default: "",
icon: "",
image: "",
},
},
defaultVariants: {
variant: "default",
},
}
)
function ItemMedia({
className,
variant = "default",
...props
}: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>) {
return (
<div
data-slot="item-media"
data-variant={variant}
className={cn(itemMediaVariants({ variant, className }))}
{...props}
/>
)
}
function ItemContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="item-content"
className={cn(
"flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none",
className
)}
{...props}
/>
)
}
function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="item-title"
className={cn(
"line-clamp-1 flex w-fit items-center",
className
)}
{...props}
/>
)
}
function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<p
data-slot="item-description"
className={cn(
"line-clamp-2 font-normal [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
)}
{...props}
/>
)
}
function ItemActions({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="item-actions"
className={cn("flex items-center", className)}
{...props}
/>
)
}
function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="item-header"
className={cn(
"flex basis-full items-center justify-between",
className
)}
{...props}
/>
)
}
function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="item-footer"
className={cn(
"flex basis-full items-center justify-between",
className
)}
{...props}
/>
)
}
export {
Item,
ItemMedia,
ItemContent,
ItemActions,
ItemGroup,
ItemSeparator,
ItemTitle,
ItemDescription,
ItemHeader,
ItemFooter,
}
Update the import paths to match your project setup.
Usage#
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"<Item>
<ItemMedia variant="icon">
<Icon />
</ItemMedia>
<ItemContent>
<ItemTitle>Title</ItemTitle>
<ItemDescription>Description</ItemDescription>
</ItemContent>
<ItemActions>
<Button>Action</Button>
</ItemActions>
</Item>Composition#
Use the following composition to build an Item:
ItemGroup
└── Item
├── ItemHeader
├── ItemMedia
├── ItemContent
│ ├── ItemTitle
│ └── ItemDescription
├── ItemActions
└── ItemFooterItem 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.
Transparent background with no border.
Outlined style with a visible border.
Muted background for secondary content.
import { InboxIcon } from "lucide-react"
import {Size#
Use the size prop to change the size of the item. Available sizes are default, sm, and xs.
The standard size for most use cases.
A compact size for dense layouts.
The most compact size available.
import { InboxIcon } from "lucide-react"
import {Examples#
Icon#
Use ItemMedia with variant="icon" to display an icon.
New login detected from unknown device.
import { ShieldAlertIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Avatar#
You can use ItemMedia with variant="avatar" to display an avatar.
Last seen 5 months ago
Invite your team to collaborate on this project.
import { Plus } from "lucide-react"
import {Image#
Use ItemMedia with variant="image" to display an image.
import Image from "next/image"
import {Group#
Use ItemGroup to group related items together.
shadcn@vercel.com
maxleiter@vercel.com
evilrabbit@vercel.com
import * as React from "react"
import { PlusIcon } from "lucide-react"
Header#
Use ItemHeader to add a header above the item content.
Everyday tasks and UI generation.
Advanced thinking or reasoning.
Open Source model for everyone.
import Image from "next/image"
import {Link#
Use the render prop to render the item as a link. The hover and focus states will be applied to the anchor element.
import { ChevronRightIcon, ExternalLinkIcon } from "lucide-react"
import {<Item render={<a href="/dashboard" />}>
<ItemMedia variant="icon">
<HomeIcon />
</ItemMedia>
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>Overview of your account and activity.</ItemDescription>
</ItemContent>
</Item>Dropdown#
"use client"
import { ChevronDownIcon } from "lucide-react"RTL#
To enable RTL support in shadcn/ui, see the RTL configuration guide.
عنصر بسيط يحتوي على عنوان ووصف.
"use client"
import * as React from "react"API Reference#
Item#
The main component for displaying content with media, title, description, and actions.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "outline" | "muted" | "default" |
size | "default" | "sm" | "xs" | "default" |
render | React.ReactElement |
ItemGroup#
A container that groups related items together with consistent styling.
<ItemGroup>
<Item />
<Item />
</ItemGroup>ItemSeparator#
A separator between items in a group.
<ItemGroup>
<Item />
<ItemSeparator />
<Item />
</ItemGroup>ItemMedia#
Use ItemMedia to display media content such as icons, images, or avatars.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "icon" | "image" | "default" |
<ItemMedia variant="icon">
<Icon />
</ItemMedia><ItemMedia variant="image">
<img src="..." alt="..." />
</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.
<ItemTitle>Item Title</ItemTitle>ItemDescription#
Displays the description of the item.
<ItemDescription>Item description</ItemDescription>ItemActions#
Container for action buttons or other interactive elements.
<ItemActions>
<Button>Action</Button>
</ItemActions>ItemHeader#
Displays a header above the item content.
<Item>
<ItemHeader>Header</ItemHeader>
<ItemContent>...</ItemContent>
</Item>ItemFooter#
Displays a footer below the item content.
<Item>
<ItemContent>...</ItemContent>
<ItemFooter>Footer</ItemFooter>
</Item>