@softize/opus 29.0.0 → 31.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 +137 -0
- package/bin/lib/check.mjs +178 -94
- package/bin/lib/copy.mjs +2970 -1801
- package/docs/adr/0043-neutral-surfaces-and-interactions-use-opaque-role-tokens.md +52 -0
- package/docs/adr/0044-neutral-appearance-derives-from-bounded-axes-per-mode.md +27 -2
- package/docs/adr/0045-surface-replaces-content-and-card.md +3 -0
- package/docs/adr/0060-surface-composition-separates-chrome-and-intro.md +142 -0
- package/docs/adr/0062-listas-contidas-e-texto-flexivel.md +68 -0
- package/docs/adr/0063-metadados-das-superficies.md +44 -0
- package/docs/adr/0064-action-list-com-itens-e-fontes-externas.md +47 -0
- package/docs/adr/0065-presentation-composes-settings-sections.md +295 -0
- package/docs/adr/README.md +8 -0
- package/package.json +1 -1
- package/registry/skills/build-opus-ui/SKILL.md +21 -19
- package/registry/skills/build-opus-ui/references/evaluations.md +21 -10
- package/registry/skills/build-opus-ui/references/ui-patterns.md +33 -28
- package/src/core/presentation.ts +938 -32
- package/src/core/types.ts +2 -1
- package/src/ui/components/patterns/form.tsx +2 -0
- package/src/ui/components/patterns/grouped-list.ts +2 -2
- package/src/ui/components/patterns/list.tsx +588 -365
- package/src/ui/components/patterns/page-heading-context.tsx +12 -5
- package/src/ui/components/patterns/page.tsx +238 -181
- package/src/ui/components/patterns/presentation-fields.tsx +246 -0
- package/src/ui/components/patterns/presentation-sections.tsx +494 -0
- package/src/ui/components/patterns/presentation.tsx +1142 -229
- package/src/ui/components/patterns/structural-header.tsx +47 -34
- package/src/ui/components/patterns/surface-anatomy.ts +27 -217
- package/src/ui/components/patterns/surface.tsx +55 -37
- package/src/ui/components/patterns/trigger.tsx +10 -2
- package/src/ui/components/primitives/close-button.tsx +11 -3
- package/src/ui/components/primitives/command.tsx +2 -8
- package/src/ui/components/primitives/detail.tsx +1 -1
- package/src/ui/components/primitives/dialog.tsx +59 -89
- package/src/ui/components/primitives/drawer.tsx +52 -87
- package/src/ui/components/primitives/field.tsx +1 -1
- package/src/ui/components/primitives/pagination.tsx +3 -2
- package/src/ui/components/primitives/table.tsx +3 -3
- package/src/ui/components/primitives/tabs.tsx +13 -2
- package/src/ui/docs/content/action-form.md +2 -1
- package/src/ui/docs/content/action-list.md +146 -73
- package/src/ui/docs/content/action-trigger.md +5 -0
- package/src/ui/docs/content/button.md +5 -6
- package/src/ui/docs/content/command.md +62 -50
- package/src/ui/docs/content/compositions.md +129 -459
- package/src/ui/docs/content/dialog.md +72 -101
- package/src/ui/docs/content/drawer.md +69 -92
- package/src/ui/docs/content/field.md +2 -1
- package/src/ui/docs/content/page.md +207 -386
- package/src/ui/docs/content/presentation.md +371 -23
- package/src/ui/docs/content/separator.md +1 -1
- package/src/ui/docs/content/surface.md +94 -116
- package/src/ui/docs/content/table.md +7 -0
- package/src/ui/docs/content/tokens.md +18 -4
- package/src/ui/drivers/context.tsx +11 -4
- package/src/ui/drivers/react.tsx +27 -7
- package/src/ui/meta.ts +5 -5
- package/src/ui/react.tsx +38 -8
- package/src/ui/theme.css +44 -33
|
@@ -10,13 +10,20 @@ limites visuais da coleção; use [`Table`](/ui/table) diretamente quando a comp
|
|
|
10
10
|
variante `framed`. Carregamento, erro e vazio usam o mesmo [`DataState`](/ui/data-state) das
|
|
11
11
|
demais coleções.
|
|
12
12
|
|
|
13
|
-
A
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
A tabela usa a largura disponível e permite quebra em células textuais. Colunas com `fit`
|
|
14
|
+
preservam valores compactos sem quebra. A largura das colunas de dados considera cabeçalhos e
|
|
15
|
+
valores, sem comprimir todas as colunas `fit` para ampliar a primeira. Os cabeçalhos quebram
|
|
16
|
+
quando falta espaço; seleção, ações de linha e células contendo apenas um switch
|
|
17
|
+
(direto ou envolvido por TooltipTrigger) mantêm a largura compacta.
|
|
18
|
+
Se identificadores sem espaços ou larguras mínimas explícitas excederem o espaço, a rolagem
|
|
19
|
+
fica nos resultados, sem alargar a toolbar ou o rodapé. Em `layout="fill"`, o cabeçalho continua fixo nessa região.
|
|
20
|
+
|
|
21
|
+
A barra distribui os controles `inline` em mais de uma linha quando necessário, preservando sua
|
|
22
|
+
ordem. Ela não move filtros automaticamente para o modal. Seletores de valor único acompanham o
|
|
23
|
+
valor escolhido até `20rem` e truncam o excedente; a busca varia entre `8rem` e `16rem`.
|
|
24
|
+
Declare como `advanced` os filtros que não precisam ficar sempre à vista, como descreve a seção
|
|
25
|
+
“Onde cada filtro aparece”. As opções da lista e os filtros avançados formam um `ButtonGroup` espaçado;
|
|
26
|
+
`toolbarActions` acrescenta, depois deles, ações da coleção, como criar, importar e exportar.
|
|
20
27
|
|
|
21
28
|
```tsx preview col
|
|
22
29
|
render(
|
|
@@ -34,24 +41,30 @@ render(
|
|
|
34
41
|
|
|
35
42
|
## Coleção nomeada
|
|
36
43
|
|
|
37
|
-
Em uma página,
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
Em uma página, use [`Page`](/ui/page) para o título e ações gerais. Ações da coleção
|
|
45
|
+
ficam na barra do `ActionList`, inclusive a criação, mesmo sem depender dos filtros atuais.
|
|
46
|
+
Em abas, a barra acompanha a lista do painel ativo.
|
|
40
47
|
|
|
41
48
|
```tsx
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
>
|
|
48
|
-
|
|
49
|
-
</
|
|
49
|
+
<Page title="Workspaces" layout="fill">
|
|
50
|
+
<ActionList
|
|
51
|
+
action={workspaceList}
|
|
52
|
+
input={{}}
|
|
53
|
+
toolbarActions={
|
|
54
|
+
<Button aria-label="Criar workspace" onClick={openCreate}>
|
|
55
|
+
Criar
|
|
56
|
+
</Button>
|
|
57
|
+
}
|
|
58
|
+
/>
|
|
59
|
+
</Page>
|
|
50
60
|
```
|
|
51
61
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
O botão exibe “Criar”; seu nome acessível e o formulário identificam o recurso.
|
|
63
|
+
Menu com vários tipos de criação preserva os nomes específicos. Operações sobre a seleção
|
|
64
|
+
usam `batchActions`, e ações de um registro usam `rowActions`.
|
|
65
|
+
|
|
66
|
+
`toolbarActions` recebe os nós já prontos e aparece também em visualizações sem filtros
|
|
67
|
+
ou tabela. Em uma ação somente com ícone, forneça `aria-label` e tooltip.
|
|
55
68
|
|
|
56
69
|
## Barra de filtros compartilhada
|
|
57
70
|
|
|
@@ -221,7 +234,7 @@ Declare `grouping.fields` quando uma dimensão enumerável puder organizar a tab
|
|
|
221
234
|
recorte de negócio. Cada campo precisa ser um filtro `select` ou `lookup`; texto, número e data não
|
|
222
235
|
são dimensões de agrupamento. O filtro pode aceitar uma ou várias opções: cada consulta de grupo
|
|
223
236
|
envia um único valor na forma declarada. A lista continua plana por padrão, e a pessoa escolhe
|
|
224
|
-
**Agrupar por** em **
|
|
237
|
+
**Agrupar por** em **Opções da lista**.
|
|
225
238
|
|
|
226
239
|
```ts
|
|
227
240
|
filters: {
|
|
@@ -254,9 +267,17 @@ aplicados à mesma dimensão restringem os grupos exibidos.
|
|
|
254
267
|
|
|
255
268
|
## Paginação e carregamento
|
|
256
269
|
|
|
257
|
-
|
|
270
|
+
Para coleções pequenas que devem aparecer por inteiro, declare `paginate: false` no
|
|
271
|
+
contrato da list action. ActionList omite `page` e `limit` da consulta, do estado lido
|
|
272
|
+
da URL e dos links gerados; não exibe rodapé nem seletor de quantidade. O handler deve
|
|
273
|
+
devolver todos os itens que atendem à busca e aos filtros. O componente não busca páginas
|
|
274
|
+
adicionais em segundo plano nem aumenta o limite artificialmente. A opção também é
|
|
275
|
+
respeitada pelas listas renderizadas por Presentation, sem configuração visual duplicada.
|
|
276
|
+
|
|
277
|
+
Nos demais modos, `ActionList` envia `limit`, definido por `pageSize`, e `page` no input. O handler aplica o recorte e
|
|
258
278
|
devolve `total` na resposta paginada. Quando existe total, o rodapé mostra a página atual, os links
|
|
259
|
-
disponíveis e a quantidade de itens.
|
|
279
|
+
disponíveis e a quantidade de itens. Com total zero, o rodapé e seu divisor não aparecem:
|
|
280
|
+
a mensagem de vazio permanece como indicação do resultado. Alterar busca, filtro, ordenação ou período retorna à primeira
|
|
260
281
|
página. Durante a primeira consulta, `DataState` apresenta o carregamento; em atualizações
|
|
261
282
|
posteriores, a lista permanece visível com `aria-busy`.
|
|
262
283
|
|
|
@@ -272,20 +293,8 @@ rodapé podem continuar visíveis enquanto só os resultados rolam. Para isso, d
|
|
|
272
293
|
render(
|
|
273
294
|
<DocBrowserActionProvider>
|
|
274
295
|
<div className="h-80 w-full overflow-x-auto overflow-y-hidden rounded-lg border border-border">
|
|
275
|
-
<Page layout="fill">
|
|
276
|
-
<
|
|
277
|
-
<Surface as="section" level={1}>
|
|
278
|
-
<SurfaceHeader>
|
|
279
|
-
<SurfaceTitle>Workspaces</SurfaceTitle>
|
|
280
|
-
<SurfaceActions>
|
|
281
|
-
<Button>Criar workspace</Button>
|
|
282
|
-
</SurfaceActions>
|
|
283
|
-
</SurfaceHeader>
|
|
284
|
-
<SurfaceBody>
|
|
285
|
-
<ActionList action={docWorkspaceList} input={{}} />
|
|
286
|
-
</SurfaceBody>
|
|
287
|
-
</Surface>
|
|
288
|
-
</PageBody>
|
|
296
|
+
<Page title="Workspaces" layout="fill">
|
|
297
|
+
<ActionList action={docWorkspaceList} input={{}} toolbarActions={<Button aria-label="Criar workspace">Criar</Button>} />
|
|
289
298
|
</Page>
|
|
290
299
|
</div>
|
|
291
300
|
</DocBrowserActionProvider>,
|
|
@@ -312,8 +321,8 @@ componentes no caminho. Nos demais casos, a decisão é sua:
|
|
|
312
321
|
|
|
313
322
|
- Para a lista manter a altura dos resultados, como em uma seção secundária cuja rolagem pertence ao
|
|
314
323
|
`PageBody`, declare `layout="flow"`.
|
|
315
|
-
-
|
|
316
|
-
|
|
324
|
+
- `TabsPanel` repassa a altura disponível à lista. Um contêiner próprio sem essa integração
|
|
325
|
+
interrompe a herança: declare `layout="fill"` na lista e dê ao contêiner as classes
|
|
317
326
|
`flex min-h-0 flex-1 flex-col`.
|
|
318
327
|
- Dentro de [`Surface`](/ui/surface), [`Dialog`](/ui/dialog), [`Drawer`](/ui/drawer) ou
|
|
319
328
|
[`Pane`](/ui/pane), a lista não herda o `fill` da página: a altura do corpo pertence à
|
|
@@ -435,13 +444,17 @@ filters: {
|
|
|
435
444
|
|
|
436
445
|
## Exibição e estado na URL
|
|
437
446
|
|
|
438
|
-
O botão
|
|
447
|
+
O botão **Opções da lista** reúne as preferências disponíveis para a visualização. Na tabela, permite
|
|
439
448
|
escolher a ordenação, inverter sua direção, agrupar e mostrar ou ocultar colunas, inclusive as
|
|
440
|
-
declaradas com `hidden`;
|
|
441
|
-
página. Um ponto sinaliza quando alguma preferência diverge do padrão. O rodapé explicita a
|
|
449
|
+
declaradas com `hidden`; nas listas paginadas, permite alterar a quantidade de itens por
|
|
450
|
+
página. Quando não há preferências disponíveis, o botão não aparece. Um ponto sinaliza quando alguma preferência diverge do padrão. O rodapé explicita a
|
|
442
451
|
ordenação e o agrupamento ativos junto da paginação e do total. Busca, ordenação, filtros,
|
|
443
452
|
visualização, colunas e limite podem ser serializados na query string pelos helpers do componente:
|
|
444
453
|
|
|
454
|
+
Operações usam `invalidates` para atualizar os dados, e o consumidor pode manter suas
|
|
455
|
+
assinaturas de eventos. Em caso de falha, o estado de erro oferece **Tentar novamente**
|
|
456
|
+
diretamente. Não há comando de recarga manual no menu nem polling automático no ActionList.
|
|
457
|
+
|
|
445
458
|
Cada campo de `sort.fields` precisa de uma coluna com rótulo textual para aparecer no seletor e no
|
|
446
459
|
resumo do rodapé; a coluna pode estar `hidden`. Campos sem coluna continuam válidos para o handler e
|
|
447
460
|
para uma ordenação padrão, mas o Opus não expõe seu identificador técnico na interface. **Sem
|
|
@@ -461,9 +474,55 @@ restaurá-lo.
|
|
|
461
474
|
|
|
462
475
|
Convenção compacta (defaults omitidos): `?q=…&sort=key:dir&status=…&view=board&cols=a,b,c&limit=25`.
|
|
463
476
|
|
|
477
|
+
## Itens conectados
|
|
478
|
+
|
|
479
|
+
Para coleções que apresentam um nome, uma descrição e ações por registro, declare os campos
|
|
480
|
+
em `item`. O ActionList monta a moldura e os separadores com ItemGroup; mantém carregamento,
|
|
481
|
+
erro, recuperação e vazio. `title` coloca o nome da coleção junto das `toolbarActions`.
|
|
482
|
+
Nome e descrição ocupam uma linha cada, com reticências quando ultrapassam a largura disponível.
|
|
483
|
+
|
|
484
|
+
```tsx preview col
|
|
485
|
+
render(
|
|
486
|
+
<DocBrowserActionProvider>
|
|
487
|
+
<ActionList
|
|
488
|
+
action={docWorkspaceList}
|
|
489
|
+
input={{}}
|
|
490
|
+
title="Workspaces"
|
|
491
|
+
item={{ title: "name", description: "client" }}
|
|
492
|
+
/>
|
|
493
|
+
</DocBrowserActionProvider>
|
|
494
|
+
);
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Os nomes em `item` são campos diretos do resultado, com valores textuais ou numéricos.
|
|
498
|
+
O objeto é serializável. `rowActions` recebe o registro e um contexto com `items`, `total`,
|
|
499
|
+
`isFetching`, `isError` e `refetch`; `toolbarActions` também pode ser uma função desse contexto.
|
|
500
|
+
O modo de itens não combina `children`, `views` ou seleção em lote. `onRowClick` continua
|
|
501
|
+
restrito à tabela; ações dos itens ficam nos controles explícitos de `rowActions`.
|
|
502
|
+
|
|
503
|
+
Com uma página, esse modo dispensa o rodapé. Com mais resultados, mantém a paginação.
|
|
504
|
+
Depois de remover o último item de uma página, volta à última página válida. A tabela conserva
|
|
505
|
+
seu rodapé e seus controles existentes.
|
|
506
|
+
|
|
507
|
+
### Fonte governada por outro serviço
|
|
508
|
+
|
|
509
|
+
Quando a coleção pertence a uma integração que já possui cliente e autorização, `source`
|
|
510
|
+
conecta esse cliente sem criar uma action artificial. Declare uma chave com o escopo de acesso
|
|
511
|
+
e um `load(input, { signal })` que retorna `{ items, total, cursor }`. A fonte deve respeitar
|
|
512
|
+
`page` e `limit`; se o serviço retorna todos os registros, o adapter pagina o conjunto completo.
|
|
513
|
+
|
|
514
|
+
A fonte substitui `action`, exige QueryClientProvider e dispensa OpusProvider quando não há
|
|
515
|
+
actions nos controles. Seu cache é separado das actions, não reaproveita dados entre escopos e
|
|
516
|
+
é descartado após a desmontagem. Falhas usam a mensagem pública `errorMessage` e oferecem
|
|
517
|
+
recuperação; detalhes técnicos do erro não são exibidos. Dados sensíveis usados pelo cliente
|
|
518
|
+
externo devem permanecer no adapter, fora dos itens retornados.
|
|
519
|
+
|
|
520
|
+
`source` é runtime: seu loader não entra no JSON. Uma definição serializável futura deverá
|
|
521
|
+
referenciar uma fonte registrada, enquanto `item` já descreve a apresentação sem JSX.
|
|
522
|
+
|
|
464
523
|
## Composição dos itens
|
|
465
524
|
|
|
466
|
-
|
|
525
|
+
Quando `item` não representar a composição necessária, passe `children` para substituir a tabela por uma composição própria, como uma lista de
|
|
467
526
|
[`Item`](/ui/item). A barra de filtros e os estados de carregamento, erro e vazio continuam sendo
|
|
468
527
|
tratados por `ActionList`. O contrato não leva o tipo do item até o componente: anote o parâmetro de
|
|
469
528
|
`children` (ou de `render`, em uma visualização) ou declare os genéricos, como em
|
|
@@ -557,32 +616,46 @@ para fora de `toolbarActions`.
|
|
|
557
616
|
|
|
558
617
|
## Propriedades de ActionList
|
|
559
618
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
|
563
|
-
|
|
|
564
|
-
| `
|
|
565
|
-
| `
|
|
566
|
-
| `
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
|
570
|
-
|
|
|
571
|
-
| `
|
|
572
|
-
| `
|
|
573
|
-
| `
|
|
574
|
-
| `
|
|
575
|
-
| `
|
|
576
|
-
| `
|
|
577
|
-
| `
|
|
578
|
-
| `
|
|
579
|
-
| `
|
|
580
|
-
| `
|
|
581
|
-
| `
|
|
582
|
-
| `
|
|
583
|
-
| `
|
|
584
|
-
| `
|
|
585
|
-
| `
|
|
586
|
-
| `
|
|
587
|
-
| `
|
|
588
|
-
| `
|
|
619
|
+
`action` e `source` são alternativas mutuamente exclusivas.
|
|
620
|
+
|
|
621
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
622
|
+
| --- | --- | --- | --- |
|
|
623
|
+
| `source` | `ListDataSource<TItem>` | — | Fonte externa com `key` e `load`; substitui a action. |
|
|
624
|
+
| `title` | `string` | — | Título da coleção, ao lado das ações. |
|
|
625
|
+
| `item` | `ActionListItemSpec` | — | Campos `title` e `description?` da apresentação em itens. |
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
629
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
630
|
+
| `action` | `ListActionLike` | | A ListAction do Opus (kind list, output = item). A paginação envia `limit`/`page` e usa o `total` devolvido. |
|
|
631
|
+
| `input` | `TInput` | | O escopo base, como `{ workspaceId }`. A toolbar acrescenta busca, filtros e paginação sem sobrescrever essas chaves. |
|
|
632
|
+
| `layout` | `'flow' \| 'fill'` | `'fill'` como filha direta de `PageBody`, `SurfaceBody` ou do corpo da `Presentation` em uma página `fill`; `'flow'` nos demais casos | Em `fill`, ocupa a altura de um ancestral limitado e rola somente a região de resultados; na tabela, o cabeçalho fica fixo. Sem ancestral limitado, equivale a `flow`. |
|
|
633
|
+
| `cells` | `Record<string, (item) => ReactNode>` | | Células custom por cima das colunas do contrato (chave = column.key). |
|
|
634
|
+
| `filterOptions` | `Record<string, SelectOption[]>` | | Opções de runtime para filtros select/lookup. Em uma dimensão de agrupamento, a coleção precisa ser completa e ter de 1 a 12 itens. |
|
|
635
|
+
| `filterDefaults` | `Record<string, string>` | | Valores de repouso aplicados à consulta; o `X` só aparece quando o filtro diverge deles e retorna a eles. |
|
|
636
|
+
| `filterIcons` | `Record<string, ReactNode>` | | Ícones leading dos filtros, indexados pelo nome declarado no contrato. |
|
|
637
|
+
| `advancedFilters` | `{ columns?: 1 \| 2 \| 3; sectionIcons?: Record<string, ReactNode>; sectionVariant?: 'plain' \| 'framed' }` | `{ columns: 1, sectionVariant: 'plain' }` | Define as colunas, os ícones e o tratamento dos grupos; o Opus deriva a largura correspondente do diálogo. |
|
|
638
|
+
| `periodPosition` | `'before' \| 'after' \| { afterFilter: string }` | `'before'` | Posiciona o período antes, depois ou imediatamente após um filtro inline. |
|
|
639
|
+
| `period` | `{ basisFilter: string }` | | Reúne o período e o filtro inline indicado em um único controle. |
|
|
640
|
+
| `views` | `Record<string, ActionListView<TItem>>` | | Visualizações alternativas `{ label, icon?, render }`; o seletor alterna entre a tabela e estas. |
|
|
641
|
+
| `beforeContent` | `ReactNode \| (input: TInput) => ReactNode` | | Conteúdo entre a toolbar e o corpo; a função recebe o mesmo input efetivo da consulta, para resumos que acompanham o recorte. |
|
|
642
|
+
| `columns` | `ActionListColumn<TItem>[]` | | Tabela explícita, que substitui as colunas declaradas no contrato. |
|
|
643
|
+
| `children` | `(items, refetch) => ReactNode` | | Modo composição: layout livre; a toolbar segue. Tem precedência sobre columns. |
|
|
644
|
+
| `batch` | `ActionListBatchAction[]` | | Ações em lote: `{ label, can?, run, confirm?: { title, message? }, destructive? }` — liga a multi-seleção. |
|
|
645
|
+
| `rowId` | `(item) => string` | `item.id` | Identidade da linha para seleção. |
|
|
646
|
+
| `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. |
|
|
647
|
+
| `state / onStateChange` | `ActionListState / (next) => void` | interno | Estado da toolbar controlado — para quem embala sincronizar com a URL. |
|
|
648
|
+
| `empty` | `(items) => boolean` | `items.length === 0` | Sobrepõe o vazio derivado, por exemplo quando um formulário inline aberto conta como conteúdo. |
|
|
649
|
+
| `loading` | `boolean` | | Carga extra agregada à da consulta, como uma query irmã de que os `children` dependem. |
|
|
650
|
+
| `emptyMessage` | `string` | `'Nenhum resultado.'` | Frase do estado vazio (o `Empty` do `DataState`). |
|
|
651
|
+
| `errorMessage` | `string` | `'Não foi possível carregar.'` | Título do aviso de erro; a ação de tentar de novo refaz a consulta. |
|
|
652
|
+
| `retryLabel` | `string` | `'Tentar de novo'` | Nome acessível e tooltip da ação de recuperação. |
|
|
653
|
+
| `onRowClick` | `(item: TItem) => void` | | Clique na linha (ex.: navegar para o detalhe) — só na tabela. |
|
|
654
|
+
| `viewControls` | `ReactNode` | | Controles da visualização ativa, imediatamente após o seletor de visualização. |
|
|
655
|
+
| `toolbarActions` | `ReactNode \| ((context) => ReactNode)` | | Ações da coleção, incluindo criação, junto ao título quando declarado ou no fim da barra. Os nós são renderizados como recebidos: nome acessível e tooltip de uma ação somente com ícone ficam com o consumidor. |
|
|
656
|
+
| `rowActions` | `(item: TItem, context) => ReactNode` | | Ações por registro, na tabela ou à direita dos itens. Na tabela, a partir de duas, entram em um grupo com intervalo compacto; uma só fica solta, sem grupo. Cliques ali não disparam o `onRowClick`. |
|
|
657
|
+
|
|
658
|
+
Para carregar um detalhe a partir do mesmo recorte da coleção, use
|
|
659
|
+
`listStateToInput(state, action, { input, filterDefaults, pageSize })`. O helper materializa
|
|
660
|
+
busca, filtros, período, ordenação e paginação com a mesma regra usada pelo ActionList.
|
|
661
|
+
`input` transporta o escopo fixo; `filterDefaults` preenche filtros que não vieram no estado.
|
|
@@ -103,6 +103,11 @@ um atalho, um arrastar, um item de menu.
|
|
|
103
103
|
| `disabled` | `boolean` | `false` | Desabilita o botão independentemente da execução em andamento. |
|
|
104
104
|
| `onSuccess` | `(data: TData) => void` | | Pós-sucesso (cache já invalidado pelo action.invalidates). |
|
|
105
105
|
| `onLoadingChange` | `(loading: boolean) => void` | | Informa início e fim da execução a quem coordena bloqueio entre várias actions. |
|
|
106
|
+
| `aria-label` | `string` | | Nome acessível completo quando o texto visível é abreviado. |
|
|
106
107
|
| `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. |
|
|
107
108
|
| `itemLabel` | `string` | | Nome do alvo na pergunta (sai entre aspas, em destaque, antes da mensagem do contrato). |
|
|
108
109
|
| `className` | `string` | | Classes do botão. O tamanho vem de `size` (escala única); com `icon`, o default é `icon-xs`. |
|
|
110
|
+
|
|
111
|
+
Quando `label` abrevia o texto visível, forneça `aria-label` com o nome completo da operação.
|
|
112
|
+
O nome acessível deve conter o texto visível; por exemplo, “Criar” e “Criar cliente”.
|
|
113
|
+
Presentation faz essa associação ao usar um rótulo contextual no comando.
|
|
@@ -32,8 +32,8 @@ há texto visível. O glifo dentro do controle acompanha o tamanho (0.875rem em
|
|
|
32
32
|
| Nome | Medida | Uso |
|
|
33
33
|
| --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
34
34
|
| `xs` | 1.5rem | Ação dentro de um campo (`InputGroupButton`). |
|
|
35
|
-
| `sm` | 2rem |
|
|
36
|
-
| `default` | 2.25rem |
|
|
35
|
+
| `sm` | 2rem | Criação de coleções e operações densas de toolbar ou seção. |
|
|
36
|
+
| `default` | 2.25rem | Headers, footers de Dialog e Drawer e controles comuns; é também a linha de `Input`. |
|
|
37
37
|
| `lg` | 2.5rem | Chamada principal com mais área de toque. |
|
|
38
38
|
| `icon-xs` | 1.5rem | Ação só de ícone dentro de um campo ou de uma linha densa; é o quadrado de `ActionTrigger` com `icon`. |
|
|
39
39
|
| `icon-sm` | 2rem | 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`. |
|
|
@@ -41,15 +41,14 @@ há texto visível. O glifo dentro do controle acompanha o tamanho (0.875rem em
|
|
|
41
41
|
| `icon-lg` | 2.5rem | Ação só de ícone ao lado de um `lg`. |
|
|
42
42
|
|
|
43
43
|
Escolha o tamanho pela região, não pela importância visual: `variant` e `context` resolvem a
|
|
44
|
-
hierarquia da ação. Headers de Page, Dialog, Drawer e Surface usam `
|
|
44
|
+
hierarquia da ação. Headers de Page, Dialog, Drawer e Surface usam `default`/`icon`. A criação
|
|
45
45
|
no cabeçalho de uma coleção usa `sm` textual, sem ícone. Footers de
|
|
46
46
|
[`Dialog`](/ui/dialog) e [`Drawer`](/ui/drawer) conservam `default`. Operações densas de toolbar ou de seção usam `sm`;
|
|
47
47
|
ações dentro de linha ou célula usam `xs` ou `icon-xs`. Assim a mesma decisão mantém a mesma altura
|
|
48
48
|
mesmo quando uma superfície troca uma ação secundária por uma primária.
|
|
49
49
|
|
|
50
|
-
O retorno de `PageBack` usa `icon
|
|
51
|
-
(`shape="pill"`), `neutral` e `subtle`, no quadrado `icon-
|
|
52
|
-
`closeSize="xs"`.
|
|
50
|
+
O retorno de `PageBack` usa `icon`. O fechamento de Dialog e Drawer é um `CloseButton` circular
|
|
51
|
+
(`shape="pill"`), `neutral` e `subtle`, no quadrado `icon-xs` (`closeSize="xs"`) por padrão.
|
|
53
52
|
|
|
54
53
|
```tsx preview
|
|
55
54
|
<Button size="xs">Mínimo</Button>
|
|
@@ -11,13 +11,21 @@ escolher um valor em um formulário, use [`Select`](/ui/select).
|
|
|
11
11
|
<CommandList>
|
|
12
12
|
<CommandEmpty>Nada encontrado.</CommandEmpty>
|
|
13
13
|
<CommandGroup heading="Sessões">
|
|
14
|
-
<CommandItem
|
|
15
|
-
|
|
14
|
+
<CommandItem>
|
|
15
|
+
<FolderGit2 /> Onboarding do faturamento
|
|
16
|
+
</CommandItem>
|
|
17
|
+
<CommandItem>
|
|
18
|
+
<FolderGit2 /> Integração com o ERP
|
|
19
|
+
</CommandItem>
|
|
16
20
|
</CommandGroup>
|
|
17
21
|
<CommandSeparator />
|
|
18
22
|
<CommandGroup heading="Ações">
|
|
19
|
-
<CommandItem
|
|
20
|
-
|
|
23
|
+
<CommandItem>
|
|
24
|
+
<Plus /> Criar sessão <CommandShortcut>⌘N</CommandShortcut>
|
|
25
|
+
</CommandItem>
|
|
26
|
+
<CommandItem>
|
|
27
|
+
<Play /> Iniciar ambiente
|
|
28
|
+
</CommandItem>
|
|
21
29
|
</CommandGroup>
|
|
22
30
|
</CommandList>
|
|
23
31
|
</Command>
|
|
@@ -26,23 +34,23 @@ escolher um valor em um formulário, use [`Select`](/ui/select).
|
|
|
26
34
|
## Paleta de comandos em modal
|
|
27
35
|
|
|
28
36
|
`CommandDialog` apresenta a mesma lista dentro de um [`Dialog`](/ui/dialog), com um cabeçalho
|
|
29
|
-
|
|
37
|
+
padrão que mostra o título e o botão de fechar. A descrição fica disponível somente para
|
|
30
38
|
tecnologias assistivas. O componente não registra atalho de teclado: para abrir a paleta com
|
|
31
39
|
⌘K, o aplicativo escuta o evento e altera `open`, como no exemplo.
|
|
32
40
|
|
|
33
41
|
```tsx preview
|
|
34
|
-
const [open, setOpen] = useState(false)
|
|
42
|
+
const [open, setOpen] = useState(false);
|
|
35
43
|
|
|
36
44
|
useEffect(() => {
|
|
37
45
|
const onKeyDown = (event: KeyboardEvent): void => {
|
|
38
|
-
if (event.key.toLowerCase() ===
|
|
39
|
-
event.preventDefault()
|
|
40
|
-
setOpen((current) => !current)
|
|
46
|
+
if (event.key.toLowerCase() === "k" && (event.metaKey || event.ctrlKey)) {
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
setOpen((current) => !current);
|
|
41
49
|
}
|
|
42
|
-
}
|
|
43
|
-
document.addEventListener(
|
|
44
|
-
return () => document.removeEventListener(
|
|
45
|
-
}, [])
|
|
50
|
+
};
|
|
51
|
+
document.addEventListener("keydown", onKeyDown);
|
|
52
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
53
|
+
}, []);
|
|
46
54
|
|
|
47
55
|
render(
|
|
48
56
|
<>
|
|
@@ -54,63 +62,67 @@ render(
|
|
|
54
62
|
<CommandList>
|
|
55
63
|
<CommandEmpty>Nada encontrado.</CommandEmpty>
|
|
56
64
|
<CommandGroup heading="IA">
|
|
57
|
-
<CommandItem onSelect={() => setOpen(false)}
|
|
58
|
-
|
|
65
|
+
<CommandItem onSelect={() => setOpen(false)}>
|
|
66
|
+
<Bot /> Chamar agente
|
|
67
|
+
</CommandItem>
|
|
68
|
+
<CommandItem onSelect={() => setOpen(false)}>
|
|
69
|
+
<Sparkles /> Importar skill
|
|
70
|
+
</CommandItem>
|
|
59
71
|
</CommandGroup>
|
|
60
72
|
</CommandList>
|
|
61
73
|
</CommandDialog>
|
|
62
74
|
</>,
|
|
63
|
-
)
|
|
75
|
+
);
|
|
64
76
|
```
|
|
65
77
|
|
|
66
78
|
## Propriedades de Command
|
|
67
79
|
|
|
68
|
-
| Propriedade
|
|
69
|
-
|
|
70
|
-
| `shouldFilter`
|
|
71
|
-
| `filter`
|
|
72
|
-
| `value`
|
|
73
|
-
| `onValueChange` | `(value: string) => void`
|
|
74
|
-
| `loop`
|
|
75
|
-
| `label`
|
|
76
|
-
| `className`
|
|
80
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
81
|
+
| --------------- | ---------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
82
|
+
| `shouldFilter` | `boolean` | `true` | Com `false`, desliga a filtragem e a ordenação automáticas; o aplicativo passa a renderizar somente os itens que correspondem à busca. |
|
|
83
|
+
| `filter` | `(value: string, search: string, keywords?: string[]) => number` | | Pontua cada item para a busca atual, de `0` (oculto) a `1` (melhor resultado). |
|
|
84
|
+
| `value` | `string` | | Item destacado no modo controlado. |
|
|
85
|
+
| `onValueChange` | `(value: string) => void` | | Chamado quando o item destacado muda. |
|
|
86
|
+
| `loop` | `boolean` | `false` | Faz as setas voltarem ao início ou ao fim da lista. |
|
|
87
|
+
| `label` | `string` | | Nome acessível do menu, sem exibição visual. |
|
|
88
|
+
| `className` | `string` | | Classes adicionais aplicadas à raiz. |
|
|
77
89
|
|
|
78
90
|
## Propriedades de CommandInput
|
|
79
91
|
|
|
80
|
-
| Propriedade
|
|
81
|
-
|
|
82
|
-
| `placeholder`
|
|
83
|
-
| `value`
|
|
84
|
-
| `onValueChange` | `(search: string) => void` |
|
|
85
|
-
| `disabled`
|
|
86
|
-
| `className`
|
|
92
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
93
|
+
| --------------- | -------------------------- | ------- | ------------------------------------------------------------------------ |
|
|
94
|
+
| `placeholder` | `string` | | Texto exibido enquanto a busca está vazia. |
|
|
95
|
+
| `value` | `string` | | Texto da busca no modo controlado. |
|
|
96
|
+
| `onValueChange` | `(search: string) => void` | | Chamado quando o texto da busca muda. |
|
|
97
|
+
| `disabled` | `boolean` | `false` | Desabilita o campo de busca. |
|
|
98
|
+
| `className` | `string` | | Classes adicionais aplicadas ao campo; o ícone de busca fica no wrapper. |
|
|
87
99
|
|
|
88
100
|
## Propriedades de CommandDialog
|
|
89
101
|
|
|
90
|
-
| Propriedade
|
|
91
|
-
|
|
92
|
-
| `open`
|
|
93
|
-
| `onOpenChange`
|
|
94
|
-
| `title`
|
|
95
|
-
| `description`
|
|
96
|
-
| `showCloseButton` | `boolean`
|
|
97
|
-
| `className`
|
|
102
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
103
|
+
| ----------------- | ------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------- |
|
|
104
|
+
| `open` | `boolean` | | Estado do modal no modo controlado. |
|
|
105
|
+
| `onOpenChange` | `(open: boolean) => void` | | Atualiza o estado do modal; pode ser conectado ao atalho do aplicativo. |
|
|
106
|
+
| `title` | `string` | `'Paleta de comandos'` | Título exibido no header padrão; também nomeia o diálogo para tecnologias assistivas. |
|
|
107
|
+
| `description` | `string` | `'Busque um comando para executar…'` | Descrição disponível somente para tecnologias assistivas. |
|
|
108
|
+
| `showCloseButton` | `boolean` | `true` | Exibe o botão de fechamento. |
|
|
109
|
+
| `className` | `string` | | Classes do conteúdo do diálogo, como a largura. |
|
|
98
110
|
|
|
99
111
|
## Propriedades de CommandItem
|
|
100
112
|
|
|
101
|
-
| Propriedade | Tipo
|
|
102
|
-
|
|
103
|
-
| `onSelect`
|
|
104
|
-
| `value`
|
|
105
|
-
| `keywords`
|
|
106
|
-
| `disabled`
|
|
113
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
114
|
+
| ----------- | ------------------------- | ------- | ----------------------------------------------------------------------------------------- |
|
|
115
|
+
| `onSelect` | `(value: string) => void` | | Chamado ao selecionar o item por clique ou teclado. |
|
|
116
|
+
| `value` | `string` | | Valor estável usado na busca e no destaque. Sem ele, o valor é inferido do texto do item. |
|
|
117
|
+
| `keywords` | `string[]` | | Termos adicionais considerados na busca. |
|
|
118
|
+
| `disabled` | `boolean` | `false` | Impede a seleção do item. |
|
|
107
119
|
|
|
108
120
|
## Propriedades de CommandGroup
|
|
109
121
|
|
|
110
|
-
| Propriedade | Tipo
|
|
111
|
-
|
|
112
|
-
| `heading`
|
|
113
|
-
| `value`
|
|
122
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
123
|
+
| ----------- | ----------------- | ------ | -------------------------------------------------------------------- |
|
|
124
|
+
| `heading` | `React.ReactNode` | | Título exibido acima dos itens do grupo. |
|
|
125
|
+
| `value` | `string` | | Identificador do grupo; obrigatório e único quando não há `heading`. |
|
|
114
126
|
|
|
115
127
|
`CommandList` limita a altura a `18.75rem` e rola o excedente; `CommandEmpty` aparece somente quando
|
|
116
128
|
nenhum item corresponde à busca; `CommandSeparator` divide grupos; e `CommandShortcut` mostra, à
|