@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.
@@ -18,18 +18,6 @@ var __spreadValues = (a, b) => {
18
18
  return a;
19
19
  };
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
- var __objRest = (source, exclude) => {
22
- var target = {};
23
- for (var prop in source)
24
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
- target[prop] = source[prop];
26
- if (source != null && __getOwnPropSymbols)
27
- for (var prop of __getOwnPropSymbols(source)) {
28
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
- target[prop] = source[prop];
30
- }
31
- return target;
32
- };
33
21
  var __async = (__this, __arguments, generator) => {
34
22
  return new Promise((resolve, reject) => {
35
23
  var fulfilled = (value) => {
@@ -308,7 +296,7 @@ var updateVersion = (version, increment) => {
308
296
  return `${major}.${minor}.${patch}`;
309
297
  };
310
298
  var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true) => ({
311
- fields: {
299
+ fields: __spreadValues({
312
300
  _name: overrides.name || {
313
301
  type: "text",
314
302
  label: "Soft Component Name"
@@ -358,7 +346,7 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
358
346
  }
359
347
  }
360
348
  }
361
- },
349
+ }, overrides.additionalRootFields || {}),
362
350
  resolveFields({ props: data }, { fields, changed }) {
363
351
  var _a, _b;
364
352
  if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
@@ -372,7 +360,7 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
372
360
  )
373
361
  };
374
362
  else delete fields._fieldSettings;
375
- if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length) && (!(data == null ? void 0 : data._version) || changed._version || changed._fieldSettings)) {
363
+ if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length)) {
376
364
  const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
377
365
  delete fields._version;
378
366
  fields._version = {
@@ -400,14 +388,14 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
400
388
  return fields;
401
389
  },
402
390
  resolveData: (props, params) => {
403
- if (overrides.onRootsDataChange)
404
- overrides.onRootsDataChange(props, params);
405
- return {
391
+ if (overrides.resolveRootData) {
392
+ return overrides.resolveRootData(props, params, { editingComponent });
393
+ }
394
+ let result = {
406
395
  props,
407
- readOnly: Boolean(editingComponent) ? {
408
- _name: true
409
- } : void 0
396
+ readOnly: void 0
410
397
  };
398
+ return result;
411
399
  },
412
400
  render: (props) => {
413
401
  const fieldSettings = props == null ? void 0 : props._fieldSettings;
@@ -913,6 +901,21 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
913
901
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
914
902
  const fields = rootProps._fields || [];
915
903
  const field_settings = rootProps._fieldSettings || {};
904
+ const builtInRootProps = /* @__PURE__ */ new Set([
905
+ "_name",
906
+ "_category",
907
+ "_version",
908
+ "_versions",
909
+ "_fields",
910
+ "_fieldSettings"
911
+ ]);
912
+ const customRootProps = Object.keys(rootProps).filter((key) => key.startsWith("_") && !builtInRootProps.has(key)).reduce(
913
+ (acc, key) => {
914
+ acc[key] = rootProps[key];
915
+ return acc;
916
+ },
917
+ {}
918
+ );
916
919
  const slots = {};
917
920
  const components = getSubComponents(
918
921
  [editedItem],
@@ -937,6 +940,7 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
937
940
  }, {})),
938
941
  fieldSettings: field_settings,
939
942
  defaultProps,
943
+ rootProps: customRootProps,
940
944
  components,
941
945
  slots
942
946
  },
@@ -948,6 +952,24 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
948
952
  import { v4 as uuidv4 } from "uuid";
949
953
  var generateId = (type) => type ? `${type}-${uuidv4()}` : uuidv4();
950
954
 
955
+ // src/puck/lib/component-key.ts
956
+ var defaultToCamelCase = (value) => {
957
+ const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
958
+ if (tokens.length === 0) return "";
959
+ const [first, ...rest] = tokens;
960
+ return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
961
+ };
962
+ var createComponentKeyFromName = (displayName, overrides, context) => {
963
+ const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
964
+ return key.trim();
965
+ };
966
+ var getComponentNameFromKey = (key, overrides) => {
967
+ if (overrides.componentKeyToName) {
968
+ return overrides.componentKeyToName(key);
969
+ }
970
+ return key;
971
+ };
972
+
951
973
  // src/puck/lib/soft-component-to-appstate.ts
952
974
  var puckFieldsToSoftFields = (fields, slots) => {
953
975
  const softFields = [];
@@ -1066,7 +1088,7 @@ var reconstructComponents = (subComponents, componentConfigs, softComponentProps
1066
1088
  return componentData;
1067
1089
  });
1068
1090
  };
1069
- var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, displayName, category) => {
1091
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, overrides, displayName, category) => {
1070
1092
  const slots = new Set(Object.keys(softComponent.slots));
1071
1093
  const { fields, fieldSettings } = puckFieldsToSoftFields(
1072
1094
  softComponent.fields,
@@ -1077,14 +1099,17 @@ var softComponentToAppState = (softComponent, componentName, version, versions,
1077
1099
  fieldSettings[key].defaultValue = value;
1078
1100
  }
1079
1101
  });
1080
- const rootProps = {
1081
- _name: displayName || componentName,
1102
+ let rootProps = __spreadValues({
1103
+ _name: displayName || getComponentNameFromKey(componentName, overrides),
1082
1104
  _category: category,
1083
1105
  _version: version,
1084
1106
  _versions: versions,
1085
1107
  _fields: fields,
1086
1108
  _fieldSettings: fieldSettings
1087
- };
1109
+ }, softComponent.rootProps || {});
1110
+ if (overrides.onRemodel) {
1111
+ rootProps = __spreadValues(__spreadValues({}, rootProps), overrides.onRemodel(componentName));
1112
+ }
1088
1113
  const content = reconstructComponents(
1089
1114
  softComponent.components,
1090
1115
  componentConfigs,
@@ -1106,114 +1131,111 @@ var rootZone = "default-zone";
1106
1131
  var rootDroppableId = `${rootAreaId}:${rootZone}`;
1107
1132
 
1108
1133
  // src/puck/components/soft-render/index.tsx
1109
- import { useMemo, useRef } from "react";
1110
- import { v4 as uuidv42 } from "uuid";
1111
- import equal from "fast-deep-equal";
1134
+ import React2, { useMemo, memo } from "react";
1135
+ import equal from "react-fast-compare";
1112
1136
  import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
1113
- function SoftRender({
1114
- softComponentFields,
1115
- softComponentFieldSettings,
1116
- softSubComponent,
1117
- configComponents,
1118
- props,
1119
- depth = 0
1120
- }) {
1121
- const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1122
- const mapCacheRef = useRef(/* @__PURE__ */ new Map());
1123
- const prevPropsRef = useRef(null);
1124
- if (!equal(prevPropsRef.current, props)) {
1125
- mapCacheRef.current.clear();
1126
- prevPropsRef.current = props;
1127
- }
1128
- const subComponentRootProps = useMemo(
1129
- () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
1130
- (acc, [fieldKey]) => {
1131
- acc[fieldKey] = props[fieldKey];
1132
- return acc;
1133
- },
1134
- {}
1135
- ),
1136
- [softComponentFields, props]
1137
+ function isPlainObject(val) {
1138
+ if (typeof val !== "object" || val === null) return false;
1139
+ if (React2.isValidElement(val)) return false;
1140
+ if ("$$typeof" in val) return false;
1141
+ const proto = Object.getPrototypeOf(val);
1142
+ return proto === Object.prototype || proto === null;
1143
+ }
1144
+ function cloneData(value) {
1145
+ if (value === null || value === void 0) return value;
1146
+ if (typeof value === "function") return value;
1147
+ if (Array.isArray(value)) return value.map(cloneData);
1148
+ if (!isPlainObject(value)) return value;
1149
+ return Object.fromEntries(
1150
+ Object.entries(value).map(([k, v]) => [k, cloneData(v)])
1137
1151
  );
1138
- return /* @__PURE__ */ jsx5(Fragment2, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1139
- var _a2;
1152
+ }
1153
+ var SubComponentRenderer = memo(
1154
+ ({
1155
+ subComponent,
1156
+ softComponentFields,
1157
+ softComponentFieldSettings,
1158
+ configComponents,
1159
+ props,
1160
+ depth,
1161
+ index
1162
+ }) => {
1163
+ const { id, puck, editMode } = props;
1140
1164
  const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
1141
- if (!componentConfig) return null;
1142
- const resolvedProps = subComponent.fixedProps || {};
1143
1165
  const stableId = useMemo(
1144
- () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-${uuidv42()}`,
1145
- [id, depth, subComponent.type]
1166
+ () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-i${index}`,
1167
+ [id, depth, subComponent.type, index]
1146
1168
  );
1147
- if ((_a2 = subComponent.map) == null ? void 0 : _a2.length) {
1148
- subComponent.map.forEach((mapItem) => {
1149
- const { from, to, transform } = mapItem || {};
1150
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1151
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1152
- const inputValues = fromPaths.map((f) => {
1153
- const propValue = getFieldSettingsByPath(props || {}, f);
1154
- if (propValue !== void 0) return propValue;
1155
- const setting = getFieldSettingsByPath(
1156
- softComponentFieldSettings || {},
1157
- f
1158
- );
1159
- if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1160
- return setting.defaultValue;
1169
+ const finalProps = useMemo(() => {
1170
+ var _a;
1171
+ if (!componentConfig) return {};
1172
+ const clonedProps = cloneData(subComponent.fixedProps || {});
1173
+ if ((_a = subComponent.map) == null ? void 0 : _a.length) {
1174
+ subComponent.map.forEach((mapItem) => {
1175
+ const { from, to, transform } = mapItem || {};
1176
+ const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1177
+ const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1178
+ const inputValues = fromPaths.map((f) => {
1179
+ const propValue = getFieldSettingsByPath(props, f);
1180
+ if (propValue !== void 0) return propValue;
1181
+ const setting = getFieldSettingsByPath(softComponentFieldSettings || {}, f);
1182
+ if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1183
+ return setting.defaultValue;
1184
+ }
1185
+ return propValue;
1186
+ });
1187
+ const result = transform ? transform(inputValues, props) : inputValues[0];
1188
+ if (Array.isArray(result)) {
1189
+ result.forEach(
1190
+ (val, i) => toPaths[i] && setPropertyByPath(clonedProps, toPaths[i], val)
1191
+ );
1192
+ } else if (toPaths[0]) {
1193
+ setPropertyByPath(clonedProps, toPaths[0], result);
1161
1194
  }
1162
- return propValue;
1163
1195
  });
1164
- const cacheKey = inputValues.map((v, i) => `${i}:${typeof v === "object" ? JSON.stringify(v) : v}`).join("|");
1165
- let result = mapCacheRef.current.get(cacheKey);
1166
- if (!result) {
1167
- const runner = transform;
1168
- result = runner ? runner(inputValues, props) : inputValues[0];
1169
- mapCacheRef.current.set(cacheKey, result);
1170
- }
1171
- if (Array.isArray(result)) {
1172
- result.forEach(
1173
- (val, i) => toPaths[i] && setPropertyByPath(resolvedProps, toPaths[i], val)
1174
- );
1175
- } else if (toPaths[0]) {
1176
- setPropertyByPath(resolvedProps, toPaths[0], result);
1177
- }
1178
- });
1179
- }
1180
- Object.entries(componentConfig.fields || {}).forEach(
1181
- ([slotKey, field]) => {
1182
- var _a3, _b;
1183
- if (field.type === "slot") {
1184
- const enabledSlot = (_a3 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a3.find(
1196
+ }
1197
+ Object.entries(componentConfig.fields || {}).forEach(
1198
+ ([slotKey, field]) => {
1199
+ var _a2, _b, _c;
1200
+ if (field.type !== "slot") return;
1201
+ const enabledSlot = (_a2 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a2.find(
1185
1202
  (s) => s.slot === slotKey
1186
1203
  );
1187
1204
  if (enabledSlot) {
1188
1205
  const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1189
- resolvedProps[slotKey] = useMemo(
1190
- () => rest[slotName] || (() => null),
1191
- [slotName, rest[slotName]]
1192
- );
1206
+ clonedProps[slotKey] = (_c = props[slotName]) != null ? _c : (() => null);
1193
1207
  } else {
1194
- resolvedProps[slotKey] = useMemo(() => {
1195
- return ({
1196
- className,
1197
- style
1198
- }) => {
1199
- var _a4, _b2;
1200
- return /* @__PURE__ */ jsx5("div", { className, style, children: /* @__PURE__ */ jsx5(
1201
- SoftRender,
1202
- {
1203
- softComponentFields,
1204
- softSubComponent: (_b2 = (_a4 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a4[slotKey]) != null ? _b2 : [],
1205
- configComponents,
1206
- props,
1207
- depth: depth + 1
1208
- },
1209
- slotKey
1210
- ) });
1211
- };
1212
- }, [slotKey, subComponentRootProps]);
1208
+ clonedProps[slotKey] = ({
1209
+ className,
1210
+ style
1211
+ }) => {
1212
+ var _a3, _b2;
1213
+ return /* @__PURE__ */ jsx5("div", { className, style, children: /* @__PURE__ */ jsx5(
1214
+ SoftRender,
1215
+ {
1216
+ softComponentFields,
1217
+ softComponentFieldSettings,
1218
+ softSubComponent: (_b2 = (_a3 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a3[slotKey]) != null ? _b2 : [],
1219
+ configComponents,
1220
+ props,
1221
+ depth: depth + 1
1222
+ }
1223
+ ) });
1224
+ };
1213
1225
  }
1214
1226
  }
1215
- }
1216
- );
1227
+ );
1228
+ return clonedProps;
1229
+ }, [
1230
+ componentConfig,
1231
+ subComponent,
1232
+ props,
1233
+ softComponentFields,
1234
+ softComponentFieldSettings,
1235
+ configComponents,
1236
+ depth
1237
+ ]);
1238
+ if (!componentConfig) return null;
1217
1239
  const ComponentRender = componentConfig.render;
1218
1240
  return /* @__PURE__ */ jsx5(ErrorBoundary, { children: /* @__PURE__ */ jsx5(
1219
1241
  ComponentRender,
@@ -1221,10 +1243,53 @@ function SoftRender({
1221
1243
  id: stableId,
1222
1244
  editMode,
1223
1245
  puck
1224
- }, resolvedProps)
1225
- ) }, index);
1226
- }) });
1227
- }
1246
+ }, finalProps)
1247
+ ) });
1248
+ },
1249
+ // Custom comparator for SubComponentRenderer.
1250
+ //
1251
+ // Uses deep equality on subComponent (it may be a new reference even when
1252
+ // semantically unchanged if the parent SoftRender array is reconstructed)
1253
+ // and on props (the primary driver of field-mapping changes).
1254
+ // configComponents and softComponentFields are treated as stable config
1255
+ // references — reference equality is intentional and fast here.
1256
+ (prev, next) => prev.depth === next.depth && prev.index === next.index && prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal(prev.props, next.props) && equal(prev.subComponent, next.subComponent) && equal(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1257
+ );
1258
+ SubComponentRenderer.displayName = "SubComponentRenderer";
1259
+ var SoftRender = memo(
1260
+ ({
1261
+ softComponentFields,
1262
+ softComponentFieldSettings,
1263
+ softSubComponent,
1264
+ configComponents,
1265
+ props,
1266
+ depth = 0
1267
+ }) => {
1268
+ if (!(softSubComponent == null ? void 0 : softSubComponent.length)) return null;
1269
+ return /* @__PURE__ */ jsx5(Fragment2, { children: softSubComponent.map((subComponent, index) => {
1270
+ var _a;
1271
+ return /* @__PURE__ */ jsx5(
1272
+ SubComponentRenderer,
1273
+ {
1274
+ subComponent,
1275
+ softComponentFields,
1276
+ softComponentFieldSettings: softComponentFieldSettings || {},
1277
+ configComponents,
1278
+ props,
1279
+ depth,
1280
+ index
1281
+ },
1282
+ `${(_a = subComponent == null ? void 0 : subComponent.type) != null ? _a : "comp"}-${index}-${depth}`
1283
+ );
1284
+ }) });
1285
+ },
1286
+ // Covers all five props — not just `props` and `softSubComponent`.
1287
+ // configComponents / softComponentFields: reference equality (stable config).
1288
+ // softComponentFieldSettings: deep equality (may carry dynamic defaults).
1289
+ // props / softSubComponent: deep equality (primary render drivers).
1290
+ (prev, next) => prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal(prev.props, next.props) && equal(prev.softSubComponent, next.softSubComponent) && equal(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1291
+ );
1292
+ SoftRender.displayName = "SoftRender";
1228
1293
 
1229
1294
  // src/puck/lib/create-versioned-component-config.tsx
1230
1295
  import { jsx as jsx6 } from "react/jsx-runtime";
@@ -1378,18 +1443,6 @@ function demolishSoftComponent(componentName, data, config, softComponents) {
1378
1443
  };
1379
1444
  }
1380
1445
 
1381
- // src/puck/lib/component-key.ts
1382
- var defaultToCamelCase = (value) => {
1383
- const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1384
- if (tokens.length === 0) return "";
1385
- const [first, ...rest] = tokens;
1386
- return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1387
- };
1388
- var createComponentKeyFromName = (displayName, overrides, context) => {
1389
- const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1390
- return key.trim();
1391
- };
1392
-
1393
1446
  // src/puck/store/slices/builder.tsx
1394
1447
  var createBuildersSlice = (set, get, initialConfig) => ({
1395
1448
  build: (history, selectedItem, itemSelector, puckDispatch, name) => {
@@ -1489,6 +1542,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1489
1542
  versions,
1490
1543
  selectedItem.props,
1491
1544
  get().softConfig.components,
1545
+ get().overrides,
1492
1546
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || softComponentName,
1493
1547
  softComponentMeta == null ? void 0 : softComponentMeta.category
1494
1548
  );
@@ -1541,6 +1595,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1541
1595
  zone: itemSelector.zone || rootDroppableId
1542
1596
  },
1543
1597
  editingComponentId: selectedItem.props.id,
1598
+ editingComponent: softComponentName,
1544
1599
  editableComponentIds: editableIds,
1545
1600
  state: "remodeling"
1546
1601
  }));
@@ -1557,7 +1612,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1557
1612
  );
1558
1613
  },
1559
1614
  complete: (appState, setHistories, getItemBySelector) => {
1560
- var _a, _b, _c, _d, _e;
1615
+ var _a, _b, _c, _d, _e, _f, _g;
1561
1616
  if (get().state === "ready") {
1562
1617
  throw new Error("Not building or remodeling a component.");
1563
1618
  }
@@ -1576,10 +1631,11 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1576
1631
  throw new Error("Cannot find item being edited");
1577
1632
  }
1578
1633
  const rootCategory = (_e = (_d = appState.data.root) == null ? void 0 : _d.props) == null ? void 0 : _e._category;
1579
- const componentName = createComponentKeyFromName(displayName, get().overrides, {
1634
+ const rootProps = (_f = appState.data.root) == null ? void 0 : _f.props;
1635
+ const componentName = createComponentKeyFromName(displayName, get().overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
1580
1636
  existingKeys: Object.keys(get().softComponents),
1581
1637
  state: get().state
1582
- });
1638
+ }));
1583
1639
  if (!componentName) {
1584
1640
  throw new Error("Failed to generate component key from name.");
1585
1641
  }
@@ -1638,12 +1694,26 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1638
1694
  storedConfig: void 0,
1639
1695
  state: "inspecting",
1640
1696
  originalHistory: [],
1697
+ editingComponent: null,
1641
1698
  editingComponentId: null,
1642
1699
  editableComponentIds: /* @__PURE__ */ new Set()
1643
1700
  });
1644
1701
  });
1702
+ if (!version) {
1703
+ throw new Error("Failed to resolve completed component version.");
1704
+ }
1705
+ const completedSoftComponent = (_g = get().softComponents[componentName]) == null ? void 0 : _g.versions[version];
1706
+ if (!completedSoftComponent) {
1707
+ throw new Error(
1708
+ `Completed soft component "${componentName}" version "${version}" not found.`
1709
+ );
1710
+ }
1645
1711
  get().rebuildDependents(componentName, version);
1646
- return componentName;
1712
+ return {
1713
+ id: componentName,
1714
+ version,
1715
+ softComponent: completedSoftComponent
1716
+ };
1647
1717
  },
1648
1718
  inspect: (componentName, puckDispatch) => {
1649
1719
  if (get().state !== "inspecting") {
@@ -1684,6 +1754,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1684
1754
  itemSelector: null,
1685
1755
  originalItem: null,
1686
1756
  state: "ready",
1757
+ editingComponent: null,
1687
1758
  editingComponentId: null,
1688
1759
  editableComponentIds: /* @__PURE__ */ new Set()
1689
1760
  }));
@@ -1776,6 +1847,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1776
1847
  versions,
1777
1848
  currentProps,
1778
1849
  get().softConfig.components,
1850
+ get().overrides,
1779
1851
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1780
1852
  softComponentMeta == null ? void 0 : softComponentMeta.category
1781
1853
  );
@@ -2080,6 +2152,7 @@ var createSoftConfigStore = (hardConfig = {
2080
2152
  onActions,
2081
2153
  iframeDocRef,
2082
2154
  showVersionFields,
2155
+ editingComponent: null,
2083
2156
  setShowVersionFields: (show) => set({ showVersionFields: show }),
2084
2157
  getIframeDoc: () => iframeDocRef.current,
2085
2158
  setIframeDoc: (doc) => {
@@ -2373,7 +2446,7 @@ var createSoftConfigStore = (hardConfig = {
2373
2446
  };
2374
2447
 
2375
2448
  // src/puck/context/storeProvider.tsx
2376
- import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
2449
+ import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
2377
2450
  import { jsx as jsx7 } from "react/jsx-runtime";
2378
2451
  var SoftConfigProvider = ({
2379
2452
  children,
@@ -2388,10 +2461,10 @@ var SoftConfigProvider = ({
2388
2461
  () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2389
2462
  [hardConfig, softComponents, overrides, onActions, useVersioning]
2390
2463
  );
2391
- const [softConfig, setSoftConfig] = useState2(
2464
+ const [softConfig, setSoftConfig] = useState(
2392
2465
  () => store.getState().softConfig
2393
2466
  );
2394
- const [internalSoftComponents, setSoftComponents] = useState2(
2467
+ const [internalSoftComponents, setSoftComponents] = useState(
2395
2468
  () => store.getState().softComponents
2396
2469
  );
2397
2470
  const storeSetIframeDoc = useMemo2(
@@ -2400,14 +2473,19 @@ var SoftConfigProvider = ({
2400
2473
  );
2401
2474
  const validateAction = useMemo2(
2402
2475
  () => (action) => {
2476
+ var _a;
2403
2477
  const currentState = store.getState();
2404
2478
  if (currentState.state === "ready") {
2405
2479
  return true;
2406
2480
  }
2407
2481
  const editableIds = currentState.editableComponentIds;
2408
2482
  if (action.type === "replace") {
2483
+ const parentId = (_a = action.destinationZone) == null ? void 0 : _a.split(":")[0];
2409
2484
  if (action.data.props.id && editableIds.has(action.data.props.id)) {
2410
2485
  return true;
2486
+ } else if (parentId && editableIds.has(parentId)) {
2487
+ currentState.addEditableComponentId(action.data.props.id);
2488
+ return true;
2411
2489
  }
2412
2490
  return false;
2413
2491
  }
@@ -2573,28 +2651,42 @@ var useRemodel = () => {
2573
2651
  const refreshPermissions = useCustomPuck3((s) => s.refreshPermissions);
2574
2652
  const { triggerAction } = useActionEvent();
2575
2653
  const handleRemodel = (componentName) => {
2654
+ var _a, _b, _c;
2576
2655
  if (status !== "ready") {
2577
2656
  notify.error("Can only remodel when in ready state.");
2578
- return;
2657
+ return null;
2579
2658
  }
2580
2659
  const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
2581
2660
  if (!name || !Object.keys(softComponents).includes(name)) {
2582
2661
  notify.error("Selected component is not a soft component.");
2583
- return;
2662
+ return null;
2584
2663
  }
2664
+ const selectedVersion = ((_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.version) || ((_b = softComponents[name]) == null ? void 0 : _b.defaultVersion);
2665
+ const selectedSoftComponent = selectedVersion ? (_c = softComponents[name]) == null ? void 0 : _c.versions[selectedVersion] : void 0;
2585
2666
  try {
2586
2667
  remodel(history, selectedItem, itemSelector, dispatch, refreshPermissions);
2587
2668
  void triggerAction({
2588
2669
  type: "remodel",
2589
2670
  payload: {
2590
- id: name
2671
+ id: name,
2672
+ version: selectedVersion,
2673
+ softComponent: selectedSoftComponent
2591
2674
  }
2592
2675
  });
2676
+ if (selectedVersion && selectedSoftComponent) {
2677
+ return {
2678
+ id: name,
2679
+ version: selectedVersion,
2680
+ softComponent: selectedSoftComponent
2681
+ };
2682
+ }
2683
+ return { id: name, version: selectedVersion };
2593
2684
  } catch (error) {
2594
2685
  console.error("Failed to remodel:", error);
2595
2686
  notify.error(
2596
2687
  "Failed to remodel: " + (error instanceof Error ? error.message : String(error))
2597
2688
  );
2689
+ return null;
2598
2690
  }
2599
2691
  };
2600
2692
  const canRemodel = (componentName) => {
@@ -2606,7 +2698,7 @@ var useRemodel = () => {
2606
2698
 
2607
2699
  // src/puck/actions/useComplete.tsx
2608
2700
  import { createUsePuck as createUsePuck4 } from "@measured/puck";
2609
- import { useState as useState3, useCallback as useCallback2 } from "react";
2701
+ import { useState as useState2, useCallback as useCallback2 } from "react";
2610
2702
  var useCustomPuck4 = createUsePuck4();
2611
2703
  var useComplete = () => {
2612
2704
  const complete = useSoftConfig((s) => s.builder.complete);
@@ -2614,31 +2706,29 @@ var useComplete = () => {
2614
2706
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2615
2707
  const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2616
2708
  const status = useSoftConfig((s) => s.state);
2617
- const softComponents = useSoftConfig((s) => s.softComponents);
2618
- const [newComponent, setNewComponent] = useState3(null);
2709
+ const [newComponent, setNewComponent] = useState2(null);
2619
2710
  const { triggerAction } = useActionEvent();
2620
2711
  const handleComplete = useCallback2(() => {
2621
- var _a, _b;
2622
2712
  if (status === "ready") {
2623
2713
  notify.error("Not building or remodeling a component.");
2624
2714
  return null;
2625
2715
  }
2626
2716
  try {
2627
- const componentName = complete(appState, setHistories, getItemBySelector);
2628
- setNewComponent(componentName);
2717
+ const completedComponent = complete(appState, setHistories, getItemBySelector);
2718
+ setNewComponent(completedComponent);
2629
2719
  const componentData = appState.data.root;
2630
- const softComponent = (_b = softComponents[componentName]) == null ? void 0 : _b.versions[(_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion];
2631
- if (softComponent && componentData) {
2720
+ if (componentData) {
2632
2721
  void triggerAction({
2633
2722
  type: "complete",
2634
2723
  payload: {
2635
- id: componentName,
2724
+ id: completedComponent.id,
2725
+ version: completedComponent.version,
2636
2726
  componentData,
2637
- softComponent
2727
+ softComponent: completedComponent.softComponent
2638
2728
  }
2639
2729
  });
2640
2730
  }
2641
- return componentName;
2731
+ return completedComponent;
2642
2732
  } catch (error) {
2643
2733
  console.error("Failed to complete:", error);
2644
2734
  notify.error(
@@ -2646,7 +2736,7 @@ var useComplete = () => {
2646
2736
  );
2647
2737
  return null;
2648
2738
  }
2649
- }, [complete, appState, setHistories, status, softComponents, triggerAction, getItemBySelector]);
2739
+ }, [complete, appState, setHistories, status, triggerAction, getItemBySelector]);
2650
2740
  const canComplete = status === "building" || status === "remodeling";
2651
2741
  return { handleComplete, canComplete, newComponent, setNewComponent };
2652
2742
  };
@@ -2685,23 +2775,25 @@ var useCancel = () => {
2685
2775
  import { createUsePuck as createUsePuck6 } from "@measured/puck";
2686
2776
  import { useEffect as useEffect3 } from "react";
2687
2777
  var useCustomPuck6 = createUsePuck6();
2688
- var useInspect = (componentName) => {
2778
+ var useInspect = (component) => {
2689
2779
  const inspect = useSoftConfig((s) => s.builder.inspect);
2690
2780
  const dispatch = useCustomPuck6((s) => s.dispatch);
2691
2781
  const status = useSoftConfig((s) => s.state);
2692
2782
  const { triggerAction } = useActionEvent();
2693
2783
  useEffect3(() => {
2694
2784
  if (status !== "inspecting") return;
2695
- if (!componentName) {
2785
+ if (!component) {
2696
2786
  notify.error("No component to inspect.");
2697
2787
  return;
2698
2788
  }
2699
2789
  try {
2700
- inspect(componentName, dispatch);
2790
+ inspect(component.id, dispatch);
2701
2791
  void triggerAction({
2702
2792
  type: "inspect",
2703
2793
  payload: {
2704
- id: componentName
2794
+ id: component.id,
2795
+ version: component.version,
2796
+ softComponent: component.softComponent
2705
2797
  }
2706
2798
  });
2707
2799
  } catch (error) {
@@ -2710,7 +2802,7 @@ var useInspect = (componentName) => {
2710
2802
  "Failed to inspect: " + (error instanceof Error ? error.message : String(error))
2711
2803
  );
2712
2804
  }
2713
- }, [status, componentName, inspect, dispatch, triggerAction]);
2805
+ }, [status, component, inspect, dispatch, triggerAction]);
2714
2806
  };
2715
2807
 
2716
2808
  // src/puck/actions/useDecompose.tsx
@@ -2926,9 +3018,9 @@ var Header = ({
2926
3018
  {
2927
3019
  variant: "primary",
2928
3020
  onClick: () => {
2929
- const name = handleComplete();
2930
- if (name) {
2931
- setNewComponent(name);
3021
+ const completedComponent = handleComplete();
3022
+ if (completedComponent) {
3023
+ setNewComponent(completedComponent);
2932
3024
  }
2933
3025
  },
2934
3026
  children: "Complete"
@@ -2962,7 +3054,7 @@ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-run
2962
3054
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
2963
3055
  var usePuck2 = createUsePuck11();
2964
3056
  var ActionBarOverride = (props) => {
2965
- var _a;
3057
+ var _a, _b;
2966
3058
  const { handleBuild } = useBuild("Custom Name");
2967
3059
  const { handleRemodel } = useRemodel();
2968
3060
  const { handleDecompose } = useDecompose();
@@ -2970,20 +3062,31 @@ var ActionBarOverride = (props) => {
2970
3062
  const softComponents = useSoftConfig((s) => s.softComponents, shallow);
2971
3063
  const editableIds = useSoftConfig((s) => s.editableComponentIds);
2972
3064
  const selectedItem = usePuck2((s) => s.selectedItem);
3065
+ const rootProps = usePuck2((s) => s.appState.data.root.props);
2973
3066
  const status = useSoftConfig((s) => s.state);
3067
+ const itemSelector = usePuck2((s) => s.appState.ui.itemSelector);
2974
3068
  const softKeys = Object.keys(softComponents);
2975
- const key = useMemo3(() => createComponentKeyFromName(props.label || "", overrides, {
2976
- existingKeys: softKeys,
2977
- state: status
2978
- }), [
3069
+ const key = useMemo3(() => {
3070
+ const selectedType = selectedItem == null ? void 0 : selectedItem.type;
3071
+ if (selectedType && softKeys.includes(selectedType)) {
3072
+ return selectedType;
3073
+ }
3074
+ return createComponentKeyFromName(props.label || "", overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
3075
+ existingKeys: softKeys,
3076
+ state: status
3077
+ }));
3078
+ }, [
2979
3079
  props.label,
2980
3080
  overrides,
3081
+ selectedItem == null ? void 0 : selectedItem.type,
2981
3082
  softKeys,
2982
- status
3083
+ status,
3084
+ rootProps
2983
3085
  ]);
2984
3086
  const isSoftComponent2 = softKeys.includes(key);
2985
3087
  const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
2986
- const isEditable = Boolean(selectedId && editableIds.has(selectedId));
3088
+ const parentId = (_b = itemSelector == null ? void 0 : itemSelector.zone) == null ? void 0 : _b.split(":")[0];
3089
+ const isEditable = Boolean(selectedId && (editableIds.has(selectedId) || parentId && editableIds.has(parentId)));
2987
3090
  return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
2988
3091
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
2989
3092
  props.parentAction,
@@ -3021,7 +3124,7 @@ var ActionBarOverride = (props) => {
3021
3124
  };
3022
3125
 
3023
3126
  // src/puck/overrides/DrawerItem.tsx
3024
- import { useState as useState5 } from "react";
3127
+ import { useState as useState4 } from "react";
3025
3128
  import { Button as Button2, IconButton, createUsePuck as createUsePuck12 } from "@measured/puck";
3026
3129
  import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
3027
3130
 
@@ -3043,14 +3146,14 @@ var confirm = (message) => __async(null, null, function* () {
3043
3146
  });
3044
3147
 
3045
3148
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/DrawerItem.module.css#css-module
3046
- 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" };
3149
+ 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" };
3047
3150
 
3048
3151
  // src/puck/components/modal/index.tsx
3049
- import { useEffect as useEffect4, useState as useState4 } from "react";
3152
+ import { useEffect as useEffect4, useState as useState3 } from "react";
3050
3153
  import { createPortal } from "react-dom";
3051
3154
 
3052
3155
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css#css-module
3053
- var styles_module_default2 = { "Modal": "_Modal_pvj02_1", "Modal--isOpen": "_Modal--isOpen_pvj02_29", "Modal-inner": "_Modal-inner_pvj02_37" };
3156
+ var styles_module_default2 = { "Modal": "_Modal_1t9ot_1", "Modal--isOpen": "_Modal--isOpen_1t9ot_29", "Modal-inner": "_Modal-inner_1t9ot_37" };
3054
3157
 
3055
3158
  // src/puck/components/modal/index.tsx
3056
3159
  import { jsx as jsx10 } from "react/jsx-runtime";
@@ -3060,22 +3163,47 @@ var Modal = ({
3060
3163
  onClose,
3061
3164
  isOpen
3062
3165
  }) => {
3063
- const [rootEl, setRootEl] = useState4(null);
3166
+ const [rootEl, setRootEl] = useState3(null);
3064
3167
  useEffect4(() => {
3065
3168
  setRootEl(document.getElementById("puck-portal-root"));
3066
3169
  }, []);
3170
+ useEffect4(() => {
3171
+ if (!isOpen) {
3172
+ return;
3173
+ }
3174
+ const handleEscape = (event) => {
3175
+ if (event.key === "Escape") {
3176
+ onClose();
3177
+ }
3178
+ };
3179
+ document.addEventListener("keydown", handleEscape);
3180
+ return () => document.removeEventListener("keydown", handleEscape);
3181
+ }, [isOpen, onClose]);
3067
3182
  if (!rootEl) {
3068
3183
  return /* @__PURE__ */ jsx10("div", {});
3069
3184
  }
3070
3185
  return createPortal(
3071
- /* @__PURE__ */ jsx10("div", { className: getClassName4({ isOpen }), onClick: onClose, children: /* @__PURE__ */ jsx10(
3186
+ /* @__PURE__ */ jsx10(
3072
3187
  "div",
3073
3188
  {
3074
- className: getClassName4("inner"),
3075
- onClick: (e) => e.stopPropagation(),
3076
- children
3189
+ className: getClassName4({ isOpen }),
3190
+ onClick: (event) => {
3191
+ if (event.target === event.currentTarget) {
3192
+ onClose();
3193
+ }
3194
+ },
3195
+ children: /* @__PURE__ */ jsx10(
3196
+ "div",
3197
+ {
3198
+ className: getClassName4("inner"),
3199
+ role: "dialog",
3200
+ "aria-modal": "true",
3201
+ onClick: (e) => e.stopPropagation(),
3202
+ children
3203
+ }
3204
+ )
3077
3205
  }
3078
- ) }),
3206
+ ),
3079
3207
  rootEl
3080
3208
  );
3081
3209
  };
@@ -3098,13 +3226,14 @@ var DrawerItem = (props) => {
3098
3226
  );
3099
3227
  const { handleDemolish } = useDemolish();
3100
3228
  const { handleSetDefaultVersion, getVersions, getDefaultVersion } = useSetDefaultVersion();
3101
- const [isEditing, setIsEditing] = useState5(false);
3102
- const [isHovering, setIsHovering] = useState5(false);
3103
- const [selectedVersion, setSelectedVersion] = useState5("");
3104
- const [versionsToDelete, setVersionsToDelete] = useState5(
3229
+ const { triggerAction } = useActionEvent();
3230
+ const [isEditing, setIsEditing] = useState4(false);
3231
+ const [isHovering, setIsHovering] = useState4(false);
3232
+ const [selectedVersion, setSelectedVersion] = useState4("");
3233
+ const [versionsToDelete, setVersionsToDelete] = useState4(
3105
3234
  /* @__PURE__ */ new Set()
3106
3235
  );
3107
- const [migrateVersionMap, setMigrateVersionMap] = useState5({});
3236
+ const [migrationTarget, setMigrationTarget] = useState4("decompose");
3108
3237
  const useVersioning = useSoftConfig((s) => s.showVersionFields);
3109
3238
  const versions = getVersions(props.name);
3110
3239
  const defaultVersion = getDefaultVersion(props.name);
@@ -3125,19 +3254,27 @@ var DrawerItem = (props) => {
3125
3254
  break;
3126
3255
  } else {
3127
3256
  removeSoftComponentVersion(props.name, version);
3257
+ void triggerAction({
3258
+ type: "deleteVersion",
3259
+ payload: {
3260
+ id: props.name,
3261
+ version,
3262
+ migrateToVersion: migrationTarget
3263
+ }
3264
+ });
3128
3265
  }
3129
3266
  }
3130
3267
  }
3131
3268
  setIsEditing(false);
3132
3269
  setSelectedVersion("");
3133
3270
  setVersionsToDelete(/* @__PURE__ */ new Set());
3134
- setMigrateVersionMap({});
3271
+ setMigrationTarget("decompose");
3135
3272
  });
3136
3273
  const handleCancel = () => {
3137
3274
  setIsEditing(false);
3138
3275
  setSelectedVersion("");
3139
3276
  setVersionsToDelete(/* @__PURE__ */ new Set());
3140
- setMigrateVersionMap({});
3277
+ setMigrationTarget("decompose");
3141
3278
  };
3142
3279
  const toggleVersionForDeletion = (version) => {
3143
3280
  const newSet = new Set(versionsToDelete);
@@ -3159,6 +3296,13 @@ var DrawerItem = (props) => {
3159
3296
  });
3160
3297
  if (softComponents.has(props.name)) {
3161
3298
  const availableVersions = versions.filter((v) => !versionsToDelete.has(v));
3299
+ const migrationTargets = [
3300
+ { value: "decompose", label: "Decompose to basic elements" },
3301
+ ...availableVersions.map((version) => ({
3302
+ value: version,
3303
+ label: `Migrate to Version ${version}`
3304
+ }))
3305
+ ];
3162
3306
  return /* @__PURE__ */ jsxs4(Fragment5, { children: [
3163
3307
  /* @__PURE__ */ jsxs4(
3164
3308
  "div",
@@ -3229,30 +3373,35 @@ var DrawerItem = (props) => {
3229
3373
  ] }, version);
3230
3374
  }) })
3231
3375
  ] }),
3232
- versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
3376
+ versionsToDelete.size > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
3233
3377
  /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
3234
- /* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsxs4(
3235
- "select",
3378
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsx11(
3379
+ "div",
3236
3380
  {
3237
- title: "Select migration version",
3238
- className: getClassName5("select"),
3239
- value: migrateVersionMap[Array.from(versionsToDelete)[0]] || "decompose",
3240
- onChange: (e) => {
3241
- const newMap = __spreadValues({}, migrateVersionMap);
3242
- versionsToDelete.forEach((v) => {
3243
- newMap[v] = e.target.value;
3244
- });
3245
- setMigrateVersionMap(newMap);
3246
- },
3247
- children: [
3248
- /* @__PURE__ */ jsx11("option", { value: "decompose", children: "Decompose to basic elements" }),
3249
- availableVersions.map((v) => /* @__PURE__ */ jsxs4("option", { value: v, children: [
3250
- "Migrate to Version ",
3251
- v
3252
- ] }, v))
3253
- ]
3381
+ className: getClassName5("migrationList"),
3382
+ role: "radiogroup",
3383
+ "aria-label": "Migration target",
3384
+ children: migrationTargets.map((target) => {
3385
+ const isSelected = migrationTarget === target.value;
3386
+ return /* @__PURE__ */ jsxs4(
3387
+ "button",
3388
+ {
3389
+ type: "button",
3390
+ role: "radio",
3391
+ "aria-checked": isSelected,
3392
+ className: `${getClassName5("migrationOption")} ${isSelected ? getClassName5("migrationOption--isSelected") : ""}`,
3393
+ onClick: () => setMigrationTarget(target.value),
3394
+ children: [
3395
+ /* @__PURE__ */ jsx11("span", { className: getClassName5("migrationOptionLabel"), children: target.label }),
3396
+ isSelected && /* @__PURE__ */ jsx11(Check, { size: 14 })
3397
+ ]
3398
+ },
3399
+ target.value
3400
+ );
3401
+ })
3254
3402
  }
3255
- ) })
3403
+ ) }),
3404
+ /* @__PURE__ */ jsx11("p", { className: getClassName5("helpText"), children: "Choose where to move existing instances of the deleted versions." })
3256
3405
  ] })
3257
3406
  ] }) : /* @__PURE__ */ jsx11("div", { className: getClassName5("section"), children: /* @__PURE__ */ jsxs4("p", { children: [
3258
3407
  "Manage high-level settings for the ",
@@ -3283,7 +3432,7 @@ var DrawerItem = (props) => {
3283
3432
  var ComponentItem = DrawerItem;
3284
3433
 
3285
3434
  // src/puck/overrides/Drawer.tsx
3286
- import { useState as useState6 } from "react";
3435
+ import { useState as useState5 } from "react";
3287
3436
  import { createUsePuck as createUsePuck13, Drawer as PuckDrawer } from "@measured/puck";
3288
3437
  import { ChevronDown, ChevronUp } from "lucide-react";
3289
3438
 
@@ -3342,7 +3491,7 @@ var Drawer = (_props) => {
3342
3491
  const categoryEntries = Object.entries(categories).filter(
3343
3492
  ([, cat]) => cat.visible !== false
3344
3493
  );
3345
- const [expanded, setExpanded] = useState6(() => {
3494
+ const [expanded, setExpanded] = useState5(() => {
3346
3495
  const init = {};
3347
3496
  categoryEntries.forEach(([id, cat]) => {
3348
3497
  init[id] = cat.defaultExpanded !== false;
@@ -3362,11 +3511,6 @@ var Drawer = (_props) => {
3362
3511
  key
3363
3512
  )) });
3364
3513
  }
3365
- console.log(
3366
- getClassName6(),
3367
- getCategoryClassName(),
3368
- getCategoryClassName({ isExpanded: true })
3369
- );
3370
3514
  return /* @__PURE__ */ jsxs5("div", { className: getClassName6(), children: [
3371
3515
  categoryEntries.map(([id, cat]) => {
3372
3516
  var _a2, _b2, _c;