Item
templates/components/Item
Diferente do Card (peça isolada), o Item é uma LINHA de lista composável — Media + Content(Título/Descrição) + Actions — feita para se repetir dentro de um Item:Group (role="list") e ser interagida linha a linha (notificações, ajustes, contatos, itens de estoque de EPI). Os enriquecedores giram em torno dessa natureza de linha-em-lista: selecionar, reordenar, expandir, agir por linha e navegar pelo grupo.
Base congelada
A simple item with title and description.
Capacidades 8
Conteúdo
Indicador de não-lido / novo
Marca a linha como não-lida ou…
Comportamento
Selecionável na linha
Transforma a linha em opção selecionável,…
Selecionar tudo + contagem (grupo)
No nível do Item:Group, adiciona um…
Arrastar para reordenar
Adiciona uma alça de arraste (grip)…
Expansível (dobrar detalhe)
Torna a linha um disclosure: um…
Ações rápidas na linha
Escolhe quais ações aparecem no slot…
Navegação por teclado no grupo
Ativa roving tabindex no Item:Group: setas…
Estado de carregamento (skeleton)
Mostra placeholders shimmer no lugar de…
Claude Code
Cole no Claude Code — ele acerta de primeira.
Item (UI) — Design System (Symfony UX Toolkit / shadcn)
BASE CONGELADA (não mude por instância): Congelado: o layout de linha flex (Media | Content | Actions, com Header/Footer em basis-full), os variants (default/outline/muted e suas bordas), os sizes (default/sm/xs com seus gaps e paddings), os cantos rounded-lg (e rounded-sm da Media imagem), a tipografia text-sm da linha, o Título font-medium line-clamp-1, a Descrição text-muted-foreground line-clamp-2, as cores/tokens (border-border, muted-foreground, hover:bg-muted no link), a transição de cor, o foco visível (focus-visible ring), o role="list" do Group, a semântica do Separator e o passthrough de {{ attributes }} e slots. Nenhuma capacidade altera fonte, cor, cantos ou espaçamento da base.
USO: <twig:Item variant="default" />
CAPACIDADES OPT-IN (ligue sem alterar o visual):
- Selecionável na linha: Transforma a linha em opção selecionável, inserindo um controle de seleção sem mexer nos slots de conteúdo. [select → Checkbox (seleção múltipla) / Radio (seleção única) / Nenhum]- Selecionar tudo + contagem (grupo): No nível do Item:Group, adiciona um controle 'selecionar tudo' e o texto 'N de M selecionados', em sincronia com a seleção por linha. [toggle]- Arrastar para reordenar: Adiciona uma alça de arraste (grip) e o comportamento de reordenar as linhas dentro do Item:Group, persistindo a nova ordem. [toggle]- Expansível (dobrar detalhe): Torna a linha um disclosure: um chevron abre/fecha uma região extra de detalhe abaixo do conteúdo, com aria-expanded. [toggle]- Ações rápidas na linha: Escolhe quais ações aparecem no slot Actions (reveladas ao passar o mouse no desktop / deslizar no toque), sem poluir a linha em repouso. [multi → Ver / Editar / Excluir / Arquivar / Fixar / Menu …]- Indicador de não-lido / novo: Marca a linha como não-lida ou nova com um marcador aditivo (ponto ou contagem), típico de listas de notificações. [select → Ponto / Contagem numérica / Nenhum]- Navegação por teclado no grupo: Ativa roving tabindex no Item:Group: setas ↑/↓ movem o foco entre linhas, Home/End vão ao início/fim — melhoria de a11y sem tocar no visual. [toggle]- Estado de carregamento (skeleton): Mostra placeholders shimmer no lugar de Media/Título/Descrição enquanto a linha carrega dados de forma assíncrona; estado funcional, como o loading do Button. [toggle]FAÇA:
- Use <twig:Nome> — a base é congelada, você é dono do template em templates/components/.
- Ligue apenas capacidades opt-in listadas (e_funcao=true); a aparência não muda ao ligá-las.
- Passe atributos extras (id, aria-*, name, data-*) via {{ attributes }}.
NÃO FAÇA:
- Não mude cor/fonte/cantos/espaçamento por instância — é decisão de BASE, na fonte única assets/styles/app.css.
- Não crie variante/fork para a mesma coisa — existe UMA base por componente.
- Não reimplemente o componente nem adicione toolchain Node.
TESTE ANTES DE MUDAR: "é função ou é base?" — função = capacidade opt-in; base = mude o token na fonte única (assets/styles/app.css), para todos.
A11Y (herdada da base): Congelado: o layout de linha flex (Media | Content | Actions, com Header/Footer em basis-full), os variants (default/outline/muted e suas bordas), os sizes (default/sm/xs com seus gaps e paddings), os cantos rounded-lg (e rounded-sm da Media imagem), a tipografia text-sm da linha, o Título font-medium line-clamp-1, a Descrição text-muted-foreground line-clamp-2, as cores/tokens (border-border, muted-foreground, hover:bg-muted no link), a transição de cor, o foco visível (focus-visible ring), o role="list" do Group, a semântica do Separator e o passthrough de {{ attributes }} e slots
LLM / MCP
Via MCP: tool get_component com {"id": "item"} · list_capabilities("item").
Spec crua: config/ds-specs/item.json · Conectar o MCP.
Spec machine-readable (JSON)
{
"$schema_version": "1.0",
"id": "item",
"component": "Item",
"eixo": "ui",
"particularidade": "Diferente do Card (peça isolada), o Item é uma LINHA de lista composável — Media + Content(Título/Descrição) + Actions — feita para se repetir dentro de um Item:Group (role=\"list\") e ser interagida linha a linha (notificações, ajustes, contatos, itens de estoque de EPI). Os enriquecedores giram em torno dessa natureza de linha-em-lista: selecionar, reordenar, expandir, agir por linha e navegar pelo grupo.",
"base_congelada": "Congelado: o layout de linha flex (Media | Content | Actions, com Header/Footer em basis-full), os variants (default/outline/muted e suas bordas), os sizes (default/sm/xs com seus gaps e paddings), os cantos rounded-lg (e rounded-sm da Media imagem), a tipografia text-sm da linha, o Título font-medium line-clamp-1, a Descrição text-muted-foreground line-clamp-2, as cores/tokens (border-border, muted-foreground, hover:bg-muted no link), a transição de cor, o foco visível (focus-visible ring), o role=\"list\" do Group, a semântica do Separator e o passthrough de {{ attributes }} e slots. Nenhuma capacidade altera fonte, cor, cantos ou espaçamento da base.",
"props": [
{
"name": "variant",
"type": "'default'|'outline'|'muted'",
"default": "default",
"description": "The visual style variant. Defaults to `default` #}"
},
{
"name": "size",
"type": "'default'|'sm'|'xs'",
"default": "default",
"description": "The item size. Defaults to `default` #}"
},
{
"name": "as",
"type": "'div'",
"default": "div",
"description": "The HTML tag to render. Defaults to `div` #}"
}
],
"capacidades": [
{
"id": "selecion-vel-na-linha",
"nome": "Selecionável na linha",
"descricao": "Transforma a linha em opção selecionável, inserindo um controle de seleção sem mexer nos slots de conteúdo.",
"controle": "select",
"opcoes": [
"Checkbox (seleção múltipla)",
"Radio (seleção única)",
"Nenhum"
],
"posicionavel": true,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "selecionar-tudo-contagem-grupo",
"nome": "Selecionar tudo + contagem (grupo)",
"descricao": "No nível do Item:Group, adiciona um controle 'selecionar tudo' e o texto 'N de M selecionados', em sincronia com a seleção por linha.",
"controle": "toggle",
"opcoes": [],
"posicionavel": true,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "arrastar-para-reordenar",
"nome": "Arrastar para reordenar",
"descricao": "Adiciona uma alça de arraste (grip) e o comportamento de reordenar as linhas dentro do Item:Group, persistindo a nova ordem.",
"controle": "toggle",
"opcoes": [],
"posicionavel": true,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "expans-vel-dobrar-detalhe",
"nome": "Expansível (dobrar detalhe)",
"descricao": "Torna a linha um disclosure: um chevron abre/fecha uma região extra de detalhe abaixo do conteúdo, com aria-expanded.",
"controle": "toggle",
"opcoes": [],
"posicionavel": true,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "a-es-r-pidas-na-linha",
"nome": "Ações rápidas na linha",
"descricao": "Escolhe quais ações aparecem no slot Actions (reveladas ao passar o mouse no desktop / deslizar no toque), sem poluir a linha em repouso.",
"controle": "multi",
"opcoes": [
"Ver",
"Editar",
"Excluir",
"Arquivar",
"Fixar",
"Menu …"
],
"posicionavel": false,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (multi). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "indicador-de-n-o-lido-novo",
"nome": "Indicador de não-lido / novo",
"descricao": "Marca a linha como não-lida ou nova com um marcador aditivo (ponto ou contagem), típico de listas de notificações.",
"controle": "select",
"opcoes": [
"Ponto",
"Contagem numérica",
"Nenhum"
],
"posicionavel": true,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "navega-o-por-teclado-no-grupo",
"nome": "Navegação por teclado no grupo",
"descricao": "Ativa roving tabindex no Item:Group: setas ↑/↓ movem o foco entre linhas, Home/End vão ao início/fim — melhoria de a11y sem tocar no visual.",
"controle": "toggle",
"opcoes": [],
"posicionavel": false,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
},
{
"id": "estado-de-carregamento-skeleton",
"nome": "Estado de carregamento (skeleton)",
"descricao": "Mostra placeholders shimmer no lugar de Media/Título/Descrição enquanto a linha carrega dados de forma assíncrona; estado funcional, como o loading do Button.",
"controle": "toggle",
"opcoes": [],
"posicionavel": false,
"e_funcao": true,
"como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/item; comportamento via controller Stimulus. Não altera a base."
}
],
"snippet_uso": "<twig:Item variant=\"default\" />",
"exemplo_demo": "<div class=\"flex w-full max-w-md flex-col gap-6\">\n <twig:Item variant=\"outline\">\n <twig:Item:Content>\n <twig:Item:Title>Basic Item</twig:Item:Title>\n <twig:Item:Description>\n A simple item with title and description.\n </twig:Item:Description>\n </twig:Item:Content>\n <twig:Item:Actions>\n <twig:Button variant=\"outline\" size=\"sm\">\n Action\n </twig:Button>\n </twig:Item:Actions>\n </twig:Item>\n <twig:Item variant=\"outline\" size=\"sm\" as=\"a\" href=\"#\">\n <twig:Item:Media>\n <twig:ux:icon name=\"lucide:badge-check\" class=\"size-5\" />\n </twig:Item:Media>\n <twig:Item:Content>\n <twig:Item:Title>Your profile has been verified.</twig:Item:Title>\n </twig:Item:Content>\n <twig:Item:Actions>\n <twig:ux:icon name=\"lucide:chevron-right\" class=\"size-4\" />\n </twig:Item:Actions>\n </twig:Item>\n</div>",
"regras": {
"faca": [
"Use <twig:Nome> — a base é congelada, você é dono do template em templates/components/.",
"Ligue apenas capacidades opt-in listadas (e_funcao=true); a aparência não muda ao ligá-las.",
"Passe atributos extras (id, aria-*, name, data-*) via {{ attributes }}."
],
"nao_faca": [
"Não mude cor/fonte/cantos/espaçamento por instância — é decisão de BASE, na fonte única assets/styles/app.css.",
"Não crie variante/fork para a mesma coisa — existe UMA base por componente.",
"Não reimplemente o componente nem adicione toolchain Node."
]
},
"a11y": "Congelado: o layout de linha flex (Media | Content | Actions, com Header/Footer em basis-full), os variants (default/outline/muted e suas bordas), os sizes (default/sm/xs com seus gaps e paddings), os cantos rounded-lg (e rounded-sm da Media imagem), a tipografia text-sm da linha, o Título font-medium line-clamp-1, a Descrição text-muted-foreground line-clamp-2, as cores/tokens (border-border, muted-foreground, hover:bg-muted no link), a transição de cor, o foco visível (focus-visible ring), o role=\"list\" do Group, a semântica do Separator e o passthrough de {{ attributes }} e slots",
"mcp": {
"tool": "get_component",
"args": {
"id": "item"
}
}
}