@netlisian/softconfig 0.0.11 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,8 +307,11 @@ 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: {
312
+ // _editor: {
313
+ // type: "slot",
314
+ // },
303
315
  _name: {
304
316
  type: "text",
305
317
  label: "Soft Component Name"
@@ -346,7 +358,7 @@ var builderRootConfig = (config, overrides, editingComponent) => ({
346
358
  )
347
359
  };
348
360
  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)) {
361
+ 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
362
  const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
351
363
  delete fields._version;
352
364
  fields._version = {
@@ -368,6 +380,8 @@ var builderRootConfig = (config, overrides, editingComponent) => ({
368
380
  }
369
381
  ]
370
382
  };
383
+ } else {
384
+ delete fields._version;
371
385
  }
372
386
  return fields;
373
387
  },
@@ -386,80 +400,78 @@ var builderRootConfig = (config, overrides, editingComponent) => ({
386
400
  const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
387
401
  const setVersion = useSoftConfig((s) => s.builder.setVersion);
388
402
  const state = useSoftConfig((s) => s.state);
403
+ const [debouncedFieldSettings] = useDebounce(fieldSettings, 500);
389
404
  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
- }
405
+ if (!debouncedFieldSettings || Object.keys(debouncedFieldSettings).length === 0) return;
406
+ walkTree(
407
+ data,
408
+ {
409
+ components: config.components
410
+ },
411
+ (content) => content.map((child) => {
412
+ var _a;
413
+ const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
414
+ if (map.length) {
415
+ map.forEach(({ from, to, transform }) => {
416
+ if (!from || !to) return;
417
+ const fromPaths = Array.isArray(from) ? from : [from];
418
+ const toPaths = Array.isArray(to) ? to : [to];
419
+ const inputValues = fromPaths.map(
420
+ (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
421
+ );
422
+ let value = transform ? transform(
423
+ inputValues.map((v) => v == null ? void 0 : v.defaultValue),
424
+ child.props
425
+ ) : inputValues[0];
426
+ if (Array.isArray(value)) {
427
+ value.forEach((val, i) => {
428
+ if (toPaths[i]) {
429
+ const originalValue = getFieldSettingsByPath(
430
+ child.props,
431
+ toPaths[i]
432
+ );
433
+ if (originalValue !== val) {
434
+ const itemSelector = getSelectorForId(child.props.id);
435
+ if (!itemSelector) return;
436
+ setPropertyByPath(child.props, toPaths[i], val);
437
+ dispatch({
438
+ type: "replace",
439
+ data: child,
440
+ destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
441
+ destinationZone: itemSelector == null ? void 0 : itemSelector.zone
442
+ });
430
443
  }
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
444
  }
445
+ });
446
+ } else if (toPaths[0]) {
447
+ const setting = getFieldSettingsByPath(
448
+ debouncedFieldSettings,
449
+ fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
450
+ );
451
+ const defaultValue = setting == null ? void 0 : setting.defaultValue;
452
+ const originalValue = getFieldSettingsByPath(
453
+ child.props,
454
+ toPaths[0]
455
+ );
456
+ const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
457
+ if (originalValue !== finalValue) {
458
+ const itemSelector = getSelectorForId(child.props.id);
459
+ if (!itemSelector) return;
460
+ setPropertyByPath(child.props, toPaths[0], finalValue);
461
+ dispatch({
462
+ type: "replace",
463
+ data: child,
464
+ destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
465
+ destinationZone: itemSelector == null ? void 0 : itemSelector.zone
466
+ });
454
467
  }
455
- });
456
- }
457
- return child;
458
- })
459
- );
460
- }, 300);
461
- return () => clearTimeout(propagateChanges);
462
- }, [fieldSettings]);
468
+ }
469
+ });
470
+ }
471
+ return child;
472
+ })
473
+ );
474
+ }, [debouncedFieldSettings, data, dispatch, getSelectorForId, props._fieldSettings]);
463
475
  useEffect(() => {
464
476
  var _a;
465
477
  if (state !== "remodeling") return;
@@ -544,7 +556,7 @@ var getClassNameFactory = (rootClass, styles, config = { baseClass: "" }) => (op
544
556
  };
545
557
  var get_class_name_factory_default = getClassNameFactory;
546
558
 
547
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\components\error-boundary\styles.module.css#css-module
559
+ // css-module:/media/osamu/3628738E28734BBD/osamuProjects/netlisian/packages/soft-config/src/puck/components/error-boundary/styles.module.css#css-module
548
560
  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
561
 
550
562
  // src/puck/components/error-boundary/index.tsx
@@ -603,153 +615,153 @@ var ErrorBoundary = class extends Component {
603
615
 
604
616
  // src/puck/lib/builder/builder-config.tsx
605
617
  import { jsx as jsx4 } from "react/jsx-runtime";
606
- var builderConfig = (config, overrides, editingComponent) => ({
607
- root: builderRootConfig(config, overrides, editingComponent),
618
+ var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents) => ({
619
+ root: builderRootConfig(config, overrides, editingComponent, showVersionFields),
608
620
  components: Object.entries(__spreadValues({}, config.components)).reduce(
609
621
  (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
- } : {
622
+ const tempComponent = __spreadProps(__spreadValues({}, component), {
623
+ permissions: {
624
+ insert: editingComponent !== name && !(dependents == null ? void 0 : dependents.has(name))
625
+ },
626
+ resolveFields(data, params) {
627
+ return __async(this, null, function* () {
628
+ let fields = {};
629
+ if (!fields._slot) {
630
+ const slotFields = Object.entries(params.fields).filter(
631
+ ([_, field]) => field.type === "slot"
632
+ );
633
+ if (slotFields.length)
634
+ fields._slot = {
678
635
  type: "array",
679
- label: "Dynamic Field Map",
636
+ label: "Enable Dropdown Slots",
637
+ getItemSummary(item, index) {
638
+ return item.slot || `Slot ${(index || 0) + 1}`;
639
+ },
680
640
  arrayFields: {
681
- from: {
641
+ slot: {
682
642
  type: "select",
683
- label: "From",
643
+ label: "Slot",
684
644
  options: [
685
- { label: "Select a field", value: "" },
686
- ...fromOptions.map(({ label, value }) => ({
687
- label,
688
- value
645
+ { label: "Select a slot", value: "" },
646
+ ...slotFields.filter(
647
+ ([fieldName, field]) => {
648
+ var _a2;
649
+ return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
650
+ (s) => s.slot === fieldName
651
+ );
652
+ }
653
+ ).map(([fieldName, field]) => ({
654
+ label: field.label || fieldName,
655
+ value: fieldName
689
656
  }))
690
657
  ]
691
658
  },
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
- ]
659
+ name: {
660
+ type: "text",
661
+ label: "Name",
662
+ placeholder: "Optional Slot Name"
702
663
  }
703
664
  }
704
665
  };
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) {
666
+ }
667
+ const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
668
+ if (!fields._map) {
669
+ const rootProps = getRootProps(params.appState);
670
+ const fromOptions = generateDynamicFieldOptions(
671
+ (rootProps == null ? void 0 : rootProps._fields) || [],
672
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
673
+ );
674
+ const toOptions = generateFieldOptions(defaultFields, []);
675
+ fields._map = overrides.map ? {
676
+ type: "custom",
677
+ render: ({ value, onChange, id }) => {
678
+ const toOptions2 = generateFieldOptions(defaultFields, []);
679
+ const rootProps2 = getRootProps(params.appState);
680
+ return overrides.map({
681
+ rootProps: rootProps2,
682
+ value,
683
+ onChange,
684
+ id,
685
+ props: data.props || {},
686
+ fromOptions,
687
+ toOptions: toOptions2
688
+ });
689
+ }
690
+ } : {
691
+ type: "array",
692
+ label: "Dynamic Field Map",
693
+ arrayFields: {
694
+ from: {
695
+ type: "select",
696
+ label: "From",
697
+ options: [
698
+ { label: "Select a field", value: "" },
699
+ ...fromOptions.map(({ label, value }) => ({
700
+ label,
701
+ value
702
+ }))
703
+ ]
704
+ },
705
+ to: {
706
+ type: "select",
707
+ label: "To",
708
+ options: [
709
+ { label: "Select a field", value: "" },
710
+ ...toOptions.map(({ label, value }) => ({
711
+ label,
712
+ value
713
+ }))
714
+ ]
715
+ }
716
+ }
717
+ };
718
+ }
719
+ fields = __spreadValues(__spreadValues({}, fields), defaultFields);
720
+ return fields;
721
+ });
722
+ },
723
+ resolveData: ({ props }, { lastData }) => {
724
+ var _a2;
725
+ const _map = props._map || [];
726
+ const readOnlyFields = _map.flatMap((item) => item.to);
727
+ if (_map.length) {
728
+ return {
729
+ props,
730
+ readOnly: readOnlyFields.reduce(
731
+ (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
732
+ {}
733
+ )
734
+ };
735
+ }
736
+ const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
737
+ if (prevMap && prevMap.length === 1) {
738
+ const lastField = prevMap[0].to;
739
+ if (typeof lastField === "string") {
740
+ return {
741
+ props,
742
+ readOnly: { [lastField]: false }
743
+ };
744
+ }
745
+ if (Array.isArray(lastField)) {
715
746
  return {
716
747
  props,
717
- readOnly: readOnlyFields.reduce(
718
- (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
748
+ readOnly: lastField.reduce(
749
+ (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
719
750
  {}
720
751
  )
721
752
  };
722
753
  }
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
754
  }
750
- });
751
- acc[name] = tempComponent;
752
- }
755
+ return {
756
+ props,
757
+ readOnly: {}
758
+ };
759
+ },
760
+ render: (props) => {
761
+ return /* @__PURE__ */ jsx4(ErrorBoundary, { children: component.render(props) });
762
+ }
763
+ });
764
+ acc[name] = tempComponent;
753
765
  return acc;
754
766
  },
755
767
  {}
@@ -879,14 +891,14 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
879
891
  {}
880
892
  )) || {};
881
893
  };
882
- var softComponentFromAppState = (appState, configComponents) => {
894
+ var softComponentFromAppState = (appState, configComponents, editedItem) => {
883
895
  var _a;
884
896
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
885
897
  const fields = rootProps._fields || [];
886
898
  const field_settings = rootProps._fieldSettings || {};
887
899
  const slots = {};
888
900
  const components = getSubComponents(
889
- appState.data.content || [],
901
+ [editedItem],
890
902
  configComponents,
891
903
  field_settings,
892
904
  slots
@@ -1076,6 +1088,7 @@ var rootDroppableId = `${rootAreaId}:${rootZone}`;
1076
1088
  // src/puck/components/soft-render/index.tsx
1077
1089
  import { useMemo, useRef } from "react";
1078
1090
  import { v4 as uuidv42 } from "uuid";
1091
+ import equal from "fast-deep-equal";
1079
1092
  import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
1080
1093
  function SoftRender({
1081
1094
  softComponentFields,
@@ -1087,11 +1100,10 @@ function SoftRender({
1087
1100
  }) {
1088
1101
  const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1089
1102
  const mapCacheRef = useRef(/* @__PURE__ */ new Map());
1090
- const prevPropsRef = useRef("");
1091
- const propsSnapshot = JSON.stringify(props);
1092
- if (prevPropsRef.current !== propsSnapshot) {
1103
+ const prevPropsRef = useRef(null);
1104
+ if (!equal(prevPropsRef.current, props)) {
1093
1105
  mapCacheRef.current.clear();
1094
- prevPropsRef.current = propsSnapshot;
1106
+ prevPropsRef.current = props;
1095
1107
  }
1096
1108
  const subComponentRootProps = useMemo(
1097
1109
  () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
@@ -1103,10 +1115,6 @@ function SoftRender({
1103
1115
  ),
1104
1116
  [softComponentFields, props]
1105
1117
  );
1106
- const valuesToUpdateKey = useMemo(
1107
- () => JSON.stringify(subComponentRootProps),
1108
- [subComponentRootProps]
1109
- );
1110
1118
  return /* @__PURE__ */ jsx5(Fragment2, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1111
1119
  var _a2;
1112
1120
  const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
@@ -1133,7 +1141,7 @@ function SoftRender({
1133
1141
  }
1134
1142
  return propValue;
1135
1143
  });
1136
- const cacheKey = JSON.stringify(inputValues);
1144
+ const cacheKey = inputValues.map((v, i) => `${i}:${typeof v === "object" ? JSON.stringify(v) : v}`).join("|");
1137
1145
  let result = mapCacheRef.current.get(cacheKey);
1138
1146
  if (!result) {
1139
1147
  const runner = transform;
@@ -1160,7 +1168,7 @@ function SoftRender({
1160
1168
  const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1161
1169
  resolvedProps[slotKey] = useMemo(
1162
1170
  () => rest[slotName] || (() => null),
1163
- [slotName]
1171
+ [slotName, rest[slotName]]
1164
1172
  );
1165
1173
  } else {
1166
1174
  resolvedProps[slotKey] = useMemo(() => {
@@ -1181,7 +1189,7 @@ function SoftRender({
1181
1189
  slotKey
1182
1190
  ) });
1183
1191
  };
1184
- }, [valuesToUpdateKey]);
1192
+ }, [slotKey, subComponentRootProps]);
1185
1193
  }
1186
1194
  }
1187
1195
  }
@@ -1200,7 +1208,7 @@ function SoftRender({
1200
1208
 
1201
1209
  // src/puck/lib/create-versioned-component-config.tsx
1202
1210
  import { jsx as jsx6 } from "react/jsx-runtime";
1203
- var createVersionedComponentConfig = (componentName, version, allVersions, config, softComponents, defaultProps) => {
1211
+ var createVersionedComponentConfig = (componentName, version, allVersions, config, softComponents, defaultProps, showVersioning = true) => {
1204
1212
  var _a, _b;
1205
1213
  const softConfig = config;
1206
1214
  return {
@@ -1218,16 +1226,18 @@ var createVersionedComponentConfig = (componentName, version, allVersions, confi
1218
1226
  var _a2, _b2;
1219
1227
  const selectedVersion = ((_a2 = data.props) == null ? void 0 : _a2.version) || version;
1220
1228
  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: {
1229
+ let fields = {};
1230
+ if (showVersioning) {
1231
+ fields.version = {
1226
1232
  label: "Version",
1227
1233
  type: "select",
1228
1234
  options: allVersions.map((v) => ({ label: v, value: v }))
1229
- }
1230
- }, fieldsWithoutSlots);
1235
+ };
1236
+ }
1237
+ Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").forEach(([key, field]) => {
1238
+ fields[key] = field;
1239
+ });
1240
+ return fields;
1231
1241
  },
1232
1242
  render: (props) => {
1233
1243
  var _a2;
@@ -1364,14 +1374,29 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1364
1374
  props: {
1365
1375
  _name: "New Soft Component"
1366
1376
  }
1367
- },
1368
- content: [__spreadValues({}, selectedItem)]
1377
+ }
1378
+ // content: [{ ...selectedItem }],
1369
1379
  })
1370
1380
  })
1371
1381
  });
1372
1382
  const config = __spreadValues({}, get().softConfig);
1373
1383
  const overrides = get().overrides;
1374
- const buildConfig = builderConfig(config, overrides);
1384
+ const buildConfig = builderConfig(config, overrides, selectedItem.type, get().showVersionFields);
1385
+ const editableIds = /* @__PURE__ */ new Set([selectedItem.props.id]);
1386
+ const initialContent = [__spreadValues({}, selectedItem)];
1387
+ walkTree3(
1388
+ {
1389
+ root: {},
1390
+ content: initialContent
1391
+ },
1392
+ { components: config.components },
1393
+ (components) => {
1394
+ components.forEach((comp) => {
1395
+ editableIds.add(comp.props.id);
1396
+ });
1397
+ return components;
1398
+ }
1399
+ );
1375
1400
  set((s) => __spreadProps(__spreadValues({}, s), {
1376
1401
  softConfig: buildConfig,
1377
1402
  storedConfig: config,
@@ -1380,6 +1405,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1380
1405
  index: itemSelector.index,
1381
1406
  zone: itemSelector.zone || rootDroppableId
1382
1407
  },
1408
+ editingComponentId: selectedItem.props.id,
1409
+ editableComponentIds: editableIds,
1383
1410
  state: "building"
1384
1411
  }));
1385
1412
  setTimeout(
@@ -1426,16 +1453,48 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1426
1453
  selectedItem.props,
1427
1454
  get().softConfig.components
1428
1455
  );
1456
+ const config = __spreadValues({}, get().softConfig);
1457
+ const overrides = get().overrides;
1458
+ const getStore = () => get();
1459
+ const getEditableIds = () => getStore().editableComponentIds;
1460
+ const dependents = get().dependencyGraph.get(softComponentName) || /* @__PURE__ */ new Set();
1461
+ const buildConfig = builderConfig(config, overrides, softComponentName, get().showVersionFields, dependents);
1462
+ const editableIds = /* @__PURE__ */ new Set([]);
1463
+ const decomposedComponents = get().builder.decompose(selectedItem);
1464
+ walkTree3(
1465
+ { root: {}, content: decomposedComponents || [] },
1466
+ { components: config.components },
1467
+ (components) => {
1468
+ components.forEach((comp) => {
1469
+ editableIds.add(comp.props.id);
1470
+ });
1471
+ return components;
1472
+ }
1473
+ );
1429
1474
  puckDispatch({
1430
1475
  type: "setData",
1431
- data: (previous) => __spreadProps(__spreadValues({}, previous), {
1476
+ data: (prevData) => ({
1432
1477
  root: __spreadProps(__spreadValues({}, root), { _versions: versions }),
1433
- content: content || []
1478
+ content: walkTree3(__spreadValues({}, prevData), __spreadValues({}, config), (components) => {
1479
+ const next = components.map((component) => __spreadProps(__spreadValues({}, component), {
1480
+ props: __spreadValues({}, component.props)
1481
+ }));
1482
+ const index = next.findIndex(
1483
+ (component) => component.props.id === selectedItem.props.id
1484
+ );
1485
+ if (index !== -1) {
1486
+ next.splice(
1487
+ index,
1488
+ 1,
1489
+ ...decomposedComponents.map((component) => __spreadProps(__spreadValues({}, component), {
1490
+ props: __spreadValues({}, component.props)
1491
+ }))
1492
+ );
1493
+ }
1494
+ return next;
1495
+ }).content
1434
1496
  })
1435
1497
  });
1436
- const config = __spreadValues({}, get().softConfig);
1437
- const overrides = get().overrides;
1438
- const buildConfig = builderConfig(config, overrides, softComponentName);
1439
1498
  set((s) => __spreadProps(__spreadValues({}, s), {
1440
1499
  storedConfig: config,
1441
1500
  softConfig: buildConfig,
@@ -1444,20 +1503,22 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1444
1503
  index: itemSelector.index,
1445
1504
  zone: itemSelector.zone || rootDroppableId
1446
1505
  },
1506
+ editingComponentId: selectedItem.props.id,
1507
+ editableComponentIds: editableIds,
1447
1508
  state: "remodeling"
1448
1509
  }));
1449
1510
  setTimeout(
1450
1511
  () => puckDispatch({
1451
1512
  type: "replaceRoot",
1452
1513
  root: {
1453
- title: "Soft Component Builder",
1454
- _name: "New Soft Component"
1514
+ title: root.props.title,
1515
+ _name: root.props.name
1455
1516
  }
1456
1517
  }),
1457
1518
  100
1458
1519
  );
1459
1520
  },
1460
- complete: (appState, setHistories) => {
1521
+ complete: (appState, setHistories, getItemBySelector) => {
1461
1522
  var _a, _b;
1462
1523
  if (get().state === "ready") {
1463
1524
  throw new Error("Not building or remodeling a component.");
@@ -1466,7 +1527,17 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1466
1527
  if (!componentName) {
1467
1528
  throw new Error("Root component must have a name to compose.");
1468
1529
  }
1469
- const [newSoftComponentConfig, version] = get().builder.compose(appState, componentName) || [];
1530
+ const itemSelector = get().itemSelector;
1531
+ if (!itemSelector) {
1532
+ throw new Error("No item selector found for completed component.");
1533
+ }
1534
+ const selectedItem = getItemBySelector(
1535
+ itemSelector
1536
+ );
1537
+ if (!selectedItem) {
1538
+ throw new Error("Cannot find item being edited");
1539
+ }
1540
+ const [newSoftComponentConfig, version] = get().builder.compose(appState, componentName, selectedItem) || [];
1470
1541
  if (!newSoftComponentConfig) {
1471
1542
  throw new Error("Failed to compose new soft component config.");
1472
1543
  }
@@ -1498,8 +1569,11 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1498
1569
  }),
1499
1570
  storedConfig: void 0,
1500
1571
  state: "inspecting",
1501
- originalHistory: []
1572
+ originalHistory: [],
1573
+ editingComponentId: null,
1574
+ editableComponentIds: /* @__PURE__ */ new Set()
1502
1575
  }));
1576
+ get().rebuildDependents(componentName, version);
1503
1577
  return componentName;
1504
1578
  },
1505
1579
  inspect: (componentName, puckDispatch) => {
@@ -1526,7 +1600,9 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1526
1600
  set((s) => __spreadProps(__spreadValues({}, s), {
1527
1601
  state: "ready",
1528
1602
  setItemSelector: void 0,
1529
- setOriginalItem: void 0
1603
+ setOriginalItem: void 0,
1604
+ editingComponentId: null,
1605
+ editableComponentIds: /* @__PURE__ */ new Set()
1530
1606
  }));
1531
1607
  },
1532
1608
  cancel: (setHistories) => {
@@ -1538,10 +1614,12 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1538
1614
  originalHistory: [],
1539
1615
  itemSelector: null,
1540
1616
  originalItem: null,
1541
- state: "ready"
1617
+ state: "ready",
1618
+ editingComponentId: null,
1619
+ editableComponentIds: /* @__PURE__ */ new Set()
1542
1620
  }));
1543
1621
  },
1544
- compose: (appState, componentName) => {
1622
+ compose: (appState, componentName, editedItem) => {
1545
1623
  if (!componentName) {
1546
1624
  throw new Error("Root component must have a name to compose.");
1547
1625
  }
@@ -1551,7 +1629,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1551
1629
  `Component name "${componentName}" already exists in the configuration.`
1552
1630
  );
1553
1631
  }
1554
- const [softComponent, version] = softComponentFromAppState(appState, componentConfigs);
1632
+ const [softComponent, version] = softComponentFromAppState(appState, componentConfigs, editedItem);
1555
1633
  const existingComponent = get().softComponents[componentName];
1556
1634
  const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
1557
1635
  const isNewVersion = !allVersions.includes(version);
@@ -1567,7 +1645,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1567
1645
  })
1568
1646
  })
1569
1647
  }),
1570
- softComponent.defaultProps
1648
+ softComponent.defaultProps,
1649
+ get().showVersionFields
1571
1650
  );
1572
1651
  get().setSoftComponent(componentName, version, softComponent);
1573
1652
  return [newSoftComponentConfig, version];
@@ -1699,6 +1778,27 @@ function extractDependencies(softComponents, componentName, version) {
1699
1778
  processSubComponents(component.components);
1700
1779
  return dependencies;
1701
1780
  }
1781
+ function buildReverseDependencyGraph(softComponents) {
1782
+ const reverseDeps = /* @__PURE__ */ new Map();
1783
+ for (const [componentName, component] of Object.entries(softComponents)) {
1784
+ const defaultVersion = component.defaultVersion || Object.keys(component.versions || {}).pop();
1785
+ if (!defaultVersion) continue;
1786
+ Object.entries(component.versions || {}).forEach(([version, versionedComp]) => {
1787
+ const dependencies = extractDependencies(softComponents, componentName, version);
1788
+ if (!component.dependencies) {
1789
+ component.dependencies = {};
1790
+ }
1791
+ component.dependencies[version] = dependencies;
1792
+ for (const dep of dependencies) {
1793
+ if (!reverseDeps.has(dep)) {
1794
+ reverseDeps.set(dep, /* @__PURE__ */ new Set());
1795
+ }
1796
+ reverseDeps.get(dep).add(componentName);
1797
+ }
1798
+ });
1799
+ }
1800
+ return reverseDeps;
1801
+ }
1702
1802
  function topologicalSort(softComponents, hardComponentNames) {
1703
1803
  const sorted = [];
1704
1804
  const visiting = /* @__PURE__ */ new Set();
@@ -1742,7 +1842,7 @@ function topologicalSort(softComponents, hardComponentNames) {
1742
1842
  }
1743
1843
  return sorted;
1744
1844
  }
1745
- function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1845
+ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false) {
1746
1846
  var _a, _b;
1747
1847
  if (!softComponents || Object.keys(softComponents).length === 0) {
1748
1848
  return {};
@@ -1776,7 +1876,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1776
1876
  buildingConfig,
1777
1877
  // Pass the accumulating config
1778
1878
  hydratedSoftComponents,
1779
- versionedComponent.defaultProps
1879
+ versionedComponent.defaultProps,
1880
+ showVersioning
1780
1881
  );
1781
1882
  componentConfigs[name] = newSoftComponentConfig;
1782
1883
  buildingConfig.components[name] = newSoftComponentConfig;
@@ -1802,7 +1903,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1802
1903
  allVersions,
1803
1904
  hardConfig,
1804
1905
  hydratedSoftComponents,
1805
- versionedComponent.defaultProps
1906
+ versionedComponent.defaultProps,
1907
+ showVersioning
1806
1908
  );
1807
1909
  componentConfigs[name] = newSoftComponentConfig;
1808
1910
  }
@@ -1810,21 +1912,106 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides) {
1810
1912
  }
1811
1913
  }
1812
1914
 
1915
+ // src/puck/lib/edit-visibility-utils.ts
1916
+ var setEditVisibility = (doc, context) => {
1917
+ if (!doc) return;
1918
+ try {
1919
+ const root = doc.documentElement;
1920
+ if (context.mode === "none") {
1921
+ root.removeAttribute("data-edit-mode");
1922
+ root.classList.remove("edit-visibility-mode");
1923
+ doc.querySelectorAll("[data-puck-component]").forEach((el) => {
1924
+ el.removeAttribute("data-edit-visibility");
1925
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-editable", "edit-visibility-dependency");
1926
+ });
1927
+ } else {
1928
+ root.setAttribute("data-edit-mode", context.mode);
1929
+ root.classList.add("edit-visibility-mode");
1930
+ doc.querySelectorAll("[data-puck-component]").forEach((el) => {
1931
+ var _a;
1932
+ const id = el.getAttribute("data-puck-component");
1933
+ if (!id) return;
1934
+ const isEditable = context.editableIds.has(id);
1935
+ const isDependency = (_a = context.highlightDependencyIds) == null ? void 0 : _a.has(id);
1936
+ if (isEditable) {
1937
+ el.setAttribute("data-edit-visibility", "editable");
1938
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-dependency");
1939
+ el.classList.add("edit-visibility-editable");
1940
+ } else if (isDependency) {
1941
+ el.setAttribute("data-edit-visibility", "dependency");
1942
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-editable");
1943
+ el.classList.add("edit-visibility-dependency");
1944
+ } else {
1945
+ el.setAttribute("data-edit-visibility", "greyed");
1946
+ el.classList.remove("edit-visibility-editable", "edit-visibility-dependency");
1947
+ el.classList.add("edit-visibility-greyed");
1948
+ }
1949
+ });
1950
+ }
1951
+ } catch (error) {
1952
+ console.warn(`Failed to set edit visibility:`, error);
1953
+ }
1954
+ };
1955
+ var clearEditVisibility = (doc) => {
1956
+ if (!doc) return;
1957
+ try {
1958
+ const root = doc.documentElement;
1959
+ root.removeAttribute("data-edit-mode");
1960
+ root.classList.remove("edit-visibility-mode");
1961
+ doc.querySelectorAll("[data-puck-component]").forEach((el) => {
1962
+ el.removeAttribute("data-edit-visibility");
1963
+ el.classList.remove("edit-visibility-greyed", "edit-visibility-editable", "edit-visibility-dependency");
1964
+ });
1965
+ } catch (error) {
1966
+ console.warn(`Failed to clear edit visibility:`, error);
1967
+ }
1968
+ };
1969
+
1813
1970
  // src/puck/store/index.tsx
1814
1971
  var createSoftConfigStore = (hardConfig = {
1815
1972
  components: {}
1816
- }, softComponents = {}, overrides = {}, onActions) => {
1973
+ }, softComponents = {}, overrides = {}, onActions, showVersionFields = true) => {
1974
+ const iframeDocRef = { current: null };
1817
1975
  const hydratedSoftComponents = (overrides == null ? void 0 : overrides.hydrateMapTransform) ? hydrateSoftComponentsTransforms(
1818
1976
  softComponents,
1819
1977
  overrides.hydrateMapTransform
1820
1978
  ) : softComponents;
1979
+ const initialDependencyGraph = buildReverseDependencyGraph(
1980
+ hydratedSoftComponents
1981
+ );
1821
1982
  return create()(
1822
1983
  subscribeWithSelector(
1823
- devtools((set, get) => ({
1984
+ (set, get) => ({
1824
1985
  state: "ready",
1825
1986
  originalHistory: [],
1826
1987
  overrides,
1827
1988
  onActions,
1989
+ iframeDocRef,
1990
+ showVersionFields,
1991
+ setShowVersionFields: (show) => set({ showVersionFields: show }),
1992
+ getIframeDoc: () => iframeDocRef.current,
1993
+ setIframeDoc: (doc) => {
1994
+ iframeDocRef.current = doc;
1995
+ if (!doc) {
1996
+ return;
1997
+ }
1998
+ const { state, editableComponentIds } = get();
1999
+ if (state === "building") {
2000
+ setEditVisibility(doc, {
2001
+ mode: "build",
2002
+ editableIds: editableComponentIds
2003
+ });
2004
+ return;
2005
+ }
2006
+ if (state === "remodeling") {
2007
+ setEditVisibility(doc, {
2008
+ mode: "remodel",
2009
+ editableIds: editableComponentIds
2010
+ });
2011
+ return;
2012
+ }
2013
+ clearEditVisibility(doc);
2014
+ },
1828
2015
  storeHistory: (history) => set({ originalHistory: history }),
1829
2016
  removeHistory: () => set({ originalHistory: [] }),
1830
2017
  itemSelector: null,
@@ -1833,6 +2020,7 @@ var createSoftConfigStore = (hardConfig = {
1833
2020
  setOriginalItem: (item) => set({ originalItem: item }),
1834
2021
  hydratedSoftComponents,
1835
2022
  softComponents: hydratedSoftComponents,
2023
+ dependencyGraph: initialDependencyGraph,
1836
2024
  softConfig: __spreadProps(__spreadValues({}, hardConfig), {
1837
2025
  components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(
1838
2026
  hardConfig,
@@ -1874,7 +2062,8 @@ var createSoftConfigStore = (hardConfig = {
1874
2062
  Object.keys(finalComponentData.versions),
1875
2063
  state.softConfig,
1876
2064
  nextSoftComponents,
1877
- activeVersionData.defaultProps
2065
+ activeVersionData.defaultProps,
2066
+ state.showVersionFields
1878
2067
  );
1879
2068
  }
1880
2069
  });
@@ -1903,7 +2092,8 @@ var createSoftConfigStore = (hardConfig = {
1903
2092
  Object.keys(componentData.versions),
1904
2093
  softConfig,
1905
2094
  hydratedComponents,
1906
- activeVersionData.defaultProps
2095
+ activeVersionData.defaultProps,
2096
+ get().showVersionFields
1907
2097
  );
1908
2098
  }
1909
2099
  });
@@ -1931,7 +2121,8 @@ var createSoftConfigStore = (hardConfig = {
1931
2121
  allVersions,
1932
2122
  get().softConfig,
1933
2123
  get().softComponents,
1934
- softComponent.defaultProps
2124
+ softComponent.defaultProps,
2125
+ get().showVersionFields
1935
2126
  );
1936
2127
  set((state) => ({
1937
2128
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
@@ -2031,8 +2222,49 @@ var createSoftConfigStore = (hardConfig = {
2031
2222
  })
2032
2223
  }));
2033
2224
  },
2034
- builder: createBuildersSlice(set, get, hardConfig)
2035
- }))
2225
+ builder: createBuildersSlice(set, get, hardConfig),
2226
+ editingComponentId: null,
2227
+ editableComponentIds: /* @__PURE__ */ new Set(),
2228
+ setEditableComponentIds: (ids) => set({ editableComponentIds: ids }),
2229
+ addEditableComponentId: (id) => {
2230
+ set((state) => {
2231
+ const newIds = new Set(state.editableComponentIds);
2232
+ newIds.add(id);
2233
+ return { editableComponentIds: newIds };
2234
+ });
2235
+ },
2236
+ clearEditingState: () => set({
2237
+ editingComponentId: null,
2238
+ editableComponentIds: /* @__PURE__ */ new Set()
2239
+ }),
2240
+ rebuildDependents: (componentName, version) => {
2241
+ const state = get();
2242
+ const dependents = state.dependencyGraph.get(componentName) || /* @__PURE__ */ new Set();
2243
+ if (dependents.size === 0) return;
2244
+ const config = __spreadValues({}, state.softConfig);
2245
+ const softComponents2 = state.softComponents;
2246
+ const toBuild = Array.from(dependents);
2247
+ for (const dependentName of toBuild) {
2248
+ const dependent = softComponents2[dependentName];
2249
+ const defaultVersion = dependent.defaultVersion || Object.keys(dependent.versions || {}).pop();
2250
+ if (!defaultVersion) continue;
2251
+ const versionedComponent = dependent.versions[defaultVersion];
2252
+ const allVersions = Object.keys(dependent.versions || {});
2253
+ if (!versionedComponent) continue;
2254
+ const newConfig = createVersionedComponentConfig(
2255
+ dependentName,
2256
+ defaultVersion,
2257
+ allVersions,
2258
+ config,
2259
+ softComponents2,
2260
+ versionedComponent.defaultProps,
2261
+ state.showVersionFields
2262
+ );
2263
+ config.components[dependentName] = newConfig;
2264
+ }
2265
+ set((s) => __spreadProps(__spreadValues({}, s), { softConfig: config }));
2266
+ }
2267
+ })
2036
2268
  )
2037
2269
  );
2038
2270
  };
@@ -2046,11 +2278,12 @@ var SoftConfigProvider = ({
2046
2278
  softComponents,
2047
2279
  overrides,
2048
2280
  value,
2049
- onActions
2281
+ onActions,
2282
+ useVersioning = false
2050
2283
  }) => {
2051
2284
  const store = value != null ? value : useMemo2(
2052
- () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions),
2053
- [hardConfig, softComponents, overrides, onActions]
2285
+ () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2286
+ [hardConfig, softComponents, overrides, onActions, useVersioning]
2054
2287
  );
2055
2288
  const [softConfig, setSoftConfig] = useState2(
2056
2289
  () => store.getState().softConfig
@@ -2058,6 +2291,53 @@ var SoftConfigProvider = ({
2058
2291
  const [internalSoftComponents, setSoftComponents] = useState2(
2059
2292
  () => store.getState().softComponents
2060
2293
  );
2294
+ const storeSetIframeDoc = useMemo2(
2295
+ () => store.getState().setIframeDoc,
2296
+ [store]
2297
+ );
2298
+ const validateAction = useMemo2(
2299
+ () => (action) => {
2300
+ const currentState = store.getState();
2301
+ if (currentState.state === "ready") {
2302
+ return true;
2303
+ }
2304
+ const editableIds = currentState.editableComponentIds;
2305
+ if (action.type === "replace") {
2306
+ if (action.data.props.id && editableIds.has(action.data.props.id)) {
2307
+ return true;
2308
+ }
2309
+ return false;
2310
+ }
2311
+ if (action.type === "insert" || action.type === "duplicate") {
2312
+ const zone = action.type === "insert" ? action.destinationZone : action.sourceZone;
2313
+ const parentId = zone == null ? void 0 : zone.split(":")[0];
2314
+ if (parentId && !editableIds.has(parentId)) {
2315
+ return false;
2316
+ }
2317
+ if (action.type === "insert") {
2318
+ const childId = action.id;
2319
+ if (childId) {
2320
+ currentState.addEditableComponentId(childId);
2321
+ }
2322
+ }
2323
+ return true;
2324
+ }
2325
+ if (action.type === "remove" || action.type === "move" || action.type === "reorder") {
2326
+ let parentId;
2327
+ if (action.type === "remove") {
2328
+ parentId = action.zone.split(":")[0];
2329
+ } else if (action.type === "move" || action.type === "reorder") {
2330
+ parentId = action.destinationZone.split(":")[0];
2331
+ }
2332
+ if (parentId && !editableIds.has(parentId)) {
2333
+ return false;
2334
+ }
2335
+ return true;
2336
+ }
2337
+ return true;
2338
+ },
2339
+ [store]
2340
+ );
2061
2341
  useEffect2(() => {
2062
2342
  const unsubscribe = store.subscribe(() => {
2063
2343
  setSoftConfig(store.getState().softConfig);
@@ -2067,7 +2347,28 @@ var SoftConfigProvider = ({
2067
2347
  unsubscribe();
2068
2348
  };
2069
2349
  }, [store]);
2070
- return /* @__PURE__ */ jsx7(appStoreContext.Provider, { value: store, children: children(softConfig, internalSoftComponents) });
2350
+ useEffect2(() => {
2351
+ const unsubscribe = store.subscribe((state, prevState) => {
2352
+ if (prevState && state.state === prevState.state && state.editableComponentIds === prevState.editableComponentIds) {
2353
+ return;
2354
+ }
2355
+ const doc = store.getState().getIframeDoc();
2356
+ if (!doc) return;
2357
+ if (state.state === "building") {
2358
+ setEditVisibility(doc, { mode: "build", editableIds: state.editableComponentIds });
2359
+ return;
2360
+ }
2361
+ if (state.state === "remodeling") {
2362
+ setEditVisibility(doc, { mode: "remodel", editableIds: state.editableComponentIds });
2363
+ return;
2364
+ }
2365
+ clearEditVisibility(doc);
2366
+ });
2367
+ return () => {
2368
+ unsubscribe();
2369
+ };
2370
+ }, [store]);
2371
+ return /* @__PURE__ */ jsx7(appStoreContext.Provider, { value: store, children: children(softConfig, internalSoftComponents, storeSetIframeDoc, validateAction) });
2071
2372
  };
2072
2373
 
2073
2374
  // src/puck/actions/useBuild.tsx
@@ -2161,6 +2462,7 @@ var useRemodel = () => {
2161
2462
  const dispatch = useCustomPuck3((s) => s.dispatch);
2162
2463
  const status = useSoftConfig((s) => s.state);
2163
2464
  const softComponents = useSoftConfig((s) => s.softComponents);
2465
+ const refreshPermissions = useCustomPuck3((s) => s.refreshPermissions);
2164
2466
  const { triggerAction } = useActionEvent();
2165
2467
  const handleRemodel = (componentName) => {
2166
2468
  if (status !== "ready") {
@@ -2173,7 +2475,7 @@ var useRemodel = () => {
2173
2475
  return;
2174
2476
  }
2175
2477
  try {
2176
- remodel(history, selectedItem, itemSelector, dispatch);
2478
+ remodel(history, selectedItem, itemSelector, dispatch, refreshPermissions);
2177
2479
  void triggerAction({
2178
2480
  type: "remodel",
2179
2481
  payload: {
@@ -2202,6 +2504,7 @@ var useComplete = () => {
2202
2504
  const complete = useSoftConfig((s) => s.builder.complete);
2203
2505
  const appState = useCustomPuck4((s) => s.appState);
2204
2506
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2507
+ const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2205
2508
  const status = useSoftConfig((s) => s.state);
2206
2509
  const softComponents = useSoftConfig((s) => s.softComponents);
2207
2510
  const [newComponent, setNewComponent] = useState3(null);
@@ -2213,7 +2516,7 @@ var useComplete = () => {
2213
2516
  return null;
2214
2517
  }
2215
2518
  try {
2216
- const componentName = complete(appState, setHistories);
2519
+ const componentName = complete(appState, setHistories, getItemBySelector);
2217
2520
  setNewComponent(componentName);
2218
2521
  const componentData = appState.data.root;
2219
2522
  const softComponent = (_b = softComponents[componentName]) == null ? void 0 : _b.versions[(_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion];
@@ -2235,7 +2538,7 @@ var useComplete = () => {
2235
2538
  );
2236
2539
  return null;
2237
2540
  }
2238
- }, [complete, appState, setHistories, status, softComponents, triggerAction]);
2541
+ }, [complete, appState, setHistories, status, softComponents, triggerAction, getItemBySelector]);
2239
2542
  const canComplete = status === "building" || status === "remodeling";
2240
2543
  return { handleComplete, canComplete, newComponent, setNewComponent };
2241
2544
  };
@@ -2303,7 +2606,7 @@ var useInspect = (componentName) => {
2303
2606
  };
2304
2607
 
2305
2608
  // src/puck/actions/useDecompose.tsx
2306
- import { createUsePuck as createUsePuck7, walkTree as walkTree3 } from "@measured/puck";
2609
+ import { createUsePuck as createUsePuck7, walkTree as walkTree4 } from "@measured/puck";
2307
2610
  var useCustomPuck7 = createUsePuck7();
2308
2611
  var useDecompose = () => {
2309
2612
  const decompose = useSoftConfig((s) => s.builder.decompose);
@@ -2335,7 +2638,7 @@ var useDecompose = () => {
2335
2638
  notify.error("Nothing to decompose.");
2336
2639
  return;
2337
2640
  }
2338
- const newData = walkTree3(appState.data, config, (components) => {
2641
+ const newData = walkTree4(appState.data, config, (components) => {
2339
2642
  const index = components.findIndex((c) => c.props.id === target.props.id);
2340
2643
  if (index !== -1) {
2341
2644
  components.splice(index, 1, ...decomposedComponents);
@@ -2455,9 +2758,9 @@ var useSetDefaultVersion = () => {
2455
2758
  };
2456
2759
 
2457
2760
  // src/puck/overrides/Header.tsx
2458
- import { Button } from "@measured/puck";
2761
+ import { Button, createUsePuck as createUsePuck10 } from "@measured/puck";
2459
2762
 
2460
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\overrides\Header.module.css#css-module
2763
+ // css-module:/media/osamu/3628738E28734BBD/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/Header.module.css#css-module
2461
2764
  var Header_module_default = { "Header": "_Header_19oj9_1" };
2462
2765
 
2463
2766
  // src/puck/actions/usePublish.tsx
@@ -2498,6 +2801,7 @@ var usePublish = () => {
2498
2801
  // src/puck/overrides/Header.tsx
2499
2802
  import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
2500
2803
  var getClassName2 = get_class_name_factory_default("Header", Header_module_default);
2804
+ var usePuck = createUsePuck10();
2501
2805
  var Header = ({
2502
2806
  onPublish,
2503
2807
  children
@@ -2536,22 +2840,29 @@ var Header = ({
2536
2840
  };
2537
2841
 
2538
2842
  // src/puck/overrides/ActionBar.tsx
2539
- import { ActionBar } from "@measured/puck";
2843
+ import { ActionBar, createUsePuck as createUsePuck11 } from "@measured/puck";
2540
2844
  import { Combine, ComponentIcon, EditIcon } from "lucide-react";
2541
2845
 
2542
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\overrides\ActionBar.module.css#css-module
2846
+ // css-module:/media/osamu/3628738E28734BBD/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/ActionBar.module.css#css-module
2543
2847
  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
2848
 
2545
2849
  // src/puck/overrides/ActionBar.tsx
2850
+ import { shallow } from "zustand/shallow";
2546
2851
  import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
2547
2852
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
2853
+ var usePuck2 = createUsePuck11();
2548
2854
  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);
2855
+ var _a;
2856
+ const { handleBuild } = useBuild();
2857
+ const { handleRemodel } = useRemodel();
2858
+ const { handleDecompose } = useDecompose();
2859
+ const softComponents = useSoftConfig((s) => s.softComponents, shallow);
2860
+ const editableIds = useSoftConfig((s) => s.editableComponentIds);
2861
+ const selectedItem = usePuck2((s) => s.selectedItem);
2553
2862
  const status = useSoftConfig((s) => s.state);
2554
2863
  const isSoftComponent2 = Object.keys(softComponents || {}).includes(props.label);
2864
+ const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
2865
+ const isEditable = Boolean(selectedId && editableIds.has(selectedId));
2555
2866
  return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
2556
2867
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
2557
2868
  props.parentAction,
@@ -2575,15 +2886,22 @@ var ActionBarOverride = (props) => {
2575
2886
  children: /* @__PURE__ */ jsx9(Combine, { size: 16 })
2576
2887
  }
2577
2888
  )
2578
- ] }) : /* @__PURE__ */ jsx9(ActionBar.Action, { onClick: handleBuild, label: "Build Soft Component", children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 }) }) : null,
2579
- props.children
2889
+ ] }) : /* @__PURE__ */ jsx9(
2890
+ ActionBar.Action,
2891
+ {
2892
+ onClick: handleBuild,
2893
+ label: "Build Soft Component",
2894
+ children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 })
2895
+ }
2896
+ ) : null,
2897
+ status !== "ready" && !isEditable ? null : props.children
2580
2898
  ] })
2581
2899
  ] }) });
2582
2900
  };
2583
2901
 
2584
2902
  // src/puck/overrides/ComponentItem.tsx
2585
2903
  import { useState as useState5 } from "react";
2586
- import { Button as Button2, IconButton } from "@measured/puck";
2904
+ import { Button as Button2, IconButton, createUsePuck as createUsePuck12 } from "@measured/puck";
2587
2905
  import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
2588
2906
 
2589
2907
  // src/puck/lib/confirm.ts
@@ -2603,14 +2921,14 @@ var confirm = (message) => __async(null, null, function* () {
2603
2921
  }
2604
2922
  });
2605
2923
 
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" };
2924
+ // css-module:/media/osamu/3628738E28734BBD/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/ComponentItem.module.css#css-module
2925
+ 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
2926
 
2609
2927
  // src/puck/components/modal/index.tsx
2610
2928
  import { useEffect as useEffect4, useState as useState4 } from "react";
2611
2929
  import { createPortal } from "react-dom";
2612
2930
 
2613
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\components\modal\styles.module.css#css-module
2931
+ // css-module:/media/osamu/3628738E28734BBD/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css#css-module
2614
2932
  var styles_module_default2 = { "Modal": "_Modal_pvj02_1", "Modal--isOpen": "_Modal--isOpen_pvj02_29", "Modal-inner": "_Modal-inner_pvj02_37" };
2615
2933
 
2616
2934
  // src/puck/components/modal/index.tsx
@@ -2642,12 +2960,16 @@ var Modal = ({
2642
2960
  };
2643
2961
 
2644
2962
  // src/puck/overrides/ComponentItem.tsx
2963
+ import { shallow as shallow2 } from "zustand/shallow";
2645
2964
  import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
2646
2965
  var getClassName5 = get_class_name_factory_default("ComponentItem", ComponentItem_module_default);
2966
+ var usePuck3 = createUsePuck12();
2647
2967
  var ComponentItem = (props) => {
2648
2968
  const softComponents = new Set(
2649
- Object.keys(useSoftConfig((s) => s.softComponents))
2969
+ Object.keys(useSoftConfig((s) => s.softComponents, shallow2))
2650
2970
  );
2971
+ const getPermissions = usePuck3((s) => s.getPermissions);
2972
+ const insertAllowed = getPermissions({ type: props.name }).insert;
2651
2973
  const removeSoftComponentVersion = useSoftConfig(
2652
2974
  (s) => s.removeSoftComponentVersion
2653
2975
  );
@@ -2660,6 +2982,7 @@ var ComponentItem = (props) => {
2660
2982
  /* @__PURE__ */ new Set()
2661
2983
  );
2662
2984
  const [migrateVersionMap, setMigrateVersionMap] = useState5({});
2985
+ const useVersioning = useSoftConfig((s) => s.showVersionFields);
2663
2986
  const versions = getVersions(props.name);
2664
2987
  const defaultVersion = getDefaultVersion(props.name);
2665
2988
  const handleApply = () => __async(null, null, function* () {
@@ -2717,13 +3040,13 @@ var ComponentItem = (props) => {
2717
3040
  /* @__PURE__ */ jsxs4(
2718
3041
  "div",
2719
3042
  {
2720
- className: getClassName5(),
3043
+ className: getClassName5({ insertDisabled: !insertAllowed }),
2721
3044
  onMouseEnter: () => setIsHovering(true),
2722
3045
  onMouseLeave: () => setIsHovering(false),
2723
3046
  children: [
2724
3047
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
2725
3048
  /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: props.name }),
2726
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
3049
+ useVersioning && /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
2727
3050
  "v",
2728
3051
  defaultVersion
2729
3052
  ] })
@@ -2739,7 +3062,7 @@ var ComponentItem = (props) => {
2739
3062
  setIsEditing(true);
2740
3063
  setSelectedVersion(defaultVersion || "");
2741
3064
  },
2742
- children: /* @__PURE__ */ jsx11(Cog, { size: 14 })
3065
+ children: /* @__PURE__ */ jsx11(Cog, { size: 12 })
2743
3066
  }
2744
3067
  ) }),
2745
3068
  /* @__PURE__ */ jsx11("div", { className: getClassName5("grip"), children: /* @__PURE__ */ jsx11(GripVertical, { size: 16 }) })
@@ -2750,9 +3073,9 @@ var ComponentItem = (props) => {
2750
3073
  /* @__PURE__ */ jsx11(Modal, { isOpen: isEditing, onClose: handleCancel, children: /* @__PURE__ */ jsxs4("div", { className: getClassName5("modal"), children: [
2751
3074
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalHeader"), children: [
2752
3075
  /* @__PURE__ */ jsx11("h2", { className: getClassName5("modalTitle"), children: props.name }),
2753
- /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Manage versions and settings" })
3076
+ /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Component Settings" })
2754
3077
  ] }),
2755
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalBody"), children: [
3078
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("modalBody"), children: useVersioning ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2756
3079
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2757
3080
  /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Versions" }),
2758
3081
  /* @__PURE__ */ jsx11("div", { className: getClassName5("versionList"), children: versions.map((version) => {
@@ -2761,52 +3084,30 @@ var ComponentItem = (props) => {
2761
3084
  let rowClass = getClassName5("versionRow");
2762
3085
  if (isDefault) rowClass += " " + getClassName5("versionRow--isDefault");
2763
3086
  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
- );
3087
+ return /* @__PURE__ */ jsxs4("div", { className: rowClass, children: [
3088
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionInfo"), children: [
3089
+ /* @__PURE__ */ jsxs4("span", { className: getClassName5("versionNumber"), children: [
3090
+ "Version ",
3091
+ version
3092
+ ] }),
3093
+ isDefault && /* @__PURE__ */ jsx11("span", { className: getClassName5("defaultBadge"), children: "Default" }),
3094
+ isMarkedForDeletion && /* @__PURE__ */ jsx11("span", { className: getClassName5("deleteBadge"), children: "Marked for deletion" })
3095
+ ] }),
3096
+ /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionActions"), children: [
3097
+ !isDefault && !isMarkedForDeletion && /* @__PURE__ */ jsx11(Button2, { variant: "secondary", onClick: () => setSelectedVersion(version), children: "Set as Default" }),
3098
+ /* @__PURE__ */ jsx11(Button2, { variant: "secondary", onClick: () => toggleVersionForDeletion(version), children: isMarkedForDeletion ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
3099
+ /* @__PURE__ */ jsx11(X, { size: 14 }),
3100
+ " Undo"
3101
+ ] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
3102
+ /* @__PURE__ */ jsx11(Trash2, { size: 14 }),
3103
+ " Delete"
3104
+ ] }) })
3105
+ ] })
3106
+ ] }, version);
2805
3107
  }) })
2806
3108
  ] }),
2807
3109
  versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2808
3110
  /* @__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
3111
  /* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsxs4(
2811
3112
  "select",
2812
3113
  {
@@ -2829,30 +3130,26 @@ var ComponentItem = (props) => {
2829
3130
  }
2830
3131
  ) })
2831
3132
  ] })
2832
- ] }),
3133
+ ] }) : /* @__PURE__ */ jsx11("div", { className: getClassName5("section"), children: /* @__PURE__ */ jsxs4("p", { children: [
3134
+ "Manage high-level settings for the ",
3135
+ /* @__PURE__ */ jsx11("strong", { children: props.name }),
3136
+ " component."
3137
+ ] }) }) }),
2833
3138
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalFooter"), children: [
2834
3139
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("footerLeft"), children: [
2835
- /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
3140
+ useVersioning ? /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
2836
3141
  /* @__PURE__ */ jsx11(Check, { size: 16 }),
2837
- "Apply Changes"
2838
- ] }),
2839
- /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleCancel, children: [
3142
+ " Apply Changes"
3143
+ ] }) : /* @__PURE__ */ jsx11(Button2, { size: "medium", onClick: handleCancel, children: "Close" }),
3144
+ useVersioning && /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleCancel, children: [
2840
3145
  /* @__PURE__ */ jsx11(X, { size: 16 }),
2841
- "Cancel"
3146
+ " Cancel"
2842
3147
  ] })
2843
3148
  ] }),
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
- ) })
3149
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("footerRight"), children: /* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleDemolishClick, children: [
3150
+ /* @__PURE__ */ jsx11(Trash2, { size: 16 }),
3151
+ " Demolish Component"
3152
+ ] }) })
2856
3153
  ] })
2857
3154
  ] }) })
2858
3155
  ] });
@@ -2860,6 +3157,27 @@ var ComponentItem = (props) => {
2860
3157
  return /* @__PURE__ */ jsx11(Fragment5, { children: props.children });
2861
3158
  };
2862
3159
 
3160
+ // src/puck/lib/action-callback.ts
3161
+ var createActionCallback = (validateAction, undo) => {
3162
+ return (action) => {
3163
+ const isValid = validateAction(action);
3164
+ if (!isValid) {
3165
+ notify.error(
3166
+ "Editing outside the soft component is not allowed when you are editing component definition."
3167
+ );
3168
+ if (typeof requestAnimationFrame === "function") {
3169
+ requestAnimationFrame(() => {
3170
+ requestAnimationFrame(() => {
3171
+ undo();
3172
+ });
3173
+ });
3174
+ } else {
3175
+ setTimeout(() => undo(), 0);
3176
+ }
3177
+ }
3178
+ };
3179
+ };
3180
+
2863
3181
  // src/puck/lib/dissolve-all-soft-components.ts
2864
3182
  function extractDependencies2(softComponents, componentName, version) {
2865
3183
  var _a, _b;
@@ -3068,6 +3386,7 @@ export {
3068
3386
  Modal,
3069
3387
  SoftConfigProvider,
3070
3388
  confirm,
3389
+ createActionCallback,
3071
3390
  createSoftConfigStore,
3072
3391
  createUseSoftConfig,
3073
3392
  notify,