@netlisian/softconfig 0.0.11 → 0.1.1

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.
@@ -53,7 +53,12 @@ var __async = (__this, __arguments, generator) => {
53
53
 
54
54
  // src/puck/store/index.tsx
55
55
  import { create } from "zustand";
56
- import { subscribeWithSelector, devtools } from "zustand/middleware";
56
+ import { subscribeWithSelector } from "zustand/middleware";
57
+
58
+ // src/puck/store/slices/builder.tsx
59
+ import {
60
+ walkTree as walkTree3
61
+ } from "@measured/puck";
57
62
 
58
63
  // src/puck/lib/get-root-props.ts
59
64
  var getRootProps = (appState) => appState.data.root.props;
@@ -265,19 +270,23 @@ import { createContext, useContext } from "react";
265
270
  import { useStore } from "zustand";
266
271
  var appStoreContext = createContext(null);
267
272
  var createUseSoftConfig = () => {
268
- return function useSoftConfig2(selector) {
273
+ return function useSoftConfig2(selector, equalityFn) {
269
274
  const context = useContext(appStoreContext);
270
275
  if (!context) {
271
276
  throw new Error(
272
277
  "useSoftConfig must be used inside a SoftConfigProvider. Wrap your tree with <SoftConfigProvider value={store}>"
273
278
  );
274
279
  }
280
+ if (equalityFn) {
281
+ return useStore(context, selector, equalityFn);
282
+ }
275
283
  return useStore(context, selector);
276
284
  };
277
285
  };
278
286
  var useSoftConfig = createUseSoftConfig();
279
287
 
280
288
  // src/puck/lib/builder/root-config.tsx
289
+ import { useDebounce } from "use-debounce";
281
290
  import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
282
291
  var useCustomPuck = createUsePuck();
283
292
  var breakVersion = (version) => {
@@ -298,12 +307,29 @@ var updateVersion = (version, increment) => {
298
307
  }
299
308
  return `${major}.${minor}.${patch}`;
300
309
  };
301
- var builderRootConfig = (config, overrides, editingComponent) => ({
310
+ var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true) => ({
302
311
  fields: {
303
- _name: {
312
+ _name: overrides.name || {
304
313
  type: "text",
305
314
  label: "Soft Component Name"
306
315
  },
316
+ _category: overrides.categories || {
317
+ type: "select",
318
+ label: "Category",
319
+ options: [
320
+ ...Object.keys(config.categories || {}).map((cat) => {
321
+ var _a;
322
+ return {
323
+ label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
324
+ value: cat
325
+ };
326
+ }) || [],
327
+ {
328
+ label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
329
+ value: void 0
330
+ }
331
+ ]
332
+ },
307
333
  _fields: {
308
334
  type: "array",
309
335
  label: "Fields",
@@ -346,7 +372,7 @@ var builderRootConfig = (config, overrides, editingComponent) => ({
346
372
  )
347
373
  };
348
374
  else delete fields._fieldSettings;
349
- if (((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length) && (!(data == null ? void 0 : data._version) || changed._version || changed._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)) {
350
376
  const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
351
377
  delete fields._version;
352
378
  fields._version = {
@@ -368,10 +394,14 @@ var builderRootConfig = (config, overrides, editingComponent) => ({
368
394
  }
369
395
  ]
370
396
  };
397
+ } else {
398
+ delete fields._version;
371
399
  }
372
400
  return fields;
373
401
  },
374
- resolveData: (props) => {
402
+ resolveData: (props, params) => {
403
+ if (overrides.onRootsDataChange)
404
+ overrides.onRootsDataChange(props, params);
375
405
  return {
376
406
  props,
377
407
  readOnly: Boolean(editingComponent) ? {
@@ -386,80 +416,78 @@ var builderRootConfig = (config, overrides, editingComponent) => ({
386
416
  const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
387
417
  const setVersion = useSoftConfig((s) => s.builder.setVersion);
388
418
  const state = useSoftConfig((s) => s.state);
419
+ const [debouncedFieldSettings] = useDebounce(fieldSettings, 500);
389
420
  useEffect(() => {
390
- const propagateChanges = setTimeout(() => {
391
- if (!fieldSettings || Object.keys(fieldSettings).length === 0) return;
392
- walkTree(
393
- data,
394
- {
395
- components: config.components
396
- },
397
- (content) => content.map((child) => {
398
- var _a;
399
- const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
400
- if (map.length) {
401
- map.forEach(({ from, to, transform }) => {
402
- if (!from || !to) return;
403
- const fromPaths = Array.isArray(from) ? from : [from];
404
- const toPaths = Array.isArray(to) ? to : [to];
405
- const inputValues = fromPaths.map(
406
- (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
407
- );
408
- let value = transform ? transform(
409
- inputValues.map((v) => v == null ? void 0 : v.defaultValue),
410
- child.props
411
- ) : inputValues[0];
412
- if (Array.isArray(value)) {
413
- value.forEach((val, i) => {
414
- if (toPaths[i]) {
415
- const originalValue = getFieldSettingsByPath(
416
- child.props,
417
- toPaths[i]
418
- );
419
- if (originalValue !== val) {
420
- const itemSelector = getSelectorForId(child.props.id);
421
- if (!itemSelector) return;
422
- setPropertyByPath(child.props, toPaths[i], val);
423
- dispatch({
424
- type: "replace",
425
- data: child,
426
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
427
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
428
- });
429
- }
421
+ if (!debouncedFieldSettings || Object.keys(debouncedFieldSettings).length === 0) return;
422
+ walkTree(
423
+ data,
424
+ {
425
+ components: config.components
426
+ },
427
+ (content) => content.map((child) => {
428
+ var _a;
429
+ const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
430
+ if (map.length) {
431
+ map.forEach(({ from, to, transform }) => {
432
+ if (!from || !to) return;
433
+ const fromPaths = Array.isArray(from) ? from : [from];
434
+ const toPaths = Array.isArray(to) ? to : [to];
435
+ const inputValues = fromPaths.map(
436
+ (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
437
+ );
438
+ let value = transform ? transform(
439
+ inputValues.map((v) => v == null ? void 0 : v.defaultValue),
440
+ child.props
441
+ ) : inputValues[0];
442
+ if (Array.isArray(value)) {
443
+ value.forEach((val, i) => {
444
+ if (toPaths[i]) {
445
+ const originalValue = getFieldSettingsByPath(
446
+ child.props,
447
+ toPaths[i]
448
+ );
449
+ if (originalValue !== val) {
450
+ const itemSelector = getSelectorForId(child.props.id);
451
+ if (!itemSelector) return;
452
+ setPropertyByPath(child.props, toPaths[i], val);
453
+ dispatch({
454
+ type: "replace",
455
+ data: child,
456
+ destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
457
+ destinationZone: itemSelector == null ? void 0 : itemSelector.zone
458
+ });
430
459
  }
431
- });
432
- } else if (toPaths[0]) {
433
- const setting = getFieldSettingsByPath(
434
- fieldSettings,
435
- fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
436
- );
437
- const defaultValue = setting == null ? void 0 : setting.defaultValue;
438
- const originalValue = getFieldSettingsByPath(
439
- child.props,
440
- toPaths[0]
441
- );
442
- const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
443
- if (originalValue !== finalValue) {
444
- const itemSelector = getSelectorForId(child.props.id);
445
- if (!itemSelector) return;
446
- setPropertyByPath(child.props, toPaths[0], finalValue);
447
- dispatch({
448
- type: "replace",
449
- data: child,
450
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
451
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
452
- });
453
460
  }
461
+ });
462
+ } else if (toPaths[0]) {
463
+ const setting = getFieldSettingsByPath(
464
+ debouncedFieldSettings,
465
+ fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
466
+ );
467
+ const defaultValue = setting == null ? void 0 : setting.defaultValue;
468
+ const originalValue = getFieldSettingsByPath(
469
+ child.props,
470
+ toPaths[0]
471
+ );
472
+ const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
473
+ if (originalValue !== finalValue) {
474
+ const itemSelector = getSelectorForId(child.props.id);
475
+ if (!itemSelector) return;
476
+ setPropertyByPath(child.props, toPaths[0], finalValue);
477
+ dispatch({
478
+ type: "replace",
479
+ data: child,
480
+ destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
481
+ destinationZone: itemSelector == null ? void 0 : itemSelector.zone
482
+ });
454
483
  }
455
- });
456
- }
457
- return child;
458
- })
459
- );
460
- }, 300);
461
- return () => clearTimeout(propagateChanges);
462
- }, [fieldSettings]);
484
+ }
485
+ });
486
+ }
487
+ return child;
488
+ })
489
+ );
490
+ }, [debouncedFieldSettings, data, dispatch, getSelectorForId, props._fieldSettings]);
463
491
  useEffect(() => {
464
492
  var _a;
465
493
  if (state !== "remodeling") return;
@@ -544,7 +572,7 @@ var getClassNameFactory = (rootClass, styles, config = { baseClass: "" }) => (op
544
572
  };
545
573
  var get_class_name_factory_default = getClassNameFactory;
546
574
 
547
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\components\error-boundary\styles.module.css#css-module
575
+ // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/error-boundary/styles.module.css#css-module
548
576
  var styles_module_default = { "ErrorBoundary": "_ErrorBoundary_1xl05_5", "ErrorBoundary-title": "_ErrorBoundary-title_1xl05_21", "ErrorBoundary-details": "_ErrorBoundary-details_1xl05_31", "ErrorBoundary-button": "_ErrorBoundary-button_1xl05_39" };
549
577
 
550
578
  // src/puck/components/error-boundary/index.tsx
@@ -603,157 +631,158 @@ var ErrorBoundary = class extends Component {
603
631
 
604
632
  // src/puck/lib/builder/builder-config.tsx
605
633
  import { jsx as jsx4 } from "react/jsx-runtime";
606
- var builderConfig = (config, overrides, editingComponent) => ({
607
- root: builderRootConfig(config, overrides, editingComponent),
634
+ var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents) => ({
635
+ root: builderRootConfig(config, overrides, editingComponent, showVersionFields),
608
636
  components: Object.entries(__spreadValues({}, config.components)).reduce(
609
637
  (acc, [name, component]) => {
610
- if (!editingComponent || name !== editingComponent) {
611
- let _a;
612
- const tempComponent = __spreadProps(__spreadValues({}, component), {
613
- resolveFields(data, params) {
614
- return __async(this, null, function* () {
615
- let fields = {};
616
- if (!fields._slot) {
617
- const slotFields = Object.entries(params.fields).filter(
618
- ([_, field]) => field.type === "slot"
619
- );
620
- if (slotFields.length)
621
- fields._slot = {
622
- type: "array",
623
- label: "Enable Dropdown Slots",
624
- getItemSummary(item, index) {
625
- return item.slot || `Slot ${(index || 0) + 1}`;
626
- },
627
- arrayFields: {
628
- slot: {
629
- type: "select",
630
- label: "Slot",
631
- options: [
632
- { label: "Select a slot", value: "" },
633
- ...slotFields.filter(
634
- ([fieldName, field]) => {
635
- var _a2;
636
- return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
637
- (s) => s.slot === fieldName
638
- );
639
- }
640
- ).map(([fieldName, field]) => ({
641
- label: field.label || fieldName,
642
- value: fieldName
643
- }))
644
- ]
645
- },
646
- name: {
647
- type: "text",
648
- label: "Name",
649
- placeholder: "Optional Slot Name"
650
- }
651
- }
652
- };
653
- }
654
- const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
655
- if (!fields._map) {
656
- const rootProps = getRootProps(params.appState);
657
- const fromOptions = generateDynamicFieldOptions(
658
- (rootProps == null ? void 0 : rootProps._fields) || [],
659
- (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
660
- );
661
- const toOptions = generateFieldOptions(defaultFields, []);
662
- fields._map = overrides.map ? {
663
- type: "custom",
664
- render: ({ value, onChange, id }) => {
665
- const toOptions2 = generateFieldOptions(defaultFields, []);
666
- const rootProps2 = getRootProps(params.appState);
667
- return overrides.map({
668
- rootProps: rootProps2,
669
- value,
670
- onChange,
671
- id,
672
- props: data.props || {},
673
- fromOptions,
674
- toOptions: toOptions2
675
- });
676
- }
677
- } : {
638
+ const tempComponent = __spreadProps(__spreadValues({}, component), {
639
+ permissions: {
640
+ insert: editingComponent !== name && !(dependents == null ? void 0 : dependents.has(name))
641
+ },
642
+ resolveFields(data, params) {
643
+ return __async(this, null, function* () {
644
+ let fields = {};
645
+ if (!fields._slot) {
646
+ const slotFields = Object.entries(params.fields).filter(
647
+ ([_, field]) => field.type === "slot"
648
+ );
649
+ if (slotFields.length)
650
+ fields._slot = {
678
651
  type: "array",
679
- label: "Dynamic Field Map",
652
+ label: "Enable Dropdown Slots",
653
+ getItemSummary(item, index) {
654
+ return item.slot || `Slot ${(index || 0) + 1}`;
655
+ },
680
656
  arrayFields: {
681
- from: {
657
+ slot: {
682
658
  type: "select",
683
- label: "From",
659
+ label: "Slot",
684
660
  options: [
685
- { label: "Select a field", value: "" },
686
- ...fromOptions.map(({ label, value }) => ({
687
- label,
688
- value
661
+ { label: "Select a slot", value: "" },
662
+ ...slotFields.filter(
663
+ ([fieldName, field]) => {
664
+ var _a2;
665
+ return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
666
+ (s) => s.slot === fieldName
667
+ );
668
+ }
669
+ ).map(([fieldName, field]) => ({
670
+ label: field.label || fieldName,
671
+ value: fieldName
689
672
  }))
690
673
  ]
691
674
  },
692
- to: {
693
- type: "select",
694
- label: "To",
695
- options: [
696
- { label: "Select a field", value: "" },
697
- ...toOptions.map(({ label, value }) => ({
698
- label,
699
- value
700
- }))
701
- ]
675
+ name: {
676
+ type: "text",
677
+ label: "Name",
678
+ placeholder: "Optional Slot Name"
702
679
  }
703
680
  }
704
681
  };
705
- }
706
- fields = __spreadValues(__spreadValues({}, fields), defaultFields);
707
- return fields;
708
- });
709
- },
710
- resolveData: ({ props }, { lastData }) => {
711
- var _a2;
712
- const _map = props._map || [];
713
- const readOnlyFields = _map.flatMap((item) => item.to);
714
- if (_map.length) {
682
+ }
683
+ const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
684
+ if (!fields._map) {
685
+ const rootProps = getRootProps(params.appState);
686
+ const fromOptions = generateDynamicFieldOptions(
687
+ (rootProps == null ? void 0 : rootProps._fields) || [],
688
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
689
+ );
690
+ const toOptions = generateFieldOptions(defaultFields, []);
691
+ fields._map = overrides.map ? {
692
+ type: "custom",
693
+ render: ({ value, onChange, id }) => {
694
+ const toOptions2 = generateFieldOptions(defaultFields, []);
695
+ const rootProps2 = getRootProps(params.appState);
696
+ return overrides.map({
697
+ rootProps: rootProps2,
698
+ value,
699
+ onChange,
700
+ id,
701
+ props: data.props || {},
702
+ fromOptions,
703
+ toOptions: toOptions2
704
+ });
705
+ }
706
+ } : {
707
+ type: "array",
708
+ label: "Dynamic Field Map",
709
+ arrayFields: {
710
+ from: {
711
+ type: "select",
712
+ label: "From",
713
+ options: [
714
+ { label: "Select a field", value: "" },
715
+ ...fromOptions.map(({ label, value }) => ({
716
+ label,
717
+ value
718
+ }))
719
+ ]
720
+ },
721
+ to: {
722
+ type: "select",
723
+ label: "To",
724
+ options: [
725
+ { label: "Select a field", value: "" },
726
+ ...toOptions.map(({ label, value }) => ({
727
+ label,
728
+ value
729
+ }))
730
+ ]
731
+ }
732
+ }
733
+ };
734
+ }
735
+ fields = __spreadValues(__spreadValues({}, fields), defaultFields);
736
+ return fields;
737
+ });
738
+ },
739
+ resolveData: ({ props }, { lastData }) => {
740
+ var _a2;
741
+ const _map = props._map || [];
742
+ const readOnlyFields = _map.flatMap((item) => item.to);
743
+ if (_map.length) {
744
+ return {
745
+ props,
746
+ readOnly: readOnlyFields.reduce(
747
+ (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
748
+ {}
749
+ )
750
+ };
751
+ }
752
+ const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
753
+ if (prevMap && prevMap.length === 1) {
754
+ const lastField = prevMap[0].to;
755
+ if (typeof lastField === "string") {
756
+ return {
757
+ props,
758
+ readOnly: { [lastField]: false }
759
+ };
760
+ }
761
+ if (Array.isArray(lastField)) {
715
762
  return {
716
763
  props,
717
- readOnly: readOnlyFields.reduce(
718
- (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
764
+ readOnly: lastField.reduce(
765
+ (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
719
766
  {}
720
767
  )
721
768
  };
722
769
  }
723
- const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
724
- if (prevMap && prevMap.length === 1) {
725
- const lastField = prevMap[0].to;
726
- if (typeof lastField === "string") {
727
- return {
728
- props,
729
- readOnly: { [lastField]: false }
730
- };
731
- }
732
- if (Array.isArray(lastField)) {
733
- return {
734
- props,
735
- readOnly: lastField.reduce(
736
- (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
737
- {}
738
- )
739
- };
740
- }
741
- }
742
- return {
743
- props,
744
- readOnly: {}
745
- };
746
- },
747
- render: (props) => {
748
- return /* @__PURE__ */ jsx4(ErrorBoundary, { children: component.render(props) });
749
770
  }
750
- });
751
- acc[name] = tempComponent;
752
- }
771
+ return {
772
+ props,
773
+ readOnly: {}
774
+ };
775
+ },
776
+ render: (props) => {
777
+ return /* @__PURE__ */ jsx4(ErrorBoundary, { children: component.render(props) });
778
+ }
779
+ });
780
+ acc[name] = tempComponent;
753
781
  return acc;
754
782
  },
755
783
  {}
756
- )
784
+ ),
785
+ categories: config.categories || {}
757
786
  });
758
787
 
759
788
  // src/puck/lib/strip-id.ts
@@ -879,14 +908,14 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
879
908
  {}
880
909
  )) || {};
881
910
  };
882
- var softComponentFromAppState = (appState, configComponents) => {
911
+ var softComponentFromAppState = (appState, configComponents, editedItem, metadata) => {
883
912
  var _a;
884
913
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
885
914
  const fields = rootProps._fields || [];
886
915
  const field_settings = rootProps._fieldSettings || {};
887
916
  const slots = {};
888
917
  const components = getSubComponents(
889
- appState.data.content || [],
918
+ [editedItem],
890
919
  configComponents,
891
920
  field_settings,
892
921
  slots
@@ -900,6 +929,8 @@ var softComponentFromAppState = (appState, configComponents) => {
900
929
  )), slots);
901
930
  return [
902
931
  {
932
+ name: metadata.name,
933
+ category: metadata.category,
903
934
  fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, field_settings)), Object.keys(slots).reduce((acc, slot) => {
904
935
  acc[slot] = { type: "slot", label: slot };
905
936
  return acc;
@@ -1035,7 +1066,7 @@ var reconstructComponents = (subComponents, componentConfigs, softComponentProps
1035
1066
  return componentData;
1036
1067
  });
1037
1068
  };
1038
- var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs) => {
1069
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, displayName, category) => {
1039
1070
  const slots = new Set(Object.keys(softComponent.slots));
1040
1071
  const { fields, fieldSettings } = puckFieldsToSoftFields(
1041
1072
  softComponent.fields,
@@ -1047,7 +1078,8 @@ var softComponentToAppState = (softComponent, componentName, version, versions,
1047
1078
  }
1048
1079
  });
1049
1080
  const rootProps = {
1050
- _name: componentName,
1081
+ _name: displayName || componentName,
1082
+ _category: category,
1051
1083
  _version: version,
1052
1084
  _versions: versions,
1053
1085
  _fields: fields,
@@ -1076,6 +1108,7 @@ var rootDroppableId = `${rootAreaId}:${rootZone}`;
1076
1108
  // src/puck/components/soft-render/index.tsx
1077
1109
  import { useMemo, useRef } from "react";
1078
1110
  import { v4 as uuidv42 } from "uuid";
1111
+ import equal from "fast-deep-equal";
1079
1112
  import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
1080
1113
  function SoftRender({
1081
1114
  softComponentFields,
@@ -1087,11 +1120,10 @@ function SoftRender({
1087
1120
  }) {
1088
1121
  const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1089
1122
  const mapCacheRef = useRef(/* @__PURE__ */ new Map());
1090
- const prevPropsRef = useRef("");
1091
- const propsSnapshot = JSON.stringify(props);
1092
- if (prevPropsRef.current !== propsSnapshot) {
1123
+ const prevPropsRef = useRef(null);
1124
+ if (!equal(prevPropsRef.current, props)) {
1093
1125
  mapCacheRef.current.clear();
1094
- prevPropsRef.current = propsSnapshot;
1126
+ prevPropsRef.current = props;
1095
1127
  }
1096
1128
  const subComponentRootProps = useMemo(
1097
1129
  () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
@@ -1103,10 +1135,6 @@ function SoftRender({
1103
1135
  ),
1104
1136
  [softComponentFields, props]
1105
1137
  );
1106
- const valuesToUpdateKey = useMemo(
1107
- () => JSON.stringify(subComponentRootProps),
1108
- [subComponentRootProps]
1109
- );
1110
1138
  return /* @__PURE__ */ jsx5(Fragment2, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1111
1139
  var _a2;
1112
1140
  const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
@@ -1133,7 +1161,7 @@ function SoftRender({
1133
1161
  }
1134
1162
  return propValue;
1135
1163
  });
1136
- const cacheKey = JSON.stringify(inputValues);
1164
+ const cacheKey = inputValues.map((v, i) => `${i}:${typeof v === "object" ? JSON.stringify(v) : v}`).join("|");
1137
1165
  let result = mapCacheRef.current.get(cacheKey);
1138
1166
  if (!result) {
1139
1167
  const runner = transform;
@@ -1160,7 +1188,7 @@ function SoftRender({
1160
1188
  const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1161
1189
  resolvedProps[slotKey] = useMemo(
1162
1190
  () => rest[slotName] || (() => null),
1163
- [slotName]
1191
+ [slotName, rest[slotName]]
1164
1192
  );
1165
1193
  } else {
1166
1194
  resolvedProps[slotKey] = useMemo(() => {
@@ -1181,7 +1209,7 @@ function SoftRender({
1181
1209
  slotKey
1182
1210
  ) });
1183
1211
  };
1184
- }, [valuesToUpdateKey]);
1212
+ }, [slotKey, subComponentRootProps]);
1185
1213
  }
1186
1214
  }
1187
1215
  }
@@ -1200,10 +1228,11 @@ function SoftRender({
1200
1228
 
1201
1229
  // src/puck/lib/create-versioned-component-config.tsx
1202
1230
  import { jsx as jsx6 } from "react/jsx-runtime";
1203
- var createVersionedComponentConfig = (componentName, version, allVersions, config, softComponents, defaultProps) => {
1231
+ var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true) => {
1204
1232
  var _a, _b;
1205
1233
  const softConfig = config;
1206
1234
  return {
1235
+ label: displayName,
1207
1236
  fields: Object.fromEntries(
1208
1237
  (Object.entries(
1209
1238
  (_b = (_a = softComponents[componentName].versions) == null ? void 0 : _a[version]) == null ? void 0 : _b.fields
@@ -1218,16 +1247,18 @@ var createVersionedComponentConfig = (componentName, version, allVersions, confi
1218
1247
  var _a2, _b2;
1219
1248
  const selectedVersion = ((_a2 = data.props) == null ? void 0 : _a2.version) || version;
1220
1249
  const versionedComponent = (_b2 = softComponents[componentName]) == null ? void 0 : _b2.versions[selectedVersion];
1221
- const fieldsWithoutSlots = Object.fromEntries(
1222
- Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").map(([key, field]) => [key, __spreadValues({}, field)])
1223
- );
1224
- return __spreadValues({
1225
- version: {
1250
+ let fields = {};
1251
+ if (showVersioning) {
1252
+ fields.version = {
1226
1253
  label: "Version",
1227
1254
  type: "select",
1228
1255
  options: allVersions.map((v) => ({ label: v, value: v }))
1229
- }
1230
- }, fieldsWithoutSlots);
1256
+ };
1257
+ }
1258
+ Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").forEach(([key, field]) => {
1259
+ fields[key] = field;
1260
+ });
1261
+ return fields;
1231
1262
  },
1232
1263
  render: (props) => {
1233
1264
  var _a2;
@@ -1347,9 +1378,21 @@ function demolishSoftComponent(componentName, data, config, softComponents) {
1347
1378
  };
1348
1379
  }
1349
1380
 
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
+
1350
1393
  // src/puck/store/slices/builder.tsx
1351
1394
  var createBuildersSlice = (set, get, initialConfig) => ({
1352
- build: (history, selectedItem, itemSelector, puckDispatch) => {
1395
+ build: (history, selectedItem, itemSelector, puckDispatch, name) => {
1353
1396
  if (!selectedItem || !itemSelector) {
1354
1397
  throw new Error("No item selected to build from.");
1355
1398
  }
@@ -1362,16 +1405,31 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1362
1405
  data: __spreadProps(__spreadValues({}, previous.data), {
1363
1406
  root: {
1364
1407
  props: {
1365
- _name: "New Soft Component"
1408
+ _name: name || "New Soft Component"
1366
1409
  }
1367
- },
1368
- content: [__spreadValues({}, selectedItem)]
1410
+ }
1411
+ // content: [{ ...selectedItem }],
1369
1412
  })
1370
1413
  })
1371
1414
  });
1372
1415
  const config = __spreadValues({}, get().softConfig);
1373
1416
  const overrides = get().overrides;
1374
- const buildConfig = builderConfig(config, overrides);
1417
+ const buildConfig = builderConfig(config, overrides, void 0, get().showVersionFields);
1418
+ const editableIds = /* @__PURE__ */ new Set([selectedItem.props.id]);
1419
+ const initialContent = [__spreadValues({}, selectedItem)];
1420
+ walkTree3(
1421
+ {
1422
+ root: {},
1423
+ content: initialContent
1424
+ },
1425
+ { components: config.components },
1426
+ (components) => {
1427
+ components.forEach((comp) => {
1428
+ editableIds.add(comp.props.id);
1429
+ });
1430
+ return components;
1431
+ }
1432
+ );
1375
1433
  set((s) => __spreadProps(__spreadValues({}, s), {
1376
1434
  softConfig: buildConfig,
1377
1435
  storedConfig: config,
@@ -1380,6 +1438,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1380
1438
  index: itemSelector.index,
1381
1439
  zone: itemSelector.zone || rootDroppableId
1382
1440
  },
1441
+ editingComponentId: selectedItem.props.id,
1442
+ editableComponentIds: editableIds,
1383
1443
  state: "building"
1384
1444
  }));
1385
1445
  setTimeout(
@@ -1387,7 +1447,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1387
1447
  type: "replaceRoot",
1388
1448
  root: {
1389
1449
  title: "Soft Component Builder",
1390
- _name: "New Soft Component"
1450
+ _name: name || "New Soft Component"
1391
1451
  }
1392
1452
  }),
1393
1453
  100
@@ -1404,6 +1464,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1404
1464
  }
1405
1465
  const softComponentVersion = ((_a = selectedItem.props) == null ? void 0 : _a.version) || "1.0.0";
1406
1466
  const softComponent = (_b = get().softComponents[softComponentName]) == null ? void 0 : _b.versions[softComponentVersion];
1467
+ const softComponentMeta = get().softComponents[softComponentName];
1407
1468
  const versions = Object.keys(
1408
1469
  get().softComponents[softComponentName].versions || {}
1409
1470
  );
@@ -1424,18 +1485,50 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1424
1485
  softComponentVersion,
1425
1486
  versions,
1426
1487
  selectedItem.props,
1427
- get().softConfig.components
1488
+ get().softConfig.components,
1489
+ (softComponentMeta == null ? void 0 : softComponentMeta.name) || softComponentName,
1490
+ softComponentMeta == null ? void 0 : softComponentMeta.category
1491
+ );
1492
+ const config = __spreadValues({}, get().softConfig);
1493
+ const overrides = get().overrides;
1494
+ const dependents = get().dependencyGraph.get(softComponentName) || /* @__PURE__ */ new Set();
1495
+ const buildConfig = builderConfig(config, overrides, softComponentName, get().showVersionFields, dependents);
1496
+ const editableIds = /* @__PURE__ */ new Set([]);
1497
+ const decomposedComponents = get().builder.decompose(selectedItem);
1498
+ walkTree3(
1499
+ { root: {}, content: decomposedComponents || [] },
1500
+ { components: config.components },
1501
+ (components) => {
1502
+ components.forEach((comp) => {
1503
+ editableIds.add(comp.props.id);
1504
+ });
1505
+ return components;
1506
+ }
1428
1507
  );
1429
1508
  puckDispatch({
1430
1509
  type: "setData",
1431
- data: (previous) => __spreadProps(__spreadValues({}, previous), {
1510
+ data: (prevData) => ({
1432
1511
  root: __spreadProps(__spreadValues({}, root), { _versions: versions }),
1433
- content: content || []
1512
+ content: walkTree3(__spreadValues({}, prevData), __spreadValues({}, config), (components) => {
1513
+ const next = components.map((component) => __spreadProps(__spreadValues({}, component), {
1514
+ props: __spreadValues({}, component.props)
1515
+ }));
1516
+ const index = next.findIndex(
1517
+ (component) => component.props.id === selectedItem.props.id
1518
+ );
1519
+ if (index !== -1) {
1520
+ next.splice(
1521
+ index,
1522
+ 1,
1523
+ ...decomposedComponents.map((component) => __spreadProps(__spreadValues({}, component), {
1524
+ props: __spreadValues({}, component.props)
1525
+ }))
1526
+ );
1527
+ }
1528
+ return next;
1529
+ }).content
1434
1530
  })
1435
1531
  });
1436
- const config = __spreadValues({}, get().softConfig);
1437
- const overrides = get().overrides;
1438
- const buildConfig = builderConfig(config, overrides, softComponentName);
1439
1532
  set((s) => __spreadProps(__spreadValues({}, s), {
1440
1533
  storedConfig: config,
1441
1534
  softConfig: buildConfig,
@@ -1444,62 +1537,109 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1444
1537
  index: itemSelector.index,
1445
1538
  zone: itemSelector.zone || rootDroppableId
1446
1539
  },
1540
+ editingComponentId: selectedItem.props.id,
1541
+ editableComponentIds: editableIds,
1447
1542
  state: "remodeling"
1448
1543
  }));
1449
1544
  setTimeout(
1450
1545
  () => puckDispatch({
1451
1546
  type: "replaceRoot",
1452
1547
  root: {
1453
- title: "Soft Component Builder",
1454
- _name: "New Soft Component"
1548
+ title: root.props.title,
1549
+ _name: root.props._name,
1550
+ _category: root.props._category
1455
1551
  }
1456
1552
  }),
1457
1553
  100
1458
1554
  );
1459
1555
  },
1460
- complete: (appState, setHistories) => {
1461
- var _a, _b;
1556
+ complete: (appState, setHistories, getItemBySelector) => {
1557
+ var _a, _b, _c, _d, _e;
1462
1558
  if (get().state === "ready") {
1463
1559
  throw new Error("Not building or remodeling a component.");
1464
1560
  }
1465
- const componentName = (_b = (_a = appState.data.root) == null ? void 0 : _a.props) == null ? void 0 : _b._name;
1466
- if (!componentName) {
1561
+ const displayName = (_c = (_b = (_a = appState.data.root) == null ? void 0 : _a.props) == null ? void 0 : _b._name) == null ? void 0 : _c.trim();
1562
+ if (!displayName) {
1467
1563
  throw new Error("Root component must have a name to compose.");
1468
1564
  }
1469
- const [newSoftComponentConfig, version] = get().builder.compose(appState, componentName) || [];
1565
+ const itemSelector = get().itemSelector;
1566
+ if (!itemSelector) {
1567
+ throw new Error("No item selector found for completed component.");
1568
+ }
1569
+ const selectedItem = getItemBySelector(
1570
+ itemSelector
1571
+ );
1572
+ if (!selectedItem) {
1573
+ throw new Error("Cannot find item being edited");
1574
+ }
1575
+ const rootCategory = (_e = (_d = appState.data.root) == null ? void 0 : _d.props) == null ? void 0 : _e._category;
1576
+ const componentName = createComponentKeyFromName(displayName, get().overrides, {
1577
+ existingKeys: Object.keys(get().softComponents),
1578
+ state: get().state
1579
+ });
1580
+ if (!componentName) {
1581
+ throw new Error("Failed to generate component key from name.");
1582
+ }
1583
+ const [newSoftComponentConfig, version] = get().builder.compose(
1584
+ appState,
1585
+ componentName,
1586
+ selectedItem,
1587
+ displayName,
1588
+ rootCategory
1589
+ ) || [];
1470
1590
  if (!newSoftComponentConfig) {
1471
1591
  throw new Error("Failed to compose new soft component config.");
1472
1592
  }
1473
1593
  const storedHistories = get().originalHistory;
1474
1594
  setHistories([...storedHistories]);
1475
1595
  const config = __spreadValues({}, get().softConfig || initialConfig);
1476
- set((s) => __spreadProps(__spreadValues({}, s), {
1477
- softConfig: __spreadProps(__spreadValues({}, config), {
1478
- root: __spreadValues({}, initialConfig.root),
1479
- components: __spreadProps(__spreadValues({}, Object.entries(config.components).reduce(
1480
- (acc, [name, component]) => {
1481
- var _a2;
1482
- let tempComponent = (_a2 = config.components) == null ? void 0 : _a2[name];
1483
- if (tempComponent) {
1484
- acc[name] = tempComponent;
1485
- acc[name].render = tempComponent.render;
1486
- } else {
1487
- tempComponent = __spreadValues({}, component);
1488
- tempComponent == null ? true : delete tempComponent.resolvePermissions;
1489
- tempComponent == null ? true : delete tempComponent.resolveData;
1490
- acc[name] = tempComponent;
1491
- }
1492
- return acc;
1493
- },
1494
- {}
1495
- )), {
1496
- [componentName]: __spreadValues({}, newSoftComponentConfig)
1596
+ set((s) => {
1597
+ var _a2, _b2;
1598
+ const nextComponents = __spreadProps(__spreadValues({}, Object.entries(config.components).reduce(
1599
+ (acc, [name, component]) => {
1600
+ var _a3;
1601
+ let tempComponent = (_a3 = config.components) == null ? void 0 : _a3[name];
1602
+ if (tempComponent) {
1603
+ acc[name] = tempComponent;
1604
+ acc[name].render = tempComponent.render;
1605
+ } else {
1606
+ tempComponent = __spreadValues({}, component);
1607
+ tempComponent == null ? true : delete tempComponent.resolvePermissions;
1608
+ tempComponent == null ? true : delete tempComponent.resolveData;
1609
+ acc[name] = tempComponent;
1610
+ }
1611
+ return acc;
1612
+ },
1613
+ {}
1614
+ )), {
1615
+ [componentName]: __spreadValues({}, newSoftComponentConfig)
1616
+ });
1617
+ const categories = get().softConfig.categories || {};
1618
+ const nextCategories = rootCategory ? __spreadProps(__spreadValues({}, categories), {
1619
+ [rootCategory]: __spreadProps(__spreadValues({}, categories[rootCategory] || {}), {
1620
+ title: ((_a2 = categories[rootCategory]) == null ? void 0 : _a2.title) || rootCategory,
1621
+ components: Array.from(
1622
+ /* @__PURE__ */ new Set([
1623
+ ...((_b2 = categories[rootCategory]) == null ? void 0 : _b2.components) || [],
1624
+ componentName
1625
+ ])
1626
+ )
1497
1627
  })
1498
- }),
1499
- storedConfig: void 0,
1500
- state: "inspecting",
1501
- originalHistory: []
1502
- }));
1628
+ }) : categories;
1629
+ return __spreadProps(__spreadValues({}, s), {
1630
+ softConfig: __spreadProps(__spreadValues({}, config), {
1631
+ root: __spreadValues({}, initialConfig.root),
1632
+ components: nextComponents,
1633
+ categories: nextCategories
1634
+ }),
1635
+ storedConfig: void 0,
1636
+ state: "inspecting",
1637
+ originalHistory: [],
1638
+ editingComponentId: null,
1639
+ editableComponentIds: /* @__PURE__ */ new Set()
1640
+ });
1641
+ });
1642
+ get().rebuildDependents(componentName, version);
1503
1643
  return componentName;
1504
1644
  },
1505
1645
  inspect: (componentName, puckDispatch) => {
@@ -1526,7 +1666,9 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1526
1666
  set((s) => __spreadProps(__spreadValues({}, s), {
1527
1667
  state: "ready",
1528
1668
  setItemSelector: void 0,
1529
- setOriginalItem: void 0
1669
+ setOriginalItem: void 0,
1670
+ editingComponentId: null,
1671
+ editableComponentIds: /* @__PURE__ */ new Set()
1530
1672
  }));
1531
1673
  },
1532
1674
  cancel: (setHistories) => {
@@ -1538,10 +1680,12 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1538
1680
  originalHistory: [],
1539
1681
  itemSelector: null,
1540
1682
  originalItem: null,
1541
- state: "ready"
1683
+ state: "ready",
1684
+ editingComponentId: null,
1685
+ editableComponentIds: /* @__PURE__ */ new Set()
1542
1686
  }));
1543
1687
  },
1544
- compose: (appState, componentName) => {
1688
+ compose: (appState, componentName, editedItem, displayName, category) => {
1545
1689
  if (!componentName) {
1546
1690
  throw new Error("Root component must have a name to compose.");
1547
1691
  }
@@ -1551,12 +1695,21 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1551
1695
  `Component name "${componentName}" already exists in the configuration.`
1552
1696
  );
1553
1697
  }
1554
- const [softComponent, version] = softComponentFromAppState(appState, componentConfigs);
1698
+ const [softComponent, version] = softComponentFromAppState(
1699
+ appState,
1700
+ componentConfigs,
1701
+ editedItem,
1702
+ {
1703
+ name: displayName,
1704
+ category
1705
+ }
1706
+ );
1555
1707
  const existingComponent = get().softComponents[componentName];
1556
1708
  const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
1557
1709
  const isNewVersion = !allVersions.includes(version);
1558
1710
  const newSoftComponentConfig = createVersionedComponentConfig(
1559
1711
  componentName,
1712
+ displayName,
1560
1713
  version,
1561
1714
  isNewVersion ? [...allVersions, version] : allVersions,
1562
1715
  get().softConfig,
@@ -1567,7 +1720,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1567
1720
  })
1568
1721
  })
1569
1722
  }),
1570
- softComponent.defaultProps
1723
+ softComponent.defaultProps,
1724
+ get().showVersionFields
1571
1725
  );
1572
1726
  get().setSoftComponent(componentName, version, softComponent);
1573
1727
  return [newSoftComponentConfig, version];
@@ -1603,6 +1757,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1603
1757
  throw new Error("Can only switch versions during remodeling.");
1604
1758
  }
1605
1759
  const softComponent = (_a = get().softComponents[componentName]) == null ? void 0 : _a.versions[newVersion];
1760
+ const softComponentMeta = get().softComponents[componentName];
1606
1761
  if (!softComponent) {
1607
1762
  throw new Error(
1608
1763
  `Soft component "${componentName}" with version "${newVersion}" not found.`
@@ -1617,7 +1772,9 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1617
1772
  newVersion,
1618
1773
  versions,
1619
1774
  currentProps,
1620
- get().softConfig.components
1775
+ get().softConfig.components,
1776
+ (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1777
+ softComponentMeta == null ? void 0 : softComponentMeta.category
1621
1778
  );
1622
1779
  puckDispatch({
1623
1780
  type: "setData",
@@ -1669,10 +1826,11 @@ function hydrateSoftComponentsTransforms(softComponents, hydrator) {
1669
1826
  })
1670
1827
  });
1671
1828
  });
1672
- hydrated[name] = {
1829
+ hydrated[name] = __spreadProps(__spreadValues({}, comp), {
1830
+ name: comp.name || name,
1673
1831
  defaultVersion: comp.defaultVersion,
1674
1832
  versions
1675
- };
1833
+ });
1676
1834
  });
1677
1835
  return hydrated;
1678
1836
  }
@@ -1699,6 +1857,27 @@ function extractDependencies(softComponents, componentName, version) {
1699
1857
  processSubComponents(component.components);
1700
1858
  return dependencies;
1701
1859
  }
1860
+ function buildReverseDependencyGraph(softComponents) {
1861
+ const reverseDeps = /* @__PURE__ */ new Map();
1862
+ for (const [componentName, component] of Object.entries(softComponents)) {
1863
+ const defaultVersion = component.defaultVersion || Object.keys(component.versions || {}).pop();
1864
+ if (!defaultVersion) continue;
1865
+ Object.entries(component.versions || {}).forEach(([version, versionedComp]) => {
1866
+ const dependencies = extractDependencies(softComponents, componentName, version);
1867
+ if (!component.dependencies) {
1868
+ component.dependencies = {};
1869
+ }
1870
+ component.dependencies[version] = dependencies;
1871
+ for (const dep of dependencies) {
1872
+ if (!reverseDeps.has(dep)) {
1873
+ reverseDeps.set(dep, /* @__PURE__ */ new Set());
1874
+ }
1875
+ reverseDeps.get(dep).add(componentName);
1876
+ }
1877
+ });
1878
+ }
1879
+ return reverseDeps;
1880
+ }
1702
1881
  function topologicalSort(softComponents, hardComponentNames) {
1703
1882
  const sorted = [];
1704
1883
  const visiting = /* @__PURE__ */ new Set();
@@ -1742,7 +1921,7 @@ function topologicalSort(softComponents, hardComponentNames) {
1742
1921
  }
1743
1922
  return sorted;
1744
1923
  }
1745
- function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1924
+ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false) {
1746
1925
  var _a, _b;
1747
1926
  if (!softComponents || Object.keys(softComponents).length === 0) {
1748
1927
  return {};
@@ -1771,12 +1950,14 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1771
1950
  }
1772
1951
  const newSoftComponentConfig = createVersionedComponentConfig(
1773
1952
  name,
1953
+ comp.name || name,
1774
1954
  defaultVersion || "1.0.0",
1775
1955
  allVersions,
1776
1956
  buildingConfig,
1777
1957
  // Pass the accumulating config
1778
1958
  hydratedSoftComponents,
1779
- versionedComponent.defaultProps
1959
+ versionedComponent.defaultProps,
1960
+ showVersioning
1780
1961
  );
1781
1962
  componentConfigs[name] = newSoftComponentConfig;
1782
1963
  buildingConfig.components[name] = newSoftComponentConfig;
@@ -1798,11 +1979,13 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1798
1979
  }
1799
1980
  const newSoftComponentConfig = createVersionedComponentConfig(
1800
1981
  name,
1982
+ comp.name || name,
1801
1983
  defaultVersion || "1.0.0",
1802
1984
  allVersions,
1803
1985
  hardConfig,
1804
1986
  hydratedSoftComponents,
1805
- versionedComponent.defaultProps
1987
+ versionedComponent.defaultProps,
1988
+ showVersioning
1806
1989
  );
1807
1990
  componentConfigs[name] = newSoftComponentConfig;
1808
1991
  }
@@ -1810,21 +1993,114 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1810
1993
  }
1811
1994
  }
1812
1995
 
1996
+ // src/puck/lib/edit-visibility-utils.ts
1997
+ var setEditVisibility = (doc, context) => {
1998
+ if (!doc) return;
1999
+ try {
2000
+ const root = doc.documentElement;
2001
+ if (context.mode === "none") {
2002
+ root.removeAttribute("data-edit-mode");
2003
+ root.classList.remove("edit-visibility-mode");
2004
+ doc.querySelectorAll("[data-puck-component]").forEach((el) => {
2005
+ el.removeAttribute("data-edit-visibility");
2006
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-editable", "edit-visibility-dependency");
2007
+ });
2008
+ } else {
2009
+ root.setAttribute("data-edit-mode", context.mode);
2010
+ root.classList.add("edit-visibility-mode");
2011
+ doc.querySelectorAll("[data-puck-component]").forEach((el) => {
2012
+ var _a;
2013
+ const id = el.getAttribute("data-puck-component");
2014
+ if (!id) return;
2015
+ const isEditable = context.editableIds.has(id);
2016
+ const isDependency = (_a = context.highlightDependencyIds) == null ? void 0 : _a.has(id);
2017
+ if (isEditable) {
2018
+ el.setAttribute("data-edit-visibility", "editable");
2019
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-dependency");
2020
+ el.classList.add("edit-visibility-editable");
2021
+ } else if (isDependency) {
2022
+ el.setAttribute("data-edit-visibility", "dependency");
2023
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-editable");
2024
+ el.classList.add("edit-visibility-dependency");
2025
+ } else {
2026
+ el.setAttribute("data-edit-visibility", "greyed");
2027
+ el.classList.remove("edit-visibility-editable", "edit-visibility-dependency");
2028
+ el.classList.add("edit-visibility-greyed");
2029
+ }
2030
+ });
2031
+ }
2032
+ } catch (error) {
2033
+ console.warn(`Failed to set edit visibility:`, error);
2034
+ }
2035
+ };
2036
+ var clearEditVisibility = (doc) => {
2037
+ if (!doc) return;
2038
+ try {
2039
+ const root = doc.documentElement;
2040
+ root.removeAttribute("data-edit-mode");
2041
+ root.classList.remove("edit-visibility-mode");
2042
+ doc.querySelectorAll("[data-puck-component]").forEach((el) => {
2043
+ el.removeAttribute("data-edit-visibility");
2044
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-editable", "edit-visibility-dependency");
2045
+ });
2046
+ } catch (error) {
2047
+ console.warn(`Failed to clear edit visibility:`, error);
2048
+ }
2049
+ };
2050
+
1813
2051
  // src/puck/store/index.tsx
1814
2052
  var createSoftConfigStore = (hardConfig = {
1815
2053
  components: {}
1816
- }, softComponents = {}, overrides = {}, onActions) => {
2054
+ }, softComponents = {}, overrides = {}, onActions, showVersionFields = true) => {
2055
+ const normalizedSoftComponents = Object.fromEntries(
2056
+ Object.entries(softComponents || {}).map(([key, value]) => [
2057
+ key,
2058
+ __spreadProps(__spreadValues({}, value), {
2059
+ name: value.name || key
2060
+ })
2061
+ ])
2062
+ );
2063
+ const iframeDocRef = { current: null };
1817
2064
  const hydratedSoftComponents = (overrides == null ? void 0 : overrides.hydrateMapTransform) ? hydrateSoftComponentsTransforms(
1818
- softComponents,
2065
+ normalizedSoftComponents,
1819
2066
  overrides.hydrateMapTransform
1820
- ) : softComponents;
2067
+ ) : normalizedSoftComponents;
2068
+ const initialDependencyGraph = buildReverseDependencyGraph(
2069
+ hydratedSoftComponents
2070
+ );
1821
2071
  return create()(
1822
2072
  subscribeWithSelector(
1823
- devtools((set, get) => ({
2073
+ (set, get) => ({
1824
2074
  state: "ready",
1825
2075
  originalHistory: [],
1826
2076
  overrides,
1827
2077
  onActions,
2078
+ iframeDocRef,
2079
+ showVersionFields,
2080
+ setShowVersionFields: (show) => set({ showVersionFields: show }),
2081
+ getIframeDoc: () => iframeDocRef.current,
2082
+ setIframeDoc: (doc) => {
2083
+ iframeDocRef.current = doc;
2084
+ if (!doc) {
2085
+ return;
2086
+ }
2087
+ const { state, editableComponentIds } = get();
2088
+ if (state === "building") {
2089
+ setEditVisibility(doc, {
2090
+ mode: "build",
2091
+ editableIds: editableComponentIds
2092
+ });
2093
+ return;
2094
+ }
2095
+ if (state === "remodeling") {
2096
+ setEditVisibility(doc, {
2097
+ mode: "remodel",
2098
+ editableIds: editableComponentIds
2099
+ });
2100
+ return;
2101
+ }
2102
+ clearEditVisibility(doc);
2103
+ },
1828
2104
  storeHistory: (history) => set({ originalHistory: history }),
1829
2105
  removeHistory: () => set({ originalHistory: [] }),
1830
2106
  itemSelector: null,
@@ -1833,24 +2109,29 @@ var createSoftConfigStore = (hardConfig = {
1833
2109
  setOriginalItem: (item) => set({ originalItem: item }),
1834
2110
  hydratedSoftComponents,
1835
2111
  softComponents: hydratedSoftComponents,
2112
+ dependencyGraph: initialDependencyGraph,
1836
2113
  softConfig: __spreadProps(__spreadValues({}, hardConfig), {
1837
2114
  components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(
1838
2115
  hardConfig,
1839
2116
  hydratedSoftComponents,
1840
2117
  overrides
1841
- ))
2118
+ )),
2119
+ categories: __spreadValues({}, hardConfig.categories || {})
1842
2120
  }),
1843
2121
  setSoftComponent: (name, version, component) => {
2122
+ const existing = get().softComponents[name];
1844
2123
  set((state) => {
1845
- var _a;
2124
+ var _a, _b;
1846
2125
  return {
1847
2126
  softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
1848
- [name]: {
2127
+ [name]: __spreadProps(__spreadValues({}, existing), {
2128
+ name: component.name || (existing == null ? void 0 : existing.name) || name,
2129
+ category: (_a = component.category) != null ? _a : existing == null ? void 0 : existing.category,
1849
2130
  defaultVersion: version,
1850
- versions: __spreadProps(__spreadValues({}, ((_a = state.softComponents[name]) == null ? void 0 : _a.versions) || {}), {
2131
+ versions: __spreadProps(__spreadValues({}, ((_b = state.softComponents[name]) == null ? void 0 : _b.versions) || {}), {
1851
2132
  [version]: component
1852
2133
  })
1853
- }
2134
+ })
1854
2135
  })
1855
2136
  };
1856
2137
  });
@@ -1862,19 +2143,23 @@ var createSoftConfigStore = (hardConfig = {
1862
2143
  Object.entries(incomingComponents).forEach(([name, data]) => {
1863
2144
  const existing = nextSoftComponents[name];
1864
2145
  const finalComponentData = existing ? __spreadProps(__spreadValues(__spreadValues({}, existing), data), {
2146
+ name: data.name || existing.name || name,
1865
2147
  versions: __spreadValues(__spreadValues({}, existing.versions), data.versions)
1866
2148
  }) : data;
2149
+ finalComponentData.name = finalComponentData.name || name;
1867
2150
  nextSoftComponents[name] = finalComponentData;
1868
2151
  const activeVersion = finalComponentData.defaultVersion;
1869
2152
  const activeVersionData = finalComponentData.versions[activeVersion];
1870
2153
  if (activeVersionData) {
1871
2154
  nextConfigComponents[name] = createVersionedComponentConfig(
1872
2155
  name,
2156
+ finalComponentData.name || name,
1873
2157
  activeVersion,
1874
2158
  Object.keys(finalComponentData.versions),
1875
2159
  state.softConfig,
1876
2160
  nextSoftComponents,
1877
- activeVersionData.defaultProps
2161
+ activeVersionData.defaultProps,
2162
+ state.showVersionFields
1878
2163
  );
1879
2164
  }
1880
2165
  });
@@ -1899,11 +2184,13 @@ var createSoftConfigStore = (hardConfig = {
1899
2184
  if (activeVersionData) {
1900
2185
  nextConfigComponents[name] = createVersionedComponentConfig(
1901
2186
  name,
2187
+ componentData.name || name,
1902
2188
  activeVersion,
1903
2189
  Object.keys(componentData.versions),
1904
2190
  softConfig,
1905
2191
  hydratedComponents,
1906
- activeVersionData.defaultProps
2192
+ activeVersionData.defaultProps,
2193
+ get().showVersionFields
1907
2194
  );
1908
2195
  }
1909
2196
  });
@@ -1915,11 +2202,12 @@ var createSoftConfigStore = (hardConfig = {
1915
2202
  });
1916
2203
  },
1917
2204
  setSoftComponentDefaultVersion: (name, version) => {
1918
- var _a, _b, _c;
2205
+ var _a, _b, _c, _d;
1919
2206
  const softComponent = (_b = (_a = get().softComponents[name]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
1920
2207
  const allVersions = Object.keys(
1921
2208
  ((_c = get().softComponents[name]) == null ? void 0 : _c.versions) || {}
1922
2209
  );
2210
+ const displayName = ((_d = get().softComponents[name]) == null ? void 0 : _d.name) || name;
1923
2211
  if (!softComponent) {
1924
2212
  throw new Error(
1925
2213
  `Soft component "${name}" version "${version}" does not exist.`
@@ -1927,11 +2215,13 @@ var createSoftConfigStore = (hardConfig = {
1927
2215
  }
1928
2216
  const newSoftComponentConfig = createVersionedComponentConfig(
1929
2217
  name,
2218
+ displayName,
1930
2219
  version,
1931
2220
  allVersions,
1932
2221
  get().softConfig,
1933
2222
  get().softComponents,
1934
- softComponent.defaultProps
2223
+ softComponent.defaultProps,
2224
+ get().showVersionFields
1935
2225
  );
1936
2226
  set((state) => ({
1937
2227
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
@@ -1979,20 +2269,20 @@ var createSoftConfigStore = (hardConfig = {
1979
2269
  },
1980
2270
  setSoftComponentConfig: (key, config, category) => {
1981
2271
  set((state) => {
1982
- var _a;
2272
+ var _a, _b, _c;
1983
2273
  return {
1984
2274
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
1985
2275
  components: __spreadProps(__spreadValues({}, state.softConfig.components), {
1986
2276
  [key]: __spreadValues({}, config)
1987
2277
  }),
1988
- categories: category && state.softConfig.categories ? __spreadProps(__spreadValues({}, state.softConfig.categories), {
1989
- [category]: __spreadProps(__spreadValues({}, state.softConfig.categories[category]), {
2278
+ categories: category ? __spreadProps(__spreadValues({}, state.softConfig.categories || {}), {
2279
+ [category]: __spreadProps(__spreadValues({}, ((_a = state.softConfig.categories) == null ? void 0 : _a[category]) || {}), {
1990
2280
  components: [
1991
- ...((_a = state.softConfig.categories[category]) == null ? void 0 : _a.components) || [],
2281
+ ...((_c = (_b = state.softConfig.categories) == null ? void 0 : _b[category]) == null ? void 0 : _c.components) || [],
1992
2282
  key
1993
2283
  ]
1994
2284
  })
1995
- }) : state.softConfig.categories
2285
+ }) : state.softConfig.categories || {}
1996
2286
  })
1997
2287
  };
1998
2288
  });
@@ -2031,8 +2321,50 @@ var createSoftConfigStore = (hardConfig = {
2031
2321
  })
2032
2322
  }));
2033
2323
  },
2034
- builder: createBuildersSlice(set, get, hardConfig)
2035
- }))
2324
+ builder: createBuildersSlice(set, get, hardConfig),
2325
+ editingComponentId: null,
2326
+ editableComponentIds: /* @__PURE__ */ new Set(),
2327
+ setEditableComponentIds: (ids) => set({ editableComponentIds: ids }),
2328
+ addEditableComponentId: (id) => {
2329
+ set((state) => {
2330
+ const newIds = new Set(state.editableComponentIds);
2331
+ newIds.add(id);
2332
+ return { editableComponentIds: newIds };
2333
+ });
2334
+ },
2335
+ clearEditingState: () => set({
2336
+ editingComponentId: null,
2337
+ editableComponentIds: /* @__PURE__ */ new Set()
2338
+ }),
2339
+ rebuildDependents: (componentName, version) => {
2340
+ const state = get();
2341
+ const dependents = state.dependencyGraph.get(componentName) || /* @__PURE__ */ new Set();
2342
+ if (dependents.size === 0) return;
2343
+ const config = __spreadValues({}, state.softConfig);
2344
+ const softComponents2 = state.softComponents;
2345
+ const toBuild = Array.from(dependents);
2346
+ for (const dependentName of toBuild) {
2347
+ const dependent = softComponents2[dependentName];
2348
+ const defaultVersion = dependent.defaultVersion || Object.keys(dependent.versions || {}).pop();
2349
+ if (!defaultVersion) continue;
2350
+ const versionedComponent = dependent.versions[defaultVersion];
2351
+ const allVersions = Object.keys(dependent.versions || {});
2352
+ if (!versionedComponent) continue;
2353
+ const newConfig = createVersionedComponentConfig(
2354
+ dependentName,
2355
+ dependent.name || dependentName,
2356
+ defaultVersion,
2357
+ allVersions,
2358
+ config,
2359
+ softComponents2,
2360
+ versionedComponent.defaultProps,
2361
+ state.showVersionFields
2362
+ );
2363
+ config.components[dependentName] = newConfig;
2364
+ }
2365
+ set((s) => __spreadProps(__spreadValues({}, s), { softConfig: config }));
2366
+ }
2367
+ })
2036
2368
  )
2037
2369
  );
2038
2370
  };
@@ -2046,11 +2378,12 @@ var SoftConfigProvider = ({
2046
2378
  softComponents,
2047
2379
  overrides,
2048
2380
  value,
2049
- onActions
2381
+ onActions,
2382
+ useVersioning = false
2050
2383
  }) => {
2051
2384
  const store = value != null ? value : useMemo2(
2052
- () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions),
2053
- [hardConfig, softComponents, overrides, onActions]
2385
+ () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2386
+ [hardConfig, softComponents, overrides, onActions, useVersioning]
2054
2387
  );
2055
2388
  const [softConfig, setSoftConfig] = useState2(
2056
2389
  () => store.getState().softConfig
@@ -2058,6 +2391,53 @@ var SoftConfigProvider = ({
2058
2391
  const [internalSoftComponents, setSoftComponents] = useState2(
2059
2392
  () => store.getState().softComponents
2060
2393
  );
2394
+ const storeSetIframeDoc = useMemo2(
2395
+ () => store.getState().setIframeDoc,
2396
+ [store]
2397
+ );
2398
+ const validateAction = useMemo2(
2399
+ () => (action) => {
2400
+ const currentState = store.getState();
2401
+ if (currentState.state === "ready") {
2402
+ return true;
2403
+ }
2404
+ const editableIds = currentState.editableComponentIds;
2405
+ if (action.type === "replace") {
2406
+ if (action.data.props.id && editableIds.has(action.data.props.id)) {
2407
+ return true;
2408
+ }
2409
+ return false;
2410
+ }
2411
+ if (action.type === "insert" || action.type === "duplicate") {
2412
+ const zone = action.type === "insert" ? action.destinationZone : action.sourceZone;
2413
+ const parentId = zone == null ? void 0 : zone.split(":")[0];
2414
+ if (parentId && !editableIds.has(parentId)) {
2415
+ return false;
2416
+ }
2417
+ if (action.type === "insert") {
2418
+ const childId = action.id;
2419
+ if (childId) {
2420
+ currentState.addEditableComponentId(childId);
2421
+ }
2422
+ }
2423
+ return true;
2424
+ }
2425
+ if (action.type === "remove" || action.type === "move" || action.type === "reorder") {
2426
+ let parentId;
2427
+ if (action.type === "remove") {
2428
+ parentId = action.zone.split(":")[0];
2429
+ } else if (action.type === "move" || action.type === "reorder") {
2430
+ parentId = action.destinationZone.split(":")[0];
2431
+ }
2432
+ if (parentId && !editableIds.has(parentId)) {
2433
+ return false;
2434
+ }
2435
+ return true;
2436
+ }
2437
+ return true;
2438
+ },
2439
+ [store]
2440
+ );
2061
2441
  useEffect2(() => {
2062
2442
  const unsubscribe = store.subscribe(() => {
2063
2443
  setSoftConfig(store.getState().softConfig);
@@ -2067,7 +2447,33 @@ var SoftConfigProvider = ({
2067
2447
  unsubscribe();
2068
2448
  };
2069
2449
  }, [store]);
2070
- return /* @__PURE__ */ jsx7(appStoreContext.Provider, { value: store, children: children(softConfig, internalSoftComponents) });
2450
+ useEffect2(() => {
2451
+ const unsubscribe = store.subscribe((state, prevState) => {
2452
+ if (prevState && state.state === prevState.state && state.editableComponentIds === prevState.editableComponentIds) {
2453
+ return;
2454
+ }
2455
+ const doc = store.getState().getIframeDoc();
2456
+ if (!doc) return;
2457
+ if (state.state === "building") {
2458
+ setEditVisibility(doc, { mode: "build", editableIds: state.editableComponentIds });
2459
+ return;
2460
+ }
2461
+ if (state.state === "remodeling") {
2462
+ setEditVisibility(doc, { mode: "remodel", editableIds: state.editableComponentIds });
2463
+ return;
2464
+ }
2465
+ requestAnimationFrame(() => {
2466
+ const freshDoc = store.getState().getIframeDoc();
2467
+ if (freshDoc) {
2468
+ clearEditVisibility(freshDoc);
2469
+ }
2470
+ });
2471
+ });
2472
+ return () => {
2473
+ unsubscribe();
2474
+ };
2475
+ }, [store]);
2476
+ return /* @__PURE__ */ jsx7(appStoreContext.Provider, { value: store, children: children(softConfig, internalSoftComponents, storeSetIframeDoc, validateAction) });
2071
2477
  };
2072
2478
 
2073
2479
  // src/puck/actions/useBuild.tsx
@@ -2161,6 +2567,7 @@ var useRemodel = () => {
2161
2567
  const dispatch = useCustomPuck3((s) => s.dispatch);
2162
2568
  const status = useSoftConfig((s) => s.state);
2163
2569
  const softComponents = useSoftConfig((s) => s.softComponents);
2570
+ const refreshPermissions = useCustomPuck3((s) => s.refreshPermissions);
2164
2571
  const { triggerAction } = useActionEvent();
2165
2572
  const handleRemodel = (componentName) => {
2166
2573
  if (status !== "ready") {
@@ -2173,7 +2580,7 @@ var useRemodel = () => {
2173
2580
  return;
2174
2581
  }
2175
2582
  try {
2176
- remodel(history, selectedItem, itemSelector, dispatch);
2583
+ remodel(history, selectedItem, itemSelector, dispatch, refreshPermissions);
2177
2584
  void triggerAction({
2178
2585
  type: "remodel",
2179
2586
  payload: {
@@ -2202,6 +2609,7 @@ var useComplete = () => {
2202
2609
  const complete = useSoftConfig((s) => s.builder.complete);
2203
2610
  const appState = useCustomPuck4((s) => s.appState);
2204
2611
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2612
+ const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2205
2613
  const status = useSoftConfig((s) => s.state);
2206
2614
  const softComponents = useSoftConfig((s) => s.softComponents);
2207
2615
  const [newComponent, setNewComponent] = useState3(null);
@@ -2213,7 +2621,7 @@ var useComplete = () => {
2213
2621
  return null;
2214
2622
  }
2215
2623
  try {
2216
- const componentName = complete(appState, setHistories);
2624
+ const componentName = complete(appState, setHistories, getItemBySelector);
2217
2625
  setNewComponent(componentName);
2218
2626
  const componentData = appState.data.root;
2219
2627
  const softComponent = (_b = softComponents[componentName]) == null ? void 0 : _b.versions[(_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion];
@@ -2235,7 +2643,7 @@ var useComplete = () => {
2235
2643
  );
2236
2644
  return null;
2237
2645
  }
2238
- }, [complete, appState, setHistories, status, softComponents, triggerAction]);
2646
+ }, [complete, appState, setHistories, status, softComponents, triggerAction, getItemBySelector]);
2239
2647
  const canComplete = status === "building" || status === "remodeling";
2240
2648
  return { handleComplete, canComplete, newComponent, setNewComponent };
2241
2649
  };
@@ -2303,7 +2711,7 @@ var useInspect = (componentName) => {
2303
2711
  };
2304
2712
 
2305
2713
  // src/puck/actions/useDecompose.tsx
2306
- import { createUsePuck as createUsePuck7, walkTree as walkTree3 } from "@measured/puck";
2714
+ import { createUsePuck as createUsePuck7, walkTree as walkTree4 } from "@measured/puck";
2307
2715
  var useCustomPuck7 = createUsePuck7();
2308
2716
  var useDecompose = () => {
2309
2717
  const decompose = useSoftConfig((s) => s.builder.decompose);
@@ -2335,7 +2743,7 @@ var useDecompose = () => {
2335
2743
  notify.error("Nothing to decompose.");
2336
2744
  return;
2337
2745
  }
2338
- const newData = walkTree3(appState.data, config, (components) => {
2746
+ const newData = walkTree4(appState.data, config, (components) => {
2339
2747
  const index = components.findIndex((c) => c.props.id === target.props.id);
2340
2748
  if (index !== -1) {
2341
2749
  components.splice(index, 1, ...decomposedComponents);
@@ -2455,9 +2863,9 @@ var useSetDefaultVersion = () => {
2455
2863
  };
2456
2864
 
2457
2865
  // src/puck/overrides/Header.tsx
2458
- import { Button } from "@measured/puck";
2866
+ import { Button, createUsePuck as createUsePuck10 } from "@measured/puck";
2459
2867
 
2460
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\overrides\Header.module.css#css-module
2868
+ // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/Header.module.css#css-module
2461
2869
  var Header_module_default = { "Header": "_Header_19oj9_1" };
2462
2870
 
2463
2871
  // src/puck/actions/usePublish.tsx
@@ -2498,13 +2906,15 @@ var usePublish = () => {
2498
2906
  // src/puck/overrides/Header.tsx
2499
2907
  import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
2500
2908
  var getClassName2 = get_class_name_factory_default("Header", Header_module_default);
2909
+ var usePuck = createUsePuck10();
2501
2910
  var Header = ({
2502
2911
  onPublish,
2503
2912
  children
2504
2913
  }) => {
2505
- const { handleComplete, canComplete, newComponent, setNewComponent } = useComplete();
2914
+ const { handleComplete, newComponent, setNewComponent } = useComplete();
2506
2915
  const { handleCancel, canCancel } = useCancel();
2507
2916
  const { handlePublish } = usePublish();
2917
+ const puck = usePuck((s) => s.config);
2508
2918
  useInspect(newComponent);
2509
2919
  return /* @__PURE__ */ jsx8("div", { className: getClassName2(), children: canCancel ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
2510
2920
  /* @__PURE__ */ jsx8(Button, { onClick: handleCancel, children: "Cancel" }),
@@ -2536,22 +2946,41 @@ var Header = ({
2536
2946
  };
2537
2947
 
2538
2948
  // src/puck/overrides/ActionBar.tsx
2539
- import { ActionBar } from "@measured/puck";
2949
+ import { useMemo as useMemo3 } from "react";
2950
+ import { ActionBar, createUsePuck as createUsePuck11 } from "@measured/puck";
2540
2951
  import { Combine, ComponentIcon, EditIcon } from "lucide-react";
2541
2952
 
2542
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\overrides\ActionBar.module.css#css-module
2953
+ // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/ActionBar.module.css#css-module
2543
2954
  var ActionBar_module_default = { "ActionBar": "_ActionBar_pvuie_5", "ActionBar-label": "_ActionBar-label_pvuie_39", "ActionBar-action": "_ActionBar-action_pvuie_63", "ActionBar-group": "_ActionBar-group_pvuie_79" };
2544
2955
 
2545
2956
  // src/puck/overrides/ActionBar.tsx
2957
+ import { shallow } from "zustand/shallow";
2546
2958
  import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
2547
2959
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
2960
+ var usePuck2 = createUsePuck11();
2548
2961
  var ActionBarOverride = (props) => {
2549
- const { handleBuild, canBuild } = useBuild();
2550
- const { handleRemodel, canRemodel } = useRemodel();
2551
- const { handleDecompose, canDecompose } = useDecompose();
2552
- const softComponents = useSoftConfig((s) => s.softComponents);
2962
+ var _a;
2963
+ const { handleBuild } = useBuild();
2964
+ const { handleRemodel } = useRemodel();
2965
+ const { handleDecompose } = useDecompose();
2966
+ const overrides = useSoftConfig((s) => s.overrides);
2967
+ const softComponents = useSoftConfig((s) => s.softComponents, shallow);
2968
+ const editableIds = useSoftConfig((s) => s.editableComponentIds);
2969
+ const selectedItem = usePuck2((s) => s.selectedItem);
2553
2970
  const status = useSoftConfig((s) => s.state);
2554
- const isSoftComponent2 = Object.keys(softComponents || {}).includes(props.label);
2971
+ const softKeys = Object.keys(softComponents);
2972
+ const key = useMemo3(() => createComponentKeyFromName(props.label || "", overrides, {
2973
+ existingKeys: softKeys,
2974
+ state: status
2975
+ }), [
2976
+ props.label,
2977
+ overrides,
2978
+ softKeys,
2979
+ status
2980
+ ]);
2981
+ const isSoftComponent2 = softKeys.includes(key);
2982
+ const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
2983
+ const isEditable = Boolean(selectedId && editableIds.has(selectedId));
2555
2984
  return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
2556
2985
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
2557
2986
  props.parentAction,
@@ -2562,7 +2991,7 @@ var ActionBarOverride = (props) => {
2562
2991
  /* @__PURE__ */ jsx9(
2563
2992
  ActionBar.Action,
2564
2993
  {
2565
- onClick: () => handleRemodel(props.label),
2994
+ onClick: () => handleRemodel(key),
2566
2995
  label: "Remodel Soft Component",
2567
2996
  children: /* @__PURE__ */ jsx9(EditIcon, { size: 16 })
2568
2997
  }
@@ -2575,15 +3004,22 @@ var ActionBarOverride = (props) => {
2575
3004
  children: /* @__PURE__ */ jsx9(Combine, { size: 16 })
2576
3005
  }
2577
3006
  )
2578
- ] }) : /* @__PURE__ */ jsx9(ActionBar.Action, { onClick: handleBuild, label: "Build Soft Component", children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 }) }) : null,
2579
- props.children
3007
+ ] }) : /* @__PURE__ */ jsx9(
3008
+ ActionBar.Action,
3009
+ {
3010
+ onClick: handleBuild,
3011
+ label: "Build Soft Component",
3012
+ children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 })
3013
+ }
3014
+ ) : null,
3015
+ status !== "ready" && !isEditable ? null : props.children
2580
3016
  ] })
2581
3017
  ] }) });
2582
3018
  };
2583
3019
 
2584
3020
  // src/puck/overrides/ComponentItem.tsx
2585
3021
  import { useState as useState5 } from "react";
2586
- import { Button as Button2, IconButton } from "@measured/puck";
3022
+ import { Button as Button2, IconButton, createUsePuck as createUsePuck12 } from "@measured/puck";
2587
3023
  import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
2588
3024
 
2589
3025
  // src/puck/lib/confirm.ts
@@ -2603,14 +3039,14 @@ var confirm = (message) => __async(null, null, function* () {
2603
3039
  }
2604
3040
  });
2605
3041
 
2606
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\overrides\ComponentItem.module.css#css-module
2607
- var ComponentItem_module_default = { "ComponentItem": "_ComponentItem_lp9eh_1", "ComponentItem-content": "_ComponentItem-content_lp9eh_14", "ComponentItem-name": "_ComponentItem-name_lp9eh_24", "ComponentItem-version": "_ComponentItem-version_lp9eh_28", "ComponentItem-actions": "_ComponentItem-actions_lp9eh_33", "ComponentItem-settingsButton": "_ComponentItem-settingsButton_lp9eh_39", "ComponentItem-grip": "_ComponentItem-grip_lp9eh_49", "ComponentItem-modal": "_ComponentItem-modal_lp9eh_56", "ComponentItem-modalHeader": "_ComponentItem-modalHeader_lp9eh_63", "ComponentItem-modalTitle": "_ComponentItem-modalTitle_lp9eh_68", "ComponentItem-modalSubtitle": "_ComponentItem-modalSubtitle_lp9eh_75", "ComponentItem-modalBody": "_ComponentItem-modalBody_lp9eh_81", "ComponentItem-section": "_ComponentItem-section_lp9eh_90", "ComponentItem-sectionTitle": "_ComponentItem-sectionTitle_lp9eh_96", "ComponentItem-sectionDescription": "_ComponentItem-sectionDescription_lp9eh_103", "ComponentItem-versionList": "_ComponentItem-versionList_lp9eh_109", "ComponentItem-versionRow": "_ComponentItem-versionRow_lp9eh_115", "ComponentItem-versionRow--isDefault": "_ComponentItem-versionRow--isDefault_lp9eh_126", "ComponentItem-versionRow--isMarkedForDeletion": "_ComponentItem-versionRow--isMarkedForDeletion_lp9eh_131", "ComponentItem-versionInfo": "_ComponentItem-versionInfo_lp9eh_136", "ComponentItem-versionNumber": "_ComponentItem-versionNumber_lp9eh_143", "ComponentItem-defaultBadge": "_ComponentItem-defaultBadge_lp9eh_149", "ComponentItem-deleteBadge": "_ComponentItem-deleteBadge_lp9eh_160", "ComponentItem-versionActions": "_ComponentItem-versionActions_lp9eh_171", "ComponentItem-migrationOptions": "_ComponentItem-migrationOptions_lp9eh_177", "ComponentItem-select": "_ComponentItem-select_lp9eh_181", "ComponentItem-modalFooter": "_ComponentItem-modalFooter_lp9eh_202", "ComponentItem-footerLeft": "_ComponentItem-footerLeft_lp9eh_211", "ComponentItem-footerRight": "_ComponentItem-footerRight_lp9eh_216" };
3042
+ // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/ComponentItem.module.css#css-module
3043
+ var ComponentItem_module_default = { "ComponentItem": "_ComponentItem_1kbi2_1", "ComponentItem--insertDisabled": "_ComponentItem--insertDisabled_1kbi2_14", "ComponentItem-content": "_ComponentItem-content_1kbi2_21", "ComponentItem-name": "_ComponentItem-name_1kbi2_31", "ComponentItem-version": "_ComponentItem-version_1kbi2_35", "ComponentItem-actions": "_ComponentItem-actions_1kbi2_40", "ComponentItem-settingsButton": "_ComponentItem-settingsButton_1kbi2_46", "ComponentItem-grip": "_ComponentItem-grip_1kbi2_56", "ComponentItem-modal": "_ComponentItem-modal_1kbi2_63", "ComponentItem-modalHeader": "_ComponentItem-modalHeader_1kbi2_70", "ComponentItem-modalTitle": "_ComponentItem-modalTitle_1kbi2_75", "ComponentItem-modalSubtitle": "_ComponentItem-modalSubtitle_1kbi2_82", "ComponentItem-modalBody": "_ComponentItem-modalBody_1kbi2_88", "ComponentItem-section": "_ComponentItem-section_1kbi2_97", "ComponentItem-sectionTitle": "_ComponentItem-sectionTitle_1kbi2_103", "ComponentItem-sectionDescription": "_ComponentItem-sectionDescription_1kbi2_110", "ComponentItem-versionList": "_ComponentItem-versionList_1kbi2_116", "ComponentItem-versionRow": "_ComponentItem-versionRow_1kbi2_122", "ComponentItem-versionRow--isDefault": "_ComponentItem-versionRow--isDefault_1kbi2_133", "ComponentItem-versionRow--isMarkedForDeletion": "_ComponentItem-versionRow--isMarkedForDeletion_1kbi2_138", "ComponentItem-versionInfo": "_ComponentItem-versionInfo_1kbi2_143", "ComponentItem-versionNumber": "_ComponentItem-versionNumber_1kbi2_150", "ComponentItem-defaultBadge": "_ComponentItem-defaultBadge_1kbi2_156", "ComponentItem-deleteBadge": "_ComponentItem-deleteBadge_1kbi2_167", "ComponentItem-versionActions": "_ComponentItem-versionActions_1kbi2_178", "ComponentItem-migrationOptions": "_ComponentItem-migrationOptions_1kbi2_184", "ComponentItem-select": "_ComponentItem-select_1kbi2_188", "ComponentItem-modalFooter": "_ComponentItem-modalFooter_1kbi2_209", "ComponentItem-footerLeft": "_ComponentItem-footerLeft_1kbi2_218", "ComponentItem-footerRight": "_ComponentItem-footerRight_1kbi2_223" };
2608
3044
 
2609
3045
  // src/puck/components/modal/index.tsx
2610
3046
  import { useEffect as useEffect4, useState as useState4 } from "react";
2611
3047
  import { createPortal } from "react-dom";
2612
3048
 
2613
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\components\modal\styles.module.css#css-module
3049
+ // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css#css-module
2614
3050
  var styles_module_default2 = { "Modal": "_Modal_pvj02_1", "Modal--isOpen": "_Modal--isOpen_pvj02_29", "Modal-inner": "_Modal-inner_pvj02_37" };
2615
3051
 
2616
3052
  // src/puck/components/modal/index.tsx
@@ -2642,12 +3078,18 @@ var Modal = ({
2642
3078
  };
2643
3079
 
2644
3080
  // src/puck/overrides/ComponentItem.tsx
3081
+ import { shallow as shallow2 } from "zustand/shallow";
2645
3082
  import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
2646
3083
  var getClassName5 = get_class_name_factory_default("ComponentItem", ComponentItem_module_default);
3084
+ var usePuck3 = createUsePuck12();
2647
3085
  var ComponentItem = (props) => {
3086
+ const componentMeta = useSoftConfig((s) => s.softComponents[props.name]);
3087
+ const displayName = (componentMeta == null ? void 0 : componentMeta.name) || props.name;
2648
3088
  const softComponents = new Set(
2649
- Object.keys(useSoftConfig((s) => s.softComponents))
3089
+ Object.keys(useSoftConfig((s) => s.softComponents, shallow2))
2650
3090
  );
3091
+ const getPermissions = usePuck3((s) => s.getPermissions);
3092
+ const insertAllowed = getPermissions({ type: props.name }).insert;
2651
3093
  const removeSoftComponentVersion = useSoftConfig(
2652
3094
  (s) => s.removeSoftComponentVersion
2653
3095
  );
@@ -2660,6 +3102,7 @@ var ComponentItem = (props) => {
2660
3102
  /* @__PURE__ */ new Set()
2661
3103
  );
2662
3104
  const [migrateVersionMap, setMigrateVersionMap] = useState5({});
3105
+ const useVersioning = useSoftConfig((s) => s.showVersionFields);
2663
3106
  const versions = getVersions(props.name);
2664
3107
  const defaultVersion = getDefaultVersion(props.name);
2665
3108
  const handleApply = () => __async(null, null, function* () {
@@ -2704,7 +3147,7 @@ var ComponentItem = (props) => {
2704
3147
  };
2705
3148
  const handleDemolishClick = () => __async(null, null, function* () {
2706
3149
  const confirmed = yield confirm(
2707
- `Demolish "${props.name}" entirely? This will remove all versions.`
3150
+ `Demolish "${displayName}" entirely? This will remove all versions.`
2708
3151
  );
2709
3152
  if (confirmed) {
2710
3153
  handleDemolish(props.name);
@@ -2717,13 +3160,13 @@ var ComponentItem = (props) => {
2717
3160
  /* @__PURE__ */ jsxs4(
2718
3161
  "div",
2719
3162
  {
2720
- className: getClassName5(),
3163
+ className: getClassName5({ insertDisabled: !insertAllowed }),
2721
3164
  onMouseEnter: () => setIsHovering(true),
2722
3165
  onMouseLeave: () => setIsHovering(false),
2723
3166
  children: [
2724
3167
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
2725
- /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: props.name }),
2726
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
3168
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: displayName }),
3169
+ useVersioning && /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
2727
3170
  "v",
2728
3171
  defaultVersion
2729
3172
  ] })
@@ -2739,7 +3182,7 @@ var ComponentItem = (props) => {
2739
3182
  setIsEditing(true);
2740
3183
  setSelectedVersion(defaultVersion || "");
2741
3184
  },
2742
- children: /* @__PURE__ */ jsx11(Cog, { size: 14 })
3185
+ children: /* @__PURE__ */ jsx11(Cog, { size: 12 })
2743
3186
  }
2744
3187
  ) }),
2745
3188
  /* @__PURE__ */ jsx11("div", { className: getClassName5("grip"), children: /* @__PURE__ */ jsx11(GripVertical, { size: 16 }) })
@@ -2749,10 +3192,10 @@ var ComponentItem = (props) => {
2749
3192
  ),
2750
3193
  /* @__PURE__ */ jsx11(Modal, { isOpen: isEditing, onClose: handleCancel, children: /* @__PURE__ */ jsxs4("div", { className: getClassName5("modal"), children: [
2751
3194
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalHeader"), children: [
2752
- /* @__PURE__ */ jsx11("h2", { className: getClassName5("modalTitle"), children: props.name }),
2753
- /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Manage versions and settings" })
3195
+ /* @__PURE__ */ jsx11("h2", { className: getClassName5("modalTitle"), children: displayName }),
3196
+ /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Component Settings" })
2754
3197
  ] }),
2755
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalBody"), children: [
3198
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("modalBody"), children: useVersioning ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2756
3199
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2757
3200
  /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Versions" }),
2758
3201
  /* @__PURE__ */ jsx11("div", { className: getClassName5("versionList"), children: versions.map((version) => {
@@ -2761,52 +3204,30 @@ var ComponentItem = (props) => {
2761
3204
  let rowClass = getClassName5("versionRow");
2762
3205
  if (isDefault) rowClass += " " + getClassName5("versionRow--isDefault");
2763
3206
  if (isMarkedForDeletion) rowClass += " " + getClassName5("versionRow--isMarkedForDeletion");
2764
- return /* @__PURE__ */ jsxs4(
2765
- "div",
2766
- {
2767
- className: rowClass,
2768
- children: [
2769
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionInfo"), children: [
2770
- /* @__PURE__ */ jsxs4("span", { className: getClassName5("versionNumber"), children: [
2771
- "Version ",
2772
- version
2773
- ] }),
2774
- isDefault && /* @__PURE__ */ jsx11("span", { className: getClassName5("defaultBadge"), children: "Default" }),
2775
- isMarkedForDeletion && /* @__PURE__ */ jsx11("span", { className: getClassName5("deleteBadge"), children: "Marked for deletion" })
2776
- ] }),
2777
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionActions"), children: [
2778
- !isDefault && !isMarkedForDeletion && /* @__PURE__ */ jsx11(
2779
- Button2,
2780
- {
2781
- variant: "secondary",
2782
- onClick: () => setSelectedVersion(version),
2783
- children: "Set as Default"
2784
- }
2785
- ),
2786
- /* @__PURE__ */ jsx11(
2787
- Button2,
2788
- {
2789
- variant: isMarkedForDeletion ? "secondary" : "secondary",
2790
- onClick: () => toggleVersionForDeletion(version),
2791
- children: isMarkedForDeletion ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2792
- /* @__PURE__ */ jsx11(X, { size: 14 }),
2793
- "Undo"
2794
- ] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
2795
- /* @__PURE__ */ jsx11(Trash2, { size: 14 }),
2796
- "Delete"
2797
- ] })
2798
- }
2799
- )
2800
- ] })
2801
- ]
2802
- },
2803
- version
2804
- );
3207
+ return /* @__PURE__ */ jsxs4("div", { className: rowClass, children: [
3208
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionInfo"), children: [
3209
+ /* @__PURE__ */ jsxs4("span", { className: getClassName5("versionNumber"), children: [
3210
+ "Version ",
3211
+ version
3212
+ ] }),
3213
+ isDefault && /* @__PURE__ */ jsx11("span", { className: getClassName5("defaultBadge"), children: "Default" }),
3214
+ isMarkedForDeletion && /* @__PURE__ */ jsx11("span", { className: getClassName5("deleteBadge"), children: "Marked for deletion" })
3215
+ ] }),
3216
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionActions"), children: [
3217
+ !isDefault && !isMarkedForDeletion && /* @__PURE__ */ jsx11(Button2, { variant: "secondary", onClick: () => setSelectedVersion(version), children: "Set as Default" }),
3218
+ /* @__PURE__ */ jsx11(Button2, { variant: "secondary", onClick: () => toggleVersionForDeletion(version), children: isMarkedForDeletion ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
3219
+ /* @__PURE__ */ jsx11(X, { size: 14 }),
3220
+ " Undo"
3221
+ ] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
3222
+ /* @__PURE__ */ jsx11(Trash2, { size: 14 }),
3223
+ " Delete"
3224
+ ] }) })
3225
+ ] })
3226
+ ] }, version);
2805
3227
  }) })
2806
3228
  ] }),
2807
3229
  versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2808
3230
  /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
2809
- /* @__PURE__ */ jsx11("p", { className: getClassName5("sectionDescription"), children: "Choose what to do with components using deleted versions" }),
2810
3231
  /* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsxs4(
2811
3232
  "select",
2812
3233
  {
@@ -2829,30 +3250,26 @@ var ComponentItem = (props) => {
2829
3250
  }
2830
3251
  ) })
2831
3252
  ] })
2832
- ] }),
3253
+ ] }) : /* @__PURE__ */ jsx11("div", { className: getClassName5("section"), children: /* @__PURE__ */ jsxs4("p", { children: [
3254
+ "Manage high-level settings for the ",
3255
+ /* @__PURE__ */ jsx11("strong", { children: displayName }),
3256
+ " component."
3257
+ ] }) }) }),
2833
3258
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalFooter"), children: [
2834
3259
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("footerLeft"), children: [
2835
- /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
3260
+ useVersioning ? /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
2836
3261
  /* @__PURE__ */ jsx11(Check, { size: 16 }),
2837
- "Apply Changes"
2838
- ] }),
2839
- /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleCancel, children: [
3262
+ " Apply Changes"
3263
+ ] }) : /* @__PURE__ */ jsx11(Button2, { size: "medium", onClick: handleCancel, children: "Close" }),
3264
+ useVersioning && /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleCancel, children: [
2840
3265
  /* @__PURE__ */ jsx11(X, { size: 16 }),
2841
- "Cancel"
3266
+ " Cancel"
2842
3267
  ] })
2843
3268
  ] }),
2844
- /* @__PURE__ */ jsx11("div", { className: getClassName5("footerRight"), children: /* @__PURE__ */ jsxs4(
2845
- Button2,
2846
- {
2847
- size: "medium",
2848
- variant: "secondary",
2849
- onClick: handleDemolishClick,
2850
- children: [
2851
- /* @__PURE__ */ jsx11(Trash2, { size: 16 }),
2852
- "Demolish Component"
2853
- ]
2854
- }
2855
- ) })
3269
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("footerRight"), children: /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleDemolishClick, children: [
3270
+ /* @__PURE__ */ jsx11(Trash2, { size: 16 }),
3271
+ " Demolish Component"
3272
+ ] }) })
2856
3273
  ] })
2857
3274
  ] }) })
2858
3275
  ] });
@@ -2860,6 +3277,27 @@ var ComponentItem = (props) => {
2860
3277
  return /* @__PURE__ */ jsx11(Fragment5, { children: props.children });
2861
3278
  };
2862
3279
 
3280
+ // src/puck/lib/action-callback.ts
3281
+ var createActionCallback = (validateAction, undo) => {
3282
+ return (action) => {
3283
+ const isValid = validateAction(action);
3284
+ if (!isValid) {
3285
+ notify.error(
3286
+ "Editing outside the soft component is not allowed when you are editing component definition."
3287
+ );
3288
+ if (typeof requestAnimationFrame === "function") {
3289
+ requestAnimationFrame(() => {
3290
+ requestAnimationFrame(() => {
3291
+ undo();
3292
+ });
3293
+ });
3294
+ } else {
3295
+ setTimeout(() => undo(), 0);
3296
+ }
3297
+ }
3298
+ };
3299
+ };
3300
+
2863
3301
  // src/puck/lib/dissolve-all-soft-components.ts
2864
3302
  function extractDependencies2(softComponents, componentName, version) {
2865
3303
  var _a, _b;
@@ -3068,6 +3506,7 @@ export {
3068
3506
  Modal,
3069
3507
  SoftConfigProvider,
3070
3508
  confirm,
3509
+ createActionCallback,
3071
3510
  createSoftConfigStore,
3072
3511
  createUseSoftConfig,
3073
3512
  notify,