@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.
Files changed (154) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/bin/lib/check.mjs +1098 -310
  3. package/bin/lib/copy.mjs +12 -5
  4. package/docs/adr/0003-dictionary-presentation-is-declared.md +3 -0
  5. package/docs/adr/0004-page-content-state-is-composed.md +65 -0
  6. package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +180 -0
  7. package/docs/adr/0006-semantic-context-precedes-visual-variant.md +182 -0
  8. package/docs/adr/0007-toast-actions-form-an-ordered-collection.md +63 -0
  9. package/docs/adr/0008-hierarchical-navigation-is-composed-at-the-consumer-boundary.md +71 -0
  10. package/docs/radius-scale.md +1 -1
  11. package/package.json +1 -1
  12. package/registry/instructions/opus.md +5 -0
  13. package/registry/skills/build-opus-ui/SKILL.md +27 -16
  14. package/registry/skills/build-opus-ui/references/evaluations.md +16 -5
  15. package/registry/skills/build-opus-ui/references/ui-patterns.md +38 -15
  16. package/registry/skills/maintain-opus-docs/SKILL.md +83 -0
  17. package/registry/skills/maintain-opus-docs/agents/openai.yaml +4 -0
  18. package/registry/skills/maintain-opus-docs/references/editorial-standard.md +85 -0
  19. package/registry/skills/maintain-opus-docs/references/evaluations.md +34 -0
  20. package/registry/skills/maintain-opus-docs/scripts/audit-docs.mjs +81 -0
  21. package/registry/skills/model-opus-dictionary/SKILL.md +4 -2
  22. package/registry/skills/model-opus-dictionary/references/evaluations.md +4 -3
  23. package/registry/templates/app/src/App.tsx +1 -1
  24. package/src/core/dictionary.ts +52 -14
  25. package/src/core/index.ts +10 -0
  26. package/src/core/ui-context.ts +29 -0
  27. package/src/schema/drivers/zod.ts +17 -8
  28. package/src/ui/components/patterns/action-form-card.tsx +18 -12
  29. package/src/ui/components/patterns/confirm.tsx +163 -40
  30. package/src/ui/components/patterns/content-header.tsx +335 -61
  31. package/src/ui/components/patterns/data-state.tsx +23 -10
  32. package/src/ui/components/patterns/list.tsx +1097 -783
  33. package/src/ui/components/patterns/page-state.tsx +115 -0
  34. package/src/ui/components/patterns/page.tsx +231 -41
  35. package/src/ui/components/patterns/sidebar.tsx +357 -83
  36. package/src/ui/components/patterns/trigger.tsx +37 -30
  37. package/src/ui/components/patterns/view.tsx +7 -11
  38. package/src/ui/components/primitives/alert.tsx +298 -110
  39. package/src/ui/components/primitives/ask.tsx +2 -1
  40. package/src/ui/components/primitives/badge.tsx +91 -30
  41. package/src/ui/components/primitives/button.tsx +99 -60
  42. package/src/ui/components/primitives/calendar.tsx +39 -39
  43. package/src/ui/components/primitives/card.tsx +96 -23
  44. package/src/ui/components/primitives/detail.tsx +2 -2
  45. package/src/ui/components/primitives/dialog.tsx +196 -39
  46. package/src/ui/components/primitives/dictionary-value.tsx +9 -14
  47. package/src/ui/components/primitives/dot.tsx +74 -21
  48. package/src/ui/components/primitives/drawer.tsx +40 -24
  49. package/src/ui/components/primitives/empty.tsx +3 -3
  50. package/src/ui/components/primitives/item.tsx +135 -79
  51. package/src/ui/components/primitives/menu.tsx +11 -3
  52. package/src/ui/components/primitives/metric-card.tsx +133 -0
  53. package/src/ui/components/primitives/sonner.tsx +187 -8
  54. package/src/ui/components/primitives/table.tsx +2 -2
  55. package/src/ui/docs/DocBrowser.tsx +104 -25
  56. package/src/ui/docs/changelog.tsx +1 -1
  57. package/src/ui/docs/content/accordion.md +22 -16
  58. package/src/ui/docs/content/action-form-card.md +8 -8
  59. package/src/ui/docs/content/action-form-dialog.md +9 -9
  60. package/src/ui/docs/content/action-form.md +28 -34
  61. package/src/ui/docs/content/action-list-dialog.md +11 -6
  62. package/src/ui/docs/content/action-list.md +64 -39
  63. package/src/ui/docs/content/action-trigger.md +21 -14
  64. package/src/ui/docs/content/action-view.md +8 -8
  65. package/src/ui/docs/content/actions.md +9 -9
  66. package/src/ui/docs/content/ai.md +3 -3
  67. package/src/ui/docs/content/alert.md +54 -28
  68. package/src/ui/docs/content/aspect-ratio.md +4 -4
  69. package/src/ui/docs/content/audit.md +2 -2
  70. package/src/ui/docs/content/auth.md +3 -3
  71. package/src/ui/docs/content/avatar.md +34 -14
  72. package/src/ui/docs/content/badge.md +21 -22
  73. package/src/ui/docs/content/breadcrumb.md +13 -8
  74. package/src/ui/docs/content/button.md +93 -15
  75. package/src/ui/docs/content/calendar.md +5 -5
  76. package/src/ui/docs/content/card.md +6 -6
  77. package/src/ui/docs/content/carousel.md +16 -11
  78. package/src/ui/docs/content/chat.md +3 -3
  79. package/src/ui/docs/content/checkbox.md +7 -7
  80. package/src/ui/docs/content/cli.md +5 -5
  81. package/src/ui/docs/content/collapsible.md +8 -8
  82. package/src/ui/docs/content/command.md +16 -8
  83. package/src/ui/docs/content/composer.md +2 -2
  84. package/src/ui/docs/content/content.md +44 -0
  85. package/src/ui/docs/content/copyable.md +4 -3
  86. package/src/ui/docs/content/customization.md +7 -7
  87. package/src/ui/docs/content/cycle.md +3 -3
  88. package/src/ui/docs/content/data-state.md +11 -12
  89. package/src/ui/docs/content/data.md +26 -33
  90. package/src/ui/docs/content/detail.md +8 -5
  91. package/src/ui/docs/content/dialog.md +339 -31
  92. package/src/ui/docs/content/dictionary-value.md +19 -18
  93. package/src/ui/docs/content/dock.md +3 -3
  94. package/src/ui/docs/content/dot.md +7 -7
  95. package/src/ui/docs/content/drawer.md +32 -16
  96. package/src/ui/docs/content/empty-value.md +2 -2
  97. package/src/ui/docs/content/empty.md +19 -12
  98. package/src/ui/docs/content/events.md +4 -4
  99. package/src/ui/docs/content/field.md +34 -12
  100. package/src/ui/docs/content/getting-started.md +1 -1
  101. package/src/ui/docs/content/icon-picker.md +8 -4
  102. package/src/ui/docs/content/input-otp.md +20 -12
  103. package/src/ui/docs/content/input.md +121 -9
  104. package/src/ui/docs/content/item.md +64 -24
  105. package/src/ui/docs/content/kbd.md +19 -11
  106. package/src/ui/docs/content/label.md +5 -3
  107. package/src/ui/docs/content/log.md +4 -4
  108. package/src/ui/docs/content/markdown.md +7 -6
  109. package/src/ui/docs/content/mcp.md +13 -15
  110. package/src/ui/docs/content/menu.md +36 -17
  111. package/src/ui/docs/content/metric-card.md +41 -0
  112. package/src/ui/docs/content/observability.md +2 -2
  113. package/src/ui/docs/content/page.md +93 -10
  114. package/src/ui/docs/content/pagination.md +22 -17
  115. package/src/ui/docs/content/popover.md +16 -8
  116. package/src/ui/docs/content/progress.md +7 -5
  117. package/src/ui/docs/content/queue.md +5 -5
  118. package/src/ui/docs/content/radio-group.md +20 -12
  119. package/src/ui/docs/content/router.md +11 -6
  120. package/src/ui/docs/content/scheduler.md +4 -5
  121. package/src/ui/docs/content/scroll-area.md +12 -7
  122. package/src/ui/docs/content/select.md +42 -29
  123. package/src/ui/docs/content/semantic-context.md +63 -0
  124. package/src/ui/docs/content/separator.md +5 -5
  125. package/src/ui/docs/content/sidebar.md +325 -56
  126. package/src/ui/docs/content/skeleton.md +5 -4
  127. package/src/ui/docs/content/slider.md +8 -7
  128. package/src/ui/docs/content/spinner.md +8 -8
  129. package/src/ui/docs/content/split.md +8 -5
  130. package/src/ui/docs/content/storage.md +6 -8
  131. package/src/ui/docs/content/switch.md +8 -7
  132. package/src/ui/docs/content/table.md +16 -6
  133. package/src/ui/docs/content/tabs.md +28 -14
  134. package/src/ui/docs/content/testing.md +9 -11
  135. package/src/ui/docs/content/textarea.md +5 -4
  136. package/src/ui/docs/content/toast.md +47 -13
  137. package/src/ui/docs/content/toggle.md +75 -7
  138. package/src/ui/docs/content/tokens.md +31 -3
  139. package/src/ui/docs/content/tooltip.md +19 -11
  140. package/src/ui/docs/content/truncate.md +7 -8
  141. package/src/ui/docs/content/ui.md +10 -9
  142. package/src/ui/docs/content/upgrading.md +7 -8
  143. package/src/ui/docs/doc-client.tsx +2 -2
  144. package/src/ui/docs/registry.tsx +580 -229
  145. package/src/ui/lib/semantic-context.ts +30 -0
  146. package/src/ui/meta.ts +278 -286
  147. package/src/ui/react.tsx +377 -111
  148. package/src/ui/theme.css +116 -0
  149. package/src/ui/components/primitives/alert-dialog.tsx +0 -190
  150. package/src/ui/docs/content/alert-dialog.md +0 -73
  151. package/src/ui/docs/content/button-group.md +0 -71
  152. package/src/ui/docs/content/confirm.md +0 -120
  153. package/src/ui/docs/content/input-group.md +0 -78
  154. package/src/ui/docs/content/toggle-group.md +0 -81
@@ -1,6 +1,7 @@
1
- ## Básico
1
+ ## Uma tecla
2
2
 
3
- Uma tecla por Kbd. É visual quem escuta o atalho é o seu handler, não o componente.
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
- Envolva as teclas num KbdGroup e ponha o conector (+) como texto entre elas — o padrão pra paleta de comandos do Maestro.
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 (lucide) como filho do Kbd ganha size-3 automático — bom pra ⌘ e Enter, onde o glifo melhor que a letra.
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 um TooltipContent o Kbd inverte o tom sozinho (fundo claro sobre o balão escuro) — anuncie o atalho da ação ao passar o mouse.
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
- ## Props
58
+ ## Propriedades de Kbd
56
59
 
57
- | Prop | Tipo | Default | Descrição |
60
+ | Propriedade | Tipo | Padrão | Descrição |
58
61
  |---|---|---|---|
59
- | `children (Kbd)` | `React.ReactNode` | | A tecla texto (Esc, ⌘, K) ou um ícone lucide, que recebe size-3 automático. |
60
- | `className (Kbd)` | `string` | | Classes extras na tecla, mescladas com cn — pra ajustar tamanho ou cor pontualmente. |
61
- | `children (KbdGroup)` | `React.ReactNode` | | As teclas do combo, mais o conector (ex.: "+") como texto entre elas. |
62
- | `className (KbdGroup)` | `string` | | Classes extras no agrupador (inline-flex + gap-1), mescladas com cn. |
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 aponta pro id do controle clicar no rótulo foca o campo.
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
- O Label já é flex com gap controle inline entra sem wrapper extra; clicar no texto alterna a caixa.
14
+ `Label`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
- Controle disabled esmaece o rótulo junto (peer-disabled) o par inteiro comunica o estado, sem classe manual.
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
- Log estruturado que chega no handler com contexto (per-request, per-action) via
8
- `ctx.log`. O contrato é o `LoggerAdapter` a mesma interface `Logger` que o core usa por
9
- dentro, então o seu log e o do runtime saem no mesmo lugar, no mesmo formato.
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 (por enquanto)
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
- Uso: <Markdown content={fonte} />. No palco, o resultado; no bloco abaixo, a fonte markdown que o produziu. O componente recebe só content: string.
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 MESMO que renderiza estas páginas.',
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, pro tom certo.',
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
- ## Props
37
+ ## Propriedades de Markdown
37
38
 
38
- | Prop | Tipo | Default | Descrição |
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 pra texto vindo de gente ou de modelo. |
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
- Expõe as actions `ai:enabled` do runtime como **tools MCP** — a porta pra uma IA de **fora**
8
- (Claude Desktop, o agente de um parceiro, um hub próprio) alcançar o app pelo protocolo. É o
9
- mesmo bridge do agente co-locado (`runtime.aiTools`) e a mesma execução (`runtime.execute`,
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 pra remoto
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
- ## Interno × MCP
31
+ ## Escolher entre integração interna e MCP
33
32
 
34
- - **Monolito / chat co-locado:** não precisa de MCP — `runtime.aiFor(base).run()` chama as
35
- actions direto, in-process (ver o recurso **IA generativa**).
36
- - **IA por fora / ecossistema:** o agente vive num serviço próprio e alcança N apps pela
37
- mesma porta MCP. É aqui que ele se paga.
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
- Mesmas tools, transportes diferentes.
38
+ ## Limites atuais
40
39
 
41
- ## Limites (por enquanto)
42
-
43
- Você monta o transporte (stdio/HTTP) — o server é agnóstico. A confirmação de action
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
- Ícone à esquerda, atalho à direita (MenuShortcut), separador antes da zona perigosa e variant destructive na ação que destrói.
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 variant="destructive"><Trash2 /> Excluir</MenuItem>
15
+ <MenuItem context="danger"><Trash2 /> Excluir</MenuItem>
15
16
  </MenuContent>
16
17
  </Menu>
17
18
  ```
18
19
 
19
- ## Contexto: clique direito
20
+ ## Abrir pelo menu de contexto
20
21
 
21
- O papel do ContextMenu (aposentado na 5.0.0) com o MESMO componente muda o
22
- gatilho: controlado, ancorado no ponteiro. `onContextMenu` guarda a posição e abre;
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 variant="destructive"><Trash2 /> Excluir</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: checkbox e radio
54
+ ## Seleção por checkbox ou radio
55
55
 
56
- CheckboxItem pra liga/desliga, RadioGroup pra escolha exclusiva estado fica no consumidor (controlado).
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 pra</MenuSubTrigger>
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
- ## Props
107
+ ## Propriedades de MenuItem
107
108
 
108
- | Prop | Tipo | Default | Descrição |
109
+ | Propriedade | Tipo | Padrão | Descrição |
109
110
  |---|---|---|---|
110
- | `MenuItem.variant` | `'default' \| 'destructive'` | `'default'` | destructive tonaliza texto e foco em vermelho — só pra ação que destrói. |
111
- | `MenuItem.inset` | `boolean` | | Recuo à esquerda pra alinhar item sem ícone com os que têm. |
112
- | `MenuContent.align / sideOffset` | `'start' \| 'center' \| 'end' / number` | `'center' / 4` | Alinhamento e distância em relação ao gatilho (Radix). |
113
- | `MenuCheckboxItem.checked / onCheckedChange` | `boolean / (checked: boolean) => void` | | Estado do liga/desliga — controlado pelo consumidor. |
114
- | `MenuRadioGroup.value / onValueChange` | `string / (value: string) => void` | | Escolha exclusiva entre os MenuRadioItem filhos. |
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
- O core expõe uma porta vendor-neutral; o driver OpenTelemetry cria spans ativos para actions
8
- e reactions sem escolher backend, exporter ou Collector.
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. As ações ficam à direita e acompanham a base do conjunto formado pelo título e pela
5
- descrição. O container é centralizado e ocupa a largura disponível até `72rem` (`max-w-6xl`). Use
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
- ## Props
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
- | Prop | Tipo | Default | Descrição |
115
+ | Propriedade | Tipo | Padrão | Descrição |
33
116
  |---|---|---|---|
34
- | `title` | `string` | | O h1 da página. |
35
- | `count` | `number` | | Total de itens ao lado do título (mono, esmaecido). |
36
- | `description` | `ReactNode` | | Linha de contexto sob o título (ex.: "N no total · X ativos"). |
37
- | `actions` | `ReactNode` | | Ações à direita do cabeçalho, alinhadas à base do título e da descrição. |
38
- | `className` | `string` | `max-w-6xl` | Classes do container para substituir o teto padrão de `72rem`. |
39
- | `children` | `ReactNode` | | O conteúdo espaçamento e diagramação são seus. |
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
- ## Básico
1
+ ## Navegação entre páginas
2
2
 
3
- É composição: Pagination embrulha PaginationContent, e cada PaginationItem segura um link. `page`
4
- dá o número e o nome acessível (“Página N”); `isActive` marca a página atual (vira outline). Cada
5
- número tem altura fixa e largura mínima quadrada que cresce com os dígitos 5726 e 5727 nunca se
6
- colam. As setas seguem quadradas e já falam pt-BR; `label` localiza, `iconOnly` deixa só a seta.
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; o número manda no resto. Na escala densa de um rodapé, ajuste por
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 é o atalho decorativo (aria-hidden) entre blocos de páginas distantes — útil quando a lista de sessões do workspace tem páginas demais pra caber na barra.
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
- ## Props
126
+ ## Propriedades de PaginationLink
127
127
 
128
- | Prop | Tipo | Default | Descrição |
128
+ | Propriedade | Tipo | Padrão | Descrição |
129
129
  |---|---|---|---|
130
- | `page (PaginationLink)` | `number` | | Número da página: vira o conteúdo (quando não há `children`) e o nome acessível “Página N”. |
131
- | `isActive (PaginationLink)` | `boolean` | `false` | Marca a página atual: vira outline e ganha aria-current="page". Os demais ficam ghost. |
132
- | `href (PaginationLink)` | `string` | | Com `href` o link é um `<a>`; sem `href` é um `<button>` controlado por `onClick`, com `disabled`. |
133
- | `size (PaginationLink)` | `'default' \| 'sm' \| 'lg' \| 'icon' \| 'icon-sm' \| 'icon-xs'` | `'default'` | Escala do Button. Números usam `default` (largura mínima quadrada que cresce); as setas com `iconOnly` usam `icon`. |
134
- | `label (Previous/Next)` | `string` | `'Página anterior'` / `'Próxima página'` | Nome acessível e texto visível das setas. |
135
- | `iconOnly (Previous/Next)` | `boolean` | `false` | Só a seta, quadrada (`size="icon"`); o `label` continua como nome acessível. |
136
- | `iconClassName (Previous/Next)` | `string` | | Classe do svg da seta, para a escala densa (`size-3.5`). |
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
- ## Estrutura
1
+ ## Painel ancorado
2
2
 
3
- PopoverHeader agrupa título e descrição; o corpo é livre (form curto, detalhes). Superfície bg-popover — a elevação da casa.
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; sideOffset afasta. O padrão (center) serve pra quase tudo.
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
- ## Props
45
+ ## Propriedades de Popover
44
46
 
45
- | Prop | Tipo | Default | Descrição |
47
+ | Propriedade | Tipo | Padrão | Descrição |
46
48
  |---|---|---|---|
47
- | `PopoverContent.align` | `'start' \| 'center' \| 'end'` | `'center'` | Alinhamento do painel em relação ao gatilho. |
48
- | `PopoverContent.sideOffset` | `number` | `4` | Distância (px) entre gatilho e painel. |
49
- | `Popover.open / onOpenChange` | `boolean / (open: boolean) => void` | | Modo controlado (Radix) — pra fechar por código depois de salvar. |
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
- ## Básico
1
+ ## Progresso determinado
2
2
 
3
- value vai de 0 a 100 o preenchimento anima a cada mudança. Sem value (ou null) a barra fica vazia.
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
- Guarde o value no estado e atualize conforme a tarefa avança aqui cada clique soma um passo na sincronização do workspace Empresa X.
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
- ## Props
66
+ ## Propriedades de Progress
65
67
 
66
- | Prop | Tipo | Default | Descrição |
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-*. |