@softize/opus 12.11.0 → 13.1.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 +76 -0
- package/PROMOTED.md +46 -0
- package/README.md +28 -19
- package/bin/cli.mjs +87 -216
- package/bin/lib/check.mjs +2 -7
- package/bin/lib/cli-shared.mjs +131 -0
- package/bin/lib/copy.mjs +1 -5
- package/bin/lib/db.mjs +16 -74
- package/bin/lib/gen-openapi.mjs +3 -3
- package/bin/lib/gen-runner.mjs +1 -1
- package/bin/lib/gen.mjs +14 -69
- package/bin/lib/mcp.mjs +3 -1
- package/bin/lib/seed.mjs +5 -62
- package/docs/adr/0005-structural-surfaces-share-an-explicit-anatomy.md +93 -10
- package/docs/adr/0007-toast-actions-form-an-ordered-collection.md +63 -0
- package/docs/adr/0008-hierarchical-navigation-is-composed-at-the-consumer-boundary.md +71 -0
- package/docs/ownership-vs-shadcn-lock.md +2 -3
- package/docs/protocol.md +7 -7
- package/docs/radius-scale.md +1 -1
- package/docs/releasing.md +8 -2
- package/package.json +7 -3
- package/registry/skills/maintain-opus-docs/SKILL.md +83 -0
- package/registry/skills/maintain-opus-docs/agents/openai.yaml +4 -0
- package/registry/skills/maintain-opus-docs/references/editorial-standard.md +85 -0
- package/registry/skills/maintain-opus-docs/references/evaluations.md +34 -0
- package/registry/skills/maintain-opus-docs/scripts/audit-docs.mjs +81 -0
- package/registry/templates/app/package.json +1 -1
- package/registry/templates/app/src/main.tsx +4 -4
- package/src/audit/drivers/console.ts +1 -0
- package/src/auth/drivers/better-auth.ts +1 -0
- package/src/auth/drivers/jwt.ts +1 -0
- package/src/cache/drivers/memory.ts +1 -0
- package/src/client/drivers/fetch.ts +2 -1
- package/src/core/actions.ts +6 -1
- package/src/core/audit.ts +9 -3
- package/src/core/contracts.ts +7 -0
- package/src/core/domain.ts +1 -1
- package/src/core/errors.ts +18 -15
- package/src/core/index.ts +4 -2
- package/src/core/package-version.ts +26 -0
- package/src/core/reactions.ts +1 -1
- package/src/core/runtime.ts +33 -23
- package/src/core/schedules.ts +1 -1
- package/src/core/types.ts +2 -2
- package/src/dsl/eval.ts +2 -2
- package/src/dsl/kysely.ts +2 -2
- package/src/dsl/loads.ts +1 -1
- package/src/dsl/parser.ts +5 -5
- package/src/events/drivers/mitt.ts +1 -0
- package/src/mcp/index.ts +2 -1
- package/src/observability/drivers/opentelemetry.ts +1 -0
- package/src/queue/drivers/bullmq.ts +3 -3
- package/src/scheduler/drivers/node-cron.ts +3 -2
- package/src/scheduler/every.ts +7 -7
- package/src/schema/openapi.ts +3 -3
- package/src/seed/index.ts +29 -0
- package/src/server/drivers/fastify.ts +5 -2
- package/src/server/drivers/node.ts +9 -6
- package/src/server/index.ts +3 -1
- package/src/storage/drivers/fs.ts +1 -0
- package/src/testing/index.ts +3 -3
- package/src/ui/components/patterns/confirm.tsx +142 -42
- package/src/ui/components/patterns/content-header.tsx +7 -1
- package/src/ui/components/patterns/data-state.tsx +1 -1
- package/src/ui/components/patterns/dock.tsx +20 -3
- package/src/ui/components/patterns/form.tsx +12 -8
- package/src/ui/components/patterns/list.tsx +36 -41
- package/src/ui/components/patterns/page-state.tsx +2 -2
- package/src/ui/components/patterns/page.tsx +19 -1
- package/src/ui/components/patterns/shell-nav.tsx +10 -3
- package/src/ui/components/patterns/sidebar.tsx +43 -32
- package/src/ui/components/patterns/trigger.tsx +39 -38
- package/src/ui/components/patterns/view.tsx +26 -17
- package/src/ui/components/primitives/alert.tsx +14 -8
- package/src/ui/components/primitives/ask.tsx +3 -3
- package/src/ui/components/primitives/badge.tsx +11 -6
- package/src/ui/components/primitives/breadcrumb.tsx +2 -2
- package/src/ui/components/primitives/button.tsx +16 -3
- package/src/ui/components/primitives/calendar.tsx +28 -2
- package/src/ui/components/primitives/carousel.tsx +3 -3
- package/src/ui/components/primitives/chat.tsx +1 -1
- package/src/ui/components/primitives/checkbox.tsx +1 -1
- package/src/ui/components/primitives/command.tsx +2 -2
- package/src/ui/components/primitives/control.ts +12 -0
- package/src/ui/components/primitives/copyable.tsx +1 -1
- package/src/ui/components/primitives/dialog.tsx +202 -40
- package/src/ui/components/primitives/dot.tsx +5 -0
- package/src/ui/components/primitives/drawer.tsx +18 -8
- package/src/ui/components/primitives/empty.tsx +3 -3
- package/src/ui/components/primitives/field.tsx +3 -3
- package/src/ui/components/primitives/icon-picker.tsx +3 -1
- package/src/ui/components/primitives/input-group.tsx +1 -1
- package/src/ui/components/primitives/input-otp.tsx +1 -1
- package/src/ui/components/primitives/input.tsx +2 -2
- package/src/ui/components/primitives/item.tsx +3 -3
- package/src/ui/components/primitives/progress.tsx +32 -3
- package/src/ui/components/primitives/radio-group.tsx +1 -1
- package/src/ui/components/primitives/resizable.tsx +3 -1
- package/src/ui/components/primitives/select.tsx +5 -5
- package/src/ui/components/primitives/slider.tsx +5 -1
- package/src/ui/components/primitives/sonner.tsx +190 -8
- package/src/ui/components/primitives/switch.tsx +1 -0
- package/src/ui/components/primitives/tabs.tsx +1 -0
- package/src/ui/components/primitives/textarea.tsx +1 -1
- package/src/ui/components/primitives/toggle.tsx +1 -1
- package/src/ui/components/primitives/tooltip.tsx +1 -0
- package/src/ui/docs/DocBrowser.tsx +102 -23
- package/src/ui/docs/changelog.tsx +1 -1
- package/src/ui/docs/content/accordion.md +22 -16
- package/src/ui/docs/content/action-form-card.md +8 -8
- package/src/ui/docs/content/action-form-dialog.md +9 -9
- package/src/ui/docs/content/action-form.md +37 -36
- package/src/ui/docs/content/action-list-dialog.md +11 -6
- package/src/ui/docs/content/action-list.md +73 -39
- package/src/ui/docs/content/action-trigger.md +29 -15
- package/src/ui/docs/content/action-view.md +17 -10
- package/src/ui/docs/content/actions.md +9 -9
- package/src/ui/docs/content/ai.md +3 -3
- package/src/ui/docs/content/alert.md +14 -12
- package/src/ui/docs/content/ask.md +11 -0
- package/src/ui/docs/content/aspect-ratio.md +4 -4
- package/src/ui/docs/content/audit.md +2 -2
- package/src/ui/docs/content/auth.md +3 -3
- package/src/ui/docs/content/avatar.md +34 -14
- package/src/ui/docs/content/badge.md +3 -3
- package/src/ui/docs/content/breadcrumb.md +13 -8
- package/src/ui/docs/content/button.md +81 -6
- package/src/ui/docs/content/calendar.md +18 -5
- package/src/ui/docs/content/card.md +27 -1
- package/src/ui/docs/content/carousel.md +16 -11
- package/src/ui/docs/content/chat.md +23 -3
- package/src/ui/docs/content/checkbox.md +7 -7
- package/src/ui/docs/content/cli.md +74 -22
- package/src/ui/docs/content/collapsible.md +8 -8
- package/src/ui/docs/content/command.md +16 -8
- package/src/ui/docs/content/composer.md +17 -2
- package/src/ui/docs/content/content.md +17 -2
- package/src/ui/docs/content/copyable.md +12 -3
- package/src/ui/docs/content/customization.md +5 -5
- package/src/ui/docs/content/cycle.md +3 -3
- package/src/ui/docs/content/data-state.md +11 -12
- package/src/ui/docs/content/data.md +26 -33
- package/src/ui/docs/content/detail.md +22 -4
- package/src/ui/docs/content/dialog.md +339 -31
- package/src/ui/docs/content/dictionary-value.md +17 -10
- package/src/ui/docs/content/dock.md +11 -3
- package/src/ui/docs/content/dot.md +8 -0
- package/src/ui/docs/content/drawer.md +27 -14
- package/src/ui/docs/content/empty-value.md +2 -2
- package/src/ui/docs/content/empty.md +19 -12
- package/src/ui/docs/content/events.md +4 -4
- package/src/ui/docs/content/field.md +34 -12
- package/src/ui/docs/content/getting-started.md +3 -3
- package/src/ui/docs/content/icon-picker.md +19 -4
- package/src/ui/docs/content/input-otp.md +20 -12
- package/src/ui/docs/content/input.md +121 -9
- package/src/ui/docs/content/item.md +27 -13
- package/src/ui/docs/content/kbd.md +19 -11
- package/src/ui/docs/content/label.md +12 -3
- package/src/ui/docs/content/log.md +4 -4
- package/src/ui/docs/content/markdown.md +7 -6
- package/src/ui/docs/content/mcp.md +13 -15
- package/src/ui/docs/content/menu.md +40 -16
- package/src/ui/docs/content/metric-card.md +13 -0
- package/src/ui/docs/content/observability.md +2 -2
- package/src/ui/docs/content/page.md +59 -6
- package/src/ui/docs/content/pagination.md +22 -17
- package/src/ui/docs/content/popover.md +22 -8
- package/src/ui/docs/content/progress.md +15 -16
- package/src/ui/docs/content/queue.md +5 -5
- package/src/ui/docs/content/radio-group.md +20 -12
- package/src/ui/docs/content/router.md +11 -6
- package/src/ui/docs/content/scheduler.md +4 -5
- package/src/ui/docs/content/scroll-area.md +12 -7
- package/src/ui/docs/content/select.md +47 -34
- package/src/ui/docs/content/semantic-context.md +2 -2
- package/src/ui/docs/content/separator.md +5 -5
- package/src/ui/docs/content/sidebar.md +329 -54
- package/src/ui/docs/content/skeleton.md +9 -2
- package/src/ui/docs/content/slider.md +8 -7
- package/src/ui/docs/content/spinner.md +8 -8
- package/src/ui/docs/content/split.md +29 -5
- package/src/ui/docs/content/storage.md +6 -8
- package/src/ui/docs/content/switch.md +8 -7
- package/src/ui/docs/content/table.md +13 -3
- package/src/ui/docs/content/tabs.md +28 -14
- package/src/ui/docs/content/testing.md +9 -11
- package/src/ui/docs/content/textarea.md +12 -4
- package/src/ui/docs/content/toast.md +47 -13
- package/src/ui/docs/content/toggle.md +75 -7
- package/src/ui/docs/content/tokens.md +7 -7
- package/src/ui/docs/content/tooltip.md +19 -11
- package/src/ui/docs/content/truncate.md +15 -8
- package/src/ui/docs/content/ui.md +24 -9
- package/src/ui/docs/content/upgrading.md +7 -8
- package/src/ui/docs/doc-client.tsx +5 -5
- package/src/ui/docs/doc.tsx +26 -14
- package/src/ui/docs/registry.tsx +25 -42
- package/src/ui/docs/standalone.tsx +2 -2
- package/src/ui/drivers/react.tsx +17 -12
- package/src/ui/lib/action-errors.ts +45 -0
- package/src/ui/lib/zod-pt-br.ts +31 -4
- package/src/ui/meta.ts +65 -95
- package/src/ui/react.tsx +17 -16
- package/src/ui/theme.css +60 -8
- package/src/vite/design.ts +6 -18
- package/src/ui/components/primitives/alert-dialog.tsx +0 -192
- package/src/ui/docs/content/alert-dialog.md +0 -73
- package/src/ui/docs/content/button-group.md +0 -71
- package/src/ui/docs/content/confirm.md +0 -120
- package/src/ui/docs/content/input-group.md +0 -79
- package/src/ui/docs/content/page-state.md +0 -45
- package/src/ui/docs/content/toggle-group.md +0 -81
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Um painel por vez
|
|
2
2
|
|
|
3
|
-
`type=single`
|
|
4
|
-
|
|
3
|
+
Use `type="single"` quando somente um painel deve permanecer aberto. Com `collapsible`, a pessoa
|
|
4
|
+
também pode fechar o painel atual; sem essa propriedade, um item permanece expandido.
|
|
5
|
+
`defaultValue` define o item inicialmente aberto no modo não controlado.
|
|
5
6
|
|
|
6
7
|
```tsx preview
|
|
7
8
|
<Accordion type="single" collapsible defaultValue="overview" className="w-full">
|
|
@@ -28,8 +29,8 @@ sempre fica um item expandido. `defaultValue` deixa o estado com o componente.
|
|
|
28
29
|
|
|
29
30
|
## Múltiplos abertos
|
|
30
31
|
|
|
31
|
-
`type=multiple`
|
|
32
|
-
array com os itens
|
|
32
|
+
Use `type="multiple"` quando os painéis puderem permanecer abertos ao mesmo tempo. Nesse modo,
|
|
33
|
+
`defaultValue` recebe um array com os itens inicialmente expandidos.
|
|
33
34
|
|
|
34
35
|
```tsx preview
|
|
35
36
|
<Accordion type="multiple" defaultValue={['skills', 'prompt']} className="w-full">
|
|
@@ -48,10 +49,10 @@ array com os itens abertos de saída.
|
|
|
48
49
|
</Accordion>
|
|
49
50
|
```
|
|
50
51
|
|
|
51
|
-
##
|
|
52
|
+
## Estado controlado
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
Use `value` e `onValueChange` quando outro elemento ou estado do aplicativo também precisar
|
|
55
|
+
controlar o painel aberto.
|
|
55
56
|
|
|
56
57
|
```tsx preview
|
|
57
58
|
const [open, setOpen] = React.useState('developer')
|
|
@@ -74,13 +75,18 @@ render(
|
|
|
74
75
|
)
|
|
75
76
|
```
|
|
76
77
|
|
|
77
|
-
##
|
|
78
|
+
## Propriedades de Accordion
|
|
78
79
|
|
|
79
|
-
|
|
|
80
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
80
81
|
|---|---|---|---|
|
|
81
|
-
| `type`
|
|
82
|
-
| `collapsible`
|
|
83
|
-
| `defaultValue`
|
|
84
|
-
| `value`
|
|
85
|
-
| `onValueChange`
|
|
86
|
-
|
|
82
|
+
| `type` | `'single' \| 'multiple'` | | `single` abre um painel por vez; `multiple` permite manter vários abertos. |
|
|
83
|
+
| `collapsible` | `boolean` | `false` | No modo `single`, permite fechar o item aberto. |
|
|
84
|
+
| `defaultValue` | `string \| string[]` | | Item ou itens inicialmente abertos no modo não controlado. |
|
|
85
|
+
| `value` | `string \| string[]` | | Item ou itens abertos no modo controlado. Use com `onValueChange`. |
|
|
86
|
+
| `onValueChange` | `(value) => void` | | Chamado quando a pessoa abre ou fecha um item. |
|
|
87
|
+
|
|
88
|
+
## Propriedades de AccordionItem
|
|
89
|
+
|
|
90
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
91
|
+
|---|---|---|---|
|
|
92
|
+
| `value` | `string` | | Identificador usado por `defaultValue` e `value` no `Accordion`. |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Formulário em uma seção
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Use `ActionFormCard` para apresentar um `ActionForm` como seção delimitada da página. O componente
|
|
4
|
+
aplica a estrutura e o espaçamento de `Card`, sem a faixa de ações de um modal. O título é opcional.
|
|
5
5
|
|
|
6
6
|
```tsx preview col md
|
|
7
7
|
<DocBrowserActionProvider>
|
|
@@ -14,11 +14,11 @@ faixa de modal). Pra estruturar uma seção da página como painel. O título é
|
|
|
14
14
|
</DocBrowserActionProvider>
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Propriedades de ActionFormCard
|
|
18
18
|
|
|
19
|
-
|
|
|
19
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
20
20
|
|---|---|---|---|
|
|
21
|
-
| `title` | `string` | | Título do
|
|
21
|
+
| `title` | `string` | | Título do cabeçalho. Sem ele, o card começa diretamente pelo corpo. |
|
|
22
22
|
| `description` | `string` | | Subtítulo opcional, abaixo do título. |
|
|
23
|
-
| `action / defaultValues / fieldOptions / submitLabel / onSuccess / onCancel` |
|
|
24
|
-
| `cardClassName` | `string` | | Classes
|
|
23
|
+
| `action / defaultValues / fieldOptions / submitLabel / onSuccess / onCancel` | Propriedades de `ActionForm` | | Mantêm o mesmo comportamento do formulário interno. |
|
|
24
|
+
| `cardClassName` | `string` | | Classes aplicadas à superfície do card. `className` continua sendo aplicado ao `<form>`. |
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Formulário em um modal
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Use `ActionFormDialog` quando o formulário precisar interromper o fluxo atual sem levar a pessoa
|
|
4
|
+
para outra página. O consumidor controla `open`; depois de uma execução bem-sucedida, o componente
|
|
5
|
+
fecha o modal. O cabeçalho e o rodapé permanecem visíveis enquanto os campos podem rolar.
|
|
6
6
|
|
|
7
7
|
```tsx preview
|
|
8
8
|
const [open, setOpen] = useState(false)
|
|
@@ -22,11 +22,11 @@ render(
|
|
|
22
22
|
)
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Propriedades de ActionFormDialog
|
|
26
26
|
|
|
27
|
-
|
|
|
27
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
28
28
|
|---|---|---|---|
|
|
29
|
-
| `open / onOpenChange` | `boolean / (open: boolean) => void` | |
|
|
30
|
-
| `title / description` | `string` | |
|
|
29
|
+
| `open / onOpenChange` | `boolean / (open: boolean) => void` | | Estado controlado do modal. `onOpenChange(false)` é chamado no sucesso e ao cancelar. |
|
|
30
|
+
| `title / description` | `string` | | Conteúdo do cabeçalho; `description` é opcional. |
|
|
31
31
|
| `submitLabel` | `string` | `'Salvar'` | Resultado da ação principal. Em criação, informe `Criar {recurso}`; em edição, `Salvar alterações`. |
|
|
32
|
-
| `…ActionFormProps` | `action, defaultValues, onSuccess, fieldOptions…` | |
|
|
32
|
+
| `…ActionFormProps` | `action, defaultValues, onSuccess, fieldOptions…` | | Demais propriedades repassadas ao `ActionForm` interno. |
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Formulário derivado do contrato
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Use `ActionForm` para gerar campos, validação e mensagens a partir de uma `FormAction`. Sem
|
|
4
|
+
`children`, o componente escolhe o controle adequado para cada campo e preserva a ordem declarada
|
|
5
|
+
no contrato. No exemplo, altere um valor para habilitar a ação principal.
|
|
6
6
|
|
|
7
7
|
```tsx preview col md
|
|
8
8
|
<DocBrowserActionProvider>
|
|
@@ -10,13 +10,12 @@ submit só habilita com mudança real (dirty).
|
|
|
10
10
|
</DocBrowserActionProvider>
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
## Composição
|
|
13
|
+
## Composição dos campos
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
invalidação
|
|
19
|
-
(quem diagrama usa grid/gap/space-y como quiser).
|
|
15
|
+
Passe `children` quando a disposição automática não atender ao formulário. Cada
|
|
16
|
+
`ActionFormField` mantém rótulo, ajuda, controle, obrigatoriedade e erro derivados do contrato;
|
|
17
|
+
o consumidor define apenas a grade, as condições e o espaçamento. Execução, validação, toast e
|
|
18
|
+
invalidação continuam sob responsabilidade de `ActionForm`.
|
|
20
19
|
|
|
21
20
|
```tsx preview col md
|
|
22
21
|
<DocBrowserActionProvider>
|
|
@@ -35,8 +34,8 @@ invalidação) continua encapsulado — e o espaçamento é 100% seu: o campo n
|
|
|
35
34
|
|
|
36
35
|
## Valores iniciais e rótulos
|
|
37
36
|
|
|
38
|
-
defaultValues
|
|
39
|
-
|
|
37
|
+
`defaultValues` preenche o formulário para edição. `submitLabel` e `cancelLabel` nomeiam as ações;
|
|
38
|
+
`onCancel` devolve ao consumidor a decisão de fechar um painel ou navegar para outra página.
|
|
40
39
|
|
|
41
40
|
```tsx preview col md
|
|
42
41
|
<DocBrowserActionProvider>
|
|
@@ -51,47 +50,50 @@ quem orquestra (fechar drawer, voltar…).
|
|
|
51
50
|
|
|
52
51
|
## Pré-requisitos
|
|
53
52
|
|
|
54
|
-
|
|
55
|
-
canônico).
|
|
53
|
+
Monte os providers de consulta e execução uma vez na raiz do aplicativo:
|
|
56
54
|
|
|
57
55
|
```tsx
|
|
58
56
|
/* main.tsx do app. */
|
|
59
57
|
<QueryClientProvider client={queryClient}>
|
|
60
|
-
<
|
|
58
|
+
<OpusProvider client={apiClient}>
|
|
61
59
|
<App />
|
|
62
|
-
</
|
|
60
|
+
</OpusProvider>
|
|
63
61
|
</QueryClientProvider>
|
|
64
62
|
```
|
|
65
63
|
|
|
66
|
-
##
|
|
64
|
+
## useFormAction
|
|
67
65
|
|
|
68
|
-
|
|
66
|
+
`ActionForm` é uma composição sobre `useFormAction(action, { defaultValues, onSuccess, onError })`,
|
|
67
|
+
que devolve o `form` do react-hook-form já com o resolver Zod em pt-BR, `submit`, `isLoading`,
|
|
68
|
+
`error`, `isSuccess` e `reset`. Use o hook direto quando o formulário precisar de um layout ou de um
|
|
69
|
+
ciclo de vida que o pattern não cobre; validação e execução continuam iguais.
|
|
70
|
+
|
|
71
|
+
## Propriedades de ActionForm
|
|
72
|
+
|
|
73
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
69
74
|
|---|---|---|---|
|
|
70
75
|
| `action` | `FormContract<TInput, TData>` | | O contrato da FormAction — dele saem campos (input Zod + fields), mensagens e invalidação de cache. |
|
|
71
76
|
| `defaultValues` | `Partial<TInput>` | | Valores iniciais — o modo edição de um update/patch. |
|
|
72
77
|
| `onSuccess` | `(data: TData) => void` | | Pós-sucesso (o toast e a invalidação de cache já aconteceram). |
|
|
73
78
|
| `submitLabel / cancelLabel / onCancel` | `string / string / () => void` | `'Salvar' / 'Cancelar'` | Rodapé do form — o Cancelar só aparece com onCancel. |
|
|
74
79
|
| `fieldOptions` | `Record<string, SelectOption[]>` | | Opções de runtime por campo (ex.: ids de skills) — sobrepõe as inferidas do z.enum. |
|
|
75
|
-
| `className / body / footer` | `string / (node) => node / (node) => node` | | className = classes do `<form>`. body/footer =
|
|
76
|
-
| `children` | `ReactNode` | | Modo
|
|
80
|
+
| `className / body / footer` | `string / (node) => node / (node) => node` | | className = classes do `<form>`. body/footer = slots: recebem os campos / os botões e escolhem o invólucro — é como o ActionFormDialog injeta DialogBody/DialogFooter (scroll + faixa). |
|
|
81
|
+
| `children` | `ReactNode` | | Modo composição: diagrame com `<ActionFormField name />`. Sem children, o automático monta todos os campos na ordem do contrato. |
|
|
77
82
|
|
|
78
|
-
## ActionFormField
|
|
83
|
+
## Propriedades de ActionFormField
|
|
79
84
|
|
|
80
|
-
|
|
|
85
|
+
| Propriedade | Tipo | Descrição |
|
|
81
86
|
|---|---|---|
|
|
82
87
|
| `name` | `string` | O campo do contrato (chave em `fields`/schema). Fora do schema, não renderiza. |
|
|
83
88
|
| `options` | `SelectOption[]` | Opções por id de runtime — sobrepõe o fieldOptions do form e o z.enum. |
|
|
84
|
-
| `className` | `string` | Classes do invólucro (ex.: `col-span-2`
|
|
89
|
+
| `className` | `string` | Classes do invólucro (ex.: `col-span-2` em uma grid). |
|
|
85
90
|
|
|
86
|
-
##
|
|
91
|
+
## Origem das opções de seleção
|
|
87
92
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
`t.dict` no schema** (zero-config: campo `meuDict.zod()` — ou multiselect com elemento dict —
|
|
93
|
-
resolve value→label pela meta que viaja no contrato, sem registry) > **chaves cruas do
|
|
94
|
-
z.enum**. Campo texto com opções declaradas (runtime ou spec) vira single-select por-id.
|
|
93
|
+
As opções seguem esta precedência: `options` no campo, `fieldOptions` no formulário, `options` no
|
|
94
|
+
`FieldSpec`, metadata de `t.dict` no schema e, por último, as chaves de `z.enum`. Uma fonte mais
|
|
95
|
+
específica substitui as seguintes. Dicionários registrados no `OpusProvider` resolvem rótulos por
|
|
96
|
+
referência; itens estáticos permanecem como declarados no contrato.
|
|
95
97
|
|
|
96
98
|
## Widgets declarativos
|
|
97
99
|
|
|
@@ -103,11 +105,10 @@ escolha rica em card, com conteúdo de apoio; para uma lista textual comum, pref
|
|
|
103
105
|
Outros identificadores continuam válidos como metadado
|
|
104
106
|
para renderers próprios; o `ActionForm` aplica sua inferência normal quando não reconhece o widget.
|
|
105
107
|
|
|
106
|
-
## Controle
|
|
108
|
+
## Controle próprio com useActionFormContext
|
|
107
109
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
sem abandonar o `<ActionForm>`:
|
|
110
|
+
Quando nenhum widget atender ao campo, use `useActionFormContext` no modo de composição. O controle
|
|
111
|
+
próprio participa da mesma validação e execução sem abandonar o `ActionForm`:
|
|
111
112
|
|
|
112
113
|
```tsx
|
|
113
114
|
import { useActionFormContext } from '@softize/opus/ui/react'
|
|
@@ -132,4 +133,4 @@ function PermissionGrid() {
|
|
|
132
133
|
```
|
|
133
134
|
|
|
134
135
|
O contexto também expõe `shape` (Zod por campo), `fields` (FieldSpec) e `fieldOptions`.
|
|
135
|
-
Fora de um `<ActionForm>`, o hook
|
|
136
|
+
Fora de um `<ActionForm>`, o hook lança um erro que informa o provider ausente.
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Listagem em um modal
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `ActionListDialog` para consultar e apresentar uma `ListAction` sem sair do contexto atual. A
|
|
4
|
+
lista carrega ao abrir, refaz a consulta quando `input` muda e acompanha invalidações declaradas por
|
|
5
|
+
outras actions. O consumidor compõe os itens por `children`; o modal mantém os estados e a barra de
|
|
6
|
+
ações.
|
|
4
7
|
|
|
5
8
|
```tsx preview col
|
|
6
9
|
const [open, setOpen] = useState(false)
|
|
@@ -38,9 +41,11 @@ render(
|
|
|
38
41
|
)
|
|
39
42
|
```
|
|
40
43
|
|
|
41
|
-
##
|
|
44
|
+
## Estado adicional do consumidor
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
Quando o modal depender de outra consulta, `loading` combina esse carregamento ao estado da lista.
|
|
47
|
+
Use `empty` para substituir a regra de vazio, por exemplo enquanto um formulário de criação ocupa o
|
|
48
|
+
corpo do modal.
|
|
44
49
|
|
|
45
50
|
```tsx
|
|
46
51
|
<ActionListDialog
|
|
@@ -52,9 +57,9 @@ Dois escape hatches, pros casos em que o modal agrega mais de uma fonte: `loadin
|
|
|
52
57
|
/>
|
|
53
58
|
```
|
|
54
59
|
|
|
55
|
-
##
|
|
60
|
+
## Propriedades de ActionListDialog
|
|
56
61
|
|
|
57
|
-
|
|
|
62
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
58
63
|
|---|---|---|---|
|
|
59
64
|
| `action / input` | `ListAction / TInput` | | O contrato e os filtros — mudou o input, re-busca; `invalidates` de forms/triggers refaz sozinho. |
|
|
60
65
|
| `open / onOpenChange` | `boolean / (open) => void` | | Controle do modal — de quem orquestra. |
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Listagem derivada do contrato
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `ActionList` para apresentar uma coleção pesquisável descrita por uma `ListAction`. O contrato
|
|
4
|
+
define colunas, busca, filtros, período, ordenação e paginação; a interface materializa esses
|
|
5
|
+
recursos e envia o estado correspondente no input. Filtros avançados aparecem no modal “Filtros” e
|
|
6
|
+
os filtros aplicados permanecem visíveis como chips removíveis.
|
|
7
|
+
|
|
8
|
+
A barra se adapta ao espaço disponível. A busca cede largura primeiro e filtros que deixam de caber
|
|
9
|
+
migram para o modal; a linha só quebra quando nenhum controle restante puder ceder espaço.
|
|
4
10
|
|
|
5
11
|
```tsx preview col
|
|
6
12
|
render(
|
|
@@ -28,18 +34,16 @@ superfícies que não são listagens, como relatórios. O estado é controlado p
|
|
|
28
34
|
/>
|
|
29
35
|
```
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
somente quando declarados. Períodos incluem os presets do
|
|
35
|
-
contrato e o intervalo personalizado no mesmo calendário usado pela `ActionList`.
|
|
37
|
+
Seletores inline mantêm largura previsível (`w-40`; lookup e múltiplo usam `w-52`). Rótulos longos
|
|
38
|
+
são truncados no controle, mas permanecem completos na lista. No modal de filtros avançados, o
|
|
39
|
+
seletor ocupa toda a largura. Busca, filtros e período aparecem somente quando declarados.
|
|
36
40
|
|
|
37
41
|
## Colunas de dicionário
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
Quando o campo de saída usa `t.dict().zod()`, a coluna apresenta o valor com `DictionaryValue` e
|
|
44
|
+
respeita o papel declarado pelo dicionário. Classificações usam badge `outline`; status e estágio
|
|
45
|
+
usam badge tonal; `plain` e papéis ausentes permanecem como texto. Para um campo `string`, a coluna
|
|
46
|
+
pode indicar um dicionário registrado no provider:
|
|
43
47
|
`{ key: 'source', label: 'Fonte', dictionary: 'customerSource' }`. Dimensões independentes, como
|
|
44
48
|
tipo e estágio, ficam em colunas distintas — a leitura de comparação depende disso. `type:
|
|
45
49
|
'badge'` continua sendo o chip `outline` legado; com dicionário, ele mostra o rótulo em vez do
|
|
@@ -56,7 +60,8 @@ Renderer customizado reutiliza `EmptyValue`.
|
|
|
56
60
|
|
|
57
61
|
## Células custom (cells)
|
|
58
62
|
|
|
59
|
-
|
|
63
|
+
Use `cells` somente quando uma coluna precisar de apresentação própria, como link, composição ou
|
|
64
|
+
ação. A chave corresponde à `key` da coluna. Valores de dicionário não precisam desse override.
|
|
60
65
|
|
|
61
66
|
```tsx preview col
|
|
62
67
|
render(
|
|
@@ -78,9 +83,12 @@ render(
|
|
|
78
83
|
)
|
|
79
84
|
```
|
|
80
85
|
|
|
81
|
-
## Período
|
|
86
|
+
## Período obrigatório
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
Quando o contrato declara `periods`, a listagem sempre possui um recorte temporal. O preset marcado
|
|
89
|
+
com `default: true`, ou o primeiro da coleção, começa aplicado. Presets usam um valor relativo na
|
|
90
|
+
URL, como `?period=last7`; o padrão é omitido. Um intervalo personalizado usa diretamente as datas,
|
|
91
|
+
como `?period=2026-07-01..2026-07-07`, e chega ao handler pelos parâmetros `from` e `to`.
|
|
84
92
|
|
|
85
93
|
```tsx
|
|
86
94
|
periods: [
|
|
@@ -89,15 +97,23 @@ periods: [
|
|
|
89
97
|
{ value: 'thisMonth', label: 'Este mês' },
|
|
90
98
|
]
|
|
91
99
|
// Presets computáveis: today · yesterday · last7 · last30 · thisMonth · lastMonth.
|
|
100
|
+
// presetRange('last7') → { from: 'YYYY-MM-DD', to: 'YYYY-MM-DD' } — o mesmo cálculo do pattern.
|
|
92
101
|
```
|
|
93
102
|
|
|
94
|
-
## Paginação e
|
|
103
|
+
## Paginação e carregamento
|
|
95
104
|
|
|
96
|
-
|
|
105
|
+
`ActionList` envia `limit`, definido por `pageSize`, e `page` no input. O handler aplica o recorte e
|
|
106
|
+
devolve `total` na resposta paginada. Quando existe total, o rodapé mostra a página atual, os links
|
|
107
|
+
disponíveis e a quantidade de itens. Alterar busca, filtro, ordenação ou período retorna à primeira
|
|
108
|
+
página. Durante a primeira consulta, `DataState` apresenta o carregamento; em atualizações
|
|
109
|
+
posteriores, a lista permanece visível com `aria-busy`.
|
|
97
110
|
|
|
98
|
-
##
|
|
111
|
+
## Ações em lote
|
|
99
112
|
|
|
100
|
-
`batch`
|
|
113
|
+
`batch` acrescenta seleção à tabela. `can(item)` determina quais linhas podem participar: itens
|
|
114
|
+
inelegíveis não são selecionáveis, “Selecionar todos” inclui somente os elegíveis e `run` recebe
|
|
115
|
+
apenas essa seleção. Com `confirm`, o componente pede confirmação antes de executar. Ao concluir, a
|
|
116
|
+
seleção é limpa e a consulta é refeita.
|
|
101
117
|
|
|
102
118
|
```tsx
|
|
103
119
|
<ActionList action={runList} input={{}}
|
|
@@ -110,9 +126,12 @@ O pattern manda `limit` (= `pageSize`, default 50) e `page` no input; o handler
|
|
|
110
126
|
/>
|
|
111
127
|
```
|
|
112
128
|
|
|
113
|
-
##
|
|
129
|
+
## Outras visualizações
|
|
114
130
|
|
|
115
|
-
|
|
131
|
+
Uma coleção também pode aparecer como quadro, galeria, lista ou calendário. Cada entrada de `views`
|
|
132
|
+
fornece um `render`; `ActionList` preserva a mesma fonte de dados, filtros e estado na URL. Declare
|
|
133
|
+
`icon` para controles somente com ícone; sem ele, o rótulo permanece visível. A visualização
|
|
134
|
+
“Tabela” aparece quando existem colunas.
|
|
116
135
|
|
|
117
136
|
```tsx preview col
|
|
118
137
|
render(
|
|
@@ -146,13 +165,16 @@ render(
|
|
|
146
165
|
)
|
|
147
166
|
```
|
|
148
167
|
|
|
149
|
-
## Filtros dependentes
|
|
168
|
+
## Filtros dependentes e opções remotas
|
|
150
169
|
|
|
151
|
-
|
|
170
|
+
`FilterSpec` também cobre dependências, dicionários e consultas remotas:
|
|
152
171
|
|
|
153
|
-
- **`depends: ['outroFiltro']
|
|
154
|
-
|
|
155
|
-
- **`options: { kind: '
|
|
172
|
+
- **`depends: ['outroFiltro']`:** desabilita o filtro até que suas dependências tenham valor e o
|
|
173
|
+
limpa quando uma delas muda.
|
|
174
|
+
- **`options: { kind: 'dictionary', ref: 'sessionStatus' }`:** resolve opções e rótulos por um
|
|
175
|
+
dicionário registrado no `OpusProvider`. `filterOptions` substitui essa fonte quando informado.
|
|
176
|
+
- **`options: { kind: 'lookup', source: 'x.lookup' }`:** consulta uma action com `{ q }` e os valores
|
|
177
|
+
das dependências. A resposta segue o formato `{ value, label }`.
|
|
156
178
|
|
|
157
179
|
```tsx
|
|
158
180
|
filters: {
|
|
@@ -166,9 +188,12 @@ filters: {
|
|
|
166
188
|
}
|
|
167
189
|
```
|
|
168
190
|
|
|
169
|
-
## Exibição e URL
|
|
191
|
+
## Exibição e estado na URL
|
|
170
192
|
|
|
171
|
-
O botão de exibição
|
|
193
|
+
O botão de exibição abre as preferências da listagem em qualquer visualização. Na tabela, permite
|
|
194
|
+
mostrar ou ocultar colunas, inclusive as declaradas com `hidden`; em todas as visualizações, permite
|
|
195
|
+
alterar a quantidade de itens por página. Busca, ordenação, filtros, visualização, colunas e limite
|
|
196
|
+
podem ser serializados na query string pelos helpers do componente:
|
|
172
197
|
|
|
173
198
|
```tsx
|
|
174
199
|
<ActionList
|
|
@@ -181,9 +206,10 @@ O botão de exibição (engrenagem) abre o popover de configuração da listagem
|
|
|
181
206
|
|
|
182
207
|
Convenção compacta (defaults omitidos): `?q=…&sort=chave:dir&status=…&view=board&cols=a,b,c&limit=25`.
|
|
183
208
|
|
|
184
|
-
## Composição
|
|
209
|
+
## Composição dos itens
|
|
185
210
|
|
|
186
|
-
|
|
211
|
+
Passe `children` para substituir a tabela por uma composição própria. A barra de filtros e os
|
|
212
|
+
estados de carregamento, erro e vazio continuam sendo tratados por `ActionList`.
|
|
187
213
|
|
|
188
214
|
```tsx preview col
|
|
189
215
|
render(
|
|
@@ -209,30 +235,38 @@ render(
|
|
|
209
235
|
)
|
|
210
236
|
```
|
|
211
237
|
|
|
212
|
-
##
|
|
238
|
+
## Declaração na ListAction
|
|
213
239
|
|
|
214
240
|
| Chave | O que declara |
|
|
215
241
|
|---|---|
|
|
216
242
|
| `columns` | `{ key, label, type?, sortable?, fit?, hidden?, dateFormat?, dictionary?, empty? }` — a tabela. `hidden` fica fora (base do futuro column picker); `dictionary` nomeia o dicionário do provider; `empty` dá o significado da ausência. |
|
|
217
|
-
| `filters` | `{ [nome]: { label, type, options?, multiple?, advanced?, depends?, … } }` — a toolbar. `advanced` vai
|
|
243
|
+
| `filters` | `{ [nome]: { label, type, options?, multiple?, advanced?, depends?, … } }` — a toolbar. `advanced` vai para o modal; `depends` desabilita/cascateia; options `kind: 'lookup'` busca em uma action. Valor aplicado entra no input com o mesmo nome. |
|
|
218
244
|
| `text` | `{ fields }` — liga a busca; convenção: param `q` no input. Com período/filtros no contrato ela fica à direita; sendo a ÚNICA forma de recorte, abre a linha. |
|
|
219
245
|
| `sort` | `{ fields, default }` — ordenação inicial; header ordenável escreve `sort: 'chave:dir'`. |
|
|
220
246
|
| `periods` | `{ value, label }[]` — o controle de período (presets + Personalizado com calendário); materializa em `from`/`to` no input. |
|
|
221
247
|
|
|
222
|
-
##
|
|
248
|
+
## useListAction
|
|
249
|
+
|
|
250
|
+
Quando o layout não cabe no `ActionList`, `useListAction(action, input)` entrega o mesmo fetch
|
|
251
|
+
declarativo (`items`, `total`, `error`, `isLoading`, `isFetching`, `refetch`) sob o
|
|
252
|
+
`QueryClientProvider`, e `presetRange(preset)` materializa os presets de período (`today`, `last7`,
|
|
253
|
+
`thisMonth`…) em `{ from, to }` no formato `YYYY-MM-DD` — o mesmo cálculo que o pattern faz antes de
|
|
254
|
+
chamar a action.
|
|
255
|
+
|
|
256
|
+
## Propriedades de ActionList
|
|
223
257
|
|
|
224
|
-
|
|
|
258
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
225
259
|
|---|---|---|---|
|
|
226
260
|
| `action` | `ListAction<TInput, TItem>` | | A ListAction do Opus (kind list, output = item, paginate cursor). |
|
|
227
261
|
| `input` | `TInput` | | O ESCOPO BASE (ex.: { workspaceId }) — a toolbar soma por cima, nunca sobrescreve. |
|
|
228
262
|
| `cells` | `Record<string, (item) => ReactNode>` | | Células custom por cima das colunas do contrato (chave = column.key). |
|
|
229
|
-
| `filterOptions` | `Record<string, SelectOption[]>` | | Opções de runtime
|
|
263
|
+
| `filterOptions` | `Record<string, SelectOption[]>` | | Opções de runtime para os filtros select/lookup (chave = nome do filtro). |
|
|
230
264
|
| `columns` | `ActionListColumn<TItem>[]` | | Tabela EXPLÍCITA — sobrepõe as colunas do contrato (escape hatch). |
|
|
231
|
-
| `children` | `(items, refetch) => ReactNode` | | Modo
|
|
265
|
+
| `children` | `(items, refetch) => ReactNode` | | Modo composição: layout livre; a toolbar segue. Tem precedência sobre columns. |
|
|
232
266
|
| `batch` | `ActionListBatchAction[]` | | Ações em lote: `{ label, can?, run, confirm?, destructive? }` — liga a multi-seleção. |
|
|
233
|
-
| `rowId` | `(item) => string` | `item.id` | Identidade da linha
|
|
234
|
-
| `pageSize` | `number` | `50` | Itens por página
|
|
235
|
-
| `state / onStateChange` | `ActionListState / (next) => void` | interno | Estado da toolbar controlado —
|
|
267
|
+
| `rowId` | `(item) => string` | `item.id` | Identidade da linha para seleção. |
|
|
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
|
+
| `state / onStateChange` | `ActionListState / (next) => void` | interno | Estado da toolbar controlado — para quem embala sincronizar com a URL. |
|
|
236
270
|
| `emptyMessage` | `string` | `'Nenhum resultado.'` | O texto do estado vazio. |
|
|
237
|
-
| `onRowClick` | `(item: TItem) => void` | | Clique na linha (ex.: navegar
|
|
271
|
+
| `onRowClick` | `(item: TItem) => void` | | Clique na linha (ex.: navegar para o detalhe) — só na tabela. |
|
|
238
272
|
| `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`. |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Executar uma action
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Use `ActionTrigger` para executar uma `SimpleAction` a partir de um botão. Sem confirmação, o clique
|
|
4
|
+
inicia a operação, desabilita o controle durante a execução e apresenta as mensagens do contrato em
|
|
5
|
+
um toast. O rótulo padrão vem de `action.label`.
|
|
5
6
|
|
|
6
7
|
```tsx preview
|
|
7
8
|
<DocBrowserActionProvider>
|
|
@@ -11,8 +12,9 @@ Sem confirm, dispara no clique: desabilita enquanto roda e toca o toast do contr
|
|
|
11
12
|
|
|
12
13
|
## Confirmação declarada no contrato
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
Quando a action declara `confirm`, o componente monta o diálogo e aplica o contexto `danger` se a
|
|
16
|
+
operação for destrutiva. Use a propriedade `confirm` somente quando esta ocorrência precisar de uma
|
|
17
|
+
mensagem diferente da declarada no contrato.
|
|
16
18
|
|
|
17
19
|
```tsx preview
|
|
18
20
|
<DocBrowserActionProvider>
|
|
@@ -33,9 +35,11 @@ confirm: {
|
|
|
33
35
|
<ActionTrigger action={sessionDeleteContract} input={{ id: session.id }} />
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
##
|
|
38
|
+
## Ação somente com ícone
|
|
37
39
|
|
|
38
|
-
Com `icon`, o botão
|
|
40
|
+
Com `icon`, o botão exibe somente o ícone e usa `label`, ou `action.label`, no tooltip e no nome
|
|
41
|
+
acessível. O clique não aciona o item clicável ao redor. `itemLabel` identifica o registro na
|
|
42
|
+
mensagem de confirmação.
|
|
39
43
|
|
|
40
44
|
```tsx
|
|
41
45
|
<ActionTrigger
|
|
@@ -47,26 +51,36 @@ Com `icon`, o botão vira icon-only: o `label` (ou o `action.label`) migra pro t
|
|
|
47
51
|
/>
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
>
|
|
54
|
+
> `ActionTrigger` substitui o antigo `DeleteButton`. Ao migrar, declare `confirm` no contrato para
|
|
55
|
+
> preservar a confirmação que o componente anterior sempre apresentava.
|
|
51
56
|
|
|
52
57
|
## Erro que a pessoa entende
|
|
53
58
|
|
|
54
|
-
Quando a action falha,
|
|
59
|
+
Quando a action falha, uma mensagem do servidor substitui o texto genérico somente nos erros de
|
|
60
|
+
negócio `conflict`, `validation` e `not_found`:
|
|
55
61
|
|
|
56
62
|
> Este agente tem 3 conversas — desabilite em vez de excluir.
|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
Erros inesperados mantêm a mensagem genérica do contrato, evitando expor detalhes de banco ou
|
|
65
|
+
infraestrutura. O servidor registra o detalhe técnico para diagnóstico.
|
|
59
66
|
|
|
60
|
-
##
|
|
67
|
+
## useTriggerAction
|
|
61
68
|
|
|
62
|
-
|
|
69
|
+
`ActionTrigger` é uma composição sobre `useTriggerAction(action, { onSuccess, onError })`, que
|
|
70
|
+
devolve `trigger(input)`, `isLoading`, `error` e `reset`, e invalida o cache declarado em
|
|
71
|
+
`action.invalidates`. Use o hook direto quando a execução parte de um gesto que não é um botão —
|
|
72
|
+
um atalho, um arrastar, um item de menu.
|
|
73
|
+
|
|
74
|
+
## Propriedades de ActionTrigger
|
|
75
|
+
|
|
76
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
63
77
|
|---|---|---|---|
|
|
64
78
|
| `action` | `SimpleContract<TInput, TData>` | | A SimpleAction do Opus — label, messages e confirm vêm do contrato. |
|
|
65
79
|
| `input` | `TInput` | | O que a action recebe — geralmente { id }. |
|
|
66
80
|
| `label` | `string` | `action.label` | Sobrepõe o texto do botão. |
|
|
67
|
-
| `variant / size` | `
|
|
81
|
+
| `context / variant / size` | `do Button` | gatilho: `primary`/`solid`; `danger` quando a action é `destructive`; no modo ícone, `ghost` e `neutral` (ou `danger` se destrutiva) / `default` | Visual do gatilho; `context` explícito vence. O botão de confirmar é sempre `solid`: `danger` quando a action é `destructive`, senão a prop `context` do gatilho (ou `primary`). |
|
|
68
82
|
| `confirm` | `{ title, description?, actionLabel?, cancelLabel? }` | | Confirmação via prop — sobrepõe o ConfirmSpec do contrato. |
|
|
69
83
|
| `onSuccess` | `(data: TData) => void` | | Pós-sucesso (cache já invalidado pelo action.invalidates). |
|
|
70
|
-
| `icon` | `React.ReactNode` | | Torna o botão icon-only: rótulo no tooltip e no `aria-label`, clique que não vaza
|
|
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. |
|
|
71
85
|
| `itemLabel` | `string` | | Nome do alvo na pergunta (sai entre aspas, em destaque, antes da mensagem do contrato). |
|
|
72
|
-
| `className` | `string` | | Classes do botão (ex.: apertar o tamanho
|
|
86
|
+
| `className` | `string` | | Classes do botão (ex.: apertar o tamanho em uma linha densa). |
|