Presets

Blocks

Get PRO

Need premium blocks and templates? Upgrade to PRO and get access.

Upgrade
JoinLogin
Presets
Monochrome
Overview
  • Introduction
  • Components
  • Installation
Components
  • Accordion
  • Alert
  • Alert Dialog
  • Aspect Ratio
  • Avatar
  • Badge
  • Breadcrumb
  • Button
  • Button Group
  • CalendarNEW
  • Card
  • CarouselNEW
  • Checkbox
  • Collapsible
  • Dialog
  • Dropdown Menu
  • Empty
  • Field
  • Input
  • Input Group
  • Item
  • Kbd
  • Label
  • Native Select
  • Scroll Area
  • SelectNEW
  • Separator
  • SwitchNEW
  • Table
  • Tabs
  • Textarea
  • TooltipNEW

Item

PreviousNext

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

1import { Button } from "@/components/ui/button";2import {3  Item,4  ItemActions,

Installation

pnpm dlx sprawlify@latest add item
npx sprawlify@latest add item
yarn sprawlify@latest add item
bunx --bun sprawlify@latest add item

Install the following dependencies:

pnpm add @sprawlify/primitives @sprawlify/react
npm install @sprawlify/primitives @sprawlify/react
yarn add @sprawlify/primitives @sprawlify/react
bun add @sprawlify/primitives @sprawlify/react

Add the following files to your project:

item.tsx
1"use client";23import * as React from "react";4import { cva, type VariantProps } from "class-variance-authority";5import { cn } from "@/lib/utils";6import { Separator } from "@/components/ui/separator";7import { sprawlify } from "@sprawlify/react";89function ItemGroup({ className, ...props }: React.ComponentProps<typeof sprawlify.div>) {10  return (11    <sprawlify.div12      role="list"13      data-scope="item"14      data-part="group"15      data-slot="item-group"16      className={cn(17        "gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2 group/item-group flex w-full flex-col",18        className,19      )}20      {...props}21    />22  );23}2425function ItemSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {26  return (27    <Separator28      data-scope="item"29      data-part="separator"30      data-slot="item-separator"31      orientation="horizontal"32      className={cn("my-2", className)}33      {...props}34    />35  );36}3738const itemVariants = cva(39  "[a]:hover:bg-muted rounded-lg border text-sm w-full group/item focus-visible:border-ring focus-visible:ring-ring/50 flex items-center flex-wrap outline-none transition-colors duration-100 focus-visible:ring-[3px] [a]:transition-colors",40  {41    variants: {42      variant: {43        default: "border-transparent",44        outline: "border-border",45        muted: "bg-muted/50 border-transparent",46      },47      size: {48        default: "gap-2.5 px-3 py-2.5",49        sm: "gap-2.5 px-3 py-2.5",50        xs: "gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0",51      },52    },53    defaultVariants: {54      variant: "default",55      size: "default",56    },57  },58);5960function Item({61  className,62  variant = "default",63  size = "default",64  ...props65}: React.ComponentProps<typeof sprawlify.div> & VariantProps<typeof itemVariants>) {66  return (67    <sprawlify.div68      data-scope="item"69      data-part="root"70      data-slot="item"71      data-variant={variant}72      data-size={size}73      className={cn(itemVariants({ variant, size, className }))}74      {...props}75    />76  );77}7879const itemMediaVariants = cva(80  "gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start flex shrink-0 items-center justify-center [&_svg]:pointer-events-none",81  {82    variants: {83      variant: {84        default: "bg-transparent",85        icon: "[&_svg:not([class*='size-'])]:size-4",86        image:87          "size-10 overflow-hidden rounded-sm group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 [&_img]:size-full [&_img]:object-cover",88      },89    },90    defaultVariants: {91      variant: "default",92    },93  },94);9596function ItemMedia({97  className,98  variant = "default",99  ...props100}: React.ComponentProps<typeof sprawlify.div> & VariantProps<typeof itemMediaVariants>) {101  return (102    <sprawlify.div103      data-scope="item"104      data-part="media"105      data-slot="item-media"106      data-variant={variant}107      className={cn(itemMediaVariants({ variant, className }))}108      {...props}109    />110  );111}112113function ItemContent({ className, ...props }: React.ComponentProps<typeof sprawlify.div>) {114  return (115    <sprawlify.div116      data-scope="item"117      data-part="content"118      data-slot="item-content"119      className={cn(120        "gap-1 group-data-[size=xs]/item:gap-0 flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none",121        className,122      )}123      {...props}124    />125  );126}127128function ItemTitle({ className, ...props }: React.ComponentProps<typeof sprawlify.div>) {129  return (130    <sprawlify.div131      data-scope="item"132      data-part="title"133      data-slot="item-title"134      className={cn(135        "gap-2 text-sm leading-snug font-medium underline-offset-4 line-clamp-1 flex w-fit items-center",136        className,137      )}138      {...props}139    />140  );141}142143function ItemDescription({ className, ...props }: React.ComponentProps<typeof sprawlify.p>) {144  return (145    <sprawlify.p146      data-scope="item"147      data-part="description"148      data-slot="item-description"149      className={cn(150        "text-muted-foreground text-left text-sm leading-normal group-data-[size=xs]/item:text-xs [&>a:hover]:text-primary line-clamp-2 font-normal [&>a]:underline [&>a]:underline-offset-4",151        className,152      )}153      {...props}154    />155  );156}157158function ItemActions({ className, ...props }: React.ComponentProps<typeof sprawlify.div>) {159  return (160    <sprawlify.div161      data-scope="item"162      data-part="actions"163      data-slot="item-actions"164      className={cn("gap-2 flex items-center", className)}165      {...props}166    />167  );168}169170function ItemHeader({ className, ...props }: React.ComponentProps<typeof sprawlify.div>) {171  return (172    <sprawlify.div173      data-scope="item"174      data-part="header"175      data-slot="item-header"176      className={cn("gap-2 flex basis-full items-center justify-between", className)}177      {...props}178    />179  );180}181182function ItemFooter({ className, ...props }: React.ComponentProps<typeof sprawlify.div>) {183  return (184    <sprawlify.div185      data-scope="item"186      data-part="footer"187      data-slot="item-footer"188      className={cn("gap-2 flex basis-full items-center justify-between", className)}189      {...props}190    />191  );192}193194export {195  Item,196  ItemMedia,197  ItemContent,198  ItemActions,199  ItemGroup,200  ItemSeparator,201  ItemTitle,202  ItemDescription,203  ItemHeader,204  ItemFooter,205};206

Update the import paths to match your project setup.

Usage

1import {
2  ItemGroup,
3  ItemSeparator,
4  Item,
5  ItemMedia,
6  ItemContent,
7  ItemTitle,
8  ItemDescription,
9  ItemAction
10} 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>

Examples

Avatar

You can use ItemMedia with variant="avatar" to display an avatar.

1import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";2import { Button } from "@/components/ui/button";3import {4  Item,

Group

Use ItemGroup to group related items together.

1import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";2import { Button } from "@/components/ui/button";3import {4  Item,

Header

Use ItemHeader to add a header above the item content.

1import {2  Item,3  ItemContent,4  ItemDescription,

Icon

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

1import { Button } from "@/components/ui/button";2import {3  Item,4  ItemActions,

Image

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

1import {2  Item,3  ItemContent,4  ItemDescription,

Link

Use the asChild prop to render the item as a link. The hover and focus states will be applied to the anchor element.

1import { Item, ItemActions, ItemContent, ItemDescription, ItemTitle } from "@/components/ui/item";2import { ChevronRightIcon, ExternalLinkIcon } from "lucide-react";34export default function Preview() {

On This Page

InstallationUsageExamplesAvatarGroupHeaderIconImageLink

Get PRO

Need premium blocks and templates? Upgrade to PRO and get access.