@softize/opus 18.2.0 → 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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,24 @@ Depois de qualquer bump, rode os gates (`typecheck` · `test` · `opus check` ·
7
7
  `opus copy --check` · `base copy check` · `manifest:check`) — eles apontam o que a
8
8
  mudança cobra do seu código.
9
9
 
10
+ ## 18.3.0 — 2026-09-17
11
+
12
+ `ActionList` passa a oferecer composição previsível para barras densas: filtros inline de valor
13
+ único abraçam o conteúdo até o limite da barra, a busca ocupa o espaço flexível restante, dropdowns
14
+ podem ser mais largos que o controle e filtros pesquisáveis podem omitir a opção vazia. Valores de
15
+ repouso, ícones por filtro, agrupamento de tipo de data com período e ícones nas seções avançadas
16
+ ficam declarados pelas props do pattern. A barra deixa de transformar filtros inline em chips por
17
+ falta de espaço; a página preserva sua largura mínima e delega o overflow à superfície correta.
18
+
19
+ Listagens podem usar `layout="fill"` para ocupar a altura disponível e manter a rolagem dentro da
20
+ tabela, com cabeçalho fixo e a mesma moldura nos estados vazio, carregando e erro. `Page` e
21
+ `Presentation` propagam esse contrato sem criar uma segunda rolagem no frame.
22
+
23
+ `MetricCard` aceita `secondaryMetric` para uma leitura complementar diretamente relacionada,
24
+ exibida como lâmina posterior com explicação própria. `FieldLegend` aceita ícone e a variante
25
+ `section`; o `Select` equaliza a ação de limpar com os demais campos e permite que sua lista cresça
26
+ além do gatilho sem alterar o layout.
27
+
10
28
  ## 18.2.0 — 2026-09-16
11
29
 
12
30
  `Presentation` passa a aceitar um body serializável baseado em componente. O contrato continua
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softize/opus",
3
- "version": "18.2.0",
3
+ "version": "18.3.0",
4
4
  "description": "End-to-end action protocol for TypeScript. Single package with subpath exports (core + adapters).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -37,8 +37,9 @@ existentes, mantendo navegação observável e componentes reutilizáveis sem la
37
37
  permanece sempre presente.
38
38
  6. Deixar ausência, paginação e largura de filtro com o pattern: célula e `DetailField` já
39
39
  representam valor ausente (`EmptyValue`, `empty` para o significado do domínio); listas
40
- paginam pela primitiva `Pagination`; selects inline de filtro têm largura fixa. Não reescrever
41
- esses defaults na tela.
40
+ paginam pela primitiva `Pagination`; selects inline de valor único abraçam o valor até o limite
41
+ definido pela barra, e o menu pode ser mais largo que o controle. Não reescrever esses defaults
42
+ na tela.
42
43
  7. Tratar página, filtro, seleção e modal importante como estado navegável por URL quando
43
44
  o produto precisa de deep link, back/forward ou refresh. Em `Presentation`, declarar `route`
44
45
  no artefato e deixar o adaptador apenas conectar a spec ao router da aplicação.
@@ -122,9 +122,10 @@ ContentDescription, ContentMeta, ContentActions) + ContentBody`. `ContentHeader`
122
122
  - Paginação é a primitiva `Pagination`, inclusive dentro de `ActionList`. Número de página tem
123
123
  largura mínima e cresce com os dígitos; só as setas são quadradas. Não montar paginador com
124
124
  `Button` nem prender números a `size-*`.
125
- - Select inline de filtro tem largura fixa (`w-40`; lookup e múltiplo `w-52`): a label trunca, o
126
- valor trunca no trigger e a opção inteira fica na lista. Não dimensionar filtro pelo conteúdo
127
- nem pela label; o modal usa `w-full`.
125
+ - Select inline de valor único abraça o valor selecionado até `max-w-80`. Acima desse limite, o
126
+ valor trunca no gatilho e a opção inteira permanece na lista, que pode ser mais larga.
127
+ Multiseleção mantém `w-52`; o modal usa `w-full`. Não recalcular essa largura na tela nem
128
+ dimensioná-la pela label do filtro.
128
129
  - Catálogo e API efetivos vêm dos exports da versão instalada, não de memória ou exemplo antigo.
129
130
  - Em componentes semânticos, `context` responde por que há destaque e `variant` responde como ele
130
131
  aparece. O vocabulário canônico é `neutral | primary | info | success | warning | danger`; as
@@ -93,7 +93,6 @@ class ActionErrorImpl extends Error implements ActionError {
93
93
  readonly i18nParams?: Record<string, unknown>
94
94
  readonly field?: string
95
95
  readonly issues?: ValidationIssue[]
96
- override readonly cause?: unknown
97
96
  readonly meta?: Record<string, unknown>
98
97
 
99
98
  constructor(input: ErrorInput) {
package/src/core/types.ts CHANGED
@@ -598,6 +598,10 @@ export interface FilterSpec {
598
598
 
599
599
  type: 'text' | 'select' | 'lookup' | 'date' | 'number'
600
600
  multiple?: boolean
601
+ /** Habilita busca local nas opções de um `select`; `lookup` já é pesquisável por natureza. */
602
+ searchable?: boolean
603
+ /** Quando `false`, a interface omite a opção vazia. Limpar restaura o default do filtro. */
604
+ allowEmpty?: boolean
601
605
  mode?: 'server' | 'client'
602
606
  operators?: FilterOp[]
603
607
  path?: string
@@ -75,7 +75,7 @@ export function DataState({
75
75
  if (colSpan !== undefined) {
76
76
  return (
77
77
  <tr data-slot="data-state" data-status={status}>
78
- <td colSpan={colSpan} className="px-4 py-4 text-center text-sm">
78
+ <td colSpan={colSpan} className="px-4 py-4 text-center align-middle text-sm">
79
79
  {surface}
80
80
  </td>
81
81
  </tr>