@softize/opus 12.11.0 → 13.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 +29 -0
- package/bin/lib/check.mjs +2 -7
- package/bin/lib/copy.mjs +1 -5
- 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/radius-scale.md +1 -1
- package/package.json +1 -1
- 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/src/ui/components/patterns/confirm.tsx +140 -40
- package/src/ui/components/patterns/list.tsx +35 -40
- package/src/ui/components/patterns/page-state.tsx +2 -2
- package/src/ui/components/patterns/sidebar.tsx +26 -26
- package/src/ui/components/patterns/trigger.tsx +25 -22
- package/src/ui/components/primitives/alert.tsx +3 -3
- package/src/ui/components/primitives/dialog.tsx +196 -39
- package/src/ui/components/primitives/drawer.tsx +8 -5
- package/src/ui/components/primitives/empty.tsx +3 -3
- package/src/ui/components/primitives/item.tsx +3 -3
- package/src/ui/components/primitives/sonner.tsx +187 -8
- package/src/ui/docs/DocBrowser.tsx +102 -23
- 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 +28 -34
- package/src/ui/docs/content/action-list-dialog.md +11 -6
- package/src/ui/docs/content/action-list.md +64 -39
- package/src/ui/docs/content/action-trigger.md +21 -14
- package/src/ui/docs/content/action-view.md +8 -8
- 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/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 +5 -5
- package/src/ui/docs/content/card.md +1 -1
- package/src/ui/docs/content/carousel.md +16 -11
- package/src/ui/docs/content/chat.md +3 -3
- package/src/ui/docs/content/checkbox.md +7 -7
- package/src/ui/docs/content/cli.md +5 -5
- 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 +2 -2
- package/src/ui/docs/content/content.md +2 -2
- package/src/ui/docs/content/copyable.md +4 -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 +3 -3
- package/src/ui/docs/content/dialog.md +339 -31
- package/src/ui/docs/content/dictionary-value.md +8 -8
- package/src/ui/docs/content/dock.md +3 -3
- 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 +1 -1
- package/src/ui/docs/content/icon-picker.md +8 -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 +5 -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 +34 -16
- package/src/ui/docs/content/observability.md +2 -2
- package/src/ui/docs/content/page.md +51 -6
- package/src/ui/docs/content/pagination.md +22 -17
- package/src/ui/docs/content/popover.md +16 -8
- package/src/ui/docs/content/progress.md +7 -5
- 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 +42 -29
- package/src/ui/docs/content/separator.md +5 -5
- package/src/ui/docs/content/sidebar.md +323 -54
- package/src/ui/docs/content/skeleton.md +3 -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 +8 -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 +5 -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 +3 -3
- package/src/ui/docs/content/tooltip.md +19 -11
- package/src/ui/docs/content/truncate.md +7 -8
- package/src/ui/docs/content/ui.md +10 -9
- package/src/ui/docs/content/upgrading.md +7 -8
- package/src/ui/docs/registry.tsx +20 -37
- package/src/ui/meta.ts +64 -94
- package/src/ui/react.tsx +15 -16
- package/src/ui/theme.css +50 -0
- 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,13 +1,14 @@
|
|
|
1
1
|
## Fonte e resultado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Passe o texto em `content`. O exemplo mostra primeiro o resultado renderizado e, depois, o Markdown
|
|
4
|
+
que o produziu.
|
|
4
5
|
|
|
5
6
|
```tsx preview col 2xl
|
|
6
7
|
const sample = [
|
|
7
8
|
'# Markdown na Softize',
|
|
8
9
|
'',
|
|
9
10
|
'Renderiza **doc técnica** e mensagem de chat — `SKILL.md`, síntese de papel, resposta de agente.',
|
|
10
|
-
'O motor é o markdown-it, o
|
|
11
|
+
'O motor é o markdown-it, o mesmo que renderiza estas páginas.',
|
|
11
12
|
'',
|
|
12
13
|
'## Sintaxe coberta',
|
|
13
14
|
'',
|
|
@@ -18,7 +19,7 @@ const sample = [
|
|
|
18
19
|
'1. Primeiro passo',
|
|
19
20
|
'2. Segundo passo',
|
|
20
21
|
'',
|
|
21
|
-
'> Citação calma,
|
|
22
|
+
'> Citação calma, para o tom certo.',
|
|
22
23
|
'',
|
|
23
24
|
'---',
|
|
24
25
|
'',
|
|
@@ -33,9 +34,9 @@ render(<Markdown content={sample} />)
|
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## Propriedades de Markdown
|
|
37
38
|
|
|
38
|
-
|
|
|
39
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
39
40
|
|---|---|---|---|
|
|
40
|
-
| `content` | `string` | | O markdown cru (CommonMark + tabela GFM, via markdown-it). HTML no fonte é **escapado**, não interpretado — por isso serve
|
|
41
|
+
| `content` | `string` | | O markdown cru (CommonMark + tabela GFM, via markdown-it). HTML no fonte é **escapado**, não interpretado — por isso serve para texto vindo de gente ou de modelo. |
|
|
41
42
|
| `className` | `string` | | Classes do wrapper. |
|
|
@@ -4,10 +4,9 @@ title: MCP
|
|
|
4
4
|
|
|
5
5
|
# MCP
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
como o usuário resolvido). O MCP é só o transporte.
|
|
7
|
+
Use o servidor MCP para disponibilizar actions `ai:enabled` a agentes que executam fora da
|
|
8
|
+
aplicação. A chamada continua passando por `runtime.execute`, com a mesma validação, autorização e
|
|
9
|
+
auditoria; o MCP fornece apenas o transporte.
|
|
11
10
|
|
|
12
11
|
## Montar
|
|
13
12
|
|
|
@@ -22,23 +21,22 @@ const server = createOpusMcpServer(runtime, {
|
|
|
22
21
|
resolveContext: async (extra) => auth.resolveFromMcp(extra),
|
|
23
22
|
})
|
|
24
23
|
|
|
25
|
-
await server.connect(new StdioServerTransport()) // local; HTTP/SSE
|
|
24
|
+
await server.connect(new StdioServerTransport()) // local; HTTP/SSE para remoto
|
|
26
25
|
```
|
|
27
26
|
|
|
28
27
|
`ListTools` devolve as actions `ai:enabled` (nome + descrição + JSON Schema do input);
|
|
29
28
|
`CallTool` executa a action pelo `runtime.execute` — validação, auth (`ctx.can`) e audit,
|
|
30
29
|
tudo igual a uma chamada normal. Read-only? Marque só actions de leitura com `ai:enabled`.
|
|
31
30
|
|
|
32
|
-
##
|
|
31
|
+
## Escolher entre integração interna e MCP
|
|
33
32
|
|
|
34
|
-
- **
|
|
35
|
-
|
|
36
|
-
- **
|
|
37
|
-
|
|
33
|
+
- **Agente dentro da aplicação:** use `runtime.aiFor(base).run()` para chamar as actions no mesmo
|
|
34
|
+
processo.
|
|
35
|
+
- **Agente em outro serviço:** use MCP para oferecer a mesma coleção de ferramentas por uma
|
|
36
|
+
interface interoperável.
|
|
38
37
|
|
|
39
|
-
|
|
38
|
+
## Limites atuais
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
`destructive` sobre MCP (elicitation) entra quando um caso real cobrar; comece read-only.
|
|
40
|
+
O consumidor escolhe e monta o transporte, como stdio ou HTTP. A confirmação de actions destrutivas
|
|
41
|
+
ainda não faz parte desta integração; até que esse fluxo exista, exponha somente operações de
|
|
42
|
+
leitura.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
## Menu de ações
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`context="danger"`
|
|
3
|
+
Use `Menu` para reunir ações relacionadas em um painel ancorado. `MenuShortcut` posiciona o atalho à
|
|
4
|
+
direita; separe ações perigosas e declare `context="danger"` nelas.
|
|
5
5
|
|
|
6
6
|
```tsx preview
|
|
7
7
|
<Menu>
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
</Menu>
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## Abrir pelo menu de contexto
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
um gatilho invisível `position: fixed` naquele ponto ancora o conteúdo.
|
|
22
|
+
Para abrir pelo clique direito, controle o estado do menu e use a posição do ponteiro como âncora.
|
|
23
|
+
Esse padrão substitui o antigo `ContextMenu` sem introduzir outra família de componentes.
|
|
25
24
|
|
|
26
25
|
```tsx preview
|
|
27
26
|
const [pos, setPos] = useState(null)
|
|
@@ -52,9 +51,10 @@ render(
|
|
|
52
51
|
)
|
|
53
52
|
```
|
|
54
53
|
|
|
55
|
-
## Seleção
|
|
54
|
+
## Seleção por checkbox ou radio
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
Use `MenuCheckboxItem` para opções independentes e `MenuRadioGroup` para escolhas mutuamente
|
|
57
|
+
exclusivas. O consumidor controla o estado nos dois casos.
|
|
58
58
|
|
|
59
59
|
```tsx preview
|
|
60
60
|
const [showArchived, setShowArchived] = useState(false)
|
|
@@ -93,7 +93,7 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
93
93
|
<MenuContent align="start">
|
|
94
94
|
<MenuItem><ExternalLink /> Abrir preview</MenuItem>
|
|
95
95
|
<MenuSub>
|
|
96
|
-
<MenuSubTrigger><ArrowDownAZ /> Mover
|
|
96
|
+
<MenuSubTrigger><ArrowDownAZ /> Mover para</MenuSubTrigger>
|
|
97
97
|
<MenuSubContent>
|
|
98
98
|
<MenuItem>Empresa X</MenuItem>
|
|
99
99
|
<MenuItem>Softize</MenuItem>
|
|
@@ -104,12 +104,30 @@ MenuSub aninha um nível; inset alinha itens sem ícone com os que têm.
|
|
|
104
104
|
</Menu>
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
##
|
|
107
|
+
## Propriedades de MenuItem
|
|
108
108
|
|
|
109
|
-
|
|
|
109
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
110
110
|
|---|---|---|---|
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
| `context` | `'neutral' \| 'danger'` | `'neutral'` | `danger` sinaliza uma ação com consequência perigosa. |
|
|
112
|
+
| `inset` | `boolean` | | Alinha um item sem ícone com os itens que possuem ícone. |
|
|
113
|
+
|
|
114
|
+
## Propriedades de MenuContent
|
|
115
|
+
|
|
116
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
117
|
+
|---|---|---|---|
|
|
118
|
+
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alinhamento do painel em relação ao gatilho. |
|
|
119
|
+
| `sideOffset` | `number` | `4` | Distância entre o gatilho e o painel. |
|
|
120
|
+
|
|
121
|
+
## Propriedades de MenuCheckboxItem
|
|
122
|
+
|
|
123
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `checked` | `boolean` | | Estado controlado do item. |
|
|
126
|
+
| `onCheckedChange` | `(checked: boolean) => void` | | Chamado quando a pessoa alterna o item. |
|
|
127
|
+
|
|
128
|
+
## Propriedades de MenuRadioGroup
|
|
129
|
+
|
|
130
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
131
|
+
|---|---|---|---|
|
|
132
|
+
| `value` | `string` | | Valor selecionado no grupo. |
|
|
133
|
+
| `onValueChange` | `(value: string) => void` | | Chamado quando a pessoa seleciona outro `MenuRadioItem`. |
|
|
@@ -4,8 +4,8 @@ title: Observabilidade
|
|
|
4
4
|
|
|
5
5
|
# Observabilidade
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Use `ObservabilityAdapter` para envolver actions e reactions em spans sem acoplar o core a um
|
|
8
|
+
fornecedor. O driver OpenTelemetry deixa backend, exporter e Collector sob controle do aplicativo.
|
|
9
9
|
|
|
10
10
|
## Driver OpenTelemetry
|
|
11
11
|
|
|
@@ -16,10 +16,9 @@ Uma navegação contextual para outra página pode ocupar `actions`, e tabs fica
|
|
|
16
16
|
recortes da mesma superfície. Canvas e outros workspaces espaciais imersivos podem usar um shell
|
|
17
17
|
próprio quando o cabeçalho reduzir a área útil ou duplicar controles persistentes da superfície.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
fontes independentes e uma falha parcial não deve ocultar as demais seções.
|
|
19
|
+
Estados integrais de carregamento, falha ou ausência são compostos no body com `PageState`,
|
|
20
|
+
detalhado abaixo. `Page` não recebe flags de dados: uma página pode agregar fontes independentes e
|
|
21
|
+
uma falha parcial não deve ocultar as demais seções.
|
|
23
22
|
|
|
24
23
|
```tsx preview col
|
|
25
24
|
render(
|
|
@@ -65,9 +64,44 @@ render(
|
|
|
65
64
|
)
|
|
66
65
|
```
|
|
67
66
|
|
|
68
|
-
##
|
|
67
|
+
## Estados integrais
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
Use `PageState` quando carregamento, falha ou ausência substituírem todo o conteúdo principal. Na
|
|
70
|
+
forma curta ele pode ser escrito como filho direto de `Page`, que cria o `PageBody`; na forma
|
|
71
|
+
explícita, coloque-o dentro de `PageBody`. O cabeçalho continua visível e o estado recebe composição,
|
|
72
|
+
altura e semântica acessível consistentes.
|
|
73
|
+
|
|
74
|
+
```tsx preview col
|
|
75
|
+
<Page title="Relatório">
|
|
76
|
+
<PageState
|
|
77
|
+
status="error"
|
|
78
|
+
title="Não foi possível carregar o relatório"
|
|
79
|
+
description="Tente novamente. Se o problema continuar, volte mais tarde."
|
|
80
|
+
action={<Button>Tentar novamente</Button>}
|
|
81
|
+
/>
|
|
82
|
+
</Page>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`loading` centraliza o `Spinner`; `error` compõe `Alert`; `empty` compõe `Empty`; e `ready` entrega
|
|
86
|
+
os filhos sem acrescentar uma superfície.
|
|
87
|
+
|
|
88
|
+
```tsx preview col
|
|
89
|
+
<Page title="Relatórios">
|
|
90
|
+
<PageState
|
|
91
|
+
status="empty"
|
|
92
|
+
title="Nenhum relatório"
|
|
93
|
+
description="Crie o primeiro relatório para começar."
|
|
94
|
+
action={<Button>Novo relatório</Button>}
|
|
95
|
+
/>
|
|
96
|
+
</Page>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Não use `PageState` para uma falha parcial. Se outra parte da página continua utilizável, mantenha o
|
|
100
|
+
estado na própria seção com `DataState`, `ActionView`, `ActionList` ou `Alert`.
|
|
101
|
+
|
|
102
|
+
## Propriedades de Page
|
|
103
|
+
|
|
104
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
71
105
|
| ------------- | ----------- | ----------- | ----------------------------------------------------------------------------------------------- |
|
|
72
106
|
| `title` | `string` | | O h1 da página. |
|
|
73
107
|
| `count` | `number` | | Total de itens ao lado do título (mono, esmaecido). |
|
|
@@ -75,3 +109,14 @@ render(
|
|
|
75
109
|
| `actions` | `ReactNode` | | Ações contextuais no extremo oposto do cabeçalho; em telas estreitas, ficam abaixo do contexto. |
|
|
76
110
|
| `className` | `string` | `max-w-7xl` | Classes do container para substituir o teto padrão de `80rem`. |
|
|
77
111
|
| `children` | `ReactNode` | | O body da página — espaçamento e diagramação são seus. |
|
|
112
|
+
|
|
113
|
+
## Propriedades de PageState
|
|
114
|
+
|
|
115
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
116
|
+
|---|---|---|---|
|
|
117
|
+
| `status` | `'loading' \| 'error' \| 'empty' \| 'ready'` | | Estado integral do conteúdo. |
|
|
118
|
+
| `title` | `ReactNode` | Texto seguro por estado | Situação reconhecível pela pessoa. |
|
|
119
|
+
| `description` | `ReactNode` | | Impacto ou próximo passo aplicável. |
|
|
120
|
+
| `icon` | `ReactNode` | Alerta no erro | Ícone decorativo do estado. |
|
|
121
|
+
| `action` | `ReactNode` | | Recuperação, seleção ou criação aplicável. |
|
|
122
|
+
| `children` | `ReactNode` | | Conteúdo renderizado somente em `ready`. |
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Navegação entre páginas
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
É o único paginador da casa: `ActionList` compõe esta primitiva no rodapé, na escala densa.
|
|
3
|
+
Componha `Pagination`, `PaginationContent` e um `PaginationItem` para cada link. `page` fornece o
|
|
4
|
+
número e o nome acessível; `isActive` identifica a página atual. Os controles mantêm altura fixa e
|
|
5
|
+
a largura cresce quando o número precisa de mais espaço. `ActionList` usa esta mesma primitiva no
|
|
6
|
+
rodapé.
|
|
8
7
|
|
|
9
8
|
```tsx preview
|
|
10
9
|
<Pagination>
|
|
@@ -30,7 +29,7 @@ colam. As setas seguem quadradas e já falam pt-BR; `label` localiza, `iconOnly`
|
|
|
30
29
|
|
|
31
30
|
## Números longos
|
|
32
31
|
|
|
33
|
-
A largura mínima é quadrada
|
|
32
|
+
A largura mínima é quadrada e cresce conforme o conteúdo. Na escala densa de um rodapé, ajuste por
|
|
34
33
|
`className` (`h-7 min-w-7 text-xs` nos números; `size-7` mais `iconClassName="size-3.5"` nas
|
|
35
34
|
setas com `iconOnly`).
|
|
36
35
|
|
|
@@ -61,7 +60,8 @@ setas com `iconOnly`).
|
|
|
61
60
|
|
|
62
61
|
## Com elipse
|
|
63
62
|
|
|
64
|
-
PaginationEllipsis
|
|
63
|
+
`PaginationEllipsis` marca, de forma decorativa e com `aria-hidden`, uma sequência de páginas que
|
|
64
|
+
não cabe na barra.
|
|
65
65
|
|
|
66
66
|
```tsx preview
|
|
67
67
|
<Pagination>
|
|
@@ -123,14 +123,19 @@ render(
|
|
|
123
123
|
)
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
##
|
|
126
|
+
## Propriedades de PaginationLink
|
|
127
127
|
|
|
128
|
-
|
|
|
128
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
129
129
|
|---|---|---|---|
|
|
130
|
-
| `page
|
|
131
|
-
| `isActive
|
|
132
|
-
| `href
|
|
133
|
-
| `size
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
| `page` | `number` | | Número usado como conteúdo, quando `children` não é informado, e no nome acessível “Página N”. |
|
|
131
|
+
| `isActive` | `boolean` | `false` | Marca a página atual com `aria-current="page"` e tratamento `outline`. |
|
|
132
|
+
| `href` | `string` | | Renderiza um `<a>`. Sem `href`, o componente usa `<button>` e aceita `onClick` e `disabled`. |
|
|
133
|
+
| `size` | `'default' \| 'sm' \| 'lg' \| 'icon' \| 'icon-sm' \| 'icon-xs'` | `'default'` | Escala herdada de `Button`. A largura mínima cresce para acomodar números longos. |
|
|
134
|
+
|
|
135
|
+
## Propriedades de PaginationPrevious e PaginationNext
|
|
136
|
+
|
|
137
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
138
|
+
|---|---|---|---|
|
|
139
|
+
| `label` | `string` | `'Página anterior'` ou `'Próxima página'` | Nome acessível e texto visível da ação. |
|
|
140
|
+
| `iconOnly` | `boolean` | `false` | Exibe somente a seta; `label` continua disponível para leitura assistiva. |
|
|
141
|
+
| `iconClassName` | `string` | | Classes aplicadas ao ícone da seta. |
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Painel ancorado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Popover` para apresentar conteúdo livre junto a um gatilho, sem abrir um modal.
|
|
4
|
+
`PopoverHeader` agrupa título e descrição; o restante do painel aceita formulários curtos ou
|
|
5
|
+
detalhes.
|
|
4
6
|
|
|
5
7
|
```tsx preview
|
|
6
8
|
<Popover>
|
|
@@ -23,7 +25,7 @@ PopoverHeader agrupa título e descrição; o corpo é livre (form curto, detalh
|
|
|
23
25
|
|
|
24
26
|
## Alinhamento
|
|
25
27
|
|
|
26
|
-
align posiciona o painel em relação ao gatilho
|
|
28
|
+
`align` posiciona o painel em relação ao gatilho e `sideOffset` define a distância entre eles.
|
|
27
29
|
|
|
28
30
|
```tsx preview
|
|
29
31
|
<Popover>
|
|
@@ -40,10 +42,16 @@ align posiciona o painel em relação ao gatilho; sideOffset afasta. O padrão (
|
|
|
40
42
|
</Popover>
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
##
|
|
45
|
+
## Propriedades de Popover
|
|
44
46
|
|
|
45
|
-
|
|
|
47
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
46
48
|
|---|---|---|---|
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
|
|
49
|
+
| `open` | `boolean` | | Estado no modo controlado. |
|
|
50
|
+
| `onOpenChange` | `(open: boolean) => void` | | Atualiza o estado para permitir abertura ou fechamento por código. |
|
|
51
|
+
|
|
52
|
+
## Propriedades de PopoverContent
|
|
53
|
+
|
|
54
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alinhamento do painel em relação ao gatilho. |
|
|
57
|
+
| `sideOffset` | `number` | `4` | Distância entre o gatilho e o painel. |
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Progresso determinado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `Progress` quando a tarefa informar uma porcentagem de conclusão. `value` aceita valores de 0 a
|
|
4
|
+
100 e anima o preenchimento a cada mudança. Sem valor, a barra permanece vazia.
|
|
4
5
|
|
|
5
6
|
```tsx preview col
|
|
6
7
|
<div className="w-full max-w-sm space-y-2">
|
|
@@ -14,7 +15,8 @@ value vai de 0 a 100 — o preenchimento anima a cada mudança. Sem value (ou nu
|
|
|
14
15
|
|
|
15
16
|
## Controlado
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Controle `value` externamente quando o progresso acompanhar uma tarefa em andamento. No exemplo,
|
|
19
|
+
cada clique avança uma etapa da sincronização.
|
|
18
20
|
|
|
19
21
|
```tsx preview col
|
|
20
22
|
const [step, setStep] = useState(40)
|
|
@@ -61,9 +63,9 @@ className compõe sobre o padrão: ajuste a altura no Progress e tinja o preench
|
|
|
61
63
|
</div>
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
##
|
|
66
|
+
## Propriedades de Progress
|
|
65
67
|
|
|
66
|
-
|
|
|
68
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
67
69
|
|---|---|---|---|
|
|
68
70
|
| `value` | `number \| null` | | O progresso de 0 a 100. O preenchimento anima a cada mudança; null/ausente deixa a barra vazia. |
|
|
69
71
|
| `className` | `string` | | Compõe sobre o padrão — ajuste a altura (h-1.5/h-3) ou tinja o indicador via [&_[data-slot=progress-indicator]]:bg-*. |
|
|
@@ -4,8 +4,8 @@ title: Filas
|
|
|
4
4
|
|
|
5
5
|
# Filas
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
Use uma action em background quando a operação não puder manter a requisição aberta. O
|
|
8
|
+
`QueueAdapter` enfileira o trabalho e devolve um `JobHandle` para acompanhamento pelo cliente.
|
|
9
9
|
|
|
10
10
|
## O contrato
|
|
11
11
|
|
|
@@ -44,7 +44,7 @@ const queue = bullmqQueue({ queue: new Queue('opus', { connection: { host: 'loca
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Redis-backed (durável, entre-processos, retries). Peers opcionais (`bullmq`, `ioredis`) só
|
|
47
|
-
|
|
47
|
+
para quem usa o driver.
|
|
48
48
|
|
|
49
49
|
## No runtime
|
|
50
50
|
|
|
@@ -82,7 +82,7 @@ Multiplicador exponencial diferente de 2 ou `maxMs` exige `backoffStrategy` cust
|
|
|
82
82
|
é rejeitado pelo driver em vez de ser silenciosamente ignorado. `timeout` permanece no
|
|
83
83
|
envelope para o worker aplicar, pois não é uma opção de execução do `Queue.add`.
|
|
84
84
|
|
|
85
|
-
## Limites
|
|
85
|
+
## Limites atuais
|
|
86
86
|
|
|
87
|
-
Driver hoje: `bullmq` (Redis). In-memory
|
|
87
|
+
Driver hoje: `bullmq` (Redis). In-memory para dev e outros backends (SQS, pg-boss…) entram
|
|
88
88
|
por reincidência.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## Escolha única
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use `RadioGroup` quando todas as opções mutuamente exclusivas precisarem permanecer visíveis. Cada
|
|
4
|
+
`RadioGroupItem` declara um `value` e deve estar associado a um `Label`. `defaultValue` define a
|
|
5
|
+
opção inicial no modo não controlado.
|
|
4
6
|
|
|
5
7
|
```tsx preview col-start
|
|
6
8
|
<RadioGroup defaultValue="balanced">
|
|
@@ -21,7 +23,7 @@ Cada RadioGroupItem tem um value; o item escolhido é o value do RadioGroup. def
|
|
|
21
23
|
|
|
22
24
|
## Controlado
|
|
23
25
|
|
|
24
|
-
value
|
|
26
|
+
Use `value` e `onValueChange` quando outro estado da aplicação também precisar acompanhar a escolha.
|
|
25
27
|
|
|
26
28
|
```tsx preview col-start
|
|
27
29
|
const [agent, setAgent] = useState('reviewer')
|
|
@@ -46,7 +48,8 @@ render(
|
|
|
46
48
|
|
|
47
49
|
## Item desabilitado
|
|
48
50
|
|
|
49
|
-
disabled
|
|
51
|
+
`disabled` em `RadioGroupItem` bloqueia somente aquela opção e atualiza o `Label` associado. Para
|
|
52
|
+
bloquear todas as opções, aplique `disabled` ao `RadioGroup`.
|
|
50
53
|
|
|
51
54
|
```tsx preview col-start
|
|
52
55
|
<RadioGroup defaultValue="empresa-x-web">
|
|
@@ -65,13 +68,18 @@ disabled num RadioGroupItem esmaece e tira a opção da escolha; o Label em par
|
|
|
65
68
|
</RadioGroup>
|
|
66
69
|
```
|
|
67
70
|
|
|
68
|
-
##
|
|
71
|
+
## Propriedades de RadioGroup
|
|
69
72
|
|
|
70
|
-
|
|
|
73
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
71
74
|
|---|---|---|---|
|
|
72
|
-
| `value
|
|
73
|
-
| `onValueChange
|
|
74
|
-
| `defaultValue
|
|
75
|
-
| `disabled
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
| `value` | `string` | | Opção escolhida no modo controlado. Use com `onValueChange`. |
|
|
76
|
+
| `onValueChange` | `(value: string) => void` | | Chamado quando a pessoa escolhe outra opção. |
|
|
77
|
+
| `defaultValue` | `string` | | Opção inicial no modo não controlado. |
|
|
78
|
+
| `disabled` | `boolean` | `false` | Desabilita todo o grupo. |
|
|
79
|
+
|
|
80
|
+
## Propriedades de RadioGroupItem
|
|
81
|
+
|
|
82
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
83
|
+
|---|---|---|---|
|
|
84
|
+
| `value` | `string` | | Valor que o item atribui ao grupo quando selecionado. |
|
|
85
|
+
| `disabled` | `boolean` | `false` | Desabilita somente este item; o `Label` associado acompanha o estado. |
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
##
|
|
1
|
+
## A URL como estado
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use o router do Opus em aplicações pequenas que precisam reagir à URL sem uma tabela de rotas.
|
|
4
|
+
`pushState`, `popstate` e `useSyncExternalStore` preservam links diretos, recarregamento e o botão
|
|
5
|
+
Voltar sem manter uma segunda cópia do destino atual.
|
|
4
6
|
|
|
5
7
|
```tsx
|
|
6
8
|
import { navigate, useSegments } from '@softize/opus/ui/react'
|
|
@@ -12,9 +14,10 @@ function App() {
|
|
|
12
14
|
}
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Limite do router
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
O router oferece leitura reativa da URL e `navigate`; o aplicativo decide o que renderizar. Ele não
|
|
20
|
+
inclui tabela de rotas, parâmetros tipados nem carregamento de dados.
|
|
18
21
|
|
|
19
22
|
A régua: se a sua tela precisa de casamento de padrão (`/users/:id/posts/:postId`), params tipados ou data loaders, o caso pede uma biblioteca de rotas, não isto. Um app de back-office com uma dúzia de destinos quase nunca precisa.
|
|
20
23
|
|
|
@@ -27,13 +30,15 @@ A régua: se a sua tela precisa de casamento de padrão (`/users/:id/posts/:post
|
|
|
27
30
|
| `useSearchParams()` | A querystring reativa — o lar natural do estado interno de uma seção (qual relatório está aberto, o recorte de uma lista). |
|
|
28
31
|
| `navigate(path, opts?)` | `pushState` + notifica. `{ replace: true }` troca a entrada corrente. |
|
|
29
32
|
|
|
30
|
-
##
|
|
33
|
+
## Comportamentos preservados
|
|
31
34
|
|
|
32
35
|
**Destino igual é no-op.** `navigate` resolve o destino com `new URL` e compara o `href` inteiro — não faz nada se você já está exatamente lá. Sem isso, clicar duas vezes no mesmo item do menu empilha entradas idênticas e o botão "voltar" não sai do lugar.
|
|
33
36
|
|
|
34
37
|
Comparar strings cruas parece bastar e não basta, em duas frentes. O **hash**: estando em `/a#secao`, `navigate('/a')` pareceria destino repetido e a âncora nunca sairia da URL. E o **encoding**: `window.location` devolve `/relatórios` como `/relat%C3%B3rios`, então a comparação crua nunca casa e cada clique empilha — bem no caso pt-BR, e no ``navigate(`/reports?report=${arquivo}`)`` com nome de arquivo acentuado.
|
|
35
38
|
|
|
36
|
-
**A notificação
|
|
39
|
+
**A notificação usa um evento do navegador.** Como `pushState` não dispara `popstate`, `navigate`
|
|
40
|
+
emite o evento explicitamente. Isso mantém listeners existentes e cópias diferentes do pacote
|
|
41
|
+
sincronizados pela mesma janela.
|
|
37
42
|
|
|
38
43
|
**`useSyncExternalStore`, não `useState`.** Ler `window.location` dentro de `useState`/`useEffect` sofre *tearing* no modo concurrent: dois componentes podem renderizar o mesmo commit com URLs diferentes. As cópias que este módulo substituiu faziam isso.
|
|
39
44
|
|
|
@@ -4,9 +4,8 @@ title: Agendador
|
|
|
4
4
|
|
|
5
5
|
# Agendador
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
e o runtime
|
|
9
|
-
execução). O contrato é o `SchedulerAdapter`.
|
|
7
|
+
Use um schedule para executar uma action por cron ou intervalo. O `SchedulerAdapter` registra o
|
|
8
|
+
agendamento e o runtime executa a action com provenance `schedule`, preservando sua rastreabilidade.
|
|
10
9
|
|
|
11
10
|
## O contrato
|
|
12
11
|
|
|
@@ -59,8 +58,8 @@ const runtime = createRuntime({
|
|
|
59
58
|
O runtime registra os schedules do domínio no `start()` e chama a action quando o tempo bate
|
|
60
59
|
— nada de disparar no handler.
|
|
61
60
|
|
|
62
|
-
## Limites
|
|
61
|
+
## Limites atuais
|
|
63
62
|
|
|
64
|
-
Driver hoje: `node-cron` (in-process — some se o processo cair;
|
|
63
|
+
Driver hoje: `node-cron` (in-process — some se o processo cair; em um cluster, cada nó
|
|
65
64
|
dispararia). Backends duráveis/distribuídos (BullMQ repeatable, Temporal…) entram por
|
|
66
65
|
reincidência.
|
|
@@ -4,7 +4,7 @@ Dê a altura ao ScrollArea (h-48) e ponha o conteúdo dentro — a barra vertica
|
|
|
4
4
|
|
|
5
5
|
```tsx preview col
|
|
6
6
|
const sessions = [
|
|
7
|
-
{ id: 'empresa-x-1842', title: 'Migrar billing
|
|
7
|
+
{ id: 'empresa-x-1842', title: 'Migrar billing para o novo schema', agent: 'developer' },
|
|
8
8
|
{ id: 'empresa-x-1839', title: 'Revisar handoff do checkout', agent: 'reviewer' },
|
|
9
9
|
{ id: 'empresa-x-1835', title: 'Redesenhar o painel de rotas', agent: 'designer' },
|
|
10
10
|
{ id: 'empresa-x-1830', title: 'Corrigir flaky no teste de webhook', agent: 'developer' },
|
|
@@ -30,7 +30,7 @@ render(
|
|
|
30
30
|
|
|
31
31
|
## Trilho horizontal
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Para rolar na horizontal, acrescente <ScrollBar orientation="horizontal" /> como filho e deixe o conteúdo em uma linha que não quebra (flex + w-max).
|
|
34
34
|
|
|
35
35
|
```tsx preview col
|
|
36
36
|
const skills = ['implement-opus-change', 'create-opus-action', 'test-opus-action', 'build-opus-ui', 'upgrade-opus']
|
|
@@ -80,10 +80,15 @@ render(
|
|
|
80
80
|
)
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
##
|
|
83
|
+
## Propriedades de ScrollArea
|
|
84
84
|
|
|
85
|
-
|
|
|
85
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
86
86
|
|---|---|---|---|
|
|
87
|
-
| `className
|
|
88
|
-
| `children
|
|
89
|
-
|
|
87
|
+
| `className` | `string` | | Classes que definem as dimensões da janela rolável. Sem uma dimensão limitada, não há conteúdo a recortar. |
|
|
88
|
+
| `children` | `React.ReactNode` | | Conteúdo da janela, incluindo uma `ScrollBar` horizontal quando necessária. |
|
|
89
|
+
|
|
90
|
+
## Propriedades de ScrollBar
|
|
91
|
+
|
|
92
|
+
| Propriedade | Tipo | Padrão | Descrição |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `orientation` | `'vertical' \| 'horizontal'` | `'vertical'` | Direção da barra. A barra vertical já faz parte de `ScrollArea`. |
|