@praxisui/rich-content 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 +71 -296
  2. package/package.json +6 -2
package/README.md CHANGED
@@ -1,14 +1,8 @@
1
1
  # @praxisui/rich-content
2
2
 
3
- Rich content rendering and authoring primitives for Praxis UI surfaces,
4
- including semantic blocks, governed action surfaces and page-builder
5
- integration.
3
+ Rich content rendering and authoring primitives for Praxis UI surfaces. Install `@praxisui/rich-content` when a host needs portable `RichContentDocument` JSON for semantic blocks, cards, metrics, timelines, action surfaces and page-builder widgets.
6
4
 
7
- ## Documentation
8
-
9
- - Official documentation: 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
5
+ The package renders structured content. It does not execute business actions by itself; interactive nodes delegate confirmation and dispatch to host capabilities.
12
6
 
13
7
  ## Install
14
8
 
@@ -17,20 +11,12 @@ npm i @praxisui/rich-content@latest
17
11
  ```
18
12
 
19
13
  Peer dependencies:
20
- - `@angular/core` `^21.0.0`
21
- - `@angular/common` `^21.0.0`
22
- - `@angular/forms` `^21.0.0`
14
+
15
+ - `@angular/common`, `@angular/core`, `@angular/forms` `^21.0.0`
23
16
  - `@praxisui/core` `^9.0.0-beta.1`
24
17
  - `rxjs` `~7.8.0`
25
18
 
26
- ## When to use
27
-
28
- - Render portable `RichContentDocument` JSON inside Praxis runtime surfaces
29
- - Provide page-builder widgets for semantic content blocks
30
- - Reuse the canonical rich-content editor instead of building local JSON editors
31
- - Validate rich documents before persistence with `validateRichContentDocument()`
32
-
33
- ## Minimal standalone renderer
19
+ ## Minimal Renderer
34
20
 
35
21
  ```ts
36
22
  import { Component } from '@angular/core';
@@ -44,7 +30,7 @@ import type { RichContentDocument } from '@praxisui/core';
44
30
  template: `<praxis-rich-content [document]="document" />`,
45
31
  })
46
32
  export class RichContentPreviewComponent {
47
- document: RichContentDocument = {
33
+ readonly document: RichContentDocument = {
48
34
  kind: 'praxis.rich-content',
49
35
  version: '1.0.0',
50
36
  nodes: [
@@ -55,308 +41,97 @@ export class RichContentPreviewComponent {
55
41
  }
56
42
  ```
57
43
 
58
- `PraxisRichContent` renders metadata-driven rich nodes and blocks used by Praxis
59
- components such as table renderers, list metrics and compact status surfaces.
44
+ Use `layout="inline"` for compact compositions such as icon + text, badges, links or value/caption pairs. The default `layout="block"` preserves document-style rendering.
45
+
46
+ ```html
47
+ <praxis-rich-content
48
+ layout="inline"
49
+ rootClassName="status-badge__content"
50
+ [nodes]="[
51
+ { type: 'icon', icon: 'check_circle' },
52
+ { type: 'text', text: 'Active' }
53
+ ]"
54
+ />
55
+ ```
60
56
 
61
57
  ## Page Builder Integration
62
58
 
63
- `@praxisui/rich-content` is a first-class widget for `@praxisui/page-builder`.
64
- Register the metadata provider so the palette can discover the renderer:
59
+ Register the metadata provider so `@praxisui/page-builder` and dynamic widget loaders can discover the component and its canonical settings editor.
65
60
 
66
61
  ```ts
62
+ import { ApplicationConfig } from '@angular/core';
67
63
  import { providePraxisRichContentMetadata } from '@praxisui/rich-content';
68
64
 
69
- bootstrapApplication(AppComponent, {
70
- providers: [
71
- providePraxisRichContentMetadata(),
72
- ],
73
- });
65
+ export const appConfig: ApplicationConfig = {
66
+ providers: [providePraxisRichContentMetadata()],
67
+ };
74
68
  ```
75
69
 
76
- Use the component as a page widget by setting `definition.id` to
77
- `praxis-rich-content` and passing the canonical document through
78
- `definition.inputs.document`.
70
+ Use widget id `praxis-rich-content` and pass the document through `definition.inputs.document`.
71
+
72
+ ## Document Contract
73
+
74
+ `RichContentDocument` must use:
79
75
 
80
76
  ```ts
81
- const page = {
82
- widgets: [
83
- {
84
- key: 'overview-rich-content',
85
- definition: {
86
- id: 'praxis-rich-content',
87
- inputs: {
88
- document: {
89
- kind: 'praxis.rich-content',
90
- version: '1.0.0',
91
- nodes: [
92
- {
93
- type: 'card',
94
- title: 'Resumo',
95
- content: [
96
- { type: 'text', text: 'Conteudo editorial declarativo' },
97
- { type: 'badge', label: 'canonico' },
98
- ],
99
- },
100
- ],
101
- },
102
- },
103
- },
104
- },
105
- ],
106
- };
77
+ {
78
+ kind: 'praxis.rich-content',
79
+ version: '1.0.0',
80
+ nodes: []
81
+ }
82
+ ```
83
+
84
+ The runtime supports semantic presentation nodes such as text, badges, icons, cards, callouts, key/value lists, stats, tabs, timelines, lookup surfaces, record summaries, action cards, media blocks and presets. Use official docs for the full node vocabulary.
85
+
86
+ Conditional metadata is governed by the shared JSON Logic contract:
87
+
88
+ - `visibleWhen` and `loadWhen` gate rendering.
89
+ - `disabledWhen` disables interactive surfaces.
90
+ - `classWhen` and `styleWhen` apply declarative visual state.
91
+ - Invalid visibility/loading/style rules fail closed; invalid `disabledWhen` fails safe by disabling the action.
92
+
93
+ Validate before persistence:
94
+
95
+ ```ts
96
+ import { validateRichContentDocument } from '@praxisui/rich-content';
97
+
98
+ const result = validateRichContentDocument(document);
99
+ if (!result.valid) {
100
+ throw new Error(result.issues[0]?.message ?? 'Invalid rich content document');
101
+ }
107
102
  ```
108
103
 
109
- For AI-assisted page authoring, register `RICH_CONTENT_AI_CAPABILITIES` in the
110
- page-builder widget catalog map for `praxis-rich-content`.
111
-
112
- ## Visual Authoring
113
-
114
- The component metadata exposes `PraxisRichContentConfigEditor` as the canonical
115
- settings-panel editor for `praxis-rich-content`. Hosts such as
116
- `@praxisui/page-builder` should open this editor from the component metadata
117
- instead of creating local rich-content JSON editors.
118
-
119
- The canonical editor provides structured block authoring for common top-level
120
- nodes (`text`, `badge`, `icon`, `image`, `metric`, `progress`, `compose`,
121
- `link`, `actionButton`, `card`, `callout`, `ctaGroup`, `keyValueList`,
122
- `emptyState`, `propertySheet`, `statGroup`, `tabs`, `recordSummary`, `lookupResult`, `lookupCard`, `relatedRecord`,
123
- `actionCard`, `collapsibleCard`, `disclosure`, `accordion`, `formLauncher`, `mediaBlock`,
124
- `timeline` and `preset`), including add, reorder, inline removal confirmation
125
- and field-level editing. It also supports nested authoring for
126
- `card.content[]`, named card slots, `compose.items[]`, `timeline.items[]` and
127
- governed action collections such as `callout.actions[]`,
128
- `recordSummary.actions[]`, `lookupCard.secondaryActions[]`, `actionCard.secondaryActions[]` and
129
- `disclosure.actions[]`, plus governed preset selection from
130
- `PRAXIS_RICH_BLOCK_PRESETS`. Common node metadata such as `testId`,
131
- `className`, capability-gated visibility (`requiresCapabilities` and
132
- `capabilityMode`), a simple `visibleWhen` equality rule and one safe inline
133
- style declaration can be edited visually. Advanced JSON remains available for
134
- less common nested fields and deep structures, but it is no longer the only
135
- authoring path.
136
-
137
- Runtime conditional metadata is governed by the shared JSON Logic contract:
138
- `visibleWhen` and `loadWhen` gate rendering, `disabledWhen` disables interactive
139
- surfaces, and `classWhen`/`styleWhen` apply declarative visual state. Invalid
140
- visibility/loading/style rules fail closed by not rendering or not applying the
141
- rule; invalid `disabledWhen` fails safe by disabling the action surface.
142
-
143
- The editor receives the widget input envelope and returns the same canonical
144
- shape expected by the runtime:
104
+ The validator rejects unsupported document versions, unknown node types, unsafe URLs, unsafe style values and malformed nested nodes.
105
+
106
+ ## Authoring
107
+
108
+ `PraxisRichContentConfigEditor` is the canonical Settings Panel editor for `praxis-rich-content`. It opens and saves the same widget input envelope consumed by the renderer:
145
109
 
146
110
  ```ts
147
111
  {
148
112
  inputs: {
149
- document: {
150
- kind: 'praxis.rich-content',
151
- version: '1.0.0',
152
- nodes: []
153
- },
113
+ document: { kind: 'praxis.rich-content', version: '1.0.0', nodes: [] },
154
114
  layout: 'block',
155
- rootClassName: 'employee-expansion-rich'
115
+ rootClassName: 'employee-summary'
156
116
  }
157
117
  }
158
118
  ```
159
119
 
160
- This keeps the authoring round-trip aligned with the renderer:
161
- `open -> edit -> apply/save -> persist -> reopen -> render`.
162
-
163
- Authoring labels, helper text and validation messages use the rich-content i18n
164
- dictionary. Apps can provide overrides with `providePraxisRichContentI18n()` or
165
- reuse `resolvePraxisRichContentText()` when extending the canonical editor.
166
-
167
- The editor validates the public `RichContentDocument` contract before
168
- Apply/Save. Hosts that need the same checks outside the settings panel can use
169
- `validateRichContentDocument()` from `@praxisui/rich-content` to reject
170
- unsupported document versions, unknown node types, unsafe URLs, unsafe style
171
- values and malformed nested nodes before persistence.
172
-
173
- ### Timeline authoring
174
-
175
- `timeline` is a governed rich-content block, not a local page-builder widget.
176
- The public document contract supports node-level presentation fields
177
- `orientation`, `order`, `position`, `connectorVariant`, `connectorColor`,
178
- `markerVariant`, `markerColor` and `markerStyle`, plus item-level `opposite`
179
- and `oppositeExpr` content. `orientation` accepts `vertical` or `horizontal`;
180
- `order` accepts `normal` or `reverse`, allowing hosts and agents to publish the
181
- same lifecycle data as a vertical document flow, a horizontal process rail or a
182
- reverse chronological activity stream without reshaping `timeline.items[]`.
183
- Timeline items may override `connectorVariant`, `connectorColor`, `markerColor`
184
- and `markerStyle` when a specific step needs status or exception emphasis.
185
- These fields are available through the canonical rich-content editor, validated
186
- by `validateRichContentDocument()` and consumed directly by the runtime
187
- renderer.
188
-
189
- Use timeline node settings when the host needs to publish lifecycle, workflow or
190
- operational history as portable `RichContentDocument` JSON. Use item-level
191
- fields such as `title`, `subtitle`, `meta`, `icon`, `badge` and `opposite` for
192
- display data, with `*Expr` variants when the values come from the widget
193
- context.
194
-
195
- ## Semantic blocks and interactive surfaces
196
-
197
- `@praxisui/rich-content` now supports a broader contract for configuration-first
198
- platform surfaces:
199
-
200
- - semantic editorial blocks such as `callout`, `keyValueList`, `emptyState`,
201
- `recordSummary`, `statGroup`, `tabs`, `lookupResult`, `lookupCard`, `relatedRecord`, `actionCard`, `collapsibleCard`,
202
- `disclosure` and `accordion`
203
- - interactive buttons through `actionButton`, mediated by
204
- `hostCapabilities.dispatchAction(...)`; when `action.confirmMessage` is
205
- present, runtime first calls `hostCapabilities.confirmAction(...)` and fails
206
- closed without dispatch if the host does not confirm
207
- - governed action surfaces such as `lookupCard`, `relatedRecord`, `actionCard` and `formLauncher`, which keep
208
- the document canonical while delegating execution to host capabilities
209
- - capability-gated visibility through `requiresCapabilities` and
210
- `capabilityMode`
211
- - richer `card` composition through semantic surface fields (`variant`, `tone`,
212
- `size`, `density`, `orientation`), optional `media`, `headerAction`,
213
- whole-card `interaction`, accessibility overrides and named slots (`header`,
214
- `body`, `footer`, `actions`, `aside`) while preserving the required
215
- `content[]` path for existing consumers
216
-
217
- This keeps purely visual content (`card`, `callout`, `keyValueList`) distinct
218
- from host-mediated interaction (`actionButton`) without introducing ad hoc host
219
- JSON.
220
-
221
- Example semantic card surface:
222
-
223
- ```ts
224
- const document: RichContentDocument = {
225
- kind: 'praxis.rich-content',
226
- version: '1.0.0',
227
- nodes: [
228
- {
229
- type: 'card',
230
- titleExpr: '${decision.title}',
231
- subtitleExpr: '${decision.source}',
232
- variant: 'elevated',
233
- tone: 'info',
234
- size: 'lg',
235
- orientation: 'horizontal',
236
- media: {
237
- kind: 'icon',
238
- icon: 'psychology',
239
- label: 'AI-authored decision surface',
240
- placement: 'leading',
241
- },
242
- interaction: {
243
- mode: 'action',
244
- action: { actionId: 'decision.open' },
245
- },
246
- accessibility: {
247
- role: 'button',
248
- ariaLabel: 'Open decision surface',
249
- },
250
- content: [
251
- { type: 'text', textExpr: '${decision.summary}' },
252
- ],
253
- },
254
- ],
255
- };
256
- ```
120
+ The editor supports structured block authoring, nested card/timeline/action collections, preset selection and advanced JSON for less common deep structures. Labels and validation messages use the rich-content i18n dictionary; override them with `providePraxisRichContentI18n()`.
257
121
 
258
- ## Governed presets
259
-
260
- The preset registry still uses `PRAXIS_RICH_BLOCK_PRESETS`, and the lib now also
261
- publishes `providePraxisDefaultRichBlockPresets()` with a small canonical starter
262
- set for configuration-first hosts:
263
-
264
- - `callout-guidance`
265
- - `empty-state-launcher`
266
- - `record-summary-compact`
267
-
268
- For widget hosts such as `@praxisui/page-builder`, the component metadata also
269
- publishes insertion presets through `ComponentDocMeta.insertionPresets`. The
270
- current canonical starter set is:
271
-
272
- - `editorial-card`
273
- - `callout-guidance`
274
- - `cta-group`
275
- - `knowledge-surface`
276
- - `lookup-card`
277
- - `related-record`
278
- - `action-card`
279
- - `approval-audit-surface`
280
- - `approval-decision-surface`
281
- - `approval-review-surface`
282
- - `approval-sla-triage-surface`
283
- - `approval-delegation-exception-surface`
284
- - `employee-insight-surface`
285
- - `hr-compensation-review-surface`
286
- - `hr-performance-review-surface`
287
- - `hr-promotion-review-surface`
288
- - `hr-offboarding-surface`
289
- - `hr-succession-planning-surface`
290
- - `hr-leave-absence-surface`
291
- - `hr-internal-mobility-surface`
292
- - `onboarding-journey-surface`
293
- - `onboarding-equipment-access-recovery-surface`
294
- - `onboarding-day-30-coaching-surface`
295
- - `onboarding-manager-follow-up-surface`
296
- - `onboarding-readiness-surface`
297
- - `stat-group`
298
- - `timeline-surface`
299
- - `tabs-surface`
300
-
301
- Hosts can use the defaults directly or provide their own governed preset pack.
302
-
303
- ## Agentic Authoring Contract
304
-
305
- `@praxisui/rich-content` publishes an executable `ComponentAuthoringManifest`
306
- through `PRAXIS_RICH_CONTENT_AUTHORING_MANIFEST`.
307
-
308
- The manifest treats rich content as structured `RichContentDocument` data, not
309
- HTML or markdown patches. It governs document replacement, block add/remove,
310
- block order, text updates, canonical link nodes, common node metadata,
311
- `mediaBlock` fields, timeline node settings, `timeline.items[]`, preset refs
312
- and sanitization policy.
313
- Security-sensitive policy edits and destructive removals require confirmation
314
- before a patch can be compiled.
315
-
316
- Link authoring uses a first-class `link` node with `label`, `href`, `target`
317
- and `rel`; unsafe protocols are rejected by `validateRichContentDocument()`.
318
-
319
- Each operation declares its own editable target resolver, ambiguity policy,
320
- preconditions, validators, affected paths, effects and typed submission impact.
321
- Document, block, text, link, media, timeline, preset, metadata and sanitization
322
- operations are `config-only` because they edit the structured widget input
323
- contract. `display.mode.set` is `visual-only` because it changes `layout` and
324
- `rootClassName` without mutating the `RichContentDocument`.
325
-
326
- ## Layout Modes
327
-
328
- The component defaults to `layout="block"` to preserve document-style rendering.
329
- Use `layout="inline"` when rendering compact multi-node compositions such as
330
- `icon + text`, badges, chips, links, buttons or value/caption pairs.
122
+ `PRAXIS_RICH_CONTENT_AUTHORING_MANIFEST` describes governed AI/tooling operations for document replacement, block add/remove/order, text updates, link nodes, media blocks, timeline nodes/items, presets, metadata and sanitization policy. Rich content authoring is structured JSON, not arbitrary HTML or markdown patches.
331
123
 
332
- ```html
333
- <praxis-rich-content
334
- layout="inline"
335
- rootClassName="status-badge__content"
336
- [nodes]="[
337
- { type: 'icon', icon: 'check_circle' },
338
- { type: 'text', text: 'Ativo' }
339
- ]"
340
- ></praxis-rich-content>
341
- ```
124
+ ## Presets
342
125
 
343
- Inline mode adds `prx-rich-content-root--inline` to the root and
344
- `prx-rich-node--inline` to each rendered node, allowing host components to align
345
- siblings without overriding the default block contract.
126
+ Use `PRAXIS_RICH_BLOCK_PRESETS` for host-governed preset registries. `providePraxisDefaultRichBlockPresets()` publishes a small starter set, and component metadata exposes insertion presets for page-builder-style hosts.
346
127
 
347
- Consumers can tune inline layout through inherited CSS custom properties on the
348
- `praxis-rich-content` host or an ancestor:
128
+ ## Public API Snapshot
349
129
 
350
- ```css
351
- .metric-value {
352
- --prx-rich-content-inline-align-items: baseline;
353
- --prx-rich-content-inline-flex-wrap: wrap;
354
- --prx-rich-content-inline-gap: 6px;
355
- }
356
- ```
130
+ Main exports include `PraxisRichContent`, `PraxisRichContentConfigEditor`, `RichContentPresetRegistryService`, `validateRichContentDocument`, `providePraxisRichContentMetadata`, rich-content i18n helpers, AI capabilities and `PRAXIS_RICH_CONTENT_AUTHORING_MANIFEST`.
357
131
 
358
- Supported inline variables:
132
+ ## Official Links
359
133
 
360
- - `--prx-rich-content-inline-align-items`, default `center`
361
- - `--prx-rich-content-inline-flex-wrap`, default `nowrap`
362
- - `--prx-rich-content-inline-gap`, default `6px`
134
+ - Documentation: https://praxisui.dev/docs/components
135
+ - Live demo: https://praxis-ui-4e602.web.app
136
+ - Quickstart repository: https://github.com/codexrodrigues/praxis-ui-quickstart
137
+ - Source and issues: https://github.com/codexrodrigues/praxis-ui-angular
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@praxisui/rich-content",
3
- "version": "9.0.0-beta.1",
3
+ "version": "9.0.0-beta.2",
4
4
  "description": "Rich content rendering and authoring primitives for Praxis UI surfaces, including semantic blocks and page-builder integration.",
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/forms": "^21.0.0",
10
10
  "rxjs": "~7.8.0"
11
11
  },
@@ -13,6 +13,10 @@
13
13
  "tslib": "^2.3.0"
14
14
  },
15
15
  "sideEffects": false,
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/codexrodrigues/praxis-ui-angular.git"
19
+ },
16
20
  "module": "fesm2022/praxisui-rich-content.mjs",
17
21
  "typings": "types/praxisui-rich-content.d.ts",
18
22
  "exports": {