@softize/opus 18.5.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 +275 -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 +298 -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 +16 -12
- package/src/ui/components/patterns/fill-region.ts +150 -0
- package/src/ui/components/patterns/heading-level.ts +16 -0
- package/src/ui/components/patterns/list.tsx +103 -73
- package/src/ui/components/patterns/page.tsx +20 -4
- package/src/ui/components/patterns/pane.tsx +294 -0
- package/src/ui/components/patterns/presentation.tsx +81 -54
- package/src/ui/components/patterns/sidebar.tsx +13 -72
- package/src/ui/components/patterns/split.tsx +51 -38
- package/src/ui/components/patterns/surface-anatomy.ts +246 -0
- package/src/ui/components/patterns/surface-header.tsx +51 -6
- package/src/ui/components/patterns/surface-media.tsx +69 -0
- 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/card.tsx +91 -29
- 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 +14 -5
- package/src/ui/components/primitives/copyable.tsx +120 -10
- package/src/ui/components/primitives/detail.tsx +10 -13
- package/src/ui/components/primitives/dialog.tsx +179 -45
- package/src/ui/components/primitives/drawer.tsx +131 -24
- 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/metric-card.tsx +98 -39
- 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 +252 -35
- 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 +37 -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 +219 -28
- 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 +193 -22
- 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 +68 -21
- package/src/ui/docs/content/observability.md +10 -9
- package/src/ui/docs/content/page.md +125 -11
- package/src/ui/docs/content/pagination.md +13 -5
- package/src/ui/docs/content/pane.md +300 -0
- 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 +25 -45
- package/src/ui/docs/content/skeleton.md +13 -4
- 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 +34 -20
- 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 +14 -2
- package/src/ui/drivers/react.tsx +16 -8
- package/src/ui/meta.ts +38 -32
- package/src/ui/react.tsx +14 -0
- package/src/vite/design.ts +16 -4
|
@@ -4,45 +4,71 @@ title: MCP
|
|
|
4
4
|
|
|
5
5
|
# MCP
|
|
6
6
|
|
|
7
|
-
Use o servidor MCP para disponibilizar actions
|
|
8
|
-
aplicação. A chamada
|
|
9
|
-
auditoria; o MCP fornece apenas o transporte.
|
|
7
|
+
Use o servidor MCP do runtime para disponibilizar actions do app a agentes que executam fora da
|
|
8
|
+
aplicação, como o Claude Desktop ou o agente de um parceiro. A chamada passa por `runtime.execute`,
|
|
9
|
+
com a mesma validação, autorização e auditoria de qualquer outra; o MCP fornece apenas o transporte.
|
|
10
|
+
|
|
11
|
+
Este servidor é diferente de `opus mcp`, que atende o agente que trabalha no código do projeto
|
|
12
|
+
durante o desenvolvimento e não executa actions. Veja [CLI opus](/docs/cli).
|
|
10
13
|
|
|
11
14
|
## Montar
|
|
12
15
|
|
|
16
|
+
`createOpusMcpServer` recebe o runtime e devolve um servidor MCP; o app escolhe o transporte e o
|
|
17
|
+
conecta. `resolveContext` recebe os dados da requisição MCP e devolve o contexto do runtime, com
|
|
18
|
+
usuário, tenant e `can`. No transporte HTTP do SDK MCP, os headers da requisição chegam em
|
|
19
|
+
`requestInfo`, e o adapter de autenticação do app pode lê-los:
|
|
20
|
+
|
|
13
21
|
```ts
|
|
14
22
|
import { createOpusMcpServer } from '@softize/opus/mcp'
|
|
15
|
-
import {
|
|
23
|
+
import { jwtAuth } from '@softize/opus/auth/jwt'
|
|
24
|
+
|
|
25
|
+
const auth = jwtAuth({
|
|
26
|
+
secret: process.env.JWT_SECRET!,
|
|
27
|
+
mapUser: (payload) => ({ id: String(payload.sub) }),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
type McpRequestExtra = {
|
|
31
|
+
requestInfo?: { headers: Record<string, string | string[] | undefined> }
|
|
32
|
+
}
|
|
16
33
|
|
|
17
34
|
const server = createOpusMcpServer(runtime, {
|
|
18
35
|
name: 'meu-app',
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
36
|
+
resolveContext: async (extra) => {
|
|
37
|
+
const request = (extra as McpRequestExtra).requestInfo ?? { headers: {} }
|
|
38
|
+
const { user, tenantId, can } = await auth.resolveContext(request)
|
|
39
|
+
return { user, tenantId: tenantId ?? null, can }
|
|
40
|
+
},
|
|
22
41
|
})
|
|
23
42
|
|
|
24
|
-
await server.connect(
|
|
43
|
+
await server.connect(transport) // StreamableHTTPServerTransport, por exemplo
|
|
25
44
|
```
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
46
|
+
Sem `resolveContext`, a chamada é anônima: não há usuário, `can` nega tudo e só actions `public`
|
|
47
|
+
executam. Com ele, o agente age como o usuário identificado. No transporte stdio não há headers;
|
|
48
|
+
a identidade precisa vir do próprio processo, como um token de serviço lido do ambiente.
|
|
49
|
+
|
|
50
|
+
## O que fica disponível
|
|
51
|
+
|
|
52
|
+
Só actions expostas à IA ficam disponíveis, tanto para listar quanto para executar: as que declaram
|
|
53
|
+
`ai: true` ou um objeto `ai` sem `enabled: false`. `ListTools` devolve cada uma com `name` (o
|
|
54
|
+
identificador técnico), `title` (a `label` legível, quando existe), descrição e JSON Schema da
|
|
55
|
+
entrada. Em `_meta`, cada tool traz os
|
|
56
|
+
[Produtos de Dados](/docs/data-products) relacionados: `com.softize.opus/data-products` lista os
|
|
57
|
+
identificadores e `com.softize.opus/data-product-labels`, o nome legível de cada um.
|
|
58
|
+
|
|
59
|
+
`CallTool` recusa com erro qualquer nome fora dessa lista; os demais seguem por `runtime.execute`.
|
|
60
|
+
A exposição declarada em `ai` decide o que o cliente MCP pode executar, e a autorização do contexto
|
|
61
|
+
continua valendo sobre ela. Para um acesso somente de leitura, exponha apenas actions de leitura.
|
|
36
62
|
|
|
37
63
|
## Escolher entre integração interna e MCP
|
|
38
64
|
|
|
39
65
|
- **Agente dentro da aplicação:** use `runtime.aiFor(base).run()` para chamar as actions no mesmo
|
|
40
|
-
processo.
|
|
41
|
-
- **Agente em outro serviço:** use MCP para oferecer a mesma coleção de ferramentas por
|
|
42
|
-
interface interoperável.
|
|
66
|
+
processo. Veja [IA generativa](/docs/ai).
|
|
67
|
+
- **Agente em outro serviço:** use o servidor MCP para oferecer a mesma coleção de ferramentas por
|
|
68
|
+
uma interface interoperável.
|
|
43
69
|
|
|
44
70
|
## Limites atuais
|
|
45
71
|
|
|
46
|
-
O
|
|
47
|
-
|
|
48
|
-
leitura.
|
|
72
|
+
O servidor MCP não pede confirmação: uma action com `ai.destructive` ou `ai.requiresConfirmation`
|
|
73
|
+
executa como qualquer outra ferramenta anunciada. Como a mesma exposição em `ai` alimenta o agente
|
|
74
|
+
do app e o MCP, ao montar o servidor MCP exponha à IA somente operações de leitura.
|
|
@@ -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
|
|
@@ -45,7 +45,9 @@ apresente dois cards independentes.
|
|
|
45
45
|
labelAction={
|
|
46
46
|
<Tooltip>
|
|
47
47
|
<TooltipTrigger asChild>
|
|
48
|
-
<Button size="icon-xs" variant="ghost" aria-label="Sobre Agendados"
|
|
48
|
+
<Button size="icon-xs" variant="ghost" aria-label="Sobre Agendados">
|
|
49
|
+
<Info />
|
|
50
|
+
</Button>
|
|
49
51
|
</TooltipTrigger>
|
|
50
52
|
<TooltipContent>Eventos atualmente agendados.</TooltipContent>
|
|
51
53
|
</Tooltip>
|
|
@@ -56,7 +58,9 @@ apresente dois cards independentes.
|
|
|
56
58
|
labelAction: (
|
|
57
59
|
<Tooltip>
|
|
58
60
|
<TooltipTrigger asChild>
|
|
59
|
-
<Button size="icon-xs" variant="ghost" aria-label="Sobre o período"
|
|
61
|
+
<Button size="icon-xs" variant="ghost" aria-label="Sobre o período">
|
|
62
|
+
<Info />
|
|
63
|
+
</Button>
|
|
60
64
|
</TooltipTrigger>
|
|
61
65
|
<TooltipContent>Agendamentos registrados dentro do período.</TooltipContent>
|
|
62
66
|
</Tooltip>
|
|
@@ -65,6 +69,43 @@ apresente dois cards independentes.
|
|
|
65
69
|
/>
|
|
66
70
|
```
|
|
67
71
|
|
|
72
|
+
## Como filtro ou seleção
|
|
73
|
+
|
|
74
|
+
Use a ativação controlada quando escolher uma métrica também precisar aplicar um recorte. O card
|
|
75
|
+
expõe o estado por `aria-pressed` e preserva controles complementares, como o tooltip do rótulo,
|
|
76
|
+
sem disparar a ativação.
|
|
77
|
+
|
|
78
|
+
```tsx preview col
|
|
79
|
+
const [metric, setMetric] = useState('scheduled')
|
|
80
|
+
|
|
81
|
+
render(
|
|
82
|
+
<div className="grid grid-cols-2 gap-3">
|
|
83
|
+
<MetricCard
|
|
84
|
+
label="Agendados"
|
|
85
|
+
value="18"
|
|
86
|
+
active={metric === 'scheduled'}
|
|
87
|
+
activationLabel="Filtrar por Agendados"
|
|
88
|
+
onActivate={() => setMetric('scheduled')}
|
|
89
|
+
/>
|
|
90
|
+
<MetricCard
|
|
91
|
+
label="Efetivados"
|
|
92
|
+
value="11"
|
|
93
|
+
active={metric === 'completed'}
|
|
94
|
+
activationLabel="Filtrar por Efetivados"
|
|
95
|
+
onActivate={() => setMetric('completed')}
|
|
96
|
+
/>
|
|
97
|
+
</div>,
|
|
98
|
+
)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`active`, `activationLabel` e `onActivate` formam uma capacidade única: informe as três propriedades
|
|
102
|
+
para tornar o card ativável. O consumidor continua responsável pelo estado e pelo recorte aplicado.
|
|
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
|
+
|
|
68
109
|
## Carregamento
|
|
69
110
|
|
|
70
111
|
`loading` preserva a geometria do card com placeholders e marca a superfície como ocupada para
|
|
@@ -76,22 +117,28 @@ tecnologias assistivas. O contêiner da coleção continua responsável pela men
|
|
|
76
117
|
|
|
77
118
|
## Propriedades de MetricCard
|
|
78
119
|
|
|
79
|
-
| Propriedade
|
|
80
|
-
|
|
81
|
-
| `label`
|
|
82
|
-
| `value`
|
|
83
|
-
| `loading`
|
|
84
|
-
| `labelAction`
|
|
85
|
-
| `description`
|
|
86
|
-
| `secondaryMetric` | `MetricCardSecondaryMetric`
|
|
87
|
-
| `icon`
|
|
88
|
-
| `context`
|
|
89
|
-
| `action`
|
|
120
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
121
|
+
| ----------------- | ----------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| `label` | `ReactNode` | | O nome da medida. |
|
|
123
|
+
| `value` | `ReactNode` | | O valor já formatado pelo consumidor. |
|
|
124
|
+
| `loading` | `boolean` | `false` | Substitui rótulo e valor por skeletons e marca `aria-busy`. |
|
|
125
|
+
| `labelAction` | `ReactNode` | | Controle ao lado do rótulo, como uma explicação em tooltip. |
|
|
126
|
+
| `description` | `ReactNode` | | Contexto que explica recorte, proporção ou significado do valor. |
|
|
127
|
+
| `secondaryMetric` | `MetricCardSecondaryMetric` | | Medida complementar exibida como uma lâmina posterior sob o card principal. |
|
|
128
|
+
| `icon` | `ReactNode` | | Ícone decorativo que identifica a natureza da medida. |
|
|
129
|
+
| `context` | `'neutral' \| 'info' \| 'success' \| 'warning' \| 'danger'` | `'neutral'` | Contexto semântico do ícone; não altera a superfície do card. |
|
|
130
|
+
| `action` | `ReactNode` | | Ação relacionada diretamente à medida. |
|
|
131
|
+
| `active` | `boolean` | | Indica se a medida controla o recorte atualmente aplicado. Exige `activationLabel` e `onActivate`. |
|
|
132
|
+
| `activationLabel` | `string` | | Nome acessível da ativação. Exige `active` e `onActivate`. |
|
|
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`.
|
|
90
137
|
|
|
91
138
|
## Propriedades de MetricCardSecondaryMetric
|
|
92
139
|
|
|
93
|
-
| Propriedade
|
|
94
|
-
|
|
95
|
-
| `label`
|
|
96
|
-
| `value`
|
|
97
|
-
| `labelAction` | `ReactNode` |
|
|
140
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
141
|
+
| ------------- | ----------- | ------ | ------------------------------------------------------------------- |
|
|
142
|
+
| `label` | `ReactNode` | | O nome da medida complementar. |
|
|
143
|
+
| `value` | `ReactNode` | | O valor complementar já formatado pelo consumidor. |
|
|
144
|
+
| `labelAction` | `ReactNode` | | Controle próprio ao lado do rótulo, como uma explicação em tooltip. |
|
|
@@ -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,15 @@ 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
|
-
|
|
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.
|
|
18
|
+
|
|
19
|
+
A `Page` é contínua por definição: separar o chrome do conteúdo é trabalho do shell, e não há
|
|
20
|
+
divisores entre regiões para declarar. O `layout` da `Page` não é a anatomia de superfície de
|
|
21
|
+
[`Card`](/ui/card), [`Dialog`](/ui/dialog), [`Drawer`](/ui/drawer) e [`Pane`](/ui/pane) — aqui ele
|
|
22
|
+
decide a ocupação de altura. `flow`, o padrão, deixa a página crescer e a rolagem acontecer na
|
|
23
|
+
janela; `fill` limita a página à altura do shell para que uma região interna, como uma tabela longa
|
|
24
|
+
ou um split, assuma a rolagem.
|
|
19
25
|
|
|
20
26
|
`PageShell` não inclui sidebar nem inventa breadcrumb. Ele ocupa o painel principal já delimitado e
|
|
21
27
|
mantém a barra com `3.75rem`, mesmo quando o conteúdo muda de estado. Tabs ficam reservados a recortes
|
|
@@ -44,7 +50,8 @@ render(
|
|
|
44
50
|
|
|
45
51
|
Use `PageBack` em uma subpágina simples. O destino é explícito para continuar correto após refresh ou
|
|
46
52
|
acesso por link direto; não derive esse retorno do histórico do navegador. No header padrão, o
|
|
47
|
-
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.
|
|
48
55
|
|
|
49
56
|
```tsx preview col
|
|
50
57
|
<Page>
|
|
@@ -57,8 +64,30 @@ controle aparece antes do título como ícone com nome acessível e tooltip deri
|
|
|
57
64
|
```
|
|
58
65
|
|
|
59
66
|
Não combine `PageBack` com breadcrumb. Use o retorno para um único pai conhecido. Quando houver
|
|
60
|
-
mais de um ancestral relevante, envolva o `Breadcrumb` em `PageNavigation`; ele
|
|
61
|
-
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
|
+
```
|
|
62
91
|
|
|
63
92
|
## Barra persistente do shell
|
|
64
93
|
|
|
@@ -142,8 +171,87 @@ render(
|
|
|
142
171
|
|
|
143
172
|
Fora de `PageShell`, use `PageIntro` quando o conteúdo precisar de uma introdução separada do
|
|
144
173
|
chrome. Dentro do shell, ele pode ser combinado com `PageHeader`: o primeiro permanece no conteúdo
|
|
145
|
-
e o segundo alimenta a barra. Em uma página de listagem, `Content` pode fornecer o
|
|
146
|
-
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
|
+
```
|
|
147
255
|
|
|
148
256
|
## Estados integrais
|
|
149
257
|
|
|
@@ -188,7 +296,8 @@ e, sem `title`, valem `errorMessage` e `emptyMessage`.
|
|
|
188
296
|
```
|
|
189
297
|
|
|
190
298
|
Não use `PageState` para uma falha parcial. Se outra parte da página continua utilizável, mantenha o
|
|
191
|
-
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).
|
|
192
301
|
|
|
193
302
|
## Propriedades de Page
|
|
194
303
|
|
|
@@ -196,8 +305,10 @@ estado na própria seção com `DataState`, `ActionView`, `ActionList` ou `Alert
|
|
|
196
305
|
| ----------- | ----------- | ----------- | ----------------------------------------------------------------------------------------------- |
|
|
197
306
|
| `title` | `ReactNode` | | O h1 da página. |
|
|
198
307
|
| `actions` | `ReactNode` | | Ações contextuais no extremo oposto do cabeçalho. |
|
|
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`. |
|
|
199
309
|
| `className` | `string` | `max-w-7xl` | Classes do container para substituir o teto padrão de `80rem`. |
|
|
200
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. |
|
|
201
312
|
|
|
202
313
|
## Propriedades de PageShell
|
|
203
314
|
|
|
@@ -234,7 +345,7 @@ que o shell projeta na barra, e ignora `className` e os demais atributos.
|
|
|
234
345
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
235
346
|
| ------------ | -------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------ |
|
|
236
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. |
|
|
237
|
-
| `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`). |
|
|
238
349
|
| `aria-label` | `string` | `Voltar para {children}` | Nome acessível; informe-o quando `children` não for texto simples. |
|
|
239
350
|
| `onClick` | `MouseEventHandler<HTMLAnchorElement>` | | Integração opcional com o roteador do consumidor, junto do `href`, nunca no lugar dele. |
|
|
240
351
|
| `className` | `string` | | Classes adicionais do link renderizado como botão `ghost`. |
|
|
@@ -251,7 +362,7 @@ que o shell projeta na barra, e ignora `className` e os demais atributos.
|
|
|
251
362
|
|
|
252
363
|
| Propriedade | Tipo | Descrição |
|
|
253
364
|
| ----------- | --------------------------------- | ----------------------------------------------- |
|
|
254
|
-
| `children` | `ReactNode` | Título principal `h1
|
|
365
|
+
| `children` | `ReactNode` | Título principal `h1`, com a mesma escala em `PageHeader` e `PageIntro`. |
|
|
255
366
|
| `className` | `string` | Classes adicionais do título. |
|
|
256
367
|
| demais | Atributos de `HTMLHeadingElement` | Atributos nativos repassados ao heading. |
|
|
257
368
|
|
|
@@ -279,6 +390,9 @@ que o shell projeta na barra, e ignora `className` e os demais atributos.
|
|
|
279
390
|
| `className` | `string` | Classes adicionais da região principal. |
|
|
280
391
|
| demais | Atributos de `HTMLDivElement` | Atributos nativos repassados ao container. |
|
|
281
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
|
+
|
|
282
396
|
## Propriedades de PageActionsTarget
|
|
283
397
|
|
|
284
398
|
| Propriedade | Tipo | Descrição |
|