@softize/opus 12.11.0 → 13.1.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 (213) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/PROMOTED.md +46 -0
  3. package/README.md +28 -19
  4. package/bin/cli.mjs +87 -216
  5. package/bin/lib/check.mjs +2 -7
  6. package/bin/lib/cli-shared.mjs +131 -0
  7. package/bin/lib/copy.mjs +1 -5
  8. package/bin/lib/db.mjs +16 -74
  9. package/bin/lib/gen-openapi.mjs +3 -3
  10. package/bin/lib/gen-runner.mjs +1 -1
  11. package/bin/lib/gen.mjs +14 -69
  12. package/bin/lib/mcp.mjs +3 -1
  13. package/bin/lib/seed.mjs +5 -62
  14. package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +93 -10
  15. package/docs/adr/0007-toast-actions-form-an-ordered-collection.md +63 -0
  16. package/docs/adr/0008-hierarchical-navigation-is-composed-at-the-consumer-boundary.md +71 -0
  17. package/docs/ownership-vs-shadcn-lock.md +2 -3
  18. package/docs/protocol.md +7 -7
  19. package/docs/radius-scale.md +1 -1
  20. package/docs/releasing.md +8 -2
  21. package/package.json +7 -3
  22. package/registry/skills/maintain-opus-docs/SKILL.md +83 -0
  23. package/registry/skills/maintain-opus-docs/agents/openai.yaml +4 -0
  24. package/registry/skills/maintain-opus-docs/references/editorial-standard.md +85 -0
  25. package/registry/skills/maintain-opus-docs/references/evaluations.md +34 -0
  26. package/registry/skills/maintain-opus-docs/scripts/audit-docs.mjs +81 -0
  27. package/registry/templates/app/package.json +1 -1
  28. package/registry/templates/app/src/main.tsx +4 -4
  29. package/src/audit/drivers/console.ts +1 -0
  30. package/src/auth/drivers/better-auth.ts +1 -0
  31. package/src/auth/drivers/jwt.ts +1 -0
  32. package/src/cache/drivers/memory.ts +1 -0
  33. package/src/client/drivers/fetch.ts +2 -1
  34. package/src/core/actions.ts +6 -1
  35. package/src/core/audit.ts +9 -3
  36. package/src/core/contracts.ts +7 -0
  37. package/src/core/domain.ts +1 -1
  38. package/src/core/errors.ts +18 -15
  39. package/src/core/index.ts +4 -2
  40. package/src/core/package-version.ts +26 -0
  41. package/src/core/reactions.ts +1 -1
  42. package/src/core/runtime.ts +33 -23
  43. package/src/core/schedules.ts +1 -1
  44. package/src/core/types.ts +2 -2
  45. package/src/dsl/eval.ts +2 -2
  46. package/src/dsl/kysely.ts +2 -2
  47. package/src/dsl/loads.ts +1 -1
  48. package/src/dsl/parser.ts +5 -5
  49. package/src/events/drivers/mitt.ts +1 -0
  50. package/src/mcp/index.ts +2 -1
  51. package/src/observability/drivers/opentelemetry.ts +1 -0
  52. package/src/queue/drivers/bullmq.ts +3 -3
  53. package/src/scheduler/drivers/node-cron.ts +3 -2
  54. package/src/scheduler/every.ts +7 -7
  55. package/src/schema/openapi.ts +3 -3
  56. package/src/seed/index.ts +29 -0
  57. package/src/server/drivers/fastify.ts +5 -2
  58. package/src/server/drivers/node.ts +9 -6
  59. package/src/server/index.ts +3 -1
  60. package/src/storage/drivers/fs.ts +1 -0
  61. package/src/testing/index.ts +3 -3
  62. package/src/ui/components/patterns/confirm.tsx +142 -42
  63. package/src/ui/components/patterns/content-header.tsx +7 -1
  64. package/src/ui/components/patterns/data-state.tsx +1 -1
  65. package/src/ui/components/patterns/dock.tsx +20 -3
  66. package/src/ui/components/patterns/form.tsx +12 -8
  67. package/src/ui/components/patterns/list.tsx +36 -41
  68. package/src/ui/components/patterns/page-state.tsx +2 -2
  69. package/src/ui/components/patterns/page.tsx +19 -1
  70. package/src/ui/components/patterns/shell-nav.tsx +10 -3
  71. package/src/ui/components/patterns/sidebar.tsx +43 -32
  72. package/src/ui/components/patterns/trigger.tsx +39 -38
  73. package/src/ui/components/patterns/view.tsx +26 -17
  74. package/src/ui/components/primitives/alert.tsx +14 -8
  75. package/src/ui/components/primitives/ask.tsx +3 -3
  76. package/src/ui/components/primitives/badge.tsx +11 -6
  77. package/src/ui/components/primitives/breadcrumb.tsx +2 -2
  78. package/src/ui/components/primitives/button.tsx +16 -3
  79. package/src/ui/components/primitives/calendar.tsx +28 -2
  80. package/src/ui/components/primitives/carousel.tsx +3 -3
  81. package/src/ui/components/primitives/chat.tsx +1 -1
  82. package/src/ui/components/primitives/checkbox.tsx +1 -1
  83. package/src/ui/components/primitives/command.tsx +2 -2
  84. package/src/ui/components/primitives/control.ts +12 -0
  85. package/src/ui/components/primitives/copyable.tsx +1 -1
  86. package/src/ui/components/primitives/dialog.tsx +202 -40
  87. package/src/ui/components/primitives/dot.tsx +5 -0
  88. package/src/ui/components/primitives/drawer.tsx +18 -8
  89. package/src/ui/components/primitives/empty.tsx +3 -3
  90. package/src/ui/components/primitives/field.tsx +3 -3
  91. package/src/ui/components/primitives/icon-picker.tsx +3 -1
  92. package/src/ui/components/primitives/input-group.tsx +1 -1
  93. package/src/ui/components/primitives/input-otp.tsx +1 -1
  94. package/src/ui/components/primitives/input.tsx +2 -2
  95. package/src/ui/components/primitives/item.tsx +3 -3
  96. package/src/ui/components/primitives/progress.tsx +32 -3
  97. package/src/ui/components/primitives/radio-group.tsx +1 -1
  98. package/src/ui/components/primitives/resizable.tsx +3 -1
  99. package/src/ui/components/primitives/select.tsx +5 -5
  100. package/src/ui/components/primitives/slider.tsx +5 -1
  101. package/src/ui/components/primitives/sonner.tsx +190 -8
  102. package/src/ui/components/primitives/switch.tsx +1 -0
  103. package/src/ui/components/primitives/tabs.tsx +1 -0
  104. package/src/ui/components/primitives/textarea.tsx +1 -1
  105. package/src/ui/components/primitives/toggle.tsx +1 -1
  106. package/src/ui/components/primitives/tooltip.tsx +1 -0
  107. package/src/ui/docs/DocBrowser.tsx +102 -23
  108. package/src/ui/docs/changelog.tsx +1 -1
  109. package/src/ui/docs/content/accordion.md +22 -16
  110. package/src/ui/docs/content/action-form-card.md +8 -8
  111. package/src/ui/docs/content/action-form-dialog.md +9 -9
  112. package/src/ui/docs/content/action-form.md +37 -36
  113. package/src/ui/docs/content/action-list-dialog.md +11 -6
  114. package/src/ui/docs/content/action-list.md +73 -39
  115. package/src/ui/docs/content/action-trigger.md +29 -15
  116. package/src/ui/docs/content/action-view.md +17 -10
  117. package/src/ui/docs/content/actions.md +9 -9
  118. package/src/ui/docs/content/ai.md +3 -3
  119. package/src/ui/docs/content/alert.md +14 -12
  120. package/src/ui/docs/content/ask.md +11 -0
  121. package/src/ui/docs/content/aspect-ratio.md +4 -4
  122. package/src/ui/docs/content/audit.md +2 -2
  123. package/src/ui/docs/content/auth.md +3 -3
  124. package/src/ui/docs/content/avatar.md +34 -14
  125. package/src/ui/docs/content/badge.md +3 -3
  126. package/src/ui/docs/content/breadcrumb.md +13 -8
  127. package/src/ui/docs/content/button.md +81 -6
  128. package/src/ui/docs/content/calendar.md +18 -5
  129. package/src/ui/docs/content/card.md +27 -1
  130. package/src/ui/docs/content/carousel.md +16 -11
  131. package/src/ui/docs/content/chat.md +23 -3
  132. package/src/ui/docs/content/checkbox.md +7 -7
  133. package/src/ui/docs/content/cli.md +74 -22
  134. package/src/ui/docs/content/collapsible.md +8 -8
  135. package/src/ui/docs/content/command.md +16 -8
  136. package/src/ui/docs/content/composer.md +17 -2
  137. package/src/ui/docs/content/content.md +17 -2
  138. package/src/ui/docs/content/copyable.md +12 -3
  139. package/src/ui/docs/content/customization.md +5 -5
  140. package/src/ui/docs/content/cycle.md +3 -3
  141. package/src/ui/docs/content/data-state.md +11 -12
  142. package/src/ui/docs/content/data.md +26 -33
  143. package/src/ui/docs/content/detail.md +22 -4
  144. package/src/ui/docs/content/dialog.md +339 -31
  145. package/src/ui/docs/content/dictionary-value.md +17 -10
  146. package/src/ui/docs/content/dock.md +11 -3
  147. package/src/ui/docs/content/dot.md +8 -0
  148. package/src/ui/docs/content/drawer.md +27 -14
  149. package/src/ui/docs/content/empty-value.md +2 -2
  150. package/src/ui/docs/content/empty.md +19 -12
  151. package/src/ui/docs/content/events.md +4 -4
  152. package/src/ui/docs/content/field.md +34 -12
  153. package/src/ui/docs/content/getting-started.md +3 -3
  154. package/src/ui/docs/content/icon-picker.md +19 -4
  155. package/src/ui/docs/content/input-otp.md +20 -12
  156. package/src/ui/docs/content/input.md +121 -9
  157. package/src/ui/docs/content/item.md +27 -13
  158. package/src/ui/docs/content/kbd.md +19 -11
  159. package/src/ui/docs/content/label.md +12 -3
  160. package/src/ui/docs/content/log.md +4 -4
  161. package/src/ui/docs/content/markdown.md +7 -6
  162. package/src/ui/docs/content/mcp.md +13 -15
  163. package/src/ui/docs/content/menu.md +40 -16
  164. package/src/ui/docs/content/metric-card.md +13 -0
  165. package/src/ui/docs/content/observability.md +2 -2
  166. package/src/ui/docs/content/page.md +59 -6
  167. package/src/ui/docs/content/pagination.md +22 -17
  168. package/src/ui/docs/content/popover.md +22 -8
  169. package/src/ui/docs/content/progress.md +15 -16
  170. package/src/ui/docs/content/queue.md +5 -5
  171. package/src/ui/docs/content/radio-group.md +20 -12
  172. package/src/ui/docs/content/router.md +11 -6
  173. package/src/ui/docs/content/scheduler.md +4 -5
  174. package/src/ui/docs/content/scroll-area.md +12 -7
  175. package/src/ui/docs/content/select.md +47 -34
  176. package/src/ui/docs/content/semantic-context.md +2 -2
  177. package/src/ui/docs/content/separator.md +5 -5
  178. package/src/ui/docs/content/sidebar.md +329 -54
  179. package/src/ui/docs/content/skeleton.md +9 -2
  180. package/src/ui/docs/content/slider.md +8 -7
  181. package/src/ui/docs/content/spinner.md +8 -8
  182. package/src/ui/docs/content/split.md +29 -5
  183. package/src/ui/docs/content/storage.md +6 -8
  184. package/src/ui/docs/content/switch.md +8 -7
  185. package/src/ui/docs/content/table.md +13 -3
  186. package/src/ui/docs/content/tabs.md +28 -14
  187. package/src/ui/docs/content/testing.md +9 -11
  188. package/src/ui/docs/content/textarea.md +12 -4
  189. package/src/ui/docs/content/toast.md +47 -13
  190. package/src/ui/docs/content/toggle.md +75 -7
  191. package/src/ui/docs/content/tokens.md +7 -7
  192. package/src/ui/docs/content/tooltip.md +19 -11
  193. package/src/ui/docs/content/truncate.md +15 -8
  194. package/src/ui/docs/content/ui.md +24 -9
  195. package/src/ui/docs/content/upgrading.md +7 -8
  196. package/src/ui/docs/doc-client.tsx +5 -5
  197. package/src/ui/docs/doc.tsx +26 -14
  198. package/src/ui/docs/registry.tsx +25 -42
  199. package/src/ui/docs/standalone.tsx +2 -2
  200. package/src/ui/drivers/react.tsx +17 -12
  201. package/src/ui/lib/action-errors.ts +45 -0
  202. package/src/ui/lib/zod-pt-br.ts +31 -4
  203. package/src/ui/meta.ts +65 -95
  204. package/src/ui/react.tsx +17 -16
  205. package/src/ui/theme.css +60 -8
  206. package/src/vite/design.ts +6 -18
  207. package/src/ui/components/primitives/alert-dialog.tsx +0 -192
  208. package/src/ui/docs/content/alert-dialog.md +0 -73
  209. package/src/ui/docs/content/button-group.md +0 -71
  210. package/src/ui/docs/content/confirm.md +0 -120
  211. package/src/ui/docs/content/input-group.md +0 -79
  212. package/src/ui/docs/content/page-state.md +0 -45
  213. package/src/ui/docs/content/toggle-group.md +0 -81
@@ -1,120 +0,0 @@
1
- ## O trio imperativo: `dialog`
2
-
3
- `dialog.alert` · `dialog.confirm` · `dialog.prompt` — o trio do browser (`alert`/`confirm`/`prompt`), mas **assíncrono, com tema e a11y-correto**. Cada um pergunta e **espera a resposta**:
4
-
5
- ```tsx
6
- await dialog.alert({ title: 'Sessão expirada', description: 'Você será desconectado.' }) // Promise<void>
7
- const ok = await dialog.confirm({ title: 'Excluir a sessão?', variant: 'destructive' }) // Promise<boolean>
8
- const nome = await dialog.prompt({ title: 'Nome do snapshot', placeholder: 'ex.: v1-final' }) // Promise<string | null>
9
- ```
10
-
11
- É a mesma forma do `toast` (superfície imperativa, host no shell), mas que **responde** — e é isso que tira as ~15 linhas de JSX que cada tela montava. Por baixo é o `AlertDialog`: `role="alertdialog"`, foco preso, **não fecha no clique fora** — a semântica de uma interrupção que EXIGE resposta. Fechar por ESC/Cancelar resolve o "não" de cada tipo (`void`, `false`, `null`).
12
-
13
- ```tsx preview
14
- function Demo() {
15
- const [last, setLast] = useState('—')
16
- return (
17
- <div className="flex flex-wrap items-center gap-3">
18
- <DialogHost />
19
- <Button variant="outline" size="sm" onClick={async () => {
20
- await dialog.alert({ title: 'Sessão expirada', description: 'Você será desconectado.' })
21
- setLast('alert → OK')
22
- }}>alert</Button>
23
- <Button variant="outline" size="sm" onClick={async () => {
24
- const ok = await dialog.confirm({ title: 'Excluir a sessão?', description: 'Some o worktree e o preview.', action: 'Excluir', variant: 'destructive' })
25
- setLast('confirm → ' + (ok ? 'excluída' : 'mantida'))
26
- }}>confirm</Button>
27
- <Button variant="outline" size="sm" onClick={async () => {
28
- const name = await dialog.prompt({ title: 'Nome do snapshot', placeholder: 'ex.: v1-final' })
29
- setLast('prompt → ' + (name === null ? 'cancelado' : name))
30
- }}>prompt</Button>
31
- <span className="text-sm text-muted-foreground">Última: {last}</span>
32
- </div>
33
- )
34
- }
35
- render(<Demo />)
36
- ```
37
-
38
- ## Por que namespace, e não `confirm()` solto
39
-
40
- `alert`/`confirm`/`prompt` são **globais do browser**. Como função solta, esquecer o import não daria erro — o TypeScript resolveria pro global e o código abriria a caixa cinza do sistema (sem tema, que webview suprime). `window.dialog` não existe, então o namespace **imuniza** a família contra esse footgun. `confirm()` segue exportado como alias (retrocompat), mas o novo código usa `dialog.confirm`.
41
-
42
- ## `body`: corpo com conteúdo próprio
43
-
44
- Os três aceitam `body` — conteúdo que a `description` de texto não expressa (uma lista do que será afetado, um detalhe destacado). É o que antes obrigava a compor o `AlertDialog` à mão:
45
-
46
- ```tsx preview
47
- function Demo() {
48
- const [status, setStatus] = useState('—')
49
- return (
50
- <div className="flex items-center gap-3">
51
- <DialogHost />
52
- <Button variant="outline" size="sm" onClick={async () => {
53
- const ok = await dialog.confirm({
54
- title: 'Encerrar 3 sessões?',
55
- description: 'Os agentes abaixo serão interrompidos:',
56
- body: (
57
- <ul className="list-disc space-y-1 pl-5 text-sm text-muted-foreground">
58
- <li><span className="font-medium text-foreground">developer</span> — empresa-x-api</li>
59
- <li><span className="font-medium text-foreground">reviewer</span> — empresa-x-web</li>
60
- </ul>
61
- ),
62
- action: 'Encerrar todas',
63
- })
64
- setStatus(ok ? 'encerradas' : 'mantidas')
65
- }}>Encerrar sessões</Button>
66
- <span className="text-sm text-muted-foreground">Resposta: {status}</span>
67
- </div>
68
- )
69
- }
70
- render(<Demo />)
71
- ```
72
-
73
- ## O host
74
-
75
- Monte **um** `<DialogHost />` no shell do app, ao lado do `<Toaster />`:
76
-
77
- ```tsx
78
- <>
79
- {rotas}
80
- <Toaster />
81
- <DialogHost />
82
- </>
83
- ```
84
-
85
- Sem ele, os três **lançam** — em vez de devolver uma promise que nunca resolve. Promise pendurada viraria clique sem efeito, o pior desfecho pra uma interrupção que exige resposta: a pessoa acha que respondeu, ou clica de novo. (`<ConfirmHost />` segue valendo como alias de `<DialogHost />`.)
86
-
87
- Várias perguntas seguidas entram numa **fila** e aparecem uma por vez — cada `await` recebe a resposta do SEU diálogo (duas caixas empilhadas seriam ambíguas sobre qual clique respondeu o quê).
88
-
89
- ## Quando NÃO usar
90
-
91
- - **Excluir uma entidade por contrato** → `ActionTrigger` com `icon={<Trash2 />}`: lê o `action.confirm`, dispara a action e fala o erro de negócio.
92
- - **Um form de verdade** (validação, vários campos, submete uma action) → `ActionFormDialog`. O `dialog.prompt` é só pra UMA string livre.
93
- - **Mais de duas ações** (ex.: Salvar / Descartar / Cancelar) ou **layout totalmente custom** → componha o `AlertDialog` à mão.
94
- - **Só avisar, sem cobrar decisão** → `toast` (passageiro) ou `Alert` (fica na página). O `dialog.alert` é pro aviso que **bloqueia** e exige um "OK".
95
-
96
- ## Opções
97
-
98
- Comuns aos três (`dialog.alert`/`confirm`/`prompt`):
99
-
100
- | Opção | Tipo | Default | Descrição |
101
- |---|---|---|---|
102
- | `title` | `React.ReactNode` | | O enunciado. Obrigatório. |
103
- | `description` | `React.ReactNode` | | O que a pessoa precisa saber pra decidir — a CONSEQUÊNCIA, não o óbvio. |
104
- | `body` | `React.ReactNode` | | Conteúdo próprio entre a descrição e os botões (lista, detalhe). |
105
- | `media` | `React.ReactNode` | | Ícone grande acima do título (o quadro do `AlertDialogMedia`). |
106
- | `action` | `string` | `'OK'` / `'Confirmar'` | Rótulo do botão que confirma (default `'OK'` no alert, `'Confirmar'` nos outros). |
107
-
108
- Só `confirm` e `prompt`:
109
-
110
- | Opção | Tipo | Default | Descrição |
111
- |---|---|---|---|
112
- | `cancel` | `string` | `'Cancelar'` | Rótulo do botão que recusa. |
113
- | `variant` | `'default' \| 'destructive'` | `'default'` | `destructive` pinta o confirmar — o que apaga tem que parecer o que apaga. |
114
-
115
- Só `prompt`:
116
-
117
- | Opção | Tipo | Default | Descrição |
118
- |---|---|---|---|
119
- | `placeholder` | `string` | | Texto-fantasma do input. |
120
- | `defaultValue` | `string` | | Valor inicial (o input abre focado e selecionado). |
@@ -1,79 +0,0 @@
1
- > Só um **ícone leading**? Não precisa do InputGroup — é a prop `icon` do `Input` (a mesma do Select e do Alert). O InputGroup é pros casos que a prop não cobre: botão no fim, prefixo de texto, adorno em bloco, múltiplos.
2
-
3
- ## Com ícone (addon)
4
-
5
- InputGroupAddon na borda (align inline-start por padrão) cola um ícone ao InputGroupInput dentro da mesma moldura. Clicar no addon foca o campo. Pra um leading simples, prefira `<Input icon={…} />`; aqui é quando o ícone convive com outros adornos.
6
-
7
- ```tsx preview col
8
- <InputGroup>
9
- <InputGroupAddon>
10
- <Search />
11
- </InputGroupAddon>
12
- <InputGroupInput placeholder="Buscar sessões do workspace" />
13
- </InputGroup>
14
- ```
15
-
16
- ## Ícone + ação juntos (o caso do InputGroup)
17
-
18
- > Só uma ação no fim (um limpar, um mostrar-senha)? Isso é `<Input trailing={…} />` — não precisa do InputGroup. O InputGroup entra quando os adornos se ACUMULAM: aqui, um ícone leading E um botão no fim, na mesma moldura (a busca do `ActionList` é assim). `align=inline-end` joga o addon pro fim; `InputGroupButton` já vem ghost, tamanho `icon-xs`.
19
-
20
- ```tsx preview col
21
- <InputGroup>
22
- <InputGroupAddon>
23
- <Search />
24
- </InputGroupAddon>
25
- <InputGroupInput placeholder="Buscar agente" defaultValue="reviewer" />
26
- <InputGroupAddon align="inline-end">
27
- <InputGroupButton size="icon-xs" aria-label="Limpar filtro">
28
- <X />
29
- </InputGroupButton>
30
- </InputGroupAddon>
31
- </InputGroup>
32
- ```
33
-
34
- ## Prefixo e sufixo
35
-
36
- InputGroupText é o rótulo inerte na borda — prefixo ou sufixo. Aqui emoldura o slug do repositório entre o host fixo e o sufixo .git.
37
-
38
- ```tsx preview col
39
- <InputGroup>
40
- <InputGroupAddon>
41
- <GitBranch />
42
- <InputGroupText>github.com/softize/</InputGroupText>
43
- </InputGroupAddon>
44
- <InputGroupInput placeholder="empresa-x-api" />
45
- <InputGroupAddon align="inline-end">
46
- <InputGroupText>.git</InputGroupText>
47
- </InputGroupAddon>
48
- </InputGroup>
49
- ```
50
-
51
- ## Composer com rodapé
52
-
53
- Com InputGroupTextarea a moldura cresce; align=block-end empilha um rodapé de ações embaixo do campo — o padrão do composer de brief do agente.
54
-
55
- ```tsx preview col
56
- <InputGroup>
57
- <InputGroupTextarea placeholder="Descreva a task para o agente developer" rows={3} />
58
- <InputGroupAddon align="block-end">
59
- <InputGroupText>
60
- <Sparkles />
61
- Título gerado pela IA
62
- </InputGroupText>
63
- <InputGroupButton size="sm" context="primary" variant="solid" className="ml-auto" aria-label="Enviar brief">
64
- Enviar
65
- <ArrowUp />
66
- </InputGroupButton>
67
- </InputGroupAddon>
68
- </InputGroup>
69
- ```
70
-
71
- ## Props
72
-
73
- | Prop | Tipo | Default | Descrição |
74
- |---|---|---|---|
75
- | `align` (InputGroupAddon) | `'inline-start' \| 'inline-end' \| 'block-start' \| 'block-end'` | `'inline-start'` | Onde o addon ancora: inline nas laterais; block empilha (vira coluna) acima ou abaixo — block exige a moldura alta de um InputGroupTextarea. |
76
- | `size` (InputGroupButton) | `'xs' \| 'sm' \| 'icon-xs' \| 'icon-sm'` | `'xs'` | Tamanho do botão embutido. As variantes icon-* são quadradas, pra um botão só de ícone. |
77
- | `context` (InputGroupButton) | `'neutral' \| 'primary' \| 'danger'` | `'primary'` | Significado semântico herdado do Button. |
78
- | `variant` (InputGroupButton) | `'solid' \| 'subtle' \| 'outline' \| 'ghost' \| 'link'` | `'ghost'` | Tratamento visual herdado do Button. O padrão ghost some na moldura; use `solid` para dar ênfase à ação. |
79
- | `placeholder / defaultValue / value` (InputGroupInput, InputGroupTextarea) | `string` | | Props nativas do <input>/<textarea> repassadas ao controle. Controle como faria com Input/Textarea (value + onChange). |
@@ -1,45 +0,0 @@
1
- ## Estado integral da página
2
-
3
- Use `PageState` quando carregamento, falha ou ausência substituírem todo o conteúdo principal. Na
4
- forma curta ele pode ser escrito como filho direto de `Page`, que cria o `PageBody`; na forma
5
- explícita, coloque-o dentro de `PageBody`. O cabeçalho continua visível e o estado recebe composição,
6
- altura e semântica acessível consistentes.
7
-
8
- ```tsx preview col
9
- <Page title="Relatório">
10
- <PageState
11
- status="error"
12
- title="Não foi possível carregar o relatório"
13
- description="Tente novamente. Se o problema continuar, volte mais tarde."
14
- action={<Button variant="outline">Tentar novamente</Button>}
15
- />
16
- </Page>
17
- ```
18
-
19
- `loading` centraliza o `Spinner`; `error` compõe `Alert`; `empty` compõe `Empty`; e `ready` entrega
20
- os filhos sem acrescentar uma superfície.
21
-
22
- ```tsx preview col
23
- <Page title="Relatórios">
24
- <PageState
25
- status="empty"
26
- title="Nenhum relatório"
27
- description="Crie o primeiro relatório para começar."
28
- action={<Button>Novo relatório</Button>}
29
- />
30
- </Page>
31
- ```
32
-
33
- Não use `PageState` para uma falha parcial. Se outra parte da página continua utilizável, mantenha o
34
- estado na própria seção com `DataState`, `ActionView`, `ActionList` ou `Alert`.
35
-
36
- ## Props
37
-
38
- | Prop | Tipo | Default | Descrição |
39
- |---|---|---|---|
40
- | `status` | `'loading' \| 'error' \| 'empty' \| 'ready'` | | Estado integral do conteúdo. |
41
- | `title` | `ReactNode` | Texto seguro por estado | Situação reconhecível pela pessoa. |
42
- | `description` | `ReactNode` | | Impacto ou próximo passo aplicável. |
43
- | `icon` | `ReactNode` | Alerta no erro | Ícone decorativo do estado. |
44
- | `action` | `ReactNode` | | Recuperação, seleção ou criação aplicável. |
45
- | `children` | `ReactNode` | | Conteúdo renderizado somente em `ready`. |
@@ -1,81 +0,0 @@
1
- ## Escolha única
2
-
3
- type=single deixa um item ativo por vez; value é uma string. Controlado por value + onValueChange — bom pra alternar a visão de um workspace.
4
-
5
- ```tsx preview
6
- const [view, setView] = useState('sessions')
7
-
8
- render(
9
- <ToggleGroup type="single" value={view} onValueChange={(v) => v && setView(v)}>
10
- <ToggleGroupItem value="overview">Visão geral</ToggleGroupItem>
11
- <ToggleGroupItem value="sessions">Sessões</ToggleGroupItem>
12
- <ToggleGroupItem value="skills">Skills</ToggleGroupItem>
13
- </ToggleGroup>,
14
- )
15
- ```
16
-
17
- ## Escolha múltipla
18
-
19
- type=multiple permite vários ativos ao mesmo tempo; value é um array de strings. O padrão pra uma barra de formatação.
20
-
21
- ```tsx preview
22
- const [marks, setMarks] = useState(['bold'])
23
-
24
- render(
25
- <ToggleGroup type="multiple" value={marks} onValueChange={setMarks}>
26
- <ToggleGroupItem value="bold" aria-label="Negrito">
27
- <Bold />
28
- </ToggleGroupItem>
29
- <ToggleGroupItem value="italic" aria-label="Itálico">
30
- <Italic />
31
- </ToggleGroupItem>
32
- <ToggleGroupItem value="underline" aria-label="Sublinhado">
33
- <Underline />
34
- </ToggleGroupItem>
35
- </ToggleGroup>,
36
- )
37
- ```
38
-
39
- ## Variante outline
40
-
41
- variant=outline emoldura o grupo com borda; size e o variant definidos no ToggleGroup descem pra cada ToggleGroupItem via contexto.
42
-
43
- ```tsx preview
44
- <ToggleGroup type="single" variant="outline" defaultValue="left" aria-label="Alinhamento">
45
- <ToggleGroupItem value="left" aria-label="Esquerda">
46
- <AlignLeft />
47
- </ToggleGroupItem>
48
- <ToggleGroupItem value="center" aria-label="Centro">
49
- <AlignCenter />
50
- </ToggleGroupItem>
51
- <ToggleGroupItem value="right" aria-label="Direita">
52
- <AlignRight />
53
- </ToggleGroupItem>
54
- </ToggleGroup>
55
- ```
56
-
57
- ## Com espaçamento
58
-
59
- spacing afasta os itens (em unidades de spacing do tema) — sem ele os botões ficam colados num bloco único.
60
-
61
- ```tsx preview
62
- <ToggleGroup type="single" variant="outline" spacing={2} defaultValue="developer">
63
- <ToggleGroupItem value="developer">developer</ToggleGroupItem>
64
- <ToggleGroupItem value="reviewer">reviewer</ToggleGroupItem>
65
- <ToggleGroupItem value="designer">designer</ToggleGroupItem>
66
- </ToggleGroup>
67
- ```
68
-
69
- ## Props
70
-
71
- | Prop | Tipo | Default | Descrição |
72
- |---|---|---|---|
73
- | `type (ToggleGroup)` | `'single' \| 'multiple'` | | single mantém um item ativo (value: string); multiple permite vários (value: string[]). |
74
- | `value (ToggleGroup)` | `string \| string[]` | | O(s) item(ns) ativo(s) no modo controlado — pareie com onValueChange. O tipo segue o type. |
75
- | `onValueChange (ToggleGroup)` | `(value: string \| string[]) => void` | | Chamado quando a seleção muda. No single, vem string vazia ao desmarcar o ativo. |
76
- | `defaultValue (ToggleGroup)` | `string \| string[]` | | A seleção inicial no modo não controlado. |
77
- | `variant (ToggleGroup)` | `'default' \| 'outline'` | `'default'` | default é sem moldura; outline emoldura o grupo com borda. Desce pros itens via contexto. |
78
- | `size (ToggleGroup)` | `'default' \| 'sm' \| 'lg'` | `'default'` | Altura e respiro dos itens. Desce pros itens via contexto. |
79
- | `spacing (ToggleGroup)` | `number` | `0` | Distância entre os itens (unidades de spacing). 0 cola tudo num bloco único. |
80
- | `value (ToggleGroupItem)` | `string` | | Identificador do item — é o que entra no value do grupo quando ativado. |
81
- | `disabled (ToggleGroupItem)` | `boolean` | `false` | Esmaece e bloqueia um item específico do grupo. |