@softize/opus 19.0.0 → 20.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +193 -0
- package/bin/cli.mjs +5 -0
- package/bin/lib/check.mjs +198 -10
- package/bin/lib/copy.mjs +29 -0
- package/bin/lib/mcp.mjs +1 -1
- package/docs/adr/0023-surfaces-share-one-anatomy-and-two-layouts.md +5 -0
- package/docs/adr/0024-fill-height-propagates-by-context.md +118 -0
- package/docs/data-products.md +15 -9
- package/docs/protocol.md +3 -4
- package/docs/releasing.md +2 -2
- package/package.json +2 -2
- package/registry/skills/create-opus-action/scripts/scaffold.mjs +2 -1
- package/registry/templates/app/package.json +1 -1
- package/src/core/runtime.ts +96 -8
- package/src/core/types.ts +5 -2
- package/src/ui/components/patterns/action-form-card.tsx +11 -1
- package/src/ui/components/patterns/content-header.tsx +15 -3
- package/src/ui/components/patterns/fill-region.ts +150 -0
- package/src/ui/components/patterns/list.tsx +89 -78
- package/src/ui/components/patterns/page.tsx +20 -4
- package/src/ui/components/patterns/presentation.tsx +52 -37
- package/src/ui/components/patterns/split.tsx +44 -4
- package/src/ui/components/patterns/surface-anatomy.ts +35 -8
- package/src/ui/components/patterns/trigger.tsx +12 -2
- package/src/ui/components/primitives/alert.tsx +9 -1
- package/src/ui/components/primitives/avatar.tsx +7 -3
- package/src/ui/components/primitives/carousel.tsx +34 -5
- package/src/ui/components/primitives/checkbox.tsx +11 -3
- package/src/ui/components/primitives/command.tsx +2 -1
- package/src/ui/components/primitives/copyable.tsx +120 -10
- package/src/ui/components/primitives/dialog.tsx +41 -10
- package/src/ui/components/primitives/drawer.tsx +9 -1
- package/src/ui/components/primitives/empty.tsx +1 -1
- package/src/ui/components/primitives/icon-picker.tsx +6 -2
- package/src/ui/components/primitives/icon-tile.tsx +7 -0
- package/src/ui/components/primitives/input-group.tsx +9 -2
- package/src/ui/components/primitives/input-otp.tsx +1 -1
- package/src/ui/components/primitives/kbd.tsx +1 -1
- package/src/ui/components/primitives/label.tsx +3 -0
- package/src/ui/components/primitives/menu.tsx +5 -0
- package/src/ui/components/primitives/popover.tsx +1 -1
- package/src/ui/components/primitives/progress.tsx +9 -1
- package/src/ui/components/primitives/slider.tsx +62 -11
- package/src/ui/components/primitives/truncate.tsx +10 -1
- package/src/ui/docs/content/accordion.md +74 -27
- package/src/ui/docs/content/action-form-card.md +24 -15
- package/src/ui/docs/content/action-form-dialog.md +17 -7
- package/src/ui/docs/content/action-form.md +92 -77
- package/src/ui/docs/content/action-list-dialog.md +75 -38
- package/src/ui/docs/content/action-list.md +134 -52
- package/src/ui/docs/content/action-trigger.md +27 -10
- package/src/ui/docs/content/action-view.md +14 -14
- package/src/ui/docs/content/actions.md +161 -66
- package/src/ui/docs/content/ai.md +43 -44
- package/src/ui/docs/content/alert.md +83 -29
- package/src/ui/docs/content/ask.md +51 -26
- package/src/ui/docs/content/aspect-ratio.md +22 -24
- package/src/ui/docs/content/audit.md +23 -19
- package/src/ui/docs/content/auth.md +38 -19
- package/src/ui/docs/content/avatar.md +54 -5
- package/src/ui/docs/content/badge.md +29 -9
- package/src/ui/docs/content/breadcrumb.md +21 -8
- package/src/ui/docs/content/button.md +73 -43
- package/src/ui/docs/content/calendar.md +134 -26
- package/src/ui/docs/content/card.md +41 -15
- package/src/ui/docs/content/carousel.md +37 -6
- package/src/ui/docs/content/chat.md +118 -37
- package/src/ui/docs/content/checkbox.md +73 -7
- package/src/ui/docs/content/cli.md +94 -55
- package/src/ui/docs/content/collapsible.md +43 -19
- package/src/ui/docs/content/command.md +30 -8
- package/src/ui/docs/content/composer.md +23 -8
- package/src/ui/docs/content/content.md +31 -7
- package/src/ui/docs/content/copyable.md +39 -8
- package/src/ui/docs/content/customization.md +55 -46
- package/src/ui/docs/content/cycle.md +33 -18
- package/src/ui/docs/content/data-products.md +115 -0
- package/src/ui/docs/content/data-state.md +20 -6
- package/src/ui/docs/content/data.md +20 -19
- package/src/ui/docs/content/detail.md +12 -5
- package/src/ui/docs/content/dialog.md +107 -24
- package/src/ui/docs/content/dictionary-value.md +4 -4
- package/src/ui/docs/content/dock.md +54 -19
- package/src/ui/docs/content/dot.md +35 -5
- package/src/ui/docs/content/drawer.md +63 -19
- package/src/ui/docs/content/empty-value.md +20 -6
- package/src/ui/docs/content/empty.md +24 -3
- package/src/ui/docs/content/events.md +76 -16
- package/src/ui/docs/content/executions.md +9 -9
- package/src/ui/docs/content/field.md +21 -6
- package/src/ui/docs/content/getting-started.md +44 -34
- package/src/ui/docs/content/icon-picker.md +19 -13
- package/src/ui/docs/content/icon-tile.md +28 -5
- package/src/ui/docs/content/input-otp.md +58 -7
- package/src/ui/docs/content/input.md +22 -3
- package/src/ui/docs/content/item.md +53 -6
- package/src/ui/docs/content/kbd.md +5 -1
- package/src/ui/docs/content/label.md +13 -4
- package/src/ui/docs/content/log.md +5 -5
- package/src/ui/docs/content/markdown.md +5 -4
- package/src/ui/docs/content/mcp.md +49 -23
- package/src/ui/docs/content/menu.md +95 -10
- package/src/ui/docs/content/metric-card.md +12 -4
- package/src/ui/docs/content/observability.md +10 -9
- package/src/ui/docs/content/page.md +118 -12
- package/src/ui/docs/content/pagination.md +13 -5
- package/src/ui/docs/content/pane.md +55 -5
- package/src/ui/docs/content/popover.md +42 -5
- package/src/ui/docs/content/presentation.md +91 -47
- package/src/ui/docs/content/progress.md +27 -14
- package/src/ui/docs/content/queue.md +39 -21
- package/src/ui/docs/content/radio-group.md +26 -4
- package/src/ui/docs/content/router.md +29 -10
- package/src/ui/docs/content/runtime.md +90 -54
- package/src/ui/docs/content/scheduler.md +53 -21
- package/src/ui/docs/content/scroll-area.md +42 -35
- package/src/ui/docs/content/select.md +78 -33
- package/src/ui/docs/content/semantic-context.md +21 -2
- package/src/ui/docs/content/separator.md +15 -9
- package/src/ui/docs/content/sidebar.md +3 -2
- package/src/ui/docs/content/skeleton.md +6 -1
- package/src/ui/docs/content/slider.md +37 -9
- package/src/ui/docs/content/spinner.md +4 -3
- package/src/ui/docs/content/split.md +19 -0
- package/src/ui/docs/content/storage.md +8 -9
- package/src/ui/docs/content/switch.md +10 -7
- package/src/ui/docs/content/table.md +46 -8
- package/src/ui/docs/content/tabs.md +14 -4
- package/src/ui/docs/content/testing.md +76 -31
- package/src/ui/docs/content/textarea.md +5 -4
- package/src/ui/docs/content/toast.md +48 -7
- package/src/ui/docs/content/toggle.md +3 -3
- package/src/ui/docs/content/tokens.md +15 -26
- package/src/ui/docs/content/tooltip.md +18 -2
- package/src/ui/docs/content/truncate.md +36 -6
- package/src/ui/docs/content/ui.md +74 -22
- package/src/ui/docs/content/upgrading.md +45 -36
- package/src/ui/docs/plugin.ts +36 -2
- package/src/ui/docs/registry.tsx +6 -0
- package/src/ui/drivers/react.tsx +16 -8
- package/src/ui/meta.ts +31 -31
- package/src/vite/design.ts +16 -4
|
@@ -17,13 +17,58 @@ direita; separe ações perigosas e declare `context="danger"` nelas.
|
|
|
17
17
|
</Menu>
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
`MenuShortcut` só exibe o atalho. Registre a tecla no aplicativo; o menu não a escuta.
|
|
21
|
+
|
|
22
|
+
## Executar a ação do item
|
|
23
|
+
|
|
24
|
+
`onSelect` recebe a escolha feita por clique ou teclado. Depois dele, o menu fecha. Para manter o
|
|
25
|
+
painel aberto, como em uma alternância que a pessoa pode repetir, chame `event.preventDefault()` no
|
|
26
|
+
handler. `disabled` mantém o item visível, mas impede a seleção.
|
|
27
|
+
|
|
28
|
+
```tsx preview
|
|
29
|
+
const [pinned, setPinned] = useState(false)
|
|
30
|
+
const [last, setLast] = useState('Nenhuma ação ainda.')
|
|
31
|
+
|
|
32
|
+
render(
|
|
33
|
+
<div className="flex items-center gap-4">
|
|
34
|
+
<Menu>
|
|
35
|
+
<MenuTrigger asChild>
|
|
36
|
+
<Button variant="outline">Sessão <ChevronDown /></Button>
|
|
37
|
+
</MenuTrigger>
|
|
38
|
+
<MenuContent align="start">
|
|
39
|
+
<MenuItem onSelect={() => setLast('Link copiado.')}><Link /> Copiar link</MenuItem>
|
|
40
|
+
<MenuItem
|
|
41
|
+
onSelect={(event) => {
|
|
42
|
+
event.preventDefault()
|
|
43
|
+
setPinned((current) => !current)
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{pinned ? <PinOff /> : <Pin />} {pinned ? 'Desafixar' : 'Fixar'}
|
|
47
|
+
</MenuItem>
|
|
48
|
+
<MenuItem disabled><Share2 /> Compartilhar</MenuItem>
|
|
49
|
+
</MenuContent>
|
|
50
|
+
</Menu>
|
|
51
|
+
<p className="text-sm text-muted-foreground">{last}</p>
|
|
52
|
+
</div>,
|
|
53
|
+
)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Para navegar em vez de executar, use `asChild` com um link: o item passa a renderizar o `<a>`,
|
|
57
|
+
com o estilo e a navegação por teclado do menu.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
<MenuItem asChild>
|
|
61
|
+
<a href="/sessoes/42">Abrir sessão</a>
|
|
62
|
+
</MenuItem>
|
|
63
|
+
```
|
|
64
|
+
|
|
20
65
|
## Abrir pelo menu de contexto
|
|
21
66
|
|
|
22
67
|
Para abrir pelo clique direito, controle o estado do menu e use a posição do ponteiro como âncora.
|
|
23
|
-
|
|
68
|
+
Não há componente separado para menu de contexto; use `Menu` controlado.
|
|
24
69
|
|
|
25
70
|
```tsx preview
|
|
26
|
-
const [pos, setPos] = useState(null)
|
|
71
|
+
const [pos, setPos] = useState<{ x: number; y: number } | null>(null)
|
|
27
72
|
|
|
28
73
|
render(
|
|
29
74
|
<div>
|
|
@@ -34,7 +79,7 @@ render(
|
|
|
34
79
|
}}
|
|
35
80
|
className="flex h-28 items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground select-none"
|
|
36
81
|
>
|
|
37
|
-
|
|
82
|
+
Clique com o botão direito aqui
|
|
38
83
|
</div>
|
|
39
84
|
<Menu open={pos !== null} onOpenChange={(open) => { if (!open) setPos(null) }}>
|
|
40
85
|
<MenuTrigger asChild>
|
|
@@ -83,7 +128,8 @@ render(
|
|
|
83
128
|
|
|
84
129
|
## Submenu e inset
|
|
85
130
|
|
|
86
|
-
MenuSub aninha um nível
|
|
131
|
+
`MenuSub` aninha um nível: `MenuSubTrigger` abre o painel `MenuSubContent` ao lado do item. `inset`
|
|
132
|
+
alinha itens sem ícone com os que têm.
|
|
87
133
|
|
|
88
134
|
```tsx preview
|
|
89
135
|
<Menu>
|
|
@@ -93,7 +139,7 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
93
139
|
<MenuContent align="start">
|
|
94
140
|
<MenuItem><ExternalLink /> Abrir preview</MenuItem>
|
|
95
141
|
<MenuSub>
|
|
96
|
-
<MenuSubTrigger><
|
|
142
|
+
<MenuSubTrigger><FolderInput /> Mover para</MenuSubTrigger>
|
|
97
143
|
<MenuSubContent>
|
|
98
144
|
<MenuItem>Empresa X</MenuItem>
|
|
99
145
|
<MenuItem>Softize</MenuItem>
|
|
@@ -104,6 +150,10 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
104
150
|
</Menu>
|
|
105
151
|
```
|
|
106
152
|
|
|
153
|
+
`MenuContent` já renderiza o painel em um portal, fora do fluxo da página. `MenuPortal` continua
|
|
154
|
+
exportado, mas está depreciado e sai em uma próxima versão maior: envolver o conteúdo com ele não
|
|
155
|
+
muda onde o painel aparece. Código novo usa só `MenuContent`.
|
|
156
|
+
|
|
107
157
|
## Propriedades de Menu
|
|
108
158
|
|
|
109
159
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
@@ -112,10 +162,26 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
112
162
|
| `onOpenChange` | `(open: boolean) => void` | | Chamado quando o painel abre ou fecha. |
|
|
113
163
|
| `defaultOpen` | `boolean` | `false` | Estado inicial no modo não controlado. |
|
|
114
164
|
|
|
165
|
+
## Propriedades de MenuTrigger
|
|
166
|
+
|
|
167
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
168
|
+
|---|---|---|---|
|
|
169
|
+
| `asChild` | `boolean` | `false` | Usa o filho, como um `Button`, como gatilho em vez de renderizar outro `<button>`. |
|
|
170
|
+
|
|
171
|
+
## Propriedades de MenuContent
|
|
172
|
+
|
|
173
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
174
|
+
|---|---|---|---|
|
|
175
|
+
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alinhamento do painel em relação ao gatilho. |
|
|
176
|
+
| `sideOffset` | `number` | `4` | Distância entre o gatilho e o painel. |
|
|
177
|
+
|
|
115
178
|
## Propriedades de MenuItem
|
|
116
179
|
|
|
117
180
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
118
181
|
|---|---|---|---|
|
|
182
|
+
| `onSelect` | `(event: Event) => void` | | Chamado quando a pessoa escolhe o item por clique ou teclado. `event.preventDefault()` mantém o menu aberto. |
|
|
183
|
+
| `disabled` | `boolean` | `false` | Mantém o item visível e impede a seleção. |
|
|
184
|
+
| `asChild` | `boolean` | `false` | Renderiza o filho, como um `<a>`, com o comportamento de item de menu. |
|
|
119
185
|
| `context` | `'neutral' \| 'danger'` | `'neutral'` | `danger` sinaliza uma ação com consequência perigosa. |
|
|
120
186
|
| `inset` | `boolean` | | Alinha um item sem ícone com os itens que possuem ícone. |
|
|
121
187
|
|
|
@@ -125,12 +191,11 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
125
191
|
`MenuLabel` para nomear o grupo e `MenuSeparator` para separá-lo do próximo. Não tem props
|
|
126
192
|
próprias além das de DOM.
|
|
127
193
|
|
|
128
|
-
## Propriedades de
|
|
194
|
+
## Propriedades de MenuLabel
|
|
129
195
|
|
|
130
196
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
131
197
|
|---|---|---|---|
|
|
132
|
-
| `
|
|
133
|
-
| `sideOffset` | `number` | `4` | Distância entre o gatilho e o painel. |
|
|
198
|
+
| `inset` | `boolean` | | Alinha o rótulo com itens que possuem ícone. |
|
|
134
199
|
|
|
135
200
|
## Propriedades de MenuCheckboxItem
|
|
136
201
|
|
|
@@ -153,14 +218,34 @@ próprias além das de DOM.
|
|
|
153
218
|
| `value` | `string` | | Valor que o item entrega ao `MenuRadioGroup` quando é selecionado. |
|
|
154
219
|
| `disabled` | `boolean` | `false` | Impede a seleção do item. |
|
|
155
220
|
|
|
156
|
-
## Propriedades de
|
|
221
|
+
## Propriedades de MenuSeparator
|
|
222
|
+
|
|
223
|
+
`MenuSeparator` desenha a linha entre grupos de itens. Não tem props próprias; aceita as de um
|
|
224
|
+
elemento `div`, como `className`.
|
|
225
|
+
|
|
226
|
+
## Propriedades de MenuShortcut
|
|
227
|
+
|
|
228
|
+
`MenuShortcut` exibe o atalho no extremo direito do item. Não tem props próprias; aceita as de um
|
|
229
|
+
elemento `span`, como `className`.
|
|
230
|
+
|
|
231
|
+
## Propriedades de MenuSub
|
|
157
232
|
|
|
158
233
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
159
234
|
|---|---|---|---|
|
|
160
|
-
| `
|
|
235
|
+
| `open` | `boolean` | | Estado do submenu no modo controlado. |
|
|
236
|
+
| `onOpenChange` | `(open: boolean) => void` | | Chamado quando o submenu abre ou fecha. |
|
|
237
|
+
| `defaultOpen` | `boolean` | `false` | Estado inicial no modo não controlado. |
|
|
161
238
|
|
|
162
239
|
## Propriedades de MenuSubTrigger
|
|
163
240
|
|
|
164
241
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
165
242
|
|---|---|---|---|
|
|
166
243
|
| `inset` | `boolean` | | Alinha o gatilho do submenu sem ícone com os itens que possuem ícone. |
|
|
244
|
+
| `disabled` | `boolean` | `false` | Impede que o submenu abra. |
|
|
245
|
+
|
|
246
|
+
## Propriedades de MenuSubContent
|
|
247
|
+
|
|
248
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
249
|
+
|---|---|---|---|
|
|
250
|
+
| `sideOffset` | `number` | `0` | Distância entre o item que abre o submenu e o painel. |
|
|
251
|
+
| `alignOffset` | `number` | `0` | Deslocamento do painel ao longo do item que o abre. |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
MetricCard
|
|
2
|
-
valor já calculado e formatado; busca de dados,
|
|
3
|
-
consumidor.
|
|
1
|
+
Use `MetricCard` para apresentar uma medida resumida, como um total ou uma contagem, com rótulo,
|
|
2
|
+
valor e contexto em hierarquia consistente. Passe o valor já calculado e formatado; busca de dados,
|
|
3
|
+
recorte e regras de negócio permanecem no consumidor.
|
|
4
4
|
|
|
5
5
|
```tsx preview col
|
|
6
6
|
<MetricCard
|
|
@@ -101,6 +101,11 @@ render(
|
|
|
101
101
|
`active`, `activationLabel` e `onActivate` formam uma capacidade única: informe as três propriedades
|
|
102
102
|
para tornar o card ativável. O consumidor continua responsável pelo estado e pelo recorte aplicado.
|
|
103
103
|
|
|
104
|
+
O card ativo recebe a borda na cor primária. Ao passar o ponteiro, a borda se destaca, e o foco de
|
|
105
|
+
teclado desenha um anel por dentro da borda. Com ativação, use `onActivate` em vez de `onClick`: o
|
|
106
|
+
tipo recusa `onClick`, porque um clique genérico no card também dispararia ao usar `labelAction` ou
|
|
107
|
+
`action`. Enquanto `loading` estiver ativo, a ativação fica desabilitada.
|
|
108
|
+
|
|
104
109
|
## Carregamento
|
|
105
110
|
|
|
106
111
|
`loading` preserva a geometria do card com placeholders e marca a superfície como ocupada para
|
|
@@ -125,7 +130,10 @@ tecnologias assistivas. O contêiner da coleção continua responsável pela men
|
|
|
125
130
|
| `action` | `ReactNode` | | Ação relacionada diretamente à medida. |
|
|
126
131
|
| `active` | `boolean` | | Indica se a medida controla o recorte atualmente aplicado. Exige `activationLabel` e `onActivate`. |
|
|
127
132
|
| `activationLabel` | `string` | | Nome acessível da ativação. Exige `active` e `onActivate`. |
|
|
128
|
-
| `onActivate` | `() => void` | | Ativa a medida como recorte ou seleção. Exige `active` e `activationLabel`.
|
|
133
|
+
| `onActivate` | `() => void` | | Ativa a medida como recorte ou seleção. Exige `active` e `activationLabel`; não combina com `onClick`. Desabilitada durante `loading`. |
|
|
134
|
+
| `className` | `string` | | Ajusta o card, ou o contêiner quando há ativação ou medida complementar. |
|
|
135
|
+
|
|
136
|
+
As demais propriedades são as nativas de `div`.
|
|
129
137
|
|
|
130
138
|
## Propriedades de MetricCardSecondaryMetric
|
|
131
139
|
|
|
@@ -37,20 +37,21 @@ global. Um `Tracer` também pode ser injetado para testes ou providers não glob
|
|
|
37
37
|
|
|
38
38
|
## Semântica
|
|
39
39
|
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
40
|
+
- Os spans se chamam `opus.action <action>` e `opus.reaction <reaction>`.
|
|
41
|
+
- O span pai vem de `ContextBase.trace` ou do evento recebido.
|
|
42
|
+
- Actions usam `ActionResult.ok` para o status; reactions usam a resolução ou a rejeição da Promise.
|
|
43
|
+
- Somente atributos de baixa cardinalidade, de uma lista fixa, são anexados.
|
|
44
|
+
- Input, output, ator, tenant, request ID, código e mensagem de erro e baggage não entram no span.
|
|
45
45
|
- `TraceContext` devolve apenas `traceId`, `spanId`, `traceFlags` e `traceState`.
|
|
46
46
|
|
|
47
47
|
## Fronteira HTTP W3C
|
|
48
48
|
|
|
49
|
-
Os drivers Fastify e Node oferecem propagação explícita, desativada por
|
|
49
|
+
Os drivers Fastify e Node oferecem propagação explícita, desativada por padrão:
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
|
-
fastifyServer({ app, traceContext: 'w3c' })
|
|
53
|
-
nodeServer
|
|
52
|
+
const server = fastifyServer({ app, traceContext: 'w3c' })
|
|
53
|
+
// nodeServer devolve { adapter, handler, hasRoute }; o runtime recebe `adapter`.
|
|
54
|
+
const node = nodeServer({ traceContext: 'w3c' })
|
|
54
55
|
```
|
|
55
56
|
|
|
56
57
|
O opt-in extrai um `traceparent` v00 válido (e `tracestate` limitado) para
|
|
@@ -65,7 +66,7 @@ O driver OpenTelemetry não instrumenta HTTP automaticamente e não oferece back
|
|
|
65
66
|
Use o opt-in dos drivers Fastify/Node acima ou forneça `ContextBase.trace` na instrumentação
|
|
66
67
|
de outro transporte. A fronteira implementa somente `traceparent` v00 e uma validação
|
|
67
68
|
defensiva limitada de `tracestate`; não é um propagator OTel genérico.
|
|
68
|
-
|
|
69
|
+
A saúde do exporter e do Collector só é reportada quando o app injeta `healthCheck`; o padrão
|
|
69
70
|
confirma apenas que a API do driver está configurada.
|
|
70
71
|
Sem um provider que produza spans válidos, o driver falha antes do callback e o runtime aplica
|
|
71
72
|
a degradação lenient — executa a action uma vez, sem trace — em vez de propagar IDs inválidos.
|
|
@@ -13,9 +13,8 @@ A forma curta é o padrão para páginas comuns. Fora de `PageShell`, ela cria `
|
|
|
13
13
|
`PageBody`. Dentro dele, cria `PageHeader` para as ações, `PageIntro` para o título e `PageBody`.
|
|
14
14
|
A forma explícita exige exatamente um heading principal. Use `PageTitle` no header ou intro,
|
|
15
15
|
`Content level={1}` no body, ou deixe um `PageState` ativo assumir esse papel. Assim, header e
|
|
16
|
-
introdução podem ser omitidos quando o próprio conteúdo nomeia a página.
|
|
17
|
-
|
|
18
|
-
conteúdo que os explica.
|
|
16
|
+
introdução podem ser omitidos quando o próprio conteúdo nomeia a página. Contadores e outros
|
|
17
|
+
indicadores pertencem ao conteúdo que os explica.
|
|
19
18
|
|
|
20
19
|
A `Page` é contínua por definição: separar o chrome do conteúdo é trabalho do shell, e não há
|
|
21
20
|
divisores entre regiões para declarar. O `layout` da `Page` não é a anatomia de superfície de
|
|
@@ -51,7 +50,8 @@ render(
|
|
|
51
50
|
|
|
52
51
|
Use `PageBack` em uma subpágina simples. O destino é explícito para continuar correto após refresh ou
|
|
53
52
|
acesso por link direto; não derive esse retorno do histórico do navegador. No header padrão, o
|
|
54
|
-
controle aparece antes do título como ícone
|
|
53
|
+
controle aparece antes do título como ícone; o nome acessível e a dica nativa do navegador (atributo
|
|
54
|
+
`title`) derivam do destino.
|
|
55
55
|
|
|
56
56
|
```tsx preview col
|
|
57
57
|
<Page>
|
|
@@ -64,8 +64,30 @@ controle aparece antes do título como ícone com nome acessível e tooltip deri
|
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
Não combine `PageBack` com breadcrumb. Use o retorno para um único pai conhecido. Quando houver
|
|
67
|
-
mais de um ancestral relevante, envolva o `Breadcrumb` em `PageNavigation`; ele
|
|
68
|
-
posição introdutória sem transformar a trilha em ação.
|
|
67
|
+
mais de um ancestral relevante, envolva o [`Breadcrumb`](/ui/breadcrumb) em `PageNavigation`; ele
|
|
68
|
+
ocupa a mesma posição introdutória sem transformar a trilha em ação.
|
|
69
|
+
|
|
70
|
+
```tsx preview col
|
|
71
|
+
<Page>
|
|
72
|
+
<PageHeader>
|
|
73
|
+
<PageNavigation>
|
|
74
|
+
<Breadcrumb>
|
|
75
|
+
<BreadcrumbList>
|
|
76
|
+
<BreadcrumbItem>Vendas</BreadcrumbItem>
|
|
77
|
+
<BreadcrumbSeparator />
|
|
78
|
+
<BreadcrumbItem>Clientes</BreadcrumbItem>
|
|
79
|
+
<BreadcrumbSeparator />
|
|
80
|
+
<BreadcrumbPage>Carla Souza</BreadcrumbPage>
|
|
81
|
+
</BreadcrumbList>
|
|
82
|
+
</Breadcrumb>
|
|
83
|
+
</PageNavigation>
|
|
84
|
+
</PageHeader>
|
|
85
|
+
<PageIntro>
|
|
86
|
+
<PageTitle>Carla Souza</PageTitle>
|
|
87
|
+
</PageIntro>
|
|
88
|
+
<PageBody>Dados do cliente.</PageBody>
|
|
89
|
+
</Page>
|
|
90
|
+
```
|
|
69
91
|
|
|
70
92
|
## Barra persistente do shell
|
|
71
93
|
|
|
@@ -149,8 +171,87 @@ render(
|
|
|
149
171
|
|
|
150
172
|
Fora de `PageShell`, use `PageIntro` quando o conteúdo precisar de uma introdução separada do
|
|
151
173
|
chrome. Dentro do shell, ele pode ser combinado com `PageHeader`: o primeiro permanece no conteúdo
|
|
152
|
-
e o segundo alimenta a barra. Em uma página de listagem, `Content` pode fornecer o
|
|
153
|
-
da coleção, deixando `Page` apenas com `PageBody`.
|
|
174
|
+
e o segundo alimenta a barra. Em uma página de listagem, [`Content`](/ui/content) pode fornecer o
|
|
175
|
+
título e as ações da coleção, deixando `Page` apenas com `PageBody`.
|
|
176
|
+
|
|
177
|
+
## Ações de etapa no rodapé
|
|
178
|
+
|
|
179
|
+
Use `PageFooter` quando a página for uma etapa de um fluxo e a decisão precisar ficar ao alcance ao
|
|
180
|
+
fim do conteúdo, como confirmar uma importação. O rodapé fica depois do body, com a mesma altura da
|
|
181
|
+
barra e as ações alinhadas no fim da linha.
|
|
182
|
+
|
|
183
|
+
```tsx preview col
|
|
184
|
+
<Page>
|
|
185
|
+
<PageHeader>
|
|
186
|
+
<PageTitle>Importar clientes</PageTitle>
|
|
187
|
+
</PageHeader>
|
|
188
|
+
<PageBody>Revise os 128 registros antes de confirmar.</PageBody>
|
|
189
|
+
<PageFooter>
|
|
190
|
+
<ButtonGroup mode="spaced">
|
|
191
|
+
<Button variant="ghost">Cancelar</Button>
|
|
192
|
+
<Button>Importar</Button>
|
|
193
|
+
</ButtonGroup>
|
|
194
|
+
</PageFooter>
|
|
195
|
+
</Page>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Ocupar a altura disponível
|
|
199
|
+
|
|
200
|
+
Use `layout="fill"` quando uma região interna, como uma tabela longa ou um split, precisar rolar
|
|
201
|
+
dentro da página em vez de a página inteira rolar. A página passa a ocupar exatamente a altura do
|
|
202
|
+
contêiner. Para uma região que você mesmo compõe, dê `min-h-0 flex-1` à que assume a folga e a
|
|
203
|
+
rolagem, como o `PageBody` do exemplo.
|
|
204
|
+
|
|
205
|
+
```tsx preview col
|
|
206
|
+
render(
|
|
207
|
+
<div className="h-72 overflow-hidden rounded-lg border border-border">
|
|
208
|
+
<Page layout="fill">
|
|
209
|
+
<PageHeader>
|
|
210
|
+
<PageTitle>Ordens de serviço</PageTitle>
|
|
211
|
+
</PageHeader>
|
|
212
|
+
<PageBody className="min-h-0 flex-1 space-y-2 overflow-y-auto">
|
|
213
|
+
{['OS-1842', 'OS-1839', 'OS-1835', 'OS-1830', 'OS-1827', 'OS-1821', 'OS-1818'].map((id) => (
|
|
214
|
+
<div key={id} className="rounded-md border border-border p-3 text-sm">
|
|
215
|
+
{id}
|
|
216
|
+
</div>
|
|
217
|
+
))}
|
|
218
|
+
</PageBody>
|
|
219
|
+
</Page>
|
|
220
|
+
</div>,
|
|
221
|
+
);
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Uma [`ActionList`](/ui/action-list) não precisa dessas classes. Filha de `PageBody`, ou de um
|
|
225
|
+
[`Content`](/ui/content) dentro dele, ela recebe a altura da página e assume `layout="fill"`
|
|
226
|
+
sozinha: `PageBody`, `Content` e `ContentBody` passam a repassar a altura até ela, o cabeçalho da
|
|
227
|
+
tabela fica fixo e só os resultados rolam. As demais seções do `PageBody` mantêm a altura do
|
|
228
|
+
próprio conteúdo, e uma página `fill` sem lista não muda.
|
|
229
|
+
|
|
230
|
+
## Levar as ações para outra barra
|
|
231
|
+
|
|
232
|
+
`PageShell` já projeta as ações na barra persistente. Use `PageActionsTarget` somente quando um
|
|
233
|
+
hospedeiro próprio tiver outra barra para elas: as `PageActions` da árvore interna passam a ser
|
|
234
|
+
renderizadas no elemento indicado em `target`. Enquanto `target` for `null`, fora de um shell, as
|
|
235
|
+
ações continuam no cabeçalho da página.
|
|
236
|
+
|
|
237
|
+
```tsx preview col
|
|
238
|
+
function Example() {
|
|
239
|
+
const [target, setTarget] = useState<HTMLElement | null>(null)
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div className="space-y-3">
|
|
243
|
+
<div ref={setTarget} className="flex justify-end rounded-lg border border-border p-2" />
|
|
244
|
+
<PageActionsTarget target={target}>
|
|
245
|
+
<Page title="Clientes" actions={<Button variant="outline">Exportar</Button>}>
|
|
246
|
+
Conteúdo da listagem.
|
|
247
|
+
</Page>
|
|
248
|
+
</PageActionsTarget>
|
|
249
|
+
</div>
|
|
250
|
+
)
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
render(<Example />)
|
|
254
|
+
```
|
|
154
255
|
|
|
155
256
|
## Estados integrais
|
|
156
257
|
|
|
@@ -195,7 +296,8 @@ e, sem `title`, valem `errorMessage` e `emptyMessage`.
|
|
|
195
296
|
```
|
|
196
297
|
|
|
197
298
|
Não use `PageState` para uma falha parcial. Se outra parte da página continua utilizável, mantenha o
|
|
198
|
-
estado na própria seção com `DataState
|
|
299
|
+
estado na própria seção com [`DataState`](/ui/data-state), [`ActionView`](/ui/action-view),
|
|
300
|
+
[`ActionList`](/ui/action-list) ou [`Alert`](/ui/alert).
|
|
199
301
|
|
|
200
302
|
## Propriedades de Page
|
|
201
303
|
|
|
@@ -203,9 +305,10 @@ estado na própria seção com `DataState`, `ActionView`, `ActionList` ou `Alert
|
|
|
203
305
|
| ----------- | ----------- | ----------- | ----------------------------------------------------------------------------------------------- |
|
|
204
306
|
| `title` | `ReactNode` | | O h1 da página. |
|
|
205
307
|
| `actions` | `ReactNode` | | Ações contextuais no extremo oposto do cabeçalho. |
|
|
206
|
-
| `layout` | `'flow' \| 'fill'` | `'flow'` | Ocupação de altura, não anatomia: `fill` limita a página ao shell para que uma região interna role
|
|
308
|
+
| `layout` | `'flow' \| 'fill'` | `'flow'` | Ocupação de altura, não anatomia: `fill` limita a página ao shell para que uma região interna role e leva essa altura até uma `ActionList` composta em `PageBody`. |
|
|
207
309
|
| `className` | `string` | `max-w-7xl` | Classes do container para substituir o teto padrão de `80rem`. |
|
|
208
310
|
| `children` | `ReactNode` | | O body da página — espaçamento e diagramação são seus. |
|
|
311
|
+
| demais | Atributos de `HTMLElement` | | Atributos nativos repassados ao elemento `main`, como `id` ou `aria-label`. `className` vai para o container interno. |
|
|
209
312
|
|
|
210
313
|
## Propriedades de PageShell
|
|
211
314
|
|
|
@@ -242,7 +345,7 @@ que o shell projeta na barra, e ignora `className` e os demais atributos.
|
|
|
242
345
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
243
346
|
| ------------ | -------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------ |
|
|
244
347
|
| `href` | `string` | obrigatório | Destino explícito da página pai. Sem ele o retorno não é tabulável nem tem nome acessível. |
|
|
245
|
-
| `children` | `ReactNode` | obrigatório | Nome do destino pai usado no rótulo acessível e
|
|
348
|
+
| `children` | `ReactNode` | obrigatório | Nome do destino pai usado no rótulo acessível e na dica nativa (`title`). |
|
|
246
349
|
| `aria-label` | `string` | `Voltar para {children}` | Nome acessível; informe-o quando `children` não for texto simples. |
|
|
247
350
|
| `onClick` | `MouseEventHandler<HTMLAnchorElement>` | | Integração opcional com o roteador do consumidor, junto do `href`, nunca no lugar dele. |
|
|
248
351
|
| `className` | `string` | | Classes adicionais do link renderizado como botão `ghost`. |
|
|
@@ -259,7 +362,7 @@ que o shell projeta na barra, e ignora `className` e os demais atributos.
|
|
|
259
362
|
|
|
260
363
|
| Propriedade | Tipo | Descrição |
|
|
261
364
|
| ----------- | --------------------------------- | ----------------------------------------------- |
|
|
262
|
-
| `children` | `ReactNode` | Título principal `h1
|
|
365
|
+
| `children` | `ReactNode` | Título principal `h1`, com a mesma escala em `PageHeader` e `PageIntro`. |
|
|
263
366
|
| `className` | `string` | Classes adicionais do título. |
|
|
264
367
|
| demais | Atributos de `HTMLHeadingElement` | Atributos nativos repassados ao heading. |
|
|
265
368
|
|
|
@@ -287,6 +390,9 @@ que o shell projeta na barra, e ignora `className` e os demais atributos.
|
|
|
287
390
|
| `className` | `string` | Classes adicionais da região principal. |
|
|
288
391
|
| demais | Atributos de `HTMLDivElement` | Atributos nativos repassados ao container. |
|
|
289
392
|
|
|
393
|
+
Em uma `Page` com `layout="fill"`, o `PageBody` vira coluna flexível sozinho quando contém uma `ActionList` que
|
|
394
|
+
ocupa a altura.
|
|
395
|
+
|
|
290
396
|
## Propriedades de PageActionsTarget
|
|
291
397
|
|
|
292
398
|
| Propriedade | Tipo | Descrição |
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
## Navegação entre páginas
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Pagination` quando uma coleção for dividida em páginas e a pessoa precisar saltar entre elas.
|
|
4
|
+
Em uma listagem derivada de uma action, [`ActionList`](/ui/action-list) já monta esta paginação no
|
|
5
|
+
rodapé; componha-a diretamente apenas em coleções próprias.
|
|
6
|
+
|
|
7
|
+
Monte `Pagination`, `PaginationContent` e um `PaginationItem` para cada link. `page` fornece o
|
|
4
8
|
número e o nome acessível; `isActive` identifica a página atual. Os controles mantêm altura fixa e
|
|
5
|
-
a largura cresce quando o número precisa de mais espaço.
|
|
6
|
-
rodapé.
|
|
9
|
+
a largura cresce quando o número precisa de mais espaço.
|
|
7
10
|
|
|
8
11
|
```tsx preview
|
|
9
12
|
<Pagination>
|
|
@@ -30,8 +33,9 @@ rodapé.
|
|
|
30
33
|
## Números longos
|
|
31
34
|
|
|
32
35
|
A largura mínima é quadrada e cresce conforme o conteúdo. Na escala densa de um rodapé, as setas e a
|
|
33
|
-
elipse usam `size="icon-sm"
|
|
34
|
-
números
|
|
36
|
+
elipse usam `size="icon-sm"`, o quadrado de `1.75rem` da escala única, com ícone de `0.875rem`. Os
|
|
37
|
+
números não têm um degrau textual de `1.75rem` na escala e, por isso, recebem a mesma medida por
|
|
38
|
+
`className`, como no exemplo.
|
|
35
39
|
|
|
36
40
|
```tsx preview
|
|
37
41
|
<Pagination>
|
|
@@ -148,3 +152,7 @@ render(
|
|
|
148
152
|
|---|---|---|---|
|
|
149
153
|
| `size` | `'icon-xs' \| 'icon-sm' \| 'icon' \| 'icon-lg'` | `'icon'` | Quadrado da escala única; use o mesmo tamanho das setas ao lado. |
|
|
150
154
|
| `className` | `string` | | Classes adicionais aplicadas à elipse. |
|
|
155
|
+
|
|
156
|
+
`Pagination` renderiza um `<nav>` com o nome acessível “Paginação”, `PaginationContent` um `<ul>` e
|
|
157
|
+
`PaginationItem` um `<li>`. Os três não têm propriedades próprias e aceitam as props nativas do
|
|
158
|
+
respectivo elemento, incluindo `className`.
|
|
@@ -62,11 +62,55 @@ render(
|
|
|
62
62
|
|
|
63
63
|
O cabeçalho reconhece quatro slots — `PaneMedia`, `PaneTitle`, `PaneDescription` e `PaneActions` —
|
|
64
64
|
e monta a linha sozinho: mídia, título e descrição de um lado, ações no extremo oposto. A ordem em
|
|
65
|
-
que os slots são escritos não altera a posição
|
|
66
|
-
renderização com um erro
|
|
65
|
+
que os slots são escritos não altera a posição. Cada slot aparece no máximo uma vez: repetir um
|
|
66
|
+
deles interrompe a renderização com um erro que lista os slots aceitos.
|
|
67
67
|
|
|
68
68
|
Título e descrição truncam quando a coluna encolhe, em vez de quebrar a altura da faixa.
|
|
69
69
|
|
|
70
|
+
Nas ações do cabeçalho, use `Button` `ghost` no tamanho `icon-sm` (1.75rem), como nos exemplos. O
|
|
71
|
+
pane é uma superfície densa, com título e descrição em escala menor, e o quadrado menor acompanha
|
|
72
|
+
essa escala. [`Dialog`](/ui/dialog) e [`Drawer`](/ui/drawer) usam `icon` (2.25rem) no voltar e nas
|
|
73
|
+
ações do cabeçalho, e a [`Presentation`](/ui/presentation) usa o mesmo tamanho no voltar e no botão
|
|
74
|
+
que abre o assistente.
|
|
75
|
+
|
|
76
|
+
## Busca ou marca no cabeçalho
|
|
77
|
+
|
|
78
|
+
Uma coluna às vezes precisa, no topo, de algo que não é título nem ação: uma busca que filtra a
|
|
79
|
+
lista, a marca de uma barra lateral. Escreva esse conteúdo direto dentro do `PaneHeader`, ao lado
|
|
80
|
+
dos slots. Só o `Pane` aceita conteúdo livre no cabeçalho; os headers de `Card`, `Dialog` e `Drawer`
|
|
81
|
+
aceitam apenas os próprios slots.
|
|
82
|
+
|
|
83
|
+
```tsx preview
|
|
84
|
+
render(
|
|
85
|
+
<div className="h-56 overflow-hidden rounded-lg border border-border">
|
|
86
|
+
<Split>
|
|
87
|
+
<Pane initialSize="18rem">
|
|
88
|
+
<PaneHeader>
|
|
89
|
+
<Input icon={<Search />} placeholder="Buscar conversa" aria-label="Buscar conversa" />
|
|
90
|
+
<PaneActions>
|
|
91
|
+
<Button variant="ghost" size="icon-sm" aria-label="Nova conversa">
|
|
92
|
+
<SquarePen />
|
|
93
|
+
</Button>
|
|
94
|
+
</PaneActions>
|
|
95
|
+
</PaneHeader>
|
|
96
|
+
<PaneBody className="space-y-1">
|
|
97
|
+
<p className="text-sm">Revisão do contrato</p>
|
|
98
|
+
<p className="text-sm text-muted-foreground">Importação de clientes</p>
|
|
99
|
+
</PaneBody>
|
|
100
|
+
</Pane>
|
|
101
|
+
<Pane grow>
|
|
102
|
+
<p className="text-sm text-muted-foreground">Conversa selecionada.</p>
|
|
103
|
+
</Pane>
|
|
104
|
+
</Split>
|
|
105
|
+
</div>,
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
O conteúdo livre ocupa o lugar do título e absorve a largura disponível, por isso as ações
|
|
110
|
+
continuam no extremo oposto. Quando há título, o conteúdo livre vem sempre depois do título e da descrição,
|
|
111
|
+
qualquer que seja a ordem no JSX: uma busca escrita junto de um `PaneTitle` aparece abaixo dele, não
|
|
112
|
+
ao lado. Para algo antes do título, use `PaneMedia`; para algo ao lado, use `PaneActions`.
|
|
113
|
+
|
|
70
114
|
## Escolher entre seccionado e contínuo
|
|
71
115
|
|
|
72
116
|
`layout` declara a anatomia da superfície inteira e fica no root; os slots leem esse valor e não o
|
|
@@ -86,6 +130,11 @@ Os divisores são derivados da vizinhança: cada região desenha a linha quando
|
|
|
86
130
|
lado. Um cabeçalho sem corpo não fecha nada, e um cabeçalho seguido direto de um rodapé produz uma
|
|
87
131
|
linha só. A tela não escreve `border-b` nem `border-t`.
|
|
88
132
|
|
|
133
|
+
No `continuous`, um cabeçalho sem corpo nem rodapé fecha o pane com o mesmo recuo que tem em cima.
|
|
134
|
+
Uma classe `pb-*` no `PaneHeader` não altera esse recuo: a regra só vale quando o cabeçalho é a
|
|
135
|
+
última região e tem precedência sobre o `className`. No `sectioned`, a faixa tem altura fixa e
|
|
136
|
+
centraliza a linha, então não há recuo de baixo a ajustar.
|
|
137
|
+
|
|
89
138
|
## Recuo do pane e recuo das regiões
|
|
90
139
|
|
|
91
140
|
`inset` é o respiro interno do pane sem slots: `md` por padrão, com `none`, `sm` e `lg`
|
|
@@ -99,11 +148,12 @@ O ajuste enxerga só o primeiro nível. Se os slots vierem dentro de outro compo
|
|
|
99
148
|
|
|
100
149
|
## A matriz de layouts e slots
|
|
101
150
|
|
|
102
|
-
As regiões são independentes
|
|
151
|
+
As regiões são independentes: a coluna usa só as que precisa, nos dois layouts, e os divisores
|
|
152
|
+
acompanham as regiões presentes.
|
|
103
153
|
|
|
104
154
|
```tsx preview col
|
|
105
155
|
render(
|
|
106
|
-
<div className="grid
|
|
156
|
+
<div className="grid grid-cols-2 gap-4">
|
|
107
157
|
<div className="h-56 overflow-hidden rounded-lg border border-border">
|
|
108
158
|
<Pane className="h-full">
|
|
109
159
|
<PaneHeader>
|
|
@@ -198,7 +248,7 @@ documento não muda a aparência da faixa.
|
|
|
198
248
|
|
|
199
249
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
200
250
|
|---|---|---|---|
|
|
201
|
-
| `children` | `ReactNode` | |
|
|
251
|
+
| `children` | `ReactNode` | | `PaneMedia`, `PaneTitle`, `PaneDescription` e `PaneActions`, no máximo um de cada, e conteúdo livre, que aparece depois do título e da descrição. |
|
|
202
252
|
| `className` | `string` | | Ajusta a faixa fixa sobre o recuo do layout. |
|
|
203
253
|
|
|
204
254
|
## Propriedades de PaneMedia
|