Skip to content
Esc
navigateopen⌘Jpreview
On this page

Item

A flexible list row with media, content, and actions.

Two-factor authentication

Add an extra layer of security to your account.

Update available

Version 2.4 is ready to install.

import * as stylex from '@stylexjs/stylex';

import { Button } from '@/components/ui/button';
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemGroup,
  ItemMedia,
  ItemTitle,
} from '@/components/ui/item';
import { Switch } from '@/components/ui/switch';
import { container } from '@/lib/constants.stylex';

export default function ItemDemo() {
  return (
    <ItemGroup style={styles.group}>
      <Item variant="outline">
        <ItemContent>
          <ItemTitle>Two-factor authentication</ItemTitle>
          <ItemDescription>
            Add an extra layer of security to your account.
          </ItemDescription>
        </ItemContent>
        <ItemActions>
          <Switch defaultChecked />
        </ItemActions>
      </Item>
      <Item variant="muted">
        <ItemMedia variant="icon">
          <svg
            width="16"
            height="16"
            viewBox={`0 0 16 16`}
            fill="none"
            stroke="currentColor"
            strokeWidth="1.5"
            strokeLinecap="round"
            aria-hidden
          >
            <path d={`M8 10.5V7M8 5v.01M14.5 8a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0`} />
          </svg>
        </ItemMedia>
        <ItemContent>
          <ItemTitle>Update available</ItemTitle>
          <ItemDescription>Version 2.4 is ready to install.</ItemDescription>
        </ItemContent>
        <ItemActions>
          <Button variant="outline" size="sm">
            Install
          </Button>
        </ItemActions>
      </Item>
    </ItemGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.xl,
  },
});

Install

npx shadcn@latest add @madeui/item

Usage

import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemGroup,
  ItemMedia,
  ItemTitle,
} from '@/components/ui/item';

Composition

<ItemGroup>
  <Item>
    <ItemMedia />
    <ItemContent>
      <ItemTitle />
      <ItemDescription />
    </ItemContent>
    <ItemActions />
  </Item>
  <ItemSeparator />
</ItemGroup>

Variants

Default

A borderless row.

Outline

A bordered row.

Muted

A tinted background row.

import * as stylex from '@stylexjs/stylex';

import { Item, ItemContent, ItemDescription, ItemGroup, ItemTitle } from '@/components/ui/item';
import { container } from '@/lib/constants.stylex';

export default function ItemVariants() {
  return (
    <ItemGroup style={styles.group}>
      <Item variant="default">
        <ItemContent>
          <ItemTitle>Default</ItemTitle>
          <ItemDescription>A borderless row.</ItemDescription>
        </ItemContent>
      </Item>
      <Item variant="outline">
        <ItemContent>
          <ItemTitle>Outline</ItemTitle>
          <ItemDescription>A bordered row.</ItemDescription>
        </ItemContent>
      </Item>
      <Item variant="muted">
        <ItemContent>
          <ItemTitle>Muted</ItemTitle>
          <ItemDescription>A tinted background row.</ItemDescription>
        </ItemContent>
      </Item>
    </ItemGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.xl,
  },
});

Sizes

Extra small
Small
Medium
import * as stylex from '@stylexjs/stylex';

import { Item, ItemContent, ItemGroup, ItemTitle } from '@/components/ui/item';
import { container } from '@/lib/constants.stylex';

export default function ItemSizes() {
  return (
    <ItemGroup style={styles.group}>
      <Item variant="outline" size="xs">
        <ItemContent>
          <ItemTitle>Extra small</ItemTitle>
        </ItemContent>
      </Item>
      <Item variant="outline" size="sm">
        <ItemContent>
          <ItemTitle>Small</ItemTitle>
        </ItemContent>
      </Item>
      <Item variant="outline" size="md">
        <ItemContent>
          <ItemTitle>Medium</ItemTitle>
        </ItemContent>
      </Item>
    </ItemGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.xl,
  },
});

Avatar

Use ItemMedia to hold our Avatar component.

MD
madeui

Left a comment on your pull request.

import * as stylex from '@stylexjs/stylex';

import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Item, ItemContent, ItemDescription, ItemGroup, ItemMedia, ItemTitle } from '@/components/ui/item';
import { container } from '@/lib/constants.stylex';

export default function ItemAvatar() {
  return (
    <ItemGroup style={styles.group}>
      <Item variant="outline">
        <ItemMedia>
          <Avatar>
            <AvatarImage src="https://github.com/madeui.png" alt="@madeui" />
            <AvatarFallback>MD</AvatarFallback>
          </Avatar>
        </ItemMedia>
        <ItemContent>
          <ItemTitle>madeui</ItemTitle>
          <ItemDescription>Left a comment on your pull request.</ItemDescription>
        </ItemContent>
      </Item>
    </ItemGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.xl,
  },
});

Group

Group related items with ItemGroup, dividing them with ItemSeparator.

Deploy succeeded

Production · 2 minutes ago

New comment

On issue #482 · 1 hour ago

Build failed

staging branch · yesterday

import * as React from 'react';

import * as stylex from '@stylexjs/stylex';

import { Item, ItemContent, ItemDescription, ItemGroup, ItemSeparator, ItemTitle } from '@/components/ui/item';
import { container } from '@/lib/constants.stylex';

const activity = [
  { title: 'Deploy succeeded', description: 'Production · 2 minutes ago' },
  { title: 'New comment', description: 'On issue #482 · 1 hour ago' },
  { title: 'Build failed', description: 'staging branch · yesterday' },
];

export default function ItemGroupExample() {
  return (
    <ItemGroup style={styles.group}>
      {activity.map((entry, index) => (
        <React.Fragment key={entry.title}>
          <Item>
            <ItemContent>
              <ItemTitle>{entry.title}</ItemTitle>
              <ItemDescription>{entry.description}</ItemDescription>
            </ItemContent>
          </Item>
          {index < activity.length - 1 && <ItemSeparator />}
        </React.Fragment>
      ))}
    </ItemGroup>
  );
}

const styles = stylex.create({
  group: {
    maxWidth: container.xl,
  },
});

Use the render prop to render the item as an anchor — hover and focus states apply to the element itself.

import { Item, ItemContent, ItemDescription, ItemMedia, ItemTitle } from '@/components/ui/item';

// The `render` prop swaps the underlying element — here an <a>, so hover and
// focus states apply to the anchor.
export default function ItemLink() {
  return (
    <Item variant="outline" render={<a href="#dashboard" />}>
      <ItemMedia variant="icon">
        <svg
          width="16"
          height="16"
          viewBox={`0 0 16 16`}
          fill="none"
          stroke="currentColor"
          strokeWidth="1.5"
          strokeLinecap="round"
          strokeLinejoin="round"
          aria-hidden
        >
          <path d={`M2 6.5 8 2l6 4.5v6.5a1 1 0 0 1-1 1h-2.5v-4h-5v4H4a1 1 0 0 1-1-1z`} />
        </svg>
      </ItemMedia>
      <ItemContent>
        <ItemTitle>Dashboard</ItemTitle>
        <ItemDescription>Overview of your account and activity.</ItemDescription>
      </ItemContent>
    </Item>
  );
}

API reference

Item

Prop Type Default Description
variant 'default' | 'outline' | 'muted' 'default'
size 'xs' | 'sm' | 'md' 'md'
render ReactElement Render as another element, e.g. render={<a href="…" />}.
style StyleXStyles StyleX styles merged last — always win over the component’s own styles.

ItemMedia accepts variant: 'default', 'icon', or 'image' (40px rounded thumbnail). ItemHeader / ItemFooter span the full row width.

Was this page helpful?