@netlisian/softconfig 0.1.2 → 0.1.4

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.
@@ -23,18 +23,6 @@ var __spreadValues = (a, b) => {
23
23
  return a;
24
24
  };
25
25
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
- var __objRest = (source, exclude) => {
27
- var target = {};
28
- for (var prop in source)
29
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
30
- target[prop] = source[prop];
31
- if (source != null && __getOwnPropSymbols)
32
- for (var prop of __getOwnPropSymbols(source)) {
33
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
34
- target[prop] = source[prop];
35
- }
36
- return target;
37
- };
38
26
  var __export = (target, all) => {
39
27
  for (var name in all)
40
28
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -360,7 +348,7 @@ var updateVersion = (version, increment) => {
360
348
  return `${major}.${minor}.${patch}`;
361
349
  };
362
350
  var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true) => ({
363
- fields: {
351
+ fields: __spreadValues({
364
352
  _name: overrides.name || {
365
353
  type: "text",
366
354
  label: "Soft Component Name"
@@ -410,7 +398,7 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
410
398
  }
411
399
  }
412
400
  }
413
- },
401
+ }, overrides.additionalRootFields || {}),
414
402
  resolveFields({ props: data }, { fields, changed }) {
415
403
  var _a, _b;
416
404
  if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
@@ -424,7 +412,7 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
424
412
  )
425
413
  };
426
414
  else delete fields._fieldSettings;
427
- if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length) && (!(data == null ? void 0 : data._version) || changed._version || changed._fieldSettings)) {
415
+ if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length)) {
428
416
  const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
429
417
  delete fields._version;
430
418
  fields._version = {
@@ -452,14 +440,14 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
452
440
  return fields;
453
441
  },
454
442
  resolveData: (props, params) => {
455
- if (overrides.onRootsDataChange)
456
- overrides.onRootsDataChange(props, params);
457
- return {
443
+ if (overrides.resolveRootData) {
444
+ return overrides.resolveRootData(props, params, { editingComponent });
445
+ }
446
+ let result = {
458
447
  props,
459
- readOnly: Boolean(editingComponent) ? {
460
- _name: true
461
- } : void 0
448
+ readOnly: void 0
462
449
  };
450
+ return result;
463
451
  },
464
452
  render: (props) => {
465
453
  const fieldSettings = props == null ? void 0 : props._fieldSettings;
@@ -965,6 +953,21 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
965
953
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
966
954
  const fields = rootProps._fields || [];
967
955
  const field_settings = rootProps._fieldSettings || {};
956
+ const builtInRootProps = /* @__PURE__ */ new Set([
957
+ "_name",
958
+ "_category",
959
+ "_version",
960
+ "_versions",
961
+ "_fields",
962
+ "_fieldSettings"
963
+ ]);
964
+ const customRootProps = Object.keys(rootProps).filter((key) => key.startsWith("_") && !builtInRootProps.has(key)).reduce(
965
+ (acc, key) => {
966
+ acc[key] = rootProps[key];
967
+ return acc;
968
+ },
969
+ {}
970
+ );
968
971
  const slots = {};
969
972
  const components = getSubComponents(
970
973
  [editedItem],
@@ -989,6 +992,7 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
989
992
  }, {})),
990
993
  fieldSettings: field_settings,
991
994
  defaultProps,
995
+ rootProps: customRootProps,
992
996
  components,
993
997
  slots
994
998
  },
@@ -1000,6 +1004,24 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
1000
1004
  var import_uuid = require("uuid");
1001
1005
  var generateId = (type) => type ? `${type}-${(0, import_uuid.v4)()}` : (0, import_uuid.v4)();
1002
1006
 
1007
+ // src/puck/lib/component-key.ts
1008
+ var defaultToCamelCase = (value) => {
1009
+ const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1010
+ if (tokens.length === 0) return "";
1011
+ const [first, ...rest] = tokens;
1012
+ return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1013
+ };
1014
+ var createComponentKeyFromName = (displayName, overrides, context) => {
1015
+ const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1016
+ return key.trim();
1017
+ };
1018
+ var getComponentNameFromKey = (key, overrides) => {
1019
+ if (overrides.componentKeyToName) {
1020
+ return overrides.componentKeyToName(key);
1021
+ }
1022
+ return key;
1023
+ };
1024
+
1003
1025
  // src/puck/lib/soft-component-to-appstate.ts
1004
1026
  var puckFieldsToSoftFields = (fields, slots) => {
1005
1027
  const softFields = [];
@@ -1118,7 +1140,7 @@ var reconstructComponents = (subComponents, componentConfigs, softComponentProps
1118
1140
  return componentData;
1119
1141
  });
1120
1142
  };
1121
- var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, displayName, category) => {
1143
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, overrides, displayName, category) => {
1122
1144
  const slots = new Set(Object.keys(softComponent.slots));
1123
1145
  const { fields, fieldSettings } = puckFieldsToSoftFields(
1124
1146
  softComponent.fields,
@@ -1129,14 +1151,17 @@ var softComponentToAppState = (softComponent, componentName, version, versions,
1129
1151
  fieldSettings[key].defaultValue = value;
1130
1152
  }
1131
1153
  });
1132
- const rootProps = {
1133
- _name: displayName || componentName,
1154
+ let rootProps = __spreadValues({
1155
+ _name: displayName || getComponentNameFromKey(componentName, overrides),
1134
1156
  _category: category,
1135
1157
  _version: version,
1136
1158
  _versions: versions,
1137
1159
  _fields: fields,
1138
1160
  _fieldSettings: fieldSettings
1139
- };
1161
+ }, softComponent.rootProps || {});
1162
+ if (overrides.onRemodel) {
1163
+ rootProps = __spreadValues(__spreadValues({}, rootProps), overrides.onRemodel(componentName));
1164
+ }
1140
1165
  const content = reconstructComponents(
1141
1166
  softComponent.components,
1142
1167
  componentConfigs,
@@ -1158,114 +1183,111 @@ var rootZone = "default-zone";
1158
1183
  var rootDroppableId = `${rootAreaId}:${rootZone}`;
1159
1184
 
1160
1185
  // src/puck/components/soft-render/index.tsx
1161
- var import_react4 = require("react");
1162
- var import_uuid2 = require("uuid");
1163
- var import_fast_deep_equal = __toESM(require("fast-deep-equal"));
1186
+ var import_react4 = __toESM(require("react"));
1187
+ var import_react_fast_compare = __toESM(require("react-fast-compare"));
1164
1188
  var import_jsx_runtime5 = require("react/jsx-runtime");
1165
- function SoftRender({
1166
- softComponentFields,
1167
- softComponentFieldSettings,
1168
- softSubComponent,
1169
- configComponents,
1170
- props,
1171
- depth = 0
1172
- }) {
1173
- const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1174
- const mapCacheRef = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
1175
- const prevPropsRef = (0, import_react4.useRef)(null);
1176
- if (!(0, import_fast_deep_equal.default)(prevPropsRef.current, props)) {
1177
- mapCacheRef.current.clear();
1178
- prevPropsRef.current = props;
1179
- }
1180
- const subComponentRootProps = (0, import_react4.useMemo)(
1181
- () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
1182
- (acc, [fieldKey]) => {
1183
- acc[fieldKey] = props[fieldKey];
1184
- return acc;
1185
- },
1186
- {}
1187
- ),
1188
- [softComponentFields, props]
1189
+ function isPlainObject(val) {
1190
+ if (typeof val !== "object" || val === null) return false;
1191
+ if (import_react4.default.isValidElement(val)) return false;
1192
+ if ("$$typeof" in val) return false;
1193
+ const proto = Object.getPrototypeOf(val);
1194
+ return proto === Object.prototype || proto === null;
1195
+ }
1196
+ function cloneData(value) {
1197
+ if (value === null || value === void 0) return value;
1198
+ if (typeof value === "function") return value;
1199
+ if (Array.isArray(value)) return value.map(cloneData);
1200
+ if (!isPlainObject(value)) return value;
1201
+ return Object.fromEntries(
1202
+ Object.entries(value).map(([k, v]) => [k, cloneData(v)])
1189
1203
  );
1190
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1191
- var _a2;
1204
+ }
1205
+ var SubComponentRenderer = (0, import_react4.memo)(
1206
+ ({
1207
+ subComponent,
1208
+ softComponentFields,
1209
+ softComponentFieldSettings,
1210
+ configComponents,
1211
+ props,
1212
+ depth,
1213
+ index
1214
+ }) => {
1215
+ const { id, puck, editMode } = props;
1192
1216
  const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
1193
- if (!componentConfig) return null;
1194
- const resolvedProps = subComponent.fixedProps || {};
1195
1217
  const stableId = (0, import_react4.useMemo)(
1196
- () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-${(0, import_uuid2.v4)()}`,
1197
- [id, depth, subComponent.type]
1218
+ () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-i${index}`,
1219
+ [id, depth, subComponent.type, index]
1198
1220
  );
1199
- if ((_a2 = subComponent.map) == null ? void 0 : _a2.length) {
1200
- subComponent.map.forEach((mapItem) => {
1201
- const { from, to, transform } = mapItem || {};
1202
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1203
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1204
- const inputValues = fromPaths.map((f) => {
1205
- const propValue = getFieldSettingsByPath(props || {}, f);
1206
- if (propValue !== void 0) return propValue;
1207
- const setting = getFieldSettingsByPath(
1208
- softComponentFieldSettings || {},
1209
- f
1210
- );
1211
- if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1212
- return setting.defaultValue;
1221
+ const finalProps = (0, import_react4.useMemo)(() => {
1222
+ var _a;
1223
+ if (!componentConfig) return {};
1224
+ const clonedProps = cloneData(subComponent.fixedProps || {});
1225
+ if ((_a = subComponent.map) == null ? void 0 : _a.length) {
1226
+ subComponent.map.forEach((mapItem) => {
1227
+ const { from, to, transform } = mapItem || {};
1228
+ const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1229
+ const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1230
+ const inputValues = fromPaths.map((f) => {
1231
+ const propValue = getFieldSettingsByPath(props, f);
1232
+ if (propValue !== void 0) return propValue;
1233
+ const setting = getFieldSettingsByPath(softComponentFieldSettings || {}, f);
1234
+ if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1235
+ return setting.defaultValue;
1236
+ }
1237
+ return propValue;
1238
+ });
1239
+ const result = transform ? transform(inputValues, props) : inputValues[0];
1240
+ if (Array.isArray(result)) {
1241
+ result.forEach(
1242
+ (val, i) => toPaths[i] && setPropertyByPath(clonedProps, toPaths[i], val)
1243
+ );
1244
+ } else if (toPaths[0]) {
1245
+ setPropertyByPath(clonedProps, toPaths[0], result);
1213
1246
  }
1214
- return propValue;
1215
1247
  });
1216
- const cacheKey = inputValues.map((v, i) => `${i}:${typeof v === "object" ? JSON.stringify(v) : v}`).join("|");
1217
- let result = mapCacheRef.current.get(cacheKey);
1218
- if (!result) {
1219
- const runner = transform;
1220
- result = runner ? runner(inputValues, props) : inputValues[0];
1221
- mapCacheRef.current.set(cacheKey, result);
1222
- }
1223
- if (Array.isArray(result)) {
1224
- result.forEach(
1225
- (val, i) => toPaths[i] && setPropertyByPath(resolvedProps, toPaths[i], val)
1226
- );
1227
- } else if (toPaths[0]) {
1228
- setPropertyByPath(resolvedProps, toPaths[0], result);
1229
- }
1230
- });
1231
- }
1232
- Object.entries(componentConfig.fields || {}).forEach(
1233
- ([slotKey, field]) => {
1234
- var _a3, _b;
1235
- if (field.type === "slot") {
1236
- const enabledSlot = (_a3 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a3.find(
1248
+ }
1249
+ Object.entries(componentConfig.fields || {}).forEach(
1250
+ ([slotKey, field]) => {
1251
+ var _a2, _b, _c;
1252
+ if (field.type !== "slot") return;
1253
+ const enabledSlot = (_a2 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a2.find(
1237
1254
  (s) => s.slot === slotKey
1238
1255
  );
1239
1256
  if (enabledSlot) {
1240
1257
  const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1241
- resolvedProps[slotKey] = (0, import_react4.useMemo)(
1242
- () => rest[slotName] || (() => null),
1243
- [slotName, rest[slotName]]
1244
- );
1258
+ clonedProps[slotKey] = (_c = props[slotName]) != null ? _c : (() => null);
1245
1259
  } else {
1246
- resolvedProps[slotKey] = (0, import_react4.useMemo)(() => {
1247
- return ({
1248
- className,
1249
- style
1250
- }) => {
1251
- var _a4, _b2;
1252
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1253
- SoftRender,
1254
- {
1255
- softComponentFields,
1256
- softSubComponent: (_b2 = (_a4 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a4[slotKey]) != null ? _b2 : [],
1257
- configComponents,
1258
- props,
1259
- depth: depth + 1
1260
- },
1261
- slotKey
1262
- ) });
1263
- };
1264
- }, [slotKey, subComponentRootProps]);
1260
+ clonedProps[slotKey] = ({
1261
+ className,
1262
+ style
1263
+ }) => {
1264
+ var _a3, _b2;
1265
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1266
+ SoftRender,
1267
+ {
1268
+ softComponentFields,
1269
+ softComponentFieldSettings,
1270
+ softSubComponent: (_b2 = (_a3 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a3[slotKey]) != null ? _b2 : [],
1271
+ configComponents,
1272
+ props,
1273
+ depth: depth + 1
1274
+ }
1275
+ ) });
1276
+ };
1265
1277
  }
1266
1278
  }
1267
- }
1268
- );
1279
+ );
1280
+ return clonedProps;
1281
+ }, [
1282
+ componentConfig,
1283
+ subComponent,
1284
+ props,
1285
+ softComponentFields,
1286
+ softComponentFieldSettings,
1287
+ configComponents,
1288
+ depth
1289
+ ]);
1290
+ if (!componentConfig) return null;
1269
1291
  const ComponentRender = componentConfig.render;
1270
1292
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1271
1293
  ComponentRender,
@@ -1273,10 +1295,53 @@ function SoftRender({
1273
1295
  id: stableId,
1274
1296
  editMode,
1275
1297
  puck
1276
- }, resolvedProps)
1277
- ) }, index);
1278
- }) });
1279
- }
1298
+ }, finalProps)
1299
+ ) });
1300
+ },
1301
+ // Custom comparator for SubComponentRenderer.
1302
+ //
1303
+ // Uses deep equality on subComponent (it may be a new reference even when
1304
+ // semantically unchanged if the parent SoftRender array is reconstructed)
1305
+ // and on props (the primary driver of field-mapping changes).
1306
+ // configComponents and softComponentFields are treated as stable config
1307
+ // references — reference equality is intentional and fast here.
1308
+ (prev, next) => prev.depth === next.depth && prev.index === next.index && prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && (0, import_react_fast_compare.default)(prev.props, next.props) && (0, import_react_fast_compare.default)(prev.subComponent, next.subComponent) && (0, import_react_fast_compare.default)(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1309
+ );
1310
+ SubComponentRenderer.displayName = "SubComponentRenderer";
1311
+ var SoftRender = (0, import_react4.memo)(
1312
+ ({
1313
+ softComponentFields,
1314
+ softComponentFieldSettings,
1315
+ softSubComponent,
1316
+ configComponents,
1317
+ props,
1318
+ depth = 0
1319
+ }) => {
1320
+ if (!(softSubComponent == null ? void 0 : softSubComponent.length)) return null;
1321
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: softSubComponent.map((subComponent, index) => {
1322
+ var _a;
1323
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1324
+ SubComponentRenderer,
1325
+ {
1326
+ subComponent,
1327
+ softComponentFields,
1328
+ softComponentFieldSettings: softComponentFieldSettings || {},
1329
+ configComponents,
1330
+ props,
1331
+ depth,
1332
+ index
1333
+ },
1334
+ `${(_a = subComponent == null ? void 0 : subComponent.type) != null ? _a : "comp"}-${index}-${depth}`
1335
+ );
1336
+ }) });
1337
+ },
1338
+ // Covers all five props — not just `props` and `softSubComponent`.
1339
+ // configComponents / softComponentFields: reference equality (stable config).
1340
+ // softComponentFieldSettings: deep equality (may carry dynamic defaults).
1341
+ // props / softSubComponent: deep equality (primary render drivers).
1342
+ (prev, next) => prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && (0, import_react_fast_compare.default)(prev.props, next.props) && (0, import_react_fast_compare.default)(prev.softSubComponent, next.softSubComponent) && (0, import_react_fast_compare.default)(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1343
+ );
1344
+ SoftRender.displayName = "SoftRender";
1280
1345
 
1281
1346
  // src/puck/lib/create-versioned-component-config.tsx
1282
1347
  var import_jsx_runtime6 = require("react/jsx-runtime");
@@ -1430,18 +1495,6 @@ function demolishSoftComponent(componentName, data, config, softComponents) {
1430
1495
  };
1431
1496
  }
1432
1497
 
1433
- // src/puck/lib/component-key.ts
1434
- var defaultToCamelCase = (value) => {
1435
- const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1436
- if (tokens.length === 0) return "";
1437
- const [first, ...rest] = tokens;
1438
- return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1439
- };
1440
- var createComponentKeyFromName = (displayName, overrides, context) => {
1441
- const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1442
- return key.trim();
1443
- };
1444
-
1445
1498
  // src/puck/store/slices/builder.tsx
1446
1499
  var createBuildersSlice = (set, get, initialConfig) => ({
1447
1500
  build: (history, selectedItem, itemSelector, puckDispatch, name) => {
@@ -1541,6 +1594,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1541
1594
  versions,
1542
1595
  selectedItem.props,
1543
1596
  get().softConfig.components,
1597
+ get().overrides,
1544
1598
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || softComponentName,
1545
1599
  softComponentMeta == null ? void 0 : softComponentMeta.category
1546
1600
  );
@@ -1593,6 +1647,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1593
1647
  zone: itemSelector.zone || rootDroppableId
1594
1648
  },
1595
1649
  editingComponentId: selectedItem.props.id,
1650
+ editingComponent: softComponentName,
1596
1651
  editableComponentIds: editableIds,
1597
1652
  state: "remodeling"
1598
1653
  }));
@@ -1609,7 +1664,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1609
1664
  );
1610
1665
  },
1611
1666
  complete: (appState, setHistories, getItemBySelector) => {
1612
- var _a, _b, _c, _d, _e;
1667
+ var _a, _b, _c, _d, _e, _f, _g;
1613
1668
  if (get().state === "ready") {
1614
1669
  throw new Error("Not building or remodeling a component.");
1615
1670
  }
@@ -1628,10 +1683,11 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1628
1683
  throw new Error("Cannot find item being edited");
1629
1684
  }
1630
1685
  const rootCategory = (_e = (_d = appState.data.root) == null ? void 0 : _d.props) == null ? void 0 : _e._category;
1631
- const componentName = createComponentKeyFromName(displayName, get().overrides, {
1686
+ const rootProps = (_f = appState.data.root) == null ? void 0 : _f.props;
1687
+ const componentName = createComponentKeyFromName(displayName, get().overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
1632
1688
  existingKeys: Object.keys(get().softComponents),
1633
1689
  state: get().state
1634
- });
1690
+ }));
1635
1691
  if (!componentName) {
1636
1692
  throw new Error("Failed to generate component key from name.");
1637
1693
  }
@@ -1690,12 +1746,26 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1690
1746
  storedConfig: void 0,
1691
1747
  state: "inspecting",
1692
1748
  originalHistory: [],
1749
+ editingComponent: null,
1693
1750
  editingComponentId: null,
1694
1751
  editableComponentIds: /* @__PURE__ */ new Set()
1695
1752
  });
1696
1753
  });
1754
+ if (!version) {
1755
+ throw new Error("Failed to resolve completed component version.");
1756
+ }
1757
+ const completedSoftComponent = (_g = get().softComponents[componentName]) == null ? void 0 : _g.versions[version];
1758
+ if (!completedSoftComponent) {
1759
+ throw new Error(
1760
+ `Completed soft component "${componentName}" version "${version}" not found.`
1761
+ );
1762
+ }
1697
1763
  get().rebuildDependents(componentName, version);
1698
- return componentName;
1764
+ return {
1765
+ id: componentName,
1766
+ version,
1767
+ softComponent: completedSoftComponent
1768
+ };
1699
1769
  },
1700
1770
  inspect: (componentName, puckDispatch) => {
1701
1771
  if (get().state !== "inspecting") {
@@ -1736,6 +1806,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1736
1806
  itemSelector: null,
1737
1807
  originalItem: null,
1738
1808
  state: "ready",
1809
+ editingComponent: null,
1739
1810
  editingComponentId: null,
1740
1811
  editableComponentIds: /* @__PURE__ */ new Set()
1741
1812
  }));
@@ -1828,6 +1899,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1828
1899
  versions,
1829
1900
  currentProps,
1830
1901
  get().softConfig.components,
1902
+ get().overrides,
1831
1903
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1832
1904
  softComponentMeta == null ? void 0 : softComponentMeta.category
1833
1905
  );
@@ -2132,6 +2204,7 @@ var createSoftConfigStore = (hardConfig = {
2132
2204
  onActions,
2133
2205
  iframeDocRef,
2134
2206
  showVersionFields,
2207
+ editingComponent: null,
2135
2208
  setShowVersionFields: (show) => set({ showVersionFields: show }),
2136
2209
  getIframeDoc: () => iframeDocRef.current,
2137
2210
  setIframeDoc: (doc) => {
@@ -2452,14 +2525,19 @@ var SoftConfigProvider = ({
2452
2525
  );
2453
2526
  const validateAction = (0, import_react5.useMemo)(
2454
2527
  () => (action) => {
2528
+ var _a;
2455
2529
  const currentState = store.getState();
2456
2530
  if (currentState.state === "ready") {
2457
2531
  return true;
2458
2532
  }
2459
2533
  const editableIds = currentState.editableComponentIds;
2460
2534
  if (action.type === "replace") {
2535
+ const parentId = (_a = action.destinationZone) == null ? void 0 : _a.split(":")[0];
2461
2536
  if (action.data.props.id && editableIds.has(action.data.props.id)) {
2462
2537
  return true;
2538
+ } else if (parentId && editableIds.has(parentId)) {
2539
+ currentState.addEditableComponentId(action.data.props.id);
2540
+ return true;
2463
2541
  }
2464
2542
  return false;
2465
2543
  }
@@ -2625,28 +2703,42 @@ var useRemodel = () => {
2625
2703
  const refreshPermissions = useCustomPuck3((s) => s.refreshPermissions);
2626
2704
  const { triggerAction } = useActionEvent();
2627
2705
  const handleRemodel = (componentName) => {
2706
+ var _a, _b, _c;
2628
2707
  if (status !== "ready") {
2629
2708
  notify.error("Can only remodel when in ready state.");
2630
- return;
2709
+ return null;
2631
2710
  }
2632
2711
  const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
2633
2712
  if (!name || !Object.keys(softComponents).includes(name)) {
2634
2713
  notify.error("Selected component is not a soft component.");
2635
- return;
2714
+ return null;
2636
2715
  }
2716
+ const selectedVersion = ((_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.version) || ((_b = softComponents[name]) == null ? void 0 : _b.defaultVersion);
2717
+ const selectedSoftComponent = selectedVersion ? (_c = softComponents[name]) == null ? void 0 : _c.versions[selectedVersion] : void 0;
2637
2718
  try {
2638
2719
  remodel(history, selectedItem, itemSelector, dispatch, refreshPermissions);
2639
2720
  void triggerAction({
2640
2721
  type: "remodel",
2641
2722
  payload: {
2642
- id: name
2723
+ id: name,
2724
+ version: selectedVersion,
2725
+ softComponent: selectedSoftComponent
2643
2726
  }
2644
2727
  });
2728
+ if (selectedVersion && selectedSoftComponent) {
2729
+ return {
2730
+ id: name,
2731
+ version: selectedVersion,
2732
+ softComponent: selectedSoftComponent
2733
+ };
2734
+ }
2735
+ return { id: name, version: selectedVersion };
2645
2736
  } catch (error) {
2646
2737
  console.error("Failed to remodel:", error);
2647
2738
  notify.error(
2648
2739
  "Failed to remodel: " + (error instanceof Error ? error.message : String(error))
2649
2740
  );
2741
+ return null;
2650
2742
  }
2651
2743
  };
2652
2744
  const canRemodel = (componentName) => {
@@ -2666,31 +2758,29 @@ var useComplete = () => {
2666
2758
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2667
2759
  const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2668
2760
  const status = useSoftConfig((s) => s.state);
2669
- const softComponents = useSoftConfig((s) => s.softComponents);
2670
2761
  const [newComponent, setNewComponent] = (0, import_react7.useState)(null);
2671
2762
  const { triggerAction } = useActionEvent();
2672
2763
  const handleComplete = (0, import_react7.useCallback)(() => {
2673
- var _a, _b;
2674
2764
  if (status === "ready") {
2675
2765
  notify.error("Not building or remodeling a component.");
2676
2766
  return null;
2677
2767
  }
2678
2768
  try {
2679
- const componentName = complete(appState, setHistories, getItemBySelector);
2680
- setNewComponent(componentName);
2769
+ const completedComponent = complete(appState, setHistories, getItemBySelector);
2770
+ setNewComponent(completedComponent);
2681
2771
  const componentData = appState.data.root;
2682
- const softComponent = (_b = softComponents[componentName]) == null ? void 0 : _b.versions[(_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion];
2683
- if (softComponent && componentData) {
2772
+ if (componentData) {
2684
2773
  void triggerAction({
2685
2774
  type: "complete",
2686
2775
  payload: {
2687
- id: componentName,
2776
+ id: completedComponent.id,
2777
+ version: completedComponent.version,
2688
2778
  componentData,
2689
- softComponent
2779
+ softComponent: completedComponent.softComponent
2690
2780
  }
2691
2781
  });
2692
2782
  }
2693
- return componentName;
2783
+ return completedComponent;
2694
2784
  } catch (error) {
2695
2785
  console.error("Failed to complete:", error);
2696
2786
  notify.error(
@@ -2698,7 +2788,7 @@ var useComplete = () => {
2698
2788
  );
2699
2789
  return null;
2700
2790
  }
2701
- }, [complete, appState, setHistories, status, softComponents, triggerAction, getItemBySelector]);
2791
+ }, [complete, appState, setHistories, status, triggerAction, getItemBySelector]);
2702
2792
  const canComplete = status === "building" || status === "remodeling";
2703
2793
  return { handleComplete, canComplete, newComponent, setNewComponent };
2704
2794
  };
@@ -2737,23 +2827,25 @@ var useCancel = () => {
2737
2827
  var import_puck9 = require("@measured/puck");
2738
2828
  var import_react8 = require("react");
2739
2829
  var useCustomPuck6 = (0, import_puck9.createUsePuck)();
2740
- var useInspect = (componentName) => {
2830
+ var useInspect = (component) => {
2741
2831
  const inspect = useSoftConfig((s) => s.builder.inspect);
2742
2832
  const dispatch = useCustomPuck6((s) => s.dispatch);
2743
2833
  const status = useSoftConfig((s) => s.state);
2744
2834
  const { triggerAction } = useActionEvent();
2745
2835
  (0, import_react8.useEffect)(() => {
2746
2836
  if (status !== "inspecting") return;
2747
- if (!componentName) {
2837
+ if (!component) {
2748
2838
  notify.error("No component to inspect.");
2749
2839
  return;
2750
2840
  }
2751
2841
  try {
2752
- inspect(componentName, dispatch);
2842
+ inspect(component.id, dispatch);
2753
2843
  void triggerAction({
2754
2844
  type: "inspect",
2755
2845
  payload: {
2756
- id: componentName
2846
+ id: component.id,
2847
+ version: component.version,
2848
+ softComponent: component.softComponent
2757
2849
  }
2758
2850
  });
2759
2851
  } catch (error) {
@@ -2762,7 +2854,7 @@ var useInspect = (componentName) => {
2762
2854
  "Failed to inspect: " + (error instanceof Error ? error.message : String(error))
2763
2855
  );
2764
2856
  }
2765
- }, [status, componentName, inspect, dispatch, triggerAction]);
2857
+ }, [status, component, inspect, dispatch, triggerAction]);
2766
2858
  };
2767
2859
 
2768
2860
  // src/puck/actions/useDecompose.tsx
@@ -2978,9 +3070,9 @@ var Header = ({
2978
3070
  {
2979
3071
  variant: "primary",
2980
3072
  onClick: () => {
2981
- const name = handleComplete();
2982
- if (name) {
2983
- setNewComponent(name);
3073
+ const completedComponent = handleComplete();
3074
+ if (completedComponent) {
3075
+ setNewComponent(completedComponent);
2984
3076
  }
2985
3077
  },
2986
3078
  children: "Complete"
@@ -3014,7 +3106,7 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
3014
3106
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
3015
3107
  var usePuck2 = (0, import_puck14.createUsePuck)();
3016
3108
  var ActionBarOverride = (props) => {
3017
- var _a;
3109
+ var _a, _b;
3018
3110
  const { handleBuild } = useBuild("Custom Name");
3019
3111
  const { handleRemodel } = useRemodel();
3020
3112
  const { handleDecompose } = useDecompose();
@@ -3022,20 +3114,31 @@ var ActionBarOverride = (props) => {
3022
3114
  const softComponents = useSoftConfig((s) => s.softComponents, import_shallow.shallow);
3023
3115
  const editableIds = useSoftConfig((s) => s.editableComponentIds);
3024
3116
  const selectedItem = usePuck2((s) => s.selectedItem);
3117
+ const rootProps = usePuck2((s) => s.appState.data.root.props);
3025
3118
  const status = useSoftConfig((s) => s.state);
3119
+ const itemSelector = usePuck2((s) => s.appState.ui.itemSelector);
3026
3120
  const softKeys = Object.keys(softComponents);
3027
- const key = (0, import_react9.useMemo)(() => createComponentKeyFromName(props.label || "", overrides, {
3028
- existingKeys: softKeys,
3029
- state: status
3030
- }), [
3121
+ const key = (0, import_react9.useMemo)(() => {
3122
+ const selectedType = selectedItem == null ? void 0 : selectedItem.type;
3123
+ if (selectedType && softKeys.includes(selectedType)) {
3124
+ return selectedType;
3125
+ }
3126
+ return createComponentKeyFromName(props.label || "", overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
3127
+ existingKeys: softKeys,
3128
+ state: status
3129
+ }));
3130
+ }, [
3031
3131
  props.label,
3032
3132
  overrides,
3133
+ selectedItem == null ? void 0 : selectedItem.type,
3033
3134
  softKeys,
3034
- status
3135
+ status,
3136
+ rootProps
3035
3137
  ]);
3036
3138
  const isSoftComponent2 = softKeys.includes(key);
3037
3139
  const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
3038
- const isEditable = Boolean(selectedId && editableIds.has(selectedId));
3140
+ const parentId = (_b = itemSelector == null ? void 0 : itemSelector.zone) == null ? void 0 : _b.split(":")[0];
3141
+ const isEditable = Boolean(selectedId && (editableIds.has(selectedId) || parentId && editableIds.has(parentId)));
3039
3142
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: getClassName3(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar, { children: [
3040
3143
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar.Group, { children: [
3041
3144
  props.parentAction,
@@ -3095,14 +3198,14 @@ var confirm = (message) => __async(null, null, function* () {
3095
3198
  });
3096
3199
 
3097
3200
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/DrawerItem.module.css#css-module
3098
- var DrawerItem_module_default = { "DrawerItem": "_DrawerItem_29z19_1", "DrawerItem--insertDisabled": "_DrawerItem--insertDisabled_29z19_14", "DrawerItem-content": "_DrawerItem-content_29z19_21", "DrawerItem-name": "_DrawerItem-name_29z19_31", "DrawerItem-version": "_DrawerItem-version_29z19_35", "DrawerItem-actions": "_DrawerItem-actions_29z19_40", "DrawerItem-settingsButton": "_DrawerItem-settingsButton_29z19_46", "DrawerItem-grip": "_DrawerItem-grip_29z19_56", "DrawerItem-modal": "_DrawerItem-modal_29z19_63", "DrawerItem-modalHeader": "_DrawerItem-modalHeader_29z19_70", "DrawerItem-modalTitle": "_DrawerItem-modalTitle_29z19_75", "DrawerItem-modalSubtitle": "_DrawerItem-modalSubtitle_29z19_82", "DrawerItem-modalBody": "_DrawerItem-modalBody_29z19_88", "DrawerItem-section": "_DrawerItem-section_29z19_97", "DrawerItem-sectionTitle": "_DrawerItem-sectionTitle_29z19_103", "DrawerItem-sectionDescription": "_DrawerItem-sectionDescription_29z19_110", "DrawerItem-versionList": "_DrawerItem-versionList_29z19_116", "DrawerItem-versionRow": "_DrawerItem-versionRow_29z19_122", "DrawerItem-versionRow--isDefault": "_DrawerItem-versionRow--isDefault_29z19_133", "DrawerItem-versionRow--isMarkedForDeletion": "_DrawerItem-versionRow--isMarkedForDeletion_29z19_138", "DrawerItem-versionInfo": "_DrawerItem-versionInfo_29z19_143", "DrawerItem-versionNumber": "_DrawerItem-versionNumber_29z19_150", "DrawerItem-defaultBadge": "_DrawerItem-defaultBadge_29z19_156", "DrawerItem-deleteBadge": "_DrawerItem-deleteBadge_29z19_167", "DrawerItem-versionActions": "_DrawerItem-versionActions_29z19_178", "DrawerItem-migrationOptions": "_DrawerItem-migrationOptions_29z19_184", "DrawerItem-select": "_DrawerItem-select_29z19_188", "DrawerItem-modalFooter": "_DrawerItem-modalFooter_29z19_209", "DrawerItem-footerLeft": "_DrawerItem-footerLeft_29z19_218", "DrawerItem-footerRight": "_DrawerItem-footerRight_29z19_223" };
3201
+ var DrawerItem_module_default = { "DrawerItem": "_DrawerItem_182aj_1", "DrawerItem--insertDisabled": "_DrawerItem--insertDisabled_182aj_14", "DrawerItem-content": "_DrawerItem-content_182aj_21", "DrawerItem-name": "_DrawerItem-name_182aj_31", "DrawerItem-version": "_DrawerItem-version_182aj_35", "DrawerItem-actions": "_DrawerItem-actions_182aj_40", "DrawerItem-settingsButton": "_DrawerItem-settingsButton_182aj_46", "DrawerItem-grip": "_DrawerItem-grip_182aj_56", "DrawerItem-modal": "_DrawerItem-modal_182aj_63", "DrawerItem-modalHeader": "_DrawerItem-modalHeader_182aj_71", "DrawerItem-modalTitle": "_DrawerItem-modalTitle_182aj_77", "DrawerItem-modalSubtitle": "_DrawerItem-modalSubtitle_182aj_84", "DrawerItem-modalBody": "_DrawerItem-modalBody_182aj_90", "DrawerItem-section": "_DrawerItem-section_182aj_100", "DrawerItem-sectionTitle": "_DrawerItem-sectionTitle_182aj_106", "DrawerItem-sectionDescription": "_DrawerItem-sectionDescription_182aj_113", "DrawerItem-versionList": "_DrawerItem-versionList_182aj_119", "DrawerItem-versionRow": "_DrawerItem-versionRow_182aj_125", "DrawerItem-versionRow--isDefault": "_DrawerItem-versionRow--isDefault_182aj_136", "DrawerItem-versionRow--isMarkedForDeletion": "_DrawerItem-versionRow--isMarkedForDeletion_182aj_141", "DrawerItem-versionInfo": "_DrawerItem-versionInfo_182aj_146", "DrawerItem-versionNumber": "_DrawerItem-versionNumber_182aj_153", "DrawerItem-defaultBadge": "_DrawerItem-defaultBadge_182aj_159", "DrawerItem-deleteBadge": "_DrawerItem-deleteBadge_182aj_170", "DrawerItem-versionActions": "_DrawerItem-versionActions_182aj_181", "DrawerItem-migrationOptions": "_DrawerItem-migrationOptions_182aj_187", "DrawerItem-migrationList": "_DrawerItem-migrationList_182aj_191", "DrawerItem-migrationOption": "_DrawerItem-migrationOption_182aj_187", "DrawerItem-migrationOption--isSelected": "_DrawerItem-migrationOption--isSelected_182aj_229", "DrawerItem-migrationOptionLabel": "_DrawerItem-migrationOptionLabel_182aj_234", "DrawerItem-modalFooter": "_DrawerItem-modalFooter_182aj_240", "DrawerItem-footerLeft": "_DrawerItem-footerLeft_182aj_250", "DrawerItem-footerRight": "_DrawerItem-footerRight_182aj_255" };
3099
3202
 
3100
3203
  // src/puck/components/modal/index.tsx
3101
3204
  var import_react10 = require("react");
3102
3205
  var import_react_dom = require("react-dom");
3103
3206
 
3104
3207
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css#css-module
3105
- var styles_module_default2 = { "Modal": "_Modal_pvj02_1", "Modal--isOpen": "_Modal--isOpen_pvj02_29", "Modal-inner": "_Modal-inner_pvj02_37" };
3208
+ var styles_module_default2 = { "Modal": "_Modal_1t9ot_1", "Modal--isOpen": "_Modal--isOpen_1t9ot_29", "Modal-inner": "_Modal-inner_1t9ot_37" };
3106
3209
 
3107
3210
  // src/puck/components/modal/index.tsx
3108
3211
  var import_jsx_runtime10 = require("react/jsx-runtime");
@@ -3116,18 +3219,43 @@ var Modal = ({
3116
3219
  (0, import_react10.useEffect)(() => {
3117
3220
  setRootEl(document.getElementById("puck-portal-root"));
3118
3221
  }, []);
3222
+ (0, import_react10.useEffect)(() => {
3223
+ if (!isOpen) {
3224
+ return;
3225
+ }
3226
+ const handleEscape = (event) => {
3227
+ if (event.key === "Escape") {
3228
+ onClose();
3229
+ }
3230
+ };
3231
+ document.addEventListener("keydown", handleEscape);
3232
+ return () => document.removeEventListener("keydown", handleEscape);
3233
+ }, [isOpen, onClose]);
3119
3234
  if (!rootEl) {
3120
3235
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", {});
3121
3236
  }
3122
3237
  return (0, import_react_dom.createPortal)(
3123
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: getClassName4({ isOpen }), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3238
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3124
3239
  "div",
3125
3240
  {
3126
- className: getClassName4("inner"),
3127
- onClick: (e) => e.stopPropagation(),
3128
- children
3241
+ className: getClassName4({ isOpen }),
3242
+ onClick: (event) => {
3243
+ if (event.target === event.currentTarget) {
3244
+ onClose();
3245
+ }
3246
+ },
3247
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3248
+ "div",
3249
+ {
3250
+ className: getClassName4("inner"),
3251
+ role: "dialog",
3252
+ "aria-modal": "true",
3253
+ onClick: (e) => e.stopPropagation(),
3254
+ children
3255
+ }
3256
+ )
3129
3257
  }
3130
- ) }),
3258
+ ),
3131
3259
  rootEl
3132
3260
  );
3133
3261
  };
@@ -3150,13 +3278,14 @@ var DrawerItem = (props) => {
3150
3278
  );
3151
3279
  const { handleDemolish } = useDemolish();
3152
3280
  const { handleSetDefaultVersion, getVersions, getDefaultVersion } = useSetDefaultVersion();
3281
+ const { triggerAction } = useActionEvent();
3153
3282
  const [isEditing, setIsEditing] = (0, import_react11.useState)(false);
3154
3283
  const [isHovering, setIsHovering] = (0, import_react11.useState)(false);
3155
3284
  const [selectedVersion, setSelectedVersion] = (0, import_react11.useState)("");
3156
3285
  const [versionsToDelete, setVersionsToDelete] = (0, import_react11.useState)(
3157
3286
  /* @__PURE__ */ new Set()
3158
3287
  );
3159
- const [migrateVersionMap, setMigrateVersionMap] = (0, import_react11.useState)({});
3288
+ const [migrationTarget, setMigrationTarget] = (0, import_react11.useState)("decompose");
3160
3289
  const useVersioning = useSoftConfig((s) => s.showVersionFields);
3161
3290
  const versions = getVersions(props.name);
3162
3291
  const defaultVersion = getDefaultVersion(props.name);
@@ -3177,19 +3306,27 @@ var DrawerItem = (props) => {
3177
3306
  break;
3178
3307
  } else {
3179
3308
  removeSoftComponentVersion(props.name, version);
3309
+ void triggerAction({
3310
+ type: "deleteVersion",
3311
+ payload: {
3312
+ id: props.name,
3313
+ version,
3314
+ migrateToVersion: migrationTarget
3315
+ }
3316
+ });
3180
3317
  }
3181
3318
  }
3182
3319
  }
3183
3320
  setIsEditing(false);
3184
3321
  setSelectedVersion("");
3185
3322
  setVersionsToDelete(/* @__PURE__ */ new Set());
3186
- setMigrateVersionMap({});
3323
+ setMigrationTarget("decompose");
3187
3324
  });
3188
3325
  const handleCancel = () => {
3189
3326
  setIsEditing(false);
3190
3327
  setSelectedVersion("");
3191
3328
  setVersionsToDelete(/* @__PURE__ */ new Set());
3192
- setMigrateVersionMap({});
3329
+ setMigrationTarget("decompose");
3193
3330
  };
3194
3331
  const toggleVersionForDeletion = (version) => {
3195
3332
  const newSet = new Set(versionsToDelete);
@@ -3211,6 +3348,13 @@ var DrawerItem = (props) => {
3211
3348
  });
3212
3349
  if (softComponents.has(props.name)) {
3213
3350
  const availableVersions = versions.filter((v) => !versionsToDelete.has(v));
3351
+ const migrationTargets = [
3352
+ { value: "decompose", label: "Decompose to basic elements" },
3353
+ ...availableVersions.map((version) => ({
3354
+ value: version,
3355
+ label: `Migrate to Version ${version}`
3356
+ }))
3357
+ ];
3214
3358
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3215
3359
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3216
3360
  "div",
@@ -3281,30 +3425,35 @@ var DrawerItem = (props) => {
3281
3425
  ] }, version);
3282
3426
  }) })
3283
3427
  ] }),
3284
- versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: getClassName5("section"), children: [
3428
+ versionsToDelete.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: getClassName5("section"), children: [
3285
3429
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
3286
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3287
- "select",
3430
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3431
+ "div",
3288
3432
  {
3289
- title: "Select migration version",
3290
- className: getClassName5("select"),
3291
- value: migrateVersionMap[Array.from(versionsToDelete)[0]] || "decompose",
3292
- onChange: (e) => {
3293
- const newMap = __spreadValues({}, migrateVersionMap);
3294
- versionsToDelete.forEach((v) => {
3295
- newMap[v] = e.target.value;
3296
- });
3297
- setMigrateVersionMap(newMap);
3298
- },
3299
- children: [
3300
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "decompose", children: "Decompose to basic elements" }),
3301
- availableVersions.map((v) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("option", { value: v, children: [
3302
- "Migrate to Version ",
3303
- v
3304
- ] }, v))
3305
- ]
3433
+ className: getClassName5("migrationList"),
3434
+ role: "radiogroup",
3435
+ "aria-label": "Migration target",
3436
+ children: migrationTargets.map((target) => {
3437
+ const isSelected = migrationTarget === target.value;
3438
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3439
+ "button",
3440
+ {
3441
+ type: "button",
3442
+ role: "radio",
3443
+ "aria-checked": isSelected,
3444
+ className: `${getClassName5("migrationOption")} ${isSelected ? getClassName5("migrationOption--isSelected") : ""}`,
3445
+ onClick: () => setMigrationTarget(target.value),
3446
+ children: [
3447
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: getClassName5("migrationOptionLabel"), children: target.label }),
3448
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react2.Check, { size: 14 })
3449
+ ]
3450
+ },
3451
+ target.value
3452
+ );
3453
+ })
3306
3454
  }
3307
- ) })
3455
+ ) }),
3456
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: getClassName5("helpText"), children: "Choose where to move existing instances of the deleted versions." })
3308
3457
  ] })
3309
3458
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("section"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { children: [
3310
3459
  "Manage high-level settings for the ",
@@ -3414,11 +3563,6 @@ var Drawer = (_props) => {
3414
3563
  key
3415
3564
  )) });
3416
3565
  }
3417
- console.log(
3418
- getClassName6(),
3419
- getCategoryClassName(),
3420
- getCategoryClassName({ isExpanded: true })
3421
- );
3422
3566
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: getClassName6(), children: [
3423
3567
  categoryEntries.map(([id, cat]) => {
3424
3568
  var _a2, _b2, _c;