---
title: Item
description: "A flexible list row with media, content, and actions."
---

```tsx
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

```bash
npx shadcn@latest add @madeui/item
```

## Usage

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

## Composition

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

## Variants

```tsx
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

```tsx
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.

```tsx
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`.

```tsx
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,
  },
});
```

## Link

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

```tsx
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.
