@praxisui/editorial-forms 9.0.0-beta.1 → 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 +52 -303
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,28 +1,8 @@
1
1
  # @praxisui/editorial-forms
2
2
 
3
- > Specialist Angular runtime for editorial experiences: journeys, semantic blocks, presets, runtime snapshots, and operational fallbacks.
3
+ Specialist Angular runtime for editorial form experiences: journeys, semantic blocks, presets, runtime snapshots, fallbacks and operational diagnostics. Use it when a flow is more than a flat schema-driven form and needs guided editorial structure, compliance context or host-level operational rules.
4
4
 
5
- `@praxisui/editorial-forms` is designed for flows that are more than a regular form. Use it when the experience has editorial structure, guided steps, reusable content blocks, compliance context, or host-level operational rules.
6
-
7
- ## Documentation
8
-
9
- - Official docs: https://praxisui.dev/docs/components
10
- - Quickstart reference app: https://github.com/codexrodrigues/praxis-ui-quickstart
11
- - Live Praxis UI demo: https://praxis-ui-4e602.web.app
12
-
13
- ## When to use
14
-
15
- - Build guided journeys instead of a single flat form
16
- - Compose semantic blocks with audit-friendly runtime resolution
17
- - Keep host observability outside DOM parsing
18
- - Support graceful degradation when an optional form engine is unavailable
19
- - Separate editorial runtime concerns from `FormConfig` authoring concerns
20
-
21
- ## When not to use
22
-
23
- - Plain schema-driven forms without editorial flow
24
- - Screens that only need `@praxisui/dynamic-form`
25
- - Cases where the host does not need snapshots, fallbacks, or runtime diagnostics
5
+ Use `@praxisui/dynamic-form` directly for plain schema-driven forms without editorial journey, fallback or snapshot requirements.
26
6
 
27
7
  ## Install
28
8
 
@@ -32,51 +12,29 @@ npm i @praxisui/editorial-forms@latest
32
12
 
33
13
  Peer dependencies:
34
14
 
35
- - `@angular/common` `^21.0.0`
36
- - `@angular/core` `^21.0.0`
37
- - `@angular/material` `^21.0.0`
15
+ - `@angular/common`, `@angular/core`, `@angular/material` `^21.0.0`
38
16
  - `@praxisui/core` `^9.0.0-beta.1`
39
17
 
40
18
  Optional integration:
41
19
 
42
- - `@praxisui/dynamic-form` if your `dataCollection` blocks should render real forms instead of fallback content
20
+ - `@praxisui/dynamic-form` when `dataCollection` blocks should render real forms instead of fallback content.
43
21
 
44
- ## App provider
22
+ ## App Provider
45
23
 
46
- Register the package provider in hosts that render the runtime through dynamic
47
- widget composition, including `@praxisui/core` dynamic pages, page-builder
48
- previews, examples, recipes and labs:
24
+ Register the package provider when the runtime is rendered through dynamic widget composition, page-builder previews, examples, recipes or labs.
49
25
 
50
26
  ```ts
27
+ import { ApplicationConfig } from '@angular/core';
51
28
  import { providePraxisEditorialForms } from '@praxisui/editorial-forms';
52
29
 
53
- export const appConfig = {
54
- providers: [
55
- providePraxisEditorialForms(),
56
- ],
30
+ export const appConfig: ApplicationConfig = {
31
+ providers: [providePraxisEditorialForms()],
57
32
  };
58
33
  ```
59
34
 
60
- `providePraxisEditorialForms()` registers the package dynamic widget metadata for
61
- `praxis-editorial-form-runtime`. It does not register the optional
62
- `@praxisui/dynamic-form` adapter and does not create a global singleton runtime
63
- graph.
64
-
65
- Without this provider, hosts may still use `EditorialFormRuntimeComponent`
66
- directly through a standalone import, but `DynamicWidgetLoader` cannot discover
67
- `praxis-editorial-form-runtime` from a JSON page definition.
35
+ `providePraxisEditorialForms()` registers metadata for `praxis-editorial-form-runtime`. Direct standalone imports still work without it, but `DynamicWidgetLoader` cannot discover the runtime from JSON page definitions.
68
36
 
69
- ## Core concepts
70
-
71
- - `solution`: canonical editorial definition
72
- - `instance`: host/runtime instance with overrides and compatibility inputs
73
- - `journey`: resolved experience path
74
- - `presentation`: visual shell contract for orientation, density, theme tokens, and stepper behavior
75
- - `snapshot`: stable resolved state emitted to the host
76
- - `fallback`: operational state exposed as `normal`, `warning`, `degraded`, or `blocked`
77
- - `operationalEvent`: lightweight technical event for logs, monitoring, and runbooks
78
-
79
- ## Quick start
37
+ ## Quick Start
80
38
 
81
39
  ```ts
82
40
  import { Component } from '@angular/core';
@@ -102,7 +60,7 @@ import {
102
60
  `,
103
61
  })
104
62
  export class EditorialRuntimeDemoComponent {
105
- solution: EditorialRuntimeInput['solution'] = {
63
+ readonly solution: EditorialRuntimeInput['solution'] = {
106
64
  solutionId: 'privacy-consent',
107
65
  version: '1.0.0',
108
66
  problemType: 'generic',
@@ -115,196 +73,72 @@ export class EditorialRuntimeDemoComponent {
115
73
  {
116
74
  stepId: 'review',
117
75
  label: 'Review and confirm',
118
- blocks: [
119
- {
120
- blockId: 'consent-form',
121
- kind: 'dataCollection',
122
- formBlockId: 'consent-form',
123
- },
124
- ],
76
+ blocks: [{ blockId: 'consent-form', kind: 'dataCollection', formBlockId: 'consent-form' }],
125
77
  },
126
78
  ],
127
79
  },
128
80
  ],
129
81
  };
130
82
 
131
- instance: EditorialRuntimeInput['instance'] = {
83
+ readonly instance: EditorialRuntimeInput['instance'] = {
132
84
  journeyId: 'privacy-consent-journey',
133
85
  };
134
86
 
135
- runtimeContext: EditorialRuntimeInput['runtimeContext'] = {
87
+ readonly runtimeContext: EditorialRuntimeInput['runtimeContext'] = {
136
88
  locale: 'en-US',
137
89
  };
138
90
 
139
- hostConfig: EditorialRuntimeHostConfig = {
91
+ readonly hostConfig: EditorialRuntimeHostConfig = {
140
92
  emitOperationalEvents: true,
141
93
  forwardAdapterOperationalEvents: true,
142
94
  };
143
95
 
144
- onSnapshot(snapshot: unknown) {
145
- console.log('snapshot', snapshot);
146
- }
147
-
148
- onFallback(state: unknown) {
149
- console.log('fallback', state);
150
- }
96
+ onSnapshot(snapshot: unknown): void {}
97
+ onFallback(state: unknown): void {}
151
98
  }
152
99
  ```
153
100
 
154
- ## Stable host contract
155
-
156
- `EditorialFormRuntimeComponent` exposes these stable inputs:
157
-
158
- - `solution`
159
- - `instance`
160
- - `runtimeContext`
161
- - `hostConfig`
162
-
163
- Stable outputs:
164
-
165
- - `snapshotChange`
166
- - `fallbackChange`
167
- - `operationalEvent`
168
-
169
- Recommended host usage:
170
-
171
- - use `snapshotChange` for resolved state, audit trails, and product UX derivation
172
- - use `fallbackChange` for operational UX decisions
173
- - use `operationalEvent` for technical telemetry, not as primary user-facing UI content
174
- - keep `runtimeContext` immutable from the host side; the runtime now emits refreshed state as blocks and adapters materialize `formData`
175
-
176
- ## Dynamic widget composition
177
-
178
- The runtime publishes `praxis-editorial-form-runtime` as dynamic widget metadata
179
- with these canonical component ports:
101
+ ## Stable Runtime Contract
180
102
 
181
103
  Inputs:
182
104
 
183
- - `solution`
184
- - `instance`
185
- - `runtimeContext`
186
- - `hostConfig`
105
+ - `solution`: canonical editorial solution definition.
106
+ - `instance`: host/runtime instance with journey, context and overrides.
107
+ - `runtimeContext`: host-provided context merged with instance context.
108
+ - `hostConfig`: runtime telemetry and adapter forwarding options.
187
109
 
188
110
  Outputs:
189
111
 
190
- - `snapshotChange`
191
- - `fallbackChange`
192
- - `operationalEvent`
193
-
194
- Nested dynamic page links must target these ports through
195
- `composition.links` using `component-port` endpoints. When the editorial runtime
196
- is nested inside a container such as Tabs or Expansion, persist the nested child
197
- identity through `nestedPath` and keep the terminal segment as a widget segment
198
- with stable `key` and `componentType: "praxis-editorial-form-runtime"`.
199
-
200
- Do not expose `widgetEvent`, `bindingPath`, host-specific aliases, or
201
- container-owned child-specific ports as the final contract for editorial runtime
202
- composition.
203
-
204
- ## Presentation layer
205
-
206
- The runtime now supports an optional `presentation` contract inside the editorial `solution`.
207
-
208
- Current V1 coverage:
209
-
210
- - horizontal or vertical stepper
211
- - responsive collapse to mobile orientation through `layout.responsive.mobileOrientation`
212
- - density variants (`compact`, `comfortable`, `relaxed`)
213
- - theme tokens applied as CSS variables
214
- - shell max width and spacing overrides
215
- - visual step metadata (`kind`, `icon`, `visual`)
216
-
217
- Contractualized and currently effective in the renderer:
218
-
219
- - `presentation.layout.orientation`
220
- - `presentation.layout.density`
221
- - `presentation.layout.maxWidth`
222
- - `presentation.layout.spacing.pagePadding`
223
- - `presentation.layout.spacing.shellPadding`
224
- - `presentation.layout.spacing.blockGap`
225
- - `presentation.layout.spacing.sectionGap`
226
- - `presentation.layout.spacing.actionGap`
227
- - `presentation.layout.responsive.mobileOrientation`
228
- - `presentation.layout.responsive.collapseStepperBelow`
229
- - `presentation.layout.shellVariant`
230
- - `presentation.theme.*` tokens mapped in `buildRuntimeCssVars(...)`
231
- - `presentation.stepper.visible`
232
- - `presentation.stepper.orientation`
233
- - `presentation.stepper.showLabels`
234
- - `presentation.stepper.showDescriptions`
235
- - `presentation.stepper.showConnectors`
236
- - `presentation.stepper.connectorStyle`
237
- - `presentation.stepper.allowStepJump`
112
+ - `snapshotChange`: resolved state for audit trails, product UX and host derivation.
113
+ - `fallbackChange`: operational fallback state: `normal`, `warning`, `degraded` or `blocked`.
114
+ - `operationalEvent`: technical telemetry for logs, monitoring and runbooks.
238
115
 
239
- Accepted by schema but currently diagnosed as unsupported:
116
+ Dynamic widget id: `praxis-editorial-form-runtime`. Use `composition.links` with `component-port` endpoints for canonical dynamic-page wiring; do not expose container-specific child ports as the final contract.
240
117
 
241
- - `presentation.layout.contentAlign`
242
- - `presentation.layout.responsive.tabletOrientation`
243
- - `presentation.stepper.size`
244
- - `presentation.stepper.align`
245
- - `presentation.stepper.variant` values without distinct renderer behavior from `icon-label`
118
+ ## Presentation And I18n
246
119
 
247
- Important note:
120
+ The `solution.presentation` contract controls orientation, density, responsive behavior, shell spacing, theme tokens and stepper presentation. Unsupported accepted keys emit snapshot diagnostics instead of pretending runtime support.
248
121
 
249
- - when these unsupported keys are present, the runtime emits `presentation-config-unsupported` diagnostics in the snapshot instead of silently pretending support
250
-
251
- Current V1 presentational blocks:
252
-
253
- - `introHero`
254
- - `selectionCards`
255
- - `reviewSections`
256
- - `successPanel`
257
-
258
- Important note for hosts:
259
-
260
- - `selectionCards` and `dataCollection` now feed the same runtime context shape through immutable `runtimeContextChange` emissions
261
- - review blocks should consume `snapshot.context.formData` paths to stay consistent with the canonical runtime state
262
- - internal runtime copy now resolves through `PraxisI18nService`; the package exports `providePraxisEditorialFormsI18n(...)` with built-in `pt-BR` and `en-US` dictionaries
263
- - `reviewSections` now supports `EditorialReviewSectionField.format` for `date`, `phone`, `email`, `boolean` and `list`, while preserving plain text fallback when `format` is omitted
264
-
265
- If your host wants to override or extend the built-in runtime copy, register the package i18n provider:
122
+ Register i18n overrides with:
266
123
 
267
124
  ```ts
268
125
  import { providePraxisEditorialFormsI18n } from '@praxisui/editorial-forms';
269
126
 
270
- export const appConfig = {
271
- providers: [
272
- providePraxisEditorialFormsI18n({
273
- locale: 'en-US',
274
- dictionaries: {
275
- 'en-US': {
276
- 'praxis.editorialForms.runtime.actions.next': 'Continue',
277
- },
127
+ providers: [
128
+ providePraxisEditorialFormsI18n({
129
+ locale: 'en-US',
130
+ dictionaries: {
131
+ 'en-US': {
132
+ 'praxis.editorialForms.runtime.actions.next': 'Continue',
278
133
  },
279
- }),
280
- ],
281
- };
134
+ },
135
+ }),
136
+ ];
282
137
  ```
283
138
 
284
- ## Optional `dataCollection` adapter
285
-
286
- The core runtime does not hardwire `@praxisui/dynamic-form`.
139
+ ## Optional Dynamic Form Adapter
287
140
 
288
- If your host wants to render `dataCollection` blocks with Praxis Dynamic Form, register the optional adapter:
289
-
290
- ```ts
291
- import { provideEditorialDynamicFormAdapter } from '@praxisui/editorial-forms';
292
- import { PraxisDynamicForm } from '@praxisui/dynamic-form';
293
-
294
- export const appConfig = {
295
- providers: [
296
- provideEditorialDynamicFormAdapter({ component: PraxisDynamicForm }),
297
- ],
298
- };
299
- ```
300
-
301
- Important host contract:
302
-
303
- - the editorial adapter only registers the `dataCollection` renderer; it does not provide `GenericCrudService`
304
- - if your editorial flow materializes remote `@praxisui/dynamic-form` behavior, the host still owns the same DI contract documented for `praxis-dynamic-form`
305
- - when the effective form depends on remote schema, `resourcePath`, remote submit, or inherited `endpointKey`, provide `GenericCrudService` in the host scope that renders the runtime and configure that same instance before the form materializes
306
-
307
- Minimal host example:
141
+ The core editorial runtime does not hardwire `@praxisui/dynamic-form`. Register the optional adapter when `dataCollection` blocks should materialize Praxis Dynamic Form.
308
142
 
309
143
  ```ts
310
144
  import { GenericCrudService } from '@praxisui/core';
@@ -319,106 +153,21 @@ export const appConfig = {
319
153
  };
320
154
  ```
321
155
 
322
- Without this provider, `dataCollection` blocks degrade to an accessible fallback and the runtime keeps exposing the missing-adapter state through snapshot diagnostics and operational events.
323
-
324
- ## Public API highlights
325
-
326
- - `EditorialFormRuntimeComponent`
327
- - `PRAXIS_EDITORIAL_FORMS_AUTHORING_MANIFEST`
328
- - `resolveEditorialRuntimeSnapshot(...)`
329
- - `EditorialDataBlockAdapter`
330
- - `EDITORIAL_DATA_BLOCK_ADAPTER`
331
- - `provideEditorialDataBlockAdapter(...)`
332
- - `createEditorialDynamicFormAdapter(...)`
333
- - `provideEditorialDynamicFormAdapter(...)`
334
-
335
- Runtime model types:
336
-
337
- - `EditorialRuntimeInput`
338
- - `EditorialRuntimeHostConfig`
339
- - `EditorialRuntimeSnapshot`
340
- - `EditorialResolvedJourney`
341
- - `EditorialResolvedStep`
342
- - `EditorialResolvedBlock`
343
- - `EditorialRuntimeDiagnostic`
344
- - `EditorialRuntimeOperationalEvent`
345
-
346
- Presentation model types from `@praxisui/core`:
347
-
348
- - `EditorialWizardPresentation`
349
- - `EditorialLayoutConfig`
350
- - `EditorialThemeTokens`
351
- - `EditorialStepperConfig`
352
- - `EditorialStepVisualConfig`
353
-
354
- ## Agentic authoring contract
355
-
356
- `PRAXIS_EDITORIAL_FORMS_AUTHORING_MANIFEST` is the executable AI authoring contract for this package.
357
-
358
- The manifest governs editorial document orchestration:
359
-
360
- - `snapshot.set`
361
- - `fallback.configure`
362
- - `presentation.configure`
363
- - `adapter.bind`
364
- - `dataBlock.add`
365
- - `dataBlock.remove`
366
- - `fieldBinding.set`
367
-
368
- Boundary rules:
369
-
370
- - `solution`, `instance` and `runtimeContext` resolve into `EditorialRuntimeSnapshot` without hidden drift
371
- - `fallback` must be explicit and backed by diagnostics
372
- - `presentation` only changes `solution.presentation`; it must not mutate domain data
373
- - `dataCollection` blocks require a registered adapter that supports the requested context
374
- - `dataBlock` authoring uses canonical `blockId` and `kind`; `id` and `type` are not accepted aliases
375
- - `snapshot.set` updates canonical runtime inputs (`solution`, `instance.context`, and `runtimeContext`) and does not persist active journey state as `instance.journeyId`
376
- - `FieldMetadata` shape changes are delegated to `@praxisui/metadata-editor` and dynamic-fields discovery instead of being redefined here
377
-
378
- ## Resolution and fallback behavior
379
-
380
- The resolved snapshot formalizes:
381
-
382
- - deterministic block provenance with `primarySource` and `trail`
383
- - instance override policy with `append`, `insertBefore`, `insertAfter`, `replace`, and `remove`
384
- - resolved `dataCollectionState` before the concrete form engine renders
385
-
386
- Current `dataCollection` config resolution order:
387
-
388
- 1. `block.formConfig`
389
- 2. `instance.overrides.runtimeFormConfigs`
390
- 3. `instance.compatibilityFormConfigs`
391
-
392
- Fallback states:
393
-
394
- - `normal`
395
- - `warning`
396
- - `degraded`
397
- - `blocked`
398
-
399
- ## Architecture rule
400
-
401
- Allowed:
402
-
403
- - `@praxisui/editorial-forms -> @praxisui/core`
404
- - `@praxisui/editorial-forms -> @praxisui/dynamic-form` only through optional adapter/provider integration
156
+ The adapter registers the renderer only. The host still owns `GenericCrudService`, endpoint configuration, remote schema access and submit behavior required by dynamic forms.
405
157
 
406
- Avoid:
158
+ Without the adapter, `dataCollection` blocks render accessible fallback content and expose diagnostics through snapshots and operational events.
407
159
 
408
- - `@praxisui/core -> @praxisui/editorial-forms`
409
- - moving editorial domain growth back into `@praxisui/dynamic-form`
160
+ ## Authoring
410
161
 
411
- ## Validation status
162
+ `PRAXIS_EDITORIAL_FORMS_AUTHORING_MANIFEST` governs AI/tooling operations for snapshots, fallback, presentation, adapter binding, data block add/remove and field binding. `FieldMetadata` shape changes are delegated to `@praxisui/metadata-editor` and dynamic-fields discovery instead of being redefined by this package.
412
163
 
413
- The package is covered by:
164
+ ## Public API Snapshot
414
165
 
415
- - unit specs for runtime resolution and component behavior
416
- - controlled host specs for real Angular integration
417
- - end-to-end validation of editorial runtime flows in host routes
166
+ Main exports include `EditorialFormRuntimeComponent`, `providePraxisEditorialForms`, runtime contracts, snapshot/fallback/event models, preset resolution helpers, optional data-block adapter APIs, dynamic-form adapter APIs, renderer components, i18n helpers, testing fixtures and `PRAXIS_EDITORIAL_FORMS_AUTHORING_MANIFEST`.
418
167
 
419
- ## More reading
168
+ ## Official Links
420
169
 
421
- - Architecture: https://github.com/codexrodrigues/praxis-ui-angular/blob/main/projects/praxis-editorial-forms/docs/architecture.md
422
- - Continuation plan: https://github.com/codexrodrigues/praxis-ui-angular/blob/main/projects/praxis-editorial-forms/docs/continuation-plan.md
423
- - Authoring plan: https://github.com/codexrodrigues/praxis-ui-angular/blob/main/projects/praxis-editorial-forms/docs/editorial-authoring-plan.md
424
- - Recovery playbook: https://github.com/codexrodrigues/praxis-ui-angular/blob/main/projects/praxis-editorial-forms/docs/recovery-playbook.md
170
+ - Documentation: https://praxisui.dev/docs/components
171
+ - Live demo: https://praxis-ui-4e602.web.app
172
+ - Quickstart repository: https://github.com/codexrodrigues/praxis-ui-quickstart
173
+ - Source and issues: https://github.com/codexrodrigues/praxis-ui-angular
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@praxisui/editorial-forms",
3
- "version": "9.0.0-beta.1",
3
+ "version": "9.0.0-beta.2",
4
4
  "description": "Editorial form runtime for Praxis UI: journeys, presets, semantic blocks, and specialist hosting for editorial experiences.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/core": "^9.0.0-beta.1",
8
+ "@praxisui/core": "^9.0.0-beta.2",
9
9
  "@angular/material": "^21.0.0"
10
10
  },
11
11
  "dependencies": {
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "https://github.com/codexrodrigues/praxis-ui-angular"
20
+ "url": "git+https://github.com/codexrodrigues/praxis-ui-angular.git"
21
21
  },
22
22
  "homepage": "https://praxisui.dev",
23
23
  "bugs": {