@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
|
@@ -35,33 +35,73 @@ acompanham o tamanho.
|
|
|
35
35
|
```tsx preview
|
|
36
36
|
<Avatar size="xs">
|
|
37
37
|
<AvatarFallback>AL</AvatarFallback>
|
|
38
|
+
<AvatarBadge className="bg-context-success" />
|
|
38
39
|
</Avatar>
|
|
39
40
|
<Avatar size="sm">
|
|
40
41
|
<AvatarFallback>AL</AvatarFallback>
|
|
42
|
+
<AvatarBadge className="bg-context-success" />
|
|
41
43
|
</Avatar>
|
|
42
44
|
<Avatar size="default">
|
|
43
45
|
<AvatarFallback>AL</AvatarFallback>
|
|
46
|
+
<AvatarBadge className="bg-context-success" />
|
|
44
47
|
</Avatar>
|
|
45
48
|
<Avatar size="lg">
|
|
46
49
|
<AvatarFallback>AL</AvatarFallback>
|
|
50
|
+
<AvatarBadge className="bg-context-success" />
|
|
47
51
|
</Avatar>
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
## Com selo de status
|
|
51
55
|
|
|
52
|
-
AvatarBadge
|
|
53
|
-
para
|
|
56
|
+
AvatarBadge mostra o estado de quem o avatar representa: verde para a pessoa online ou para o
|
|
57
|
+
agente developer rodando uma sessão, cinza para quem está ocioso. Sem classe, o selo usa a cor
|
|
58
|
+
primária; tinja-o com className. Ele fica no canto inferior direito, sobre a borda do círculo.
|
|
59
|
+
|
|
60
|
+
O selo comunica o estado só pela cor. Quando o estado importa e não aparece em texto ao lado, dê um
|
|
61
|
+
nome ao selo com `role="img"` e `aria-label`, como o `label` do [`Dot`](/ui/dot) faz.
|
|
54
62
|
|
|
55
63
|
```tsx preview
|
|
64
|
+
<Avatar>
|
|
65
|
+
<AvatarImage src="https://github.com/joaocampos.png" alt="João Campos" />
|
|
66
|
+
<AvatarFallback>JC</AvatarFallback>
|
|
67
|
+
<AvatarBadge className="bg-context-success" role="img" aria-label="Online" />
|
|
68
|
+
</Avatar>
|
|
56
69
|
<Avatar>
|
|
57
70
|
<AvatarFallback>
|
|
58
71
|
<Bot className="size-4" />
|
|
59
72
|
</AvatarFallback>
|
|
60
|
-
<AvatarBadge className="bg-context-success" />
|
|
73
|
+
<AvatarBadge className="bg-context-success" role="img" aria-label="Em sessão" />
|
|
61
74
|
</Avatar>
|
|
62
75
|
<Avatar>
|
|
63
76
|
<AvatarFallback>RV</AvatarFallback>
|
|
64
|
-
<AvatarBadge className="bg-
|
|
77
|
+
<AvatarBadge className="bg-context-neutral-emphasis" role="img" aria-label="Ocioso" />
|
|
78
|
+
</Avatar>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Um ícone filho aparece dentro do selo, em `0.5rem`. No tamanho `xs`, o selo é pequeno demais para o
|
|
82
|
+
ícone e mostra só a cor.
|
|
83
|
+
|
|
84
|
+
```tsx preview
|
|
85
|
+
<Avatar size="lg">
|
|
86
|
+
<AvatarFallback>AL</AvatarFallback>
|
|
87
|
+
<AvatarBadge role="img" aria-label="Verificado">
|
|
88
|
+
<Check />
|
|
89
|
+
</AvatarBadge>
|
|
90
|
+
</Avatar>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Forma do avatar
|
|
94
|
+
|
|
95
|
+
O avatar é circular por padrão. Para logo de organização ou workspace, declare outra forma no
|
|
96
|
+
próprio Avatar, como `rounded-lg`: a imagem e o fallback a acompanham. O Avatar não recorta o que
|
|
97
|
+
você coloca direto nele; para imagem ou iniciais, use AvatarImage e AvatarFallback.
|
|
98
|
+
|
|
99
|
+
```tsx preview
|
|
100
|
+
<Avatar className="rounded-lg">
|
|
101
|
+
<AvatarFallback>EX</AvatarFallback>
|
|
102
|
+
</Avatar>
|
|
103
|
+
<Avatar size="lg" className="rounded-lg">
|
|
104
|
+
<AvatarFallback>EX</AvatarFallback>
|
|
65
105
|
</Avatar>
|
|
66
106
|
```
|
|
67
107
|
|
|
@@ -91,6 +131,7 @@ excedente — os membros do workspace Empresa X.
|
|
|
91
131
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
92
132
|
|---|---|---|---|
|
|
93
133
|
| `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. |
|
|
134
|
+
| `className` | `string` | | Classes do root. Uma forma declarada aqui, como `rounded-lg`, vale também para AvatarImage e AvatarFallback. |
|
|
94
135
|
|
|
95
136
|
## Propriedades de AvatarImage
|
|
96
137
|
|
|
@@ -109,7 +150,15 @@ excedente — os membros do workspace Empresa X.
|
|
|
109
150
|
|
|
110
151
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
111
152
|
|---|---|---|---|
|
|
112
|
-
| `className` | `string` | | Classes usadas para comunicar visualmente o status no selo. |
|
|
153
|
+
| `className` | `string` | | Classes usadas para comunicar visualmente o status no selo. Sem cor própria, o fundo é `bg-primary`. |
|
|
154
|
+
| `children` | `React.ReactNode` | | Ícone opcional dentro do selo; fica oculto no tamanho `xs`. |
|
|
155
|
+
|
|
156
|
+
Os demais atributos, como `role` e `aria-label`, vão para o elemento `span`.
|
|
157
|
+
|
|
158
|
+
## Propriedades de AvatarGroup
|
|
159
|
+
|
|
160
|
+
`AvatarGroup` sobrepõe os `Avatar` filhos e desenha o anel de fundo que os separa. Não tem props
|
|
161
|
+
próprias; aceita as de um elemento `div`, como `className`.
|
|
113
162
|
|
|
114
163
|
## Propriedades de AvatarGroupCount
|
|
115
164
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
## Contexto e variante
|
|
2
2
|
|
|
3
|
-
Badge
|
|
4
|
-
|
|
3
|
+
Use `Badge` para um rótulo curto de estado ou categoria que precisa continuar legível. O Badge não é
|
|
4
|
+
interativo; para clique, use [`Button`](/ui/button). Quando só a cor basta, ao lado de um texto que
|
|
5
|
+
já nomeia o item, use [`Dot`](/ui/dot).
|
|
6
|
+
|
|
7
|
+
`context` comunica o significado; `variant` escolhe entre preenchimento sólido, superfície sutil ou
|
|
8
|
+
contorno.
|
|
5
9
|
|
|
6
10
|
```tsx preview
|
|
7
11
|
<Badge context="neutral">Agente</Badge>
|
|
@@ -11,9 +15,9 @@ escolhe entre preenchimento sólido, superfície sutil ou contorno.
|
|
|
11
15
|
|
|
12
16
|
## Contextos de status
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
declarado usa `DictionaryValue
|
|
16
|
-
decisão em cada tela.
|
|
18
|
+
Todos os contextos usam `subtle` por padrão, incluindo `success`, `warning`, `info` e `danger`.
|
|
19
|
+
Valor de dicionário com papel declarado usa [`DictionaryValue`](/ui/dictionary-value), que escolhe o
|
|
20
|
+
contexto pelo próprio dicionário em vez de repetir esta decisão em cada tela.
|
|
17
21
|
|
|
18
22
|
```tsx preview
|
|
19
23
|
<Badge context="success">Ativa</Badge>
|
|
@@ -24,7 +28,7 @@ decisão em cada tela.
|
|
|
24
28
|
|
|
25
29
|
## Com ícone
|
|
26
30
|
|
|
27
|
-
Um
|
|
31
|
+
Um ícone filho recebe `size-3` automaticamente e reforça o estado sem aumentar a altura do rótulo.
|
|
28
32
|
|
|
29
33
|
```tsx preview
|
|
30
34
|
<Badge context="success"><CircleCheck /> Regressão verde</Badge>
|
|
@@ -32,8 +36,9 @@ Um svg filho ganha size-3 automaticamente — bom para reforçar o estado sem cr
|
|
|
32
36
|
|
|
33
37
|
## Como link (asChild)
|
|
34
38
|
|
|
35
|
-
asChild
|
|
36
|
-
|
|
39
|
+
Com `asChild`, o Badge entrega a aparência ao filho em vez de renderizar o próprio `<span>`: um
|
|
40
|
+
`<a>` passa a ter a forma de badge e mantém a navegação. O Badge não aplica estado de hover;
|
|
41
|
+
acrescente-o por `className` quando o link precisar de retorno visual.
|
|
37
42
|
|
|
38
43
|
```tsx preview
|
|
39
44
|
<Badge asChild context="neutral" variant="solid">
|
|
@@ -47,4 +52,19 @@ hover; acrescente-o por `className` quando o link precisar de retorno visual.
|
|
|
47
52
|
|---|---|---|---|
|
|
48
53
|
| `context` | `'neutral' \| 'primary' \| 'info' \| 'success' \| 'warning' \| 'danger'` | `'neutral'` | O significado ou destaque contextual. |
|
|
49
54
|
| `variant` | `'solid' \| 'subtle' \| 'outline'` | `'subtle'` | O tratamento visual aplicado ao contexto. |
|
|
50
|
-
| `asChild` | `boolean` | `false` | Renderiza
|
|
55
|
+
| `asChild` | `boolean` | `false` | Renderiza o filho, como um `<a>`, com a aparência de badge, em vez de um `<span>`. |
|
|
56
|
+
|
|
57
|
+
Os demais atributos vão para o `<span>` ou, com `asChild`, para o filho.
|
|
58
|
+
|
|
59
|
+
## Função badgeVariants
|
|
60
|
+
|
|
61
|
+
`badgeVariants({ context, variant })` retorna as classes do Badge para um componente que só aceita
|
|
62
|
+
`className` e não pode ser envolvido com `asChild`. Os padrões são os mesmos do Badge: `neutral` e
|
|
63
|
+
`subtle`.
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
function badgeVariants(options?: {
|
|
67
|
+
context?: BadgeContext | null
|
|
68
|
+
variant?: BadgeVariant | null
|
|
69
|
+
}): string
|
|
70
|
+
```
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
## Caminho atual
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Use `Breadcrumb` quando a página estiver vários níveis abaixo da entrada da seção e a pessoa
|
|
4
|
+
precisar ver onde está e voltar a um nível intermediário. Em uma página, a trilha ocupa a região de
|
|
5
|
+
navegação do cabeçalho, como descreve [`Page`](/ui/page); quando basta voltar ao nível imediatamente
|
|
6
|
+
acima, use o retorno de `PageBack`.
|
|
7
|
+
|
|
8
|
+
Monte a trilha item a item: `BreadcrumbLink` nos níveis navegáveis, `BreadcrumbPage` no nível atual
|
|
9
|
+
e um `BreadcrumbSeparator` entre cada item. `BreadcrumbPage` não é clicável e marca a página atual
|
|
10
|
+
com `aria-current="page"`.
|
|
5
11
|
|
|
6
12
|
```tsx preview col-start
|
|
7
13
|
<Breadcrumb>
|
|
@@ -21,10 +27,10 @@ clicável, aria-current=page) e um BreadcrumbSeparator entre cada item.
|
|
|
21
27
|
</Breadcrumb>
|
|
22
28
|
```
|
|
23
29
|
|
|
24
|
-
## Com ícone e separador
|
|
30
|
+
## Com ícone e separador próprio
|
|
25
31
|
|
|
26
|
-
O primeiro nível pode levar um ícone
|
|
27
|
-
chevron padrão por outro
|
|
32
|
+
O primeiro nível pode levar um ícone para reforçar a origem da trilha. `BreadcrumbSeparator` aceita
|
|
33
|
+
`children` para trocar o chevron padrão por outro ícone, como a barra do exemplo.
|
|
28
34
|
|
|
29
35
|
```tsx preview col-start
|
|
30
36
|
<Breadcrumb>
|
|
@@ -53,9 +59,10 @@ chevron padrão por outro glifo (aqui, uma barra).
|
|
|
53
59
|
|
|
54
60
|
## Colapsado
|
|
55
61
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
Quando a trilha tiver mais níveis do que o espaço comporta, `BreadcrumbEllipsis` substitui os níveis
|
|
63
|
+
intermediários e mantém visíveis a raiz e os níveis mais próximos da página atual. A elipse é
|
|
64
|
+
decorativa (`aria-hidden`), e não um menu: os níveis omitidos deixam de ser alcançáveis pela trilha.
|
|
65
|
+
Ofereça esse caminho por outro meio, como a navegação da seção.
|
|
59
66
|
|
|
60
67
|
```tsx preview col-start
|
|
61
68
|
<Breadcrumb>
|
|
@@ -91,3 +98,9 @@ alcançáveis pela trilha. Ofereça esse caminho por outro meio, como a navegaç
|
|
|
91
98
|
| Propriedade | Tipo | Padrão | Descrição |
|
|
92
99
|
|---|---|---|---|
|
|
93
100
|
| `children` | `React.ReactNode` | `<ChevronRight />` | Elemento entre os itens. Omita para usar o chevron padrão ou passe outro ícone. |
|
|
101
|
+
|
|
102
|
+
`Breadcrumb` renderiza um `<nav>` com o nome acessível “Navegação estrutural”; `BreadcrumbList`, um
|
|
103
|
+
`<ol>`; `BreadcrumbItem`, um `<li>`; `BreadcrumbPage`, um `<span>`; e `BreadcrumbEllipsis`, um
|
|
104
|
+
`<span>`. Nenhum deles tem propriedades próprias: todos aceitam as props nativas do respectivo
|
|
105
|
+
elemento, incluindo `className`. Passe `aria-label` ao `Breadcrumb` quando a página tiver mais de
|
|
106
|
+
uma trilha.
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
## Contexto e variante
|
|
2
2
|
|
|
3
|
-
`context` declara a hierarquia ou o risco da ação; `variant`
|
|
4
|
-
`primary` para a ação principal, `neutral` para ações de apoio e
|
|
5
|
-
consequência perigosa. A variante `outline` mantém o fundo
|
|
6
|
-
superfície apenas no hover, preservando o fundo da região onde o
|
|
3
|
+
Use `Button` para iniciar uma ação. `context` declara a hierarquia ou o risco da ação; `variant`
|
|
4
|
+
escolhe o tratamento visual. Use `primary` para a ação principal, `neutral` para ações de apoio e
|
|
5
|
+
`danger` quando a ação tiver uma consequência perigosa. A variante `outline` mantém o fundo
|
|
6
|
+
transparente em repouso e usa uma superfície apenas no hover, preservando o fundo da região onde o
|
|
7
|
+
botão está inserido. `subtle` preenche o botão com um tom suave do contexto, para ações que precisam
|
|
8
|
+
de presença sem competir com a principal.
|
|
7
9
|
|
|
8
10
|
```tsx preview
|
|
9
11
|
<Button>Criar workspace</Button>
|
|
10
12
|
<Button context="neutral" variant="solid">Duplicar</Button>
|
|
13
|
+
<Button variant="subtle">Convidar pessoa</Button>
|
|
11
14
|
<Button context="neutral" variant="outline">Ver prévia</Button>
|
|
12
15
|
<Button context="neutral" variant="ghost">Cancelar</Button>
|
|
13
16
|
<Button context="danger" variant="solid">Excluir</Button>
|
|
@@ -16,8 +19,9 @@ superfície apenas no hover, preservando o fundo da região onde o botão está
|
|
|
16
19
|
|
|
17
20
|
## Tamanhos
|
|
18
21
|
|
|
19
|
-
`size` usa a escala única dos controles: o mesmo nome tem a mesma
|
|
20
|
-
`Tabs`, `Toggle`, `
|
|
22
|
+
`size` usa a escala única dos controles: o mesmo nome tem a mesma altura em `Button`, `Select`,
|
|
23
|
+
`Tabs`, `Toggle`, `Avatar` e nos botões embutidos. `Switch` e `Spinner` usam os mesmos nomes, mas
|
|
24
|
+
acompanham o tamanho do ícone de cada degrau, e não a altura da linha. Os tamanhos de texto dão a
|
|
21
25
|
altura da linha; os `icon-*` são quadrados para botões só de ícone, que exigem `aria-label` porque não
|
|
22
26
|
há texto visível. O glifo dentro do controle acompanha o tamanho (0.875rem em `xs`, `sm`,
|
|
23
27
|
`icon-xs`, `icon-sm` e `icon`; 1rem em `default`; 1.25rem em `lg` e `icon-lg`), a menos que o
|
|
@@ -26,8 +30,8 @@ há texto visível. O glifo dentro do controle acompanha o tamanho (0.875rem em
|
|
|
26
30
|
| Nome | Medida | Uso |
|
|
27
31
|
| --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
28
32
|
| `xs` | 1.5rem | Ação dentro de um campo (`InputGroupButton`). |
|
|
29
|
-
| `sm` | 2rem |
|
|
30
|
-
| `default` | 2.25rem | Decisão da superfície
|
|
33
|
+
| `sm` | 2rem | Operação densa em toolbar ou dentro de uma seção, ao lado de `Select` e `Tabs` `sm`. |
|
|
34
|
+
| `default` | 2.25rem | Decisão da superfície: header de Page, criação no cabeçalho de uma coleção e footer de Dialog ou Drawer; é também a linha de `Input`. |
|
|
31
35
|
| `lg` | 2.5rem | Chamada principal com mais área de toque. |
|
|
32
36
|
| `icon-xs` | 1.5rem | Ação só de ícone dentro de um campo ou de uma linha densa; é o quadrado de `ActionTrigger` com `icon`. |
|
|
33
37
|
| `icon-sm` | 1.75rem | Ação só de ícone em composições compactas que precisam de mais presença; também é o quadrado das setas do pager de `ActionList`. |
|
|
@@ -35,10 +39,11 @@ há texto visível. O glifo dentro do controle acompanha o tamanho (0.875rem em
|
|
|
35
39
|
| `icon-lg` | 2.5rem | Ação só de ícone ao lado de um `lg`. |
|
|
36
40
|
|
|
37
41
|
Escolha o tamanho pela região, não pela importância visual: `variant` e `context` resolvem a
|
|
38
|
-
hierarquia da ação. Headers de Page
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
hierarquia da ação. Headers de Page, a criação no cabeçalho de uma coleção e footers de
|
|
43
|
+
[`Dialog`](/ui/dialog) e [`Drawer`](/ui/drawer) usam `default`; a criação de uma coleção é um botão textual, sem
|
|
44
|
+
ícone, como mostra [`Content`](/ui/content). Operações densas de toolbar ou de seção usam `sm`;
|
|
45
|
+
ações dentro de linha ou célula usam `xs` ou `icon-xs`. Assim a mesma decisão mantém a mesma altura
|
|
46
|
+
mesmo quando uma superfície troca uma ação secundária por uma primária.
|
|
42
47
|
|
|
43
48
|
O retorno de `PageBack` usa `icon`. O fechamento de Dialog e Drawer é um `CloseButton` circular
|
|
44
49
|
(`shape="pill"`), `neutral` e `subtle`, no quadrado `icon-sm` por padrão, ou `icon-xs` com
|
|
@@ -49,29 +54,43 @@ O retorno de `PageBack` usa `icon`. O fechamento de Dialog e Drawer é um `Close
|
|
|
49
54
|
<Button size="sm">Pequeno</Button>
|
|
50
55
|
<Button>Padrão</Button>
|
|
51
56
|
<Button size="lg">Grande</Button>
|
|
52
|
-
<Button size="icon-xs" variant="ghost" aria-label="
|
|
53
|
-
<Button size="icon-sm" variant="ghost" aria-label="
|
|
54
|
-
<Button size="icon" aria-label="
|
|
55
|
-
<Button size="icon-lg" aria-label="
|
|
57
|
+
<Button size="icon-xs" variant="ghost" aria-label="Configurações"><Settings /></Button>
|
|
58
|
+
<Button size="icon-sm" variant="ghost" aria-label="Configurações"><Settings /></Button>
|
|
59
|
+
<Button size="icon" aria-label="Configurações"><Settings /></Button>
|
|
60
|
+
<Button size="icon-lg" aria-label="Configurações"><Settings /></Button>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Forma
|
|
64
|
+
|
|
65
|
+
`shape="pill"` arredonda as extremidades por completo. Use-a quando o botão acompanhar outros
|
|
66
|
+
controles arredondados, como a busca da toolbar de listas ou um grupo de filtros em pílula.
|
|
67
|
+
|
|
68
|
+
```tsx preview
|
|
69
|
+
<Button shape="pill" variant="outline" context="neutral">Todos os status</Button>
|
|
70
|
+
<Button shape="pill" size="icon" variant="ghost" aria-label="Filtros"><Filter /></Button>
|
|
56
71
|
```
|
|
57
72
|
|
|
58
73
|
## Estados
|
|
59
74
|
|
|
60
|
-
busy
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
`busy` indica que a ação já foi acionada e ainda está em andamento: o botão mostra um
|
|
76
|
+
[`Spinner`](/ui/spinner) e fica desabilitado até a conclusão. `icon` recebe o elemento do ícone e o
|
|
77
|
+
dimensiona pelo `size`; com `busy`, o spinner ocupa o lugar do ícone, sem alterar a largura. Para o
|
|
78
|
+
carregamento de conteúdo antes de qualquer ação, use [`DataState`](/ui/data-state) ou
|
|
79
|
+
[`Skeleton`](/ui/skeleton).
|
|
63
80
|
|
|
64
81
|
```tsx preview
|
|
65
82
|
<Button disabled>Desabilitado</Button>
|
|
66
83
|
<Button busy>Salvando…</Button>
|
|
67
|
-
<Button icon={<
|
|
68
|
-
<Button icon={<
|
|
84
|
+
<Button icon={<Download />}>Exportar</Button>
|
|
85
|
+
<Button icon={<Download />} busy>Exportar</Button>
|
|
69
86
|
```
|
|
70
87
|
|
|
71
88
|
## Como outro elemento (asChild)
|
|
72
89
|
|
|
73
|
-
|
|
74
|
-
|
|
90
|
+
Quando a ação navega para outro endereço, o elemento correto é um link, mesmo que ele precise da
|
|
91
|
+
aparência de botão. Com `asChild`, o `Button` aplica seus estilos ao filho, como um `<a>` ou o link
|
|
92
|
+
do roteador, sem criar uma cópia das classes. Quando não houver um único filho para receber os
|
|
93
|
+
estilos, use `buttonVariants` para obter as classes.
|
|
75
94
|
|
|
76
95
|
```tsx preview
|
|
77
96
|
<Button asChild variant="outline">
|
|
@@ -90,20 +109,20 @@ buttonVariants serve para o caso sem filho único.
|
|
|
90
109
|
| `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`. |
|
|
91
110
|
| `shape` | `'default' \| 'pill'` | `'default'` | Geometria do botão; `pill` arredonda as extremidades por completo. |
|
|
92
111
|
| `asChild` | `boolean` | `false` | Renderiza como o filho (Radix Slot) em vez de `<button>` — para âncoras e afins. |
|
|
93
|
-
| `busy` | `boolean` | `false` | Ação em andamento
|
|
94
|
-
| `icon` | `React.ReactNode` | | Ícone à esquerda, como nó (ex.: `icon={<Plus />}`); o glifo segue o `size`.
|
|
112
|
+
| `busy` | `boolean` | `false` | Ação em andamento, depois do clique: mostra o `Spinner` e desabilita o botão. Não indica carregamento de conteúdo; para isso, use `DataState` ou `Skeleton`. |
|
|
113
|
+
| `icon` | `React.ReactNode` | | Ícone à esquerda, como nó (ex.: `icon={<Plus />}`); o glifo segue o `size`. Com `busy`, dá lugar ao `Spinner`; os dois não aparecem juntos. |
|
|
95
114
|
|
|
96
115
|
## ButtonGroup
|
|
97
116
|
|
|
98
|
-
Use `ButtonGroup` para manter ações relacionadas juntas. No modo `connected`,
|
|
99
|
-
|
|
117
|
+
Use `ButtonGroup` para manter ações relacionadas juntas. No modo `connected`, o padrão, as
|
|
118
|
+
bordas internas colapsam e somente as pontas externas ficam arredondadas. Mantenha a
|
|
100
119
|
mesma variante nos filhos para preservar a unidade visual.
|
|
101
120
|
|
|
102
121
|
```tsx preview
|
|
103
122
|
<ButtonGroup>
|
|
104
123
|
<Button variant="outline">Visão geral</Button>
|
|
105
|
-
<Button variant="outline">
|
|
106
|
-
<Button variant="outline">
|
|
124
|
+
<Button variant="outline">Histórico</Button>
|
|
125
|
+
<Button variant="outline">Anexos</Button>
|
|
107
126
|
</ButtonGroup>
|
|
108
127
|
```
|
|
109
128
|
|
|
@@ -111,7 +130,7 @@ mesma variante nos filhos para preservar a unidade visual.
|
|
|
111
130
|
|
|
112
131
|
Use `mode="spaced"` quando os controles pertencem ao mesmo conjunto, mas cada um precisa preservar
|
|
113
132
|
sua própria forma e superfície de hover. O grupo aplica o intervalo compacto de `0.25rem` sem
|
|
114
|
-
conectar bordas. Esse modo atende ações
|
|
133
|
+
conectar bordas. Esse modo atende ações só com ícone em barras e linhas de listagem.
|
|
115
134
|
|
|
116
135
|
```tsx preview
|
|
117
136
|
<ButtonGroup mode="spaced">
|
|
@@ -131,8 +150,7 @@ conectar bordas. Esse modo atende ações icon-only em barras e linhas de listag
|
|
|
131
150
|
|
|
132
151
|
`DialogFooter` e `DrawerFooter` cuidam somente da faixa; envolva as decisões em um
|
|
133
152
|
`ButtonGroup mode="spaced"`, que responde pelo agrupamento e pela distribuição. Por padrão, as
|
|
134
|
-
ações preservam a largura do conteúdo e `Cancelar` usa `ghost`.
|
|
135
|
-
quando as duas decisões tiverem peso equivalente; nesse caso, `Cancelar` usa `outline`.
|
|
153
|
+
ações preservam a largura do conteúdo e `Cancelar` usa `ghost`.
|
|
136
154
|
|
|
137
155
|
```tsx
|
|
138
156
|
<DialogFooter>
|
|
@@ -145,6 +163,18 @@ quando as duas decisões tiverem peso equivalente; nesse caso, `Cancelar` usa `o
|
|
|
145
163
|
</DialogFooter>
|
|
146
164
|
```
|
|
147
165
|
|
|
166
|
+
Use `distribution="equal"` somente quando as duas decisões tiverem peso equivalente, como em uma
|
|
167
|
+
confirmação. As ações dividem a largura disponível; use `outline` no `Cancelar`.
|
|
168
|
+
|
|
169
|
+
```tsx preview col
|
|
170
|
+
<div className="w-80">
|
|
171
|
+
<ButtonGroup mode="spaced" distribution="equal">
|
|
172
|
+
<Button context="neutral" variant="outline">Cancelar</Button>
|
|
173
|
+
<Button context="danger">Excluir</Button>
|
|
174
|
+
</ButtonGroup>
|
|
175
|
+
</div>
|
|
176
|
+
```
|
|
177
|
+
|
|
148
178
|
### Ação dividida
|
|
149
179
|
|
|
150
180
|
Combine a ação principal, um separador e um botão de ícone quando o mesmo comando oferecer
|
|
@@ -152,9 +182,9 @@ variações.
|
|
|
152
182
|
|
|
153
183
|
```tsx preview
|
|
154
184
|
<ButtonGroup>
|
|
155
|
-
<Button icon={<
|
|
185
|
+
<Button icon={<Download />}>Exportar relatório</Button>
|
|
156
186
|
<ButtonGroupSeparator />
|
|
157
|
-
<Button size="icon" aria-label="Mais
|
|
187
|
+
<Button size="icon" aria-label="Mais formatos de exportação">
|
|
158
188
|
<ChevronDown />
|
|
159
189
|
</Button>
|
|
160
190
|
</ButtonGroup>
|
|
@@ -168,11 +198,11 @@ semântica de outro elemento, como `label`.
|
|
|
168
198
|
```tsx preview
|
|
169
199
|
<ButtonGroup>
|
|
170
200
|
<ButtonGroupText>
|
|
171
|
-
<
|
|
172
|
-
|
|
201
|
+
<CalendarDays />
|
|
202
|
+
Junho de 2026
|
|
173
203
|
</ButtonGroupText>
|
|
174
204
|
<Button variant="outline" icon={<RotateCw />}>
|
|
175
|
-
|
|
205
|
+
Atualizar
|
|
176
206
|
</Button>
|
|
177
207
|
</ButtonGroup>
|
|
178
208
|
```
|
|
@@ -183,14 +213,14 @@ semântica de outro elemento, como `label`.
|
|
|
183
213
|
|
|
184
214
|
```tsx preview col-start
|
|
185
215
|
<ButtonGroup orientation="vertical">
|
|
186
|
-
<Button variant="outline" size="icon" aria-label="
|
|
187
|
-
<
|
|
216
|
+
<Button variant="outline" size="icon" aria-label="Ampliar">
|
|
217
|
+
<ZoomIn />
|
|
188
218
|
</Button>
|
|
189
|
-
<Button variant="outline" size="icon" aria-label="
|
|
190
|
-
<
|
|
219
|
+
<Button variant="outline" size="icon" aria-label="Reduzir">
|
|
220
|
+
<ZoomOut />
|
|
191
221
|
</Button>
|
|
192
|
-
<Button variant="outline" size="icon" aria-label="
|
|
193
|
-
<
|
|
222
|
+
<Button variant="outline" size="icon" aria-label="Restaurar zoom">
|
|
223
|
+
<RotateCcw />
|
|
194
224
|
</Button>
|
|
195
225
|
</ButtonGroup>
|
|
196
226
|
```
|