@contentful/experience-design-system-cli 2.38.1-dev-build-2bb2d130.0 → 2.38.1-dev-build-a2bc858b.0

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/dist/app.js CHANGED
@@ -19198,6 +19198,7 @@ function GotoBanner({
19198
19198
  borderStyle: "single",
19199
19199
  borderColor: PALETTE.accent,
19200
19200
  paddingX: 1,
19201
+ paddingBottom: 1,
19201
19202
  marginTop: width === void 0 ? 1 : 0,
19202
19203
  width,
19203
19204
  flexShrink: 0,
@@ -19209,7 +19210,7 @@ function GotoBanner({
19209
19210
  return renderRow(row, i, i === highlightIndex);
19210
19211
  }),
19211
19212
  moreBelow > 0 && /* @__PURE__ */ jsx24(Text21, { color: PALETTE.muted, children: ` \u25BC ${moreBelow} more` }),
19212
- footerHint !== void 0 && /* @__PURE__ */ jsx24(Text21, { color: PALETTE.muted, children: footerHint })
19213
+ footerHint !== void 0 && /* @__PURE__ */ jsx24(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text21, { color: PALETTE.muted, children: footerHint }) })
19213
19214
  ]
19214
19215
  }
19215
19216
  );
@@ -21714,7 +21715,7 @@ var capitalize = (name) => name.charAt(0).toUpperCase() + name.slice(1);
21714
21715
  function describeGeneration(input) {
21715
21716
  const agent = capitalize(input.agent);
21716
21717
  return `${formatAcceptanceSummary({ accepted: input.acceptedCount, autoRejected: 0 })}
21717
- ${agent} is reading each selected component and writing a Contentful component definition for it${input.hasTokens ? " Using your design tokens for prop resolution." : ""}`;
21718
+ ${agent} is reading each selected component and writing a Contentful component definition for it.${input.hasTokens ? "\nUsing your design tokens for prop resolution." : ""}`;
21718
21719
  }
21719
21720
  function progressRows2(progress, agent) {
21720
21721
  const name = capitalize(agent);
@@ -23372,6 +23373,7 @@ function FieldEditor({
23372
23373
  const [rationaleOpen, setRationaleOpen] = useState19(false);
23373
23374
  const [rationaleScrollOffset, setRationaleScrollOffset] = useState19(0);
23374
23375
  const [showHelp, setShowHelp] = useState19(false);
23376
+ const [pendingDelete, setPendingDelete] = useState19(null);
23375
23377
  const props = editorState.props;
23376
23378
  const slots = editorState.slots;
23377
23379
  const contentPropIndexes = React13.useMemo(
@@ -23463,6 +23465,46 @@ function FieldEditor({
23463
23465
  setEditorState(next);
23464
23466
  onChange(serializeState(next, value));
23465
23467
  };
23468
+ const deleteRow = (row) => {
23469
+ if (row.kind === "prop") {
23470
+ const nextProps = removeAt(editorState.props, row.idx);
23471
+ commit({ ...editorState, props: nextProps });
23472
+ setPropIdx(Math.max(0, Math.min(row.idx, nextProps.length - 1)));
23473
+ const rowsAfter2 = selectableRows.filter((r) => !(r.kind === "prop" && r.idx === row.idx));
23474
+ const neighbour2 = rowsAfter2[Math.max(0, selectableRows.findIndex((r) => r.kind === row.kind && r.idx === row.idx) - 1)];
23475
+ if (!neighbour2) {
23476
+ setInSlots(false);
23477
+ setInComponentDesc(true);
23478
+ setFocusLevel("componentDescription");
23479
+ } else if (neighbour2.kind === "prop") {
23480
+ setInSlots(false);
23481
+ setPropIdx(neighbour2.idx > row.idx ? neighbour2.idx - 1 : neighbour2.idx);
23482
+ setFocusLevel("prop");
23483
+ } else {
23484
+ setInSlots(true);
23485
+ setSlotIdx(neighbour2.idx);
23486
+ setFocusLevel("slot");
23487
+ }
23488
+ return;
23489
+ }
23490
+ const nextSlots = removeAt(editorState.slots, row.idx);
23491
+ commit({ ...editorState, slots: nextSlots });
23492
+ const rowsAfter = selectableRows.filter((r) => !(r.kind === "slot" && r.idx === row.idx));
23493
+ const neighbour = rowsAfter[Math.max(0, selectableRows.findIndex((r) => r.kind === row.kind && r.idx === row.idx) - 1)];
23494
+ if (!neighbour) {
23495
+ setInSlots(false);
23496
+ setInComponentDesc(true);
23497
+ setFocusLevel("componentDescription");
23498
+ } else if (neighbour.kind === "slot") {
23499
+ setInSlots(true);
23500
+ setSlotIdx(neighbour.idx > row.idx ? neighbour.idx - 1 : neighbour.idx);
23501
+ setFocusLevel("slot");
23502
+ } else {
23503
+ setInSlots(false);
23504
+ setPropIdx(neighbour.idx);
23505
+ setFocusLevel("prop");
23506
+ }
23507
+ };
23466
23508
  const canonicalize = React13.useCallback((json) => {
23467
23509
  try {
23468
23510
  return JSON.stringify(JSON.parse(json));
@@ -23499,6 +23541,11 @@ function FieldEditor({
23499
23541
  onSave();
23500
23542
  return;
23501
23543
  }
23544
+ if (pendingDelete) {
23545
+ if (input === "y") deleteRow(pendingDelete);
23546
+ setPendingDelete(null);
23547
+ return;
23548
+ }
23502
23549
  const inDescriptionTextEntryForHelp = focusLevel === "field" && editingField && activeField === "description";
23503
23550
  const inStringDefaultTextEntryForHelp = focusLevel === "field" && editingField && activeField === "default" && currentProp != null && (currentProp.type === "string" || currentProp.type === "token");
23504
23551
  const inValueListTextEntry = editingValue != null;
@@ -23698,6 +23745,11 @@ function FieldEditor({
23698
23745
  }
23699
23746
  return;
23700
23747
  }
23748
+ if (input === "d" && !key.ctrl && !key.meta) {
23749
+ if (focusLevel === "prop" && currentProp) setPendingDelete({ kind: "prop", idx: propIdx });
23750
+ if (focusLevel === "slot" && currentSlot) setPendingDelete({ kind: "slot", idx: slotIdx });
23751
+ return;
23752
+ }
23701
23753
  if (focusLevel === "slot" && key.return && currentSlot) {
23702
23754
  setFocusLevel("field");
23703
23755
  setActiveField(SLOT_FIELDS[0] ?? null);
@@ -24004,6 +24056,10 @@ function FieldEditor({
24004
24056
  }
24005
24057
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
24006
24058
  const modeLabel = (() => {
24059
+ if (pendingDelete) {
24060
+ const name = pendingDelete.kind === "prop" ? props[pendingDelete.idx]?.name : slots[pendingDelete.idx]?.name;
24061
+ return `Delete ${pendingDelete.kind} "${name}"? [y] delete \xB7 any other key cancels`;
24062
+ }
24007
24063
  if (editingValue) {
24008
24064
  return editingValue.mode === "add" ? "Enter to add \xB7 [Esc] to cancel" : "Enter to save edit \xB7 [Esc] to cancel";
24009
24065
  }
@@ -24025,7 +24081,7 @@ function FieldEditor({
24025
24081
  if (rationaleOpen) {
24026
24082
  return "[\u2191\u2193] scroll [i/Esc] close rationale panel";
24027
24083
  }
24028
- return `[\u2191\u2193] navigate rows [Enter] edit fields [s] source [${propRationaleKey}] prop rationale [${componentRationaleKey}] component rationale [h] help [Esc] exit panel`;
24084
+ return `[\u2191\u2193] navigate [Enter] edit fields [d] delete property [h] help [s] source [Esc] exit panel`;
24029
24085
  })();
24030
24086
  const rows = [];
24031
24087
  rows.push({ kind: "component-description" });
@@ -24291,6 +24347,7 @@ function FieldEditor({
24291
24347
  /* @__PURE__ */ jsx32(Text27, { bold: true, children: "Row navigation" }),
24292
24348
  /* @__PURE__ */ jsx32(Text27, { children: " \u2191/\u2193 move between rows" }),
24293
24349
  /* @__PURE__ */ jsx32(Text27, { children: " Enter edit fields on the current row" }),
24350
+ /* @__PURE__ */ jsx32(Text27, { children: " d delete the current prop or slot (asks to confirm)" }),
24294
24351
  /* @__PURE__ */ jsx32(Text27, { children: " Esc exit the panel" }),
24295
24352
  /* @__PURE__ */ jsx32(Text27, { children: " " }),
24296
24353
  /* @__PURE__ */ jsx32(Text27, { bold: true, children: "Field editing" }),
@@ -24314,7 +24371,7 @@ function FieldEditor({
24314
24371
  /* @__PURE__ */ jsx32(Text27, { color: PALETTE.muted, children: "press ? or Esc to close" })
24315
24372
  ] }),
24316
24373
  validationError && /* @__PURE__ */ jsx32(Text27, { color: PALETTE.error, children: "\u2717 " + validationError }),
24317
- /* @__PURE__ */ jsx32(Box26, { paddingTop: 1, children: /* @__PURE__ */ jsx32(Text27, { color: PALETTE.muted, children: modeLabel }) })
24374
+ /* @__PURE__ */ jsx32(Box26, { paddingTop: 1, children: /* @__PURE__ */ jsx32(Text27, { color: pendingDelete ? PALETTE.text : PALETTE.muted, children: modeLabel }) })
24318
24375
  ]
24319
24376
  }
24320
24377
  );
@@ -24653,8 +24710,8 @@ function TokenReviewPanel({
24653
24710
  borderStyle: "single",
24654
24711
  borderColor: active ? PALETTE.text : void 0,
24655
24712
  children: [
24656
- /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, wrap: "truncate", children: `TOKEN REVIEW \u2014 ${componentName} \xB7 ${current.propName} (edit allowed)` }),
24657
- /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: `select which tokens are allowed (${rangeLabel})` }),
24713
+ /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, wrap: "truncate", children: `Review mapped tokens \u2014 ${componentName} \xB7 ${current.propName}${current.kinds.length > 0 ? ` (${current.kinds.join(", ")})` : ""}` }),
24714
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: `Tick the tokens this property may use (${rangeLabel}).` }),
24658
24715
  /* @__PURE__ */ jsx39(Text32, { children: " " }),
24659
24716
  current.paths.length === 0 && /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: "(no compatible tokens found for this token kind)" }),
24660
24717
  visiblePaths.map((path5, i) => {
@@ -24687,18 +24744,33 @@ function TokenReviewPanel({
24687
24744
  borderStyle: "single",
24688
24745
  borderColor: active ? PALETTE.text : void 0,
24689
24746
  children: [
24690
- /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, children: `TOKEN REVIEW \u2014 ${componentName}` }),
24747
+ /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, children: `Review mapped tokens \u2014 ${componentName}` }),
24748
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: `${componentName} has ${suggestions.length} design ${suggestions.length === 1 ? "prop" : "props"} of type token. Select which tokens are allowed for each property.` }),
24749
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: "Suggested tokens come from the agent. Allowed tokens are what editors can pick in Contentful." }),
24750
+ /* @__PURE__ */ jsx39(Text32, { children: " " }),
24691
24751
  suggestions.length === 0 && /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: "(no token suggestions for this component)" }),
24692
24752
  suggestions.map((s, i) => {
24693
24753
  const focused = i === selectedRow;
24694
24754
  return /* @__PURE__ */ jsxs30(Box31, { flexDirection: "column", children: [
24695
- /* @__PURE__ */ jsx39(Box31, { children: /* @__PURE__ */ jsx39(Text32, { color: focused ? PALETTE.accent : active ? void 0 : PALETTE.muted, bold: focused, children: `${focused ? figures7.pointer : " "} ${s.propName}` }) }),
24696
- /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: ` suggested: ${s.suggested.join(", ")}` }),
24697
- /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: ` allowed: ${s.allowed.join(", ")}` })
24755
+ /* @__PURE__ */ jsx39(Box31, { children: /* @__PURE__ */ jsx39(Text32, { color: focused ? PALETTE.accent : active ? void 0 : PALETTE.muted, bold: focused, children: `${focused ? figures7.pointer : " "} ${s.propName}${s.kinds.length > 0 ? ` (${s.kinds.join(", ")})` : ""}` }) }),
24756
+ /* @__PURE__ */ jsx39(
24757
+ Text32,
24758
+ {
24759
+ color: PALETTE.muted,
24760
+ children: ` suggested: ${s.suggested.length > 0 ? s.suggested.join(", ") : "none"}`
24761
+ }
24762
+ ),
24763
+ /* @__PURE__ */ jsx39(
24764
+ Text32,
24765
+ {
24766
+ color: PALETTE.muted,
24767
+ children: ` allowed: ${s.allowed.length > 0 ? s.allowed.join(", ") : "none (any token)"}`
24768
+ }
24769
+ ),
24770
+ /* @__PURE__ */ jsx39(Text32, { children: " " })
24698
24771
  ] }, s.propName);
24699
24772
  }),
24700
- /* @__PURE__ */ jsx39(Text32, { children: " " }),
24701
- /* @__PURE__ */ jsx39(Text32, { children: "[\u2191/\u2193] move [Enter] edit allowed [Esc] close" })
24773
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: "[\u2191/\u2193] move [Enter] edit allowed tokens [Esc] close" })
24702
24774
  ]
24703
24775
  }
24704
24776
  );
@@ -24946,15 +25018,9 @@ function ReviewFinalizeError({
24946
25018
  function ReviewPanelFooter({
24947
25019
  reviewEditor,
24948
25020
  sidebarFocused,
24949
- sidebarFooter,
24950
- livePreview,
24951
- livePreviewSpinner
25021
+ sidebarFooter
24952
25022
  }) {
24953
- return /* @__PURE__ */ jsxs32(Fragment10, { children: [
24954
- reviewEditor.panelOpen === "token-review" ? " [\u2191/\u2193] move [Enter] edit allowed [Esc] close" : sidebarFocused ? sidebarFooter : reviewEditor.showJson ? " [\u2191\u2193] scroll [Ctrl+u/d] half-page [gg/G] top/bottom [Tab] focus list" : " [Tab] focus list (edit fields)" + (reviewEditor.currentTokenSuggestions().length > 0 ? " [t] token review" : ""),
24955
- livePreview.status === "running" && /* @__PURE__ */ jsx42(Text34, { children: ` ${livePreviewSpinner} live preview` }),
24956
- livePreview.disabled && /* @__PURE__ */ jsx42(Text34, { children: " \xB7 live preview disabled" })
24957
- ] });
25023
+ return /* @__PURE__ */ jsx42(Fragment10, { children: reviewEditor.panelOpen === "token-review" ? "" : sidebarFocused ? sidebarFooter : reviewEditor.showJson ? " [\u2191\u2193] scroll [Ctrl+u/d] half-page [gg/G] top/bottom [Tab] focus list" : " [Tab] focus list [Enter] edit fields" + (reviewEditor.currentTokenSuggestions().length > 0 ? " [t] review mapped tokens" : "") });
24958
25024
  }
24959
25025
  function ReviewComponentTitle({
24960
25026
  selectedKey,
@@ -24988,9 +25054,7 @@ function ReviewComponentPanel({
24988
25054
  sidebarFocused,
24989
25055
  fieldEditor,
24990
25056
  saveError,
24991
- sidebarFooter,
24992
- livePreview,
24993
- livePreviewSpinner
25057
+ sidebarFooter
24994
25058
  }) {
24995
25059
  const propCount = Object.keys(selectedEntry.$properties).length;
24996
25060
  const slotCount = selectedEntry.$slots ? Object.keys(selectedEntry.$slots).length : 0;
@@ -25027,9 +25091,7 @@ function ReviewComponentPanel({
25027
25091
  {
25028
25092
  reviewEditor,
25029
25093
  sidebarFocused,
25030
- sidebarFooter,
25031
- livePreview,
25032
- livePreviewSpinner
25094
+ sidebarFooter
25033
25095
  }
25034
25096
  ) }) })
25035
25097
  ] }) });
@@ -25573,7 +25635,7 @@ function collectTokenSuggestions(entry, availableTokens = []) {
25573
25635
  const compatiblePaths = new Set(compatible);
25574
25636
  const allowed = availableTokens.length > 0 ? persistedAllowed.filter((path5) => compatiblePaths.has(path5)) : persistedAllowed;
25575
25637
  const paths = availableTokens.length > 0 ? compatible : allowed;
25576
- return { propName, paths, suggested: [...allowed], allowed };
25638
+ return { propName, kinds, paths, suggested: [...allowed], allowed };
25577
25639
  });
25578
25640
  }
25579
25641
 
@@ -26369,7 +26431,7 @@ var HELP_SECTIONS2 = [
26369
26431
  { keys: "P", label: "Component rationale" },
26370
26432
  { keys: "s", label: "Source code snippet" },
26371
26433
  { keys: "J", label: "Toggle JSON" },
26372
- { keys: "t", label: "Token review" }
26434
+ { keys: "t", label: "Review mapped tokens" }
26373
26435
  ]
26374
26436
  },
26375
26437
  {
@@ -27517,9 +27579,7 @@ function GenerateReviewStepView({
27517
27579
  initialFocusTarget: pendingEditorFocus && pendingEditorFocus.componentName === selected.key ? pendingEditorFocus.target : { kind: "description" }
27518
27580
  }
27519
27581
  ),
27520
- saveError: reviewEditor.saveError,
27521
- livePreview: livePreviewHook,
27522
- livePreviewSpinner
27582
+ saveError: reviewEditor.saveError
27523
27583
  }
27524
27584
  ) : /* @__PURE__ */ jsx48(ReviewNoSelection, {})
27525
27585
  ] }),
@@ -27551,7 +27611,7 @@ function GenerateReviewStepView({
27551
27611
  hidden: dialogOpen
27552
27612
  }
27553
27613
  ),
27554
- !dialogOpen && sidebarFocused && /* @__PURE__ */ jsx48(CompactControlBar, { hasGroupRoots, searchActive: searchOpen || searchQuery.length > 0 })
27614
+ !dialogOpen && sidebarFocused && reviewEditor.panelOpen !== "token-review" && /* @__PURE__ */ jsx48(CompactControlBar, { hasGroupRoots, searchActive: searchOpen || searchQuery.length > 0 })
27555
27615
  ] });
27556
27616
  }
27557
27617
 
@@ -28041,12 +28101,20 @@ function diffProperty(name, old, newDef) {
28041
28101
  diffs.push({ key: `${name}-new`, color: PALETTE.success, text: `+ ${name}: ${formatPropDef(newDef)}` });
28042
28102
  return diffs;
28043
28103
  }
28104
+ function formatDefault(value) {
28105
+ const sys = value?.sys;
28106
+ if (sys?.linkType === "Contentful:DesignToken" && typeof sys.urn === "string") {
28107
+ const name = sys.urn.split("/designTokens/")[1];
28108
+ if (name) return name;
28109
+ }
28110
+ return JSON.stringify(value);
28111
+ }
28044
28112
  function formatOldProp(prop) {
28045
28113
  const parts = [];
28046
28114
  if (prop.type) parts.push(prop.type);
28047
28115
  if (prop.category) parts.push(prop.category);
28048
28116
  parts.push(prop.required ? "required" : "optional");
28049
- if (prop.default !== void 0) parts.push(`default=${JSON.stringify(prop.default)}`);
28117
+ if (prop.default !== void 0) parts.push(`default=${formatDefault(prop.default)}`);
28050
28118
  return parts.join(", ");
28051
28119
  }
28052
28120
  function formatPropDef(def) {
@@ -28055,7 +28123,7 @@ function formatPropDef(def) {
28055
28123
  if (def["$category"]) parts.push(def["$category"]);
28056
28124
  if (def["$required"] === true) parts.push("required");
28057
28125
  else parts.push("optional");
28058
- if (def["$default"] !== void 0) parts.push(`default=${JSON.stringify(def["$default"])}`);
28126
+ if (def["$default"] !== void 0) parts.push(`default=${formatDefault(def["$default"])}`);
28059
28127
  return parts.join(", ");
28060
28128
  }
28061
28129
 
package/dist/index.js CHANGED
@@ -21792,6 +21792,7 @@ function GotoBanner({
21792
21792
  borderStyle: "single",
21793
21793
  borderColor: PALETTE.accent,
21794
21794
  paddingX: 1,
21795
+ paddingBottom: 1,
21795
21796
  marginTop: width === void 0 ? 1 : 0,
21796
21797
  width,
21797
21798
  flexShrink: 0,
@@ -21803,7 +21804,7 @@ function GotoBanner({
21803
21804
  return renderRow(row, i, i === highlightIndex);
21804
21805
  }),
21805
21806
  moreBelow > 0 && /* @__PURE__ */ jsx24(Text21, { color: PALETTE.muted, children: ` \u25BC ${moreBelow} more` }),
21806
- footerHint !== void 0 && /* @__PURE__ */ jsx24(Text21, { color: PALETTE.muted, children: footerHint })
21807
+ footerHint !== void 0 && /* @__PURE__ */ jsx24(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text21, { color: PALETTE.muted, children: footerHint }) })
21807
21808
  ]
21808
21809
  }
21809
21810
  );
@@ -24535,7 +24536,7 @@ function formatAcceptanceSummary(counts) {
24535
24536
  function describeGeneration(input) {
24536
24537
  const agent = capitalize(input.agent);
24537
24538
  return `${formatAcceptanceSummary({ accepted: input.acceptedCount, autoRejected: 0 })}
24538
- ${agent} is reading each selected component and writing a Contentful component definition for it${input.hasTokens ? " Using your design tokens for prop resolution." : ""}`;
24539
+ ${agent} is reading each selected component and writing a Contentful component definition for it.${input.hasTokens ? "\nUsing your design tokens for prop resolution." : ""}`;
24539
24540
  }
24540
24541
  function progressRows2(progress, agent) {
24541
24542
  const name = capitalize(agent);
@@ -26400,6 +26401,7 @@ function FieldEditor({
26400
26401
  const [rationaleOpen, setRationaleOpen] = useState19(false);
26401
26402
  const [rationaleScrollOffset, setRationaleScrollOffset] = useState19(0);
26402
26403
  const [showHelp, setShowHelp] = useState19(false);
26404
+ const [pendingDelete, setPendingDelete] = useState19(null);
26403
26405
  const props = editorState.props;
26404
26406
  const slots = editorState.slots;
26405
26407
  const contentPropIndexes = React13.useMemo(
@@ -26491,6 +26493,46 @@ function FieldEditor({
26491
26493
  setEditorState(next);
26492
26494
  onChange(serializeState(next, value));
26493
26495
  };
26496
+ const deleteRow = (row) => {
26497
+ if (row.kind === "prop") {
26498
+ const nextProps = removeAt(editorState.props, row.idx);
26499
+ commit({ ...editorState, props: nextProps });
26500
+ setPropIdx(Math.max(0, Math.min(row.idx, nextProps.length - 1)));
26501
+ const rowsAfter2 = selectableRows.filter((r) => !(r.kind === "prop" && r.idx === row.idx));
26502
+ const neighbour2 = rowsAfter2[Math.max(0, selectableRows.findIndex((r) => r.kind === row.kind && r.idx === row.idx) - 1)];
26503
+ if (!neighbour2) {
26504
+ setInSlots(false);
26505
+ setInComponentDesc(true);
26506
+ setFocusLevel("componentDescription");
26507
+ } else if (neighbour2.kind === "prop") {
26508
+ setInSlots(false);
26509
+ setPropIdx(neighbour2.idx > row.idx ? neighbour2.idx - 1 : neighbour2.idx);
26510
+ setFocusLevel("prop");
26511
+ } else {
26512
+ setInSlots(true);
26513
+ setSlotIdx(neighbour2.idx);
26514
+ setFocusLevel("slot");
26515
+ }
26516
+ return;
26517
+ }
26518
+ const nextSlots = removeAt(editorState.slots, row.idx);
26519
+ commit({ ...editorState, slots: nextSlots });
26520
+ const rowsAfter = selectableRows.filter((r) => !(r.kind === "slot" && r.idx === row.idx));
26521
+ const neighbour = rowsAfter[Math.max(0, selectableRows.findIndex((r) => r.kind === row.kind && r.idx === row.idx) - 1)];
26522
+ if (!neighbour) {
26523
+ setInSlots(false);
26524
+ setInComponentDesc(true);
26525
+ setFocusLevel("componentDescription");
26526
+ } else if (neighbour.kind === "slot") {
26527
+ setInSlots(true);
26528
+ setSlotIdx(neighbour.idx > row.idx ? neighbour.idx - 1 : neighbour.idx);
26529
+ setFocusLevel("slot");
26530
+ } else {
26531
+ setInSlots(false);
26532
+ setPropIdx(neighbour.idx);
26533
+ setFocusLevel("prop");
26534
+ }
26535
+ };
26494
26536
  const canonicalize = React13.useCallback((json) => {
26495
26537
  try {
26496
26538
  return JSON.stringify(JSON.parse(json));
@@ -26527,6 +26569,11 @@ function FieldEditor({
26527
26569
  onSave();
26528
26570
  return;
26529
26571
  }
26572
+ if (pendingDelete) {
26573
+ if (input === "y") deleteRow(pendingDelete);
26574
+ setPendingDelete(null);
26575
+ return;
26576
+ }
26530
26577
  const inDescriptionTextEntryForHelp = focusLevel === "field" && editingField && activeField === "description";
26531
26578
  const inStringDefaultTextEntryForHelp = focusLevel === "field" && editingField && activeField === "default" && currentProp != null && (currentProp.type === "string" || currentProp.type === "token");
26532
26579
  const inValueListTextEntry = editingValue != null;
@@ -26726,6 +26773,11 @@ function FieldEditor({
26726
26773
  }
26727
26774
  return;
26728
26775
  }
26776
+ if (input === "d" && !key.ctrl && !key.meta) {
26777
+ if (focusLevel === "prop" && currentProp) setPendingDelete({ kind: "prop", idx: propIdx });
26778
+ if (focusLevel === "slot" && currentSlot) setPendingDelete({ kind: "slot", idx: slotIdx });
26779
+ return;
26780
+ }
26729
26781
  if (focusLevel === "slot" && key.return && currentSlot) {
26730
26782
  setFocusLevel("field");
26731
26783
  setActiveField(SLOT_FIELDS[0] ?? null);
@@ -27032,6 +27084,10 @@ function FieldEditor({
27032
27084
  }
27033
27085
  const hasEmptyProperties = props.length === 0 && slots.length === 0;
27034
27086
  const modeLabel = (() => {
27087
+ if (pendingDelete) {
27088
+ const name = pendingDelete.kind === "prop" ? props[pendingDelete.idx]?.name : slots[pendingDelete.idx]?.name;
27089
+ return `Delete ${pendingDelete.kind} "${name}"? [y] delete \xB7 any other key cancels`;
27090
+ }
27035
27091
  if (editingValue) {
27036
27092
  return editingValue.mode === "add" ? "Enter to add \xB7 [Esc] to cancel" : "Enter to save edit \xB7 [Esc] to cancel";
27037
27093
  }
@@ -27053,7 +27109,7 @@ function FieldEditor({
27053
27109
  if (rationaleOpen) {
27054
27110
  return "[\u2191\u2193] scroll [i/Esc] close rationale panel";
27055
27111
  }
27056
- return `[\u2191\u2193] navigate rows [Enter] edit fields [s] source [${propRationaleKey}] prop rationale [${componentRationaleKey}] component rationale [h] help [Esc] exit panel`;
27112
+ return `[\u2191\u2193] navigate [Enter] edit fields [d] delete property [h] help [s] source [Esc] exit panel`;
27057
27113
  })();
27058
27114
  const rows = [];
27059
27115
  rows.push({ kind: "component-description" });
@@ -27319,6 +27375,7 @@ function FieldEditor({
27319
27375
  /* @__PURE__ */ jsx32(Text27, { bold: true, children: "Row navigation" }),
27320
27376
  /* @__PURE__ */ jsx32(Text27, { children: " \u2191/\u2193 move between rows" }),
27321
27377
  /* @__PURE__ */ jsx32(Text27, { children: " Enter edit fields on the current row" }),
27378
+ /* @__PURE__ */ jsx32(Text27, { children: " d delete the current prop or slot (asks to confirm)" }),
27322
27379
  /* @__PURE__ */ jsx32(Text27, { children: " Esc exit the panel" }),
27323
27380
  /* @__PURE__ */ jsx32(Text27, { children: " " }),
27324
27381
  /* @__PURE__ */ jsx32(Text27, { bold: true, children: "Field editing" }),
@@ -27342,7 +27399,7 @@ function FieldEditor({
27342
27399
  /* @__PURE__ */ jsx32(Text27, { color: PALETTE.muted, children: "press ? or Esc to close" })
27343
27400
  ] }),
27344
27401
  validationError && /* @__PURE__ */ jsx32(Text27, { color: PALETTE.error, children: "\u2717 " + validationError }),
27345
- /* @__PURE__ */ jsx32(Box26, { paddingTop: 1, children: /* @__PURE__ */ jsx32(Text27, { color: PALETTE.muted, children: modeLabel }) })
27402
+ /* @__PURE__ */ jsx32(Box26, { paddingTop: 1, children: /* @__PURE__ */ jsx32(Text27, { color: pendingDelete ? PALETTE.text : PALETTE.muted, children: modeLabel }) })
27346
27403
  ]
27347
27404
  }
27348
27405
  );
@@ -27735,8 +27792,8 @@ function TokenReviewPanel({
27735
27792
  borderStyle: "single",
27736
27793
  borderColor: active ? PALETTE.text : void 0,
27737
27794
  children: [
27738
- /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, wrap: "truncate", children: `TOKEN REVIEW \u2014 ${componentName} \xB7 ${current.propName} (edit allowed)` }),
27739
- /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: `select which tokens are allowed (${rangeLabel})` }),
27795
+ /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, wrap: "truncate", children: `Review mapped tokens \u2014 ${componentName} \xB7 ${current.propName}${current.kinds.length > 0 ? ` (${current.kinds.join(", ")})` : ""}` }),
27796
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: `Tick the tokens this property may use (${rangeLabel}).` }),
27740
27797
  /* @__PURE__ */ jsx39(Text32, { children: " " }),
27741
27798
  current.paths.length === 0 && /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: "(no compatible tokens found for this token kind)" }),
27742
27799
  visiblePaths.map((path5, i) => {
@@ -27769,18 +27826,33 @@ function TokenReviewPanel({
27769
27826
  borderStyle: "single",
27770
27827
  borderColor: active ? PALETTE.text : void 0,
27771
27828
  children: [
27772
- /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, children: `TOKEN REVIEW \u2014 ${componentName}` }),
27829
+ /* @__PURE__ */ jsx39(Text32, { bold: true, color: active ? void 0 : PALETTE.muted, children: `Review mapped tokens \u2014 ${componentName}` }),
27830
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: `${componentName} has ${suggestions.length} design ${suggestions.length === 1 ? "prop" : "props"} of type token. Select which tokens are allowed for each property.` }),
27831
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, wrap: "truncate", children: "Suggested tokens come from the agent. Allowed tokens are what editors can pick in Contentful." }),
27832
+ /* @__PURE__ */ jsx39(Text32, { children: " " }),
27773
27833
  suggestions.length === 0 && /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: "(no token suggestions for this component)" }),
27774
27834
  suggestions.map((s, i) => {
27775
27835
  const focused = i === selectedRow;
27776
27836
  return /* @__PURE__ */ jsxs30(Box31, { flexDirection: "column", children: [
27777
- /* @__PURE__ */ jsx39(Box31, { children: /* @__PURE__ */ jsx39(Text32, { color: focused ? PALETTE.accent : active ? void 0 : PALETTE.muted, bold: focused, children: `${focused ? figures7.pointer : " "} ${s.propName}` }) }),
27778
- /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: ` suggested: ${s.suggested.join(", ")}` }),
27779
- /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: ` allowed: ${s.allowed.join(", ")}` })
27837
+ /* @__PURE__ */ jsx39(Box31, { children: /* @__PURE__ */ jsx39(Text32, { color: focused ? PALETTE.accent : active ? void 0 : PALETTE.muted, bold: focused, children: `${focused ? figures7.pointer : " "} ${s.propName}${s.kinds.length > 0 ? ` (${s.kinds.join(", ")})` : ""}` }) }),
27838
+ /* @__PURE__ */ jsx39(
27839
+ Text32,
27840
+ {
27841
+ color: PALETTE.muted,
27842
+ children: ` suggested: ${s.suggested.length > 0 ? s.suggested.join(", ") : "none"}`
27843
+ }
27844
+ ),
27845
+ /* @__PURE__ */ jsx39(
27846
+ Text32,
27847
+ {
27848
+ color: PALETTE.muted,
27849
+ children: ` allowed: ${s.allowed.length > 0 ? s.allowed.join(", ") : "none (any token)"}`
27850
+ }
27851
+ ),
27852
+ /* @__PURE__ */ jsx39(Text32, { children: " " })
27780
27853
  ] }, s.propName);
27781
27854
  }),
27782
- /* @__PURE__ */ jsx39(Text32, { children: " " }),
27783
- /* @__PURE__ */ jsx39(Text32, { children: "[\u2191/\u2193] move [Enter] edit allowed [Esc] close" })
27855
+ /* @__PURE__ */ jsx39(Text32, { color: PALETTE.muted, children: "[\u2191/\u2193] move [Enter] edit allowed tokens [Esc] close" })
27784
27856
  ]
27785
27857
  }
27786
27858
  );
@@ -28054,15 +28126,9 @@ function ReviewFinalizeError({
28054
28126
  function ReviewPanelFooter({
28055
28127
  reviewEditor,
28056
28128
  sidebarFocused,
28057
- sidebarFooter,
28058
- livePreview,
28059
- livePreviewSpinner
28129
+ sidebarFooter
28060
28130
  }) {
28061
- return /* @__PURE__ */ jsxs32(Fragment10, { children: [
28062
- reviewEditor.panelOpen === "token-review" ? " [\u2191/\u2193] move [Enter] edit allowed [Esc] close" : sidebarFocused ? sidebarFooter : reviewEditor.showJson ? " [\u2191\u2193] scroll [Ctrl+u/d] half-page [gg/G] top/bottom [Tab] focus list" : " [Tab] focus list (edit fields)" + (reviewEditor.currentTokenSuggestions().length > 0 ? " [t] token review" : ""),
28063
- livePreview.status === "running" && /* @__PURE__ */ jsx42(Text34, { children: ` ${livePreviewSpinner} live preview` }),
28064
- livePreview.disabled && /* @__PURE__ */ jsx42(Text34, { children: " \xB7 live preview disabled" })
28065
- ] });
28131
+ return /* @__PURE__ */ jsx42(Fragment10, { children: reviewEditor.panelOpen === "token-review" ? "" : sidebarFocused ? sidebarFooter : reviewEditor.showJson ? " [\u2191\u2193] scroll [Ctrl+u/d] half-page [gg/G] top/bottom [Tab] focus list" : " [Tab] focus list [Enter] edit fields" + (reviewEditor.currentTokenSuggestions().length > 0 ? " [t] review mapped tokens" : "") });
28066
28132
  }
28067
28133
  function ReviewComponentTitle({
28068
28134
  selectedKey,
@@ -28096,9 +28162,7 @@ function ReviewComponentPanel({
28096
28162
  sidebarFocused,
28097
28163
  fieldEditor,
28098
28164
  saveError,
28099
- sidebarFooter,
28100
- livePreview,
28101
- livePreviewSpinner
28165
+ sidebarFooter
28102
28166
  }) {
28103
28167
  const propCount = Object.keys(selectedEntry.$properties).length;
28104
28168
  const slotCount = selectedEntry.$slots ? Object.keys(selectedEntry.$slots).length : 0;
@@ -28135,9 +28199,7 @@ function ReviewComponentPanel({
28135
28199
  {
28136
28200
  reviewEditor,
28137
28201
  sidebarFocused,
28138
- sidebarFooter,
28139
- livePreview,
28140
- livePreviewSpinner
28202
+ sidebarFooter
28141
28203
  }
28142
28204
  ) }) })
28143
28205
  ] }) });
@@ -28739,7 +28801,7 @@ function collectTokenSuggestions(entry, availableTokens = []) {
28739
28801
  const compatiblePaths = new Set(compatible);
28740
28802
  const allowed = availableTokens.length > 0 ? persistedAllowed.filter((path5) => compatiblePaths.has(path5)) : persistedAllowed;
28741
28803
  const paths = availableTokens.length > 0 ? compatible : allowed;
28742
- return { propName, paths, suggested: [...allowed], allowed };
28804
+ return { propName, kinds, paths, suggested: [...allowed], allowed };
28743
28805
  });
28744
28806
  }
28745
28807
  var init_token_suggestions = __esm({
@@ -30690,9 +30752,7 @@ function GenerateReviewStepView({
30690
30752
  initialFocusTarget: pendingEditorFocus && pendingEditorFocus.componentName === selected.key ? pendingEditorFocus.target : { kind: "description" }
30691
30753
  }
30692
30754
  ),
30693
- saveError: reviewEditor.saveError,
30694
- livePreview: livePreviewHook,
30695
- livePreviewSpinner
30755
+ saveError: reviewEditor.saveError
30696
30756
  }
30697
30757
  ) : /* @__PURE__ */ jsx48(ReviewNoSelection, {})
30698
30758
  ] }),
@@ -30724,7 +30784,7 @@ function GenerateReviewStepView({
30724
30784
  hidden: dialogOpen
30725
30785
  }
30726
30786
  ),
30727
- !dialogOpen && sidebarFocused && /* @__PURE__ */ jsx48(CompactControlBar, { hasGroupRoots, searchActive: searchOpen || searchQuery.length > 0 })
30787
+ !dialogOpen && sidebarFocused && reviewEditor.panelOpen !== "token-review" && /* @__PURE__ */ jsx48(CompactControlBar, { hasGroupRoots, searchActive: searchOpen || searchQuery.length > 0 })
30728
30788
  ] });
30729
30789
  }
30730
30790
  var HELP_SECTIONS2;
@@ -30806,7 +30866,7 @@ var init_generate_review_step = __esm({
30806
30866
  { keys: "P", label: "Component rationale" },
30807
30867
  { keys: "s", label: "Source code snippet" },
30808
30868
  { keys: "J", label: "Toggle JSON" },
30809
- { keys: "t", label: "Token review" }
30869
+ { keys: "t", label: "Review mapped tokens" }
30810
30870
  ]
30811
30871
  },
30812
30872
  {
@@ -31385,12 +31445,20 @@ function diffProperty(name, old, newDef) {
31385
31445
  diffs.push({ key: `${name}-new`, color: PALETTE.success, text: `+ ${name}: ${formatPropDef(newDef)}` });
31386
31446
  return diffs;
31387
31447
  }
31448
+ function formatDefault(value) {
31449
+ const sys = value?.sys;
31450
+ if (sys?.linkType === "Contentful:DesignToken" && typeof sys.urn === "string") {
31451
+ const name = sys.urn.split("/designTokens/")[1];
31452
+ if (name) return name;
31453
+ }
31454
+ return JSON.stringify(value);
31455
+ }
31388
31456
  function formatOldProp(prop) {
31389
31457
  const parts = [];
31390
31458
  if (prop.type) parts.push(prop.type);
31391
31459
  if (prop.category) parts.push(prop.category);
31392
31460
  parts.push(prop.required ? "required" : "optional");
31393
- if (prop.default !== void 0) parts.push(`default=${JSON.stringify(prop.default)}`);
31461
+ if (prop.default !== void 0) parts.push(`default=${formatDefault(prop.default)}`);
31394
31462
  return parts.join(", ");
31395
31463
  }
31396
31464
  function formatPropDef(def) {
@@ -31399,7 +31467,7 @@ function formatPropDef(def) {
31399
31467
  if (def["$category"]) parts.push(def["$category"]);
31400
31468
  if (def["$required"] === true) parts.push("required");
31401
31469
  else parts.push("optional");
31402
- if (def["$default"] !== void 0) parts.push(`default=${JSON.stringify(def["$default"])}`);
31470
+ if (def["$default"] !== void 0) parts.push(`default=${formatDefault(def["$default"])}`);
31403
31471
  return parts.join(", ");
31404
31472
  }
31405
31473
  var init_preview_diff = __esm({
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.38.1-dev-build-2bb2d130.0",
3
+ "version": "2.38.1-dev-build-a2bc858b.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -2,7 +2,6 @@ import React from 'react';
2
2
  import type { CDFComponentEntry } from '@contentful/experience-design-system-types';
3
3
  import type { CdfReviewEntry } from '../types.js';
4
4
  import type { UseReviewEditorResult } from '../use-review-editor.js';
5
- import type { UseLivePreviewReturn } from '../use-live-preview.js';
6
5
  import { type ReviewDetailsEditorProps } from './ReviewDetailsEditor.js';
7
6
  type ReviewDetailsEditorConfig = Pick<ReviewDetailsEditorProps, 'componentRationale' | 'reviewMetadata' | 'reviewEditor' | 'width' | 'height' | 'sourceBorderColor' | 'jsonValue' | 'sidebarFocused' | 'fieldEditor'>;
8
7
  export type ReviewComponentPanelProps = ReviewDetailsEditorConfig & {
@@ -10,8 +9,6 @@ export type ReviewComponentPanelProps = ReviewDetailsEditorConfig & {
10
9
  selectedEntry: CDFComponentEntry;
11
10
  saveError: string | null;
12
11
  sidebarFooter?: React.ReactNode;
13
- livePreview: Pick<UseLivePreviewReturn, 'status' | 'disabled'>;
14
- livePreviewSpinner: string;
15
12
  };
16
13
  type ReviewFieldEditor = ReviewDetailsEditorProps['fieldEditor'];
17
14
  export declare function buildReviewFieldEditor(reviewEditor: UseReviewEditorResult, selectedJson: string, onExit: () => void, overrides?: Partial<ReviewFieldEditor>): ReviewFieldEditor;
@@ -29,5 +26,5 @@ export declare function ReviewFinalizeError({ message, hidden, }: {
29
26
  message: string | null;
30
27
  hidden: boolean;
31
28
  }): React.ReactElement | null;
32
- export declare function ReviewComponentPanel({ selectedKey, selectedEntry, componentRationale, reviewMetadata, reviewEditor, width, height, sourceBorderColor, jsonValue, sidebarFocused, fieldEditor, saveError, sidebarFooter, livePreview, livePreviewSpinner, }: ReviewComponentPanelProps): React.ReactElement;
29
+ export declare function ReviewComponentPanel({ selectedKey, selectedEntry, componentRationale, reviewMetadata, reviewEditor, width, height, sourceBorderColor, jsonValue, sidebarFocused, fieldEditor, saveError, sidebarFooter, }: ReviewComponentPanelProps): React.ReactElement;
33
30
  export {};
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export type TokenPropSuggestion = {
3
3
  propName: string;
4
+ kinds: string[];
4
5
  paths: string[];
5
6
  suggested: string[];
6
7
  allowed: string[];
@@ -12,6 +12,7 @@ export type TokenReviewToken = {
12
12
  };
13
13
  export type TokenPropSuggestion = {
14
14
  propName: string;
15
+ kinds: string[];
15
16
  paths: string[];
16
17
  suggested: string[];
17
18
  allowed: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-cli",
3
- "version": "2.38.1-dev-build-2bb2d130.0",
3
+ "version": "2.38.1-dev-build-a2bc858b.0",
4
4
  "description": "Contentful Experiences design system import CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,8 +45,8 @@
45
45
  "ts-morph": "^27.0.2",
46
46
  "typescript": "^5.9.3",
47
47
  "zod": "^4.6.5",
48
- "@contentful/experience-design-system-backend-pipeline": "2.38.1-dev-build-2bb2d130.0",
49
- "@contentful/experience-design-system-types": "2.38.1-dev-build-2bb2d130.0"
48
+ "@contentful/experience-design-system-backend-pipeline": "2.38.1-dev-build-a2bc858b.0",
49
+ "@contentful/experience-design-system-types": "2.38.1-dev-build-a2bc858b.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@tsconfig/node24": "^24.0.4",