@netlisian/softconfig 0.1.3 → 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)
@@ -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, _f;
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,6 +1746,7 @@ 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
  });
@@ -1697,7 +1754,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1697
1754
  if (!version) {
1698
1755
  throw new Error("Failed to resolve completed component version.");
1699
1756
  }
1700
- const completedSoftComponent = (_f = get().softComponents[componentName]) == null ? void 0 : _f.versions[version];
1757
+ const completedSoftComponent = (_g = get().softComponents[componentName]) == null ? void 0 : _g.versions[version];
1701
1758
  if (!completedSoftComponent) {
1702
1759
  throw new Error(
1703
1760
  `Completed soft component "${componentName}" version "${version}" not found.`
@@ -1749,6 +1806,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1749
1806
  itemSelector: null,
1750
1807
  originalItem: null,
1751
1808
  state: "ready",
1809
+ editingComponent: null,
1752
1810
  editingComponentId: null,
1753
1811
  editableComponentIds: /* @__PURE__ */ new Set()
1754
1812
  }));
@@ -1841,6 +1899,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1841
1899
  versions,
1842
1900
  currentProps,
1843
1901
  get().softConfig.components,
1902
+ get().overrides,
1844
1903
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1845
1904
  softComponentMeta == null ? void 0 : softComponentMeta.category
1846
1905
  );
@@ -2145,6 +2204,7 @@ var createSoftConfigStore = (hardConfig = {
2145
2204
  onActions,
2146
2205
  iframeDocRef,
2147
2206
  showVersionFields,
2207
+ editingComponent: null,
2148
2208
  setShowVersionFields: (show) => set({ showVersionFields: show }),
2149
2209
  getIframeDoc: () => iframeDocRef.current,
2150
2210
  setIframeDoc: (doc) => {
@@ -2465,14 +2525,19 @@ var SoftConfigProvider = ({
2465
2525
  );
2466
2526
  const validateAction = (0, import_react5.useMemo)(
2467
2527
  () => (action) => {
2528
+ var _a;
2468
2529
  const currentState = store.getState();
2469
2530
  if (currentState.state === "ready") {
2470
2531
  return true;
2471
2532
  }
2472
2533
  const editableIds = currentState.editableComponentIds;
2473
2534
  if (action.type === "replace") {
2535
+ const parentId = (_a = action.destinationZone) == null ? void 0 : _a.split(":")[0];
2474
2536
  if (action.data.props.id && editableIds.has(action.data.props.id)) {
2475
2537
  return true;
2538
+ } else if (parentId && editableIds.has(parentId)) {
2539
+ currentState.addEditableComponentId(action.data.props.id);
2540
+ return true;
2476
2541
  }
2477
2542
  return false;
2478
2543
  }
@@ -3041,7 +3106,7 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
3041
3106
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
3042
3107
  var usePuck2 = (0, import_puck14.createUsePuck)();
3043
3108
  var ActionBarOverride = (props) => {
3044
- var _a;
3109
+ var _a, _b;
3045
3110
  const { handleBuild } = useBuild("Custom Name");
3046
3111
  const { handleRemodel } = useRemodel();
3047
3112
  const { handleDecompose } = useDecompose();
@@ -3049,20 +3114,31 @@ var ActionBarOverride = (props) => {
3049
3114
  const softComponents = useSoftConfig((s) => s.softComponents, import_shallow.shallow);
3050
3115
  const editableIds = useSoftConfig((s) => s.editableComponentIds);
3051
3116
  const selectedItem = usePuck2((s) => s.selectedItem);
3117
+ const rootProps = usePuck2((s) => s.appState.data.root.props);
3052
3118
  const status = useSoftConfig((s) => s.state);
3119
+ const itemSelector = usePuck2((s) => s.appState.ui.itemSelector);
3053
3120
  const softKeys = Object.keys(softComponents);
3054
- const key = (0, import_react9.useMemo)(() => createComponentKeyFromName(props.label || "", overrides, {
3055
- existingKeys: softKeys,
3056
- state: status
3057
- }), [
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
+ }, [
3058
3131
  props.label,
3059
3132
  overrides,
3133
+ selectedItem == null ? void 0 : selectedItem.type,
3060
3134
  softKeys,
3061
- status
3135
+ status,
3136
+ rootProps
3062
3137
  ]);
3063
3138
  const isSoftComponent2 = softKeys.includes(key);
3064
3139
  const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
3065
- 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)));
3066
3142
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: getClassName3(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar, { children: [
3067
3143
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar.Group, { children: [
3068
3144
  props.parentAction,