@praxisui/rich-content 10.0.0-rc.24 → 10.0.0-rc.26

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/README.md CHANGED
@@ -130,6 +130,27 @@ then resolves bindings and Json Logic without mutating the authored document.
130
130
 
131
131
  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.
132
132
 
133
+ Card nodes (`type: 'card'`) support `media.kind` values `'image'`, `'video'`, `'icon'`, `'avatar'`, `'telemetry'`, `'lottie'`, and `'component'`. When `media.kind === 'component'`, the runtime materializes the component registered in `ComponentMetadataRegistry` under `media.componentId` via `DynamicWidgetLoaderDirective`, forwarding `media.componentInputs` and the active `RichContent` `[context]` so `${...}` template expressions inside `componentInputs` resolve reactively against host/page data sources. Optional `media.width`, `media.height`, `media.aspectRatio`, `media.placement`, and `media.verticalAlign` govern the media slot geometry without custom CSS:
134
+
135
+ ```json
136
+ {
137
+ "type": "card",
138
+ "orientation": "horizontal",
139
+ "title": "Operational Readiness",
140
+ "content": [],
141
+ "media": {
142
+ "kind": "component",
143
+ "componentId": "custom-telemetry-widget",
144
+ "placement": "trailing",
145
+ "verticalAlign": "center",
146
+ "componentInputs": {
147
+ "label": "Readiness ${readinessRate}%",
148
+ "interactive": true
149
+ }
150
+ }
151
+ }
152
+ ```
153
+
133
154
  Conditional metadata is governed by the shared JSON Logic contract:
134
155
 
135
156
  - `visibleWhen` and `loadWhen` gate rendering.
@@ -166,7 +187,7 @@ The validator rejects unsupported document versions, unknown node types, unsafe
166
187
 
167
188
  The editor separates authoring into guided editing, preview and advanced JSON tabs. Guided editing keeps the document structure visible while document-level context (`context.scopes`, `context.aliases`) and the selected block expose focused controls. The advanced data/rule section surfaces canonical bindings and JsonLogic fields (`bindings`, `disabledWhen`, `loadWhen`, `classWhen`, `styleWhen`) as focused JSON editors, validates them before apply/save, and keeps the full document JSON synchronized. Preview renders the materialized document without mixing authoring fields, and advanced JSON remains available for diagnostics, migration and less common deep structures.
168
189
 
169
- The editor supports structured block authoring, nested card/timeline/action collections, preset selection, validation badges and advanced JSON for less common deep structures. Clearing `rootClassName` emits `rootClassName: ''` so host runtime bindings clear any previously applied class, and the renderer safely ignores `null`/`undefined` or whitespace-only values. Card slots (`header`, `footer`, `aside`), card content and top-level `compose` blocks support nested `compose` structures with both Flex (`direction`, `gap`, `wrap`, `alignItems`) and CSS Grid (`layout: 'grid'`, `columns`, `minColumnWidth`, `gap`, `alignItems`) configurations plus nested items. All nested presenter and action nodes inside `card` (`header`, `content`, `actions`, `footer`, `aside`) and `compose` expose `className` in the guided editor, display explicit target breadcrumbs (`Card › Section › Compose › Item`), and support deep structure tree navigation (`Card -> Slot -> Compose -> Item`) and item reordering.
190
+ The editor supports structured block authoring, nested card/timeline/action collections, card media component discovery via `ComponentMetadataRegistry` (`media.kind = 'component'`), preset selection, validation badges and advanced JSON for less common deep structures. Clearing `rootClassName` emits `rootClassName: ''` so host runtime bindings clear any previously applied class, and the renderer safely ignores `null`/`undefined` or whitespace-only values. Card slots (`header`, `footer`, `aside`), card content and top-level `compose` blocks support nested `compose` structures with both Flex (`direction`, `gap`, `wrap`, `alignItems`) and CSS Grid (`layout: 'grid'`, `columns`, `minColumnWidth`, `gap`, `alignItems`) configurations plus nested items. All nested presenter and action nodes inside `card` (`header`, `content`, `actions`, `footer`, `aside`) and `compose` expose `className` in the guided editor, display explicit target breadcrumbs (`Card › Section › Compose › Item`), and support deep structure tree navigation (`Card -> Slot -> Compose -> Item`) and item reordering.
170
191
 
171
192
  Both top-level and nested `icon` and `badge` nodes expose didactic visual appearance controls in the guided editor that persist directly to canonical `node.style` (without requiring host-specific CSS classes):
172
193
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-15T13:55:17.858Z",
3
+ "generatedAt": "2026-10-15T19:07:41.629Z",
4
4
  "packageName": "@praxisui/rich-content",
5
- "packageVersion": "10.0.0-rc.24",
5
+ "packageVersion": "10.0.0-rc.26",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -4702,7 +4702,8 @@
4702
4702
  "icon",
4703
4703
  "avatar",
4704
4704
  "telemetry",
4705
- "lottie"
4705
+ "lottie",
4706
+ "component"
4706
4707
  ]
4707
4708
  },
4708
4709
  "src": {
@@ -4737,6 +4738,20 @@
4737
4738
  "aspectRatio": {
4738
4739
  "type": "string"
4739
4740
  },
4741
+ "width": {
4742
+ "type": "string"
4743
+ },
4744
+ "height": {
4745
+ "type": "string"
4746
+ },
4747
+ "verticalAlign": {
4748
+ "enum": [
4749
+ "center",
4750
+ "top",
4751
+ "bottom",
4752
+ "stretch"
4753
+ ]
4754
+ },
4740
4755
  "objectFit": {
4741
4756
  "enum": [
4742
4757
  "cover",
@@ -4752,6 +4767,12 @@
4752
4767
  "animationSrcExpr": {
4753
4768
  "type": "string"
4754
4769
  },
4770
+ "componentId": {
4771
+ "type": "string"
4772
+ },
4773
+ "componentInputs": {
4774
+ "type": "object"
4775
+ },
4755
4776
  "telemetry": {
4756
4777
  "type": "object",
4757
4778
  "properties": {
@@ -7557,9 +7578,9 @@
7557
7578
  {
7558
7579
  "chunkIndex": 22,
7559
7580
  "chunkKind": "authoring_manifest",
7560
- "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-rich-content\",\"ownerPackage\":\"@praxisui/rich-content\",\"configSchemaId\":\"RichContentDocument\",\"chunkSection\":\"operations[2]\",\"fragmentPath\":\"operations[2]\",\"fragmentIdentity\":{\"operationId\":\"block.update\"},\"fragment\":{\"operationId\":\"block.update\",\"title\":\"Update rich content block fields\",\"scope\":\"templating\",\"targetKind\":\"block\",\"target\":{\"kind\":\"block\",\"resolver\":\"rich-block-node-by-id-or-path\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"minProperties\":1,\"properties\":{\"id\":{\"type\":\"string\"},\"testId\":{\"type\":\"string\"},\"className\":{\"type\":\"string\"},\"style\":{\"type\":\"object\"},\"visibleWhen\":{\"type\":\"object\"},\"disabledWhen\":{\"type\":\"object\"},\"loadWhen\":{\"type\":\"object\"},\"classWhen\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"styleWhen\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"requiresCapabilities\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"capabilityMode\":{\"enum\":[\"all\",\"any\"]},\"text\":{\"type\":\"string\"},\"textExpr\":{\"type\":\"string\"},\"label\":{\"type\":\"string\"},\"labelExpr\":{\"type\":\"string\"},\"href\":{\"type\":\"string\"},\"target\":{\"enum\":[\"_self\",\"_blank\"]},\"rel\":{\"type\":\"string\"},\"src\":{\"type\":\"string\"},\"alt\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"titleExpr\":{\"type\":\"string\"},\"subtitle\":{\"type\":\"string\"},\"subtitleExpr\":{\"type\":\"string\"},\"relationLabel\":{\"type\":\"string\"},\"message\":{\"type\":\"string\"},\"summary\":{\"type\":\"string\"},\"summaryExpr\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"ctaLabel\":{\"type\":\"string\"},\"caption\":{\"type\":\"string\"},\"emptyText\":{\"type\":\"string\"},\"errorText\":{\"type\":\"string\"},\"status\":{\"enum\":[\"idle\",\"resolved\",\"empty\",\"error\",\"draft\",\"simulated\",\"approved\",\"published\",\"superseded\",\"reverted\"]},\"statusExpr\":{\"type\":\"string\"},\"owner\":{\"type\":\"string\"},\"ownerExpr\":{\"type\":\"string\"},\"policySource\":{\"type\":\"string\"},\"policySourceExpr\":{\"type\":\"string\"},\"version\":{\"type\":\"string\"},\"versionExpr\":{\"type\":\"string\"},\"confidence\":{\"type\":\"number\"},\"confidenceExpr\":{\"type\":\"string\"},\"risk\":{\"enum\":[\"low\",\"medium\",\"high\",\"critical\"]},\"riskExpr\":{\"type\":\"string\"},\"lastReviewed\":{\"type\":\"string\"},\"lastReviewedExpr\":{\"type\":\"string\"},\"supersedes\":{\"type\":\"string\"},\"supersedesExpr\":{\"type\":\"string\"},\"evidence\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"appearance\":{\"enum\":[\"plain\",\"card\",\"underline\",\"pills\"]},\"variant\":{\"enum\":[\"basic\",\"raised\",\"stroked\",\"flat\",\"plain\",\"outlined\",\"elevated\",\"filled\",\"transparent\",\"unstyled\"]},\"tone\":{\"enum\":[\"neutral\",\"info\",\"success\",\"warning\",\"danger\"]},\"size\":{\"enum\":[\"sm\",\"md\",\"lg\"]},\"density\":{},\"orientation\":{},\"loading\":{\"type\":\"boolean\"},\"loadingExpr\":{\"type\":\"string\"},\"active\":{\"type\":\"boolean\"},\"activeExpr\":{\"type\":\"string\"},\"defaultTabId\":{\"type\":\"string\"},\"order\":{\"enum\":[\"normal\",\"reverse\"]},\"position\":{\"enum\":[\"left\",\"right\",\"alternate\",\"alternate-reverse\"]},\"connectorVariant\":{\"enum\":[\"solid\",\"dashed\",\"none\"]},\"connectorColor\":{\"enum\":[\"primary\",\"secondary\",\"tertiary\",\"success\",\"warning\",\"error\",\"danger\",\"info\",\"neutral\"]},\"markerVariant\":{\"enum\":[\"dot\",\"icon\",\"number\"]},\"markerColor\":{\"enum\":[\"primary\",\"secondary\",\"tertiary\",\"success\",\"warning\",\"error\",\"danger\",\"info\",\"neutral\"]},\"markerStyle\":{\"enum\":[\"filled\",\"outlined\"]},\"emphasis\":{\"enum\":[\"subtle\",\"standard\",\"strong\",\"hero\"]},\"textAppearance\":{\"enum\":[\"default\",\"prominent\",\"eyebrow\",\"label\"]},\"icon\":{\"type\":\"string\"},\"formId\":{\"type\":\"string\"},\"columns\":{\"oneOf\":[{\"type\":\"number\"},{\"enum\":[\"auto-fit\",\"auto-fill\"]}]},\"minColumnWidth\":{\"type\":\"string\"},\"alignItems\":{\"enum\":[\"stretch\",\"start\",\"center\",\"end\"]},\"layout\":{\"enum\":[\"stacked\",\"inline\",\"split\",\"grid\",\"flex\"]},\"ctaPlacement\":{\"enum\":[\"bottom\",\"inline\",\"trailing\"]},\"ctaVariant\":{\"enum\":[\"elevated\",\"stroked\",\"flat\",\"tonal\",\"raised\"]},\"action\":{\"type\":\"object\"},\"actions\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"primaryAction\":{\"type\":\"object\"},\"secondaryActions\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"media\":{\"type\":\"object\",\"properties\":{\"kind\":{\"enum\":[\"image\",\"video\",\"icon\",\"avatar\",\"telemetry\",\"lottie\"]},\"src\":{\"type\":\"string\"},\"srcExpr\":{\"type\":\"string\"},\"alt\":{\"type\":\"string\"},\"altExpr\":{\"type\":\"string\"},\"icon\":{\"type\":\"string\"},\"label\":{\"type\":\"string\"},\"labelExpr\":{\"type\":\"string\"},\"placement\":{\"enum\":[\"top\",\"leading\",\"trailing\",\"background\"]},\"aspectRatio\":{\"type\":\"string\"},\"objectFit\":{\"enum\":[\"cover\",\"contain\",\"fill\",\"none\",\"scale-down\"]},\"animationSrc\":{\"type\":\"string\"},\"animationSrcExpr\":{\"type\":\"string\"},\"telemetry\":{\"type\":\"object\",\"properties\":{\"variant\":{\"enum\":[\"radar\",\"pulse\",\"wave\",\"signal\"]},\"speed\":{\"enum\":[\"slow\",\"normal\",\"fast\"]},\"color\":{\"type\":\"string\"},\"interactive\":{\"type\":\"boolean\"}}}}},\"headerAction\":{\"type\":\"object\"},\"headingLevel\":{\"enum\":[1,2,3,4,5,6]},\"identity\":{\"type\":\"object\"},\"breadcrumbs\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"overflowActions\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"relatedLinks\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"interaction\":{\"type\":\"object\",\"properties\":{\"mode\":{\"enum\":[\"none\",\"action\",\"selectable\"]},\"action\":{\"type\":\"object\"},\"selected\":{\"type\":\"boolean\"},\"selectedExpr\":{\"type\":\"string\"}}},\"accessibility\":{\"type\":\"object\",\"properties\":{\"role\":{\"enum\":[\"article\",\"group\",\"button\"]},\"ariaLabel\":{\"type\":\"string\"},\"ariaLabelExpr\":{\"type\":\"string\"},\"ariaLabelledBy\":{\"type\":\"string\"},\"ariaDescribedBy\":{\"type\":\"string\"}}},\"fields\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"items\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"},\"label\":{\"type\":\"string\"},\"labelExpr\":{\"type\":\"string\"},\"value\":{\"type\":\"string\"},\"valueExpr\":{\"type\":\"string\"},\"hint\":{\"type\":\"string\"},\"hintExpr\":{\"type\":\"string\"},\"icon\":{\"type\":\"string\"},\"action\":{\"type\":\"object\"},\"progress\":{\"type\":\"object\",\"properties\":{\"value\":{\"type\":\"number\"},\"valueExpr\":{\"type\":\"string\"},\"max\":{\"type\":\"number\"},\"showPercent\":{\"type\":\"boolean\"},\"variant\":{\"enum\":[\"bar\",\"ring\"]},\"tone\":{\"enum\":[\"neutral\",\"info\",\"success\",\"warning\",\"danger\"]}}}}}},\"header\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"body\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"footer\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"aside\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}}}},\"effects\":[{\"kind\":\"merge-by-key\",\"path\":\"document.nodes[]\",\"key\":\"id\"}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"block-exists\",\"node-types-supported\",\"unsafe-url-rejected\",\"unsafe-style-rejected\",\"expression-path-safe\",\"document-shape-canonical\",\"editor-runtime-round-trip\"]}}",
7581
+ "content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"praxis-rich-content\",\"ownerPackage\":\"@praxisui/rich-content\",\"configSchemaId\":\"RichContentDocument\",\"chunkSection\":\"operations[2]\",\"fragmentPath\":\"operations[2]\",\"fragmentIdentity\":{\"operationId\":\"block.update\"},\"fragment\":{\"operationId\":\"block.update\",\"title\":\"Update rich content block fields\",\"scope\":\"templating\",\"targetKind\":\"block\",\"target\":{\"kind\":\"block\",\"resolver\":\"rich-block-node-by-id-or-path\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"minProperties\":1,\"properties\":{\"id\":{\"type\":\"string\"},\"testId\":{\"type\":\"string\"},\"className\":{\"type\":\"string\"},\"style\":{\"type\":\"object\"},\"visibleWhen\":{\"type\":\"object\"},\"disabledWhen\":{\"type\":\"object\"},\"loadWhen\":{\"type\":\"object\"},\"classWhen\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"styleWhen\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"requiresCapabilities\":{\"type\":\"array\",\"items\":{\"type\":\"string\"}},\"capabilityMode\":{\"enum\":[\"all\",\"any\"]},\"text\":{\"type\":\"string\"},\"textExpr\":{\"type\":\"string\"},\"label\":{\"type\":\"string\"},\"labelExpr\":{\"type\":\"string\"},\"href\":{\"type\":\"string\"},\"target\":{\"enum\":[\"_self\",\"_blank\"]},\"rel\":{\"type\":\"string\"},\"src\":{\"type\":\"string\"},\"alt\":{\"type\":\"string\"},\"title\":{\"type\":\"string\"},\"titleExpr\":{\"type\":\"string\"},\"subtitle\":{\"type\":\"string\"},\"subtitleExpr\":{\"type\":\"string\"},\"relationLabel\":{\"type\":\"string\"},\"message\":{\"type\":\"string\"},\"summary\":{\"type\":\"string\"},\"summaryExpr\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"ctaLabel\":{\"type\":\"string\"},\"caption\":{\"type\":\"string\"},\"emptyText\":{\"type\":\"string\"},\"errorText\":{\"type\":\"string\"},\"status\":{\"enum\":[\"idle\",\"resolved\",\"empty\",\"error\",\"draft\",\"simulated\",\"approved\",\"published\",\"superseded\",\"reverted\"]},\"statusExpr\":{\"type\":\"string\"},\"owner\":{\"type\":\"string\"},\"ownerExpr\":{\"type\":\"string\"},\"policySource\":{\"type\":\"string\"},\"policySourceExpr\":{\"type\":\"string\"},\"version\":{\"type\":\"string\"},\"versionExpr\":{\"type\":\"string\"},\"confidence\":{\"type\":\"number\"},\"confidenceExpr\":{\"type\":\"string\"},\"risk\":{\"enum\":[\"low\",\"medium\",\"high\",\"critical\"]},\"riskExpr\":{\"type\":\"string\"},\"lastReviewed\":{\"type\":\"string\"},\"lastReviewedExpr\":{\"type\":\"string\"},\"supersedes\":{\"type\":\"string\"},\"supersedesExpr\":{\"type\":\"string\"},\"evidence\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"appearance\":{\"enum\":[\"plain\",\"card\",\"underline\",\"pills\"]},\"variant\":{\"enum\":[\"basic\",\"raised\",\"stroked\",\"flat\",\"plain\",\"outlined\",\"elevated\",\"filled\",\"transparent\",\"unstyled\"]},\"tone\":{\"enum\":[\"neutral\",\"info\",\"success\",\"warning\",\"danger\"]},\"size\":{\"enum\":[\"sm\",\"md\",\"lg\"]},\"density\":{},\"orientation\":{},\"loading\":{\"type\":\"boolean\"},\"loadingExpr\":{\"type\":\"string\"},\"active\":{\"type\":\"boolean\"},\"activeExpr\":{\"type\":\"string\"},\"defaultTabId\":{\"type\":\"string\"},\"order\":{\"enum\":[\"normal\",\"reverse\"]},\"position\":{\"enum\":[\"left\",\"right\",\"alternate\",\"alternate-reverse\"]},\"connectorVariant\":{\"enum\":[\"solid\",\"dashed\",\"none\"]},\"connectorColor\":{\"enum\":[\"primary\",\"secondary\",\"tertiary\",\"success\",\"warning\",\"error\",\"danger\",\"info\",\"neutral\"]},\"markerVariant\":{\"enum\":[\"dot\",\"icon\",\"number\"]},\"markerColor\":{\"enum\":[\"primary\",\"secondary\",\"tertiary\",\"success\",\"warning\",\"error\",\"danger\",\"info\",\"neutral\"]},\"markerStyle\":{\"enum\":[\"filled\",\"outlined\"]},\"emphasis\":{\"enum\":[\"subtle\",\"standard\",\"strong\",\"hero\"]},\"textAppearance\":{\"enum\":[\"default\",\"prominent\",\"eyebrow\",\"label\"]},\"icon\":{\"type\":\"string\"},\"formId\":{\"type\":\"string\"},\"columns\":{\"oneOf\":[{\"type\":\"number\"},{\"enum\":[\"auto-fit\",\"auto-fill\"]}]},\"minColumnWidth\":{\"type\":\"string\"},\"alignItems\":{\"enum\":[\"stretch\",\"start\",\"center\",\"end\"]},\"layout\":{\"enum\":[\"stacked\",\"inline\",\"split\",\"grid\",\"flex\"]},\"ctaPlacement\":{\"enum\":[\"bottom\",\"inline\",\"trailing\"]},\"ctaVariant\":{\"enum\":[\"elevated\",\"stroked\",\"flat\",\"tonal\",\"raised\"]},\"action\":{\"type\":\"object\"},\"actions\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"primaryAction\":{\"type\":\"object\"},\"secondaryActions\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"media\":{\"type\":\"object\",\"properties\":{\"kind\":{\"enum\":[\"image\",\"video\",\"icon\",\"avatar\",\"telemetry\",\"lottie\",\"component\"]},\"src\":{\"type\":\"string\"},\"srcExpr\":{\"type\":\"string\"},\"alt\":{\"type\":\"string\"},\"altExpr\":{\"type\":\"string\"},\"icon\":{\"type\":\"string\"},\"label\":{\"type\":\"string\"},\"labelExpr\":{\"type\":\"string\"},\"placement\":{\"enum\":[\"top\",\"leading\",\"trailing\",\"background\"]},\"aspectRatio\":{\"type\":\"string\"},\"width\":{\"type\":\"string\"},\"height\":{\"type\":\"string\"},\"verticalAlign\":{\"enum\":[\"center\",\"top\",\"bottom\",\"stretch\"]},\"objectFit\":{\"enum\":[\"cover\",\"contain\",\"fill\",\"none\",\"scale-down\"]},\"animationSrc\":{\"type\":\"string\"},\"animationSrcExpr\":{\"type\":\"string\"},\"componentId\":{\"type\":\"string\"},\"componentInputs\":{\"type\":\"object\"},\"telemetry\":{\"type\":\"object\",\"properties\":{\"variant\":{\"enum\":[\"radar\",\"pulse\",\"wave\",\"signal\"]},\"speed\":{\"enum\":[\"slow\",\"normal\",\"fast\"]},\"color\":{\"type\":\"string\"},\"interactive\":{\"type\":\"boolean\"}}}}},\"headerAction\":{\"type\":\"object\"},\"headingLevel\":{\"enum\":[1,2,3,4,5,6]},\"identity\":{\"type\":\"object\"},\"breadcrumbs\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"overflowActions\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"relatedLinks\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"interaction\":{\"type\":\"object\",\"properties\":{\"mode\":{\"enum\":[\"none\",\"action\",\"selectable\"]},\"action\":{\"type\":\"object\"},\"selected\":{\"type\":\"boolean\"},\"selectedExpr\":{\"type\":\"string\"}}},\"accessibility\":{\"type\":\"object\",\"properties\":{\"role\":{\"enum\":[\"article\",\"group\",\"button\"]},\"ariaLabel\":{\"type\":\"string\"},\"ariaLabelExpr\":{\"type\":\"string\"},\"ariaLabelledBy\":{\"type\":\"string\"},\"ariaDescribedBy\":{\"type\":\"string\"}}},\"fields\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"items\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"},\"label\":{\"type\":\"string\"},\"labelExpr\":{\"type\":\"string\"},\"value\":{\"type\":\"string\"},\"valueExpr\":{\"type\":\"string\"},\"hint\":{\"type\":\"string\"},\"hintExpr\":{\"type\":\"string\"},\"icon\":{\"type\":\"string\"},\"action\":{\"type\":\"object\"},\"progress\":{\"type\":\"object\",\"properties\":{\"value\":{\"type\":\"number\"},\"valueExpr\":{\"type\":\"string\"},\"max\":{\"type\":\"number\"},\"showPercent\":{\"type\":\"boolean\"},\"variant\":{\"enum\":[\"bar\",\"ring\"]},\"tone\":{\"enum\":[\"neutral\",\"info\",\"success\",\"warning\",\"danger\"]}}}}}},\"header\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"body\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"footer\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}},\"aside\":{\"type\":\"array\",\"items\":{\"type\":\"object\"}}}},\"effects\":[{\"kind\":\"merge-by-key\",\"path\":\"document.nodes[]\",\"key\":\"id\"}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"block-exists\",\"node-types-supported\",\"unsafe-url-rejected\",\"unsafe-style-rejected\",\"expression-path-safe\",\"document-shape-canonical\",\"editor-runtime-round-trip\"]}}",
7561
7582
  "sourcePointer": "projects/praxis-rich-content/src/lib/ai/praxis-rich-content-authoring-manifest.ts",
7562
- "contentHash": "c4c9ab041f0b3fca247de74800ca2fc88928b273dce457d7430606b81a566761",
7583
+ "contentHash": "dc5b7f214694809a7f1f8c3b9e4f00e2df3410057c4e50c5ebdded2b96df0759",
7563
7584
  "sourceKind": "component_definition",
7564
7585
  "sourceId": "praxis-rich-content",
7565
7586
  "corpusVersion": "1.0.0"
@@ -7647,9 +7668,9 @@
7647
7668
  {
7648
7669
  "chunkIndex": 31,
7649
7670
  "chunkKind": "recipe",
7650
- "content": "{\"_comment\":\"Recipe for @praxisui/rich-content. Use RichContentDocument for governed presentation, policy notes, operational summaries, host-mediated action cards, timelines and AI-readable explanations.\",\"templateMeta\":{\"registryKey\":\"praxis-rich-content\",\"variantId\":\"knowledge-surface\",\"description\":\"Cria superfícies editoriais portáveis com RichContentDocument, incluindo blocos governados como actionCard, lookupCard e formLauncher.\",\"useWhen\":\"Create reusable rich presentation surfaces and governed editorial action surfaces that can be embedded in Dynamic Page, Tabs, Dialog, Stepper, List expansion or Page Builder.\",\"examplePrompts\":[\"create a rich content policy card\",\"show operational notes with metrics and timeline\",\"generate a reusable knowledge surface for agents\",\"create a governed action card for a host-mediated workflow\",\"show a related record summary with governed action\"]},\"authoringGuidance\":[\"Use document.kind \\\"praxis.rich-content\\\" and version \\\"1.0.0\\\".\",\"Use document.nodes for block layout surfaces and nodes for inline compact status surfaces.\",\"Use context plus *Expr properties when text, badges, metrics or progress should resolve from host state.\",\"Use actionButton, lookupCard, relatedRecord, formLauncher or actionCard when the host must mediate an action instead of embedding handlers in the document.\",\"Use action.confirmMessage when the workflow requires confirmation; the host must provide hostCapabilities.confirmAction and the runtime fails closed without dispatch if confirmation is rejected or unavailable.\",\"Use card variant/tone/size/orientation/media/interaction when the authoring intent is a semantic surface, not a host-authored wrapper.\",\"Use rich-content for presentation and explanation only; use table, list or dynamic-form for editable business data.\",\"Prefer portable nodes such as card, callout, recordSummary, relatedRecord, actionCard, compose, text, icon, badge, metric, progress, mediaBlock, avatar and timeline.\",\"Use pageHeader for a semantic functionality opening: headingLevel independent of size, optional identity, ancestor breadcrumbs, host-mediated primaryAction/secondaryActions/overflowActions, and relatedLinks with real destinations. Omit empty regions and do not duplicate table actions.\"],\"inputs\":{\"layout\":\"block\",\"rootClassName\":\"mission-knowledge-surface\",\"context\":{\"mission\":{\"name\":\"Operation Dawn Gate\",\"owner\":\"Ariadne Ops\",\"readiness\":82,\"risk\":\"Elevated\",\"region\":\"South Atlantic\"},\"policy\":{\"owner\":\"Platform Governance\",\"version\":\"2026.04\",\"source\":\"Quickstart reference contract\"}},\"document\":{\"kind\":\"praxis.rich-content\",\"version\":\"1.0.0\",\"nodes\":[{\"type\":\"card\",\"titleExpr\":\"${mission.name}\",\"subtitleExpr\":\"${policy.source}\",\"variant\":\"elevated\",\"tone\":\"info\",\"size\":\"lg\",\"orientation\":\"horizontal\",\"media\":{\"kind\":\"icon\",\"icon\":\"psychology\",\"label\":\"AI-authored semantic decision surface\",\"placement\":\"leading\"},\"accessibility\":{\"role\":\"article\",\"ariaLabel\":\"Mission knowledge surface\"},\"content\":[{\"type\":\"compose\",\"wrap\":true,\"gap\":\"sm\",\"items\":[{\"type\":\"badge\",\"labelExpr\":\"${mission.region}\"},{\"type\":\"badge\",\"labelExpr\":\"${mission.risk}\"},{\"type\":\"badge\",\"labelExpr\":\"${policy.version}\"}]},{\"type\":\"text\",\"text\":\"Use rich content when the page needs governed explanation, operational notes or agent-readable context without inventing a one-off Angular template.\"},{\"type\":\"compose\",\"wrap\":true,\"gap\":\"lg\",\"items\":[{\"type\":\"metric\",\"label\":\"Readiness\",\"valueExpr\":\"${mission.readiness}\",\"captionExpr\":\"${mission.owner}\"},{\"type\":\"progress\",\"label\":\"Execution confidence\",\"valueExpr\":\"${mission.readiness}\",\"max\":100}]}]},{\"type\":\"mediaBlock\",\"avatar\":{\"type\":\"avatar\",\"initials\":\"AI\",\"name\":\"AI recipe\"},\"title\":{\"type\":\"text\",\"text\":\"Agent authoring note\"},\"subtitle\":{\"type\":\"text\",\"text\":\"Rich content is presentation metadata. Use it for policy, summaries, timelines and explanations; use forms and tables for editable business data.\"},\"meta\":{\"type\":\"badge\",\"label\":\"copyable JSON\"},\"trailing\":[{\"type\":\"icon\",\"icon\":\"psychology\",\"ariaLabel\":\"AI ready\"}]},{\"type\":\"relatedRecord\",\"title\":\"Related approval owner\",\"subtitleExpr\":\"${policy.owner}\",\"relationLabel\":\"Policy owner\",\"metaExpr\":\"${policy.version}\",\"ctaLabel\":\"Open related owner\",\"variant\":\"raised\",\"color\":\"primary\",\"action\":{\"actionId\":\"briefing.inspect\",\"confirmMessage\":\"Confirm opening the governed briefing package?\"},\"fields\":[{\"label\":\"Source\",\"valueExpr\":\"${policy.source}\",\"hint\":\"Resolved from the same portable document context.\"}],\"secondaryActions\":[{\"type\":\"actionButton\",\"label\":\"Escalate owner review\",\"variant\":\"stroked\",\"action\":{\"actionId\":\"briefing.escalate\"}}]},{\"type\":\"actionCard\",\"title\":\"Open governed briefing\",\"subtitleExpr\":\"${policy.owner}\",\"message\":\"Use actionCard when the host must run a governed workflow from a portable editorial document.\",\"metaExpr\":\"${policy.version}\",\"ctaLabel\":\"Inspect briefing\",\"variant\":\"raised\",\"color\":\"primary\",\"action\":{\"actionId\":\"briefing.inspect\",\"confirmMessage\":\"Confirm opening the governed briefing package?\"},\"secondaryActions\":[{\"type\":\"actionButton\",\"label\":\"Escalate review\",\"variant\":\"stroked\",\"action\":{\"actionId\":\"briefing.escalate\"}}]},{\"type\":\"timeline\",\"title\":\"Knowledge lifecycle\",\"orientation\":\"horizontal\",\"order\":\"reverse\",\"position\":\"alternate\",\"connectorVariant\":\"dashed\",\"markerVariant\":\"number\",\"items\":[{\"icon\":\"schema\",\"title\":\"Contract discovered\",\"subtitle\":\"Read source metadata and decide whether the surface is data, action or explanation.\",\"meta\":\"schemas.filtered + recipes\",\"opposite\":\"1. Discover\",\"badge\":\"source\"},{\"icon\":\"article\",\"title\":\"Briefing authored\",\"subtitle\":\"Render cards, metrics, progress and guidance with one RichContentDocument.\",\"meta\":\"praxis-rich-content\",\"opposite\":\"2. Author\",\"badge\":\"runtime\"},{\"icon\":\"open_in_new\",\"title\":\"Surface reused\",\"subtitle\":\"Embed the same document in a tab, dialog, stepper, list expansion or dashboard cell.\",\"meta\":\"Dynamic Page composition\",\"opposite\":\"3. Reuse\",\"badge\":\"portable\"}]}]}},\"inlineExample\":{\"layout\":\"inline\",\"context\":{\"status\":{\"label\":\"Governed knowledge surface\",\"phase\":\"Reusable\"}},\"nodes\":[{\"type\":\"icon\",\"icon\":\"verified\",\"ariaLabel\":\"Verified\"},{\"type\":\"text\",\"textExpr\":\"${status.label}\"},{\"type\":\"badge\",\"labelExpr\":\"${status.phase}\"}]}}",
7671
+ "content": "{\"_comment\":\"Recipe for @praxisui/rich-content. Use RichContentDocument for governed presentation, policy notes, operational summaries, host-mediated action cards, timelines and AI-readable explanations.\",\"templateMeta\":{\"registryKey\":\"praxis-rich-content\",\"variantId\":\"knowledge-surface\",\"description\":\"Cria superfícies editoriais portáveis com RichContentDocument, incluindo blocos governados como actionCard, lookupCard e formLauncher.\",\"useWhen\":\"Create reusable rich presentation surfaces and governed editorial action surfaces that can be embedded in Dynamic Page, Tabs, Dialog, Stepper, List expansion or Page Builder.\",\"examplePrompts\":[\"create a rich content policy card\",\"show operational notes with metrics and timeline\",\"generate a reusable knowledge surface for agents\",\"create a governed action card for a host-mediated workflow\",\"show a related record summary with governed action\"]},\"authoringGuidance\":[\"Use document.kind \\\"praxis.rich-content\\\" and version \\\"1.0.0\\\".\",\"Use document.nodes for block layout surfaces and nodes for inline compact status surfaces.\",\"Use context plus *Expr properties when text, badges, metrics or progress should resolve from host state.\",\"Use actionButton, lookupCard, relatedRecord, formLauncher or actionCard when the host must mediate an action instead of embedding handlers in the document.\",\"Use action.confirmMessage when the workflow requires confirmation; the host must provide hostCapabilities.confirmAction and the runtime fails closed without dispatch if confirmation is rejected or unavailable.\",\"Use card variant/tone/size/orientation/media/interaction when the authoring intent is a semantic surface, not a host-authored wrapper.\",\"Use card.media.kind \\\"component\\\" with componentId, componentInputs, width, height and verticalAlign when embedding a host-registered widget (ComponentMetadataRegistry) in the card media slot; the active RichContent context is forwarded automatically to resolve ${...} bindings in componentInputs.\",\"Use rich-content for presentation and explanation only; use table, list or dynamic-form for editable business data.\",\"Prefer portable nodes such as card, callout, recordSummary, relatedRecord, actionCard, compose, text, icon, badge, metric, progress, mediaBlock, avatar and timeline.\",\"Use pageHeader for a semantic functionality opening: headingLevel independent of size, optional identity, ancestor breadcrumbs, host-mediated primaryAction/secondaryActions/overflowActions, and relatedLinks with real destinations. Omit empty regions and do not duplicate table actions.\"],\"inputs\":{\"layout\":\"block\",\"rootClassName\":\"mission-knowledge-surface\",\"context\":{\"mission\":{\"name\":\"Operation Dawn Gate\",\"owner\":\"Ariadne Ops\",\"readiness\":82,\"risk\":\"Elevated\",\"region\":\"South Atlantic\"},\"policy\":{\"owner\":\"Platform Governance\",\"version\":\"2026.04\",\"source\":\"Quickstart reference contract\"}},\"document\":{\"kind\":\"praxis.rich-content\",\"version\":\"1.0.0\",\"nodes\":[{\"type\":\"card\",\"titleExpr\":\"${mission.name}\",\"subtitleExpr\":\"${policy.source}\",\"variant\":\"elevated\",\"tone\":\"info\",\"size\":\"lg\",\"orientation\":\"horizontal\",\"media\":{\"kind\":\"icon\",\"icon\":\"psychology\",\"label\":\"AI-authored semantic decision surface\",\"placement\":\"leading\"},\"accessibility\":{\"role\":\"article\",\"ariaLabel\":\"Mission knowledge surface\"},\"content\":[{\"type\":\"compose\",\"wrap\":true,\"gap\":\"sm\",\"items\":[{\"type\":\"badge\",\"labelExpr\":\"${mission.region}\"},{\"type\":\"badge\",\"labelExpr\":\"${mission.risk}\"},{\"type\":\"badge\",\"labelExpr\":\"${policy.version}\"}]},{\"type\":\"text\",\"text\":\"Use rich content when the page needs governed explanation, operational notes or agent-readable context without inventing a one-off Angular template.\"},{\"type\":\"compose\",\"wrap\":true,\"gap\":\"lg\",\"items\":[{\"type\":\"metric\",\"label\":\"Readiness\",\"valueExpr\":\"${mission.readiness}\",\"captionExpr\":\"${mission.owner}\"},{\"type\":\"progress\",\"label\":\"Execution confidence\",\"valueExpr\":\"${mission.readiness}\",\"max\":100}]}]},{\"type\":\"mediaBlock\",\"avatar\":{\"type\":\"avatar\",\"initials\":\"AI\",\"name\":\"AI recipe\"},\"title\":{\"type\":\"text\",\"text\":\"Agent authoring note\"},\"subtitle\":{\"type\":\"text\",\"text\":\"Rich content is presentation metadata. Use it for policy, summaries, timelines and explanations; use forms and tables for editable business data.\"},\"meta\":{\"type\":\"badge\",\"label\":\"copyable JSON\"},\"trailing\":[{\"type\":\"icon\",\"icon\":\"psychology\",\"ariaLabel\":\"AI ready\"}]},{\"type\":\"relatedRecord\",\"title\":\"Related approval owner\",\"subtitleExpr\":\"${policy.owner}\",\"relationLabel\":\"Policy owner\",\"metaExpr\":\"${policy.version}\",\"ctaLabel\":\"Open related owner\",\"variant\":\"raised\",\"color\":\"primary\",\"action\":{\"actionId\":\"briefing.inspect\",\"confirmMessage\":\"Confirm opening the governed briefing package?\"},\"fields\":[{\"label\":\"Source\",\"valueExpr\":\"${policy.source}\",\"hint\":\"Resolved from the same portable document context.\"}],\"secondaryActions\":[{\"type\":\"actionButton\",\"label\":\"Escalate owner review\",\"variant\":\"stroked\",\"action\":{\"actionId\":\"briefing.escalate\"}}]},{\"type\":\"actionCard\",\"title\":\"Open governed briefing\",\"subtitleExpr\":\"${policy.owner}\",\"message\":\"Use actionCard when the host must run a governed workflow from a portable editorial document.\",\"metaExpr\":\"${policy.version}\",\"ctaLabel\":\"Inspect briefing\",\"variant\":\"raised\",\"color\":\"primary\",\"action\":{\"actionId\":\"briefing.inspect\",\"confirmMessage\":\"Confirm opening the governed briefing package?\"},\"secondaryActions\":[{\"type\":\"actionButton\",\"label\":\"Escalate review\",\"variant\":\"stroked\",\"action\":{\"actionId\":\"briefing.escalate\"}}]},{\"type\":\"timeline\",\"title\":\"Knowledge lifecycle\",\"orientation\":\"horizontal\",\"order\":\"reverse\",\"position\":\"alternate\",\"connectorVariant\":\"dashed\",\"markerVariant\":\"number\",\"items\":[{\"icon\":\"schema\",\"title\":\"Contract discovered\",\"subtitle\":\"Read source metadata and decide whether the surface is data, action or explanation.\",\"meta\":\"schemas.filtered + recipes\",\"opposite\":\"1. Discover\",\"badge\":\"source\"},{\"icon\":\"article\",\"title\":\"Briefing authored\",\"subtitle\":\"Render cards, metrics, progress and guidance with one RichContentDocument.\",\"meta\":\"praxis-rich-content\",\"opposite\":\"2. Author\",\"badge\":\"runtime\"},{\"icon\":\"open_in_new\",\"title\":\"Surface reused\",\"subtitle\":\"Embed the same document in a tab, dialog, stepper, list expansion or dashboard cell.\",\"meta\":\"Dynamic Page composition\",\"opposite\":\"3. Reuse\",\"badge\":\"portable\"}]}]}},\"inlineExample\":{\"layout\":\"inline\",\"context\":{\"status\":{\"label\":\"Governed knowledge surface\",\"phase\":\"Reusable\"}},\"nodes\":[{\"type\":\"icon\",\"icon\":\"verified\",\"ariaLabel\":\"Verified\"},{\"type\":\"text\",\"textExpr\":\"${status.label}\"},{\"type\":\"badge\",\"labelExpr\":\"${status.phase}\"}]}}",
7651
7672
  "sourcePointer": "examples/ai-recipes/praxis-rich-content.json",
7652
- "contentHash": "96145951be7ff515757347dc879097c30f5e00d0b36c6ede287f1a7666e5fb4c",
7673
+ "contentHash": "23fe87f25dc52c844764883473a3995f78687bbc6b000a1f22107dd0b5183ea4",
7653
7674
  "sourceKind": "component_definition",
7654
7675
  "sourceId": "praxis-rich-content",
7655
7676
  "corpusVersion": "1.0.0"
@@ -614,7 +614,7 @@ function validateOptionalCardMedia(value, path, issues) {
614
614
  addIssue(issues, path, 'editor.validation.objectField', 'Card media must be an object.');
615
615
  return;
616
616
  }
617
- validateEnum(value, 'kind', ['image', 'video', 'icon', 'avatar', 'telemetry', 'lottie'], path, issues, true);
617
+ validateEnum(value, 'kind', ['image', 'video', 'icon', 'avatar', 'telemetry', 'lottie', 'component'], path, issues, true);
618
618
  validateOptionalUrl(value, 'src', path, issues, 'image');
619
619
  validateOptionalExpressionPath(value, 'srcExpr', path, issues);
620
620
  validateOptionalString(value, 'alt', path, issues);
@@ -623,9 +623,21 @@ function validateOptionalCardMedia(value, path, issues) {
623
623
  validateOptionalString(value, 'label', path, issues);
624
624
  validateOptionalExpressionPath(value, 'labelExpr', path, issues);
625
625
  validateEnum(value, 'placement', ['top', 'leading', 'trailing', 'background'], path, issues, false);
626
+ validateEnum(value, 'verticalAlign', ['center', 'top', 'bottom', 'stretch'], path, issues, false);
626
627
  validateOptionalString(value, 'aspectRatio', path, issues);
628
+ validateOptionalString(value, 'width', path, issues);
629
+ validateOptionalString(value, 'height', path, issues);
627
630
  validateEnum(value, 'objectFit', ['cover', 'contain', 'fill', 'none', 'scale-down'], path, issues, false);
628
631
  validateOptionalUrl(value, 'animationSrc', path, issues, 'image');
632
+ if (value['kind'] === 'component') {
633
+ validateRequiredString(value, 'componentId', path, issues);
634
+ }
635
+ else {
636
+ validateOptionalString(value, 'componentId', path, issues);
637
+ }
638
+ if (value['componentInputs'] !== undefined && !isRecord(value['componentInputs'])) {
639
+ addIssue(issues, `${path}.componentInputs`, 'editor.validation.objectField', 'Card media componentInputs must be an object.');
640
+ }
629
641
  if (value['telemetry'] !== undefined) {
630
642
  validateCardMediaTelemetry(value['telemetry'], `${path}.telemetry`, issues);
631
643
  }