@softize/opus 18.1.1 → 18.3.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.
@@ -32,11 +32,20 @@ shell que efetivamente hospeda a rota.
32
32
  O exemplo declara a Presentation sobre um contrato de formulário e alterna a superfície. O
33
33
  `DocBrowserActionProvider` simula o cliente de actions; na aplicação, esse papel é do provider real.
34
34
 
35
+ Quando o recurso aceita assistência contextual, declare somente o gatilho serializável em
36
+ `assistant`. O renderer coloca esse gatilho no cabeçalho e abre o painel à direita do body da
37
+ própria Page, Dialog ou Drawer. Cabeçalho e rodapé continuam ocupando toda a largura da superfície;
38
+ enquanto o painel está aberto, o gatilho sai do cabeçalho e o próprio painel assume sua identidade
39
+ visual. O dado vivo do recurso não entra na definição: a página que o carregou fornece
40
+ `assistant.render`, captura identidade, nome e demais dados autorizados e monta o chat. Assim,
41
+ contexto de conversa não vira autorização nem dado persistido no manifest.
42
+
35
43
  ```tsx live
36
44
  const workspacePresentation = definePresentation({
37
45
  schemaVersion: 1,
38
46
  id: "workspace.create",
39
47
  title: "Criar workspace",
48
+ assistant: { triggerLabel: "Conversar sobre este workspace" },
40
49
  body: { action: docWorkspaceCreate.name },
41
50
  });
42
51
 
@@ -81,6 +90,22 @@ function Example() {
81
90
  if (next) setInvocation(next);
82
91
  else setOpen(false);
83
92
  }}
93
+ assistant={{
94
+ render: ({ close }) => (
95
+ <div className="flex h-full flex-col p-3">
96
+ <p className="text-sm">
97
+ Conversa vinculada ao workspace carregado pela página.
98
+ </p>
99
+ <Button
100
+ className="mt-3 self-start"
101
+ variant="ghost"
102
+ onClick={close}
103
+ >
104
+ Fechar
105
+ </Button>
106
+ </div>
107
+ ),
108
+ }}
84
109
  />
85
110
  </div>
86
111
  </DocBrowserActionProvider>
@@ -164,21 +189,22 @@ no manifest e concentre a inspeção na Lens em vez de criar um launcher flutuan
164
189
 
165
190
  ## Propriedades de Presentation
166
191
 
167
- | Propriedade | Tipo | Padrão | Descrição |
168
- | -------------------- | ------------------------------------------------ | ------ | ------------------------------------------------------ |
169
- | `definition` | `PresentationDefinition` | | Artefato estático que descreve o recurso. |
170
- | `definitions` | `PresentationDefinition[]` | | Registry alcançável por navegação, abertura e retorno. |
171
- | `actions` | `PresentationActionRegistry` | | Contratos compartilháveis referenciados pelo artefato. |
172
- | `invocation` | `PresentationInvocation` | | Surface, input e pilha da exibição atual. |
173
- | `bindingContext` | `PresentationBindingContext` | | Rota, item, seleção, sessão e resultado disponíveis. |
174
- | `onInvocationChange` | `(next: PresentationInvocation \| null) => void` | | Recebe navegação, retorno e fechamento. |
175
- | `onRefresh` | `(action: string \| null) => void` | | Recebe invalidações declaradas após sucesso. |
176
- | `listState` | `ActionListState` | | Recorte controlado da action `list` do body, quando a aplicação o sincroniza com a URL. |
192
+ | Propriedade | Tipo | Padrão | Descrição |
193
+ | -------------------- | ------------------------------------------------ | ------ | --------------------------------------------------------------------------------------------------- |
194
+ | `definition` | `PresentationDefinition` | | Artefato estático que descreve o recurso. |
195
+ | `definitions` | `PresentationDefinition[]` | | Registry alcançável por navegação, abertura e retorno. |
196
+ | `actions` | `PresentationActionRegistry` | | Contratos compartilháveis referenciados pelo artefato. |
197
+ | `invocation` | `PresentationInvocation` | | Surface, input e pilha da exibição atual. |
198
+ | `bindingContext` | `PresentationBindingContext` | | Rota, item, seleção, sessão e resultado disponíveis. |
199
+ | `assistant` | `PresentationAssistantRuntime` | | Painel contextual fornecido pela superfície hospedeira. |
200
+ | `onInvocationChange` | `(next: PresentationInvocation \| null) => void` | | Recebe navegação, retorno e fechamento. |
201
+ | `onRefresh` | `(action: string \| null) => void` | | Recebe invalidações declaradas após sucesso. |
202
+ | `listState` | `ActionListState` | | Recorte controlado da action `list` do body, quando a aplicação o sincroniza com a URL. |
177
203
  | `onListStateChange` | `(state: ActionListState) => void` | | Recebe cada mudança de recorte ou exibição da lista do body, como busca, filtros, período e página. |
178
- | `open` | `boolean` | `true` | Estado controlado de Dialog ou Drawer. |
179
- | `onOpenChange` | `(open: boolean) => void` | | Notifica abertura e fechamento da superfície modal. |
180
- | `className` | `string` | | Classes adicionais da superfície. |
181
- | `bodyClassName` | `string` | | Classes adicionais do body, aplicadas uma única vez. |
204
+ | `open` | `boolean` | `true` | Estado controlado de Dialog ou Drawer. |
205
+ | `onOpenChange` | `(open: boolean) => void` | | Notifica abertura e fechamento da superfície modal. |
206
+ | `className` | `string` | | Classes adicionais da superfície. |
207
+ | `bodyClassName` | `string` | | Classes adicionais do body, aplicadas uma única vez. |
182
208
 
183
209
  ## Propriedades de PresentationInspector
184
210
 
@@ -24,6 +24,10 @@ render(
24
24
  )
25
25
  ```
26
26
 
27
+ O gatilho respeita a largura definida pelo contexto. Ao abrir, a lista usa essa largura como mínimo
28
+ e pode crescer até `32rem` para preservar rótulos maiores sem alterar o layout do formulário ou da
29
+ toolbar. Rótulos que ultrapassarem esse limite continuam truncados como proteção de layout.
30
+
27
31
  ## Lista pesquisável
28
32
 
29
33
  Use `searchable` quando a quantidade ou os rótulos dificultarem encontrar uma opção. O gatilho
@@ -12,11 +12,13 @@ render(
12
12
  <div className="p-4 text-sm">Navegação</div>
13
13
  </Pane>
14
14
  <Pane grow inset="lg">
15
- <p className="text-sm text-muted-foreground">Conteúdo. Arraste a divisória.</p>
15
+ <p className="text-sm text-muted-foreground">
16
+ Conteúdo. Arraste a divisória.
17
+ </p>
16
18
  </Pane>
17
19
  </Split>
18
20
  </div>,
19
- )
21
+ );
20
22
  ```
21
23
 
22
24
  ## Espaçamento interno
@@ -30,8 +32,12 @@ Quando uma área precisa continuar legível em telas largas, use uma unidade abs
30
32
 
31
33
  ```tsx
32
34
  <Split resizable>
33
- <Pane grow inset="none"><Main /></Pane>
34
- <Pane initialSize="28rem" minSize="20rem" inset="none"><Inspector /></Pane>
35
+ <Pane grow inset="none">
36
+ <Main />
37
+ </Pane>
38
+ <Pane initialSize="28rem" minSize="20rem" inset="none">
39
+ <Inspector />
40
+ </Pane>
35
41
  </Split>
36
42
  ```
37
43
 
@@ -75,23 +81,78 @@ const defaultLayout = readLayout('workspace-layout')
75
81
 
76
82
  Em aplicações renderizadas no servidor, leia o armazenamento somente no cliente. `onLayoutChanged` também permite usar `sessionStorage` ou uma camada própria quando o layout precisa acompanhar outro escopo.
77
83
 
84
+ ## Assistência dentro da superfície
85
+
86
+ `SurfaceAssistant` especializa o split usado por uma Page, Dialog ou Drawer que abre assistência
87
+ contextual. O conteúdo principal permanece montado e o painel aparece à direita com largura
88
+ redimensionável. A superfície hospedeira controla o gatilho, o estado aberto e os dados passados ao
89
+ painel; o pattern cuida apenas da relação espacial. Envolva somente o body da superfície com
90
+ `SurfaceAssistant`: cabeçalho e rodapé devem permanecer fora do split e ocupar toda a largura.
91
+
92
+ ```tsx preview
93
+ function Example() {
94
+ const [open, setOpen] = React.useState(true);
95
+
96
+ return (
97
+ <div className="h-72 overflow-hidden rounded-lg border border-border">
98
+ <SurfaceAssistant
99
+ open={open}
100
+ assistantLabel="Assistente do pedido"
101
+ assistant={
102
+ <div className="h-full p-3">
103
+ <p className="text-sm">Conversa vinculada ao pedido carregado.</p>
104
+ <Button
105
+ className="mt-3"
106
+ variant="ghost"
107
+ onClick={() => setOpen(false)}
108
+ >
109
+ Fechar
110
+ </Button>
111
+ </div>
112
+ }
113
+ >
114
+ <div className="h-full p-3">
115
+ <Button variant="outline" onClick={() => setOpen(true)}>
116
+ Abrir assistente
117
+ </Button>
118
+ </div>
119
+ </SurfaceAssistant>
120
+ </div>
121
+ );
122
+ }
123
+
124
+ render(<Example />);
125
+ ```
126
+
78
127
  ## Propriedades de Split
79
128
 
80
- | Propriedade | Tipo | Padrão | Descrição |
81
- |---|---|---|---|
82
- | `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | Sentido em que os panes se alinham. |
83
- | `resizable` | `boolean` | `false` | Cada fronteira ganha um separador acessível e arrastável. |
84
- | `handle` | `boolean` | `false` | Mostra a alça visual no separador. |
85
- | `id` | `string` | | Identidade estável do grupo redimensionável. |
86
- | `defaultLayout` | `Record<string, number>` | | Layout percentual restaurado, indexado pelos ids dos panes. |
87
- | `onLayoutChanged` | `(layout, { isUserInteraction }) => void` | | Chamado ao concluir uma mudança de layout; persista onde fizer sentido. |
129
+ | Propriedade | Tipo | Padrão | Descrição |
130
+ | ----------------- | ----------------------------------------- | -------------- | ----------------------------------------------------------------------- |
131
+ | `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | Sentido em que os panes se alinham. |
132
+ | `resizable` | `boolean` | `false` | Cada fronteira ganha um separador acessível e arrastável. |
133
+ | `handle` | `boolean` | `false` | Mostra a alça visual no separador. |
134
+ | `id` | `string` | | Identidade estável do grupo redimensionável. |
135
+ | `defaultLayout` | `Record<string, number>` | | Layout percentual restaurado, indexado pelos ids dos panes. |
136
+ | `onLayoutChanged` | `(layout, { isUserInteraction }) => void` | | Chamado ao concluir uma mudança de layout; persista onde fizer sentido. |
88
137
 
89
138
  ## Propriedades de Pane
90
139
 
91
- | Propriedade | Tipo | Padrão | Descrição |
92
- |---|---|---|---|
93
- | `id` | `string` | | Identidade estável usada pelo layout redimensionável e persistido. |
94
- | `initialSize` | `number \| string` | | Tamanho inicial; número é porcentagem, string aceita `%`, `rem`, `em`, `vh`, `vw` e `px`. |
95
- | `minSize` / `maxSize` | `number \| string` | | Limites quando o split é redimensionável. |
96
- | `grow` | `boolean` | `false` | Ocupa o espaço remanescente no layout simples. |
97
- | `inset` | `'none' \| 'sm' \| 'md' \| 'lg'` | `'md'` | Respiro interno; `none` para chrome, navegação ou conteúdo com inset próprio. |
140
+ | Propriedade | Tipo | Padrão | Descrição |
141
+ | --------------------- | -------------------------------- | ------- | ----------------------------------------------------------------------------------------- |
142
+ | `id` | `string` | | Identidade estável usada pelo layout redimensionável e persistido. |
143
+ | `initialSize` | `number \| string` | | Tamanho inicial; número é porcentagem, string aceita `%`, `rem`, `em`, `vh`, `vw` e `px`. |
144
+ | `minSize` / `maxSize` | `number \| string` | | Limites quando o split é redimensionável. |
145
+ | `grow` | `boolean` | `false` | Ocupa o espaço remanescente no layout simples. |
146
+ | `inset` | `'none' \| 'sm' \| 'md' \| 'lg'` | `'md'` | Respiro interno; `none` para chrome, navegação ou conteúdo com inset próprio. |
147
+
148
+ ## Propriedades de SurfaceAssistant
149
+
150
+ | Propriedade | Tipo | Padrão | Descrição |
151
+ | ---------------- | ----------- | ------- | ------------------------------------------------------- |
152
+ | `open` | `boolean` | | Exibe o painel complementar à direita. |
153
+ | `assistantLabel` | `string` | | Nome acessível da região complementar. |
154
+ | `children` | `ReactNode` | | Conteúdo principal que permanece montado. |
155
+ | `assistant` | `ReactNode` | | Painel fornecido pela superfície que conhece o recurso. |
156
+ | `initialSize` | `PaneSize` | `28rem` | Largura inicial do painel. |
157
+ | `minSize` | `PaneSize` | `20rem` | Largura mínima durante o redimensionamento. |
158
+ | `maxSize` | `PaneSize` | `40rem` | Largura máxima durante o redimensionamento. |
package/src/ui/meta.ts CHANGED
@@ -81,7 +81,7 @@ export const componentMeta = {
81
81
  name: "metric-card",
82
82
  ancestry: "opus",
83
83
  whenToUse:
84
- "Medida resumida com rótulo, valor em destaque e descrição opcional. `context` realça semanticamente somente o ícone; aceita ação relacionada e estado de carregamento. O consumidor calcula e formata o valor; para conteúdo geral ou estrutura livre, use Card.",
84
+ "Medida resumida com rótulo, valor em destaque e descrição opcional. Use `secondaryMetric` para uma segunda leitura diretamente relacionada, exibida como lâmina posterior com explicação própria. `context` realça semanticamente somente o ícone; aceita ação relacionada e estado de carregamento. O consumidor calcula e formata os valores; para conteúdo geral ou estrutura livre, use Card.",
85
85
  },
86
86
  chat: {
87
87
  name: "chat",
@@ -321,7 +321,7 @@ export const componentMeta = {
321
321
  name: "split",
322
322
  ancestry: "opus",
323
323
  whenToUse:
324
- "Divide uma área em panes em sequência horizontal ou vertical. Use `resizable` quando a pessoa deve ajustar a fronteira; o mesmo `<Split>` vira flex simples sem ele. Cada `<Pane>` declara tamanho inicial/mínimo e inset. É o mecanismo espacial para sidebar, conteúdo e rail.",
324
+ "Divide uma área em panes em sequência horizontal ou vertical. Use `resizable` quando a pessoa deve ajustar a fronteira; o mesmo `<Split>` vira flex simples sem ele. Cada `<Pane>` declara tamanho inicial/mínimo e inset. SurfaceAssistant especializa esse layout para assistência contextual dentro de Page, Dialog ou Drawer.",
325
325
  },
326
326
  sidebar: {
327
327
  name: "sidebar",
package/src/ui/react.tsx CHANGED
@@ -105,6 +105,7 @@ export { MetricCard } from "./components/primitives/metric-card.tsx";
105
105
  export type {
106
106
  MetricCardProps,
107
107
  MetricCardContext,
108
+ MetricCardSecondaryMetric,
108
109
  MetricCardTone,
109
110
  } from "./components/primitives/metric-card.tsx";
110
111
 
@@ -424,6 +425,7 @@ export {
424
425
  PresentationInspector,
425
426
  } from "./components/patterns/presentation.tsx";
426
427
  export type {
428
+ PresentationAssistantRuntime,
427
429
  PresentationProps,
428
430
  PresentationInspectorProps,
429
431
  } from "./components/patterns/presentation.tsx";
@@ -483,6 +485,10 @@ export type {
483
485
  SplitLayoutChange,
484
486
  } from "./components/patterns/split.tsx";
485
487
 
488
+ // Assistência contextual: mantém o recurso visível e abre um painel redimensionável na superfície.
489
+ export { SurfaceAssistant } from "./components/patterns/surface-assistant.tsx";
490
+ export type { SurfaceAssistantProps } from "./components/patterns/surface-assistant.tsx";
491
+
486
492
  // A barra de ferramentas que flutua sobre uma superfície de trabalho (canvas, editor, preview).
487
493
  export {
488
494
  Dock,