Pular para o conteúdo

Label

templates/components/Label

O Label é o NOME ACESSÍVEL de um controle de formulário: um <label> que se associa a um campo (via for) e comunica as restrições do campo (obrigatório/opcional, ajuda, unidade, validade) ao usuário e à tecnologia assistiva. Sua base já é uma linha flex (items-center gap-2) pronta para receber ícone + texto, com estados disabled/peer-disabled fiados. Os enriquecedores exploram exatamente essa dupla natureza: ligar-se ao campo e qualificá-lo — sem tocar em fonte, cor, cantos ou espaçamento da base.

Base congelada

Conteúdo

Marcador de obrigatoriedade

Anexa um indicador de campo obrigatório…

Anexa um indicador de campo obrigatório (asterisco *) ou de campo opcional (texto '(opcional)'), com a semântica aria-required correspondente para leitores de tela. posicionável

Ícone do campo

Coloca um ícone lucide descrevendo o…

Coloca um ícone lucide descrevendo o tipo do campo (ex.: mail, calendar, lock) no slot gap-2 já existente da base. posicionável

Modo de associação ao controle

Escolhe como o label se liga…

Escolhe como o label se liga ao campo: explícita via atributo for=id, ou implícita envolvendo o próprio controle — capacidade puramente comportamental/a11y.

Contador de caracteres do campo

Lê ao vivo o comprimento do…

Lê ao vivo o comprimento do input associado e exibe 'n/máx' na linha do rótulo, atualizando conforme o usuário digita. posicionável

Qualificador secundário (unidade/dica)

Acrescenta um sufixo secundário em texto…

Acrescenta um sufixo secundário em texto atenuado, como unidade de medida '(kg)', '(cm)' ou restrição curta '(máx. 5)', útil em campos de EPI/SST. posicionável

Comportamento

Ajuda contextual (ícone + tooltip)

Adiciona um ícone de interrogação/info ao…

Adiciona um ícone de interrogação/info ao lado do rótulo que revela uma explicação curta do campo ao passar o mouse ou focar (tooltip acessível). posicionável

Truncar rótulo longo

Limita o texto a uma linha…

Limita o texto a uma linha com reticências em layouts densos (tabelas/grids) e mostra o rótulo completo no hover via title/tooltip.
Código gerado

Cole no Claude Code — ele acerta de primeira.

Label (UI) — Design System (Symfony UX Toolkit / shadcn)

BASE CONGELADA (não mude por instância): O elemento <label> com data-slot="label"; tipografia text-sm / leading-none / font-medium; layout em linha flex items-center gap-2; select-none; a cor herdada dos tokens (text-foreground); os estados de desabilitado já embutidos (group-data-[disabled=true]:opacity-50/pointer-events-none e peer-disabled:opacity-50/cursor-not-allowed); e a semântica a11y de rotular/associar um controle. Cantos, espaçamento (gap-2) e peso da fonte são imutáveis; toda capacidade entra como conteúdo aditivo dentro do slot ou como comportamento, nunca recolorindo/re-tipografando o texto-base.

USO: <twig:Label />

CAPACIDADES OPT-IN (ligue sem alterar o visual):
- Marcador de obrigatoriedade: Anexa um indicador de campo obrigatório (asterisco *) ou de campo opcional (texto '(opcional)'), com a semântica aria-required correspondente para leitores de tela. [select → Obrigatório (asterisco *) / Opcional (texto) / Nenhum]- Ajuda contextual (ícone + tooltip): Adiciona um ícone de interrogação/info ao lado do rótulo que revela uma explicação curta do campo ao passar o mouse ou focar (tooltip acessível). [toggle]- Ícone do campo: Coloca um ícone lucide descrevendo o tipo do campo (ex.: mail, calendar, lock) no slot gap-2 já existente da base. [text]- Modo de associação ao controle: Escolhe como o label se liga ao campo: explícita via atributo for=id, ou implícita envolvendo o próprio controle — capacidade puramente comportamental/a11y. [select → Explícita (for) / Implícita (envolve o controle)]- Contador de caracteres do campo: Lê ao vivo o comprimento do input associado e exibe 'n/máx' na linha do rótulo, atualizando conforme o usuário digita. [toggle]- Truncar rótulo longo: Limita o texto a uma linha com reticências em layouts densos (tabelas/grids) e mostra o rótulo completo no hover via title/tooltip. [toggle]- Qualificador secundário (unidade/dica): Acrescenta um sufixo secundário em texto atenuado, como unidade de medida '(kg)', '(cm)' ou restrição curta '(máx. 5)', útil em campos de EPI/SST. [text]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): e a semântica a11y de rotular/associar um controle

Via MCP: tool get_component com {"id": "label"} · list_capabilities("label").

Spec crua: config/ds-specs/label.json · Conectar o MCP.

Spec machine-readable (JSON)

{
    "$schema_version": "1.0",
    "id": "label",
    "component": "Label",
    "eixo": "ui",
    "particularidade": "O Label é o NOME ACESSÍVEL de um controle de formulário: um &lt;label&gt; que se associa a um campo (via for) e comunica as restrições do campo (obrigatório/opcional, ajuda, unidade, validade) ao usuário e à tecnologia assistiva. Sua base já é uma linha flex (items-center gap-2) pronta para receber ícone + texto, com estados disabled/peer-disabled fiados. Os enriquecedores exploram exatamente essa dupla natureza: ligar-se ao campo e qualificá-lo — sem tocar em fonte, cor, cantos ou espaçamento da base.",
    "base_congelada": "O elemento &lt;label&gt; com data-slot=\"label\"; tipografia text-sm / leading-none / font-medium; layout em linha flex items-center gap-2; select-none; a cor herdada dos tokens (text-foreground); os estados de desabilitado já embutidos (group-data-[disabled=true]:opacity-50/pointer-events-none e peer-disabled:opacity-50/cursor-not-allowed); e a semântica a11y de rotular/associar um controle. Cantos, espaçamento (gap-2) e peso da fonte são imutáveis; toda capacidade entra como conteúdo aditivo dentro do slot ou como comportamento, nunca recolorindo/re-tipografando o texto-base.",
    "props": [],
    "capacidades": [
        {
            "id": "marcador-de-obrigatoriedade",
            "nome": "Marcador de obrigatoriedade",
            "descricao": "Anexa um indicador de campo obrigatório (asterisco *) ou de campo opcional (texto '(opcional)'), com a semântica aria-required correspondente para leitores de tela.",
            "controle": "select",
            "opcoes": [
                "Obrigatório (asterisco *)",
                "Opcional (texto)",
                "Nenhum"
            ],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "ajuda-contextual-cone-tooltip",
            "nome": "Ajuda contextual (ícone + tooltip)",
            "descricao": "Adiciona um ícone de interrogação/info ao lado do rótulo que revela uma explicação curta do campo ao passar o mouse ou focar (tooltip acessível).",
            "controle": "toggle",
            "opcoes": [],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "cone-do-campo",
            "nome": "Ícone do campo",
            "descricao": "Coloca um ícone lucide descrevendo o tipo do campo (ex.: mail, calendar, lock) no slot gap-2 já existente da base.",
            "controle": "text",
            "opcoes": [],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (text). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "modo-de-associa-o-ao-controle",
            "nome": "Modo de associação ao controle",
            "descricao": "Escolhe como o label se liga ao campo: explícita via atributo for=id, ou implícita envolvendo o próprio controle — capacidade puramente comportamental/a11y.",
            "controle": "select",
            "opcoes": [
                "Explícita (for)",
                "Implícita (envolve o controle)"
            ],
            "posicionavel": false,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "contador-de-caracteres-do-campo",
            "nome": "Contador de caracteres do campo",
            "descricao": "Lê ao vivo o comprimento do input associado e exibe 'n/máx' na linha do rótulo, atualizando conforme o usuário digita.",
            "controle": "toggle",
            "opcoes": [],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "truncar-r-tulo-longo",
            "nome": "Truncar rótulo longo",
            "descricao": "Limita o texto a uma linha com reticências em layouts densos (tabelas/grids) e mostra o rótulo completo no hover via title/tooltip.",
            "controle": "toggle",
            "opcoes": [],
            "posicionavel": false,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "qualificador-secund-rio-unidade-dica",
            "nome": "Qualificador secundário (unidade/dica)",
            "descricao": "Acrescenta um sufixo secundário em texto atenuado, como unidade de medida '(kg)', '(cm)' ou restrição curta '(máx. 5)', útil em campos de EPI/SST.",
            "controle": "text",
            "opcoes": [],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (text). Ligue no configurador em /vitrine/ui/label; comportamento via controller Stimulus. Não altera a base."
        }
    ],
    "snippet_uso": "<twig:Label />",
    "exemplo_demo": "<div class=\"flex gap-2\">\n    <twig:Checkbox id=\"terms\" />\n    <twig:Label for=\"terms\">Accept terms and conditions</twig:Label>\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": "e a semântica a11y de rotular/associar um controle",
    "mcp": {
        "tool": "get_component",
        "args": {
            "id": "label"
        }
    },
    "props_nota": "Sem props próprias declaradas: a base repassa atributos nativos via {{ attributes }} (id, name, type, value, aria-*, data-*). Props específicas, quando existem, ficam nos subcomponentes."
}