@softize/opus 12.11.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/bin/lib/check.mjs +2 -7
- package/bin/lib/copy.mjs +1 -5
- package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +93 -10
- package/docs/adr/0007-toast-actions-form-an-ordered-collection.md +63 -0
- package/docs/adr/0008-hierarchical-navigation-is-composed-at-the-consumer-boundary.md +71 -0
- package/docs/radius-scale.md +1 -1
- package/package.json +1 -1
- package/registry/skills/maintain-opus-docs/SKILL.md +83 -0
- package/registry/skills/maintain-opus-docs/agents/openai.yaml +4 -0
- package/registry/skills/maintain-opus-docs/references/editorial-standard.md +85 -0
- package/registry/skills/maintain-opus-docs/references/evaluations.md +34 -0
- package/registry/skills/maintain-opus-docs/scripts/audit-docs.mjs +81 -0
- package/src/ui/components/patterns/confirm.tsx +140 -40
- package/src/ui/components/patterns/list.tsx +35 -40
- package/src/ui/components/patterns/page-state.tsx +2 -2
- package/src/ui/components/patterns/sidebar.tsx +26 -26
- package/src/ui/components/patterns/trigger.tsx +25 -22
- package/src/ui/components/primitives/alert.tsx +3 -3
- package/src/ui/components/primitives/dialog.tsx +196 -39
- package/src/ui/components/primitives/drawer.tsx +8 -5
- package/src/ui/components/primitives/empty.tsx +3 -3
- package/src/ui/components/primitives/item.tsx +3 -3
- package/src/ui/components/primitives/sonner.tsx +187 -8
- package/src/ui/docs/DocBrowser.tsx +102 -23
- package/src/ui/docs/content/accordion.md +22 -16
- package/src/ui/docs/content/action-form-card.md +8 -8
- package/src/ui/docs/content/action-form-dialog.md +9 -9
- package/src/ui/docs/content/action-form.md +28 -34
- package/src/ui/docs/content/action-list-dialog.md +11 -6
- package/src/ui/docs/content/action-list.md +64 -39
- package/src/ui/docs/content/action-trigger.md +21 -14
- package/src/ui/docs/content/action-view.md +8 -8
- package/src/ui/docs/content/actions.md +9 -9
- package/src/ui/docs/content/ai.md +3 -3
- package/src/ui/docs/content/alert.md +14 -12
- package/src/ui/docs/content/aspect-ratio.md +4 -4
- package/src/ui/docs/content/audit.md +2 -2
- package/src/ui/docs/content/auth.md +3 -3
- package/src/ui/docs/content/avatar.md +34 -14
- package/src/ui/docs/content/badge.md +3 -3
- package/src/ui/docs/content/breadcrumb.md +13 -8
- package/src/ui/docs/content/button.md +81 -6
- package/src/ui/docs/content/calendar.md +5 -5
- package/src/ui/docs/content/card.md +1 -1
- package/src/ui/docs/content/carousel.md +16 -11
- package/src/ui/docs/content/chat.md +3 -3
- package/src/ui/docs/content/checkbox.md +7 -7
- package/src/ui/docs/content/cli.md +5 -5
- package/src/ui/docs/content/collapsible.md +8 -8
- package/src/ui/docs/content/command.md +16 -8
- package/src/ui/docs/content/composer.md +2 -2
- package/src/ui/docs/content/content.md +2 -2
- package/src/ui/docs/content/copyable.md +4 -3
- package/src/ui/docs/content/customization.md +5 -5
- package/src/ui/docs/content/cycle.md +3 -3
- package/src/ui/docs/content/data-state.md +11 -12
- package/src/ui/docs/content/data.md +26 -33
- package/src/ui/docs/content/detail.md +3 -3
- package/src/ui/docs/content/dialog.md +339 -31
- package/src/ui/docs/content/dictionary-value.md +8 -8
- package/src/ui/docs/content/dock.md +3 -3
- package/src/ui/docs/content/drawer.md +27 -14
- package/src/ui/docs/content/empty-value.md +2 -2
- package/src/ui/docs/content/empty.md +19 -12
- package/src/ui/docs/content/events.md +4 -4
- package/src/ui/docs/content/field.md +34 -12
- package/src/ui/docs/content/getting-started.md +1 -1
- package/src/ui/docs/content/icon-picker.md +8 -4
- package/src/ui/docs/content/input-otp.md +20 -12
- package/src/ui/docs/content/input.md +121 -9
- package/src/ui/docs/content/item.md +27 -13
- package/src/ui/docs/content/kbd.md +19 -11
- package/src/ui/docs/content/label.md +5 -3
- package/src/ui/docs/content/log.md +4 -4
- package/src/ui/docs/content/markdown.md +7 -6
- package/src/ui/docs/content/mcp.md +13 -15
- package/src/ui/docs/content/menu.md +34 -16
- package/src/ui/docs/content/observability.md +2 -2
- package/src/ui/docs/content/page.md +51 -6
- package/src/ui/docs/content/pagination.md +22 -17
- package/src/ui/docs/content/popover.md +16 -8
- package/src/ui/docs/content/progress.md +7 -5
- package/src/ui/docs/content/queue.md +5 -5
- package/src/ui/docs/content/radio-group.md +20 -12
- package/src/ui/docs/content/router.md +11 -6
- package/src/ui/docs/content/scheduler.md +4 -5
- package/src/ui/docs/content/scroll-area.md +12 -7
- package/src/ui/docs/content/select.md +42 -29
- package/src/ui/docs/content/separator.md +5 -5
- package/src/ui/docs/content/sidebar.md +323 -54
- package/src/ui/docs/content/skeleton.md +3 -2
- package/src/ui/docs/content/slider.md +8 -7
- package/src/ui/docs/content/spinner.md +8 -8
- package/src/ui/docs/content/split.md +8 -5
- package/src/ui/docs/content/storage.md +6 -8
- package/src/ui/docs/content/switch.md +8 -7
- package/src/ui/docs/content/table.md +13 -3
- package/src/ui/docs/content/tabs.md +28 -14
- package/src/ui/docs/content/testing.md +9 -11
- package/src/ui/docs/content/textarea.md +5 -4
- package/src/ui/docs/content/toast.md +47 -13
- package/src/ui/docs/content/toggle.md +75 -7
- package/src/ui/docs/content/tokens.md +3 -3
- package/src/ui/docs/content/tooltip.md +19 -11
- package/src/ui/docs/content/truncate.md +7 -8
- package/src/ui/docs/content/ui.md +10 -9
- package/src/ui/docs/content/upgrading.md +7 -8
- package/src/ui/docs/registry.tsx +20 -37
- package/src/ui/meta.ts +64 -94
- package/src/ui/react.tsx +15 -16
- package/src/ui/theme.css +50 -0
- package/src/ui/components/primitives/alert-dialog.tsx +0 -192
- package/src/ui/docs/content/alert-dialog.md +0 -73
- package/src/ui/docs/content/button-group.md +0 -71
- package/src/ui/docs/content/confirm.md +0 -120
- package/src/ui/docs/content/input-group.md +0 -79
- package/src/ui/docs/content/page-state.md +0 -45
- package/src/ui/docs/content/toggle-group.md +0 -81
package/src/ui/meta.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @softize/opus/ui/meta — o mapa CENTRAL de `meta` de todos os componentes.
|
|
3
3
|
*
|
|
4
|
-
* O componente portado é byte-fiel ao shadcn (sem `meta` co-localizado,
|
|
4
|
+
* O componente portado é byte-fiel ao shadcn (sem `meta` co-localizado, para re-sincronizar
|
|
5
5
|
* limpo); o metadado de descoberta (whenToUse/ancestry) mora AQUI, fora do arquivo. Quem
|
|
6
6
|
* precisa do meta em RUNTIME — a doc de UI (DocBrowser), o manifesto, ferramentas — importa
|
|
7
7
|
* este subpath explicitamente (`@softize/opus/ui/meta`); o barrel de runtime (react.tsx) não
|
|
@@ -15,37 +15,37 @@ export const componentMeta = {
|
|
|
15
15
|
name: "content",
|
|
16
16
|
ancestry: "opus",
|
|
17
17
|
whenToUse:
|
|
18
|
-
"
|
|
18
|
+
"Organize uma região nomeada dentro de uma página ou de outra superfície. Use as propriedades de Content no caso comum e componha seus slots quando precisar controlar a estrutura. Para o cabeçalho principal da tela, use Page.",
|
|
19
19
|
},
|
|
20
20
|
ask: {
|
|
21
21
|
name: "ask",
|
|
22
22
|
ancestry: "opus",
|
|
23
23
|
whenToUse:
|
|
24
|
-
"
|
|
24
|
+
"Colete respostas para uma a quatro perguntas estruturadas, com opções de escolha única, múltipla ou texto livre. O consumidor controla as respostas e conecta o envio ao canal apropriado; Ask não faz transporte nem persistência.",
|
|
25
25
|
},
|
|
26
26
|
alert: {
|
|
27
27
|
name: "alert",
|
|
28
28
|
ancestry: "opus",
|
|
29
29
|
whenToUse:
|
|
30
|
-
"Aviso inline no fluxo da página — `context` declara neutral/info/success/warning/danger e `variant` escolhe subtle/outline (ADR 0006). Forma curta: `<Alert title description icon context />`; para conteúdo rico, componha AlertMedia + AlertHeader (AlertTitle e AlertDescription) + AlertActions. A mídia
|
|
30
|
+
"Aviso inline no fluxo da página — `context` declara neutral/info/success/warning/danger e `variant` escolhe subtle/outline (ADR 0006). Forma curta: `<Alert title description icon context />`; para conteúdo rico, componha AlertMedia + AlertHeader (AlertTitle e AlertDescription) + AlertActions. A mídia mantém uma moldura tonal quadrada, mesmo com descrição multilinha. O texto comunica o significado sem depender só da cor. Para interromper cobrando decisão, use `dialog.confirm()`; para recado passageiro, `toast`.",
|
|
31
31
|
},
|
|
32
32
|
badge: {
|
|
33
33
|
name: "badge",
|
|
34
34
|
ancestry: "shadcn",
|
|
35
35
|
whenToUse:
|
|
36
|
-
"Rótulo curto de status/categoria. `context` declara neutral/primary/info/success/warning/danger; `variant` escolhe solid/subtle/outline (ADR 0006). Não-interativo — para clique, use Button ou `asChild`
|
|
36
|
+
"Rótulo curto de status/categoria. `context` declara neutral/primary/info/success/warning/danger; `variant` escolhe solid/subtle/outline (ADR 0006). Não-interativo — para clique, use Button ou `asChild` em um <a>. Valor de dicionário com papel declarado usa DictionaryValue em vez de escolher contexto ou variante na tela.",
|
|
37
37
|
},
|
|
38
38
|
"empty-value": {
|
|
39
39
|
name: "empty-value",
|
|
40
40
|
ancestry: "opus",
|
|
41
41
|
whenToUse:
|
|
42
|
-
"
|
|
42
|
+
"Mostre valores ausentes de forma consistente e acessível. O modo compacto usa um travessão visual e preserva “Não informado” para leitores de tela; `label` permite declarar uma ausência específica do domínio. Zero e falso continuam sendo valores.",
|
|
43
43
|
},
|
|
44
44
|
"dictionary-value": {
|
|
45
45
|
name: "dictionary-value",
|
|
46
46
|
ancestry: "opus",
|
|
47
47
|
whenToUse:
|
|
48
|
-
"
|
|
48
|
+
"Apresente um valor de `t.dict` conforme a semântica declarada no próprio dicionário. Classificações, status, estágios e valores simples recebem tratamentos previsíveis sem inferências pelo nome; use as propriedades de apresentação apenas para exceções explícitas.",
|
|
49
49
|
},
|
|
50
50
|
dot: {
|
|
51
51
|
name: "dot",
|
|
@@ -63,19 +63,19 @@ export const componentMeta = {
|
|
|
63
63
|
name: "dock",
|
|
64
64
|
ancestry: "opus",
|
|
65
65
|
whenToUse:
|
|
66
|
-
"
|
|
66
|
+
"Ancore ferramentas a uma superfície de trabalho, como canvas, editor ou prévia. Agrupe ações relacionadas com DockGroup e mantenha o estado da superfície em SurfaceStatus. Para ações da página, use Page; para opções exclusivas, use ToggleGroup.",
|
|
67
67
|
},
|
|
68
68
|
button: {
|
|
69
69
|
name: "button",
|
|
70
70
|
ancestry: "shadcn",
|
|
71
71
|
whenToUse:
|
|
72
|
-
|
|
72
|
+
"Inicie uma ação com um controle clicável. Use `context` para o significado, `variant` para o tratamento visual e `size` para a escala; `busy` comunica o andamento e impede um novo acionamento. Para ações relacionadas, use ButtonGroup.",
|
|
73
73
|
},
|
|
74
74
|
card: {
|
|
75
75
|
name: "card",
|
|
76
76
|
ancestry: "shadcn",
|
|
77
77
|
whenToUse:
|
|
78
|
-
|
|
78
|
+
"Agrupe conteúdo relacionado em uma superfície delimitada. Use Card diretamente para um bloco simples ou componha cabeçalho, corpo e rodapé quando houver hierarquia e ações. CardContent permanece apenas como alias temporário de compatibilidade.",
|
|
79
79
|
},
|
|
80
80
|
"metric-card": {
|
|
81
81
|
name: "metric-card",
|
|
@@ -87,85 +87,85 @@ export const componentMeta = {
|
|
|
87
87
|
name: "chat",
|
|
88
88
|
ancestry: "opus",
|
|
89
89
|
whenToUse:
|
|
90
|
-
"
|
|
90
|
+
"Monte uma conversa completa com mensagens, composição, carregamento e rolagem automática. A propriedade `send` aceita resposta integral ou streaming de eventos; use Composer quando precisar apenas da entrada de texto. Defina uma altura para o contêiner.",
|
|
91
91
|
},
|
|
92
92
|
checkbox: {
|
|
93
93
|
name: "checkbox",
|
|
94
94
|
ancestry: "shadcn",
|
|
95
95
|
whenToUse:
|
|
96
|
-
"Caixa de marcação booleana (Radix). Controlado por `checked`/`onCheckedChange`. Parear com Label.
|
|
96
|
+
"Caixa de marcação booleana (Radix). Controlado por `checked`/`onCheckedChange`. Parear com Label. Para escolha única de várias opções, use Select/RadioGroup.",
|
|
97
97
|
},
|
|
98
98
|
"icon-picker": {
|
|
99
99
|
name: "icon-picker",
|
|
100
100
|
ancestry: "opus",
|
|
101
101
|
whenToUse:
|
|
102
|
-
"
|
|
102
|
+
"Permita escolher um ícone por uma lista pesquisável. O valor é o nome do ícone em kebab-case; use a mesma paleta ao renderizá-lo e forneça `icons` quando o produto precisar de um vocabulário próprio.",
|
|
103
103
|
},
|
|
104
104
|
command: {
|
|
105
105
|
name: "command",
|
|
106
106
|
ancestry: "shadcn",
|
|
107
107
|
whenToUse:
|
|
108
|
-
"Lista filtrável com teclado (cmdk) — base de command-palettes. Use CommandDialog
|
|
108
|
+
"Lista filtrável com teclado (cmdk) — base de command-palettes. Use CommandDialog para palette modal (⌘K). Para escolha simples, use o Select direto.",
|
|
109
109
|
},
|
|
110
110
|
composer: {
|
|
111
111
|
name: "composer",
|
|
112
112
|
ancestry: "opus",
|
|
113
113
|
whenToUse:
|
|
114
|
-
"
|
|
114
|
+
"Receba texto para envio sem montar uma conversa completa. Enter envia, Shift+Enter quebra a linha e `actions` acrescenta uma faixa para seletores relacionados. O componente é controlado; use Chat quando também precisar de mensagens e estado da conversa.",
|
|
115
115
|
},
|
|
116
116
|
"content-header": {
|
|
117
117
|
name: "content-header",
|
|
118
118
|
ancestry: "opus",
|
|
119
119
|
whenToUse:
|
|
120
|
-
"
|
|
120
|
+
"Estruture o cabeçalho de um Content com título, descrição, metadados e ações. No caso comum, declare esses valores diretamente em Content; componha ContentHeader apenas quando precisar controlar a anatomia.",
|
|
121
121
|
},
|
|
122
122
|
copyable: {
|
|
123
123
|
name: "copyable",
|
|
124
124
|
ancestry: "opus",
|
|
125
125
|
whenToUse:
|
|
126
|
-
"
|
|
126
|
+
"Copie identificadores, tokens, slugs ou URLs com confirmação visual. Sem filhos, Copyable funciona como botão de ícone; com filhos, mantém um rótulo visível. Em ambientes sem acesso à área de transferência, a ação não produz efeito.",
|
|
127
127
|
},
|
|
128
128
|
dialog: {
|
|
129
129
|
name: "dialog",
|
|
130
|
-
ancestry: "
|
|
130
|
+
ancestry: "opus",
|
|
131
131
|
whenToUse:
|
|
132
|
-
|
|
132
|
+
"Abra conteúdo ou uma tarefa em uma janela modal com foco contido. Use o modo padrão quando a superfície puder ser dispensada e `mode=\"alert\"` quando exigir resposta explícita. Para o caso imperativo comum, use `dialog.alert`, `dialog.confirm`, `dialog.prompt` ou `dialog.choose`. Distribua conteúdo próprio entre cabeçalho, corpo rolável e rodapé de ações.",
|
|
133
133
|
},
|
|
134
134
|
input: {
|
|
135
135
|
name: "input",
|
|
136
136
|
ancestry: "shadcn",
|
|
137
137
|
whenToUse:
|
|
138
|
-
"
|
|
138
|
+
"Receba texto em uma única linha com os atributos nativos de `input`. Use `icon` para identidade e `trailing` para uma ação no fim do campo; associe uma Label. Quando precisar combinar múltiplos adornos ou controles na mesma moldura, use InputGroup.",
|
|
139
139
|
},
|
|
140
140
|
label: {
|
|
141
141
|
name: "label",
|
|
142
142
|
ancestry: "shadcn",
|
|
143
143
|
whenToUse:
|
|
144
|
-
"Rótulo acessível de um campo. `htmlFor` aponta
|
|
144
|
+
"Rótulo acessível de um campo. `htmlFor` aponta para o id do controle. Parear com Input/Textarea/Select.",
|
|
145
145
|
},
|
|
146
146
|
markdown: {
|
|
147
147
|
name: "markdown",
|
|
148
148
|
ancestry: "opus",
|
|
149
149
|
whenToUse:
|
|
150
|
-
"
|
|
150
|
+
"Renderize Markdown como HTML semântico com a tipografia do tema. HTML recebido no texto é escapado, por isso o componente pode apresentar conteúdo de pessoas ou modelos com segurança. Para código com destaque e cópia, use CodeBlock.",
|
|
151
151
|
},
|
|
152
152
|
menu: {
|
|
153
153
|
name: "menu",
|
|
154
154
|
ancestry: "opus",
|
|
155
155
|
whenToUse:
|
|
156
|
-
'O menu de ações da casa: lista flutuante ancorada
|
|
156
|
+
'O menu de ações da casa: lista flutuante ancorada em um gatilho (Radix DropdownMenu). Compõe Menu > MenuTrigger + MenuContent e seus itens. `context="danger"` sinaliza item com consequência perigosa; `destructive` permanece alias de migração. Para escolher um valor, use Select; para busca por teclado, Command; para conteúdo livre ancorado, Popover.',
|
|
157
157
|
},
|
|
158
158
|
popover: {
|
|
159
159
|
name: "popover",
|
|
160
160
|
ancestry: "shadcn",
|
|
161
161
|
whenToUse:
|
|
162
|
-
"Painel flutuante ancorado
|
|
162
|
+
"Painel flutuante ancorado em um gatilho, sem modal (Radix). Para conteúdo livre (form curto, detalhes). Use PopoverHeader/PopoverTitle/PopoverDescription para estruturar. Para lista de ações, use Menu; para modal, Dialog.",
|
|
163
163
|
},
|
|
164
164
|
select: {
|
|
165
165
|
name: "select",
|
|
166
166
|
ancestry: "opus",
|
|
167
167
|
whenToUse:
|
|
168
|
-
|
|
168
|
+
"Ofereça escolhas a partir de uma lista declarada em `options`. Habilite pesquisa, seleção múltipla, busca remota ou controle nativo conforme a necessidade; use RadioGroup quando poucas opções precisarem permanecer visíveis.",
|
|
169
169
|
},
|
|
170
170
|
separator: {
|
|
171
171
|
name: "separator",
|
|
@@ -177,25 +177,25 @@ export const componentMeta = {
|
|
|
177
177
|
name: "skeleton",
|
|
178
178
|
ancestry: "shadcn",
|
|
179
179
|
whenToUse:
|
|
180
|
-
"
|
|
180
|
+
"Reserve a forma aproximada do conteúdo enquanto ele carrega. Defina dimensões com `className`; para uma espera sem forma conhecida, use Spinner.",
|
|
181
181
|
},
|
|
182
182
|
spinner: {
|
|
183
183
|
name: "spinner",
|
|
184
184
|
ancestry: "shadcn",
|
|
185
185
|
whenToUse:
|
|
186
|
-
"
|
|
186
|
+
"Indique uma espera sem progresso determinado, como uma ação ou consulta em andamento. Para reservar a forma do conteúdo, use Skeleton.",
|
|
187
187
|
},
|
|
188
188
|
table: {
|
|
189
189
|
name: "table",
|
|
190
190
|
ancestry: "shadcn",
|
|
191
191
|
whenToUse:
|
|
192
|
-
'Tabela de dados. Compõe Table > (TableHeader > TableRow > TableHead, TableBody > TableRow > TableCell). `variant="plain"` vem sem borda externa; `variant="framed"` aplica a moldura canônica, recorta o scroll e destaca o cabeçalho.
|
|
192
|
+
'Tabela de dados. Compõe Table > (TableHeader > TableRow > TableHead, TableBody > TableRow > TableCell). `variant="plain"` vem sem borda externa; `variant="framed"` aplica a moldura canônica, recorta o scroll e destaca o cabeçalho. Para listagem tabular — para o pattern de search use ActionList.',
|
|
193
193
|
},
|
|
194
194
|
tabs: {
|
|
195
195
|
name: "tabs",
|
|
196
196
|
ancestry: "shadcn",
|
|
197
197
|
whenToUse:
|
|
198
|
-
"
|
|
198
|
+
"Alterne entre painéis relacionados no mesmo nível de navegação. Cada TabsTrigger aponta para um TabsContent pelo mesmo `value`; TabsList controla o tratamento visual e Tabs define orientação e escala.",
|
|
199
199
|
},
|
|
200
200
|
textarea: {
|
|
201
201
|
name: "textarea",
|
|
@@ -207,133 +207,115 @@ export const componentMeta = {
|
|
|
207
207
|
name: "toast",
|
|
208
208
|
ancestry: "shadcn",
|
|
209
209
|
whenToUse:
|
|
210
|
-
"
|
|
210
|
+
"Comunique um resultado temporário sem interromper o fluxo. Monte Toaster uma vez na raiz e dispare a notificação pela API `toast`; ações seguem a ordem declarada e a última recebe destaque primário. Para uma mensagem persistente no contexto da página, use Alert.",
|
|
211
211
|
},
|
|
212
212
|
tooltip: {
|
|
213
213
|
name: "tooltip",
|
|
214
214
|
ancestry: "shadcn",
|
|
215
215
|
whenToUse:
|
|
216
|
-
"
|
|
216
|
+
"Ofereça uma dica curta ao passar o ponteiro ou focar um elemento. Envolva a árvore em TooltipProvider e mantenha ações ou conteúdo essencial fora do tooltip.",
|
|
217
217
|
},
|
|
218
218
|
truncate: {
|
|
219
219
|
name: "truncate",
|
|
220
220
|
ancestry: "opus",
|
|
221
221
|
whenToUse:
|
|
222
|
-
"
|
|
222
|
+
"Trunque uma linha de texto e mostre a dica somente quando houver transbordamento. Use `tooltip` para substituir o conteúdo da dica e `fade` para trocar as reticências por um esmaecimento. Requer TooltipProvider na raiz.",
|
|
223
223
|
},
|
|
224
224
|
accordion: {
|
|
225
225
|
name: "accordion",
|
|
226
226
|
ancestry: "shadcn",
|
|
227
227
|
whenToUse:
|
|
228
|
-
"Lista de seções empilhadas que abrem/fecham (Radix). `type` single (um painel por vez — combine com `collapsible`
|
|
229
|
-
},
|
|
230
|
-
"alert-dialog": {
|
|
231
|
-
name: "alert-dialog",
|
|
232
|
-
ancestry: "opus",
|
|
233
|
-
whenToUse:
|
|
234
|
-
'Diálogo modal que INTERROMPE pra cobrar decisão e NÃO fecha clicando fora (`role="alertdialog"`) — a confirmação destrutiva. Desenho ÚNICO e compacto (6.0.0: a prop `size` saiu, o largo não existe mais). Compõe AlertDialog > AlertDialogTrigger (asChild) + AlertDialogContent > AlertDialogHeader(AlertDialogMedia? + AlertDialogTitle/Description) + AlertDialogFooter(Cancel/Action). ATENÇÃO: Action e Cancel do Radix FECHAM ao clicar — pra ação async que só some no sucesso, use Button no footer. Na prática você quase nunca monta isto à mão: `confirm()` já faz, e o DeleteButton/ActionTrigger vêm prontos.',
|
|
228
|
+
"Lista de seções empilhadas que abrem/fecham (Radix). `type` single (um painel por vez — combine com `collapsible` para permitir fechar todos) ou multiple (vários abertos). Cada AccordionItem precisa de `value`; o chevron já vem no AccordionTrigger. Para alternar conteúdo lado a lado, use Tabs; para um único bloco recolhível solto, use Collapsible.",
|
|
235
229
|
},
|
|
236
230
|
"aspect-ratio": {
|
|
237
231
|
name: "aspect-ratio",
|
|
238
232
|
ancestry: "shadcn",
|
|
239
233
|
whenToUse:
|
|
240
|
-
"
|
|
234
|
+
"Preserve a proporção de mídias, miniaturas e prévias enquanto a largura muda ou o conteúdo carrega. A largura vem do contêiner e `ratio` determina a altura; borda, arredondamento e recorte pertencem ao AspectRatio.",
|
|
241
235
|
},
|
|
242
236
|
avatar: {
|
|
243
237
|
name: "avatar",
|
|
244
238
|
ancestry: "shadcn",
|
|
245
239
|
whenToUse:
|
|
246
|
-
|
|
240
|
+
"Represente uma pessoa ou agente por imagem, iniciais ou ícone de fallback. AvatarBadge acrescenta um estado no canto; AvatarGroup reúne participantes e AvatarGroupCount resume o excedente.",
|
|
247
241
|
},
|
|
248
242
|
breadcrumb: {
|
|
249
243
|
name: "breadcrumb",
|
|
250
244
|
ancestry: "shadcn",
|
|
251
245
|
whenToUse:
|
|
252
|
-
"Trilha de navegação hierárquica (workspace → repositório → sessão): mostra onde o usuário está e o caminho de volta. `BreadcrumbLink`
|
|
253
|
-
},
|
|
254
|
-
"button-group": {
|
|
255
|
-
name: "button-group",
|
|
256
|
-
ancestry: "shadcn",
|
|
257
|
-
whenToUse:
|
|
258
|
-
'Junta botões (e Select) num bloco coeso — bordas internas colapsadas e cantos arredondados só nas pontas. `orientation` define o eixo e `shape="pill"` arredonda as extremidades externas sem reabrir a junção interna. ButtonGroupText adiciona rótulo/prefixo; ButtonGroupSeparator corta visualmente entre ações.',
|
|
246
|
+
"Trilha de navegação hierárquica (workspace → repositório → sessão): mostra onde o usuário está e o caminho de volta. `BreadcrumbLink` para os níveis navegáveis, `BreadcrumbPage` para o atual (não clicável), `BreadcrumbSeparator` entre eles e `BreadcrumbEllipsis` para colapsar trilhas longas. Para alternar painéis no mesmo nível, use Tabs.",
|
|
259
247
|
},
|
|
260
248
|
calendar: {
|
|
261
249
|
name: "calendar",
|
|
262
250
|
ancestry: "shadcn",
|
|
263
251
|
whenToUse:
|
|
264
|
-
'Grade de datas (react-day-picker)
|
|
252
|
+
'Grade de datas (react-day-picker) para escolher um dia ou um intervalo. `mode` define a seleção (single/multiple/range) e o formato de `selected`/`onSelect` (Date, Date[] ou { from, to }). `captionLayout="dropdown"` troca o título do mês por seletores de mês/ano (pular para um período distante); `numberOfMonths` mostra meses lado a lado; `disabled` (Matcher) corta datas. Para exibir em um popover de campo, ancore no Popover.',
|
|
265
253
|
},
|
|
266
254
|
carousel: {
|
|
267
255
|
name: "carousel",
|
|
268
256
|
ancestry: "shadcn",
|
|
269
257
|
whenToUse:
|
|
270
|
-
"Trilho de slides deslizáveis (embla). Compõe Carousel > CarouselContent > CarouselItem + CarouselPrevious/CarouselNext; o `basis` do item controla quantos cabem na vista. `orientation` (horizontal/vertical), `opts` repassa o embla (loop, align), `setApi` expõe a instância.
|
|
258
|
+
"Trilho de slides deslizáveis (embla). Compõe Carousel > CarouselContent > CarouselItem + CarouselPrevious/CarouselNext; o `basis` do item controla quantos cabem na vista. `orientation` (horizontal/vertical), `opts` repassa o embla (loop, align), `setApi` expõe a instância. Para lista paginada de dados, use Table; para navegação entre painéis, Tabs.",
|
|
271
259
|
},
|
|
272
260
|
collapsible: {
|
|
273
261
|
name: "collapsible",
|
|
274
262
|
ancestry: "shadcn",
|
|
275
263
|
whenToUse:
|
|
276
|
-
"Seção que abre e fecha (Radix): um CollapsibleTrigger revela ou esconde o CollapsibleContent. Compõe Collapsible > (CollapsibleTrigger + CollapsibleContent) — o Trigger já é o `<button>`. `defaultOpen`
|
|
264
|
+
"Seção que abre e fecha (Radix): um CollapsibleTrigger revela ou esconde o CollapsibleContent. Compõe Collapsible > (CollapsibleTrigger + CollapsibleContent) — o Trigger já é o `<button>`. `defaultOpen` para o modo não controlado; `open`/`onOpenChange` para o controlado (ex.: girar o chevron); `disabled` trava o gatilho. Para alternar entre vários painéis, use Tabs; para menu de ações ancorado, Menu.",
|
|
277
265
|
},
|
|
278
266
|
drawer: {
|
|
279
267
|
name: "drawer",
|
|
280
268
|
ancestry: "opus",
|
|
281
269
|
whenToUse:
|
|
282
|
-
|
|
270
|
+
"Mostre detalhes ou edição a partir de uma borda da tela, sem trocar de página. Estruture cabeçalho, corpo e rodapé dentro de DrawerContent e escolha a borda com `side`. Para uma janela centralizada, use Dialog; para ações ancoradas, use Menu.",
|
|
283
271
|
},
|
|
284
272
|
empty: {
|
|
285
273
|
name: "empty",
|
|
286
274
|
ancestry: "shadcn",
|
|
287
275
|
whenToUse:
|
|
288
|
-
"
|
|
276
|
+
"Apresente uma região disponível para receber ou criar conteúdo, com mensagem e ações de próximo passo. Para uma lista ou tabela sem registros, use DataState ou ActionList; para erro, use Alert.",
|
|
289
277
|
},
|
|
290
278
|
field: {
|
|
291
279
|
name: "field",
|
|
292
280
|
ancestry: "shadcn",
|
|
293
281
|
whenToUse:
|
|
294
|
-
"
|
|
295
|
-
},
|
|
296
|
-
"input-group": {
|
|
297
|
-
name: "input-group",
|
|
298
|
-
ancestry: "shadcn",
|
|
299
|
-
whenToUse:
|
|
300
|
-
'Campo composto: cola ícones, texto e botões a um InputGroupInput/InputGroupTextarea numa única moldura (foco e erro propagam pro grupo todo). `shape="pill"` aplica a geometria arredondada à moldura. InputGroupAddon ancora adornos; InputGroupText é rótulo inerte; InputGroupButton é o botão embutido. Pra agrupar botões soltos, use ButtonGroup.',
|
|
282
|
+
"Componha rótulo, controle, ajuda e erro com espaçamento consistente. Use a orientação vertical no caso comum e as orientações horizontal ou responsiva quando controle e texto precisarem ficar lado a lado. Field cuida do layout; o formulário continua responsável por estado e validação.",
|
|
301
283
|
},
|
|
302
284
|
"input-otp": {
|
|
303
285
|
name: "input-otp",
|
|
304
286
|
ancestry: "shadcn",
|
|
305
287
|
whenToUse:
|
|
306
|
-
"
|
|
288
|
+
"Receba um código numérico dividido em posições, como uma confirmação de acesso ou segundo fator. InputOTP define o comprimento, os slots representam as posições e o separador organiza blocos. Para texto livre, use Input.",
|
|
307
289
|
},
|
|
308
290
|
item: {
|
|
309
291
|
name: "item",
|
|
310
292
|
ancestry: "shadcn",
|
|
311
293
|
whenToUse:
|
|
312
|
-
|
|
294
|
+
"Monte uma linha de conteúdo com mídia, título, descrição, corpo e ações. Ícones e imagens mantêm uma moldura quadrada alinhada ao topo; ItemGroup organiza várias linhas e seus divisores. ItemContent permanece apenas como alias legado.",
|
|
313
295
|
},
|
|
314
296
|
kbd: {
|
|
315
297
|
name: "kbd",
|
|
316
298
|
ancestry: "shadcn",
|
|
317
299
|
whenToUse:
|
|
318
|
-
|
|
300
|
+
"Apresente uma tecla ou combinação de teclas. KbdGroup reúne várias teclas e conectores, mas não registra o atalho; o consumidor continua responsável pelo evento de teclado.",
|
|
319
301
|
},
|
|
320
302
|
pagination: {
|
|
321
303
|
name: "pagination",
|
|
322
304
|
ancestry: "shadcn",
|
|
323
305
|
whenToUse:
|
|
324
|
-
"Navegação entre páginas montada por composição: Pagination › PaginationContent › PaginationItem com PaginationLink, mais PaginationPrevious/PaginationNext e PaginationEllipsis. `page` dá o número e o nome acessível (“Página N”); `isActive` marca a atual. Com `href` o link é `<a>`; sem `href` vira `<button>` (modo controlado, com foco e `disabled`). Os números têm largura mínima quadrada e crescem com os dígitos; as setas seguem quadradas (`iconOnly`). `label` localiza as setas. É o único paginador: ActionList compõe esta primitiva na escala densa do rodapé.
|
|
306
|
+
"Navegação entre páginas montada por composição: Pagination › PaginationContent › PaginationItem com PaginationLink, mais PaginationPrevious/PaginationNext e PaginationEllipsis. `page` dá o número e o nome acessível (“Página N”); `isActive` marca a atual. Com `href` o link é `<a>`; sem `href` vira `<button>` (modo controlado, com foco e `disabled`). Os números têm largura mínima quadrada e crescem com os dígitos; as setas seguem quadradas (`iconOnly`). `label` localiza as setas. É o único paginador: ActionList compõe esta primitiva na escala densa do rodapé. Para rolagem infinita ou listas curtas, dispense a barra.",
|
|
325
307
|
},
|
|
326
308
|
progress: {
|
|
327
309
|
name: "progress",
|
|
328
310
|
ancestry: "shadcn",
|
|
329
311
|
whenToUse:
|
|
330
|
-
"
|
|
312
|
+
"Mostre o avanço conhecido de uma tarefa com um valor entre zero e cem. Para uma espera sem percentual, use Spinner; para reservar a forma do conteúdo, use Skeleton.",
|
|
331
313
|
},
|
|
332
314
|
"radio-group": {
|
|
333
315
|
name: "radio-group",
|
|
334
316
|
ancestry: "shadcn",
|
|
335
317
|
whenToUse:
|
|
336
|
-
"Escolha única entre opções mutuamente exclusivas, todas visíveis ao mesmo tempo (Radix). Cada RadioGroupItem tem um `value`; o item escolhido vira o `value` do RadioGroup, controlado por `value`/`onValueChange` (ou `defaultValue` no modo não controlado). Pareie cada item com um Label.
|
|
318
|
+
"Escolha única entre opções mutuamente exclusivas, todas visíveis ao mesmo tempo (Radix). Cada RadioGroupItem tem um `value`; o item escolhido vira o `value` do RadioGroup, controlado por `value`/`onValueChange` (ou `defaultValue` no modo não controlado). Pareie cada item com um Label. Para poucas opções que cabem na tela; com muitas, prefira Select; para ligar/desligar um único item, Checkbox ou Switch.",
|
|
337
319
|
},
|
|
338
320
|
split: {
|
|
339
321
|
name: "split",
|
|
@@ -345,110 +327,98 @@ export const componentMeta = {
|
|
|
345
327
|
name: "sidebar",
|
|
346
328
|
ancestry: "opus",
|
|
347
329
|
whenToUse:
|
|
348
|
-
"
|
|
330
|
+
"Organize navegação global ou contextual em uma coluna lateral. Split e Pane definem posição e largura; Sidebar fornece a superfície e o colapso, enquanto PaneHeader, PaneBody e PaneFooter estruturam as regiões fixa e rolável. Use SidebarNav para grupos planos, componha árvores com SidebarItem e SidebarTreeGroup e use ShellNav quando a navegação precisar de cabeçalho e rodapé próprios.",
|
|
349
331
|
},
|
|
350
332
|
"scroll-area": {
|
|
351
333
|
name: "scroll-area",
|
|
352
334
|
ancestry: "shadcn",
|
|
353
335
|
whenToUse:
|
|
354
|
-
'Região rolável com barra estilizada da casa (Radix), no lugar da scrollbar do sistema. Dê altura (ou largura) ao ScrollArea via className e ponha o conteúdo dentro; a barra vertical já vem por padrão.
|
|
336
|
+
'Região rolável com barra estilizada da casa (Radix), no lugar da scrollbar do sistema. Dê altura (ou largura) ao ScrollArea via className e ponha o conteúdo dentro; a barra vertical já vem por padrão. Para rolagem horizontal, acrescente `<ScrollBar orientation="horizontal" />` como filho. Para a página inteira rolar, deixe o navegador cuidar — isto é para um painel com altura fixa (lista de sessões, log, trilho de skills).',
|
|
355
337
|
},
|
|
356
338
|
slider: {
|
|
357
339
|
name: "slider",
|
|
358
340
|
ancestry: "shadcn",
|
|
359
341
|
whenToUse:
|
|
360
|
-
"Controle de valor
|
|
342
|
+
"Controle de valor em uma faixa contínua, arrastado pelo thumb (Radix). `min`/`max`/`step` delimitam a faixa; `value`/`onValueChange` controlam (array de números — `[n]` para um thumb, `[a, b]` para um intervalo) ou `defaultValue` no modo não controlado. `orientation` horizontal/vertical, `disabled` esmaece. Para um número exato digitado, use Input type=number; para ligar/desligar, Switch.",
|
|
361
343
|
},
|
|
362
344
|
switch: {
|
|
363
345
|
name: "switch",
|
|
364
346
|
ancestry: "shadcn",
|
|
365
347
|
whenToUse:
|
|
366
|
-
"Liga/desliga imediato de uma preferência booleana (Radix). Controlado por `checked`/`onCheckedChange` (boolean) e em par com Label. Use
|
|
348
|
+
"Liga/desliga imediato de uma preferência booleana (Radix). Controlado por `checked`/`onCheckedChange` (boolean) e em par com Label. Use para estado que vale na hora (ativar agente, sincronizar); para confirmar dentro de um formulário, prefira Checkbox.",
|
|
367
349
|
},
|
|
368
350
|
toggle: {
|
|
369
351
|
name: "toggle",
|
|
370
352
|
ancestry: "shadcn",
|
|
371
353
|
whenToUse:
|
|
372
|
-
"
|
|
373
|
-
},
|
|
374
|
-
"toggle-group": {
|
|
375
|
-
name: "toggle-group",
|
|
376
|
-
ancestry: "shadcn",
|
|
377
|
-
whenToUse:
|
|
378
|
-
"Grupo de botões de alternância (Radix). `type` single (um ativo, value: string) ou multiple (vários, value: string[]). Controlado por `value`/`onValueChange`. `variant` default|outline, `size` default|sm|lg e `spacing` descem pros itens via contexto. Serve para alternar a visão de uma seção, montar uma barra de formatação ou apresentar escolhas ricas em cards pelo `ActionForm` com `widget: toggle-group`. Para uma escolha textual comum em formulário, especialmente com rótulos longos sem conteúdo de apoio, prefira RadioGroup.",
|
|
354
|
+
"Alterne um estado diretamente no contexto atual. ToggleGroup reúne escolhas únicas ou múltiplas e compartilha aparência e escala entre os itens. Para um valor booleano com rótulo em formulário, prefira Switch ou Checkbox.",
|
|
379
355
|
},
|
|
380
356
|
|
|
381
357
|
confirm: {
|
|
382
358
|
name: "dialog",
|
|
383
359
|
ancestry: "opus",
|
|
384
360
|
whenToUse:
|
|
385
|
-
"
|
|
361
|
+
"Solicite reconhecimento, confirmação ou uma resposta curta por uma API imperativa. Monte DialogHost uma vez no shell e use `dialog.alert`, `dialog.confirm` ou `dialog.prompt`; as solicitações são exibidas uma por vez. Para ações declaradas em contrato, prefira ActionTrigger; para formulários, use ActionFormDialog.",
|
|
386
362
|
},
|
|
387
363
|
"action-form": {
|
|
388
364
|
name: "action-form",
|
|
389
365
|
ancestry: "opus",
|
|
390
366
|
whenToUse:
|
|
391
|
-
"
|
|
367
|
+
"Renderize e envie uma FormAction com validação, estado de envio e notificação consistentes. Sem filhos, os campos seguem o schema do contrato; com ActionFormField, o consumidor controla o layout sem duplicar rótulos ou erros. Para uma ação sem campos, use ActionTrigger.",
|
|
392
368
|
},
|
|
393
369
|
"action-form-dialog": {
|
|
394
370
|
name: "action-form-dialog",
|
|
395
371
|
ancestry: "opus",
|
|
396
372
|
whenToUse:
|
|
397
|
-
"ActionForm dentro de um Dialog (form em modal) — controla open/onOpenChange + title; fecha no sucesso. Aceita children (modo composição) como o ActionForm.
|
|
373
|
+
"ActionForm dentro de um Dialog (form em modal) — controla open/onOpenChange + title; fecha no sucesso. Aceita children (modo composição) como o ActionForm. Para form inline em uma página, use ActionForm direto.",
|
|
398
374
|
},
|
|
399
375
|
"action-form-card": {
|
|
400
376
|
name: "action-form-card",
|
|
401
377
|
ancestry: "opus",
|
|
402
378
|
whenToUse:
|
|
403
|
-
"
|
|
379
|
+
"Apresente uma FormAction como seção delimitada da página. ActionFormCard combina a estrutura do Card com o comportamento de ActionForm. Para um modal, use ActionFormDialog; sem superfície adicional, use ActionForm.",
|
|
404
380
|
},
|
|
405
381
|
"action-list": {
|
|
406
382
|
name: "action-list",
|
|
407
383
|
ancestry: "opus",
|
|
408
384
|
whenToUse:
|
|
409
|
-
"
|
|
385
|
+
"Apresente uma coleção pesquisável a partir de uma ListAction. O contrato declara colunas, filtros, período e busca; ActionList coordena visualizações, paginação, seleção em lote e sincronização com a URL. Para um único recurso, use ActionView.",
|
|
410
386
|
},
|
|
411
387
|
"action-trigger": {
|
|
412
388
|
name: "action-trigger",
|
|
413
389
|
ancestry: "opus",
|
|
414
390
|
whenToUse:
|
|
415
|
-
"
|
|
391
|
+
"Dispare uma SimpleAction sem campos com carregamento, notificação e confirmação consistentes. Declare confirmações destrutivas no contrato; sem essa declaração, a ação é executada diretamente. Para mutações com campos, use ActionForm.",
|
|
416
392
|
},
|
|
417
393
|
"action-view": {
|
|
418
394
|
name: "action-view",
|
|
419
395
|
ancestry: "opus",
|
|
420
396
|
whenToUse:
|
|
421
|
-
"
|
|
397
|
+
"Carregue e apresente um recurso de uma ViewAction com estados de carregamento, erro e ausência consistentes. Os filhos definem o layout a partir dos dados e de `refetch`; para uma coleção, use ActionList.",
|
|
422
398
|
},
|
|
423
399
|
page: {
|
|
424
400
|
name: "page",
|
|
425
401
|
ancestry: "opus",
|
|
426
402
|
whenToUse:
|
|
427
|
-
"O esqueleto de página do back-office: <main> + container centralizado com teto padrão de 80rem (`max-w-7xl`). O shorthand com title, description, count e actions cria a mesma anatomia de PageHeader(PageTitle/PageDescription/PageMeta/PageActions) + PageBody disponível na forma explícita. `className` substitui o teto quando a composição pede outra largura. Quando todo o body estiver carregando, falhar ou estiver vazio, use PageState.
|
|
428
|
-
},
|
|
429
|
-
"page-state": {
|
|
430
|
-
name: "page-state",
|
|
431
|
-
ancestry: "opus",
|
|
432
|
-
whenToUse:
|
|
433
|
-
"Estado integral da área de conteúdo de Page: loading centralizado, error em Alert com recuperação aplicável, empty em Empty com contexto/ação e ready sem moldura adicional. Use como filho direto de Page somente quando o estado substitui TODO o conteúdo principal; pra seção ou coleção parcial, use DataState, ActionView ou ActionList.",
|
|
403
|
+
"O esqueleto de página do back-office: <main> + container centralizado com teto padrão de 80rem (`max-w-7xl`). O shorthand com title, description, count e actions cria a mesma anatomia de PageHeader(PageTitle/PageDescription/PageMeta/PageActions) + PageBody disponível na forma explícita. `className` substitui o teto quando a composição pede outra largura. Quando todo o body estiver carregando, falhar ou estiver vazio, use PageState. Para listagem em modal, ActionListDialog.",
|
|
434
404
|
},
|
|
435
405
|
router: {
|
|
436
406
|
name: "router",
|
|
437
407
|
ancestry: "opus",
|
|
438
408
|
whenToUse:
|
|
439
|
-
|
|
409
|
+
"Sincronize navegação simples com a URL sem adicionar uma biblioteca de rotas. Os hooks leem caminho, segmentos e busca de forma reativa, enquanto `navigate` preserva links diretos, recarga e histórico. Para padrões de rota, parâmetros tipados ou carregamento por rota, use um roteador dedicado.",
|
|
440
410
|
},
|
|
441
411
|
"data-state": {
|
|
442
412
|
name: "data-state",
|
|
443
413
|
ancestry: "opus",
|
|
444
414
|
whenToUse:
|
|
445
|
-
|
|
415
|
+
"Coordene carregamento, erro, vazio e conteúdo de uma consulta assíncrona. Use DataState dentro da estrutura que receberá os dados; para uma região disponível à criação, use Empty. Ações em andamento pertencem ao estado `busy` do controle que as iniciou.",
|
|
446
416
|
},
|
|
447
417
|
"action-list-dialog": {
|
|
448
418
|
name: "action-list-dialog",
|
|
449
419
|
ancestry: "opus",
|
|
450
420
|
whenToUse:
|
|
451
|
-
|
|
421
|
+
"Apresente uma ListAction dentro de um modal com título, descrição, total e ação relacionada. Os filhos recebem itens e `refetch` para definir a composição da lista. Para uma coleção na página, use ActionList; para um formulário modal, use ActionFormDialog.",
|
|
452
422
|
},
|
|
453
423
|
} as const satisfies Record<string, ComponentMeta>;
|
|
454
424
|
|