@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
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Uma tecla
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use um `Kbd` para representar cada tecla. O componente apresenta o atalho; a captura do teclado
|
|
4
|
+
continua no handler do aplicativo.
|
|
4
5
|
|
|
5
6
|
```tsx preview
|
|
6
7
|
<Kbd>Esc</Kbd>
|
|
@@ -8,7 +9,7 @@ Uma tecla por Kbd. É só visual — quem escuta o atalho é o seu handler, não
|
|
|
8
9
|
|
|
9
10
|
## Combinação
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Agrupe as teclas com `KbdGroup` e use `+` como texto entre elas.
|
|
12
13
|
|
|
13
14
|
```tsx preview
|
|
14
15
|
<KbdGroup>
|
|
@@ -20,7 +21,8 @@ Envolva as teclas num KbdGroup e ponha o conector (+) como texto entre elas —
|
|
|
20
21
|
|
|
21
22
|
## Com ícone
|
|
22
23
|
|
|
23
|
-
Um ícone
|
|
24
|
+
Um ícone Lucide recebe automaticamente a escala do componente. Use-o quando o símbolo for mais
|
|
25
|
+
reconhecível que o nome da tecla.
|
|
24
26
|
|
|
25
27
|
```tsx preview col-start
|
|
26
28
|
<KbdGroup>
|
|
@@ -35,7 +37,8 @@ Um ícone (lucide) como filho do Kbd ganha size-3 automático — bom pra ⌘ e
|
|
|
35
37
|
|
|
36
38
|
## No tooltip
|
|
37
39
|
|
|
38
|
-
Dentro de
|
|
40
|
+
Dentro de `TooltipContent`, o componente ajusta o contraste automaticamente. O tooltip deve nomear a
|
|
41
|
+
ação antes de informar seu atalho.
|
|
39
42
|
|
|
40
43
|
```tsx preview
|
|
41
44
|
<Tooltip>
|
|
@@ -52,11 +55,16 @@ Dentro de um TooltipContent o Kbd inverte o tom sozinho (fundo claro sobre o bal
|
|
|
52
55
|
</Tooltip>
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
##
|
|
58
|
+
## Propriedades de Kbd
|
|
56
59
|
|
|
57
|
-
|
|
|
60
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
58
61
|
|---|---|---|---|
|
|
59
|
-
| `children
|
|
60
|
-
| `className
|
|
61
|
-
|
|
62
|
-
|
|
62
|
+
| `children` | `React.ReactNode` | | Texto ou ícone que representa a tecla. Ícones Lucide recebem a escala visual do componente. |
|
|
63
|
+
| `className` | `string` | | Classes adicionais aplicadas à tecla. |
|
|
64
|
+
|
|
65
|
+
## Propriedades de KbdGroup
|
|
66
|
+
|
|
67
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| `children` | `React.ReactNode` | | Teclas da combinação e conectores, como `+`, entre elas. |
|
|
70
|
+
| `className` | `string` | | Classes adicionais aplicadas ao agrupador. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## Com campo de texto
|
|
2
2
|
|
|
3
|
-
htmlFor
|
|
3
|
+
Associe `htmlFor` ao `id` do controle para que clicar no rótulo mova o foco para o campo.
|
|
4
4
|
|
|
5
5
|
```tsx preview col md
|
|
6
6
|
<div className="grid gap-2">
|
|
@@ -11,7 +11,8 @@ htmlFor aponta pro id do controle — clicar no rótulo foca o campo.
|
|
|
11
11
|
|
|
12
12
|
## Com Checkbox
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
`Label` já organiza controles inline com espaçamento. Ao associá-lo ao `Checkbox`, clicar no texto
|
|
15
|
+
também alterna a seleção.
|
|
15
16
|
|
|
16
17
|
```tsx preview
|
|
17
18
|
<div className="flex items-center gap-2">
|
|
@@ -22,7 +23,8 @@ O Label já é flex com gap — controle inline entra sem wrapper extra; clicar
|
|
|
22
23
|
|
|
23
24
|
## Par desabilitado
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
Quando o controle está desabilitado, o rótulo associado acompanha o tratamento visual sem exigir
|
|
27
|
+
uma classe adicional.
|
|
26
28
|
|
|
27
29
|
```tsx preview
|
|
28
30
|
<div className="flex items-center gap-2">
|
|
@@ -4,9 +4,9 @@ title: Log
|
|
|
4
4
|
|
|
5
5
|
# Log
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
`
|
|
9
|
-
|
|
7
|
+
Use `ctx.log` para registrar eventos estruturados com o contexto da requisição e da action. O
|
|
8
|
+
`LoggerAdapter` também recebe os registros internos do runtime, mantendo aplicação e Opus no mesmo
|
|
9
|
+
destino e formato.
|
|
10
10
|
|
|
11
11
|
## O contrato
|
|
12
12
|
|
|
@@ -49,7 +49,7 @@ handler: async (ctx, input) => {
|
|
|
49
49
|
}
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
## Limites
|
|
52
|
+
## Limites atuais
|
|
53
53
|
|
|
54
54
|
Superfície mínima de níveis + `child`. Sem sampling nem transports próprios — isso mora no
|
|
55
55
|
`pino` que você passa. Drivers hoje: `pino`; outros entram por reincidência.
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
## Fonte e resultado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Passe o texto em `content`. O exemplo mostra primeiro o resultado renderizado e, depois, o Markdown
|
|
4
|
+
que o produziu.
|
|
4
5
|
|
|
5
6
|
```tsx preview col 2xl
|
|
6
7
|
const sample = [
|
|
7
8
|
'# Markdown na Softize',
|
|
8
9
|
'',
|
|
9
10
|
'Renderiza **doc técnica** e mensagem de chat — `SKILL.md`, síntese de papel, resposta de agente.',
|
|
10
|
-
'O motor é o markdown-it, o
|
|
11
|
+
'O motor é o markdown-it, o mesmo que renderiza estas páginas.',
|
|
11
12
|
'',
|
|
12
13
|
'## Sintaxe coberta',
|
|
13
14
|
'',
|
|
@@ -18,7 +19,7 @@ const sample = [
|
|
|
18
19
|
'1. Primeiro passo',
|
|
19
20
|
'2. Segundo passo',
|
|
20
21
|
'',
|
|
21
|
-
'> Citação calma,
|
|
22
|
+
'> Citação calma, para o tom certo.',
|
|
22
23
|
'',
|
|
23
24
|
'---',
|
|
24
25
|
'',
|
|
@@ -33,9 +34,9 @@ render(<Markdown content={sample} />)
|
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## Propriedades de Markdown
|
|
37
38
|
|
|
38
|
-
|
|
|
39
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
39
40
|
|---|---|---|---|
|
|
40
|
-
| `content` | `string` | | O markdown cru (CommonMark + tabela GFM, via markdown-it). HTML no fonte é **escapado**, não interpretado — por isso serve
|
|
41
|
+
| `content` | `string` | | O markdown cru (CommonMark + tabela GFM, via markdown-it). HTML no fonte é **escapado**, não interpretado — por isso serve para texto vindo de gente ou de modelo. |
|
|
41
42
|
| `className` | `string` | | Classes do wrapper. |
|
|
@@ -4,10 +4,9 @@ title: MCP
|
|
|
4
4
|
|
|
5
5
|
# MCP
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
como o usuário resolvido). O MCP é só o transporte.
|
|
7
|
+
Use o servidor MCP para disponibilizar actions `ai:enabled` a agentes que executam fora da
|
|
8
|
+
aplicação. A chamada continua passando por `runtime.execute`, com a mesma validação, autorização e
|
|
9
|
+
auditoria; o MCP fornece apenas o transporte.
|
|
11
10
|
|
|
12
11
|
## Montar
|
|
13
12
|
|
|
@@ -22,23 +21,22 @@ const server = createOpusMcpServer(runtime, {
|
|
|
22
21
|
resolveContext: async (extra) => auth.resolveFromMcp(extra),
|
|
23
22
|
})
|
|
24
23
|
|
|
25
|
-
await server.connect(new StdioServerTransport()) // local; HTTP/SSE
|
|
24
|
+
await server.connect(new StdioServerTransport()) // local; HTTP/SSE para remoto
|
|
26
25
|
```
|
|
27
26
|
|
|
28
27
|
`ListTools` devolve as actions `ai:enabled` (nome + descrição + JSON Schema do input);
|
|
29
28
|
`CallTool` executa a action pelo `runtime.execute` — validação, auth (`ctx.can`) e audit,
|
|
30
29
|
tudo igual a uma chamada normal. Read-only? Marque só actions de leitura com `ai:enabled`.
|
|
31
30
|
|
|
32
|
-
##
|
|
31
|
+
## Escolher entre integração interna e MCP
|
|
33
32
|
|
|
34
|
-
- **
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
|
|
33
|
+
- **Agente dentro da aplicação:** use `runtime.aiFor(base).run()` para chamar as actions no mesmo
|
|
34
|
+
processo.
|
|
35
|
+
- **Agente em outro serviço:** use MCP para oferecer a mesma coleção de ferramentas por uma
|
|
36
|
+
interface interoperável.
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
## Limites atuais
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`destructive` sobre MCP (elicitation) entra quando um caso real cobrar; comece read-only.
|
|
40
|
+
O consumidor escolhe e monta o transporte, como stdio ou HTTP. A confirmação de actions destrutivas
|
|
41
|
+
ainda não faz parte desta integração; até que esse fluxo exista, exponha somente operações de
|
|
42
|
+
leitura.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## Menu de ações
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Menu` para reunir ações relacionadas em um painel ancorado. `MenuShortcut` posiciona o atalho à
|
|
4
|
+
direita; separe ações perigosas e declare `context="danger"` nelas.
|
|
4
5
|
|
|
5
6
|
```tsx preview
|
|
6
7
|
<Menu>
|
|
@@ -11,16 +12,15 @@
|
|
|
11
12
|
<MenuItem><Pencil /> Editar <MenuShortcut>⌘E</MenuShortcut></MenuItem>
|
|
12
13
|
<MenuItem><Copy /> Duplicar</MenuItem>
|
|
13
14
|
<MenuSeparator />
|
|
14
|
-
<MenuItem
|
|
15
|
+
<MenuItem context="danger"><Trash2 /> Excluir</MenuItem>
|
|
15
16
|
</MenuContent>
|
|
16
17
|
</Menu>
|
|
17
18
|
```
|
|
18
19
|
|
|
19
|
-
##
|
|
20
|
+
## Abrir pelo menu de contexto
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
um gatilho invisível `position: fixed` naquele ponto ancora o conteúdo.
|
|
22
|
+
Para abrir pelo clique direito, controle o estado do menu e use a posição do ponteiro como âncora.
|
|
23
|
+
Esse padrão substitui o antigo `ContextMenu` sem introduzir outra família de componentes.
|
|
24
24
|
|
|
25
25
|
```tsx preview
|
|
26
26
|
const [pos, setPos] = useState(null)
|
|
@@ -44,16 +44,17 @@ render(
|
|
|
44
44
|
<MenuItem><Pencil /> Renomear</MenuItem>
|
|
45
45
|
<MenuItem><Copy /> Duplicar</MenuItem>
|
|
46
46
|
<MenuSeparator />
|
|
47
|
-
<MenuItem
|
|
47
|
+
<MenuItem context="danger"><Trash2 /> Excluir</MenuItem>
|
|
48
48
|
</MenuContent>
|
|
49
49
|
</Menu>
|
|
50
50
|
</div>,
|
|
51
51
|
)
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
## Seleção
|
|
54
|
+
## Seleção por checkbox ou radio
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Use `MenuCheckboxItem` para opções independentes e `MenuRadioGroup` para escolhas mutuamente
|
|
57
|
+
exclusivas. O consumidor controla o estado nos dois casos.
|
|
57
58
|
|
|
58
59
|
```tsx preview
|
|
59
60
|
const [showArchived, setShowArchived] = useState(false)
|
|
@@ -92,7 +93,7 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
92
93
|
<MenuContent align="start">
|
|
93
94
|
<MenuItem><ExternalLink /> Abrir preview</MenuItem>
|
|
94
95
|
<MenuSub>
|
|
95
|
-
<MenuSubTrigger><ArrowDownAZ /> Mover
|
|
96
|
+
<MenuSubTrigger><ArrowDownAZ /> Mover para</MenuSubTrigger>
|
|
96
97
|
<MenuSubContent>
|
|
97
98
|
<MenuItem>Empresa X</MenuItem>
|
|
98
99
|
<MenuItem>Softize</MenuItem>
|
|
@@ -103,12 +104,30 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
103
104
|
</Menu>
|
|
104
105
|
```
|
|
105
106
|
|
|
106
|
-
##
|
|
107
|
+
## Propriedades de MenuItem
|
|
107
108
|
|
|
108
|
-
|
|
|
109
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
109
110
|
|---|---|---|---|
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
| `context` | `'neutral' \| 'danger'` | `'neutral'` | `danger` sinaliza uma ação com consequência perigosa. |
|
|
112
|
+
| `inset` | `boolean` | | Alinha um item sem ícone com os itens que possuem ícone. |
|
|
113
|
+
|
|
114
|
+
## Propriedades de MenuContent
|
|
115
|
+
|
|
116
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alinhamento do painel em relação ao gatilho. |
|
|
119
|
+
| `sideOffset` | `number` | `4` | Distância entre o gatilho e o painel. |
|
|
120
|
+
|
|
121
|
+
## Propriedades de MenuCheckboxItem
|
|
122
|
+
|
|
123
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `checked` | `boolean` | | Estado controlado do item. |
|
|
126
|
+
| `onCheckedChange` | `(checked: boolean) => void` | | Chamado quando a pessoa alterna o item. |
|
|
127
|
+
|
|
128
|
+
## Propriedades de MenuRadioGroup
|
|
129
|
+
|
|
130
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `value` | `string` | | Valor selecionado no grupo. |
|
|
133
|
+
| `onValueChange` | `(value: string) => void` | | Chamado quando a pessoa seleciona outro `MenuRadioItem`. |
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
MetricCard apresenta uma medida resumida com hierarquia e espaçamento consistentes. Passe o
|
|
2
|
+
valor já calculado e formatado; busca de dados, recorte e regras de negócio permanecem no
|
|
3
|
+
consumidor.
|
|
4
|
+
|
|
5
|
+
```tsx preview col
|
|
6
|
+
<MetricCard
|
|
7
|
+
label="Total de cadastros"
|
|
8
|
+
value="286.317"
|
|
9
|
+
description="Prospects e clientes no cadastro global."
|
|
10
|
+
/>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Com ícone e ação
|
|
14
|
+
|
|
15
|
+
O ícone identifica visualmente a natureza da medida e é decorativo. `context="warning"` realça
|
|
16
|
+
somente o ícone; a superfície continua neutra. Use `action` apenas para uma ação diretamente
|
|
17
|
+
relacionada à medida. Um controle que explica o rótulo, como um tooltip, pertence a `labelAction`.
|
|
18
|
+
|
|
19
|
+
```tsx preview col
|
|
20
|
+
<MetricCard
|
|
21
|
+
label="Credencial"
|
|
22
|
+
value="Ausente"
|
|
23
|
+
description="Reconecte para autorizar novamente o acesso."
|
|
24
|
+
icon={<KeyRound />}
|
|
25
|
+
context="warning"
|
|
26
|
+
action={
|
|
27
|
+
<Button size="sm" variant="outline">
|
|
28
|
+
Reconectar
|
|
29
|
+
</Button>
|
|
30
|
+
}
|
|
31
|
+
/>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Carregamento
|
|
35
|
+
|
|
36
|
+
`loading` preserva a geometria do card com placeholders e marca a superfície como ocupada para
|
|
37
|
+
tecnologias assistivas. O contêiner da coleção continua responsável pela mensagem de carregamento.
|
|
38
|
+
|
|
39
|
+
```tsx preview col
|
|
40
|
+
<MetricCard loading />
|
|
41
|
+
```
|
|
@@ -4,8 +4,8 @@ title: Observabilidade
|
|
|
4
4
|
|
|
5
5
|
# Observabilidade
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Use `ObservabilityAdapter` para envolver actions e reactions em spans sem acoplar o core a um
|
|
8
|
+
fornecedor. O driver OpenTelemetry deixa backend, exporter e Collector sob controle do aplicativo.
|
|
9
9
|
|
|
10
10
|
## Driver OpenTelemetry
|
|
11
11
|
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
## Esqueleto de página
|
|
2
2
|
|
|
3
3
|
Use `Page` para manter título, contexto, ações e conteúdo no mesmo ritmo visual nas telas do
|
|
4
|
-
back-office.
|
|
5
|
-
|
|
4
|
+
back-office. Em larguras amplas, as ações ficam no extremo oposto e acompanham a base do conjunto
|
|
5
|
+
formado pelo título e pela descrição; em larguras estreitas, passam para uma linha abaixo do
|
|
6
|
+
contexto. O container é centralizado e ocupa a largura disponível até `80rem` (`max-w-7xl`). Use
|
|
6
7
|
`className` somente quando a composição pedir explicitamente outro teto ou largura total. A área
|
|
7
8
|
abaixo do cabeçalho permanece livre para tabelas, cards ou outras composições.
|
|
8
9
|
|
|
10
|
+
A forma curta é o padrão para páginas comuns. Ela cria internamente `PageHeader` e `PageBody`;
|
|
11
|
+
portanto, não produz uma estrutura visual ou semântica diferente da forma explícita.
|
|
12
|
+
|
|
13
|
+
`Page` é o esqueleto de páginas e recursos delimitados. Ele também pode ocupar o painel principal
|
|
14
|
+
de um shell com sidebar; a navegação lateral não exige remover o teto nem reconstruir o cabeçalho.
|
|
15
|
+
Uma navegação contextual para outra página pode ocupar `actions`, e tabs ficam reservados a
|
|
16
|
+
recortes da mesma superfície. Canvas e outros workspaces espaciais imersivos podem usar um shell
|
|
17
|
+
próprio quando o cabeçalho reduzir a área útil ou duplicar controles persistentes da superfície.
|
|
18
|
+
|
|
19
|
+
Estados integrais de carregamento, falha ou ausência são compostos no body com `PageState`,
|
|
20
|
+
detalhado abaixo. `Page` não recebe flags de dados: uma página pode agregar fontes independentes e
|
|
21
|
+
uma falha parcial não deve ocultar as demais seções.
|
|
22
|
+
|
|
9
23
|
```tsx preview col
|
|
10
24
|
render(
|
|
11
25
|
<div className="w-full overflow-hidden rounded-lg border border-border">
|
|
@@ -27,13 +41,82 @@ render(
|
|
|
27
41
|
)
|
|
28
42
|
```
|
|
29
43
|
|
|
30
|
-
##
|
|
44
|
+
## Composição explícita
|
|
45
|
+
|
|
46
|
+
Use os slots quando a página precisar compor o header diretamente. Não misture propriedades da
|
|
47
|
+
forma curta com `PageHeader` ou `PageBody`.
|
|
48
|
+
|
|
49
|
+
```tsx preview col
|
|
50
|
+
render(
|
|
51
|
+
<Page>
|
|
52
|
+
<PageHeader>
|
|
53
|
+
<PageTitle>Workspaces</PageTitle>
|
|
54
|
+
<PageMeta>3</PageMeta>
|
|
55
|
+
<PageDescription>Ambientes compartilhados pela equipe.</PageDescription>
|
|
56
|
+
<PageActions><Button><Plus /> Novo workspace</Button></PageActions>
|
|
57
|
+
</PageHeader>
|
|
58
|
+
<PageBody>
|
|
59
|
+
<div className="rounded-lg border border-dashed border-border p-10 text-center">
|
|
60
|
+
O conteúdo da página.
|
|
61
|
+
</div>
|
|
62
|
+
</PageBody>
|
|
63
|
+
</Page>,
|
|
64
|
+
)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Estados integrais
|
|
68
|
+
|
|
69
|
+
Use `PageState` quando carregamento, falha ou ausência substituírem todo o conteúdo principal. Na
|
|
70
|
+
forma curta ele pode ser escrito como filho direto de `Page`, que cria o `PageBody`; na forma
|
|
71
|
+
explícita, coloque-o dentro de `PageBody`. O cabeçalho continua visível e o estado recebe composição,
|
|
72
|
+
altura e semântica acessível consistentes.
|
|
73
|
+
|
|
74
|
+
```tsx preview col
|
|
75
|
+
<Page title="Relatório">
|
|
76
|
+
<PageState
|
|
77
|
+
status="error"
|
|
78
|
+
title="Não foi possível carregar o relatório"
|
|
79
|
+
description="Tente novamente. Se o problema continuar, volte mais tarde."
|
|
80
|
+
action={<Button>Tentar novamente</Button>}
|
|
81
|
+
/>
|
|
82
|
+
</Page>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`loading` centraliza o `Spinner`; `error` compõe `Alert`; `empty` compõe `Empty`; e `ready` entrega
|
|
86
|
+
os filhos sem acrescentar uma superfície.
|
|
87
|
+
|
|
88
|
+
```tsx preview col
|
|
89
|
+
<Page title="Relatórios">
|
|
90
|
+
<PageState
|
|
91
|
+
status="empty"
|
|
92
|
+
title="Nenhum relatório"
|
|
93
|
+
description="Crie o primeiro relatório para começar."
|
|
94
|
+
action={<Button>Novo relatório</Button>}
|
|
95
|
+
/>
|
|
96
|
+
</Page>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Não use `PageState` para uma falha parcial. Se outra parte da página continua utilizável, mantenha o
|
|
100
|
+
estado na própria seção com `DataState`, `ActionView`, `ActionList` ou `Alert`.
|
|
101
|
+
|
|
102
|
+
## Propriedades de Page
|
|
103
|
+
|
|
104
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
105
|
+
| ------------- | ----------- | ----------- | ----------------------------------------------------------------------------------------------- |
|
|
106
|
+
| `title` | `string` | | O h1 da página. |
|
|
107
|
+
| `count` | `number` | | Total de itens ao lado do título (mono, esmaecido). |
|
|
108
|
+
| `description` | `ReactNode` | | Linha de contexto sob o título (ex.: "N no total · X ativos"). |
|
|
109
|
+
| `actions` | `ReactNode` | | Ações contextuais no extremo oposto do cabeçalho; em telas estreitas, ficam abaixo do contexto. |
|
|
110
|
+
| `className` | `string` | `max-w-7xl` | Classes do container para substituir o teto padrão de `80rem`. |
|
|
111
|
+
| `children` | `ReactNode` | | O body da página — espaçamento e diagramação são seus. |
|
|
112
|
+
|
|
113
|
+
## Propriedades de PageState
|
|
31
114
|
|
|
32
|
-
|
|
|
115
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
33
116
|
|---|---|---|---|
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `description` | `ReactNode` | |
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `children` | `ReactNode` | |
|
|
117
|
+
| `status` | `'loading' \| 'error' \| 'empty' \| 'ready'` | | Estado integral do conteúdo. |
|
|
118
|
+
| `title` | `ReactNode` | Texto seguro por estado | Situação reconhecível pela pessoa. |
|
|
119
|
+
| `description` | `ReactNode` | | Impacto ou próximo passo aplicável. |
|
|
120
|
+
| `icon` | `ReactNode` | Alerta no erro | Ícone decorativo do estado. |
|
|
121
|
+
| `action` | `ReactNode` | | Recuperação, seleção ou criação aplicável. |
|
|
122
|
+
| `children` | `ReactNode` | | Conteúdo renderizado somente em `ready`. |
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Navegação entre páginas
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
É o único paginador da casa: `ActionList` compõe esta primitiva no rodapé, na escala densa.
|
|
3
|
+
Componha `Pagination`, `PaginationContent` e um `PaginationItem` para cada link. `page` fornece o
|
|
4
|
+
número e o nome acessível; `isActive` identifica a página atual. Os controles mantêm altura fixa e
|
|
5
|
+
a largura cresce quando o número precisa de mais espaço. `ActionList` usa esta mesma primitiva no
|
|
6
|
+
rodapé.
|
|
8
7
|
|
|
9
8
|
```tsx preview
|
|
10
9
|
<Pagination>
|
|
@@ -30,7 +29,7 @@ colam. As setas seguem quadradas e já falam pt-BR; `label` localiza, `iconOnly`
|
|
|
30
29
|
|
|
31
30
|
## Números longos
|
|
32
31
|
|
|
33
|
-
A largura mínima é quadrada
|
|
32
|
+
A largura mínima é quadrada e cresce conforme o conteúdo. Na escala densa de um rodapé, ajuste por
|
|
34
33
|
`className` (`h-7 min-w-7 text-xs` nos números; `size-7` mais `iconClassName="size-3.5"` nas
|
|
35
34
|
setas com `iconOnly`).
|
|
36
35
|
|
|
@@ -61,7 +60,8 @@ setas com `iconOnly`).
|
|
|
61
60
|
|
|
62
61
|
## Com elipse
|
|
63
62
|
|
|
64
|
-
PaginationEllipsis
|
|
63
|
+
`PaginationEllipsis` marca, de forma decorativa e com `aria-hidden`, uma sequência de páginas que
|
|
64
|
+
não cabe na barra.
|
|
65
65
|
|
|
66
66
|
```tsx preview
|
|
67
67
|
<Pagination>
|
|
@@ -123,14 +123,19 @@ render(
|
|
|
123
123
|
)
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
##
|
|
126
|
+
## Propriedades de PaginationLink
|
|
127
127
|
|
|
128
|
-
|
|
|
128
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
129
129
|
|---|---|---|---|
|
|
130
|
-
| `page
|
|
131
|
-
| `isActive
|
|
132
|
-
| `href
|
|
133
|
-
| `size
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
| `page` | `number` | | Número usado como conteúdo, quando `children` não é informado, e no nome acessível “Página N”. |
|
|
131
|
+
| `isActive` | `boolean` | `false` | Marca a página atual com `aria-current="page"` e tratamento `outline`. |
|
|
132
|
+
| `href` | `string` | | Renderiza um `<a>`. Sem `href`, o componente usa `<button>` e aceita `onClick` e `disabled`. |
|
|
133
|
+
| `size` | `'default' \| 'sm' \| 'lg' \| 'icon' \| 'icon-sm' \| 'icon-xs'` | `'default'` | Escala herdada de `Button`. A largura mínima cresce para acomodar números longos. |
|
|
134
|
+
|
|
135
|
+
## Propriedades de PaginationPrevious e PaginationNext
|
|
136
|
+
|
|
137
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| `label` | `string` | `'Página anterior'` ou `'Próxima página'` | Nome acessível e texto visível da ação. |
|
|
140
|
+
| `iconOnly` | `boolean` | `false` | Exibe somente a seta; `label` continua disponível para leitura assistiva. |
|
|
141
|
+
| `iconClassName` | `string` | | Classes aplicadas ao ícone da seta. |
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Painel ancorado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Popover` para apresentar conteúdo livre junto a um gatilho, sem abrir um modal.
|
|
4
|
+
`PopoverHeader` agrupa título e descrição; o restante do painel aceita formulários curtos ou
|
|
5
|
+
detalhes.
|
|
4
6
|
|
|
5
7
|
```tsx preview
|
|
6
8
|
<Popover>
|
|
@@ -23,7 +25,7 @@ PopoverHeader agrupa título e descrição; o corpo é livre (form curto, detalh
|
|
|
23
25
|
|
|
24
26
|
## Alinhamento
|
|
25
27
|
|
|
26
|
-
align posiciona o painel em relação ao gatilho
|
|
28
|
+
`align` posiciona o painel em relação ao gatilho e `sideOffset` define a distância entre eles.
|
|
27
29
|
|
|
28
30
|
```tsx preview
|
|
29
31
|
<Popover>
|
|
@@ -40,10 +42,16 @@ align posiciona o painel em relação ao gatilho; sideOffset afasta. O padrão (
|
|
|
40
42
|
</Popover>
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
##
|
|
45
|
+
## Propriedades de Popover
|
|
44
46
|
|
|
45
|
-
|
|
|
47
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
46
48
|
|---|---|---|---|
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
|
|
49
|
+
| `open` | `boolean` | | Estado no modo controlado. |
|
|
50
|
+
| `onOpenChange` | `(open: boolean) => void` | | Atualiza o estado para permitir abertura ou fechamento por código. |
|
|
51
|
+
|
|
52
|
+
## Propriedades de PopoverContent
|
|
53
|
+
|
|
54
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alinhamento do painel em relação ao gatilho. |
|
|
57
|
+
| `sideOffset` | `number` | `4` | Distância entre o gatilho e o painel. |
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Progresso determinado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Progress` quando a tarefa informar uma porcentagem de conclusão. `value` aceita valores de 0 a
|
|
4
|
+
100 e anima o preenchimento a cada mudança. Sem valor, a barra permanece vazia.
|
|
4
5
|
|
|
5
6
|
```tsx preview col
|
|
6
7
|
<div className="w-full max-w-sm space-y-2">
|
|
@@ -14,7 +15,8 @@ value vai de 0 a 100 — o preenchimento anima a cada mudança. Sem value (ou nu
|
|
|
14
15
|
|
|
15
16
|
## Controlado
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Controle `value` externamente quando o progresso acompanhar uma tarefa em andamento. No exemplo,
|
|
19
|
+
cada clique avança uma etapa da sincronização.
|
|
18
20
|
|
|
19
21
|
```tsx preview col
|
|
20
22
|
const [step, setStep] = useState(40)
|
|
@@ -61,9 +63,9 @@ className compõe sobre o padrão: ajuste a altura no Progress e tinja o preench
|
|
|
61
63
|
</div>
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
##
|
|
66
|
+
## Propriedades de Progress
|
|
65
67
|
|
|
66
|
-
|
|
|
68
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
67
69
|
|---|---|---|---|
|
|
68
70
|
| `value` | `number \| null` | | O progresso de 0 a 100. O preenchimento anima a cada mudança; null/ausente deixa a barra vazia. |
|
|
69
71
|
| `className` | `string` | | Compõe sobre o padrão — ajuste a altura (h-1.5/h-3) ou tinja o indicador via [&_[data-slot=progress-indicator]]:bg-*. |
|