@softize/opus 12.11.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 (119) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/bin/lib/check.mjs +2 -7
  3. package/bin/lib/copy.mjs +1 -5
  4. package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +93 -10
  5. package/docs/adr/0007-toast-actions-form-an-ordered-collection.md +63 -0
  6. package/docs/adr/0008-hierarchical-navigation-is-composed-at-the-consumer-boundary.md +71 -0
  7. package/docs/radius-scale.md +1 -1
  8. package/package.json +1 -1
  9. package/registry/skills/maintain-opus-docs/SKILL.md +83 -0
  10. package/registry/skills/maintain-opus-docs/agents/openai.yaml +4 -0
  11. package/registry/skills/maintain-opus-docs/references/editorial-standard.md +85 -0
  12. package/registry/skills/maintain-opus-docs/references/evaluations.md +34 -0
  13. package/registry/skills/maintain-opus-docs/scripts/audit-docs.mjs +81 -0
  14. package/src/ui/components/patterns/confirm.tsx +140 -40
  15. package/src/ui/components/patterns/list.tsx +35 -40
  16. package/src/ui/components/patterns/page-state.tsx +2 -2
  17. package/src/ui/components/patterns/sidebar.tsx +26 -26
  18. package/src/ui/components/patterns/trigger.tsx +25 -22
  19. package/src/ui/components/primitives/alert.tsx +3 -3
  20. package/src/ui/components/primitives/dialog.tsx +196 -39
  21. package/src/ui/components/primitives/drawer.tsx +8 -5
  22. package/src/ui/components/primitives/empty.tsx +3 -3
  23. package/src/ui/components/primitives/item.tsx +3 -3
  24. package/src/ui/components/primitives/sonner.tsx +187 -8
  25. package/src/ui/docs/DocBrowser.tsx +102 -23
  26. package/src/ui/docs/content/accordion.md +22 -16
  27. package/src/ui/docs/content/action-form-card.md +8 -8
  28. package/src/ui/docs/content/action-form-dialog.md +9 -9
  29. package/src/ui/docs/content/action-form.md +28 -34
  30. package/src/ui/docs/content/action-list-dialog.md +11 -6
  31. package/src/ui/docs/content/action-list.md +64 -39
  32. package/src/ui/docs/content/action-trigger.md +21 -14
  33. package/src/ui/docs/content/action-view.md +8 -8
  34. package/src/ui/docs/content/actions.md +9 -9
  35. package/src/ui/docs/content/ai.md +3 -3
  36. package/src/ui/docs/content/alert.md +14 -12
  37. package/src/ui/docs/content/aspect-ratio.md +4 -4
  38. package/src/ui/docs/content/audit.md +2 -2
  39. package/src/ui/docs/content/auth.md +3 -3
  40. package/src/ui/docs/content/avatar.md +34 -14
  41. package/src/ui/docs/content/badge.md +3 -3
  42. package/src/ui/docs/content/breadcrumb.md +13 -8
  43. package/src/ui/docs/content/button.md +81 -6
  44. package/src/ui/docs/content/calendar.md +5 -5
  45. package/src/ui/docs/content/card.md +1 -1
  46. package/src/ui/docs/content/carousel.md +16 -11
  47. package/src/ui/docs/content/chat.md +3 -3
  48. package/src/ui/docs/content/checkbox.md +7 -7
  49. package/src/ui/docs/content/cli.md +5 -5
  50. package/src/ui/docs/content/collapsible.md +8 -8
  51. package/src/ui/docs/content/command.md +16 -8
  52. package/src/ui/docs/content/composer.md +2 -2
  53. package/src/ui/docs/content/content.md +2 -2
  54. package/src/ui/docs/content/copyable.md +4 -3
  55. package/src/ui/docs/content/customization.md +5 -5
  56. package/src/ui/docs/content/cycle.md +3 -3
  57. package/src/ui/docs/content/data-state.md +11 -12
  58. package/src/ui/docs/content/data.md +26 -33
  59. package/src/ui/docs/content/detail.md +3 -3
  60. package/src/ui/docs/content/dialog.md +339 -31
  61. package/src/ui/docs/content/dictionary-value.md +8 -8
  62. package/src/ui/docs/content/dock.md +3 -3
  63. package/src/ui/docs/content/drawer.md +27 -14
  64. package/src/ui/docs/content/empty-value.md +2 -2
  65. package/src/ui/docs/content/empty.md +19 -12
  66. package/src/ui/docs/content/events.md +4 -4
  67. package/src/ui/docs/content/field.md +34 -12
  68. package/src/ui/docs/content/getting-started.md +1 -1
  69. package/src/ui/docs/content/icon-picker.md +8 -4
  70. package/src/ui/docs/content/input-otp.md +20 -12
  71. package/src/ui/docs/content/input.md +121 -9
  72. package/src/ui/docs/content/item.md +27 -13
  73. package/src/ui/docs/content/kbd.md +19 -11
  74. package/src/ui/docs/content/label.md +5 -3
  75. package/src/ui/docs/content/log.md +4 -4
  76. package/src/ui/docs/content/markdown.md +7 -6
  77. package/src/ui/docs/content/mcp.md +13 -15
  78. package/src/ui/docs/content/menu.md +34 -16
  79. package/src/ui/docs/content/observability.md +2 -2
  80. package/src/ui/docs/content/page.md +51 -6
  81. package/src/ui/docs/content/pagination.md +22 -17
  82. package/src/ui/docs/content/popover.md +16 -8
  83. package/src/ui/docs/content/progress.md +7 -5
  84. package/src/ui/docs/content/queue.md +5 -5
  85. package/src/ui/docs/content/radio-group.md +20 -12
  86. package/src/ui/docs/content/router.md +11 -6
  87. package/src/ui/docs/content/scheduler.md +4 -5
  88. package/src/ui/docs/content/scroll-area.md +12 -7
  89. package/src/ui/docs/content/select.md +42 -29
  90. package/src/ui/docs/content/separator.md +5 -5
  91. package/src/ui/docs/content/sidebar.md +323 -54
  92. package/src/ui/docs/content/skeleton.md +3 -2
  93. package/src/ui/docs/content/slider.md +8 -7
  94. package/src/ui/docs/content/spinner.md +8 -8
  95. package/src/ui/docs/content/split.md +8 -5
  96. package/src/ui/docs/content/storage.md +6 -8
  97. package/src/ui/docs/content/switch.md +8 -7
  98. package/src/ui/docs/content/table.md +13 -3
  99. package/src/ui/docs/content/tabs.md +28 -14
  100. package/src/ui/docs/content/testing.md +9 -11
  101. package/src/ui/docs/content/textarea.md +5 -4
  102. package/src/ui/docs/content/toast.md +47 -13
  103. package/src/ui/docs/content/toggle.md +75 -7
  104. package/src/ui/docs/content/tokens.md +3 -3
  105. package/src/ui/docs/content/tooltip.md +19 -11
  106. package/src/ui/docs/content/truncate.md +7 -8
  107. package/src/ui/docs/content/ui.md +10 -9
  108. package/src/ui/docs/content/upgrading.md +7 -8
  109. package/src/ui/docs/registry.tsx +20 -37
  110. package/src/ui/meta.ts +64 -94
  111. package/src/ui/react.tsx +15 -16
  112. package/src/ui/theme.css +50 -0
  113. package/src/ui/components/primitives/alert-dialog.tsx +0 -192
  114. package/src/ui/docs/content/alert-dialog.md +0 -73
  115. package/src/ui/docs/content/button-group.md +0 -71
  116. package/src/ui/docs/content/confirm.md +0 -120
  117. package/src/ui/docs/content/input-group.md +0 -79
  118. package/src/ui/docs/content/page-state.md +0 -45
  119. package/src/ui/docs/content/toggle-group.md +0 -81
@@ -24,7 +24,7 @@ decisão em cada tela.
24
24
 
25
25
  ## Com ícone
26
26
 
27
- Um svg filho ganha size-3 automaticamente — bom pra reforçar o estado sem crescer o rótulo.
27
+ Um svg filho ganha size-3 automaticamente — bom para reforçar o estado sem crescer o rótulo.
28
28
 
29
29
  ```tsx preview
30
30
  <Badge context="success"><CircleCheck /> Regressão verde</Badge>
@@ -41,9 +41,9 @@ variantes.
41
41
  </Badge>
42
42
  ```
43
43
 
44
- ## Props
44
+ ## Propriedades de Badge
45
45
 
46
- | Prop | Tipo | Default | Descrição |
46
+ | Propriedade | Tipo | Padrão | Descrição |
47
47
  |---|---|---|---|
48
48
  | `context` | `'neutral' \| 'primary' \| 'info' \| 'success' \| 'warning' \| 'danger'` | `'neutral'` | O significado ou destaque contextual. |
49
49
  | `variant` | `'solid' \| 'subtle' \| 'outline'` | `'subtle'` | O tratamento visual aplicado ao contexto. |
@@ -1,4 +1,4 @@
1
- ## Básico
1
+ ## Caminho atual
2
2
 
3
3
  A composição é manual: BreadcrumbLink nos níveis navegáveis, BreadcrumbPage no atual (não
4
4
  clicável, aria-current=page) e um BreadcrumbSeparator entre cada item.
@@ -23,7 +23,7 @@ clicável, aria-current=page) e um BreadcrumbSeparator entre cada item.
23
23
 
24
24
  ## Com ícone e separador custom
25
25
 
26
- O primeiro nível pode levar um ícone do lucide. BreadcrumbSeparator aceita children pra trocar o
26
+ O primeiro nível pode levar um ícone do lucide. BreadcrumbSeparator aceita children para trocar o
27
27
  chevron padrão por outro glifo (aqui, uma barra).
28
28
 
29
29
  ```tsx preview col-start
@@ -53,7 +53,7 @@ chevron padrão por outro glifo (aqui, uma barra).
53
53
 
54
54
  ## Colapsado
55
55
 
56
- Trilha funda demais pro espaço: BreadcrumbEllipsis substitui os níveis do meio (que viram um
56
+ Trilha funda demais para o espaço: BreadcrumbEllipsis substitui os níveis do meio (que viram um
57
57
  menu/popover) e mantém só a raiz e o destino.
58
58
 
59
59
  ```tsx preview col-start
@@ -78,10 +78,15 @@ menu/popover) e mantém só a raiz e o destino.
78
78
  </Breadcrumb>
79
79
  ```
80
80
 
81
- ## Props
81
+ ## Propriedades de BreadcrumbLink
82
82
 
83
- | Prop | Tipo | Default | Descrição |
83
+ | Propriedade | Tipo | Padrão | Descrição |
84
84
  |---|---|---|---|
85
- | `asChild` (BreadcrumbLink) | `boolean` | `false` | Funde as props no filho (via Slot) — use pra integrar o Link do seu roteador no lugar do `<a>` nativo. |
86
- | `href` (BreadcrumbLink) | `string` | | Destino do nível navegável — o que o consumidor decide por item. |
87
- | `children` (BreadcrumbSeparator) | `React.ReactNode` | `<ChevronRight />` | Glifo entre os itens. Omita pro chevron padrão ou passe outro ícone. |
85
+ | `asChild` | `boolean` | `false` | Repassa as propriedades ao filho para integrar o link do roteador no lugar de `<a>`. |
86
+ | `href` | `string` | | Destino do nível navegável. |
87
+
88
+ ## Propriedades de BreadcrumbSeparator
89
+
90
+ | Propriedade | Tipo | Padrão | Descrição |
91
+ |---|---|---|---|
92
+ | `children` | `React.ReactNode` | `<ChevronRight />` | Elemento entre os itens. Omita para usar o chevron padrão ou passe outro ícone. |
@@ -31,7 +31,7 @@ O tamanho icon exige `aria-label`, porque não há texto visível. Os botões s
31
31
 
32
32
  busy = ação em andamento (DEPOIS do clique): o Spinner e o disabled vêm do botão. Com icon, o
33
33
  Spinner TROCA o ícone (não soma). Não confunda com carregar conteúdo (ANTES) — isso é Spinner
34
- centralizado/Skeleton num nível de página.
34
+ centralizado/Skeleton em um nível de página.
35
35
 
36
36
  ```tsx preview
37
37
  <Button disabled>Desabilitado</Button>
@@ -43,7 +43,7 @@ centralizado/Skeleton num nível de página.
43
43
  ## Como outro elemento (asChild)
44
44
 
45
45
  Âncora com cara de botão: asChild renderiza o filho (Radix Slot) — sem forkar estilo.
46
- buttonVariants serve pro caso sem filho único.
46
+ buttonVariants serve para o caso sem filho único.
47
47
 
48
48
  ```tsx preview
49
49
  <Button asChild variant="outline">
@@ -51,13 +51,88 @@ buttonVariants serve pro caso sem filho único.
51
51
  </Button>
52
52
  ```
53
53
 
54
- ## Props
54
+ ## Propriedades de Button
55
55
 
56
- | Prop | Tipo | Default | Descrição |
56
+ | Propriedade | Tipo | Padrão | Descrição |
57
57
  |---|---|---|---|
58
58
  | `context` | `'neutral' \| 'primary' \| 'danger'` | `'primary'` | A hierarquia ou o risco comunicado pela ação. |
59
59
  | `variant` | `'solid' \| 'subtle' \| 'outline' \| 'ghost' \| 'link'` | `'solid'` | O tratamento visual aplicado ao contexto. |
60
60
  | `size` | `'default' \| 'sm' \| 'lg' \| 'icon' \| 'icon-sm' \| 'icon-xs'` | `'default'` | O tamanho. Os icon* são quadrados (2.25/2/1.5rem) para botões só de ícone, com `aria-label`. |
61
- | `asChild` | `boolean` | `false` | Renderiza como o filho (Radix Slot) em vez de `<button>` — pra âncoras e afins. |
62
- | `busy` | `boolean` | `false` | Ação em andamento (depois do clique): mostra Spinner + desabilita. Não é "carregando" de conteúdo (que é Spinner/Skeleton num nível de página). |
61
+ | `asChild` | `boolean` | `false` | Renderiza como o filho (Radix Slot) em vez de `<button>` — para âncoras e afins. |
62
+ | `busy` | `boolean` | `false` | Ação em andamento (depois do clique): mostra Spinner + desabilita. Não é "carregando" de conteúdo (que é Spinner/Skeleton em um nível de página). |
63
63
  | `icon` | `React.ElementType` | | Ícone à esquerda (ex.: icon={Plus}). No busy é trocado pelo Spinner — não soma. |
64
+
65
+ ## ButtonGroup
66
+
67
+ Use `ButtonGroup` quando ações relacionadas precisarem formar um bloco contínuo. As bordas internas
68
+ colapsam e somente as pontas externas permanecem arredondadas. Mantenha a mesma variante nos filhos
69
+ para preservar a unidade visual.
70
+
71
+ ```tsx preview
72
+ <ButtonGroup>
73
+ <Button variant="outline">Visão geral</Button>
74
+ <Button variant="outline">Sessões</Button>
75
+ <Button variant="outline">Habilidades</Button>
76
+ </ButtonGroup>
77
+ ```
78
+
79
+ ### Ação dividida
80
+
81
+ Combine a ação principal, um separador e um botão de ícone quando o mesmo comando oferecer
82
+ variações.
83
+
84
+ ```tsx preview
85
+ <ButtonGroup>
86
+ <Button icon={Play}>Rodar agente developer</Button>
87
+ <ButtonGroupSeparator />
88
+ <Button size="icon" aria-label="Mais opções">
89
+ <ChevronDown />
90
+ </Button>
91
+ </ButtonGroup>
92
+ ```
93
+
94
+ ### Com rótulo
95
+
96
+ `ButtonGroupText` adiciona um contexto inerte ao grupo. Ele também aceita `asChild` para assumir a
97
+ semântica de outro elemento, como `label`.
98
+
99
+ ```tsx preview
100
+ <ButtonGroup>
101
+ <ButtonGroupText>
102
+ <GitBranch />
103
+ empresa-x-api
104
+ </ButtonGroupText>
105
+ <Button variant="outline" icon={RotateCw}>Sincronizar</Button>
106
+ </ButtonGroup>
107
+ ```
108
+
109
+ ### Vertical
110
+
111
+ `orientation="vertical"` empilha os filhos e transfere a junção das bordas para o eixo vertical.
112
+
113
+ ```tsx preview col-start
114
+ <ButtonGroup orientation="vertical">
115
+ <Button variant="outline" size="icon" aria-label="Rodar sessão"><Play /></Button>
116
+ <Button variant="outline" size="icon" aria-label="Pausar sessão"><Pause /></Button>
117
+ <Button variant="outline" size="icon" aria-label="Reiniciar sessão"><RotateCw /></Button>
118
+ </ButtonGroup>
119
+ ```
120
+
121
+ ### Propriedades de ButtonGroup
122
+
123
+ | Propriedade | Tipo | Padrão | Descrição |
124
+ |---|---|---|---|
125
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Direção do bloco e do colapso das bordas. |
126
+ | `shape` | `'default' \| 'pill'` | `'default'` | Geometria das extremidades externas do grupo. |
127
+
128
+ ### Propriedades de ButtonGroupSeparator
129
+
130
+ | Propriedade | Tipo | Padrão | Descrição |
131
+ |---|---|---|---|
132
+ | `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | Direção do traço divisor; use vertical em grupos horizontais. |
133
+
134
+ ### Propriedades de ButtonGroupText
135
+
136
+ | Propriedade | Tipo | Padrão | Descrição |
137
+ |---|---|---|---|
138
+ | `asChild` | `boolean` | `false` | Renderiza como o filho para assumir outra semântica sem perder o estilo. |
@@ -17,7 +17,7 @@ render(
17
17
 
18
18
  ## Intervalo
19
19
 
20
- mode=range guarda { from, to } — o padrão pra filtrar sessões por janela de datas. O primeiro clique fixa o início; o segundo, o fim.
20
+ mode=range guarda { from, to } — o padrão para filtrar sessões por janela de datas. O primeiro clique fixa o início; o segundo, o fim.
21
21
 
22
22
  ```tsx preview
23
23
  const [week, setWeek] = useState<DateRange | undefined>({
@@ -37,7 +37,7 @@ render(
37
37
 
38
38
  ## Navegação por dropdown
39
39
 
40
- captionLayout=dropdown troca o título do mês por seletores de mês e ano — bom pra pular pra um período distante (ex.: histórico de um repositório) sem clicar mês a mês.
40
+ captionLayout=dropdown troca o título do mês por seletores de mês e ano — bom para pular para um período distante (ex.: histórico de um repositório) sem clicar mês a mês.
41
41
 
42
42
  ```tsx preview
43
43
  <Calendar
@@ -47,16 +47,16 @@ captionLayout=dropdown troca o título do mês por seletores de mês e ano — b
47
47
  />
48
48
  ```
49
49
 
50
- ## Props
50
+ ## Propriedades de Calendar
51
51
 
52
- | Prop | Tipo | Default | Descrição |
52
+ | Propriedade | Tipo | Padrão | Descrição |
53
53
  |---|---|---|---|
54
54
  | `mode` | `'single' \| 'multiple' \| 'range'` | | O tipo de seleção — define o formato de selected/onSelect (Date, Date[] ou { from, to }). |
55
55
  | `selected` | `Date \| Date[] \| DateRange` | | A seleção atual no modo controlado — o formato segue o mode. Pareie com onSelect. |
56
56
  | `onSelect` | `(selected) => void` | | Chamado quando o usuário escolhe uma data. O argumento segue o mode. |
57
57
  | `defaultMonth` | `Date` | | O mês exibido ao montar, sem afetar a seleção. |
58
58
  | `captionLayout` | `'label' \| 'dropdown' \| 'dropdown-months' \| 'dropdown-years'` | `'label'` | Como o título do mês aparece — label é texto fixo; dropdown vira seletores de mês e ano. |
59
- | `numberOfMonths` | `number` | `1` | Quantos meses mostrar lado a lado — útil pra escolher um intervalo longo. |
59
+ | `numberOfMonths` | `number` | `1` | Quantos meses mostrar lado a lado — útil para escolher um intervalo longo. |
60
60
  | `disabled` | `Matcher` | | Datas não selecionáveis — uma Date, um array, um { from, to } ou um predicado (date) => boolean. |
61
61
  | `buttonVariant` | `Button['variant']` | `'ghost'` | A variante dos botões de navegação (anterior/próximo). |
62
62
  | `showOutsideDays` | `boolean` | `true` | Mostra os dias do mês vizinho que completam a primeira e a última semana. |
@@ -10,7 +10,7 @@ O uso mais comum: a superfície de conteúdo em repouso (`rounded-xl` + `border`
10
10
 
11
11
  ## Estruturado (header / conteúdo / rodapé)
12
12
 
13
- Pra painel com estrutura: cada slot é dono do próprio padding (como o Dialog). CardTitle/CardDescription no header; CardFooter alinha as ações.
13
+ Para painel com estrutura: cada slot é dono do próprio padding (como o Dialog). CardTitle/CardDescription no header; CardFooter alinha as ações.
14
14
 
15
15
  ```tsx preview col
16
16
  <Card>
@@ -1,6 +1,6 @@
1
- ## Básico
1
+ ## Um slide por vez
2
2
 
3
- Compõe Carousel>CarouselContent>CarouselItem, com CarouselPrevious/CarouselNext pra navegar. As setas ficam fora do trilho (-left-12/-right-12), então reserve a margem lateral no entorno.
3
+ Compõe Carousel>CarouselContent>CarouselItem, com CarouselPrevious/CarouselNext para navegar. As setas ficam fora do trilho (-left-12/-right-12), então reserve a margem lateral no entorno.
4
4
 
5
5
  ```tsx preview
6
6
  <Carousel className="mx-12 w-full max-w-xs">
@@ -28,7 +28,7 @@ Compõe Carousel>CarouselContent>CarouselItem, com CarouselPrevious/CarouselNext
28
28
 
29
29
  ## Vários por vista
30
30
 
31
- O basis do CarouselItem decide quantos cabem na vista — basis-1/3 mostra três slides por vez. Bom pra galeria de workspaces ou repositórios.
31
+ O basis do CarouselItem decide quantos cabem na vista — basis-1/3 mostra três slides por vez. Bom para galeria de workspaces ou repositórios.
32
32
 
33
33
  ```tsx preview
34
34
  <Carousel className="mx-12 w-full max-w-sm" opts={{ align: 'start' }}>
@@ -48,7 +48,7 @@ O basis do CarouselItem decide quantos cabem na vista — basis-1/3 mostra três
48
48
 
49
49
  ## Vertical
50
50
 
51
- orientation=vertical empilha os slides; as setas migram pra cima e pra baixo (-top-12/-bottom-12). Dê uma altura ao CarouselContent pra delimitar a vista.
51
+ orientation=vertical empilha os slides; as setas migram para cima e para baixo (-top-12/-bottom-12). Dê uma altura ao CarouselContent para delimitar a vista.
52
52
 
53
53
  ```tsx preview
54
54
  <Carousel className="w-full max-w-xs" orientation="vertical">
@@ -74,12 +74,17 @@ orientation=vertical empilha os slides; as setas migram pra cima e pra baixo (-t
74
74
  </Carousel>
75
75
  ```
76
76
 
77
- ## Props
77
+ ## Propriedades de Carousel
78
78
 
79
- | Prop | Tipo | Default | Descrição |
79
+ | Propriedade | Tipo | Padrão | Descrição |
80
80
  |---|---|---|---|
81
- | `orientation (Carousel)` | `'horizontal' \| 'vertical'` | `'horizontal'` | Eixo do deslize vertical empilha os slides e gira as setas pro topo/base. |
82
- | `opts (Carousel)` | `CarouselOptions` | | Opções do embla (ex.: { loop: true }, { align: "start" }). Repassadas direto pro motor. |
83
- | `setApi (Carousel)` | `(api: CarouselApi) => void` | | Recebe a instância do embla pra controlar de fora (scrollTo, ler o slide ativo). |
84
- | `plugins (Carousel)` | `CarouselPlugin` | | Plugins do embla (ex.: autoplay) anexados ao carousel. |
85
- | `className (CarouselItem)` | `string` | | O basis decide quantos slides cabem na vista (basis-full, basis-1/2, basis-1/3). |
81
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Eixo do deslocamento. No modo vertical, os slides são empilhados e as setas apontam para cima e para baixo. |
82
+ | `opts` | `CarouselOptions` | | Opções repassadas ao Embla, como `{ loop: true }` ou `{ align: 'start' }`. |
83
+ | `setApi` | `(api: CarouselApi) => void` | | Recebe a instância para controle externo, como navegar com `scrollTo` ou ler o slide ativo. |
84
+ | `plugins` | `CarouselPlugin[]` | | Plugins do Embla associados ao carrossel, como autoplay. |
85
+
86
+ ## Propriedades de CarouselItem
87
+
88
+ | Propriedade | Tipo | Padrão | Descrição |
89
+ |---|---|---|---|
90
+ | `className` | `string` | | Classes de dimensão; a base define quantos slides cabem na área visível. |
@@ -1,6 +1,6 @@
1
- ## Básico
1
+ ## Conversa com resposta integral
2
2
 
3
- Um chat mínimo: lista de mensagens + composer. A conversa é gerenciada por dentro (estado, loading, auto-scroll; **Enter** envia, **Shift+Enter** quebra linha) — a inteligência vem da prop `send`. Com o composer vazio, **↑** recupera as mensagens anteriores do usuário e **↓** volta em direção ao rascunho; durante a edição, as setas continuam movendo o cursor normalmente. O `greeting` é o estado vazio (centrado; some quando a conversa começa e NÃO entra no transcript). Dê altura ao container.
3
+ Um chat mínimo: lista de mensagens + composer. A conversa é gerenciada por dentro (estado, loading, auto-scroll; **Enter** envia, **Shift+Enter** quebra linha) — a inteligência vem da prop `send`. Com o composer vazio, **↑** recupera as mensagens anteriores do usuário e **↓** volta em direção ao rascunho; durante a edição, as setas continuam movendo o cursor normalmente. O `greeting` é o estado vazio (centrado; some quando a conversa começa e não entra no transcript). Dê altura ao container.
4
4
 
5
5
  ```tsx preview
6
6
  <div className="h-96 rounded-lg border">
@@ -9,7 +9,7 @@ Um chat mínimo: lista de mensagens + composer. A conversa é gerenciada por den
9
9
  send={async (messages) => {
10
10
  await new Promise((r) => setTimeout(r, 500))
11
11
  const last = messages[messages.length - 1]
12
- return `Você disse: "${last.content}". (Num app real, aqui rodaria o agente.)`
12
+ return `Você disse: "${last.content}". (Em um app real, aqui rodaria o agente.)`
13
13
  }}
14
14
  />
15
15
  </div>
@@ -1,6 +1,6 @@
1
- ## Básico
1
+ ## Escolha booleana
2
2
 
3
- Sempre em par com Label (htmlFor↔id) — clicar no texto alterna a caixa. defaultChecked pro modo não controlado.
3
+ Sempre em par com Label (htmlFor↔id) — clicar no texto alterna a caixa. defaultChecked para o modo não controlado.
4
4
 
5
5
  ```tsx preview
6
6
  <div className="flex items-center gap-2">
@@ -11,7 +11,7 @@ Sempre em par com Label (htmlFor↔id) — clicar no texto alterna a caixa. defa
11
11
 
12
12
  ## Controlado
13
13
 
14
- onCheckedChange recebe boolean | 'indeterminate' — compare com true pra guardar um boolean.
14
+ onCheckedChange recebe boolean | 'indeterminate' — compare com true para guardar um boolean.
15
15
 
16
16
  ```tsx preview
17
17
  const [autoReview, setAutoReview] = useState(true)
@@ -30,7 +30,7 @@ render(
30
30
 
31
31
  ## Lista de opções
32
32
 
33
- Várias caixas, um estado: o conjunto marcado é a lista de valores — o padrão pra anexar skills a um agente.
33
+ Várias caixas, um estado: o conjunto marcado é a lista de valores — o padrão para anexar skills a um agente.
34
34
 
35
35
  ```tsx preview col-start
36
36
  const [skills, setSkills] = useState(['clean-code', 'test'])
@@ -65,11 +65,11 @@ disabled esmaece a caixa e o rótulo em par (peer-disabled no Label) — marcado
65
65
  </div>
66
66
  ```
67
67
 
68
- ## Props
68
+ ## Propriedades de Checkbox
69
69
 
70
- | Prop | Tipo | Default | Descrição |
70
+ | Propriedade | Tipo | Padrão | Descrição |
71
71
  |---|---|---|---|
72
72
  | `checked` | `boolean \| 'indeterminate'` | | O estado, no modo controlado — parear com onCheckedChange. |
73
- | `onCheckedChange` | `(checked: boolean \| 'indeterminate') => void` | | Chamado a cada alternância. Pra guardar um boolean, compare com true. |
73
+ | `onCheckedChange` | `(checked: boolean \| 'indeterminate') => void` | | Chamado a cada alternância. Para guardar um boolean, compare com true. |
74
74
  | `defaultChecked` | `boolean` | `false` | Estado inicial no modo não controlado. |
75
75
  | `disabled` | `boolean` | `false` | Esmaece e bloqueia — o Label em par esmaece junto (peer-disabled). |
@@ -5,7 +5,7 @@ title: CLI opus
5
5
  # CLI opus
6
6
 
7
7
  O Opus traz um CLI que cobre o ciclo: faz o bootstrap, gera artefatos a partir das declarações,
8
- valida as convenções e expõe o estado vivo pros agentes via MCP.
8
+ valida as convenções e expõe o estado vivo para os agentes via MCP.
9
9
 
10
10
  ## Gates
11
11
 
@@ -38,7 +38,7 @@ mesma CLI.
38
38
  ## Geração e introspecção
39
39
 
40
40
  > As declarações (`description` de entidades/actions) são a fonte; o `gen` as projeta. O manifest
41
- > é um lockfile commitado diff de manifest é ouro pra review.
41
+ > é um lockfile versionado. A diferença do manifest torna a revisão objetiva.
42
42
 
43
43
  ```bash
44
44
  opus gen # manifest / openapi / docs / stubs a partir do opus.config.ts
@@ -57,17 +57,17 @@ opus create meu-cliente --monorepo # a RAIZ de um workspace (apps/* + packages/
57
57
  opus create apps/portal # dentro de um workspace: só o app (modo detectado)
58
58
  opus setup # grava opus.json e materializa a camada específica do SDK
59
59
  opus list # lista os templates disponíveis
60
- opus add action-form # copia um template do catálogo pro projeto
60
+ opus add action-form # copia um template do catálogo para o projeto
61
61
  ```
62
62
 
63
63
  O esqueleto do `create` versiona com o Opus (sai do mesmo pacote que o SDK que ele
64
64
  configura) e nasce com os gates verdes: domínio-exemplo canônico, teste, manifest e o dev
65
- server pronto pro preview do Maestro. O método geral, a memória e a revisão vêm da Base
65
+ server pronto para o preview do Maestro. O método geral, a memória e a revisão vêm da Base
66
66
  depois de `pnpm run setup`. Dois modos, por detecção:
67
67
  repo standalone (template inteiro) ou **app em monorepo** (dentro de um workspace pnpm:
68
68
  só os arquivos do app; o que a raiz precisa ter vira aviso, sem clobber).
69
69
 
70
- ## MCP — estado vivo pros agentes
70
+ ## MCP — estado vivo para os agentes
71
71
 
72
72
  > O server MCP expõe introspecção, check e scaffold de action. É como um agente lê a estrutura e cria
73
73
  > action no formato canônico sem decorar convenção.
@@ -1,4 +1,4 @@
1
- ## Básico
1
+ ## Seção recolhível
2
2
 
3
3
  CollapsibleTrigger alterna o CollapsibleContent — o Trigger já é o <button>. defaultOpen deixa o estado com o componente.
4
4
 
@@ -18,7 +18,7 @@ CollapsibleTrigger alterna o CollapsibleContent — o Trigger já é o <button>.
18
18
 
19
19
  ## Controlado
20
20
 
21
- open + onOpenChange põem o estado nas suas mãos — dá pra refletir no gatilho (aqui o chevron gira) ou guardar a preferência.
21
+ open + onOpenChange põem o estado nas suas mãos — dá para refletir no gatilho (aqui o chevron gira) ou guardar a preferência.
22
22
 
23
23
  ```tsx preview col
24
24
  const [open, setOpen] = useState(false)
@@ -54,11 +54,11 @@ disabled no Collapsible trava o gatilho — a seção fica fixa no estado atual
54
54
  </Collapsible>
55
55
  ```
56
56
 
57
- ## Props
57
+ ## Propriedades de Collapsible
58
58
 
59
- | Prop | Tipo | Default | Descrição |
59
+ | Propriedade | Tipo | Padrão | Descrição |
60
60
  |---|---|---|---|
61
- | `defaultOpen (Collapsible)` | `boolean` | `false` | Estado inicial no modo não controlado. |
62
- | `open (Collapsible)` | `boolean` | | Estado no modo controlado pareie com onOpenChange. |
63
- | `onOpenChange (Collapsible)` | `(open: boolean) => void` | | Chamado a cada abertura ou fechamento. |
64
- | `disabled (Collapsible)` | `boolean` | `false` | Trava o gatilho a seção fica presa no estado atual. |
61
+ | `defaultOpen` | `boolean` | `false` | Estado inicial no modo não controlado. |
62
+ | `open` | `boolean` | | Estado no modo controlado. Use com `onOpenChange`. |
63
+ | `onOpenChange` | `(open: boolean) => void` | | Chamado a cada abertura ou fechamento. |
64
+ | `disabled` | `boolean` | `false` | Bloqueia o gatilho e mantém a seção no estado atual. |
@@ -1,6 +1,7 @@
1
1
  ## Lista filtrável inline
2
2
 
3
- Digite pra filtrar navegação por teclado, grupos e CommandEmpty de graça (cmdk). É a base do Select buscável; pra escolha em form, use o Select.
3
+ Digite para filtrar uma coleção com navegação por teclado, grupos e estado vazio. Command é a base
4
+ do Select pesquisável; para uma escolha em formulário, use Select.
4
5
 
5
6
  ```tsx preview
6
7
  <Command className="max-w-sm rounded-lg border border-border">
@@ -22,7 +23,7 @@ Digite pra filtrar — navegação por teclado, grupos e CommandEmpty de graça
22
23
 
23
24
  ## Palette modal (CommandDialog)
24
25
 
25
- O Command embrulhado num Dialog, com header sr-only pra a11y. O atalho ⌘K (keydown no app) só troca o open — o conteúdo é o mesmo do inline.
26
+ O Command embrulhado em um Dialog, com header sr-only para a11y. O atalho ⌘K (keydown no app) só troca o open — o conteúdo é o mesmo do inline.
26
27
 
27
28
  ```tsx preview
28
29
  const [open, setOpen] = useState(false)
@@ -46,11 +47,18 @@ render(
46
47
  )
47
48
  ```
48
49
 
49
- ## Props
50
+ ## Propriedades de CommandDialog
50
51
 
51
- | Prop | Tipo | Default | Descrição |
52
+ | Propriedade | Tipo | Padrão | Descrição |
52
53
  |---|---|---|---|
53
- | `CommandDialog.open / onOpenChange` | `boolean / (open: boolean) => void` | | Controle do modal ligue ao atalho de teclado do app. |
54
- | `CommandDialog.title / description` | `string` | `'Comandos' / 'Busque um comando pra executar.'` | Texto sr-only do header (a11y do Dialog) — não aparece na tela. |
55
- | `CommandDialog.showCloseButton` | `boolean` | `true` | Mostra o X do Dialog desligue se o Esc/clique fora bastarem. |
56
- | `CommandItem.onSelect` | `(value: string) => void` | | Dispara ao escolher (Enter ou clique) feche o palette aqui. |
54
+ | `open` | `boolean` | | Estado do modal no modo controlado. |
55
+ | `onOpenChange` | `(open: boolean) => void` | | Atualiza o estado do modal; pode ser conectado ao atalho do aplicativo. |
56
+ | `title` | `string` | `'Comandos'` | Nome acessível do diálogo, disponível para leitura assistiva. |
57
+ | `description` | `string` | `'Busque um comando para executar.'` | Descrição acessível do diálogo. |
58
+ | `showCloseButton` | `boolean` | `true` | Exibe o botão de fechamento. |
59
+
60
+ ## Propriedades de CommandItem
61
+
62
+ | Propriedade | Tipo | Padrão | Descrição |
63
+ |---|---|---|---|
64
+ | `onSelect` | `(value: string) => void` | | Chamado ao selecionar o item por clique ou teclado. |
@@ -1,6 +1,6 @@
1
- ## Básico
1
+ ## Envio de texto
2
2
 
3
- A caixa de escrever da casa: textarea numa pílula elevada (`rounded-xl` + `border` + `shadow-sm`), **Enter** envia / **Shift+Enter** quebra linha, enviar dentro. É o composer do [Chat](/components/chat) extraído — use SOZINHO quando há entrada de texto mas não um chat (ex.: criar uma sessão). Controlado: o dono do texto é você. Os callbacks opcionais `onHistoryPrevious` e `onHistoryNext` permitem que esse dono consuma **↑/↓**; sem eles, as setas mantêm o comportamento nativo da textarea.
3
+ A caixa de escrever da casa: textarea em uma pílula elevada (`rounded-xl` + `border` + `shadow-sm`), **Enter** envia / **Shift+Enter** quebra linha, enviar dentro. É o composer do [Chat](/components/chat) extraído — use sozinho quando há entrada de texto mas não um chat (ex.: criar uma sessão). Controlado: o dono do texto é você. Os callbacks opcionais `onHistoryPrevious` e `onHistoryNext` permitem que esse dono consuma **↑/↓**; sem eles, as setas mantêm o comportamento nativo da textarea.
4
4
 
5
5
  ```tsx preview col
6
6
  const [text, setText] = React.useState('')
@@ -13,7 +13,7 @@ render(
13
13
  description="Sessões com acesso à sua conta."
14
14
  actions={<Button variant="outline">Encerrar outras sessões</Button>}
15
15
  >
16
- <div className="rounded-lg border border-border p-4">MacBook Pro · ativo agora</div>
16
+ <div className="rounded-lg border border-border p-4">MacBook Para o · ativo agora</div>
17
17
  </Content>,
18
18
  )
19
19
  ```
@@ -34,7 +34,7 @@ render(
34
34
  <ContentActions><Button variant="outline">Atualizar</Button></ContentActions>
35
35
  </ContentHeader>
36
36
  <ContentBody>
37
- <div className="rounded-lg border border-border p-4">MacBook Pro · ativo agora</div>
37
+ <div className="rounded-lg border border-border p-4">MacBook Para o · ativo agora</div>
38
38
  </ContentBody>
39
39
  </Content>,
40
40
  )
@@ -1,6 +1,6 @@
1
- ## Básico
1
+ ## Copiar por ícone
2
2
 
3
- Sem filhos, é um botão-ícone: copia `value` e o ícone vira um check por ~1.5s. Bom pra toolbar ou célula estreita, ao lado de um ID/token/slug.
3
+ Sem filhos, é um botão-ícone: copia `value` e o ícone vira um check por ~1.5s. Bom para toolbar ou célula estreita, ao lado de um ID/token/slug.
4
4
 
5
5
  ```tsx preview
6
6
  <Copyable value="opus_sk_1a2b3c4d5e6f" className="text-muted-foreground hover:text-foreground" />
@@ -21,7 +21,8 @@ Com filhos, o valor visível fica à esquerda e o ícone à direita — clicar n
21
21
 
22
22
  ## Duração do feedback
23
23
 
24
- `feedbackMs` ajusta quanto o check dura (default 1500). Some no-op silencioso se o clipboard não existir (contexto inseguro/SSR).
24
+ `feedbackMs` ajusta por quanto tempo a confirmação aparece; o padrão é 1500 milissegundos. Se a
25
+ área de transferência não estiver disponível, a ação não produz efeito.
25
26
 
26
27
  ```tsx preview
27
28
  <Copyable value="copiado devagar" feedbackMs={3000} className="text-muted-foreground hover:text-foreground">
@@ -6,7 +6,7 @@ title: Customização
6
6
 
7
7
  Cinco alavancas, do global ao pontual — e um limite de propósito. O caminho previsto é compor
8
8
  e configurar, nunca forkar componente: o que não cabe nas alavancas evolui no Opus (com
9
- divergência declarada), pra valer pra casa toda.
9
+ divergência declarada), para valer para casa toda.
10
10
 
11
11
  ## 1 · Identidade por tokens
12
12
 
@@ -36,7 +36,7 @@ de 16, sem transformar esse valor em uma regra da biblioteca.
36
36
  ## 2 · className em tudo
37
37
 
38
38
  > Todo componente termina em `cn(base, className)` com tailwind-merge: o utilitário do consumidor
39
- > vence o conflito. Pra layout local (largura, margem, grid) — não pra repintar o visual da casa.
39
+ > vence o conflito. Para layout local (largura, margem, grid) — não para repintar o visual da casa.
40
40
 
41
41
  ```tsx
42
42
  <Button className="w-full">Continuar</Button>
@@ -47,7 +47,7 @@ de 16, sem transformar esse valor em uma regra da biblioteca.
47
47
  ## 3 · Recomposição estrutural
48
48
 
49
49
  > Os componentes são explodidos em slots. `asChild` (Radix Slot) renderiza como outro elemento
50
- > mantendo estilo e comportamento; os `*Variants` aplicam a cara da casa num elemento arbitrário.
50
+ > mantendo estilo e comportamento; os `*Variants` aplicam a cara da casa em um elemento arbitrário.
51
51
 
52
52
  ```tsx preview
53
53
  <Button asChild variant="outline">
@@ -65,7 +65,7 @@ de 16, sem transformar esse valor em uma regra da biblioteca.
65
65
  // asChild: o filho VIRA o botão (sem forkar estilo).
66
66
  <Button asChild><a href="/docs">Abrir documentação</a></Button>
67
67
 
68
- // buttonVariants: a cara da casa num elemento qualquer.
68
+ // buttonVariants: a cara da casa em um elemento qualquer.
69
69
  <a className={buttonVariants({ variant: 'outline' })}>Link estilizado</a>
70
70
  ```
71
71
 
@@ -115,4 +115,4 @@ const [open, setOpen] = useState(false)
115
115
 
116
116
  Se uma necessidade real não cabe nas alavancas (tokens · className · slots/asChild · props ·
117
117
  contrato), o movimento não é dialeto local: é evoluir o componente **no Opus**, com a divergência
118
- declarada (skill `build-opus-ui`) — assim a mudança vale pra casa toda, e esta doc passa a mostrá-la.
118
+ declarada (skill `build-opus-ui`) — assim a mudança vale para casa toda, e esta doc passa a mostrá-la.
@@ -16,9 +16,9 @@ No seu projeto, uma linha por apontamento em `.opus/issues.jsonl` na raiz do rep
16
16
 
17
17
  ## Não trave esperando
18
18
 
19
- O ponto do ciclo é **não bloquear a entrega**. Bateu num gap ou num bug do Opus:
19
+ O ponto do ciclo é **não bloquear a entrega**. Bateu em um gap ou em um bug do Opus:
20
20
 
21
- 1. **Contorne local** — componha um wrapper no seu projeto. O Opus entrega _source_, então dá pra embrulhar qualquer superfície dele. Nunca edite `node_modules` (some no próximo install).
21
+ 1. **Contorne local** — componha um wrapper no seu projeto. O Opus entrega _source_, então dá para embrulhar qualquer superfície dele. Nunca edite `node_modules` (some no próximo install).
22
22
  2. **Entregue** a feature com o workaround.
23
23
  3. **Aponte** no `.opus/issues.jsonl` e siga em frente.
24
24
 
@@ -28,7 +28,7 @@ O "depois" — o conserto no Opus — corre em paralelo. Ele não segura o seu t
28
28
 
29
29
  O apontamento é colhido e abre uma **Issue no repositório do Opus**, onde a triagem acontece (deduplicada — re-apontar o mesmo é idempotente):
30
30
 
31
- - **Enhancement** aceito (com reincidência) → implementado no Opus → sai num _bump_ → seu projeto atualiza o pin (`opus.json`) e troca o workaround pelo import.
31
+ - **Enhancement** aceito (com reincidência) → implementado no Opus → sai em um _bump_ → seu projeto atualiza o pin (`opus.json`) e troca o workaround pelo import.
32
32
  - **Bug** → vira _fix_ + entrada no `CHANGELOG` → no _bump_, o workaround sai.
33
33
 
34
34
  A régua e a decisão ficam com quem mantém o Opus — hoje, a **Softize**. O registro curado das promoções vive no `PROMOTED.md` do pacote.
@@ -1,9 +1,9 @@
1
1
  ## Estados
2
2
 
3
- Um lugar pro erro/carregando/vazio/conteúdo de uma carga. Carregando = Spinner centralizado;
4
- vazio = texto em uma moldura sólida no modo bloco; erro = aviso calmo (a mensagem técnica não vai
5
- pra tela). É o "antes" do conteúdo
6
- pro "depois" (ação em andamento), use o busy do Button.
3
+ Use `DataState` para apresentar carregamento, erro, vazio e conteúdo de uma mesma consulta. O
4
+ carregamento usa `Spinner`; o vazio preserva uma moldura sólida; e o erro apresenta uma mensagem
5
+ segura, sem expor detalhes técnicos. Para uma ação em andamento depois do clique, use `busy` em
6
+ `Button`.
7
7
 
8
8
  ```tsx preview col
9
9
  <div className="w-full space-y-3">
@@ -19,12 +19,11 @@ pro "depois" (ação em andamento), use o busy do Button.
19
19
  </div>
20
20
  ```
21
21
 
22
- ## Em tabela (colSpan)
22
+ ## Dentro de uma tabela
23
23
 
24
- Em lista ou tabela já emoldurada, passe colSpan: o estado vira UMA linha de largura cheia
25
- (`<tr><td colSpan>`) que cabe direto no `<tbody>`; o conteúdo são as `<tr>` dos itens. A tabela
26
- continua dona da borda, sem uma segunda moldura no vazio. Para uma região disponível para criação
27
- ou vínculo, com título, descrição ou ação, use `Empty`, cuja moldura é tracejada.
24
+ Em uma tabela já emoldurada, passe `colSpan` para ocupar uma linha inteira dentro de `<tbody>`. A
25
+ tabela continua responsável pela borda, evitando uma segunda moldura no estado vazio. Para uma
26
+ região disponível para criação ou vínculo, use `Empty`.
28
27
 
29
28
  ```tsx preview col
30
29
  <table className="w-full overflow-hidden rounded-lg border border-border text-sm">
@@ -38,13 +37,13 @@ ou vínculo, com título, descrição ou ação, use `Empty`, cuja moldura é tr
38
37
  </table>
39
38
  ```
40
39
 
41
- ## Props
40
+ ## Propriedades de DataState
42
41
 
43
- | Prop | Tipo | Default | Descrição |
42
+ | Propriedade | Tipo | Padrão | Descrição |
44
43
  |---|---|---|---|
45
44
  | `loading` | `boolean` | | Carregando (antes do conteúdo) — mostra o Spinner centralizado. |
46
45
  | `empty` | `boolean` | | Sem itens — mostra o emptyText. |
47
46
  | `emptyText` | `string` | | Texto do vazio (pt-BR, ex.: "Nenhum papel."). |
48
- | `error` | `{ message?: string } \| null` | | Erro da carga — aviso calmo. A mensagem técnica NÃO vai pra tela (use errorText). |
47
+ | `error` | `{ message?: string } \| null` | | Erro da carga — aviso calmo. A mensagem técnica não vai para tela (use errorText). |
49
48
  | `errorText` | `string` | `'Não foi possível carregar.'` | Aviso de erro, orientado ao usuário. |
50
49
  | `colSpan` | `number` | | Em tabela: renderiza o estado como `<tr><td colSpan>` (cabe direto no tbody). |