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
Capacidades 7
Conteúdo
Rótulo na linha
Insere um texto sobre a régua…
Ícone na linha
Coloca um ícone lucide sobre a…
Marcador temporal
Divisor de feed/timeline que formata um…
Orientação responsiva
Alterna horizontal↔vertical num breakpoint para separar…
Estilo tracejado/pontilhado ⚠️
Trocaria a linha sólida por tracejada/pontilhada.…
Comportamento
Fixar ao rolar (sticky)
Quando o divisor carrega um rótulo/data…
Revelar com animação
Anima a entrada da linha (cresce…
Claude Code
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
LLM / MCP
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"
}
}
}