@softize/opus 18.4.0 → 18.5.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 +12 -0
- package/docs/adr/0020-icon-tiles-are-explicitly-composed.md +46 -0
- package/docs/adr/0021-content-carries-structure-and-semantic-element.md +65 -0
- package/package.json +1 -1
- package/src/ui/components/patterns/content-header.tsx +168 -41
- package/src/ui/components/patterns/list.tsx +43 -13
- package/src/ui/components/primitives/detail.tsx +1 -1
- package/src/ui/components/primitives/empty.tsx +2 -1
- package/src/ui/components/primitives/field.tsx +38 -16
- package/src/ui/components/primitives/icon-tile.tsx +91 -0
- package/src/ui/components/primitives/item.tsx +2 -1
- package/src/ui/components/primitives/table.tsx +1 -1
- package/src/ui/docs/content/action-list.md +61 -52
- package/src/ui/docs/content/content.md +84 -8
- package/src/ui/docs/content/field.md +78 -30
- package/src/ui/docs/content/icon-tile.md +47 -0
- package/src/ui/docs/registry.tsx +6 -0
- package/src/ui/meta.ts +9 -3
- package/src/ui/react.tsx +17 -0
|
@@ -25,7 +25,9 @@ vincula ao controle, ligue-o ao controle por `aria-labelledby` para manter o nom
|
|
|
25
25
|
<Field orientation="horizontal">
|
|
26
26
|
<FieldContent>
|
|
27
27
|
<FieldTitle id="auto-review-title">Acionar o revisor no handoff</FieldTitle>
|
|
28
|
-
<FieldDescription>
|
|
28
|
+
<FieldDescription>
|
|
29
|
+
Ao abrir o handoff, o agente reviewer entra na sessão automaticamente.
|
|
30
|
+
</FieldDescription>
|
|
29
31
|
</FieldContent>
|
|
30
32
|
<Switch id="auto-review" aria-labelledby="auto-review-title" defaultChecked />
|
|
31
33
|
</Field>
|
|
@@ -33,22 +35,23 @@ vincula ao controle, ligue-o ao controle por `aria-labelledby` para manter o nom
|
|
|
33
35
|
|
|
34
36
|
## Conjunto com legenda e erro
|
|
35
37
|
|
|
36
|
-
`
|
|
37
|
-
`
|
|
38
|
-
Declare `data-invalid="true"` no
|
|
39
|
-
`aria-invalid` marca apenas o controle. O
|
|
40
|
-
|
|
41
|
-
Quando vários conjuntos compartilham a mesma superfície, use `variant="section"` para separar cada
|
|
42
|
-
grupo com uma linha leve. `icon` acrescenta uma referência visual antes do título sem transformar o
|
|
43
|
-
conjunto em outro card; escolha um ícone que represente a dimensão do grupo, não uma ação.
|
|
38
|
+
Use `Content as="fieldset"` para nomear um conjunto de campos relacionados. O título vira a legenda
|
|
39
|
+
nativa, enquanto `FieldGroup` define o espaçamento e `FieldSeparator` marca uma divisão.
|
|
40
|
+
`FieldError` aparece somente quando existe mensagem de erro. Declare `data-invalid="true"` no
|
|
41
|
+
`Field` para que o rótulo acompanhe o contexto de erro; `aria-invalid` marca apenas o controle. O
|
|
42
|
+
`ActionForm` define os dois atributos sozinho.
|
|
44
43
|
|
|
45
44
|
```tsx preview col md
|
|
46
|
-
<
|
|
47
|
-
<FieldLegend>Novo agente</FieldLegend>
|
|
45
|
+
<Content as="fieldset" title="Novo agente">
|
|
48
46
|
<FieldGroup>
|
|
49
47
|
<Field data-invalid="true">
|
|
50
48
|
<FieldLabel htmlFor="agent-name">Nome</FieldLabel>
|
|
51
|
-
<Input
|
|
49
|
+
<Input
|
|
50
|
+
id="agent-name"
|
|
51
|
+
defaultValue=""
|
|
52
|
+
aria-invalid
|
|
53
|
+
placeholder="Ex.: developer"
|
|
54
|
+
/>
|
|
52
55
|
<FieldError>Informe um nome para o agente.</FieldError>
|
|
53
56
|
</Field>
|
|
54
57
|
<FieldSeparator />
|
|
@@ -57,38 +60,83 @@ conjunto em outro card; escolha um ícone que represente a dimensão do grupo, n
|
|
|
57
60
|
<span>Prompt</span>
|
|
58
61
|
<LabelHelp help="A síntese vira a primeira mensagem da sessão." />
|
|
59
62
|
</FieldLabel>
|
|
60
|
-
<Textarea
|
|
63
|
+
<Textarea
|
|
64
|
+
id="agent-prompt"
|
|
65
|
+
rows={3}
|
|
66
|
+
defaultValue="Veste o papel de developer no workspace Empresa X."
|
|
67
|
+
/>
|
|
68
|
+
</Field>
|
|
69
|
+
</FieldGroup>
|
|
70
|
+
</Content>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Conjunto com moldura
|
|
74
|
+
|
|
75
|
+
Use a moldura para distinguir grupos vizinhos que continuem pertencendo ao mesmo formulário. O
|
|
76
|
+
título permanece uma legenda semântica. A moldura é contínua por padrão; quando o agrupamento pedir
|
|
77
|
+
o acabamento compacto com a legenda integrada à borda, declare `frameVariant="legend"`.
|
|
78
|
+
|
|
79
|
+
```tsx preview col md
|
|
80
|
+
<Content
|
|
81
|
+
as="fieldset"
|
|
82
|
+
framed
|
|
83
|
+
frameVariant="legend"
|
|
84
|
+
title={
|
|
85
|
+
<span className="flex items-center gap-2">
|
|
86
|
+
<IconTile size="xs">
|
|
87
|
+
<CarFront />
|
|
88
|
+
</IconTile>
|
|
89
|
+
Veículo
|
|
90
|
+
</span>
|
|
91
|
+
}
|
|
92
|
+
>
|
|
93
|
+
<FieldGroup>
|
|
94
|
+
<Field>
|
|
95
|
+
<FieldLabel htmlFor="vehicle-plate">Placa</FieldLabel>
|
|
96
|
+
<Input id="vehicle-plate" defaultValue="GBR1A03" />
|
|
61
97
|
</Field>
|
|
62
98
|
</FieldGroup>
|
|
63
|
-
</
|
|
99
|
+
</Content>
|
|
64
100
|
```
|
|
65
101
|
|
|
102
|
+
## Compatibilidade de FieldSet
|
|
103
|
+
|
|
104
|
+
`FieldSet` e `FieldLegend` continuam disponíveis para composições existentes. Em código novo,
|
|
105
|
+
prefira `Content as="fieldset"`: ele reúne legenda, corpo e moldura na mesma anatomia usada pelas
|
|
106
|
+
demais regiões nomeadas. A migração pode ser gradual porque os controles e o `FieldGroup` não mudam.
|
|
107
|
+
|
|
108
|
+
## Propriedades de FieldSet
|
|
109
|
+
|
|
110
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
111
|
+
| ----------- | --------------------- | --------- | ----------------------------------------------------------------------------- |
|
|
112
|
+
| `variant` | `'plain' \| 'framed'` | `'plain'` | Mantém o conjunto aberto ou aplica a moldura com a legenda integrada à borda. |
|
|
113
|
+
|
|
66
114
|
## Propriedades de Field
|
|
67
115
|
|
|
68
|
-
| Propriedade
|
|
69
|
-
|
|
70
|
-
| `orientation`
|
|
71
|
-
| `data-invalid` | `boolean \| 'true' \| 'false'`
|
|
116
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
117
|
+
| -------------- | -------------------------------------------- | ------------ | ----------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `orientation` | `'vertical' \| 'horizontal' \| 'responsive'` | `'vertical'` | Direção fixa do campo. `responsive` permanece como alias compatível de `horizontal`. |
|
|
119
|
+
| `data-invalid` | `boolean \| 'true' \| 'false'` | | Com `true`, aplica o contexto de erro ao campo e ao rótulo. O `ActionForm` define o atributo sozinho. |
|
|
72
120
|
|
|
73
121
|
## Propriedades de FieldLegend
|
|
74
122
|
|
|
75
|
-
| Propriedade | Tipo
|
|
76
|
-
|
|
77
|
-
| `variant`
|
|
78
|
-
| `icon`
|
|
123
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
124
|
+
| ----------- | ---------------------------------- | ---------- | ------------------------------------------------------------------------------------------ |
|
|
125
|
+
| `variant` | `'legend' \| 'label' \| 'section'` | `'legend'` | Define o porte de título, de rótulo compacto ou de seção com divisor. |
|
|
126
|
+
| `icon` | `ReactNode` | | Exibe conteúdo decorativo antes da legenda; componha `IconTile` quando quiser uma moldura. |
|
|
79
127
|
|
|
80
128
|
## Propriedades de FieldError
|
|
81
129
|
|
|
82
|
-
| Propriedade | Tipo
|
|
83
|
-
|
|
84
|
-
| `errors`
|
|
85
|
-
| `children`
|
|
130
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
131
|
+
| ----------- | ------------------------------------------ | ------ | ----------------------------------------------------------------------------------- |
|
|
132
|
+
| `errors` | `Array<{ message?: string } \| undefined>` | | Deduplica e apresenta uma lista de erros; sem conteúdo, o componente não renderiza. |
|
|
133
|
+
| `children` | `ReactNode` | | Mensagem literal, com prioridade sobre `errors`. |
|
|
86
134
|
|
|
87
135
|
## Propriedades de FieldSeparator
|
|
88
136
|
|
|
89
|
-
| Propriedade | Tipo
|
|
90
|
-
|
|
91
|
-
| `children`
|
|
137
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
138
|
+
| ----------- | ----------- | ------ | -------------------------------------------------------------------------- |
|
|
139
|
+
| `children` | `ReactNode` | | Rótulo opcional no centro da divisão; sem conteúdo, exibe somente a linha. |
|
|
92
140
|
|
|
93
141
|
`FieldSet`, `FieldGroup`, `FieldContent`, `FieldLabel`, `FieldTitle` e `FieldDescription` aceitam as
|
|
94
|
-
props nativas dos respectivos elementos
|
|
142
|
+
props nativas dos respectivos elementos. `FieldSet` mantém `variant` durante a compatibilidade.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
## Moldura decorativa para ícone
|
|
2
|
+
|
|
3
|
+
Use `IconTile` quando um ícone precisar de uma pequena superfície para ganhar hierarquia em uma
|
|
4
|
+
legenda, item ou resumo. O componente não é interativo; para uma ação, use `Button` com tamanho de
|
|
5
|
+
ícone e um nome acessível.
|
|
6
|
+
|
|
7
|
+
```tsx preview row
|
|
8
|
+
<IconTile size="xs"><UserRound /></IconTile>
|
|
9
|
+
<IconTile size="sm" variant="outline"><CarFront /></IconTile>
|
|
10
|
+
<IconTile context="primary"><CalendarDays /></IconTile>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
O tamanho controla a caixa e o glifo pela escala compartilhada dos controles. Um ícone que declara
|
|
14
|
+
uma classe `size-*` preserva a própria medida.
|
|
15
|
+
|
|
16
|
+
## Em uma legenda
|
|
17
|
+
|
|
18
|
+
Slots de ícone não criam a moldura automaticamente. Componha `IconTile` somente quando ela fizer
|
|
19
|
+
sentido para a superfície.
|
|
20
|
+
|
|
21
|
+
```tsx preview col md
|
|
22
|
+
<Content
|
|
23
|
+
as="fieldset"
|
|
24
|
+
framed
|
|
25
|
+
frameVariant="legend"
|
|
26
|
+
title={
|
|
27
|
+
<span className="flex items-center gap-2">
|
|
28
|
+
<IconTile size="xs">
|
|
29
|
+
<CarFront />
|
|
30
|
+
</IconTile>
|
|
31
|
+
Veículo
|
|
32
|
+
</span>
|
|
33
|
+
}
|
|
34
|
+
>
|
|
35
|
+
<FieldGroup />
|
|
36
|
+
</Content>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Propriedades
|
|
40
|
+
|
|
41
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
42
|
+
| ----------- | ------------------------------------------------------------------------ | ----------- | ------------------------------------------------------------- |
|
|
43
|
+
| `context` | `'neutral' \| 'primary' \| 'info' \| 'success' \| 'warning' \| 'danger'` | `'neutral'` | Declara o significado da cor. |
|
|
44
|
+
| `size` | `'xs' \| 'sm' \| 'default' \| 'lg'` | `'default'` | Define o tamanho da caixa e do glifo na escala compartilhada. |
|
|
45
|
+
| `variant` | `'subtle' \| 'outline'` | `'subtle'` | Usa preenchimento tonal ou acrescenta borda. |
|
|
46
|
+
|
|
47
|
+
As demais propriedades são as propriedades nativas de `span`.
|
package/src/ui/docs/registry.tsx
CHANGED
|
@@ -68,6 +68,7 @@ import chatMd from "./content/chat.md?raw";
|
|
|
68
68
|
import checkboxMd from "./content/checkbox.md?raw";
|
|
69
69
|
import collapsibleMd from "./content/collapsible.md?raw";
|
|
70
70
|
import iconPickerMd from "./content/icon-picker.md?raw";
|
|
71
|
+
import iconTileMd from "./content/icon-tile.md?raw";
|
|
71
72
|
import commandMd from "./content/command.md?raw";
|
|
72
73
|
import composerMd from "./content/composer.md?raw";
|
|
73
74
|
import copyableMd from "./content/copyable.md?raw";
|
|
@@ -697,6 +698,11 @@ export const UI_SECTIONS: DocSection[] = [
|
|
|
697
698
|
title: "Empty Value",
|
|
698
699
|
render: comp("Empty Value", "empty-value", emptyValueMd),
|
|
699
700
|
},
|
|
701
|
+
{
|
|
702
|
+
slug: "icon-tile",
|
|
703
|
+
title: "Icon Tile",
|
|
704
|
+
render: comp("Icon Tile", "icon-tile", iconTileMd),
|
|
705
|
+
},
|
|
700
706
|
{ slug: "item", title: "Item", render: comp("Item", "item", itemMd) },
|
|
701
707
|
{ slug: "kbd", title: "Kbd", render: comp("Kbd", "kbd", kbdMd) },
|
|
702
708
|
{
|
package/src/ui/meta.ts
CHANGED
|
@@ -53,6 +53,12 @@ export const componentMeta = {
|
|
|
53
53
|
whenToUse:
|
|
54
54
|
"Sinal compacto de estado. `context` declara neutral/primary/info/success/warning/danger e `variant` escolhe solid/outline. Passe `label` quando a cor reforçar informação; sem label, o ponto é decorativo. Para texto visível, use Badge.",
|
|
55
55
|
},
|
|
56
|
+
"icon-tile": {
|
|
57
|
+
name: "icon-tile",
|
|
58
|
+
ancestry: "opus",
|
|
59
|
+
whenToUse:
|
|
60
|
+
"Dê suporte visual não interativo a um ícone com tamanho, contexto, preenchimento e arredondamento consistentes. Componha-o nos slots que pedem a moldura; passe o ícone diretamente quando ela não for necessária. Para uma ação, use Button com tamanho de ícone.",
|
|
61
|
+
},
|
|
56
62
|
detail: {
|
|
57
63
|
name: "detail",
|
|
58
64
|
ancestry: "opus",
|
|
@@ -117,7 +123,7 @@ export const componentMeta = {
|
|
|
117
123
|
name: "content-header",
|
|
118
124
|
ancestry: "opus",
|
|
119
125
|
whenToUse:
|
|
120
|
-
|
|
126
|
+
'Estruture uma região com título e corpo. No caso comum, declare título, descrição, contador e ações diretamente em Content; use `framed` quando a região precisar de limite próprio, `as="fieldset"` para agrupar campos sob uma legenda nativa e `frameVariant="legend"` somente quando essa legenda precisar integrar visualmente a borda. Componha ContentHeader apenas quando precisar controlar a anatomia.',
|
|
121
127
|
},
|
|
122
128
|
copyable: {
|
|
123
129
|
name: "copyable",
|
|
@@ -279,7 +285,7 @@ export const componentMeta = {
|
|
|
279
285
|
name: "field",
|
|
280
286
|
ancestry: "shadcn",
|
|
281
287
|
whenToUse:
|
|
282
|
-
|
|
288
|
+
'Componha rótulo, controle, ajuda e erro com espaçamento consistente. Use a orientação vertical no caso comum e a horizontal quando controle e texto precisarem ficar lado a lado. FieldGroup organiza vários campos; quando o conjunto precisar de título, componha-o dentro de Content com `as="fieldset"`.',
|
|
283
289
|
},
|
|
284
290
|
"input-otp": {
|
|
285
291
|
name: "input-otp",
|
|
@@ -382,7 +388,7 @@ export const componentMeta = {
|
|
|
382
388
|
name: "action-list",
|
|
383
389
|
ancestry: "opus",
|
|
384
390
|
whenToUse:
|
|
385
|
-
"Apresente uma coleção pesquisável a partir de uma ListAction. O contrato declara colunas, filtros, período e busca; ActionList coordena visualizações, paginação, seleção em lote e sincronização com a URL. Em uma página, envolva a lista com Content para manter título e criação junto da coleção. Para um único recurso, use ActionView.",
|
|
391
|
+
"Apresente uma coleção pesquisável a partir de uma ListAction. O contrato declara colunas, filtros, período e busca; ActionList coordena visualizações, paginação, seleção em lote e sincronização com a URL. A tabela derivada não cria moldura própria. Em uma página, envolva a lista com Content para manter título e criação junto da coleção. Para um único recurso, use ActionView.",
|
|
386
392
|
},
|
|
387
393
|
"action-trigger": {
|
|
388
394
|
name: "action-trigger",
|
package/src/ui/react.tsx
CHANGED
|
@@ -298,6 +298,21 @@ export {
|
|
|
298
298
|
FieldSet,
|
|
299
299
|
FieldTitle,
|
|
300
300
|
} from "./components/primitives/field.tsx";
|
|
301
|
+
export type {
|
|
302
|
+
FieldSetProps,
|
|
303
|
+
FieldSetVariant,
|
|
304
|
+
} from "./components/primitives/field.tsx";
|
|
305
|
+
export {
|
|
306
|
+
IconTile,
|
|
307
|
+
iconTileVariants,
|
|
308
|
+
resolveIconTileStyle,
|
|
309
|
+
} from "./components/primitives/icon-tile.tsx";
|
|
310
|
+
export type {
|
|
311
|
+
IconTileContext,
|
|
312
|
+
IconTileProps,
|
|
313
|
+
IconTileSize,
|
|
314
|
+
IconTileVariant,
|
|
315
|
+
} from "./components/primitives/icon-tile.tsx";
|
|
301
316
|
export {
|
|
302
317
|
InputGroup,
|
|
303
318
|
InputGroupAddon,
|
|
@@ -471,6 +486,8 @@ export {
|
|
|
471
486
|
export type {
|
|
472
487
|
ContentProps,
|
|
473
488
|
ContentHeaderProps,
|
|
489
|
+
ContentElement,
|
|
490
|
+
ContentFrameVariant,
|
|
474
491
|
ContentHeaderLevel,
|
|
475
492
|
ContentHeaderVariant,
|
|
476
493
|
} from "./components/patterns/content-header.tsx";
|