@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
@@ -10,7 +10,8 @@ no pai para evitar uma moldura dupla.
10
10
 
11
11
  ## Com ícone
12
12
 
13
- EmptyMedia variant=icon desenha o quadrado de fundo muted atrás do ícone; o EmptyHeader agrupa mídia, título e descrição no centro.
13
+ `EmptyMedia variant="icon"` aplica uma moldura quadrada e muted ao ícone. `EmptyHeader` mantém mídia,
14
+ título e descrição agrupados no centro.
14
15
 
15
16
  ```tsx preview col
16
17
  <Empty>
@@ -20,7 +21,7 @@ EmptyMedia variant=icon desenha o quadrado de fundo muted atrás do ícone; o Em
20
21
  </EmptyMedia>
21
22
  <EmptyTitle>Nenhum repositório vinculado</EmptyTitle>
22
23
  <EmptyDescription>
23
- O workspace Empresa X ainda não tem repositórios. Vincule um pra abrir sessões.
24
+ O workspace Empresa X ainda não tem repositórios. Vincule um para abrir sessões.
24
25
  </EmptyDescription>
25
26
  </EmptyHeader>
26
27
  </Empty>
@@ -28,7 +29,7 @@ EmptyMedia variant=icon desenha o quadrado de fundo muted atrás do ícone; o Em
28
29
 
29
30
  ## Com ação
30
31
 
31
- EmptyContent guarda os botões abaixo do header é o lugar da chamada pra ação que resolve o vazio.
32
+ `EmptyActions` organiza abaixo do cabeçalho as ações que permitem sair do estado vazio.
32
33
 
33
34
  ```tsx preview col
34
35
  <Empty>
@@ -38,21 +39,22 @@ EmptyContent guarda os botões abaixo do header — é o lugar da chamada pra a
38
39
  </EmptyMedia>
39
40
  <EmptyTitle>Sem skills neste agente</EmptyTitle>
40
41
  <EmptyDescription>
41
- O agente developer não tem skills anexadas. Adicione clean-code ou test pra começar.
42
+ O agente developer não tem skills anexadas. Adicione clean-code ou test para começar.
42
43
  </EmptyDescription>
43
44
  </EmptyHeader>
44
- <EmptyContent>
45
+ <EmptyActions>
45
46
  <Button>
46
47
  <Plus />
47
48
  Anexar skill
48
49
  </Button>
49
- </EmptyContent>
50
+ </EmptyActions>
50
51
  </Empty>
51
52
  ```
52
53
 
53
- ## Mídia default
54
+ ## Mídia sem moldura
54
55
 
55
- EmptyMedia variant=default (o padrão) não desenha fundo bom pra uma ilustração ou um ícone maior que se sustenta sozinho.
56
+ `EmptyMedia variant="default"` não desenha fundo. Use essa variação para ilustrações ou mídias que
57
+ tenham presença visual própria.
56
58
 
57
59
  ```tsx preview col
58
60
  <Empty>
@@ -68,9 +70,14 @@ EmptyMedia variant=default (o padrão) não desenha fundo — bom pra uma ilustr
68
70
  </Empty>
69
71
  ```
70
72
 
71
- ## Props
73
+ ## Propriedades de Empty
72
74
 
73
- | Prop | Tipo | Default | Descrição |
75
+ | Propriedade | Tipo | Padrão | Descrição |
74
76
  |---|---|---|---|
75
- | `variant (EmptyMedia)` | `'default' \| 'icon'` | `'default'` | icon desenha o quadrado de fundo muted atrás da mídia; default não desenha fundo. |
76
- | `className (Empty)` | `string` | | A moldura já vem tracejada e centrada — ajuste espaçamento ou borda por aqui. |
77
+ | `className` | `string` | | Classes aplicadas à moldura tracejada e centralizada. |
78
+
79
+ ## Propriedades de EmptyMedia
80
+
81
+ | Propriedade | Tipo | Padrão | Descrição |
82
+ |---|---|---|---|
83
+ | `variant` | `'default' \| 'icon'` | `'default'` | `icon` aplica uma moldura quadrada e muted; `default` exibe a mídia sem fundo. |
@@ -4,9 +4,9 @@ title: Eventos
4
4
 
5
5
  # Eventos
6
6
 
7
- O handler anuncia que algo aconteceu (`ctx.emit`) sem saber quem escuta. Reactions (e
8
- integrações) assinam e reagem. O barramento é um adapter do core (`EventBusAdapter`); o
9
- formato do evento é preservado de ponta a ponta.
7
+ Use eventos quando uma action precisar anunciar um fato sem conhecer seus consumidores.
8
+ `ctx.emit` publica o evento; reactions e integrações podem assiná-lo pelo `EventBusAdapter`. O
9
+ formato declarado permanece o mesmo durante todo o fluxo.
10
10
 
11
11
  ## O contrato
12
12
 
@@ -55,7 +55,7 @@ Actions declaram no contrato o que emitem (`emits: ['nota.emitida']`); o runtime
55
55
  o handler emitir algo não-declarado (`emitMode`). Uma reaction assina `nota.emitida` e roda
56
56
  como sua própria action rastreável (provenance `reaction`).
57
57
 
58
- ## Limites (por enquanto)
58
+ ## Limites atuais
59
59
 
60
60
  O driver `mitt` é in-process — sem durabilidade nem entre-processos. Barramentos duráveis/
61
61
  distribuídos (Redis, NATS…) entram por reincidência de caso real.
@@ -1,6 +1,8 @@
1
- ## Campo vertical
1
+ ## Campo empilhado
2
2
 
3
- A composição base: FieldLabel (htmlFor↔id), o controle e FieldDescription como ajuda empilhados, com o respiro do Field. O rótulo usa a mesma hierarquia compacta de `DetailField`; quando o campo é inválido, muda explicitamente para o tom destrutivo.
3
+ Use `Field` para manter rótulo, controle, ajuda e erro com espaçamento consistente. Na orientação
4
+ vertical, `FieldLabel`, o controle e `FieldDescription` ficam empilhados. Quando o controle usa
5
+ `aria-invalid`, o rótulo acompanha o contexto de erro.
4
6
 
5
7
  ```tsx preview col md
6
8
  <Field>
@@ -12,7 +14,8 @@ A composição base: FieldLabel (htmlFor↔id), o controle e FieldDescription co
12
14
 
13
15
  ## Horizontal com toggle
14
16
 
15
- orientation=horizontal põe o controle na lateral e a label à esquerda. FieldContent agrupa título e descrição num bloco; FieldTitle é o rótulo de texto quando o controle não é um <label>.
17
+ `orientation="horizontal"` posiciona o controle ao lado do texto. `FieldContent` agrupa título e
18
+ descrição; `FieldTitle` nomeia o campo quando o texto não puder ser um `<label>`.
16
19
 
17
20
  ```tsx preview col md
18
21
  <Field orientation="horizontal">
@@ -26,7 +29,8 @@ orientation=horizontal põe o controle na lateral e a label à esquerda. FieldCo
26
29
 
27
30
  ## Conjunto com legenda e erro
28
31
 
29
- FieldSet agrupa campos sob uma FieldLegend; FieldGroup o espaçamento entre eles; FieldSeparator marca uma divisão. FieldError mostra a mensagem só quando há erro (aria-invalid no controle casa o visual).
32
+ `FieldSet` agrupa campos sob uma `FieldLegend`; `FieldGroup` define o espaçamento e
33
+ `FieldSeparator` marca uma divisão. `FieldError` aparece somente quando existe mensagem de erro.
30
34
 
31
35
  ```tsx preview col md
32
36
  <FieldSet>
@@ -35,7 +39,7 @@ FieldSet agrupa campos sob uma FieldLegend; FieldGroup dá o espaçamento entre
35
39
  <Field>
36
40
  <FieldLabel htmlFor="agent-name">Nome</FieldLabel>
37
41
  <Input id="agent-name" defaultValue="" aria-invalid placeholder="Ex.: developer" />
38
- <FieldError>Informe um nome pro agente.</FieldError>
42
+ <FieldError>Informe um nome para o agente.</FieldError>
39
43
  </Field>
40
44
  <FieldSeparator />
41
45
  <Field>
@@ -47,12 +51,30 @@ FieldSet agrupa campos sob uma FieldLegend; FieldGroup dá o espaçamento entre
47
51
  </FieldSet>
48
52
  ```
49
53
 
50
- ## Props
54
+ ## Propriedades de Field
51
55
 
52
- | Prop | Tipo | Default | Descrição |
56
+ | Propriedade | Tipo | Padrão | Descrição |
53
57
  |---|---|---|---|
54
- | `orientation` (Field) | `'vertical' \| 'horizontal' \| 'responsive'` | `'vertical'` | Direção do campo: vertical empilha; horizontal põe o controle ao lado (bom pra toggle); responsive vira horizontal a partir de @md. |
55
- | `variant` (FieldLegend) | `'legend' \| 'label'` | `'legend'` | Tamanho da legenda do FieldSet — legend é o título da seção; label encolhe pro porte de rótulo. |
56
- | `errors` (FieldError) | `Array<{ message?: string }>` | | Lista de erros (ex.: do react-hook-form) — deduplica e vira uma lista. Sem children e sem erros, o FieldError não renderiza. |
57
- | `children` (FieldError) | `React.ReactNode` | | Mensagem de erro literal — tem prioridade sobre errors quando passada. |
58
- | `children` (FieldSeparator) | `React.ReactNode` | | Rótulo opcional no meio da linha divisória (ex.: "ou") — sem filhos, é só a linha. |
58
+ | `orientation` | `'vertical' \| 'horizontal' \| 'responsive'` | `'vertical'` | Direção do campo; `responsive` se torna horizontal a partir do container médio. |
59
+
60
+ ## Propriedades de FieldLegend
61
+
62
+ | Propriedade | Tipo | Padrão | Descrição |
63
+ |---|---|---|---|
64
+ | `variant` | `'legend' \| 'label'` | `'legend'` | Define o porte de título de seção ou de rótulo compacto. |
65
+
66
+ ## Propriedades de FieldError
67
+
68
+ | Propriedade | Tipo | Padrão | Descrição |
69
+ |---|---|---|---|
70
+ | `errors` | `Array<{ message?: string }>` | | Deduplica e apresenta uma lista de erros; sem conteúdo, o componente não renderiza. |
71
+ | `children` | `ReactNode` | | Mensagem literal, com prioridade sobre `errors`. |
72
+
73
+ ## Propriedades de FieldSeparator
74
+
75
+ | Propriedade | Tipo | Padrão | Descrição |
76
+ |---|---|---|---|
77
+ | `children` | `ReactNode` | | Rótulo opcional no centro da divisão; sem conteúdo, exibe somente a linha. |
78
+
79
+ `FieldSet`, `FieldGroup`, `FieldContent`, `FieldLabel`, `FieldTitle` e `FieldDescription` aceitam as
80
+ props nativas dos respectivos elementos e não adicionam propriedades próprias.
@@ -59,7 +59,7 @@ cd meu-cliente && git init
59
59
  pnpm dlx @softize/opus create apps/portal # o app (modo detectado)
60
60
  ```
61
61
 
62
- ## Carregar o Opus num projeto existente
62
+ ## Carregar o Opus em um projeto existente
63
63
 
64
64
  > O `opus.json` registra a versão usada pelo projeto. Se o arquivo ainda não existe, o setup
65
65
  > cria a estrutura necessária antes das demais etapas.
@@ -1,6 +1,8 @@
1
- O value é o **nome** do ícone (kebab-case, chave da paleta) quem consome renderiza com a mesma paleta: `iconPickerIcons[name] ?? FallbackIcon`. Selecionar o já-escolhido desmarca (volta a `''`).
1
+ Use `IconPicker` para selecionar um ícone por seu nome em kebab-case. O consumidor renderiza o
2
+ valor com a mesma paleta, por exemplo `iconPickerIcons[name] ?? FallbackIcon`. Selecionar novamente o
3
+ ícone atual limpa o valor.
2
4
 
3
- ## Básico
5
+ ## Escolher na paleta padrão
4
6
 
5
7
  ```tsx preview col md
6
8
  const [icon, setIcon] = useState('chart-line')
@@ -15,7 +17,8 @@ render(
15
17
 
16
18
  ## Renderizando o escolhido
17
19
 
18
- A paleta default é exportada (`iconPickerIcons`) use-a pra desenhar o ícone salvo onde ele aparece (item de lista, card, árvore).
20
+ A paleta padrão é exportada como `iconPickerIcons`. Use a mesma coleção para apresentar o ícone
21
+ salvo em listas, cards e árvores.
19
22
 
20
23
  ```tsx preview col md
21
24
  const [icon, setIcon] = useState('store')
@@ -34,7 +37,8 @@ render(
34
37
 
35
38
  ## Paleta própria
36
39
 
37
- `icons` troca o vocabulário (nome → componente lucide). A paleta default é curta de propósito cada ícone importado entra no bundle; monte a sua com o que faz sentido no domínio.
40
+ `icons` substitui a coleção de nomes e componentes Lucide. Mantenha somente os ícones relevantes ao
41
+ domínio, pois cada importação participa do bundle.
38
42
 
39
43
  ```tsx preview col md
40
44
  const [icon, setIcon] = useState('')
@@ -1,6 +1,7 @@
1
- ## Básico
1
+ ## Código em uma sequência
2
2
 
3
- maxLength define quantas casas existem; cada InputOTPSlot recebe o index da sua posição. Um InputOTPGroup envolve as casas.
3
+ `maxLength` define o comprimento do código. Cada `InputOTPSlot` recebe o índice de uma posição e
4
+ `InputOTPGroup` mantém a sequência agrupada.
4
5
 
5
6
  ```tsx preview
6
7
  <InputOTP maxLength={6}>
@@ -17,7 +18,8 @@ maxLength define quantas casas existem; cada InputOTPSlot recebe o index da sua
17
18
 
18
19
  ## Com separador
19
20
 
20
- Vários grupos com InputOTPSeparator entre eles quebram o código em blocos os index seguem contínuos (0–5) por cima da divisão visual.
21
+ Use `InputOTPSeparator` entre grupos para dividir visualmente o código. Os índices continuam em uma
22
+ única sequência apesar da separação.
21
23
 
22
24
  ```tsx preview
23
25
  <InputOTP maxLength={6}>
@@ -37,7 +39,8 @@ Vários grupos com InputOTPSeparator entre eles quebram o código em blocos —
37
39
 
38
40
  ## Controlado
39
41
 
40
- value + onChange deixam o código no seu estado bom pra liberar a ação só quando todas as casas estão preenchidas.
42
+ Use `value` e `onChange` quando o estado externo precisar validar o comprimento antes de liberar a
43
+ próxima ação.
41
44
 
42
45
  ```tsx preview col-start
43
46
  const [code, setCode] = useState('')
@@ -55,18 +58,23 @@ render(
55
58
  </InputOTPGroup>
56
59
  </InputOTP>
57
60
  <p className="text-sm text-muted-foreground">
58
- {code.length === 6 ? 'Código pronto pra confirmar o acesso ao workspace.' : 'Digite o código de 6 dígitos.'}
61
+ {code.length === 6 ? 'Código pronto para confirmar o acesso ao workspace.' : 'Digite o código de 6 dígitos.'}
59
62
  </p>
60
63
  </>,
61
64
  )
62
65
  ```
63
66
 
64
- ## Props
67
+ ## Propriedades de InputOTP
65
68
 
66
- | Prop | Tipo | Default | Descrição |
69
+ | Propriedade | Tipo | Padrão | Descrição |
67
70
  |---|---|---|---|
68
- | `maxLength` (InputOTP) | `number` | | Quantas casas o código tem — defina um InputOTPSlot por posição. |
69
- | `value` (InputOTP) | `string` | | O código no modo controlado parear com onChange. |
70
- | `onChange` (InputOTP) | `(value: string) => void` | | Chamado a cada dígito; recebe o código acumulado. |
71
- | `disabled` (InputOTP) | `boolean` | `false` | Esmaece e bloqueia a digitação do conjunto inteiro. |
72
- | `index` (InputOTPSlot) | `number` | | A posição da casa (0-based); liga o slot ao dígito correspondente. |
71
+ | `maxLength` | `number` | | Quantidade de posições do código. Defina um `InputOTPSlot` para cada posição. |
72
+ | `value` | `string` | | Código no modo controlado. Use com `onChange`. |
73
+ | `onChange` | `(value: string) => void` | | Chamado a cada entrada com o código acumulado. |
74
+ | `disabled` | `boolean` | `false` | Desabilita a digitação em todo o conjunto. |
75
+
76
+ ## Propriedades de InputOTPSlot
77
+
78
+ | Propriedade | Tipo | Padrão | Descrição |
79
+ |---|---|---|---|
80
+ | `index` | `number` | | Posição do caractere, começando em zero. |
@@ -1,6 +1,7 @@
1
- ## Básico
1
+ ## Campo de uma linha
2
2
 
3
- Placeholder orienta o formato, não substitui o rótulo em formulário de verdade, pareie com Label.
3
+ Use `Input` para texto de uma linha. O placeholder pode sugerir formato ou exemplo, mas não substitui
4
+ o rótulo; em formulários, associe o campo a `Label`.
4
5
 
5
6
  ```tsx preview col md
6
7
  <Input placeholder="Ex.: empresa-x" />
@@ -8,7 +9,8 @@ Placeholder orienta o formato, não substitui o rótulo — em formulário de ve
8
9
 
9
10
  ## Ícone dentro do campo
10
11
 
11
- `icon` põe um ícone LEADING dentro do campo identidade (calendário na data, prédio na filial). É a MESMA prop do Select e do Alert: adorno de campo é **prop**, não composição à mão nem ícone jogado ao lado (que desalinha na quebra de linha e some no responsivo). Decorativo — quem nomeia é o Label.
12
+ `icon` posiciona um ícone decorativo no início do campo. Use-o para reforçar a natureza do valor,
13
+ como calendário em uma data; o `Label` continua responsável pelo nome acessível.
12
14
 
13
15
  ```tsx preview col md
14
16
  <div className="grid gap-2">
@@ -17,12 +19,13 @@ Placeholder orienta o formato, não substitui o rótulo — em formulário de ve
17
19
  </div>
18
20
  ```
19
21
 
20
- Pra mais que um ícone um botão no fim, um prefixo de texto, adorno em bloco — aí é `InputGroup` (a composição rica). Só o ícone leading é a prop.
22
+ Quando o campo precisar combinar vários adornos, prefixos ou botões, use `InputGroup`.
21
23
 
22
24
 
23
25
  ## Ação no fim do campo (trailing)
24
26
 
25
- `trailing` é o par do `icon`: uma ação DENTRO do campo, no fim um botão que age sobre o valor (limpar, mostrar senha). Igual ao Select. Diferente do ícone (decorativo), o trailing é interativo.
27
+ `trailing` posiciona no fim do campo uma ação relacionada ao valor, como limpar ou mostrar uma
28
+ senha. Diferentemente de `icon`, essa região pode ser interativa.
26
29
 
27
30
  ```tsx preview col md
28
31
  function Demo() {
@@ -45,11 +48,11 @@ function Demo() {
45
48
  render(<Demo />)
46
49
  ```
47
50
 
48
- Pra MAIS de um adorno junto (ícone + botão + prefixo de texto), é `InputGroup`. Um ícone e/ou uma ação → props.
51
+ Para combinar mais de um adorno, use `InputGroup`.
49
52
 
50
53
  ## Com Label
51
54
 
52
- htmlFor aponta pro id do campo clicar no rótulo foca o input.
55
+ Associe `htmlFor` no `Label` ao `id` do campo para que o clique no rótulo mova o foco.
53
56
 
54
57
  ```tsx preview col md
55
58
  <div className="grid gap-2">
@@ -60,7 +63,8 @@ htmlFor aponta pro id do campo — clicar no rótulo foca o input.
60
63
 
61
64
  ## Tipos nativos
62
65
 
63
- type é o atributo nativo de <input> — teclado, máscara e validação vêm do browser de graça.
66
+ `type` é repassado ao `<input>` nativo, permitindo que o navegador escolha teclado e validação
67
+ adequados.
64
68
 
65
69
  ```tsx preview col md
66
70
  <Input type="email" placeholder="Ex.: joao@softize.com.br" />
@@ -70,9 +74,117 @@ type é o atributo nativo de <input> — teclado, máscara e validação vêm do
70
74
 
71
75
  ## Estados
72
76
 
73
- Inválido é aria-invalid (borda e anel destructive) — semântica e visual na mesma prop, sem classe de erro à parte. disabled esmaece e bloqueia.
77
+ Use `aria-invalid` para comunicar e apresentar o estado inválido. `disabled` impede interação e
78
+ aplica o tratamento visual correspondente.
74
79
 
75
80
  ```tsx preview col md
76
81
  <Input aria-invalid defaultValue="empresa x" placeholder="Slug do workspace" />
77
82
  <Input disabled defaultValue="softize-multica" />
78
83
  ```
84
+
85
+ ## Propriedades de Input
86
+
87
+ Além das props abaixo, `Input` aceita os atributos nativos de `<input>`.
88
+
89
+ | Propriedade | Tipo | Padrão | Descrição |
90
+ |---|---|---|---|
91
+ | `icon` | `ReactNode` | | Ícone decorativo no início do campo. |
92
+ | `trailing` | `ReactNode` | | Ação interativa no fim do campo. |
93
+ | `type` | `string` | | Tipo nativo do campo, como `text`, `email`, `password` ou `number`. |
94
+
95
+ ## InputGroup
96
+
97
+ Use `InputGroup` quando o campo precisar combinar vários adornos, prefixos, sufixos ou ações em uma
98
+ única moldura. Para somente um ícone ou uma ação no fim, continue usando `icon` ou `trailing` em
99
+ `Input`.
100
+
101
+ ### Com ícone e ação
102
+
103
+ `InputGroupAddon` ancora os adornos nas extremidades. O clique em uma área inerte do addon transfere
104
+ o foco para o campo.
105
+
106
+ ```tsx preview col
107
+ <InputGroup>
108
+ <InputGroupAddon><Search /></InputGroupAddon>
109
+ <InputGroupInput placeholder="Buscar agente" defaultValue="reviewer" />
110
+ <InputGroupAddon align="inline-end">
111
+ <InputGroupButton size="icon-xs" aria-label="Limpar filtro"><X /></InputGroupButton>
112
+ </InputGroupAddon>
113
+ </InputGroup>
114
+ ```
115
+
116
+ ### Prefixo e sufixo
117
+
118
+ `InputGroupText` apresenta texto inerte dentro da moldura.
119
+
120
+ ```tsx preview col
121
+ <InputGroup>
122
+ <InputGroupAddon>
123
+ <GitBranch />
124
+ <InputGroupText>github.com/softize/</InputGroupText>
125
+ </InputGroupAddon>
126
+ <InputGroupInput placeholder="empresa-x-api" />
127
+ <InputGroupAddon align="inline-end"><InputGroupText>.git</InputGroupText></InputGroupAddon>
128
+ </InputGroup>
129
+ ```
130
+
131
+ ### Composer com rodapé
132
+
133
+ Com `InputGroupTextarea`, um addon em `block-end` forma uma região de ações abaixo do texto.
134
+
135
+ ```tsx preview col
136
+ <InputGroup>
137
+ <InputGroupTextarea placeholder="Descreva a tarefa para o agente developer" rows={3} />
138
+ <InputGroupAddon align="block-end">
139
+ <InputGroupText><Sparkles /> Título gerado pela IA</InputGroupText>
140
+ <InputGroupButton
141
+ size="sm"
142
+ context="primary"
143
+ variant="solid"
144
+ className="ml-auto"
145
+ aria-label="Enviar tarefa"
146
+ >
147
+ Enviar <ArrowUp />
148
+ </InputGroupButton>
149
+ </InputGroupAddon>
150
+ </InputGroup>
151
+ ```
152
+
153
+ ### Propriedades de InputGroup
154
+
155
+ | Propriedade | Tipo | Padrão | Descrição |
156
+ |---|---|---|---|
157
+ | `shape` | `'default' \| 'pill'` | `'default'` | Geometria da moldura compartilhada. |
158
+
159
+ ### Propriedades de InputGroupAddon
160
+
161
+ | Propriedade | Tipo | Padrão | Descrição |
162
+ |---|---|---|---|
163
+ | `align` | `'inline-start' \| 'inline-end' \| 'block-start' \| 'block-end'` | `'inline-start'` | Posição do addon nas laterais ou acima/abaixo do controle. |
164
+
165
+ ### Propriedades de InputGroupButton
166
+
167
+ | Propriedade | Tipo | Padrão | Descrição |
168
+ |---|---|---|---|
169
+ | `size` | `'xs' \| 'sm' \| 'icon-xs' \| 'icon-sm'` | `'xs'` | Tamanho do botão embutido; as variantes `icon-*` são quadradas. |
170
+ | `context` | `'neutral' \| 'primary' \| 'danger'` | `'primary'` | Contexto semântico herdado de Button. |
171
+ | `variant` | `'solid' \| 'subtle' \| 'outline' \| 'ghost' \| 'link'` | `'ghost'` | Tratamento visual; use `solid` quando a ação precisar de ênfase. |
172
+
173
+ ### Propriedades de InputGroupInput
174
+
175
+ | Propriedade | Tipo | Padrão | Descrição |
176
+ |---|---|---|---|
177
+ | `value` / `defaultValue` | `string` | | Valor controlado ou inicial do `<input>`. |
178
+ | `placeholder` | `string` | | Exemplo ou formato esperado quando o campo está vazio. |
179
+
180
+ ### Propriedades de InputGroupTextarea
181
+
182
+ | Propriedade | Tipo | Padrão | Descrição |
183
+ |---|---|---|---|
184
+ | `value` / `defaultValue` | `string` | | Valor controlado ou inicial do `<textarea>`. |
185
+ | `placeholder` | `string` | | Exemplo ou orientação exibida quando o campo está vazio. |
186
+ | `rows` | `number` | | Número inicial de linhas visíveis. |
187
+
188
+ ### Propriedades de InputGroupText
189
+
190
+ `InputGroupText` aceita as props nativas de `<span>` e não adiciona propriedades próprias.
@@ -1,25 +1,31 @@
1
- ## Básico
1
+ ## Linha composta
2
2
 
3
- A composição completa: ItemMedia à esquerda, ItemContent (ItemTitle + ItemDescription) ocupando o meio e ItemActions à direita. variant=outline desenha a borda.
3
+ A composição completa usa `ItemMedia` à esquerda, `ItemHeader` (`ItemTitle` +
4
+ `ItemDescription`) no meio e `ItemActions` à direita. Ícone e imagem mantêm uma moldura quadrada
5
+ alinhada ao topo, mesmo quando a descrição ocupa mais linhas. `variant="outline"` desenha a borda.
4
6
 
5
7
  ```tsx preview col
6
8
  <Item variant="outline">
7
9
  <ItemMedia variant="icon">
8
10
  <FolderGit2 />
9
11
  </ItemMedia>
10
- <ItemContent>
12
+ <ItemHeader>
11
13
  <ItemTitle>empresa-x-api</ItemTitle>
12
- <ItemDescription>Repositório do backend do workspace Empresa X.</ItemDescription>
13
- </ItemContent>
14
+ <ItemDescription>
15
+ Repositório do backend do workspace Empresa X.
16
+ </ItemDescription>
17
+ </ItemHeader>
14
18
  <ItemActions>
15
- <Button size="sm" variant="outline">Abrir</Button>
19
+ <Button size="sm" variant="outline">
20
+ Abrir
21
+ </Button>
16
22
  </ItemActions>
17
23
  </Item>
18
24
  ```
19
25
 
20
26
  ## Lista emoldurada
21
27
 
22
- `ItemGroup variant="framed"` aplica a superfície canônica. Os divisores continuam explícitos com `ItemSeparator`, tanto no modo `framed` quanto no `plain` — o padrão pra listas de repositórios, agentes ou sessões.
28
+ `ItemGroup variant="framed"` aplica a superfície canônica. Os divisores continuam explícitos com `ItemSeparator`, tanto no modo `framed` quanto no `plain` — o padrão para listas de repositórios, agentes ou sessões.
23
29
 
24
30
  ```tsx preview col
25
31
  <ItemGroup variant="framed">
@@ -27,12 +33,12 @@ A composição completa: ItemMedia à esquerda, ItemContent (ItemTitle + ItemDes
27
33
  <ItemMedia variant="icon">
28
34
  <GitBranch />
29
35
  </ItemMedia>
30
- <ItemContent>
36
+ <ItemHeader>
31
37
  <ItemTitle>empresa-x-web</ItemTitle>
32
38
  <ItemDescription>Front do workspace Empresa X.</ItemDescription>
33
- </ItemContent>
39
+ </ItemHeader>
34
40
  <ItemActions>
35
- <Badge variant="success">sincronizado</Badge>
41
+ <Badge context="success">Sincronizado</Badge>
36
42
  </ItemActions>
37
43
  </Item>
38
44
  <ItemSeparator />
@@ -40,12 +46,12 @@ A composição completa: ItemMedia à esquerda, ItemContent (ItemTitle + ItemDes
40
46
  <ItemMedia variant="icon">
41
47
  <GitBranch />
42
48
  </ItemMedia>
43
- <ItemContent>
49
+ <ItemHeader>
44
50
  <ItemTitle>empresa-x-api</ItemTitle>
45
51
  <ItemDescription>Backend do workspace Empresa X.</ItemDescription>
46
- </ItemContent>
52
+ </ItemHeader>
47
53
  <ItemActions>
48
- <Badge variant="warning">3 sessões</Badge>
54
+ <Badge context="warning">3 sessões</Badge>
49
55
  </ItemActions>
50
56
  </Item>
51
57
  </ItemGroup>
@@ -53,7 +59,7 @@ A composição completa: ItemMedia à esquerda, ItemContent (ItemTitle + ItemDes
53
59
 
54
60
  ## Clicável e compacto
55
61
 
56
- asChild funde o Item num <a> — a linha inteira vira alvo (hover no fundo). size=sm aperta o respiro; ItemMedia variant=image ancora um avatar.
62
+ asChild funde o Item em um <a> — a linha inteira vira alvo (hover no fundo). size=sm aperta o respiro; ItemMedia variant=image ancora um avatar.
57
63
 
58
64
  ```tsx preview col
59
65
  <Item asChild size="sm" variant="outline">
@@ -63,10 +69,12 @@ asChild funde o Item num <a> — a linha inteira vira alvo (hover no fundo). siz
63
69
  <AvatarFallback>AL</AvatarFallback>
64
70
  </Avatar>
65
71
  </ItemMedia>
66
- <ItemContent>
72
+ <ItemHeader>
67
73
  <ItemTitle>Empresa X</ItemTitle>
68
- <ItemDescription>Workspace com 2 repositórios e 3 agentes.</ItemDescription>
69
- </ItemContent>
74
+ <ItemDescription>
75
+ Workspace com 2 repositórios e 3 agentes.
76
+ </ItemDescription>
77
+ </ItemHeader>
70
78
  <ItemActions>
71
79
  <ChevronRight className="size-4 text-muted-foreground" />
72
80
  </ItemActions>
@@ -74,12 +82,44 @@ asChild funde o Item num <a> — a linha inteira vira alvo (hover no fundo). siz
74
82
  </Item>
75
83
  ```
76
84
 
77
- ## Props
85
+ ## Corpo complementar
78
86
 
79
- | Prop | Tipo | Default | Descrição |
87
+ Use `ItemBody` quando a linha também apresenta um valor ou controle que não pertence ao título,
88
+ à descrição nem às ações.
89
+
90
+ ```tsx preview col
91
+ <Item variant="outline">
92
+ <ItemHeader>
93
+ <ItemTitle>Nome</ItemTitle>
94
+ <ItemDescription>Como você aparece para as outras pessoas.</ItemDescription>
95
+ </ItemHeader>
96
+ <ItemBody>João</ItemBody>
97
+ </Item>
98
+ ```
99
+
100
+ `ItemContent` permanece exportado somente para compatibilidade durante a versão 12. Código novo
101
+ usa `ItemHeader` ou `ItemBody` conforme o papel do conteúdo.
102
+
103
+ ## Propriedades de Item
104
+
105
+ | Propriedade | Tipo | Padrão | Descrição |
80
106
  |---|---|---|---|
81
- | `variant` (ItemGroup) | `'plain' \| 'framed'` | `'plain'` | `framed` aplica moldura e superfície; `plain` mantém a composição livre. Os divisores são explícitos nos dois modos. |
82
- | `variant` (Item) | `'default' \| 'outline' \| 'muted'` | `'default'` | O fundo da linha default transparente, outline com borda, muted levemente tingido. |
83
- | `size` (Item) | `'default' \| 'sm'` | `'default'` | O respiro interno sm aperta o padding pra listas densas. |
84
- | `asChild` (Item) | `boolean` | `false` | Funde o Item no filho (ex.: <a> ou <button>) — a linha inteira vira o alvo. |
85
- | `variant` (ItemMedia) | `'default' \| 'icon' \| 'image'` | `'default'` | A moldura da mídia — icon dá caixa quadrada com borda; image recorta a imagem; default sem moldura. |
107
+ | `variant` | `'default' \| 'outline' \| 'muted'` | `'default'` | O fundo da linha: transparente, com borda ou levemente tingido. |
108
+ | `size` | `'default' \| 'sm'` | `'default'` | O respiro interno; `sm` atende listas densas. |
109
+ | `asChild` | `boolean` | `false` | Funde o Item no filho para que a linha inteira assuma sua semântica. |
110
+
111
+ ## Propriedades de ItemGroup
112
+
113
+ | Propriedade | Tipo | Padrão | Descrição |
114
+ |---|---|---|---|
115
+ | `variant` | `'plain' \| 'framed'` | `'plain'` | `framed` aplica moldura e superfície; os divisores permanecem explícitos nos dois modos. |
116
+
117
+ ## Propriedades de ItemMedia
118
+
119
+ | Propriedade | Tipo | Padrão | Descrição |
120
+ |---|---|---|---|
121
+ | `variant` | `'default' \| 'icon' \| 'image'` | `'default'` | Define mídia livre ou uma moldura quadrada para ícone ou imagem. |
122
+
123
+ `ItemHeader`, `ItemTitle`, `ItemDescription`, `ItemBody`, `ItemActions`, `ItemFooter` e
124
+ `ItemSeparator` aceitam as props nativas dos respectivos elementos e não adicionam propriedades
125
+ próprias. `ItemContent` preserva esse mesmo contrato somente durante a migração da versão 12.