@softize/opus 12.10.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 +56 -0
- package/bin/lib/check.mjs +1098 -310
- package/bin/lib/copy.mjs +12 -5
- package/docs/adr/0003-dictionary-presentation-is-declared.md +3 -0
- package/docs/adr/0004-page-content-state-is-composed.md +65 -0
- package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +180 -0
- package/docs/adr/0006-semantic-context-precedes-visual-variant.md +182 -0
- 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/instructions/opus.md +5 -0
- package/registry/skills/build-opus-ui/SKILL.md +27 -16
- package/registry/skills/build-opus-ui/references/evaluations.md +16 -5
- package/registry/skills/build-opus-ui/references/ui-patterns.md +38 -15
- 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/registry/skills/model-opus-dictionary/SKILL.md +4 -2
- package/registry/skills/model-opus-dictionary/references/evaluations.md +4 -3
- package/registry/templates/app/src/App.tsx +1 -1
- package/src/core/dictionary.ts +52 -14
- package/src/core/index.ts +10 -0
- package/src/core/ui-context.ts +29 -0
- package/src/schema/drivers/zod.ts +17 -8
- package/src/ui/components/patterns/action-form-card.tsx +18 -12
- package/src/ui/components/patterns/confirm.tsx +163 -40
- package/src/ui/components/patterns/content-header.tsx +335 -61
- package/src/ui/components/patterns/data-state.tsx +23 -10
- package/src/ui/components/patterns/list.tsx +1097 -783
- package/src/ui/components/patterns/page-state.tsx +115 -0
- package/src/ui/components/patterns/page.tsx +231 -41
- package/src/ui/components/patterns/sidebar.tsx +357 -83
- package/src/ui/components/patterns/trigger.tsx +37 -30
- package/src/ui/components/patterns/view.tsx +7 -11
- package/src/ui/components/primitives/alert.tsx +298 -110
- package/src/ui/components/primitives/ask.tsx +2 -1
- package/src/ui/components/primitives/badge.tsx +91 -30
- package/src/ui/components/primitives/button.tsx +99 -60
- package/src/ui/components/primitives/calendar.tsx +39 -39
- package/src/ui/components/primitives/card.tsx +96 -23
- package/src/ui/components/primitives/detail.tsx +2 -2
- package/src/ui/components/primitives/dialog.tsx +196 -39
- package/src/ui/components/primitives/dictionary-value.tsx +9 -14
- package/src/ui/components/primitives/dot.tsx +74 -21
- package/src/ui/components/primitives/drawer.tsx +40 -24
- package/src/ui/components/primitives/empty.tsx +3 -3
- package/src/ui/components/primitives/item.tsx +135 -79
- package/src/ui/components/primitives/menu.tsx +11 -3
- package/src/ui/components/primitives/metric-card.tsx +133 -0
- package/src/ui/components/primitives/sonner.tsx +187 -8
- package/src/ui/components/primitives/table.tsx +2 -2
- package/src/ui/docs/DocBrowser.tsx +104 -25
- package/src/ui/docs/changelog.tsx +1 -1
- 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 +54 -28
- 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 +21 -22
- package/src/ui/docs/content/breadcrumb.md +13 -8
- package/src/ui/docs/content/button.md +93 -15
- package/src/ui/docs/content/calendar.md +5 -5
- package/src/ui/docs/content/card.md +6 -6
- 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 +44 -0
- package/src/ui/docs/content/copyable.md +4 -3
- package/src/ui/docs/content/customization.md +7 -7
- 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 +8 -5
- package/src/ui/docs/content/dialog.md +339 -31
- package/src/ui/docs/content/dictionary-value.md +19 -18
- package/src/ui/docs/content/dock.md +3 -3
- package/src/ui/docs/content/dot.md +7 -7
- package/src/ui/docs/content/drawer.md +32 -16
- 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 +64 -24
- 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 +36 -17
- package/src/ui/docs/content/metric-card.md +41 -0
- package/src/ui/docs/content/observability.md +2 -2
- package/src/ui/docs/content/page.md +93 -10
- 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/semantic-context.md +63 -0
- package/src/ui/docs/content/separator.md +5 -5
- package/src/ui/docs/content/sidebar.md +325 -56
- package/src/ui/docs/content/skeleton.md +5 -4
- 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 +16 -6
- 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 +31 -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/doc-client.tsx +2 -2
- package/src/ui/docs/registry.tsx +580 -229
- package/src/ui/lib/semantic-context.ts +30 -0
- package/src/ui/meta.ts +278 -286
- package/src/ui/react.tsx +377 -111
- package/src/ui/theme.css +116 -0
- package/src/ui/components/primitives/alert-dialog.tsx +0 -190
- 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 -78
- package/src/ui/docs/content/toggle-group.md +0 -81
|
@@ -4,8 +4,8 @@ title: Filas
|
|
|
4
4
|
|
|
5
5
|
# Filas
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Use uma action em background quando a operação não puder manter a requisição aberta. O
|
|
8
|
+
`QueueAdapter` enfileira o trabalho e devolve um `JobHandle` para acompanhamento pelo cliente.
|
|
9
9
|
|
|
10
10
|
## O contrato
|
|
11
11
|
|
|
@@ -44,7 +44,7 @@ const queue = bullmqQueue({ queue: new Queue('opus', { connection: { host: 'loca
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Redis-backed (durável, entre-processos, retries). Peers opcionais (`bullmq`, `ioredis`) só
|
|
47
|
-
|
|
47
|
+
para quem usa o driver.
|
|
48
48
|
|
|
49
49
|
## No runtime
|
|
50
50
|
|
|
@@ -82,7 +82,7 @@ Multiplicador exponencial diferente de 2 ou `maxMs` exige `backoffStrategy` cust
|
|
|
82
82
|
é rejeitado pelo driver em vez de ser silenciosamente ignorado. `timeout` permanece no
|
|
83
83
|
envelope para o worker aplicar, pois não é uma opção de execução do `Queue.add`.
|
|
84
84
|
|
|
85
|
-
## Limites
|
|
85
|
+
## Limites atuais
|
|
86
86
|
|
|
87
|
-
Driver hoje: `bullmq` (Redis). In-memory
|
|
87
|
+
Driver hoje: `bullmq` (Redis). In-memory para dev e outros backends (SQS, pg-boss…) entram
|
|
88
88
|
por reincidência.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Escolha única
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `RadioGroup` quando todas as opções mutuamente exclusivas precisarem permanecer visíveis. Cada
|
|
4
|
+
`RadioGroupItem` declara um `value` e deve estar associado a um `Label`. `defaultValue` define a
|
|
5
|
+
opção inicial no modo não controlado.
|
|
4
6
|
|
|
5
7
|
```tsx preview col-start
|
|
6
8
|
<RadioGroup defaultValue="balanced">
|
|
@@ -21,7 +23,7 @@ Cada RadioGroupItem tem um value; o item escolhido é o value do RadioGroup. def
|
|
|
21
23
|
|
|
22
24
|
## Controlado
|
|
23
25
|
|
|
24
|
-
value
|
|
26
|
+
Use `value` e `onValueChange` quando outro estado da aplicação também precisar acompanhar a escolha.
|
|
25
27
|
|
|
26
28
|
```tsx preview col-start
|
|
27
29
|
const [agent, setAgent] = useState('reviewer')
|
|
@@ -46,7 +48,8 @@ render(
|
|
|
46
48
|
|
|
47
49
|
## Item desabilitado
|
|
48
50
|
|
|
49
|
-
disabled
|
|
51
|
+
`disabled` em `RadioGroupItem` bloqueia somente aquela opção e atualiza o `Label` associado. Para
|
|
52
|
+
bloquear todas as opções, aplique `disabled` ao `RadioGroup`.
|
|
50
53
|
|
|
51
54
|
```tsx preview col-start
|
|
52
55
|
<RadioGroup defaultValue="empresa-x-web">
|
|
@@ -65,13 +68,18 @@ disabled num RadioGroupItem esmaece e tira a opção da escolha; o Label em par
|
|
|
65
68
|
</RadioGroup>
|
|
66
69
|
```
|
|
67
70
|
|
|
68
|
-
##
|
|
71
|
+
## Propriedades de RadioGroup
|
|
69
72
|
|
|
70
|
-
|
|
|
73
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
71
74
|
|---|---|---|---|
|
|
72
|
-
| `value
|
|
73
|
-
| `onValueChange
|
|
74
|
-
| `defaultValue
|
|
75
|
-
| `disabled
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
| `value` | `string` | | Opção escolhida no modo controlado. Use com `onValueChange`. |
|
|
76
|
+
| `onValueChange` | `(value: string) => void` | | Chamado quando a pessoa escolhe outra opção. |
|
|
77
|
+
| `defaultValue` | `string` | | Opção inicial no modo não controlado. |
|
|
78
|
+
| `disabled` | `boolean` | `false` | Desabilita todo o grupo. |
|
|
79
|
+
|
|
80
|
+
## Propriedades de RadioGroupItem
|
|
81
|
+
|
|
82
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
83
|
+
|---|---|---|---|
|
|
84
|
+
| `value` | `string` | | Valor que o item atribui ao grupo quando selecionado. |
|
|
85
|
+
| `disabled` | `boolean` | `false` | Desabilita somente este item; o `Label` associado acompanha o estado. |
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## A URL como estado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use o router do Opus em aplicações pequenas que precisam reagir à URL sem uma tabela de rotas.
|
|
4
|
+
`pushState`, `popstate` e `useSyncExternalStore` preservam links diretos, recarregamento e o botão
|
|
5
|
+
Voltar sem manter uma segunda cópia do destino atual.
|
|
4
6
|
|
|
5
7
|
```tsx
|
|
6
8
|
import { navigate, useSegments } from '@softize/opus/ui/react'
|
|
@@ -12,9 +14,10 @@ function App() {
|
|
|
12
14
|
}
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Limite do router
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
O router oferece leitura reativa da URL e `navigate`; o aplicativo decide o que renderizar. Ele não
|
|
20
|
+
inclui tabela de rotas, parâmetros tipados nem carregamento de dados.
|
|
18
21
|
|
|
19
22
|
A régua: se a sua tela precisa de casamento de padrão (`/users/:id/posts/:postId`), params tipados ou data loaders, o caso pede uma biblioteca de rotas, não isto. Um app de back-office com uma dúzia de destinos quase nunca precisa.
|
|
20
23
|
|
|
@@ -27,13 +30,15 @@ A régua: se a sua tela precisa de casamento de padrão (`/users/:id/posts/:post
|
|
|
27
30
|
| `useSearchParams()` | A querystring reativa — o lar natural do estado interno de uma seção (qual relatório está aberto, o recorte de uma lista). |
|
|
28
31
|
| `navigate(path, opts?)` | `pushState` + notifica. `{ replace: true }` troca a entrada corrente. |
|
|
29
32
|
|
|
30
|
-
##
|
|
33
|
+
## Comportamentos preservados
|
|
31
34
|
|
|
32
35
|
**Destino igual é no-op.** `navigate` resolve o destino com `new URL` e compara o `href` inteiro — não faz nada se você já está exatamente lá. Sem isso, clicar duas vezes no mesmo item do menu empilha entradas idênticas e o botão "voltar" não sai do lugar.
|
|
33
36
|
|
|
34
37
|
Comparar strings cruas parece bastar e não basta, em duas frentes. O **hash**: estando em `/a#secao`, `navigate('/a')` pareceria destino repetido e a âncora nunca sairia da URL. E o **encoding**: `window.location` devolve `/relatórios` como `/relat%C3%B3rios`, então a comparação crua nunca casa e cada clique empilha — bem no caso pt-BR, e no ``navigate(`/reports?report=${arquivo}`)`` com nome de arquivo acentuado.
|
|
35
38
|
|
|
36
|
-
**A notificação
|
|
39
|
+
**A notificação usa um evento do navegador.** Como `pushState` não dispara `popstate`, `navigate`
|
|
40
|
+
emite o evento explicitamente. Isso mantém listeners existentes e cópias diferentes do pacote
|
|
41
|
+
sincronizados pela mesma janela.
|
|
37
42
|
|
|
38
43
|
**`useSyncExternalStore`, não `useState`.** Ler `window.location` dentro de `useState`/`useEffect` sofre *tearing* no modo concurrent: dois componentes podem renderizar o mesmo commit com URLs diferentes. As cópias que este módulo substituiu faziam isso.
|
|
39
44
|
|
|
@@ -4,9 +4,8 @@ title: Agendador
|
|
|
4
4
|
|
|
5
5
|
# Agendador
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
e o runtime
|
|
9
|
-
execução). O contrato é o `SchedulerAdapter`.
|
|
7
|
+
Use um schedule para executar uma action por cron ou intervalo. O `SchedulerAdapter` registra o
|
|
8
|
+
agendamento e o runtime executa a action com provenance `schedule`, preservando sua rastreabilidade.
|
|
10
9
|
|
|
11
10
|
## O contrato
|
|
12
11
|
|
|
@@ -59,8 +58,8 @@ const runtime = createRuntime({
|
|
|
59
58
|
O runtime registra os schedules do domínio no `start()` e chama a action quando o tempo bate
|
|
60
59
|
— nada de disparar no handler.
|
|
61
60
|
|
|
62
|
-
## Limites
|
|
61
|
+
## Limites atuais
|
|
63
62
|
|
|
64
|
-
Driver hoje: `node-cron` (in-process — some se o processo cair;
|
|
63
|
+
Driver hoje: `node-cron` (in-process — some se o processo cair; em um cluster, cada nó
|
|
65
64
|
dispararia). Backends duráveis/distribuídos (BullMQ repeatable, Temporal…) entram por
|
|
66
65
|
reincidência.
|
|
@@ -4,7 +4,7 @@ Dê a altura ao ScrollArea (h-48) e ponha o conteúdo dentro — a barra vertica
|
|
|
4
4
|
|
|
5
5
|
```tsx preview col
|
|
6
6
|
const sessions = [
|
|
7
|
-
{ id: 'empresa-x-1842', title: 'Migrar billing
|
|
7
|
+
{ id: 'empresa-x-1842', title: 'Migrar billing para o novo schema', agent: 'developer' },
|
|
8
8
|
{ id: 'empresa-x-1839', title: 'Revisar handoff do checkout', agent: 'reviewer' },
|
|
9
9
|
{ id: 'empresa-x-1835', title: 'Redesenhar o painel de rotas', agent: 'designer' },
|
|
10
10
|
{ id: 'empresa-x-1830', title: 'Corrigir flaky no teste de webhook', agent: 'developer' },
|
|
@@ -30,7 +30,7 @@ render(
|
|
|
30
30
|
|
|
31
31
|
## Trilho horizontal
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Para rolar na horizontal, acrescente <ScrollBar orientation="horizontal" /> como filho e deixe o conteúdo em uma linha que não quebra (flex + w-max).
|
|
34
34
|
|
|
35
35
|
```tsx preview col
|
|
36
36
|
const skills = ['implement-opus-change', 'create-opus-action', 'test-opus-action', 'build-opus-ui', 'upgrade-opus']
|
|
@@ -80,10 +80,15 @@ render(
|
|
|
80
80
|
)
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
##
|
|
83
|
+
## Propriedades de ScrollArea
|
|
84
84
|
|
|
85
|
-
|
|
|
85
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
86
86
|
|---|---|---|---|
|
|
87
|
-
| `className
|
|
88
|
-
| `children
|
|
89
|
-
|
|
87
|
+
| `className` | `string` | | Classes que definem as dimensões da janela rolável. Sem uma dimensão limitada, não há conteúdo a recortar. |
|
|
88
|
+
| `children` | `React.ReactNode` | | Conteúdo da janela, incluindo uma `ScrollBar` horizontal quando necessária. |
|
|
89
|
+
|
|
90
|
+
## Propriedades de ScrollBar
|
|
91
|
+
|
|
92
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Direção da barra. A barra vertical já faz parte de `ScrollArea`. |
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Escolha em lista
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Select` para escolhas em lista. Declare as opções como dados em `options`; `label` é usado no
|
|
4
|
+
campo, na busca e na leitura assistiva. Associe `id` ao `htmlFor` de `Label` em formulários.
|
|
4
5
|
|
|
5
6
|
```tsx preview col md
|
|
6
7
|
const [role, setRole] = useState('')
|
|
@@ -23,9 +24,10 @@ render(
|
|
|
23
24
|
)
|
|
24
25
|
```
|
|
25
26
|
|
|
26
|
-
##
|
|
27
|
+
## Lista pesquisável
|
|
27
28
|
|
|
28
|
-
`searchable`
|
|
29
|
+
Use `searchable` quando a quantidade ou os rótulos dificultarem encontrar uma opção. O próprio
|
|
30
|
+
campo passa a filtrar `label`, `hint` e `value` com a busca do cmdk.
|
|
29
31
|
|
|
30
32
|
```tsx preview col md
|
|
31
33
|
const [issue, setIssue] = useState('')
|
|
@@ -49,9 +51,11 @@ render(
|
|
|
49
51
|
)
|
|
50
52
|
```
|
|
51
53
|
|
|
52
|
-
##
|
|
54
|
+
## Seleção múltipla
|
|
53
55
|
|
|
54
|
-
`multiple
|
|
56
|
+
Com `multiple`, `value` e `onChange` usam `string[]`. As opções escolhidas aparecem como chips
|
|
57
|
+
removíveis e a lista permanece aberta para escolhas sucessivas. “Selecionar tudo” fica disponível
|
|
58
|
+
somente quando todas as opções estão carregadas localmente e a busca está vazia.
|
|
55
59
|
|
|
56
60
|
```tsx preview col md
|
|
57
61
|
const [skills, setSkills] = useState<string[]>(['clean-code'])
|
|
@@ -77,9 +81,10 @@ render(
|
|
|
77
81
|
)
|
|
78
82
|
```
|
|
79
83
|
|
|
80
|
-
##
|
|
84
|
+
## Controle nativo
|
|
81
85
|
|
|
82
|
-
`native`
|
|
86
|
+
Use `native` para uma lista curta e conhecida, como prioridade ou ambiente. O sistema operacional
|
|
87
|
+
controla a interação do `<select>`. Busca, seleção múltipla e conteúdo rico exigem o modo padrão.
|
|
83
88
|
|
|
84
89
|
```tsx preview col md
|
|
85
90
|
const [env, setEnv] = useState('preview')
|
|
@@ -104,7 +109,8 @@ render(
|
|
|
104
109
|
|
|
105
110
|
## Grupos
|
|
106
111
|
|
|
107
|
-
`group`
|
|
112
|
+
`group` reúne opções sob um título nos dois modos. Use grupos quando a lista combinar conjuntos com
|
|
113
|
+
origens ou papéis distintos.
|
|
108
114
|
|
|
109
115
|
```tsx preview col md
|
|
110
116
|
const [reviewer, setReviewer] = useState('')
|
|
@@ -124,9 +130,10 @@ render(
|
|
|
124
130
|
)
|
|
125
131
|
```
|
|
126
132
|
|
|
127
|
-
## Busca
|
|
133
|
+
## Busca no servidor
|
|
128
134
|
|
|
129
|
-
Com `onSearch
|
|
135
|
+
Com `onSearch`, o consumidor consulta as opções ao abrir e ao digitar, com debounce. Atualize
|
|
136
|
+
`options` com a resposta e use `loading` durante a consulta. Esse modo já habilita o campo de busca.
|
|
130
137
|
|
|
131
138
|
```tsx preview col md
|
|
132
139
|
const ASSIGNEES = [
|
|
@@ -163,7 +170,8 @@ render(
|
|
|
163
170
|
|
|
164
171
|
## Ícone dentro do campo
|
|
165
172
|
|
|
166
|
-
`icon`
|
|
173
|
+
`icon` posiciona um ícone decorativo antes do texto ou dos chips. Use-o para reforçar a identidade do
|
|
174
|
+
campo sem criar um elemento separado ao lado do controle.
|
|
167
175
|
|
|
168
176
|
```tsx preview col-start
|
|
169
177
|
const [task, setTask] = useState('')
|
|
@@ -182,9 +190,10 @@ render(
|
|
|
182
190
|
)
|
|
183
191
|
```
|
|
184
192
|
|
|
185
|
-
##
|
|
193
|
+
## Tamanho
|
|
186
194
|
|
|
187
|
-
O
|
|
195
|
+
O tamanho padrão acompanha `Input` e `Button`. Use `size="sm"` em barras de filtros e outras
|
|
196
|
+
composições densas.
|
|
188
197
|
|
|
189
198
|
```tsx preview col-start
|
|
190
199
|
const [a, setA] = useState('gra-2')
|
|
@@ -203,9 +212,10 @@ render(
|
|
|
203
212
|
)
|
|
204
213
|
```
|
|
205
214
|
|
|
206
|
-
## Limpar
|
|
215
|
+
## Limpar a seleção
|
|
207
216
|
|
|
208
|
-
`clearable`
|
|
217
|
+
`clearable` acrescenta uma ação que limpa o valor sem abrir a lista. No modo simples, o valor volta
|
|
218
|
+
a vazio; no múltiplo, volta a `[]`. Os filtros de `ActionList` já habilitam esse comportamento.
|
|
209
219
|
|
|
210
220
|
```tsx preview col md
|
|
211
221
|
function Demo() {
|
|
@@ -229,9 +239,10 @@ function Demo() {
|
|
|
229
239
|
render(<Demo />)
|
|
230
240
|
```
|
|
231
241
|
|
|
232
|
-
##
|
|
242
|
+
## Conteúdo rico nas opções
|
|
233
243
|
|
|
234
|
-
`label`
|
|
244
|
+
Mantenha `label` como string para busca e leitura assistiva. Use `content` para acrescentar ícone,
|
|
245
|
+
avatar ou texto complementar à opção apresentada na lista.
|
|
235
246
|
|
|
236
247
|
```tsx preview col md
|
|
237
248
|
const [agent, setAgent] = useState('developer')
|
|
@@ -271,9 +282,10 @@ render(
|
|
|
271
282
|
)
|
|
272
283
|
```
|
|
273
284
|
|
|
274
|
-
##
|
|
285
|
+
## Select na barra do Composer
|
|
275
286
|
|
|
276
|
-
`variant="ghost"`
|
|
287
|
+
Use `variant="ghost"` para integrar o seletor à barra de ações de `Composer`. `triggerLabel` pode
|
|
288
|
+
encurtar somente o texto do gatilho; a lista continua exibindo o `label` completo.
|
|
277
289
|
|
|
278
290
|
```tsx preview col-start
|
|
279
291
|
const [task, setTask] = useState('GB-42')
|
|
@@ -292,9 +304,10 @@ render(
|
|
|
292
304
|
)
|
|
293
305
|
```
|
|
294
306
|
|
|
295
|
-
## Ação no fim do campo
|
|
307
|
+
## Ação no fim do campo
|
|
296
308
|
|
|
297
|
-
`trailing`
|
|
309
|
+
`trailing` posiciona uma ação relacionada ao valor antes do chevron. Interagir com essa região não
|
|
310
|
+
abre a lista.
|
|
298
311
|
|
|
299
312
|
```tsx preview col-start
|
|
300
313
|
const [task, setTask] = useState('gra-2')
|
|
@@ -318,9 +331,9 @@ render(
|
|
|
318
331
|
)
|
|
319
332
|
```
|
|
320
333
|
|
|
321
|
-
##
|
|
334
|
+
## Propriedades de Select
|
|
322
335
|
|
|
323
|
-
|
|
|
336
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
324
337
|
|---|---|---|---|
|
|
325
338
|
| `options` | `SelectOption[]` | | As opções: `{ value, label, hint?, content?, triggerLabel?, group?, disabled? }`. |
|
|
326
339
|
| `value` | `string \| string[]` | | O selecionado: string no single, string[] no multiple. |
|
|
@@ -328,16 +341,16 @@ render(
|
|
|
328
341
|
| `native` | `boolean` | `false` | Renderiza o `<select>` do sistema. Exclui busca, multi e ghost (o browser é quem desenha a lista). |
|
|
329
342
|
| `searchable` | `boolean` | `false` | O campo vira busca: filtra a lista enquanto digita. |
|
|
330
343
|
| `multiple` | `boolean` | `false` | Chips removíveis, lista que permanece aberta e Selecionar tudo. |
|
|
331
|
-
| `variant` | `'default' \| 'ghost'` | `'default'` | `ghost` = sem moldura,
|
|
344
|
+
| `variant` | `'default' \| 'ghost'` | `'default'` | `ghost` = sem moldura, para barra do composer. |
|
|
332
345
|
| `placeholder` | `string` | `'Selecione…'` | Texto do campo vazio. |
|
|
333
|
-
| `searchPlaceholder` | `string` | | Placeholder enquanto busca; cai
|
|
346
|
+
| `searchPlaceholder` | `string` | | Placeholder enquanto busca; cai para o `placeholder` se ausente. |
|
|
334
347
|
| `emptyText` | `string` | `'Nada encontrado.'` | Mensagem quando a busca não acha nada. |
|
|
335
348
|
| `onSearch` | `(query: string) => void` | | Busca server-side (debounced, ao abrir e ao digitar): desliga o filtro do cmdk — o pai atualiza `options`. |
|
|
336
349
|
| `loading` | `boolean` | | Mostra Buscando… enquanto o fetch corre (use com `onSearch`). |
|
|
337
|
-
| `clearable` | `boolean` | `false` | X no controle quando há seleção — limpa
|
|
350
|
+
| `clearable` | `boolean` | `false` | X no controle quando há seleção — limpa em um clique. |
|
|
338
351
|
| `icon` | `React.ReactNode` | | Ícone leading DENTRO do controle (decorativo) — herda `size-4` e o tom muted. |
|
|
339
352
|
| `trailing` | `React.ReactNode` | | Ação custom no FIM do controle (antes do chevron) — o clique não abre a lista. |
|
|
340
|
-
| `size` | `'default' \| 'sm'` | `'default'` | Altura: default (h-9, a do Input e do Button) ou sm (h-8)
|
|
353
|
+
| `size` | `'default' \| 'sm'` | `'default'` | Altura: default (h-9, a do Input e do Button) ou sm (h-8) para toolbar densa. |
|
|
341
354
|
| `disabled` | `boolean` | `false` | Esmaece e trava o controle. |
|
|
342
|
-
| `id` | `string` | | Vai
|
|
355
|
+
| `id` | `string` | | Vai para o campo — para parear com o `htmlFor` do Label. |
|
|
343
356
|
| `className` | `string` | | Classes da raiz do controle, incluindo campo, ícones e ações, em todos os modos. |
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contexto & Variante
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Contexto & Variante
|
|
6
|
+
|
|
7
|
+
Componentes semânticos separam significado de aparência. `context` responde por que o elemento
|
|
8
|
+
recebe destaque; `variant` escolhe como esse significado aparece. Essa ordem evita que nomes como
|
|
9
|
+
`success`, `warning` ou `danger` sejam tratados como decoração local.
|
|
10
|
+
|
|
11
|
+
## Contextos
|
|
12
|
+
|
|
13
|
+
| Contexto | Uso |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `neutral` | Estado normal, inativo ou sem julgamento positivo ou negativo. |
|
|
16
|
+
| `primary` | Ação ou elemento de maior destaque no contexto atual. |
|
|
17
|
+
| `info` | Informação ou processo em andamento sem alerta. |
|
|
18
|
+
| `success` | Resultado positivo ou estado saudável. |
|
|
19
|
+
| `warning` | Condição que pede atenção, mas ainda não é uma falha. |
|
|
20
|
+
| `danger` | Falha, impedimento ou consequência perigosa. |
|
|
21
|
+
|
|
22
|
+
`light` e `dark` são temas, não contextos. `secondary` descreve hierarquia de ação em APIs antigas;
|
|
23
|
+
um estado sem destaque usa `neutral`. `destructive` continua sendo uma propriedade comportamental
|
|
24
|
+
de actions e confirmações; sua projeção visual usa `danger`.
|
|
25
|
+
|
|
26
|
+
## Variantes
|
|
27
|
+
|
|
28
|
+
`solid`, `subtle`, `outline`, `ghost` e `link` descrevem somente tratamento visual. Cada componente
|
|
29
|
+
aceita o subconjunto coerente com seu papel.
|
|
30
|
+
|
|
31
|
+
```tsx preview col
|
|
32
|
+
<div className="flex flex-wrap gap-2">
|
|
33
|
+
<Badge context="success" variant="solid">Concluído</Badge>
|
|
34
|
+
<Badge context="success" variant="subtle">Concluído</Badge>
|
|
35
|
+
<Badge context="success" variant="outline">Concluído</Badge>
|
|
36
|
+
</div>
|
|
37
|
+
<div className="flex flex-wrap gap-2">
|
|
38
|
+
<Button context="primary" variant="solid">Salvar</Button>
|
|
39
|
+
<Button context="neutral" variant="outline">Voltar</Button>
|
|
40
|
+
<Button context="danger" variant="ghost">Excluir</Button>
|
|
41
|
+
</div>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Dicionários
|
|
45
|
+
|
|
46
|
+
Status e estágios declaram `context` na entrada. A tela usa `DictionaryValue` ou `ActionList` e não
|
|
47
|
+
escolhe a aparência novamente.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const status = t.dict(
|
|
51
|
+
{
|
|
52
|
+
running: { label: 'Em andamento', context: 'info' },
|
|
53
|
+
completed: { label: 'Concluído', context: 'success' },
|
|
54
|
+
failed: { label: 'Falhou', context: 'danger' },
|
|
55
|
+
},
|
|
56
|
+
{ presentation: 'status' },
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Compatibilidade
|
|
61
|
+
|
|
62
|
+
`tone` em dicionários e variantes semânticas antigas continuam aceitos durante a migração. Código
|
|
63
|
+
novo usa `context`; não misture o contrato antigo e o novo na mesma ocorrência.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Separar blocos empilhados
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use a orientação horizontal entre blocos empilhados. A linha ocupa toda a largura disponível.
|
|
4
4
|
|
|
5
5
|
```tsx preview col
|
|
6
6
|
<div>
|
|
@@ -13,7 +13,7 @@ Divide blocos empilhados — ocupa a largura toda do contêiner.
|
|
|
13
13
|
|
|
14
14
|
## Vertical
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Use a orientação vertical entre itens lado a lado. A linha herda a altura do contêiner.
|
|
17
17
|
|
|
18
18
|
```tsx preview
|
|
19
19
|
<div className="flex h-4 items-center gap-3 text-sm">
|
|
@@ -25,9 +25,9 @@ Entre itens de uma linha. O vertical herda a altura do contêiner — dê altura
|
|
|
25
25
|
</div>
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Propriedades de Separator
|
|
29
29
|
|
|
30
|
-
|
|
|
30
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
31
31
|
|---|---|---|---|
|
|
32
32
|
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Direção da linha. Vertical precisa de altura vinda do contêiner. |
|
|
33
33
|
| `decorative` | `boolean` | `true` | Decorativa some da árvore de acessibilidade. Use false quando a divisão é semântica. |
|