Capítulo 71 de 108

Item

Core Idea

Container flex versátil para exibir conteúdo com mídia, título, descrição e ações, o bloco de construção padrão para listas (notificações, membros de equipe, resultados de busca, opções de dropdown). Use Item para exibir conteúdo; use Field quando o conteúdo é um input de formulário.

Key Concepts

  • variant: "default" | "outline" | "muted".
  • size: "default" | "sm" | "xs".
  • render: renderiza o Item como outro elemento (ex. <a href="#" />), aplicando estados de hover/focus ao elemento real.
  • ItemMedia variant="default" | "icon" | "image": icon estiliza para ícones simples; image/default para avatar, imagem ou grupo de avatares.
  • ItemGroup: agrupa múltiplos Item com espaçamento/estilo consistente; combina com ItemSeparator entre eles.
  • ItemHeader / ItemFooter: slots opcionais acima/abaixo do conteúdo principal (ex. imagem de capa no header).

Code Examples

<Item variant="outline">
  <ItemContent>
    <ItemTitle>Basic Item</ItemTitle>
    <ItemDescription>A simple item with title and description.</ItemDescription>
  </ItemContent>
  <ItemActions>
    <Button variant="outline" size="sm">Action</Button>
  </ItemActions>
</Item>
  • O que demonstra: composição mínima com título, descrição e ação.
<ItemGroup className="gap-4">
  {music.map((song) => (
    <Item key={song.title} variant="outline" render={<a href="#" />} role="listitem">
      <ItemMedia variant="image">
        <Image src={`https://avatar.vercel.sh/${song.title}`} alt={song.title} width={32} height={32} className="object-cover grayscale" />
      </ItemMedia>
      <ItemContent>
        <ItemTitle className="line-clamp-1">{song.title} - <span className="text-muted-foreground">{song.album}</span></ItemTitle>
        <ItemDescription>{song.artist}</ItemDescription>
      </ItemContent>
      <ItemContent className="flex-none text-center">
        <ItemDescription>{song.duration}</ItemDescription>
      </ItemContent>
    </Item>
  ))}
</ItemGroup>
  • O que demonstra: lista clicável (item vira link via render) com imagem, título de duas partes e uma segunda coluna de conteúdo (duração) usando flex-none.
<DropdownMenuItem key={person.username}>
  <Item size="xs" className="w-full p-2">
    <ItemMedia>
      <Avatar className="size-[--spacing(6.5)]">
        <AvatarImage src={person.avatar} className="grayscale" />
        <AvatarFallback>{person.username.charAt(0)}</AvatarFallback>
      </Avatar>
    </ItemMedia>
    <ItemContent className="gap-0">
      <ItemTitle>{person.username}</ItemTitle>
      <ItemDescription className="leading-none">{person.email}</ItemDescription>
    </ItemContent>
  </Item>
</DropdownMenuItem>
  • O que demonstra: Item size="xs" embutido dentro de um DropdownMenuItem para listas de seleção com avatar + nome + email.

Reference Tables

Item

PropTypeDefault
variant"default" | "outline" | "muted""default"
size"default" | "sm" | "xs""default"
renderReact.ReactElement

ItemMedia

PropTypeDefault
variant"default" | "icon" | "image""default"
ItemGroup
└── Item
    ├── ItemHeader
    ├── ItemMedia
    ├── ItemContent
    │   ├── ItemTitle
    │   └── ItemDescription
    ├── ItemActions
    └── ItemFooter

Anti-patterns

  • Usar Item para inputs de formulário (checkbox, radio, select): use Field nesse caso — Item é só para exibição de conteúdo, não captura de dados.
  • ItemMedia sem variant correto: usar variant="icon" para uma imagem real (ou vice-versa) quebra o dimensionamento/estilo esperado.

Key Takeaways

  1. Regra de decisão simples: conteúdo estático (título/descrição/ação) → Item; input de formulário → Field.
  2. render prop transforma Item em link mantendo hover/focus — mesmo padrão usado em Badge e Button (nativeButton={false} quando aplicável).
  3. ItemGroup + ItemSeparator é o padrão para listas de itens relacionados (ex. membros de equipe, notificações).
  4. size="xs" é o tamanho ideal para reuso dentro de outro componente compacto, como itens de DropdownMenuContent.

Connects To

  • Avatar (ch063): ItemMedia sem variant="icon" frequentemente contém um Avatar ou grupo de avatares.
  • Empty (ch062): estrutura Header/Content/Media semelhante, mas para estado vazio em vez de lista de conteúdo.
  • Spinner (ch059) e Badge (ch061): comumente usados dentro de Item como indicadores de status.