@softize/opus 13.1.0 → 14.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 +34 -0
- package/bin/lib/copy.mjs +276 -6
- package/docs/code-style.md +4 -1
- package/package.json +1 -1
- package/registry/instructions/opus.md +3 -3
- package/registry/templates/app/src/App.tsx +11 -6
- package/src/core/types.ts +3 -4
- package/src/ui/components/patterns/action-list-dialog.tsx +10 -3
- package/src/ui/components/patterns/confirm.tsx +2 -31
- package/src/ui/components/patterns/content-header.tsx +42 -141
- package/src/ui/components/patterns/data-state.tsx +42 -68
- package/src/ui/components/patterns/form.tsx +15 -15
- package/src/ui/components/patterns/list.tsx +14 -8
- package/src/ui/components/patterns/page-state.tsx +39 -51
- package/src/ui/components/patterns/page.tsx +18 -53
- package/src/ui/components/patterns/state-surface.tsx +148 -0
- package/src/ui/components/patterns/surface-header.tsx +119 -0
- package/src/ui/components/patterns/trigger.tsx +7 -9
- package/src/ui/components/patterns/view.tsx +14 -16
- package/src/ui/components/primitives/alert.tsx +1 -33
- package/src/ui/components/primitives/avatar.tsx +15 -5
- package/src/ui/components/primitives/badge.tsx +2 -43
- package/src/ui/components/primitives/button.tsx +31 -35
- package/src/ui/components/primitives/control.ts +60 -0
- package/src/ui/components/primitives/dot.tsx +1 -30
- package/src/ui/components/primitives/input-group.tsx +11 -8
- package/src/ui/components/primitives/item.tsx +3 -1
- package/src/ui/components/primitives/menu.tsx +1 -7
- package/src/ui/components/primitives/pagination.tsx +16 -8
- package/src/ui/components/primitives/select.tsx +2 -2
- package/src/ui/components/primitives/spinner.tsx +13 -16
- package/src/ui/components/primitives/switch.tsx +4 -1
- package/src/ui/components/primitives/tabs.tsx +5 -3
- package/src/ui/components/primitives/toggle.tsx +9 -4
- package/src/ui/docs/content/action-form.md +26 -0
- package/src/ui/docs/content/action-list-dialog.md +2 -2
- package/src/ui/docs/content/action-list.md +3 -1
- package/src/ui/docs/content/action-trigger.md +4 -4
- package/src/ui/docs/content/action-view.md +3 -2
- package/src/ui/docs/content/avatar.md +7 -3
- package/src/ui/docs/content/button.md +30 -14
- package/src/ui/docs/content/communication.md +36 -0
- package/src/ui/docs/content/content.md +5 -4
- package/src/ui/docs/content/data-state.md +17 -13
- package/src/ui/docs/content/dialog.md +1 -4
- package/src/ui/docs/content/input.md +1 -1
- package/src/ui/docs/content/item.md +1 -1
- package/src/ui/docs/content/page.md +12 -4
- package/src/ui/docs/content/pagination.md +11 -9
- package/src/ui/docs/content/semantic-context.md +3 -2
- package/src/ui/docs/content/sidebar.md +2 -42
- package/src/ui/docs/content/spinner.md +9 -6
- package/src/ui/docs/content/switch.md +1 -1
- package/src/ui/docs/content/tabs.md +1 -1
- package/src/ui/docs/content/toggle.md +1 -1
- package/src/ui/drivers/react.tsx +1 -6
- package/src/ui/meta.ts +5 -5
- package/src/ui/react.tsx +8 -16
- package/src/ui/components/patterns/shell-nav.tsx +0 -154
|
@@ -3,11 +3,13 @@ import { cva, type VariantProps } from "class-variance-authority"
|
|
|
3
3
|
import { Tabs as TabsPrimitive } from "radix-ui"
|
|
4
4
|
|
|
5
5
|
import { cn } from '../../lib/cn.ts'
|
|
6
|
+
import { controlHeight, type ControlSize } from './control.ts'
|
|
6
7
|
|
|
7
8
|
// Divergência da casa (ejetado): o Tabs ganhou `size` — Button e Select têm `sm`, o Tabs
|
|
8
9
|
// não tinha, e uma fileira densa ficava com o segmento 0.25rem mais alto
|
|
9
|
-
// que os irmãos. O tamanho flui pra TabsList via contexto (a altura é dela)
|
|
10
|
-
|
|
10
|
+
// que os irmãos. O tamanho flui pra TabsList via contexto (a altura é dela) e a medida é a
|
|
11
|
+
// da escala de control.ts.
|
|
12
|
+
type TabsSize = Extract<ControlSize, "default" | "sm">
|
|
11
13
|
const TabsSizeContext = React.createContext<TabsSize>("default")
|
|
12
14
|
|
|
13
15
|
function Tabs({
|
|
@@ -64,7 +66,7 @@ function TabsList({
|
|
|
64
66
|
data-slot="tabs-list"
|
|
65
67
|
data-variant={variant}
|
|
66
68
|
data-size={size}
|
|
67
|
-
className={cn(tabsListVariants({ variant }), size
|
|
69
|
+
className={cn(tabsListVariants({ variant }), controlHeight[size], className)}
|
|
68
70
|
{...props}
|
|
69
71
|
/>
|
|
70
72
|
)
|
|
@@ -3,9 +3,13 @@ import { cva, type VariantProps } from "class-variance-authority"
|
|
|
3
3
|
import { Toggle as TogglePrimitive } from "radix-ui"
|
|
4
4
|
|
|
5
5
|
import { cn } from '../../lib/cn.ts'
|
|
6
|
+
import { controlHeight, focusRing } from './control.ts'
|
|
6
7
|
|
|
7
8
|
const toggleVariants = cva(
|
|
8
|
-
|
|
9
|
+
[
|
|
10
|
+
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-context-danger aria-invalid:ring-context-danger/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground dark:aria-invalid:ring-context-danger/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
11
|
+
focusRing,
|
|
12
|
+
],
|
|
9
13
|
{
|
|
10
14
|
variants: {
|
|
11
15
|
variant: {
|
|
@@ -13,10 +17,11 @@ const toggleVariants = cva(
|
|
|
13
17
|
outline:
|
|
14
18
|
"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
|
|
15
19
|
},
|
|
20
|
+
// Alturas da escala de control.ts (`sm` = o mesmo h-8 de Button e Select).
|
|
16
21
|
size: {
|
|
17
|
-
default:
|
|
18
|
-
sm:
|
|
19
|
-
lg:
|
|
22
|
+
default: `${controlHeight.default} min-w-9 px-2`,
|
|
23
|
+
sm: `${controlHeight.sm} min-w-8 px-1.5`,
|
|
24
|
+
lg: `${controlHeight.lg} min-w-10 px-2.5`,
|
|
20
25
|
},
|
|
21
26
|
shape: {
|
|
22
27
|
default: '',
|
|
@@ -88,6 +88,32 @@ ciclo de vida que o pattern não cobre; validação e execução continuam iguai
|
|
|
88
88
|
| `options` | `SelectOption[]` | Opções por id de runtime — sobrepõe o fieldOptions do form e o z.enum. |
|
|
89
89
|
| `className` | `string` | Classes do invólucro (ex.: `col-span-2` em uma grid). |
|
|
90
90
|
|
|
91
|
+
## Ajuda na label
|
|
92
|
+
|
|
93
|
+
`FieldSpec.help` aparece como um ícone junto à label, com o texto num tooltip. Escreva ali o
|
|
94
|
+
critério, o efeito ou a limitação que a label não diz; ajuda que só repete a label deve ser omitida.
|
|
95
|
+
Não existe texto auxiliar sob o campo: quem precisa de uma frase permanente abaixo do controle usa
|
|
96
|
+
`FieldDescription` na composição própria.
|
|
97
|
+
|
|
98
|
+
`LabelHelp` é esse mesmo ícone, exportado para um formulário sem contrato mostrar a ajuda no mesmo
|
|
99
|
+
lugar:
|
|
100
|
+
|
|
101
|
+
```tsx preview col md
|
|
102
|
+
<Field>
|
|
103
|
+
<FieldLabel htmlFor="staff" className="items-center gap-1.5">
|
|
104
|
+
<span>Staff</span>
|
|
105
|
+
<LabelHelp help="Tem acesso ao back-office e a todos os workspaces." />
|
|
106
|
+
</FieldLabel>
|
|
107
|
+
<Input id="staff" placeholder="Empresa X" />
|
|
108
|
+
</Field>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Propriedades de LabelHelp
|
|
112
|
+
|
|
113
|
+
| Propriedade | Tipo | Descrição |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `help` | `string` | O texto do tooltip. Vazio ou ausente, o ícone não renderiza. |
|
|
116
|
+
|
|
91
117
|
## Origem das opções de seleção
|
|
92
118
|
|
|
93
119
|
As opções seguem esta precedência: `options` no campo, `fieldOptions` no formulário, `options` no
|
|
@@ -23,7 +23,7 @@ render(
|
|
|
23
23
|
<Plus /> Workspace
|
|
24
24
|
</Button>
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
emptyMessage="Nenhum workspace."
|
|
27
27
|
>
|
|
28
28
|
{(workspaces) => (
|
|
29
29
|
<div className="space-y-2">
|
|
@@ -69,5 +69,5 @@ corpo do modal.
|
|
|
69
69
|
| `actions` | `ReactNode` | | Ação à direita da toolbar — em geral o botão de criar. |
|
|
70
70
|
| `empty` | `(items) => boolean` | `items.length === 0` | Sobrepõe o vazio derivado. |
|
|
71
71
|
| `loading` | `boolean` | | Carga extra agregada à do fetch (query irmã). |
|
|
72
|
-
| `
|
|
72
|
+
| `emptyMessage / errorMessage / retryLabel` | `string` | | Textos dos estados, repassados ao `ActionList` (e dele ao `DataState`). |
|
|
73
73
|
| `className` | `string` | `sm:max-w-3xl` | Largura do DialogContent. |
|
|
@@ -267,6 +267,8 @@ chamar a action.
|
|
|
267
267
|
| `rowId` | `(item) => string` | `item.id` | Identidade da linha para seleção. |
|
|
268
268
|
| `pageSize` | `number` | `50` | Itens por página padrão (vira `limit`/`page` no input; handler devolve `total`). O usuário troca no popover de exibição. |
|
|
269
269
|
| `state / onStateChange` | `ActionListState / (next) => void` | interno | Estado da toolbar controlado — para quem embala sincronizar com a URL. |
|
|
270
|
-
| `emptyMessage` | `string` | `'Nenhum resultado.'` |
|
|
270
|
+
| `emptyMessage` | `string` | `'Nenhum resultado.'` | Frase do estado vazio (o `Empty` do `DataState`). |
|
|
271
|
+
| `errorMessage` | `string` | `'Não foi possível carregar.'` | Título do aviso de erro; o botão de tentar de novo refaz a consulta. |
|
|
272
|
+
| `retryLabel` | `string` | `'Tentar de novo'` | Rótulo do botão de recuperação. |
|
|
271
273
|
| `onRowClick` | `(item: TItem) => void` | | Clique na linha (ex.: navegar para o detalhe) — só na tabela. |
|
|
272
274
|
| `rowActions` | `(item: TItem) => ReactNode` | | Ações por linha (coluna final, à direita) — apresentação de quem chama, como `cells`; cliques ali não disparam o `onRowClick`. |
|
|
@@ -37,9 +37,9 @@ confirm: {
|
|
|
37
37
|
|
|
38
38
|
## Ação somente com ícone
|
|
39
39
|
|
|
40
|
-
Com `icon`, o botão exibe somente o ícone
|
|
41
|
-
|
|
42
|
-
mensagem de confirmação.
|
|
40
|
+
Com `icon`, o botão exibe somente o ícone no quadrado `icon-sm` da escala (1.75rem, a ação que mora
|
|
41
|
+
dentro de uma linha ou card) e usa `label`, ou `action.label`, no tooltip e no nome acessível. O clique
|
|
42
|
+
não aciona o item clicável ao redor. `itemLabel` identifica o registro na mensagem de confirmação.
|
|
43
43
|
|
|
44
44
|
```tsx
|
|
45
45
|
<ActionTrigger
|
|
@@ -83,4 +83,4 @@ um atalho, um arrastar, um item de menu.
|
|
|
83
83
|
| `onSuccess` | `(data: TData) => void` | | Pós-sucesso (cache já invalidado pelo action.invalidates). |
|
|
84
84
|
| `icon` | `React.ReactNode` | | Torna o botão icon-only: rótulo no tooltip e no `aria-label`, clique que não vaza para o item. |
|
|
85
85
|
| `itemLabel` | `string` | | Nome do alvo na pergunta (sai entre aspas, em destaque, antes da mensagem do contrato). |
|
|
86
|
-
| `className` | `string` | | Classes do botão (
|
|
86
|
+
| `className` | `string` | | Classes do botão. O tamanho vem de `size` (escala única); com `icon` é sempre `icon-sm`. |
|
|
@@ -21,7 +21,7 @@ render(
|
|
|
21
21
|
<div className="space-y-1.5">
|
|
22
22
|
<div className="flex items-center gap-2">
|
|
23
23
|
<h3 className="text-sm font-semibold">{ws.name}</h3>
|
|
24
|
-
<Badge
|
|
24
|
+
<Badge context={ws.status === 'active' ? 'success' : 'warning'}>{ws.status}</Badge>
|
|
25
25
|
</div>
|
|
26
26
|
<p className="text-sm text-muted-foreground">
|
|
27
27
|
Cliente {ws.client} · {ws.agents} agentes vinculados.
|
|
@@ -50,5 +50,6 @@ mais de uma região da tela ou quando o carregamento precisa ser orquestrado por
|
|
|
50
50
|
| `children` | `(data: TData, refetch) => ReactNode` | | Conteúdo apresentado quando os dados estão disponíveis. `refetch` permite recarregar por código. |
|
|
51
51
|
| `render` | `(data: TData, refetch) => ReactNode` | | Alias de compatibilidade de `children`; `children` tem precedência. |
|
|
52
52
|
| `loading` | `ReactNode \| boolean` | `3 skeletons` | Sobrescreve o carregamento: um nó próprio, `true` para o padrão ou `false` para não renderizar nada enquanto carrega. |
|
|
53
|
-
| `empty` | `ReactNode` | `
|
|
53
|
+
| `empty` | `ReactNode` | `emptyMessage` ou nada | Sobrescreve o estado vazio (200 sem dado). |
|
|
54
|
+
| `emptyMessage` | `string` | | Atalho do vazio: a frase na mesma superfície de `DataState` (`Empty` com moldura sólida). |
|
|
54
55
|
| `error` | `(err, retry) => ReactNode` | `"Não foi possível carregar" + Tentar de novo` | Sobrescreve o estado de erro padrão. Sem ele, a frase do servidor só aparece quando é legível pela pessoa (`conflict`, `validation`, `not_found`, `authorization`, `authentication`); código técnico nunca vira título, e o botão de tentar de novo some quando o problema é de permissão ou sessão. |
|
|
@@ -28,10 +28,14 @@ para agente.
|
|
|
28
28
|
|
|
29
29
|
## Tamanhos
|
|
30
30
|
|
|
31
|
-
size
|
|
32
|
-
|
|
31
|
+
`size` usa a escala única dos controles: o avatar de uma linha mede o mesmo que o controle ao lado
|
|
32
|
+
(`sm` 2rem, `default` 2.25rem, `lg` 2.5rem); `xs` (1.5rem) é a lista densa. O fallback e o selo
|
|
33
|
+
acompanham o tamanho.
|
|
33
34
|
|
|
34
35
|
```tsx preview
|
|
36
|
+
<Avatar size="xs">
|
|
37
|
+
<AvatarFallback>AL</AvatarFallback>
|
|
38
|
+
</Avatar>
|
|
35
39
|
<Avatar size="sm">
|
|
36
40
|
<AvatarFallback>AL</AvatarFallback>
|
|
37
41
|
</Avatar>
|
|
@@ -86,7 +90,7 @@ excedente — os membros do workspace Empresa X.
|
|
|
86
90
|
|
|
87
91
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
88
92
|
|---|---|---|---|
|
|
89
|
-
| `size` | `'sm' \| 'default' \| 'lg'` | `'default'` | Diâmetro do retrato; o fallback e o selo acompanham
|
|
93
|
+
| `size` | `'xs' \| 'sm' \| 'default' \| 'lg'` | `'default'` | Diâmetro do retrato na escala única dos controles (1.5 · 2 · 2.25 · 2.5rem); o fallback e o selo acompanham. |
|
|
90
94
|
|
|
91
95
|
## Propriedades de AvatarImage
|
|
92
96
|
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`context` declara a hierarquia ou o risco da ação; `variant` escolhe o tratamento visual. Use
|
|
4
4
|
`primary` para a ação principal, `neutral` para ações de apoio e `danger` quando a ação tiver uma
|
|
5
|
-
consequência perigosa.
|
|
6
|
-
compatibilidade.
|
|
5
|
+
consequência perigosa.
|
|
7
6
|
|
|
8
7
|
```tsx preview
|
|
9
8
|
<Button>Criar workspace</Button>
|
|
@@ -16,28 +15,45 @@ compatibilidade.
|
|
|
16
15
|
|
|
17
16
|
## Tamanhos
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
`size` usa a escala única dos controles: o mesmo nome tem a mesma medida em `Button`, `Select`,
|
|
19
|
+
`Tabs`, `Toggle`, `Switch`, `Avatar`, `Spinner` e nos botões embutidos. Os tamanhos de texto dão a
|
|
20
|
+
altura da linha; os `icon-*` são quadrados para botões só de ícone, que exigem `aria-label` porque não
|
|
21
|
+
há texto visível. O glifo dentro do controle acompanha o tamanho (0.875rem em `xs` e `sm`, 1rem em
|
|
22
|
+
`default`, 1.25rem em `lg`), a menos que o ícone traga um `size-*` próprio.
|
|
23
|
+
|
|
24
|
+
| Nome | Medida | Uso |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| `xs` | 1.5rem | Ação dentro de um campo (`InputGroupButton`). |
|
|
27
|
+
| `sm` | 2rem | Toolbar e cabeçalho densos, ao lado de `Select` e `Tabs` `sm`. |
|
|
28
|
+
| `default` | 2.25rem | A linha padrão, a mesma de `Input`. |
|
|
29
|
+
| `lg` | 2.5rem | Chamada principal com mais área de toque. |
|
|
30
|
+
| `icon-xs` | 1.5rem | Ação só de ícone dentro de um campo, como o `trailing` de Input ou Select. |
|
|
31
|
+
| `icon-sm` | 1.75rem | Ação só de ícone dentro de uma linha ou card; é o quadrado de `ActionTrigger` com `icon` e das setas do pager de `ActionList`. |
|
|
32
|
+
| `icon` | 2.25rem | Ação só de ícone na linha padrão. |
|
|
33
|
+
| `icon-lg` | 2.5rem | Ação só de ícone ao lado de um `lg`. |
|
|
20
34
|
|
|
21
35
|
```tsx preview
|
|
36
|
+
<Button size="xs">Mínimo</Button>
|
|
22
37
|
<Button size="sm">Pequeno</Button>
|
|
23
38
|
<Button>Padrão</Button>
|
|
24
39
|
<Button size="lg">Grande</Button>
|
|
25
|
-
<Button size="icon" aria-label="Novo"><Plus /></Button>
|
|
26
|
-
<Button size="icon-sm" variant="ghost" aria-label="Novo"><Plus /></Button>
|
|
27
40
|
<Button size="icon-xs" variant="ghost" aria-label="Novo"><Plus /></Button>
|
|
41
|
+
<Button size="icon-sm" variant="ghost" aria-label="Novo"><Plus /></Button>
|
|
42
|
+
<Button size="icon" aria-label="Novo"><Plus /></Button>
|
|
43
|
+
<Button size="icon-lg" aria-label="Novo"><Plus /></Button>
|
|
28
44
|
```
|
|
29
45
|
|
|
30
46
|
## Estados
|
|
31
47
|
|
|
32
|
-
busy = ação em andamento (DEPOIS do clique): o Spinner e o disabled vêm do botão.
|
|
33
|
-
Spinner TROCA o ícone (não soma). Não
|
|
34
|
-
|
|
48
|
+
busy = ação em andamento (DEPOIS do clique): o Spinner e o disabled vêm do botão. `icon` recebe o
|
|
49
|
+
elemento do ícone e o dimensiona pelo `size`; com icon, o Spinner TROCA o ícone (não soma). Não
|
|
50
|
+
confunda com carregar conteúdo (ANTES) — isso é `DataState` ou `Skeleton` em um nível de página.
|
|
35
51
|
|
|
36
52
|
```tsx preview
|
|
37
53
|
<Button disabled>Desabilitado</Button>
|
|
38
54
|
<Button busy>Salvando…</Button>
|
|
39
|
-
<Button icon={Plus}>Novo</Button>
|
|
40
|
-
<Button icon={Plus} busy>Novo</Button>
|
|
55
|
+
<Button icon={<Plus />}>Novo</Button>
|
|
56
|
+
<Button icon={<Plus />} busy>Novo</Button>
|
|
41
57
|
```
|
|
42
58
|
|
|
43
59
|
## Como outro elemento (asChild)
|
|
@@ -57,10 +73,10 @@ buttonVariants serve para o caso sem filho único.
|
|
|
57
73
|
|---|---|---|---|
|
|
58
74
|
| `context` | `'neutral' \| 'primary' \| 'danger'` | `'primary'` | A hierarquia ou o risco comunicado pela ação. |
|
|
59
75
|
| `variant` | `'solid' \| 'subtle' \| 'outline' \| 'ghost' \| 'link'` | `'solid'` | O tratamento visual aplicado ao contexto. |
|
|
60
|
-
| `size` | `'
|
|
76
|
+
| `size` | `'xs' \| 'sm' \| 'default' \| 'lg' \| 'icon-xs' \| 'icon-sm' \| 'icon' \| 'icon-lg'` | `'default'` | A medida na escala única dos controles (tabela acima). Os `icon-*` são quadrados para botões só de ícone, com `aria-label`. |
|
|
61
77
|
| `asChild` | `boolean` | `false` | Renderiza como o filho (Radix Slot) em vez de `<button>` — para âncoras e afins. |
|
|
62
78
|
| `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
|
-
| `icon` | `React.
|
|
79
|
+
| `icon` | `React.ReactNode` | | Ícone à esquerda, como nó (ex.: `icon={<Plus />}`); o glifo segue o `size`. No busy é trocado pelo Spinner — não soma. |
|
|
64
80
|
|
|
65
81
|
## ButtonGroup
|
|
66
82
|
|
|
@@ -83,7 +99,7 @@ variações.
|
|
|
83
99
|
|
|
84
100
|
```tsx preview
|
|
85
101
|
<ButtonGroup>
|
|
86
|
-
<Button icon={Play}>Rodar agente developer</Button>
|
|
102
|
+
<Button icon={<Play />}>Rodar agente developer</Button>
|
|
87
103
|
<ButtonGroupSeparator />
|
|
88
104
|
<Button size="icon" aria-label="Mais opções">
|
|
89
105
|
<ChevronDown />
|
|
@@ -102,7 +118,7 @@ semântica de outro elemento, como `label`.
|
|
|
102
118
|
<GitBranch />
|
|
103
119
|
empresa-x-api
|
|
104
120
|
</ButtonGroupText>
|
|
105
|
-
<Button variant="outline" icon={RotateCw}>Sincronizar</Button>
|
|
121
|
+
<Button variant="outline" icon={<RotateCw />}>Sincronizar</Button>
|
|
106
122
|
</ButtonGroup>
|
|
107
123
|
```
|
|
108
124
|
|
|
@@ -50,6 +50,42 @@ frase. Não copie as regras da Base para cá.
|
|
|
50
50
|
| placeholder de campo ou busca | `placeholder` |
|
|
51
51
|
| `Select.emptyText` e grupos de opção | `empty-state` e `heading` |
|
|
52
52
|
| confirmação local do `ActionTrigger` | `title`, `dialog-body` e `button` |
|
|
53
|
+
| `dialog.alert/confirm/prompt/choose` — `title`, `description`/`body`, `action`/`cancel`, `actions[].label` | `title`, `dialog-body`, `button` (e `placeholder` no `prompt`) |
|
|
54
|
+
| filhos de `TooltipContent` | `label` |
|
|
55
|
+
| `LabelHelp.help` | `helper-text` |
|
|
56
|
+
| `emptyMessage`, `errorMessage`, `retryLabel` de `DataState`, `PageState`, `ActionList`, `ActionListDialog` e `ActionView` | `empty-state`, `error`, `button` |
|
|
57
|
+
|
|
58
|
+
O tooltip entra como `label` porque nomeia um controle icon-only: é um fragmento curto, sem
|
|
59
|
+
ponto final, e a Base não define um papel próprio para tooltip. Texto de ajuda que precisa de
|
|
60
|
+
frase completa pertence ao `help` de um campo (contrato ou `LabelHelp`), não ao tooltip.
|
|
61
|
+
|
|
62
|
+
## Alcance do inventário além das props
|
|
63
|
+
|
|
64
|
+
Quem vê o gate reprovar ou precisa de uma dispensa deve saber o que o extrator alcança sem
|
|
65
|
+
declaração adicional:
|
|
66
|
+
|
|
67
|
+
- **Diálogos imperativos.** `dialog.confirm({ title, description, action })` e as demais
|
|
68
|
+
respostas (`alert`, `prompt`, `choose`) entram no inventário como se fossem props de um
|
|
69
|
+
`ActionFormDialog`; o campo do diagnóstico é `dialog.confirm().title`,
|
|
70
|
+
`dialog.choose().actions[0].label` etc. Constantes locais resolvem normalmente. Uma função
|
|
71
|
+
que devolve template (`description: describe(nome)`) gera o diagnóstico `content` habitual e
|
|
72
|
+
se declara em `copy.dynamic` como `message-template`. Opções construídas em tempo de execução
|
|
73
|
+
ou mutadas depois de declaradas reprovam como estrutura, porque nenhum texto pode ser
|
|
74
|
+
atribuído a elas.
|
|
75
|
+
- **`LabelHelp` como filho.** `<FieldLabel>Nome<LabelHelp help="…" /></FieldLabel>` inventaria
|
|
76
|
+
`Nome` como label e a ajuda como helper-text; o ícone não torna o label opaco. Um wrapper
|
|
77
|
+
local com o mesmo nome continua opaco, porque o extrator não infere o que ele renderiza.
|
|
78
|
+
- **Rótulos em array literal local.** Quando um componente mapeado lê `item.label` (ou a chave
|
|
79
|
+
destruturada) dentro de `map`, `forEach`, `filter` ou `for…of` sobre um array literal do
|
|
80
|
+
mesmo arquivo, cada literal do array vira um texto na linha em que foi escrito, em vez de um
|
|
81
|
+
diagnóstico sobre a prop. `filter`, `slice`, `toSorted` e `toReversed` podem ficar entre o
|
|
82
|
+
array e a iteração. O limite é deliberado: o array precisa ser literal e declarado no mesmo
|
|
83
|
+
arquivo; o elemento só pode ser lido (`item.chave`), nunca passado adiante, espalhado ou
|
|
84
|
+
atribuído; o callback não pode receber o próprio array como terceiro parâmetro; e nenhum
|
|
85
|
+
elemento pode ter a chave dinâmica. Arrays importados, derivados por spread ou por
|
|
86
|
+
concatenação continuam gerando o diagnóstico da prop.
|
|
87
|
+
- **Elementos JSX genéricos.** `<ActionList<Input, Row> emptyMessage="…">` extrai igual a
|
|
88
|
+
`<ActionList emptyMessage="…">`.
|
|
53
89
|
|
|
54
90
|
Copy visual e nome acessível são superfícies cumulativas. Um `aria-label` estático nomeia
|
|
55
91
|
um controle icon-only, mas não torna aceitável nem invisível ao gate um texto visual opaco.
|
|
@@ -22,7 +22,8 @@ render(
|
|
|
22
22
|
|
|
23
23
|
Use os slots quando o header precisar de composição própria. A árvore aceita exatamente um
|
|
24
24
|
`ContentHeader` e um `ContentBody` como filhos diretos. O header exige um `ContentTitle` e aceita
|
|
25
|
-
uma descrição, um
|
|
25
|
+
uma descrição, um contador (`ContentMeta`) e uma região de ações — a mesma anatomia de `PageHeader`,
|
|
26
|
+
com os mesmos slots e o mesmo layout; só o nível do heading e a hierarquia visual mudam.
|
|
26
27
|
|
|
27
28
|
```tsx preview col
|
|
28
29
|
render(
|
|
@@ -48,12 +49,12 @@ do pai correto, filhos estruturais indiretos e a mistura de shorthand com compos
|
|
|
48
49
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
49
50
|
|---|---|---|---|
|
|
50
51
|
| `title` | `ReactNode` | | Forma curta: título da região (vira o heading ligado à `section`). |
|
|
51
|
-
| `
|
|
52
|
+
| `count` | `number` | | Forma curta: total de itens ao lado do título — o mesmo `count` de `Page`. |
|
|
52
53
|
| `description` | `ReactNode` | | Forma curta: frase de apoio sob o título. |
|
|
53
54
|
| `actions` | `ReactNode` | | Forma curta: ações alinhadas à direita do header. |
|
|
54
55
|
| `level` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | herdado | Nível semântico do heading, independente do destaque visual. |
|
|
55
|
-
| `variant` | `'page' \| 'section'` | `'section'` | Hierarquia visual
|
|
56
|
+
| `variant` | `'page' \| 'section'` | `'section'` | Hierarquia visual: `page` reproduz o cabeçalho de `Page`; `section` é a região dentro de uma superfície. |
|
|
56
57
|
|
|
57
58
|
Na composição explícita, `ContentHeader` recebe `ContentTitle`, `ContentMeta`, `ContentDescription` e
|
|
58
59
|
`ContentActions`, e `ContentBody` recebe o conteúdo; nenhum desses slots aceita `title` ou `level`
|
|
59
|
-
próprios — a hierarquia é declarada em `Content`.
|
|
60
|
+
próprios — a hierarquia é declarada em `Content`. `ContentHeader` não existe fora de `Content`.
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
## Estados
|
|
2
2
|
|
|
3
|
-
Use `DataState` para apresentar carregamento, erro, vazio e conteúdo de uma mesma consulta.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
`
|
|
3
|
+
Use `DataState` para apresentar carregamento, erro, vazio e conteúdo de uma mesma consulta. As
|
|
4
|
+
superfícies são as mesmas de `PageState`, na escala de uma seção: o carregamento é um contêiner
|
|
5
|
+
`role="status"` com o `Spinner`; o vazio compõe `Empty` com moldura sólida e `emptyMessage` como
|
|
6
|
+
título; o erro é um `Alert` de contexto `danger` com uma mensagem segura, sem expor detalhes
|
|
7
|
+
técnicos, e o botão de recuperação quando há `onRetry`. Para uma ação em andamento depois do
|
|
8
|
+
clique, use `busy` em `Button`.
|
|
7
9
|
|
|
8
10
|
```tsx preview col
|
|
9
11
|
<div className="w-full space-y-3">
|
|
10
12
|
<DataState loading>
|
|
11
13
|
<div />
|
|
12
14
|
</DataState>
|
|
13
|
-
<DataState empty
|
|
15
|
+
<DataState empty emptyMessage="Nenhum papel.">
|
|
14
16
|
<div />
|
|
15
17
|
</DataState>
|
|
16
|
-
<DataState error={{ message: 'detalhe técnico fica no console' }}>
|
|
18
|
+
<DataState error={{ message: 'detalhe técnico fica no console' }} onRetry={() => undefined}>
|
|
17
19
|
<div />
|
|
18
20
|
</DataState>
|
|
19
21
|
</div>
|
|
@@ -22,13 +24,13 @@ segura, sem expor detalhes técnicos. Para uma ação em andamento depois do cli
|
|
|
22
24
|
## Dentro de uma tabela
|
|
23
25
|
|
|
24
26
|
Em uma tabela já emoldurada, passe `colSpan` para ocupar uma linha inteira dentro de `<tbody>`. A
|
|
25
|
-
tabela continua responsável pela borda
|
|
26
|
-
|
|
27
|
+
tabela continua responsável pela borda: o `Empty` dentro dela vem sem moldura. Para uma região
|
|
28
|
+
disponível para criação ou vínculo, use `Empty` diretamente, com a moldura tracejada.
|
|
27
29
|
|
|
28
30
|
```tsx preview col
|
|
29
31
|
<table className="w-full overflow-hidden rounded-lg border border-border text-sm">
|
|
30
32
|
<tbody>
|
|
31
|
-
<DataState empty
|
|
33
|
+
<DataState empty emptyMessage="Nenhum usuário." colSpan={3}>
|
|
32
34
|
<tr>
|
|
33
35
|
<td />
|
|
34
36
|
</tr>
|
|
@@ -42,8 +44,10 @@ região disponível para criação ou vínculo, use `Empty`.
|
|
|
42
44
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
43
45
|
|---|---|---|---|
|
|
44
46
|
| `loading` | `boolean` | | Carregando (antes do conteúdo) — mostra o Spinner centralizado. |
|
|
45
|
-
| `empty` | `boolean` | | Sem itens —
|
|
46
|
-
| `
|
|
47
|
-
| `error` | `{ message?: string } \| null` | | Erro da carga — aviso calmo. A mensagem técnica não vai para tela (use
|
|
48
|
-
| `
|
|
47
|
+
| `empty` | `boolean` | | Sem itens — compõe `Empty` com o `emptyMessage`. |
|
|
48
|
+
| `emptyMessage` | `string` | `'Nada por aqui.'` | Frase do vazio (ex.: "Nenhum papel."). |
|
|
49
|
+
| `error` | `{ message?: string } \| null` | | Erro da carga — aviso calmo. A mensagem técnica não vai para tela (use `errorMessage`). |
|
|
50
|
+
| `errorMessage` | `string` | `'Não foi possível carregar.'` | Título do aviso de erro, orientado à pessoa. |
|
|
51
|
+
| `onRetry` | `() => void \| Promise<void>` | | Recuperação: mostra o botão de tentar de novo no estado de erro. |
|
|
52
|
+
| `retryLabel` | `string` | `'Tentar de novo'` | Rótulo do botão de recuperação. |
|
|
49
53
|
| `colSpan` | `number` | | Em tabela: renderiza o estado como `<tr><td colSpan>` (cabe direto no tbody). |
|
|
@@ -305,7 +305,7 @@ avançada; ele recebe `children` e `container` conforme o portal do Radix.
|
|
|
305
305
|
## Propriedades de DialogHost
|
|
306
306
|
|
|
307
307
|
`DialogHost` não recebe propriedades. Monte uma instância no shell para atender toda a API
|
|
308
|
-
imperativa.
|
|
308
|
+
imperativa.
|
|
309
309
|
|
|
310
310
|
## Opções de dialog.alert
|
|
311
311
|
|
|
@@ -363,6 +363,3 @@ imperativa. `ConfirmHost` permanece como alias de migração.
|
|
|
363
363
|
| `context` | `ButtonContext` | Última ação: `primary`; demais: `neutral` | Define o significado semântico. |
|
|
364
364
|
| `variant` | `ButtonVariant` | Última ação: `solid`; demais: `ghost` | Define o tratamento visual. |
|
|
365
365
|
| `disabled` | `boolean` | `false` | Impede a escolha desta ação. |
|
|
366
|
-
|
|
367
|
-
`confirm()` e `ConfirmHost` continuam disponíveis apenas como aliases de migração para
|
|
368
|
-
`dialog.confirm()` e `DialogHost`.
|
|
@@ -166,7 +166,7 @@ Com `InputGroupTextarea`, um addon em `block-end` forma uma região de ações a
|
|
|
166
166
|
|
|
167
167
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
168
168
|
|---|---|---|---|
|
|
169
|
-
| `size` | `'xs' \| 'sm' \| 'icon-xs' \| 'icon-sm'` | `'xs'` |
|
|
169
|
+
| `size` | `'xs' \| 'sm' \| 'icon-xs' \| 'icon-sm'` | `'xs'` | O subconjunto da escala única que cabe num campo (1.5 · 2 · 1.5 · 1.75rem); os `icon-*` são quadrados. |
|
|
170
170
|
| `context` | `'neutral' \| 'primary' \| 'danger'` | `'primary'` | Contexto semântico herdado de Button. |
|
|
171
171
|
| `variant` | `'solid' \| 'subtle' \| 'outline' \| 'ghost' \| 'link'` | `'ghost'` | Tratamento visual; use `solid` quando a ação precisar de ênfase. |
|
|
172
172
|
|
|
@@ -105,7 +105,7 @@ usa `ItemHeader` ou `ItemBody` conforme o papel do conteúdo.
|
|
|
105
105
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
106
106
|
|---|---|---|---|
|
|
107
107
|
| `variant` | `'default' \| 'outline' \| 'muted'` | `'default'` | O fundo da linha: transparente, com borda ou levemente tingido. |
|
|
108
|
-
| `size` | `'default' \| 'sm'` | `'default'` | O respiro interno; `sm` atende listas densas. |
|
|
108
|
+
| `size` | `'default' \| 'sm'` | `'default'` | O respiro interno, com os nomes da escala única; `sm` atende listas densas. |
|
|
109
109
|
| `asChild` | `boolean` | `false` | Funde o Item no filho para que a linha inteira assuma sua semântica. |
|
|
110
110
|
|
|
111
111
|
## Propriedades de ItemGroup
|
|
@@ -8,7 +8,9 @@ contexto. O container é centralizado e ocupa a largura disponível até `80rem`
|
|
|
8
8
|
abaixo do cabeçalho permanece livre para tabelas, cards ou outras composições.
|
|
9
9
|
|
|
10
10
|
A forma curta é o padrão para páginas comuns. Ela cria internamente `PageHeader` e `PageBody`;
|
|
11
|
-
portanto, não produz uma estrutura visual ou semântica diferente da forma explícita.
|
|
11
|
+
portanto, não produz uma estrutura visual ou semântica diferente da forma explícita. O cabeçalho é a
|
|
12
|
+
mesma anatomia de `Content` (título, contador, descrição e ações): o que muda entre os dois é o nível
|
|
13
|
+
do heading e a hierarquia visual.
|
|
12
14
|
|
|
13
15
|
`Page` é o esqueleto de páginas e recursos delimitados. Ele também pode ocupar o painel principal
|
|
14
16
|
de um shell com sidebar; a navegação lateral não exige remover o teto nem reconstruir o cabeçalho.
|
|
@@ -90,8 +92,10 @@ altura e semântica acessível consistentes.
|
|
|
90
92
|
</Page>
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
`loading` centraliza o `Spinner
|
|
94
|
-
os filhos sem
|
|
95
|
+
`loading` centraliza o `Spinner` num contêiner `role="status"`; `error` compõe `Alert` com o botão
|
|
96
|
+
de recuperação quando há `onRetry`; `empty` compõe `Empty`; e `ready` entrega os filhos sem
|
|
97
|
+
acrescentar uma superfície. São as mesmas superfícies de `DataState`, na escala da página: `title`
|
|
98
|
+
e `description` nomeiam a situação e, sem `title`, valem `errorMessage` e `emptyMessage`.
|
|
95
99
|
|
|
96
100
|
```tsx preview col
|
|
97
101
|
<Page title="Relatórios">
|
|
@@ -126,5 +130,9 @@ estado na própria seção com `DataState`, `ActionView`, `ActionList` ou `Alert
|
|
|
126
130
|
| `title` | `ReactNode` | Texto seguro por estado | Situação reconhecível pela pessoa. |
|
|
127
131
|
| `description` | `ReactNode` | | Impacto ou próximo passo aplicável. |
|
|
128
132
|
| `icon` | `ReactNode` | Alerta no erro | Ícone decorativo do estado. |
|
|
129
|
-
| `action` | `ReactNode` | |
|
|
133
|
+
| `action` | `ReactNode` | | Seleção ou criação aplicável ao estado. |
|
|
134
|
+
| `emptyMessage` | `string` | `'Nada por aqui'` | Título do vazio quando `title` não é informado. |
|
|
135
|
+
| `errorMessage` | `string` | `'Não foi possível carregar esta página'` | Título do erro quando `title` não é informado. |
|
|
136
|
+
| `onRetry` | `() => void \| Promise<void>` | | Recuperação do erro: acrescenta o botão de tentar de novo ao lado de `action`. |
|
|
137
|
+
| `retryLabel` | `string` | `'Tentar de novo'` | Rótulo do botão de recuperação. |
|
|
130
138
|
| `children` | `ReactNode` | | Conteúdo renderizado somente em `ready`. |
|
|
@@ -29,21 +29,21 @@ rodapé.
|
|
|
29
29
|
|
|
30
30
|
## Números longos
|
|
31
31
|
|
|
32
|
-
A largura mínima é quadrada e cresce conforme o conteúdo. Na escala densa de um rodapé,
|
|
33
|
-
`
|
|
34
|
-
|
|
32
|
+
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"` (o quadrado de 1.75rem da escala única, com o glifo de 0.875rem); os
|
|
34
|
+
números, que não têm um degrau de 1.75rem na escala, ajustam por `className` (`h-7 min-w-7 text-xs`).
|
|
35
35
|
|
|
36
36
|
```tsx preview
|
|
37
37
|
<Pagination>
|
|
38
38
|
<PaginationContent className="gap-0.5">
|
|
39
39
|
<PaginationItem>
|
|
40
|
-
<PaginationPrevious href="#" iconOnly
|
|
40
|
+
<PaginationPrevious href="#" iconOnly size="icon-sm" />
|
|
41
41
|
</PaginationItem>
|
|
42
42
|
<PaginationItem>
|
|
43
43
|
<PaginationLink href="#" page={1} className="h-7 min-w-7 text-xs" />
|
|
44
44
|
</PaginationItem>
|
|
45
45
|
<PaginationItem>
|
|
46
|
-
<PaginationEllipsis
|
|
46
|
+
<PaginationEllipsis size="icon-sm" />
|
|
47
47
|
</PaginationItem>
|
|
48
48
|
<PaginationItem>
|
|
49
49
|
<PaginationLink href="#" page={5726} className="h-7 min-w-7 text-xs" />
|
|
@@ -52,7 +52,7 @@ setas com `iconOnly`).
|
|
|
52
52
|
<PaginationLink href="#" page={5727} isActive className="h-7 min-w-7 text-xs" />
|
|
53
53
|
</PaginationItem>
|
|
54
54
|
<PaginationItem>
|
|
55
|
-
<PaginationNext href="#" iconOnly
|
|
55
|
+
<PaginationNext href="#" iconOnly size="icon-sm" />
|
|
56
56
|
</PaginationItem>
|
|
57
57
|
</PaginationContent>
|
|
58
58
|
</Pagination>
|
|
@@ -61,7 +61,8 @@ setas com `iconOnly`).
|
|
|
61
61
|
## Com elipse
|
|
62
62
|
|
|
63
63
|
`PaginationEllipsis` marca, de forma decorativa e com `aria-hidden`, uma sequência de páginas que
|
|
64
|
-
não cabe na barra.
|
|
64
|
+
não cabe na barra. `size` aceita os quadrados da escala (`icon-xs`, `icon-sm`, `icon`, `icon-lg`) para
|
|
65
|
+
parear com as setas.
|
|
65
66
|
|
|
66
67
|
```tsx preview
|
|
67
68
|
<Pagination>
|
|
@@ -130,7 +131,7 @@ render(
|
|
|
130
131
|
| `page` | `number` | | Número usado como conteúdo, quando `children` não é informado, e no nome acessível “Página N”. |
|
|
131
132
|
| `isActive` | `boolean` | `false` | Marca a página atual com `aria-current="page"` e tratamento `outline`. |
|
|
132
133
|
| `href` | `string` | | Renderiza um `<a>`. Sem `href`, o componente usa `<button>` e aceita `onClick` e `disabled`. |
|
|
133
|
-
| `size` | `'
|
|
134
|
+
| `size` | `ButtonProps['size']` | `'default'` | A escala única, via `Button`. A largura mínima cresce para acomodar números longos; os `icon-*` são quadrados. |
|
|
134
135
|
|
|
135
136
|
## Propriedades de PaginationPrevious e PaginationNext
|
|
136
137
|
|
|
@@ -138,4 +139,5 @@ render(
|
|
|
138
139
|
|---|---|---|---|
|
|
139
140
|
| `label` | `string` | `'Página anterior'` ou `'Próxima página'` | Nome acessível e texto visível da ação. |
|
|
140
141
|
| `iconOnly` | `boolean` | `false` | Exibe somente a seta; `label` continua disponível para leitura assistiva. |
|
|
141
|
-
| `
|
|
142
|
+
| `size` | `ButtonProps['size']` | `'default'`; `'icon'` com `iconOnly` | A escala única; `icon-sm` para o rodapé denso. |
|
|
143
|
+
| `iconClassName` | `string` | | Classes aplicadas ao ícone da seta, quando o glifo da escala não servir. |
|
|
@@ -59,5 +59,6 @@ const status = t.dict(
|
|
|
59
59
|
|
|
60
60
|
## Compatibilidade
|
|
61
61
|
|
|
62
|
-
`tone` em dicionários
|
|
63
|
-
|
|
62
|
+
`tone` em dicionários continua aceito durante a migração; código novo usa `context`. As variantes
|
|
63
|
+
semânticas antigas dos componentes (`default`, `secondary`, `destructive`, `success`, `warning`,
|
|
64
|
+
`info`) saíram na 14.0.0: `variant` só descreve tratamento visual e o significado é sempre `context`.
|
|
@@ -61,7 +61,7 @@ uma sidebar fixa, redimensionável ou recolhida.
|
|
|
61
61
|
| `PaneHeader` | Mantém identidade, contexto ou ações no topo. |
|
|
62
62
|
| `PaneBody` | Ocupa o espaço restante e concentra a rolagem vertical. |
|
|
63
63
|
| `PaneFooter` | Mantém ações persistentes no rodapé. |
|
|
64
|
-
| `SidebarNav`
|
|
64
|
+
| `SidebarNav` | Apresenta e controla os destinos de navegação. |
|
|
65
65
|
|
|
66
66
|
`PaneContent` permanece como alias temporário de `PaneBody` durante a versão 12. Código novo usa
|
|
67
67
|
`PaneBody`.
|
|
@@ -134,26 +134,9 @@ render(
|
|
|
134
134
|
Esse é o padrão usado pelo `DocBrowser`: seções são rótulos, grupos nomeados são nós expansíveis e
|
|
135
135
|
páginas são folhas. Um grupo começa aberto e volta a abrir quando contém a página ativa.
|
|
136
136
|
|
|
137
|
-
`ShellNav` continua disponível para uma navegação plana com cabeçalho próprio e grupos ancorados no
|
|
138
|
-
rodapé, mas está descontinuado: código novo usa `SidebarNav`, que cobre o mesmo caso integrado à
|
|
139
|
-
`Sidebar`. Ele gerencia a rolagem internamente e se adapta quando estiver dentro de uma `Sidebar`
|
|
140
|
-
recolhida.
|
|
141
|
-
|
|
142
|
-
```tsx
|
|
143
|
-
<Sidebar collapsed={collapsed}>
|
|
144
|
-
<ShellNav
|
|
145
|
-
heading={<ShellNavHeading title="Relatórios" action={<CreateReportButton />} />}
|
|
146
|
-
groups={reportGroups}
|
|
147
|
-
footer={settingsGroups}
|
|
148
|
-
activeId={activeId}
|
|
149
|
-
onSelect={navigateToReport}
|
|
150
|
-
/>
|
|
151
|
-
</Sidebar>
|
|
152
|
-
```
|
|
153
|
-
|
|
154
137
|
## Recolher a coluna
|
|
155
138
|
|
|
156
|
-
`collapsed` pertence à `Sidebar`. Nesse estado, `SidebarItem
|
|
139
|
+
`collapsed` pertence à `Sidebar`. Nesse estado, `SidebarItem` e `SidebarNav` mantêm
|
|
157
140
|
somente os ícones e expõem os rótulos em tooltips. Por isso, todo destino que aparece no modo
|
|
158
141
|
recolhido precisa de um ícone reconhecível e de um `label` completo.
|
|
159
142
|
|
|
@@ -329,26 +312,3 @@ O driver de drag-and-drop continua externo e fornece seus atributos por `dragPro
|
|
|
329
312
|
|---|---|---|---|
|
|
330
313
|
| `className` | `string` | | Ajusta o grupo sem substituir o recuo, o espaçamento e a guia vertical padrão. |
|
|
331
314
|
| `children` | `ReactNode` | | Itens ou grupos que descendem do nó anterior. |
|
|
332
|
-
|
|
333
|
-
## Propriedades de ShellNav
|
|
334
|
-
|
|
335
|
-
| Propriedade | Tipo | Padrão | Descrição |
|
|
336
|
-
|---|---|---|---|
|
|
337
|
-
| `groups` | `ShellNavGroup[]` | | Grupos planos exibidos na região rolável. Grupos vazios são omitidos. |
|
|
338
|
-
| `activeId` | `string` | | Identificador do destino atual. |
|
|
339
|
-
| `onSelect` | `(id: string) => void` | | Recebe o identificador selecionado. |
|
|
340
|
-
| `heading` | `ReactNode` | | Conteúdo fixo acima da navegação; fica oculto no modo recolhido. |
|
|
341
|
-
| `footer` | `ShellNavGroup[]` | | Grupos ancorados abaixo da região rolável. |
|
|
342
|
-
| `navLabel` | `string` | `'Navegação'` | Nome acessível da landmark `nav`. |
|
|
343
|
-
| `className` | `string` | | Ajusta a coluna da navegação. A largura vem do contêiner. |
|
|
344
|
-
|
|
345
|
-
Cada `ShellNavGroup` recebe `label` opcional e `items`. Um `ShellNavItem` declara `id`, `label`,
|
|
346
|
-
`icon`, `badge` e `disabled`.
|
|
347
|
-
|
|
348
|
-
## Propriedades de ShellNavHeading
|
|
349
|
-
|
|
350
|
-
| Propriedade | Tipo | Padrão | Descrição |
|
|
351
|
-
|---|---|---|---|
|
|
352
|
-
| `title` | `ReactNode` | | Título da navegação. |
|
|
353
|
-
| `action` | `ReactNode` | | Ação relacionada apresentada no extremo oposto. |
|
|
354
|
-
| `className` | `string` | | Ajusta a faixa de cabeçalho. |
|