@praxisui/expansion 9.0.0-beta.0 → 9.0.0-beta.2

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 (2) hide show
  1. package/README.md +87 -213
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  title: "Expansion"
3
3
  slug: "expansion-overview"
4
- description: "Visao geral do @praxisui/expansion com metadata-first panels, persistencia, providers e integracao com registry."
4
+ description: "Public npm documentation for @praxisui/expansion: metadata-driven accordion panels, persistence, providers, lazy panel content and runtime authoring."
5
5
  doc_type: "reference"
6
6
  document_kind: "component-overview"
7
7
  component: "expansion"
@@ -24,7 +24,7 @@ icon: "expand"
24
24
  toc: true
25
25
  sidebar: true
26
26
  search_boost: 1.0
27
- reading_time: 8
27
+ reading_time: 5
28
28
  estimated_setup_time: 15
29
29
  version: "1.0"
30
30
  related_docs:
@@ -35,267 +35,141 @@ keywords:
35
35
  - "expansion panel"
36
36
  - "metadata"
37
37
  - "providers"
38
- last_updated: "2026-03-07"
38
+ last_updated: "2026-06-16"
39
39
  ---
40
40
 
41
- # @praxisui/expansion — Praxis Expansion Panel
41
+ # @praxisui/expansion
42
42
 
43
- ## Documentation
43
+ `@praxisui/expansion` renders Angular Material expansion panels from Praxis metadata. Install it when a host needs governed accordion layouts with panel persistence, dynamic field/widget content, runtime editing and registry projection for dynamic pages.
44
44
 
45
- - Official documentation: https://praxisui.dev/components/expansion
46
- - Quickstart reference app: https://github.com/codexrodrigues/praxis-ui-quickstart
47
- - Live Praxis UI demo: https://praxis-ui-4e602.web.app
48
- - Recommended for: accordion and panel layouts driven by metadata with editor integration
45
+ The package owns the expansion shell and metadata shape. The host owns domain data, widget providers, authorization, persistence beyond component config and any business effect triggered from panel actions.
49
46
 
50
- ## When to use
51
-
52
- - Organizar blocos expansivos em telas configuradas por metadata
53
- - Reaproveitar paines tipo accordion em fluxos com editor embutido
54
- - Manter comportamento e defaults de expansion alinhados no ecossistema Praxis UI
55
-
56
- Widget baseado em Angular Material (MatAccordion/MatExpansionPanel) com configuração via metadata, editor embutido e integração com o `ComponentMetadataRegistry` para uso em páginas dinâmicas canônicas.
57
-
58
- ## Instalação e Providers
47
+ ## Install
59
48
 
60
49
  ```bash
61
- npm i @praxisui/expansion@beta
50
+ npm i @praxisui/expansion@latest
62
51
  ```
63
52
 
64
53
  Peer dependencies:
65
- - `@angular/core` `^21.0.0`
66
- - `@angular/common` `^21.0.0`
67
- - `@angular/forms` `^21.0.0`
68
- - `@angular/router` `^21.0.0`
69
- - `@angular/cdk` `^21.0.0`
70
- - `@angular/material` `^21.0.0`
71
- - `@praxisui/core` `^9.0.0-beta.0`
72
- - `@praxisui/dynamic-fields` `^9.0.0-beta.0`
73
- - `@praxisui/settings-panel` `^9.0.0-beta.0`
74
- - `@praxisui/ai` `^9.0.0-beta.0`
75
- - `rxjs` `~7.8.0`
76
-
77
- - Registrar o metadata do componente:
78
54
 
79
- ```ts
80
- import { providePraxisExpansionMetadata } from '@praxisui/expansion';
81
-
82
- bootstrapApplication(AppComponent, {
83
- providers: [providePraxisExpansionMetadata()],
84
- });
85
- ```
55
+ - `@angular/common`, `@angular/core`, `@angular/forms`, `@angular/router`, `@angular/cdk`, `@angular/material` `^21.0.0`
56
+ - `@praxisui/core`, `@praxisui/dynamic-fields`, `@praxisui/settings-panel`, `@praxisui/ai` `^9.0.0-beta.1`
57
+ - `rxjs` `~7.8.0`
86
58
 
87
- - (Opcional) Definir defaults globais do painel:
59
+ ## App Providers
88
60
 
89
61
  ```ts
90
- import { providePraxisExpansionDefaults } from '@praxisui/expansion';
62
+ import { ApplicationConfig } from '@angular/core';
63
+ import {
64
+ providePraxisExpansionDefaults,
65
+ providePraxisExpansionMetadata,
66
+ } from '@praxisui/expansion';
91
67
 
92
- bootstrapApplication(AppComponent, {
68
+ export const appConfig: ApplicationConfig = {
93
69
  providers: [
94
- providePraxisExpansionDefaults({ collapsedHeight: '48px', expandedHeight: '64px', hideToggle: false }),
70
+ providePraxisExpansionMetadata(),
71
+ providePraxisExpansionDefaults({
72
+ collapsedHeight: '48px',
73
+ expandedHeight: '64px',
74
+ hideToggle: false,
75
+ }),
95
76
  ],
96
- });
77
+ };
97
78
  ```
98
79
 
99
- ## Exemplo básico (metadata)
80
+ `providePraxisExpansionMetadata()` registers `praxis-expansion` for the Praxis component metadata registry. `providePraxisExpansionDefaults()` is optional; instance `defaultOptions` take precedence.
100
81
 
101
- ```ts
102
- import { ExpansionMetadata } from '@praxisui/expansion';
82
+ ## Minimal Standalone Panel
103
83
 
104
- const expansionConfig: ExpansionMetadata = {
105
- accordion: { multi: true, displayMode: 'default', togglePosition: 'after' },
106
- panels: [
107
- { id: 'general', title: 'Geral', description: 'Informações principais', expanded: true },
108
- { id: 'advanced', title: 'Avançado', description: 'Opções avançadas' },
109
- ],
110
- };
111
- ```
84
+ ```ts
85
+ import { Component } from '@angular/core';
86
+ import { PraxisExpansion, type ExpansionMetadata } from '@praxisui/expansion';
87
+
88
+ @Component({
89
+ selector: 'app-expansion-host',
90
+ standalone: true,
91
+ imports: [PraxisExpansion],
92
+ template: `
93
+ <praxis-expansion
94
+ expansionId="customer-panels"
95
+ [config]="config"
96
+ [enableCustomization]="true"
97
+ (expandedChange)="onExpandedChange($event)"
98
+ />
99
+ `,
100
+ })
101
+ export class ExpansionHostComponent {
102
+ readonly config: ExpansionMetadata = {
103
+ accordion: { multi: true, displayMode: 'default', togglePosition: 'after' },
104
+ panels: [
105
+ { id: 'general', title: 'General', description: 'Main customer data', expanded: true },
106
+ { id: 'history', title: 'History', description: 'Timeline and related records' },
107
+ ],
108
+ };
112
109
 
113
- ```html
114
- <praxis-expansion expansionId="expansion-demo" [config]="expansionConfig" [enableCustomization]="true"></praxis-expansion>
110
+ onExpandedChange(event: { panelId?: string; panelIndex: number; expanded: boolean }): void {
111
+ console.log('panel changed', event);
112
+ }
113
+ }
115
114
  ```
116
115
 
117
- ## Persistência
116
+ ## Main Inputs And Outputs
118
117
 
119
- - Quando `expansionId` é fornecido, a configuração é salva/recuperada em `AsyncConfigStorage` na chave `expansion:<component_id>`.
120
- - Use `componentInstanceId` quando houver múltiplas instâncias com o mesmo `expansionId` na mesma rota.
118
+ - `config: ExpansionMetadata | null`: canonical accordion and panel configuration.
119
+ - `expansionId: string`: required stable id used for local configuration persistence.
120
+ - `componentInstanceId?: string`: disambiguates repeated instances on the same route.
121
+ - `context: Record<string, unknown>`: context passed to dynamic child widgets.
122
+ - `strictValidation: boolean`: keeps runtime validation strict by default.
123
+ - `enableCustomization: boolean`: opens runtime authoring affordances.
124
+ - `defaultOptions?: MatExpansionPanelDefaultOptions`: instance Material expansion defaults.
125
+ - Events: `opened`, `closed`, `expandedChange`, `afterExpand`, `afterCollapse`, `destroyed`.
126
+ - `widgetEvent`: legacy/advanced bridge for nested widget and panel action events.
121
127
 
122
- ## Lazy loading de conteúdo (por painel)
128
+ The component also exposes imperative methods by template ref: `open(idOrIndex)`, `close(idOrIndex)`, `toggle(idOrIndex)`, `openAll()` and `closeAll()`.
123
129
 
124
- O componente utiliza `<ng-template matExpansionPanelContent>`, logo o conteúdo interno de cada painel é criado apenas quando o painel é aberto. Não é necessário habilitar um flag: basta declarar `content` (campos) e/ou `widgets` (widgets dinâmicos) no painel.
130
+ ## Metadata Shape
125
131
 
126
132
  ```ts
127
- const expansionConfig: ExpansionMetadata = {
133
+ const config: ExpansionMetadata = {
128
134
  accordion: { multi: true },
129
135
  panels: [
130
136
  {
131
- id: 'general',
132
- title: 'Geral',
137
+ id: 'details',
138
+ title: 'Details',
133
139
  expanded: true,
134
- // Campos dinâmicos (renderizados ao abrir)
135
140
  content: [
136
- { id: 'text', inputs: { field: { name: 'nome', label: 'Nome' } } },
141
+ { id: 'name', inputs: { field: { name: 'name', label: 'Name' } } },
137
142
  ],
138
143
  },
139
144
  {
140
- id: 'advanced',
141
- title: 'Avançado',
142
- // Widgets dinâmicos (renderizados ao abrir)
145
+ id: 'orders',
146
+ title: 'Orders',
143
147
  widgets: [
144
- { id: 'praxis-table', inputs: { config: { /* ... */ } } },
148
+ { id: 'praxis-table', inputs: { resourcePath: 'orders' } },
145
149
  ],
146
- },
147
- ],
148
- };
149
- ```
150
-
151
- ## Nested Ports e Conexoes
152
-
153
- Para conectar widgets dentro de paineis a estado ou widgets externos, use `composition.links` com endpoint `component-port + nestedPath`.
154
-
155
- Exemplo de output de chart dentro do painel `analytics`:
156
-
157
- ```json
158
- {
159
- "kind": "component-port",
160
- "ref": {
161
- "widget": "expansion-widget",
162
- "nestedPath": [
163
- { "kind": "panel", "id": "analytics", "index": 0 },
164
- { "kind": "widget", "key": "payroll-chart", "componentType": "praxis-chart" }
165
- ],
166
- "port": "pointClick",
167
- "direction": "output"
168
- }
169
- }
170
- ```
171
-
172
- Regras:
173
-
174
- - `ref.widget` e a instancia top-level de `praxis-expansion`;
175
- - o segmento terminal deve ser `kind: "widget"` com `key` estavel;
176
- - `widgetEvent` permanece como bridge avancada/legado, nao como contrato principal;
177
- - inputs nested devem atualizar o config declarativo do widget filho, inclusive quando o painel ainda nao montou por lazy loading.
178
-
179
- ## Action Row por painel
180
-
181
- Adicione botões de ação no rodapé do painel com `actionButtons`. O evento é reemitido via `widgetEvent` com `output: 'action'`; trate esse fluxo como bridge avancada/legado para acoes de painel, nao como modelo principal de nested component ports.
182
-
183
- ```ts
184
- const expansionConfig: ExpansionMetadata = {
185
- panels: [
186
- {
187
- id: 'general',
188
- title: 'Geral',
189
150
  actionButtons: [
190
- { label: 'Salvar', icon: 'save', action: 'save-general' },
191
- { label: 'Cancelar', icon: 'close', action: 'cancel-general' },
151
+ { label: 'Refresh', icon: 'refresh', action: 'refresh-orders' },
192
152
  ],
193
153
  },
194
154
  ],
195
155
  };
196
156
  ```
197
157
 
198
- ```html
199
- <praxis-expansion expansionId="expansion-demo"
200
- [config]="expansionConfig"
201
- (widgetEvent)="onExpansionEvent($event)">
202
- </praxis-expansion>
203
- ```
204
-
205
- ```ts
206
- onExpansionEvent(ev: { panelId?: string; panelIndex?: number; sourceId: string; output?: string; payload?: any }) {
207
- if (ev.output === 'action') {
208
- // ev.payload.action -> 'save-general' | 'cancel-general' | ...
209
- }
210
- }
211
- ```
212
-
213
- ## Defaults (heights e toggle) por instância
214
-
215
- Você pode passar `defaultOptions` direto no componente, que tem precedência sobre os valores providos globalmente via provider.
216
-
217
- ```html
218
- <praxis-expansion expansionId="expansion-demo"
219
- [config]="expansionConfig"
220
- [defaultOptions]="{ collapsedHeight: '48px', expandedHeight: '64px', hideToggle: false }">
221
- </praxis-expansion>
222
- ```
223
-
224
- ## Controle programático: open/close/toggle/openAll/closeAll
225
-
226
- O componente expõe métodos para controlar a expansão por índice (numérico) ou por id (string):
227
-
228
- ```html
229
- <praxis-expansion expansionId="expansion-demo" #expRef [config]="expansionConfig"></praxis-expansion>
230
-
231
- <button (click)="expRef.open('general')">Abrir Geral</button>
232
- <button (click)="expRef.close(1)">Fechar painel 2</button>
233
- <button (click)="expRef.toggle('advanced')">Alternar Avançado</button>
234
- <button (click)="expRef.openAll()">Abrir todos</button>
235
- <button (click)="expRef.closeAll()">Fechar todos</button>
236
- ```
237
-
238
- ## Eventos suportados
239
-
240
- ```html
241
- <praxis-expansion expansionId="expansion-demo"
242
- [config]="expansionConfig"
243
- (opened)="onOpened($event)"
244
- (afterExpand)="onAfterExpand($event)"
245
- (expandedChange)="onExpandedChange($event)"
246
- (afterCollapse)="onAfterCollapse($event)"
247
- (closed)="onClosed($event)"
248
- (destroyed)="onDestroyed($event)">
249
- </praxis-expansion>
250
- ```
251
-
252
- Cada evento inclui `{ panelId?: string; panelIndex: number }` (ou `expanded: boolean` no caso de `expandedChange`).
253
-
254
- ## Agentic Authoring
255
-
256
- O contrato executavel de authoring fica em `PRAXIS_EXPANSION_AUTHORING_MANIFEST`.
257
- Ele modela edicoes em `ExpansionMetadata` por operacoes atomicas sobre paineis,
258
- cabecalhos, conteudo lazy, estado expandido/desabilitado e comportamento do
259
- accordion.
260
-
261
- Quando `enableCustomization` esta ativo, o runtime abre o `PraxisAiAssistantShellComponent`
262
- com contexto semantico dos paineis e registra a sessao no dock global de assistentes.
263
- O assistente envia estado atual, perfil dos paineis, campos de schema e referencia ao
264
- manifesto de authoring para a IA. Patches JSON livres nao sao aplicados no runtime:
265
- mudancas locais devem nascer de um `componentEditPlan` validado pelo manifesto, e
266
- regras compartilhadas seguem por `domain-rules/intake`.
158
+ Panel `content` and `widgets` are rendered lazily with `matExpansionPanelContent`, so child runtime is created when the panel opens. Use stable `panels[].id` values; authoring, persistence and nested paths rely on them.
267
159
 
268
- Cobertura principal:
160
+ ## Persistence And Authoring
269
161
 
270
- - `panel.add`, `panel.remove`, `panel.order.set`
271
- - `panel.title.set`, `panel.description.set`, `panel.icon.set`
272
- - `panel.disabled.set`
273
- - `behavior.multiExpand.set`
274
- - `behavior.defaultExpanded.set`
275
- - `panel.content.set`
162
+ When `expansionId` is provided, configuration is stored under a key derived from route, component type, `expansionId` and optional `componentInstanceId`. `enableCustomization` opens Settings Panel editing and the governed semantic assistant flow.
276
163
 
277
- As operacoes preservam `panels[].id` como identidade canonica. Remover um painel
278
- com `content`, `widgets` ou `actionButtons` exige confirmacao explicita. Quando
279
- `accordion.multi` estiver desabilitado, somente um painel pode ficar expandido por
280
- padrao; o authoring deve colapsar os demais ou falhar validacao.
164
+ `PRAXIS_EXPANSION_AUTHORING_MANIFEST` describes supported AI/tooling operations for panel add/remove/order, titles, descriptions, icons, disabled state, default expanded state, multi-expand behavior and panel content. Free JSON patches are not the public authoring contract.
281
165
 
282
- Cada operacao declara `target.resolver`, `preconditions`, `validators`,
283
- `affectedPaths`, `effects` e `submissionImpact` tipado. Edicoes de conteudo de
284
- painel podem afetar dados schema-backed porque `panels[].content` hospeda
285
- `FieldMetadata[]`; widgets filhos continuam governados pelos contratos dos
286
- respectivos componentes.
166
+ ## Public API Snapshot
287
167
 
288
- ## Tokens de Estilo por instância
289
-
290
- Os tokens opcionais em `appearance.tokens` permitem customizações rápidas por instância; por exemplo:
291
-
292
- ```ts
293
- const expansionConfig: ExpansionMetadata = {
294
- appearance: { tokens: { 'header-background-color': 'rgba(0,0,0,0.04)' } },
295
- panels: [ /* ... */ ],
296
- };
297
- ``;
168
+ Main exports include `PraxisExpansion`, `ExpansionMetadata`, `PanelMetadata`, `PraxisExpansionConfigEditor`, `PraxisExpansionWidgetConfigEditor`, `providePraxisExpansionMetadata`, `providePraxisExpansionDefaults`, AI capability metadata and `PRAXIS_EXPANSION_AUTHORING_MANIFEST`.
298
169
 
299
- ## Integração via Registry / Gridster
170
+ ## Official Links
300
171
 
301
- Ao registrar `providePraxisExpansionMetadata()`, o widget `praxis-expansion` fica disponível para o `DynamicWidgetLoader` e pode ser usado em páginas dinâmicas canônicas. Basta fornecer um `WidgetDefinition` com `id: 'praxis-expansion'` e `inputs.config` com o `ExpansionMetadata` desejado.
172
+ - Documentation: https://praxisui.dev/components/expansion
173
+ - Live demo: https://praxis-ui-4e602.web.app
174
+ - Quickstart repository: https://github.com/codexrodrigues/praxis-ui-quickstart
175
+ - Source and issues: https://github.com/codexrodrigues/praxis-ui-angular
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@praxisui/expansion",
3
- "version": "9.0.0-beta.0",
3
+ "version": "9.0.0-beta.2",
4
4
  "description": "Expansion panel (accordion) components for Praxis UI with metadata configuration and editor integration.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
8
  "@angular/material": "^21.0.0",
9
9
  "@angular/cdk": "^21.0.0",
10
- "@praxisui/core": "^9.0.0-beta.0",
11
- "@praxisui/dynamic-fields": "^9.0.0-beta.0",
12
- "@praxisui/settings-panel": "^9.0.0-beta.0",
10
+ "@praxisui/core": "^9.0.0-beta.2",
11
+ "@praxisui/dynamic-fields": "^9.0.0-beta.2",
12
+ "@praxisui/settings-panel": "^9.0.0-beta.2",
13
13
  "@angular/forms": "^21.0.0",
14
14
  "@angular/router": "^21.0.0",
15
- "@praxisui/ai": "^9.0.0-beta.0",
15
+ "@praxisui/ai": "^9.0.0-beta.2",
16
16
  "rxjs": "~7.8.0"
17
17
  },
18
18
  "dependencies": {
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
27
- "url": "https://github.com/codexrodrigues/praxis-ui-angular"
27
+ "url": "git+https://github.com/codexrodrigues/praxis-ui-angular.git"
28
28
  },
29
29
  "homepage": "https://praxisui.dev",
30
30
  "bugs": {