@praxisui/rich-content 10.0.0-rc.20 → 10.0.0-rc.22

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-10-15T03:52:00.118Z",
3
+ "generatedAt": "2026-10-15T06:07:49.426Z",
4
4
  "packageName": "@praxisui/rich-content",
5
- "packageVersion": "10.0.0-rc.20",
5
+ "packageVersion": "10.0.0-rc.22",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 1,
@@ -9250,6 +9250,8 @@ class PraxisRichContentConfigEditor {
9250
9250
  initialInputs = this.normalizeInputs(this.inputs);
9251
9251
  pendingRemoval = null;
9252
9252
  advancedJsonFieldDrafts = {};
9253
+ // Draft identity stays internal: array positions can change without changing the owner.
9254
+ advancedJsonDraftOwners = new Map();
9253
9255
  ngOnChanges(changes) {
9254
9256
  if (changes['inputs']) {
9255
9257
  this.load(this.normalizeInputs(this.inputs), false);
@@ -9265,6 +9267,7 @@ class PraxisRichContentConfigEditor {
9265
9267
  const document = this.parseDocument();
9266
9268
  if (draft && this.documentJson === this.stringify(draft)) {
9267
9269
  this.parsedDocument = draft;
9270
+ this.rebindAdvancedJsonDraftOwners(draft);
9268
9271
  this.updateDocumentOverview(draft);
9269
9272
  }
9270
9273
  if (!document || this.hasAdvancedJsonFieldErrors()) {
@@ -10483,6 +10486,7 @@ class PraxisRichContentConfigEditor {
10483
10486
  }
10484
10487
  setAdvancedJsonField(index, field, value) {
10485
10488
  const key = this.getAdvancedJsonFieldKey(index, field);
10489
+ this.trackAdvancedJsonDraftOwner(key, this.ensureEditableDocument().nodes[index], field);
10486
10490
  const trimmed = value.trim();
10487
10491
  this.advancedJsonFieldDrafts[key] = value;
10488
10492
  if (!trimmed) {
@@ -10505,6 +10509,7 @@ class PraxisRichContentConfigEditor {
10505
10509
  this.setAdvancedJsonFieldInvalid(key, this.getAdvancedJsonFieldShapeError(field));
10506
10510
  return;
10507
10511
  }
10512
+ this.reconcileAdvancedJsonDraftOwners();
10508
10513
  const nextDocument = this.cloneValue(this.ensureEditableDocument());
10509
10514
  const node = nextDocument.nodes[index];
10510
10515
  node[field] = parsed;
@@ -10515,6 +10520,7 @@ class PraxisRichContentConfigEditor {
10515
10520
  return;
10516
10521
  }
10517
10522
  this.parsedDocument = nextDocument;
10523
+ this.rebindAdvancedJsonDraftOwners(nextDocument);
10518
10524
  this.documentJson = nextJson;
10519
10525
  delete this.advancedJsonFieldDrafts[key];
10520
10526
  delete this.advancedJsonFieldErrors[key];
@@ -10585,6 +10591,7 @@ class PraxisRichContentConfigEditor {
10585
10591
  clearAdvancedJsonFieldState() {
10586
10592
  this.advancedJsonFieldDrafts = {};
10587
10593
  this.advancedJsonFieldErrors = {};
10594
+ this.advancedJsonDraftOwners.clear();
10588
10595
  }
10589
10596
  hasAdvancedJsonFieldErrors() {
10590
10597
  return Object.keys(this.advancedJsonFieldErrors).length > 0;
@@ -11160,6 +11167,8 @@ class PraxisRichContentConfigEditor {
11160
11167
  return 'custom';
11161
11168
  }
11162
11169
  applyIconSurfacePreset(node, preset) {
11170
+ if (preset === 'custom')
11171
+ return;
11163
11172
  const existingColor = getNodeStyleProp(node, 'color');
11164
11173
  const currentColor = existingColor || 'var(--md-sys-color-primary, #3154e7)';
11165
11174
  const currentFontSize = getNodeStyleProp(node, 'fontSize') || '20px';
@@ -11247,6 +11256,8 @@ class PraxisRichContentConfigEditor {
11247
11256
  return 'custom';
11248
11257
  }
11249
11258
  applyBadgeStylePreset(node, preset) {
11259
+ if (preset === 'custom')
11260
+ return;
11250
11261
  resetNodeVisualStyles(node, BADGE_VISUAL_STYLE_PROPS);
11251
11262
  if (preset === 'default') {
11252
11263
  this.syncStructuredDocumentChange();
@@ -11585,10 +11596,9 @@ class PraxisRichContentConfigEditor {
11585
11596
  // Preserve the live structured draft reference so bound node references remain active
11586
11597
  // even across consecutive edits or temporary empty required fields.
11587
11598
  this.parsedDocument = draft;
11599
+ this.rebindAdvancedJsonDraftOwners(draft);
11588
11600
  this.updateDocumentOverview(draft);
11589
11601
  this.markDirty();
11590
- this.parsedDocument = draft;
11591
- this.updateDocumentOverview(draft);
11592
11602
  this.cdr.markForCheck();
11593
11603
  }
11594
11604
  createDefaultNode(type) {
@@ -11960,6 +11970,7 @@ class PraxisRichContentConfigEditor {
11960
11970
  }
11961
11971
  applyActionPayloadEdit(actionOwner, field, value, path, cleanup) {
11962
11972
  const key = this.getActionPayloadFieldKey(path);
11973
+ this.trackAdvancedJsonDraftOwner(key, actionOwner, undefined, path);
11963
11974
  if (field === 'payloadPath') {
11964
11975
  const trimmed = value.trim();
11965
11976
  const currentAction = actionOwner.action ?? {
@@ -12022,7 +12033,88 @@ class PraxisRichContentConfigEditor {
12022
12033
  }
12023
12034
  }
12024
12035
  getActionPayloadFieldKey(path) {
12025
- return `action-payload:${path}`;
12036
+ return `action-payload:${this.formatAdvancedJsonDraftPath(this.parseAdvancedJsonDraftPath(path))}`;
12037
+ }
12038
+ parseAdvancedJsonDraftPath(path) {
12039
+ return path.replace(/^\$\.?/, '').replace(/\[(\d+)\]/g, '.$1')
12040
+ .split('.').filter(Boolean).map(segment => /^\d+$/.test(segment) ? Number(segment) : segment);
12041
+ }
12042
+ formatAdvancedJsonDraftPath(path) {
12043
+ return path.map((segment, index) => typeof segment === 'number'
12044
+ ? `[${segment}]` : `${index ? '.' : ''}${segment}`).join('');
12045
+ }
12046
+ findAdvancedJsonDraftOwnerPath(owner) {
12047
+ const visit = (value, path) => {
12048
+ if (value === owner)
12049
+ return path;
12050
+ if (!value || typeof value !== 'object')
12051
+ return null;
12052
+ for (const [key, child] of Object.entries(value)) {
12053
+ const found = visit(child, [...path, Array.isArray(value) ? Number(key) : key]);
12054
+ if (found)
12055
+ return found;
12056
+ }
12057
+ return null;
12058
+ };
12059
+ return visit(this.parsedDocument, []);
12060
+ }
12061
+ trackAdvancedJsonDraftOwner(key, owner, field, payloadPath) {
12062
+ const path = this.findAdvancedJsonDraftOwnerPath(owner);
12063
+ if (!path)
12064
+ return;
12065
+ const suppliedPath = payloadPath === undefined ? undefined : this.parseAdvancedJsonDraftPath(payloadPath);
12066
+ const rooted = suppliedPath?.[0] === 'nodes'
12067
+ && path.every((segment, index) => suppliedPath[index] === segment);
12068
+ this.advancedJsonDraftOwners.set(key, {
12069
+ owner, path, field,
12070
+ payloadSuffix: rooted ? suppliedPath.slice(path.length) : undefined,
12071
+ fixedKey: payloadPath !== undefined && !rooted ? key : undefined,
12072
+ });
12073
+ }
12074
+ reconcileAdvancedJsonDraftOwners() {
12075
+ if (!this.parsedDocument || !this.advancedJsonDraftOwners.size)
12076
+ return;
12077
+ const drafts = { ...this.advancedJsonFieldDrafts };
12078
+ const errors = { ...this.advancedJsonFieldErrors };
12079
+ const owners = [...this.advancedJsonDraftOwners];
12080
+ this.advancedJsonDraftOwners.clear();
12081
+ // Remove old positions before assigning new positions, including swaps.
12082
+ for (const [key] of owners) {
12083
+ delete this.advancedJsonFieldDrafts[key];
12084
+ delete this.advancedJsonFieldErrors[key];
12085
+ }
12086
+ for (const [key, record] of owners) {
12087
+ if (!(key in drafts) && !(key in errors))
12088
+ continue;
12089
+ const path = this.findAdvancedJsonDraftOwnerPath(record.owner);
12090
+ if (!path)
12091
+ continue;
12092
+ const nextKey = record.fixedKey ?? (record.field !== undefined
12093
+ ? this.getAdvancedJsonFieldKey(Number(path[1]), record.field)
12094
+ : this.getActionPayloadFieldKey(this.formatAdvancedJsonDraftPath([...path, ...(record.payloadSuffix ?? [])])));
12095
+ if (key in drafts)
12096
+ this.advancedJsonFieldDrafts[nextKey] = drafts[key];
12097
+ if (key in errors)
12098
+ this.advancedJsonFieldErrors[nextKey] = errors[key];
12099
+ this.advancedJsonDraftOwners.set(nextKey, { ...record, path });
12100
+ }
12101
+ }
12102
+ rebindAdvancedJsonDraftOwners(document) {
12103
+ for (const [key, record] of this.advancedJsonDraftOwners) {
12104
+ let owner = document;
12105
+ for (const segment of record.path) {
12106
+ owner = owner && typeof owner === 'object'
12107
+ ? owner[String(segment)] : undefined;
12108
+ }
12109
+ if (owner && typeof owner === 'object') {
12110
+ record.owner = owner;
12111
+ }
12112
+ else {
12113
+ this.advancedJsonDraftOwners.delete(key);
12114
+ delete this.advancedJsonFieldDrafts[key];
12115
+ delete this.advancedJsonFieldErrors[key];
12116
+ }
12117
+ }
12026
12118
  }
12027
12119
  createActionPreset(preset) {
12028
12120
  if (preset === 'primary') {
@@ -12050,6 +12142,7 @@ class PraxisRichContentConfigEditor {
12050
12142
  return node;
12051
12143
  }
12052
12144
  parseDocument() {
12145
+ this.reconcileAdvancedJsonDraftOwners();
12053
12146
  try {
12054
12147
  const parsed = JSON.parse(this.documentJson);
12055
12148
  this.documentSyntaxInvalid = false;
@@ -12071,6 +12164,7 @@ class PraxisRichContentConfigEditor {
12071
12164
  }
12072
12165
  const document = parsed;
12073
12166
  this.parsedDocument = document;
12167
+ this.rebindAdvancedJsonDraftOwners(document);
12074
12168
  this.reconcileSelectedNodeIndex(document);
12075
12169
  this.updateDocumentOverview(document);
12076
12170
  if (this.hasAdvancedJsonFieldErrors()) {
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@praxisui/rich-content",
3
- "version": "10.0.0-rc.20",
3
+ "version": "10.0.0-rc.22",
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
8
  "@angular/material": "^21.0.0",
9
- "@praxisui/core": "^10.0.0-rc.20",
9
+ "@praxisui/core": "^10.0.0-rc.22",
10
10
  "@angular/forms": "^21.0.0",
11
11
  "rxjs": "~7.8.0"
12
12
  },
@@ -387,6 +387,7 @@ declare class PraxisRichContentConfigEditor implements SettingsValueProvider, On
387
387
  private initialInputs;
388
388
  private pendingRemoval;
389
389
  private advancedJsonFieldDrafts;
390
+ private advancedJsonDraftOwners;
390
391
  ngOnChanges(changes: SimpleChanges): void;
391
392
  ngOnInit(): void;
392
393
  getSettingsValue(): PraxisRichContentEditorValue | null;
@@ -726,6 +727,12 @@ declare class PraxisRichContentConfigEditor implements SettingsValueProvider, On
726
727
  private setActionNodeField;
727
728
  private applyActionPayloadEdit;
728
729
  private getActionPayloadFieldKey;
730
+ private parseAdvancedJsonDraftPath;
731
+ private formatAdvancedJsonDraftPath;
732
+ private findAdvancedJsonDraftOwnerPath;
733
+ private trackAdvancedJsonDraftOwner;
734
+ private reconcileAdvancedJsonDraftOwners;
735
+ private rebindAdvancedJsonDraftOwners;
729
736
  private createActionPreset;
730
737
  private ensureTimelineNode;
731
738
  private parseDocument;