Pular para o conteúdo

Separator

templates/components/Separator

O Separator é uma régua divisória de 1px em bg-border, puramente presentacional e sem conteúdo próprio: sua função é separar/agrupar sem competir visualmente. Por ser tão mínimo, os enriquecedores só podem adicionar significado (rótulo, ícone, marcador de data) ou comportamento (sticky, responsivo, animar entrada) SOBRE a linha — nunca engrossá-la, colori-la, recantoá-la ou mudar seu respiro.

Base congelada

shadcn/ui
The Foundation for your Design System
A set of beautifully designed components that you can customize, extend, and build on.

Conteúdo

Rótulo na linha

Insere um texto sobre a régua…

Insere um texto sobre a régua (ex.: 'OU' no login, 'Dados do EPI' entre seções de formulário) com a linha continuando dos dois lados; o texto herda tipografia/cor da base. posicionável

Ícone na linha

Coloca um ícone lucide sobre a…

Coloca um ícone lucide sobre a régua, sozinho ou junto ao rótulo (ponto, chevron, estrela…), como marcador de agrupamento — sem alterar a espessura da linha. posicionável

Marcador temporal

Divisor de feed/timeline que formata um…

Divisor de feed/timeline que formata um valor via locale em 'Hoje/Ontem' ou data absoluta, agrupando itens por período em listas longas (ex.: entregas de EPI por dia).

Orientação responsiva

Alterna horizontal↔vertical num breakpoint para separar…

Alterna horizontal↔vertical num breakpoint para separar blocos que empilham no mobile e ficam lado a lado no desktop, reusando a prop de orientação da base — sem mexer em tokens.

Estilo tracejado/pontilhado ⚠️

Trocaria a linha sólida por tracejada/pontilhada.…

Trocaria a linha sólida por tracejada/pontilhada. REPROVADO no teste 'é função ou é base?': altera o DESENHO da régua, então é decisão de BASE (muda para todos em app.css), nunca enricher por instância. Listado como fronteira honesta.

Comportamento

Fixar ao rolar (sticky)

Quando o divisor carrega um rótulo/data…

Quando o divisor carrega um rótulo/data de grupo, ele gruda no topo enquanto sua seção rola — mantém o contexto do agrupamento visível em listas longas. Comportamento de scroll, visual idêntico.

Revelar com animação

Anima a entrada da linha (cresce…

Anima a entrada da linha (cresce do centro ou fade-in) ao montar ou ao entrar na viewport; o estado final é pixel-a-pixel idêntico à base congelada.
Código gerado

Cole no Claude Code — ele acerta de primeira.

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

BASE CONGELADA (não mude por instância): A própria linha e sua semântica: espessura 1px (h-px / w-px), cor bg-border (token único), preenchimento w-full / self-stretch, orientação horizontal|vertical (prop de base, não enricher), e a a11y — role separator|none + aria-orientation via a prop decorative. Qualquer texto/ícone adicionado herda os tokens da base (muted-foreground, text-sm); nada de fonte, cor, cantos ou espaçamento muda por instância.

USO: <twig:Separator />

CAPACIDADES OPT-IN (ligue sem alterar o visual):
- Rótulo na linha: Insere um texto sobre a régua (ex.: 'OU' no login, 'Dados do EPI' entre seções de formulário) com a linha continuando dos dois lados; o texto herda tipografia/cor da base. [text]- Ícone na linha: Coloca um ícone lucide sobre a régua, sozinho ou junto ao rótulo (ponto, chevron, estrela…), como marcador de agrupamento — sem alterar a espessura da linha. [select → Ponto (dot) / Chevron / Estrela / Losango / Mais (+) / Barra (/)]- Marcador temporal: Divisor de feed/timeline que formata um valor via locale em 'Hoje/Ontem' ou data absoluta, agrupando itens por período em listas longas (ex.: entregas de EPI por dia). [select → Data absoluta (03 jul 2026) / Relativo (Hoje / Ontem) / Data + hora]- Orientação responsiva: Alterna horizontal↔vertical num breakpoint para separar blocos que empilham no mobile e ficam lado a lado no desktop, reusando a prop de orientação da base — sem mexer em tokens. [select → Horizontal → vertical (≥ md) / Vertical → horizontal (< md)]- Fixar ao rolar (sticky): Quando o divisor carrega um rótulo/data de grupo, ele gruda no topo enquanto sua seção rola — mantém o contexto do agrupamento visível em listas longas. Comportamento de scroll, visual idêntico. [toggle]- Revelar com animação: Anima a entrada da linha (cresce do centro ou fade-in) ao montar ou ao entrar na viewport; o estado final é pixel-a-pixel idêntico à base congelada. [select → Nenhuma / Crescer do centro / Esmaecer (fade-in)]- Estilo tracejado/pontilhado: Trocaria a linha sólida por tracejada/pontilhada. REPROVADO no teste 'é função ou é base?': altera o DESENHO da régua, então é decisão de BASE (muda para todos em app.css), nunca enricher por instância. Listado como fronteira honesta. [select → Sólida (base) / Tracejada / Pontilhada]  (⚠️ borderline: revisar se não é decisão de base)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): A própria linha e sua semântica: espessura 1px (h-px / w-px), cor bg-border (token único), preenchimento w-full / self-stretch, orientação horizontal|vertical (prop de base, não enricher), e a a11y — role separator|none + aria-orientation via a prop decorative

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

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

Spec machine-readable (JSON)

{
    "$schema_version": "1.0",
    "id": "separator",
    "component": "Separator",
    "eixo": "ui",
    "particularidade": "O Separator é uma régua divisória de 1px em bg-border, puramente presentacional e sem conteúdo próprio: sua função é separar/agrupar sem competir visualmente. Por ser tão mínimo, os enriquecedores só podem adicionar significado (rótulo, ícone, marcador de data) ou comportamento (sticky, responsivo, animar entrada) SOBRE a linha — nunca engrossá-la, colori-la, recantoá-la ou mudar seu respiro.",
    "base_congelada": "A própria linha e sua semântica: espessura 1px (h-px / w-px), cor bg-border (token único), preenchimento w-full / self-stretch, orientação horizontal|vertical (prop de base, não enricher), e a a11y — role separator|none + aria-orientation via a prop decorative. Qualquer texto/ícone adicionado herda os tokens da base (muted-foreground, text-sm); nada de fonte, cor, cantos ou espaçamento muda por instância.",
    "props": [
        {
            "name": "orientation",
            "type": "'horizontal'|'vertical'",
            "default": "horizontal",
            "description": "The separator orientation. Defaults to `horizontal` #}"
        },
        {
            "name": "decorative",
            "type": "boolean",
            "default": "true",
            "description": "Whether the separator is purely decorative (not semantic). Defaults to `true` #}"
        }
    ],
    "capacidades": [
        {
            "id": "r-tulo-na-linha",
            "nome": "Rótulo na linha",
            "descricao": "Insere um texto sobre a régua (ex.: 'OU' no login, 'Dados do EPI' entre seções de formulário) com a linha continuando dos dois lados; o texto herda tipografia/cor da base.",
            "controle": "text",
            "opcoes": [],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (text). Ligue no configurador em /vitrine/ui/separator; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "cone-na-linha",
            "nome": "Ícone na linha",
            "descricao": "Coloca um ícone lucide sobre a régua, sozinho ou junto ao rótulo (ponto, chevron, estrela…), como marcador de agrupamento — sem alterar a espessura da linha.",
            "controle": "select",
            "opcoes": [
                "Ponto (dot)",
                "Chevron",
                "Estrela",
                "Losango",
                "Mais (+)",
                "Barra (/)"
            ],
            "posicionavel": true,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/separator; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "marcador-temporal",
            "nome": "Marcador temporal",
            "descricao": "Divisor de feed/timeline que formata um valor via locale em 'Hoje/Ontem' ou data absoluta, agrupando itens por período em listas longas (ex.: entregas de EPI por dia).",
            "controle": "select",
            "opcoes": [
                "Data absoluta (03 jul 2026)",
                "Relativo (Hoje / Ontem)",
                "Data + hora"
            ],
            "posicionavel": false,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/separator; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "orienta-o-responsiva",
            "nome": "Orientação responsiva",
            "descricao": "Alterna horizontal↔vertical num breakpoint para separar blocos que empilham no mobile e ficam lado a lado no desktop, reusando a prop de orientação da base — sem mexer em tokens.",
            "controle": "select",
            "opcoes": [
                "Horizontal → vertical (≥ md)",
                "Vertical → horizontal (< md)"
            ],
            "posicionavel": false,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/separator; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "fixar-ao-rolar-sticky",
            "nome": "Fixar ao rolar (sticky)",
            "descricao": "Quando o divisor carrega um rótulo/data de grupo, ele gruda no topo enquanto sua seção rola — mantém o contexto do agrupamento visível em listas longas. Comportamento de scroll, visual idêntico.",
            "controle": "toggle",
            "opcoes": [],
            "posicionavel": false,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (toggle). Ligue no configurador em /vitrine/ui/separator; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "revelar-com-anima-o",
            "nome": "Revelar com animação",
            "descricao": "Anima a entrada da linha (cresce do centro ou fade-in) ao montar ou ao entrar na viewport; o estado final é pixel-a-pixel idêntico à base congelada.",
            "controle": "select",
            "opcoes": [
                "Nenhuma",
                "Crescer do centro",
                "Esmaecer (fade-in)"
            ],
            "posicionavel": false,
            "e_funcao": true,
            "como_plugar": "Capacidade opt-in (select). Ligue no configurador em /vitrine/ui/separator; comportamento via controller Stimulus. Não altera a base."
        },
        {
            "id": "estilo-tracejado-pontilhado",
            "nome": "Estilo tracejado/pontilhado",
            "descricao": "Trocaria a linha sólida por tracejada/pontilhada. REPROVADO no teste 'é função ou é base?': altera o DESENHO da régua, então é decisão de BASE (muda para todos em app.css), nunca enricher por instância. Listado como fronteira honesta.",
            "controle": "select",
            "opcoes": [
                "Sólida (base)",
                "Tracejada",
                "Pontilhada"
            ],
            "posicionavel": false,
            "e_funcao": false,
            "como_plugar": "REPROVADO no teste 'é função ou é base' — NÃO plugar como capacidade. É decisão de BASE: mude o token na fonte única assets/styles/app.css, valendo para TODOS os componentes."
        }
    ],
    "snippet_uso": "<twig:Separator />",
    "exemplo_demo": "<div class=\"flex max-w-sm flex-col gap-4 text-sm\">\n    <div class=\"flex flex-col gap-1.5\">\n        <div class=\"leading-none font-medium\">shadcn/ui</div>\n        <div class=\"text-muted-foreground\">The Foundation for your Design System</div>\n    </div>\n    <twig:Separator />\n    <div>A set of beautifully designed components that you can customize, extend, and build on.</div>\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": "A própria linha e sua semântica: espessura 1px (h-px / w-px), cor bg-border (token único), preenchimento w-full / self-stretch, orientação horizontal|vertical (prop de base, não enricher), e a a11y — role separator|none + aria-orientation via a prop decorative",
    "mcp": {
        "tool": "get_component",
        "args": {
            "id": "separator"
        }
    }
}