@softize/opus 30.0.0 → 31.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/bin/lib/check.mjs +109 -101
  3. package/bin/lib/copy.mjs +2973 -1801
  4. package/docs/adr/0043-neutral-surfaces-and-interactions-use-opaque-role-tokens.md +52 -0
  5. package/docs/adr/0044-neutral-appearance-derives-from-bounded-axes-per-mode.md +27 -2
  6. package/docs/adr/0060-surface-composition-separates-chrome-and-intro.md +142 -0
  7. package/docs/adr/0064-action-list-com-itens-e-fontes-externas.md +47 -0
  8. package/docs/adr/0065-presentation-composes-settings-sections.md +295 -0
  9. package/docs/adr/0066-civil-date-input-and-calendar-list.md +28 -0
  10. package/docs/adr/README.md +6 -0
  11. package/package.json +1 -1
  12. package/registry/skills/build-opus-ui/SKILL.md +21 -19
  13. package/registry/skills/build-opus-ui/references/evaluations.md +13 -11
  14. package/registry/skills/build-opus-ui/references/ui-patterns.md +24 -27
  15. package/src/core/presentation.ts +938 -32
  16. package/src/core/types.ts +2 -0
  17. package/src/ui/components/patterns/form.tsx +22 -1
  18. package/src/ui/components/patterns/grouped-list.ts +2 -2
  19. package/src/ui/components/patterns/list-calendar.tsx +129 -0
  20. package/src/ui/components/patterns/list.tsx +612 -382
  21. package/src/ui/components/patterns/page-heading-context.tsx +12 -5
  22. package/src/ui/components/patterns/page.tsx +227 -197
  23. package/src/ui/components/patterns/presentation-fields.tsx +246 -0
  24. package/src/ui/components/patterns/presentation-sections.tsx +494 -0
  25. package/src/ui/components/patterns/presentation.tsx +1142 -229
  26. package/src/ui/components/patterns/structural-header.tsx +23 -32
  27. package/src/ui/components/patterns/surface-anatomy.ts +27 -217
  28. package/src/ui/components/patterns/surface.tsx +19 -29
  29. package/src/ui/components/patterns/trigger.tsx +10 -2
  30. package/src/ui/components/primitives/calendar.tsx +39 -18
  31. package/src/ui/components/primitives/close-button.tsx +11 -3
  32. package/src/ui/components/primitives/command.tsx +2 -8
  33. package/src/ui/components/primitives/date-input.tsx +276 -0
  34. package/src/ui/components/primitives/detail.tsx +1 -1
  35. package/src/ui/components/primitives/dialog.tsx +19 -81
  36. package/src/ui/components/primitives/drawer.tsx +17 -79
  37. package/src/ui/components/primitives/field.tsx +1 -1
  38. package/src/ui/components/primitives/pagination.tsx +3 -2
  39. package/src/ui/components/primitives/table.tsx +1 -1
  40. package/src/ui/components/primitives/tabs.tsx +13 -2
  41. package/src/ui/docs/content/action-form.md +6 -1
  42. package/src/ui/docs/content/action-list.md +156 -68
  43. package/src/ui/docs/content/action-trigger.md +5 -0
  44. package/src/ui/docs/content/button.md +5 -6
  45. package/src/ui/docs/content/calendar-month-view.md +50 -0
  46. package/src/ui/docs/content/calendar.md +6 -1
  47. package/src/ui/docs/content/command.md +62 -50
  48. package/src/ui/docs/content/compositions.md +129 -459
  49. package/src/ui/docs/content/date-input.md +67 -0
  50. package/src/ui/docs/content/dialog.md +44 -112
  51. package/src/ui/docs/content/drawer.md +44 -103
  52. package/src/ui/docs/content/field.md +2 -1
  53. package/src/ui/docs/content/input.md +3 -0
  54. package/src/ui/docs/content/page.md +204 -412
  55. package/src/ui/docs/content/presentation.md +371 -23
  56. package/src/ui/docs/content/separator.md +1 -1
  57. package/src/ui/docs/content/surface.md +65 -120
  58. package/src/ui/docs/content/tokens.md +18 -4
  59. package/src/ui/docs/registry.tsx +38 -9
  60. package/src/ui/drivers/context.tsx +11 -4
  61. package/src/ui/drivers/react.tsx +27 -7
  62. package/src/ui/meta.ts +17 -6
  63. package/src/ui/react.tsx +41 -8
  64. package/src/ui/theme.css +44 -33
@@ -43,31 +43,33 @@ existentes, mantendo navegação observável e componentes reutilizáveis sem la
43
43
  7. Tratar página, filtro, seleção e modal importante como estado navegável por URL quando
44
44
  o produto precisa de deep link, back/forward ou refresh. Em `Presentation`, declarar `route`
45
45
  no artefato e deixar o adaptador apenas conectar a spec ao router da aplicação.
46
- 8. Compor Page, Dialog e Drawer pela mesma gramática: no formato compacto, título e orientação
47
- ficam no Header; com Intro, navegação e ações da superfície ficam no Header e a Intro abre o
48
- Body com título, orientação e ações locais em IntroActions. Declarar a escolha pelos slots,
49
- sem prop redundante. Usar PageIntro na Page explícita; a forma curta de Page já coloca title e
50
- description na intro e actions no header. Não misturar shorthand com regiões explícitas.
51
- Manter exatamente um heading principal, inclusive quando Surface level={1} nomeia uma coleção
52
- ou PageState substitui a página. PageShell fornece contexto sem criar barra paralela; header
53
- sem controles não reserva espaço. Preservar o teto de 80rem e separar composição de ocupação
54
- de altura (flow/fill). Surface mantém o cabeçalho do conteúdo; Pane distribui espaço e recebe
55
- uma superfície quando precisar de anatomia visual. Não criar Intro nem controles de navegação
56
- artificiais para Surface ou Pane.
57
- Em `Surface framed`, usar `layout="sectioned"` e `SurfaceBody flush` quando o filho direto já
58
- controlar o recuo do body, como `DetailGroup` com divisores, lista ou tabela; não reconstruir
59
- divisor, padding ou recorte por classes no consumidor. Em grupos de formulário,
60
- `as="fieldset"` transforma o header em `legend` nativa sem variante visual paralela.
46
+ 8. Compor Page, Dialog, Drawer e Surface pela mesma anatomia: título, descrição opcional,
47
+ metadados e ações gerais no Header; conteúdo no Body; decisões no Footer. Não existem
48
+ `compact`, `sectioned`, `surfaceLayout`, `*Intro` nem a escolha visual `layout` nesses roots.
49
+ Preservar exatamente um heading principal. Page usa uma coluna aberta, padding de `2.5rem`
50
+ e título de `1.875rem`, sem divisores entre regiões. `width` limita a coluna; omitido, ocupa a
51
+ largura disponível. `Page.layout="flow"` rola a página inteira; `fill` mantém o header visível
52
+ e entrega a altura restante à lista ou à rolagem do body. Não oferecer `composition`.
53
+ PageBack recebe destino pai explícito e aparece como primeira ação de ícone no Header.
54
+ Não criar barra de breadcrumb. PageShell fornece ações sem barra paralela.
55
+ Headers usam botões `default`/`icon` e linha mínima de `2.25rem`. Regiões delimitadas têm recuo
56
+ de `1rem`, e bodies governam o ritmo vertical de `1rem`. Divisores são automáticos entre
57
+ regiões existentes. Surface sem moldura se alinha ao hospedeiro, sem recuo lateral ou inferior.
58
+ Usar `flush` quando o filho já controla o recuo; não reconstruir padding ou divisores na tela.
59
+ `tabs` integra a navegação ao Header; ações da coleção ficam em `ActionList.toolbarActions`
60
+ dentro do painel ativo. Pane distribui espaço e recebe Surface quando precisar de anatomia.
61
+ `Surface as="fieldset"` mantém legend nativa na faixa do cabeçalho, sem variante de moldura.
61
62
  9. Manter margem e posicionamento no consumidor; componente reutilizável controla apenas
62
63
  seu interior.
63
64
  10. Não definir a fonte raiz em uma biblioteca ou componente. O navegador e a aplicação são
64
65
  responsáveis por `font-size` em `html`; medidas escaláveis da UI usam `rem` ou a escala
65
66
  relativa do Tailwind. Reservar `px` a hairlines e compensações presas à geometria da borda,
66
67
  com justificativa e cobertura explícitas.
67
- 11. Em uma página centrada em coleção, compor `Surface + ActionList`: título e criação ficam em
68
- extremos opostos do `SurfaceHeader`; a criação usa botão textual `sm`, sem ícone, com
69
- `Criar recurso`. Busca, filtros, atualização, estados e paginação permanecem no `ActionList`.
70
- Reservar `toolbarActions` a operações ligadas ao recorte atual.
68
+ 11. Em uma página centrada em coleção, compor `Page + ActionList`; usar `Surface` para uma coleção
69
+ subordinada. Manter criação, importação e exportação em `ActionList.toolbarActions`, junto
70
+ de busca e filtros. Reservar ações do header à página ou superfície como um todo.
71
+ Usar botão textual normal, sem ícone, com `Criar`; preservar `Criar recurso` no nome acessível
72
+ e no título do formulário. Manter nomes específicos em menus com vários tipos de criação.
71
73
  12. Evoluir um pattern compartilhado apenas quando a recorrência e o contrato estiverem claros.
72
74
  13. Tratar tokens de superfície como pares indivisíveis no mesmo fragmento de classes:
73
75
  `bg-card text-card-foreground` e `bg-popover text-popover-foreground`. Não depender da
@@ -4,13 +4,13 @@
4
4
  - Não dispara: “Ajuste o CSS de um e-mail estático.”
5
5
  - Execução: implementar uma lista com modal roteável e provar loading, erro, vazio e back.
6
6
  - Execução estrutural: montar uma página de relatório isolada com `Page > PageHeader + PageBody`,
7
- outra em `PageShell` com navegação contextual acima de `Page > PageHeader + PageBody`, garantindo
7
+ outra em `PageShell` com ações contextuais no `PageHeader`, garantindo
8
8
  exatamente um `PageTitle` no header, e uma coleção nomeada com
9
9
  `Surface > SurfaceHeader + SurfaceBody > ActionList`. Provar que criação fica em
10
- `SurfaceActions`, no extremo oposto ao título, como botão textual `sm` sem ícone e com
11
- `Criar recurso`, enquanto uma operação dependente do recorte usa `toolbarActions`; incluir
10
+ `ActionList.toolbarActions`, junto das operações do recorte, como botão textual normal sem ícone
11
+ com `Criar`, nome acessível `Criar recurso` e formulário com título específico; incluir
12
12
  `ActionFilterBar` separado do renderer, `ItemGroup` para
13
- uma coleção secundária e um `ActionFormDialog`; provar teto padrão de `80rem`, hierarquia por
13
+ uma coleção secundária e um `ActionFormDialog`; provar ocupação de toda a largura e scroll somente no body, hierarquia por
14
14
  `level`, vazio estrutural sólido, `Empty` apenas para criação ou vínculo, números sem alinhamento
15
15
  inferido e footer modal com largura natural, alinhado à direita e cancelamento `ghost`; incluir
16
16
  separadamente um caso deliberadamente equivalente com distribuição 50/50 e cancelamento
@@ -22,7 +22,7 @@
22
22
  rejeita a mistura entre props abreviadas e headers explícitos.
23
23
  - Execução de forma: compor uma tabela dentro de `Surface` sem moldura duplicada, manter a moldura
24
24
  estrutural standalone em `rounded-lg` e os controles internos em `rounded-md`.
25
- - Execução de Surface seccionada: compor `Surface framed layout="sectioned"` com mídia e
25
+ - Execução de Surface: compor `Surface framed` com mídia e
26
26
  `DetailGroup` com divisores; provar header com divisor, `SurfaceBody flush` sem recuo e ausência
27
27
  de classes no consumidor que reconstruam essa anatomia. Provar `as="fieldset"` com `legend`
28
28
  nativa sem `frameVariant`.
@@ -79,16 +79,18 @@ da label, duplicação entre hint/help e perda de `aria-describedby` quando apar
79
79
 
80
80
  - Gatilho positivo: “Monte o detalhe de um recurso com menu da página separado do título.”
81
81
  - Gatilho negativo: “Explique por que a ADR antiga juntava título e ações”, sem pedido de UI.
82
- - Execução: montar o mesmo detalhe em Page, Dialog e Drawer com header de navegação/ações e intro
83
- abrindo o body; montar também a versão compacta sem intro. Provar título único, ações locais em
84
- IntroActions, nenhum header vazio na Page e transição de loading para conteúdo sem título duplicado.
85
- - Reprovar intro depois de texto, título simultâneo em header e intro, ações da superfície no título
86
- ou adaptação de Pane para que ele volte a possuir anatomia visual.
82
+ - Execução: montar o mesmo detalhe em Page, Dialog e Drawer com título e ações gerais no Header;
83
+ provar um único título, linha mínima de `2.25rem`, botões normais e transição de loading para
84
+ conteúdo sem duplicação. Page usa coluna aberta com padding de `2.5rem`, título de `1.875rem`,
85
+ largura independente e rolagem flow/fill; Drawer e Dialog preservam recuo de `1rem` e divisores. Conferir tabs nativas e operações
86
+ de coleção dentro do painel ativo, junto à listagem.
87
+ - Reprovar `*Intro`, `compact`, `sectioned`, `surfaceLayout`, `tabsActions`, layout visual e
88
+ PageNavigation. Conferir que o checker orienta a migração. Não recriar anatomia em Pane.
87
89
 
88
90
  ## Metadados e contadores
89
91
 
90
92
  - Execução: compor um detalhe com título, descrição e badges em PageMeta, DrawerMeta e DialogMeta;
91
- conferir a faixa separada em Header compacto e Intro. Em Surface, conferir que SurfaceCount
93
+ conferir a faixa separada no Header. Em Surface, conferir que SurfaceCount
92
94
  fica na linha do título e SurfaceMeta abaixo dela. Migrar um contador antigo e uma descrição
93
95
  antiga sem alterar suas funções; provar a equivalência das formas curtas com `meta`.
94
96
  - Reprova: contador em SurfaceMeta, metadados em Description, dois Meta, Meta sem título,
@@ -7,25 +7,21 @@
7
7
  - Uma `Presentation` que representa esse estado declara `route.path` e `route.surface`. Rotas com
8
8
  parâmetro podem declarar `route.record` para hidratar o item a partir de uma Presentation de
9
9
  lista; não reconstruir essa decisão com condicionais no componente da página.
10
- - `Page` fornece o `<main>` e o container centralizado com teto padrão de `80rem`. Sua forma
11
- explícita exige `PageBody`, exatamente um heading principal e aceita `PageHeader` e `PageFooter`.
12
- Declare esse heading com PageTitle na PageIntro ou no PageHeader compacto, Surface level={1}
13
- ou PageState ativo. A intro abre o body; ações locais usam PageIntroActions, enquanto PageActions
14
- pertence ao header. A forma curta coloca title/description na intro e actions no header.
15
- Não misturar as duas formas. Para ajustar a largura interna, usar contentClassName; className pertence ao container externo.
16
- - Na composição com intro, PageHeader reúne navegação contextual e ações da superfície na mesma
17
- linha. PageBack recebe o destino pai explícito; para vários ancestrais relevantes, usar Breadcrumb
18
- em PageNavigation. Não combinar retorno e breadcrumb, nem criar chrome paralelo. Na composição
19
- compacta, título e orientação permanecem no header. PageActionsTarget fica reservado a workspaces
20
- imersivos com chrome próprio.
21
- - Quando shell e rota conhecem partes diferentes da mesma página, use `PageShell` ao redor da rota.
22
- O shell entrega navegação e ações ao `PageHeader` descendente sem criar uma barra visual.
23
- Ações com texto no cabeçalho usam `sm`, e ações somente com ícone usam `icon-sm`.
24
- Ações de footer de Dialog e Drawer conservam `default`. O tamanho `sm` fica para ações operacionais em
25
- toolbar, seção ou coleção densa, e `xs`/`icon-xs` para ações internas de linha ou célula. Contexto
26
- e variante resolvem a hierarquia visual sem alterar essa medida. Em uma coleção, a ação de
27
- criar usa botão textual `sm`, sem ícone, no extremo oposto do `SurfaceHeader`. Não monte
28
- cabeçalho paralelo, portal ou seletor global para reconstruir essa composição.
10
+ - `Page` fornece o `<main>` e a coluna com largura `narrow`, `default` ou `wide` (padrão). Sua forma explícita usa
11
+ `PageHeader` com `PageTitle`, `PageBody` e `PageFooter` opcional. A forma curta produz a mesma
12
+ anatomia; não misturar props abreviadas com slots explícitos. PageState ativo assume o título.
13
+ - Page, Dialog, Drawer e Surface têm Header com título, descrição opcional, metadados e ações
14
+ gerais, Body com ritmo de `1rem` e Footer opcional. Não há `*Intro`, `compact`, `sectioned` ou
15
+ escolha visual de layout. `Page.layout` preserva somente a ocupação `flow`/`fill`.
16
+ - Page tem uma aparência aberta, padding de `2.5rem` e título de `1.875rem`, sem divisores.
17
+ `flow` rola a página inteira; `fill` entrega a altura restante à lista ou ao body.
18
+ PageBack usa o destino pai e aparece como
19
+ primeira ação de ícone. PageShell entrega ações sem criar barra paralela; breadcrumbs
20
+ não fazem parte da composição. PageActionsTarget atende workspaces com chrome próprio.
21
+ - Headers usam botões `default`/`icon` e linha mínima de `2.25rem`. Regiões delimitadas
22
+ de Drawer, Dialog e Surface conservam recuo de `1rem` e divisores automáticos. Surface sem moldura permanece
23
+ alinhada ao hospedeiro. A prop `tabs` integra a navegação ao Header; operações da coleção ficam
24
+ em `ActionList.toolbarActions` no painel ativo. Não reconstruir isso por portais ou seletores.
29
25
  - `PageState` substitui todo o conteúdo principal quando a página carrega, falha ou está vazia. Na
30
26
  forma curta ele pode ser escrito como filho direto de `Page`, que cria o `PageBody`; na forma
31
27
  explícita, fica sozinho dentro de `PageBody`. Nos três estados ativos, o cabeçalho da Page
@@ -38,24 +34,25 @@
38
34
  - `Surface` delimita uma região e segue a anatomia `Surface > SurfaceHeader (SurfaceMedia,
39
35
  SurfaceTitle, SurfaceCount, SurfaceDescription, SurfaceMeta, SurfaceActions) + SurfaceBody + SurfaceFooter`.
40
36
  Os slots nunca ficam soltos. `title`, `description`, `count`, `meta`, `media` e `actions` são a abreviação
41
- para o caso direto e não podem ser misturados ao header explícito. Em `level={1}`, ações da
42
- coleção ficam no extremo oposto ao título; a criação usa botão textual `sm`, sem ícone, com
43
- `Criar recurso`.
37
+ para o caso direto e não podem ser misturados ao header explícito. Ações do header pertencem à
38
+ superfície como um todo; operações da coleção ficam em `ActionList.toolbarActions`.
44
39
  O diálogo de criação usa `Criar recurso` e o de edição, `Editar recurso`. `level` preserva a
45
- hierarquia semântica do heading. `Surface framed` aceita `layout="sectioned"`; declare
40
+ hierarquia semântica do heading. Declare
46
41
  `SurfaceBody flush` quando o filho direto já possui recuo interno, como `DetailGroup` com
47
42
  divisores, lista ou tabela. `as="fieldset"` cria a `legend` nativa sem variante de moldura.
48
43
  - `PageMeta`, `DialogMeta` e `DrawerMeta` recebem badges, datas e autoria em faixa própria
49
- após título, descrição e ações, dentro de Header compacto ou Intro da mesma família.
44
+ após título, descrição e ações, dentro do Header da mesma família.
50
45
  `SurfaceMeta` ocupa essa faixa em `SurfaceHeader`; `SurfaceCount` mantém o contador na linha
51
46
  do título. Ao migrar, conferir manualmente os antigos `SurfaceMeta`: contadores passam a
52
47
  `SurfaceCount`, frases de orientação a `SurfaceDescription`, e metadados permanecem em Meta.
53
48
  Cada composição aceita um Meta e exige título. Page e Surface aceitam `meta` na forma curta;
54
49
  fieldset e Dialog em `mode="alert"` não aceitam Meta. Informações necessárias à decisão
55
50
  permanecem no corpo ou junto à ação correspondente.
56
- - Uma página centrada em coleção compõe `Surface + ActionList`. O `SurfaceHeader` recebe título e
57
- criação; o `ActionList` mantém busca, filtros, atualização, resultados, estados e paginação.
58
- `toolbarActions` fica reservado a operações que dependem do recorte atual.
51
+ - Uma página centrada em coleção compõe `Page + ActionList`; coleções subordinadas podem usar
52
+ `Surface`. Criação, importação e exportação ficam em `toolbarActions`, junto de busca e filtros.
53
+ O botão de criação é textual normal, sem ícone, com `Criar` e nome acessível `Criar recurso`.
54
+ Menus com vários tipos de criação preservam os nomes específicos. Operações de seleção usam
55
+ `batchActions`, e operações individuais usam `rowActions`.
59
56
  - `Surface` e Drawer nomeiam a região principal como `SurfaceBody` e `DrawerBody`. `Pane` é apenas
60
57
  uma unidade dimensionável de `Split` e não possui anatomia interna. `*Content` permanece
61
58
  reservado a raízes técnicas ou painéis cujo papel não é o corpo de uma estrutura, como