@netlisian/softconfig 0.0.9 → 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,
@@ -1855,6 +2043,67 @@ var createSoftConfigStore = (hardConfig = {
1855
2043
  };
1856
2044
  });
1857
2045
  },
2046
+ setSoftComponents: (incomingComponents) => {
2047
+ const state = get();
2048
+ const nextSoftComponents = __spreadValues({}, state.softComponents);
2049
+ const nextConfigComponents = __spreadValues({}, state.softConfig.components);
2050
+ Object.entries(incomingComponents).forEach(([name, data]) => {
2051
+ const existing = nextSoftComponents[name];
2052
+ const finalComponentData = existing ? __spreadProps(__spreadValues(__spreadValues({}, existing), data), {
2053
+ versions: __spreadValues(__spreadValues({}, existing.versions), data.versions)
2054
+ }) : data;
2055
+ nextSoftComponents[name] = finalComponentData;
2056
+ const activeVersion = finalComponentData.defaultVersion;
2057
+ const activeVersionData = finalComponentData.versions[activeVersion];
2058
+ if (activeVersionData) {
2059
+ nextConfigComponents[name] = createVersionedComponentConfig(
2060
+ name,
2061
+ activeVersion,
2062
+ Object.keys(finalComponentData.versions),
2063
+ state.softConfig,
2064
+ nextSoftComponents,
2065
+ activeVersionData.defaultProps,
2066
+ state.showVersionFields
2067
+ );
2068
+ }
2069
+ });
2070
+ set({
2071
+ softComponents: nextSoftComponents,
2072
+ softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
2073
+ components: nextConfigComponents
2074
+ })
2075
+ });
2076
+ },
2077
+ hydrateTransforms: () => {
2078
+ const { overrides: overrides2, softComponents: softComponents2, softConfig } = get();
2079
+ if (!(overrides2 == null ? void 0 : overrides2.hydrateMapTransform)) return;
2080
+ const hydratedComponents = hydrateSoftComponentsTransforms(
2081
+ softComponents2,
2082
+ overrides2.hydrateMapTransform
2083
+ );
2084
+ const nextConfigComponents = __spreadValues({}, softConfig.components);
2085
+ Object.entries(hydratedComponents).forEach(([name, componentData]) => {
2086
+ const activeVersion = componentData.defaultVersion;
2087
+ const activeVersionData = componentData.versions[activeVersion];
2088
+ if (activeVersionData) {
2089
+ nextConfigComponents[name] = createVersionedComponentConfig(
2090
+ name,
2091
+ activeVersion,
2092
+ Object.keys(componentData.versions),
2093
+ softConfig,
2094
+ hydratedComponents,
2095
+ activeVersionData.defaultProps,
2096
+ get().showVersionFields
2097
+ );
2098
+ }
2099
+ });
2100
+ set({
2101
+ softComponents: hydratedComponents,
2102
+ softConfig: __spreadProps(__spreadValues({}, softConfig), {
2103
+ components: nextConfigComponents
2104
+ })
2105
+ });
2106
+ },
1858
2107
  setSoftComponentDefaultVersion: (name, version) => {
1859
2108
  var _a, _b, _c;
1860
2109
  const softComponent = (_b = (_a = get().softComponents[name]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
@@ -1872,7 +2121,8 @@ var createSoftConfigStore = (hardConfig = {
1872
2121
  allVersions,
1873
2122
  get().softConfig,
1874
2123
  get().softComponents,
1875
- softComponent.defaultProps
2124
+ softComponent.defaultProps,
2125
+ get().showVersionFields
1876
2126
  );
1877
2127
  set((state) => ({
1878
2128
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
@@ -1972,8 +2222,49 @@ var createSoftConfigStore = (hardConfig = {
1972
2222
  })
1973
2223
  }));
1974
2224
  },
1975
- builder: createBuildersSlice(set, get, hardConfig)
1976
- }))
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
+ })
1977
2268
  )
1978
2269
  );
1979
2270
  };
@@ -1987,11 +2278,12 @@ var SoftConfigProvider = ({
1987
2278
  softComponents,
1988
2279
  overrides,
1989
2280
  value,
1990
- onActions
2281
+ onActions,
2282
+ useVersioning = false
1991
2283
  }) => {
1992
2284
  const store = value != null ? value : useMemo2(
1993
- () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions),
1994
- [hardConfig, softComponents, overrides, onActions]
2285
+ () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2286
+ [hardConfig, softComponents, overrides, onActions, useVersioning]
1995
2287
  );
1996
2288
  const [softConfig, setSoftConfig] = useState2(
1997
2289
  () => store.getState().softConfig
@@ -1999,6 +2291,53 @@ var SoftConfigProvider = ({
1999
2291
  const [internalSoftComponents, setSoftComponents] = useState2(
2000
2292
  () => store.getState().softComponents
2001
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
+ );
2002
2341
  useEffect2(() => {
2003
2342
  const unsubscribe = store.subscribe(() => {
2004
2343
  setSoftConfig(store.getState().softConfig);
@@ -2008,7 +2347,28 @@ var SoftConfigProvider = ({
2008
2347
  unsubscribe();
2009
2348
  };
2010
2349
  }, [store]);
2011
- 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) });
2012
2372
  };
2013
2373
 
2014
2374
  // src/puck/actions/useBuild.tsx
@@ -2074,7 +2434,7 @@ var useBuild = () => {
2074
2434
  try {
2075
2435
  build(history, selectedItem, itemSelector, dispatch);
2076
2436
  if (selectedItem == null ? void 0 : selectedItem.type) {
2077
- triggerAction({
2437
+ void triggerAction({
2078
2438
  type: "build",
2079
2439
  payload: {
2080
2440
  id: selectedItem.type
@@ -2102,6 +2462,7 @@ var useRemodel = () => {
2102
2462
  const dispatch = useCustomPuck3((s) => s.dispatch);
2103
2463
  const status = useSoftConfig((s) => s.state);
2104
2464
  const softComponents = useSoftConfig((s) => s.softComponents);
2465
+ const refreshPermissions = useCustomPuck3((s) => s.refreshPermissions);
2105
2466
  const { triggerAction } = useActionEvent();
2106
2467
  const handleRemodel = (componentName) => {
2107
2468
  if (status !== "ready") {
@@ -2114,8 +2475,8 @@ var useRemodel = () => {
2114
2475
  return;
2115
2476
  }
2116
2477
  try {
2117
- remodel(history, selectedItem, itemSelector, dispatch);
2118
- triggerAction({
2478
+ remodel(history, selectedItem, itemSelector, dispatch, refreshPermissions);
2479
+ void triggerAction({
2119
2480
  type: "remodel",
2120
2481
  payload: {
2121
2482
  id: name
@@ -2143,6 +2504,7 @@ var useComplete = () => {
2143
2504
  const complete = useSoftConfig((s) => s.builder.complete);
2144
2505
  const appState = useCustomPuck4((s) => s.appState);
2145
2506
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2507
+ const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2146
2508
  const status = useSoftConfig((s) => s.state);
2147
2509
  const softComponents = useSoftConfig((s) => s.softComponents);
2148
2510
  const [newComponent, setNewComponent] = useState3(null);
@@ -2154,12 +2516,12 @@ var useComplete = () => {
2154
2516
  return null;
2155
2517
  }
2156
2518
  try {
2157
- const componentName = complete(appState, setHistories);
2519
+ const componentName = complete(appState, setHistories, getItemBySelector);
2158
2520
  setNewComponent(componentName);
2159
2521
  const componentData = appState.data.root;
2160
2522
  const softComponent = (_b = softComponents[componentName]) == null ? void 0 : _b.versions[(_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion];
2161
2523
  if (softComponent && componentData) {
2162
- triggerAction({
2524
+ void triggerAction({
2163
2525
  type: "complete",
2164
2526
  payload: {
2165
2527
  id: componentName,
@@ -2176,7 +2538,7 @@ var useComplete = () => {
2176
2538
  );
2177
2539
  return null;
2178
2540
  }
2179
- }, [complete, appState, setHistories, status, softComponents, triggerAction]);
2541
+ }, [complete, appState, setHistories, status, softComponents, triggerAction, getItemBySelector]);
2180
2542
  const canComplete = status === "building" || status === "remodeling";
2181
2543
  return { handleComplete, canComplete, newComponent, setNewComponent };
2182
2544
  };
@@ -2196,7 +2558,7 @@ var useCancel = () => {
2196
2558
  }
2197
2559
  try {
2198
2560
  cancel(setHistories);
2199
- triggerAction({
2561
+ void triggerAction({
2200
2562
  type: "cancel",
2201
2563
  payload: {}
2202
2564
  });
@@ -2228,7 +2590,7 @@ var useInspect = (componentName) => {
2228
2590
  }
2229
2591
  try {
2230
2592
  inspect(componentName, dispatch);
2231
- triggerAction({
2593
+ void triggerAction({
2232
2594
  type: "inspect",
2233
2595
  payload: {
2234
2596
  id: componentName
@@ -2244,7 +2606,7 @@ var useInspect = (componentName) => {
2244
2606
  };
2245
2607
 
2246
2608
  // src/puck/actions/useDecompose.tsx
2247
- import { createUsePuck as createUsePuck7, walkTree as walkTree3 } from "@measured/puck";
2609
+ import { createUsePuck as createUsePuck7, walkTree as walkTree4 } from "@measured/puck";
2248
2610
  var useCustomPuck7 = createUsePuck7();
2249
2611
  var useDecompose = () => {
2250
2612
  const decompose = useSoftConfig((s) => s.builder.decompose);
@@ -2276,7 +2638,7 @@ var useDecompose = () => {
2276
2638
  notify.error("Nothing to decompose.");
2277
2639
  return;
2278
2640
  }
2279
- const newData = walkTree3(appState.data, config, (components) => {
2641
+ const newData = walkTree4(appState.data, config, (components) => {
2280
2642
  const index = components.findIndex((c) => c.props.id === target.props.id);
2281
2643
  if (index !== -1) {
2282
2644
  components.splice(index, 1, ...decomposedComponents);
@@ -2287,7 +2649,7 @@ var useDecompose = () => {
2287
2649
  type: "setData",
2288
2650
  data: newData
2289
2651
  });
2290
- triggerAction({
2652
+ void triggerAction({
2291
2653
  type: "decompose",
2292
2654
  payload: {
2293
2655
  id: componentName
@@ -2328,7 +2690,7 @@ var useDemolish = () => {
2328
2690
  }
2329
2691
  try {
2330
2692
  demolish(componentName, data, dispatch);
2331
- triggerAction({
2693
+ void triggerAction({
2332
2694
  type: "demolish",
2333
2695
  payload: {
2334
2696
  id: componentName
@@ -2367,7 +2729,7 @@ var useSetDefaultVersion = () => {
2367
2729
  return;
2368
2730
  }
2369
2731
  setSoftComponentDefaultVersion(componentName, version);
2370
- triggerAction({
2732
+ void triggerAction({
2371
2733
  type: "setDefaultVersion",
2372
2734
  payload: {
2373
2735
  id: componentName,
@@ -2396,9 +2758,9 @@ var useSetDefaultVersion = () => {
2396
2758
  };
2397
2759
 
2398
2760
  // src/puck/overrides/Header.tsx
2399
- import { Button } from "@measured/puck";
2761
+ import { Button, createUsePuck as createUsePuck10 } from "@measured/puck";
2400
2762
 
2401
- // 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
2402
2764
  var Header_module_default = { "Header": "_Header_19oj9_1" };
2403
2765
 
2404
2766
  // src/puck/actions/usePublish.tsx
@@ -2423,7 +2785,7 @@ var usePublish = () => {
2423
2785
  const rootComponentType = (_a = data.root) == null ? void 0 : _a.type;
2424
2786
  const rootVersion = (_b = components[rootComponentType]) == null ? void 0 : _b.defaultVersion;
2425
2787
  if (rootComponentType && rootVersion) {
2426
- triggerAction({
2788
+ void triggerAction({
2427
2789
  type: "publish",
2428
2790
  payload: {
2429
2791
  id: rootComponentType,
@@ -2439,6 +2801,7 @@ var usePublish = () => {
2439
2801
  // src/puck/overrides/Header.tsx
2440
2802
  import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
2441
2803
  var getClassName2 = get_class_name_factory_default("Header", Header_module_default);
2804
+ var usePuck = createUsePuck10();
2442
2805
  var Header = ({
2443
2806
  onPublish,
2444
2807
  children
@@ -2477,22 +2840,29 @@ var Header = ({
2477
2840
  };
2478
2841
 
2479
2842
  // src/puck/overrides/ActionBar.tsx
2480
- import { ActionBar } from "@measured/puck";
2843
+ import { ActionBar, createUsePuck as createUsePuck11 } from "@measured/puck";
2481
2844
  import { Combine, ComponentIcon, EditIcon } from "lucide-react";
2482
2845
 
2483
- // 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
2484
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" };
2485
2848
 
2486
2849
  // src/puck/overrides/ActionBar.tsx
2850
+ import { shallow } from "zustand/shallow";
2487
2851
  import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
2488
2852
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
2853
+ var usePuck2 = createUsePuck11();
2489
2854
  var ActionBarOverride = (props) => {
2490
- const { handleBuild, canBuild } = useBuild();
2491
- const { handleRemodel, canRemodel } = useRemodel();
2492
- const { handleDecompose, canDecompose } = useDecompose();
2493
- 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);
2494
2862
  const status = useSoftConfig((s) => s.state);
2495
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));
2496
2866
  return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
2497
2867
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
2498
2868
  props.parentAction,
@@ -2516,15 +2886,22 @@ var ActionBarOverride = (props) => {
2516
2886
  children: /* @__PURE__ */ jsx9(Combine, { size: 16 })
2517
2887
  }
2518
2888
  )
2519
- ] }) : /* @__PURE__ */ jsx9(ActionBar.Action, { onClick: handleBuild, label: "Build Soft Component", children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 }) }) : null,
2520
- 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
2521
2898
  ] })
2522
2899
  ] }) });
2523
2900
  };
2524
2901
 
2525
2902
  // src/puck/overrides/ComponentItem.tsx
2526
2903
  import { useState as useState5 } from "react";
2527
- import { Button as Button2, IconButton } from "@measured/puck";
2904
+ import { Button as Button2, IconButton, createUsePuck as createUsePuck12 } from "@measured/puck";
2528
2905
  import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
2529
2906
 
2530
2907
  // src/puck/lib/confirm.ts
@@ -2544,14 +2921,14 @@ var confirm = (message) => __async(null, null, function* () {
2544
2921
  }
2545
2922
  });
2546
2923
 
2547
- // css-module:D:\osamuProjects\netlisian\packages\soft-config\src\puck\overrides\ComponentItem.module.css#css-module
2548
- 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" };
2549
2926
 
2550
2927
  // src/puck/components/modal/index.tsx
2551
2928
  import { useEffect as useEffect4, useState as useState4 } from "react";
2552
2929
  import { createPortal } from "react-dom";
2553
2930
 
2554
- // 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
2555
2932
  var styles_module_default2 = { "Modal": "_Modal_pvj02_1", "Modal--isOpen": "_Modal--isOpen_pvj02_29", "Modal-inner": "_Modal-inner_pvj02_37" };
2556
2933
 
2557
2934
  // src/puck/components/modal/index.tsx
@@ -2583,12 +2960,16 @@ var Modal = ({
2583
2960
  };
2584
2961
 
2585
2962
  // src/puck/overrides/ComponentItem.tsx
2963
+ import { shallow as shallow2 } from "zustand/shallow";
2586
2964
  import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
2587
2965
  var getClassName5 = get_class_name_factory_default("ComponentItem", ComponentItem_module_default);
2966
+ var usePuck3 = createUsePuck12();
2588
2967
  var ComponentItem = (props) => {
2589
2968
  const softComponents = new Set(
2590
- Object.keys(useSoftConfig((s) => s.softComponents))
2969
+ Object.keys(useSoftConfig((s) => s.softComponents, shallow2))
2591
2970
  );
2971
+ const getPermissions = usePuck3((s) => s.getPermissions);
2972
+ const insertAllowed = getPermissions({ type: props.name }).insert;
2592
2973
  const removeSoftComponentVersion = useSoftConfig(
2593
2974
  (s) => s.removeSoftComponentVersion
2594
2975
  );
@@ -2601,6 +2982,7 @@ var ComponentItem = (props) => {
2601
2982
  /* @__PURE__ */ new Set()
2602
2983
  );
2603
2984
  const [migrateVersionMap, setMigrateVersionMap] = useState5({});
2985
+ const useVersioning = useSoftConfig((s) => s.showVersionFields);
2604
2986
  const versions = getVersions(props.name);
2605
2987
  const defaultVersion = getDefaultVersion(props.name);
2606
2988
  const handleApply = () => __async(null, null, function* () {
@@ -2658,13 +3040,13 @@ var ComponentItem = (props) => {
2658
3040
  /* @__PURE__ */ jsxs4(
2659
3041
  "div",
2660
3042
  {
2661
- className: getClassName5(),
3043
+ className: getClassName5({ insertDisabled: !insertAllowed }),
2662
3044
  onMouseEnter: () => setIsHovering(true),
2663
3045
  onMouseLeave: () => setIsHovering(false),
2664
3046
  children: [
2665
3047
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
2666
3048
  /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: props.name }),
2667
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
3049
+ useVersioning && /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
2668
3050
  "v",
2669
3051
  defaultVersion
2670
3052
  ] })
@@ -2680,7 +3062,7 @@ var ComponentItem = (props) => {
2680
3062
  setIsEditing(true);
2681
3063
  setSelectedVersion(defaultVersion || "");
2682
3064
  },
2683
- children: /* @__PURE__ */ jsx11(Cog, { size: 14 })
3065
+ children: /* @__PURE__ */ jsx11(Cog, { size: 12 })
2684
3066
  }
2685
3067
  ) }),
2686
3068
  /* @__PURE__ */ jsx11("div", { className: getClassName5("grip"), children: /* @__PURE__ */ jsx11(GripVertical, { size: 16 }) })
@@ -2691,9 +3073,9 @@ var ComponentItem = (props) => {
2691
3073
  /* @__PURE__ */ jsx11(Modal, { isOpen: isEditing, onClose: handleCancel, children: /* @__PURE__ */ jsxs4("div", { className: getClassName5("modal"), children: [
2692
3074
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalHeader"), children: [
2693
3075
  /* @__PURE__ */ jsx11("h2", { className: getClassName5("modalTitle"), children: props.name }),
2694
- /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Manage versions and settings" })
3076
+ /* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Component Settings" })
2695
3077
  ] }),
2696
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalBody"), children: [
3078
+ /* @__PURE__ */ jsx11("div", { className: getClassName5("modalBody"), children: useVersioning ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2697
3079
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2698
3080
  /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Versions" }),
2699
3081
  /* @__PURE__ */ jsx11("div", { className: getClassName5("versionList"), children: versions.map((version) => {
@@ -2702,52 +3084,30 @@ var ComponentItem = (props) => {
2702
3084
  let rowClass = getClassName5("versionRow");
2703
3085
  if (isDefault) rowClass += " " + getClassName5("versionRow--isDefault");
2704
3086
  if (isMarkedForDeletion) rowClass += " " + getClassName5("versionRow--isMarkedForDeletion");
2705
- return /* @__PURE__ */ jsxs4(
2706
- "div",
2707
- {
2708
- className: rowClass,
2709
- children: [
2710
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionInfo"), children: [
2711
- /* @__PURE__ */ jsxs4("span", { className: getClassName5("versionNumber"), children: [
2712
- "Version ",
2713
- version
2714
- ] }),
2715
- isDefault && /* @__PURE__ */ jsx11("span", { className: getClassName5("defaultBadge"), children: "Default" }),
2716
- isMarkedForDeletion && /* @__PURE__ */ jsx11("span", { className: getClassName5("deleteBadge"), children: "Marked for deletion" })
2717
- ] }),
2718
- /* @__PURE__ */ jsxs4("div", { className: getClassName5("versionActions"), children: [
2719
- !isDefault && !isMarkedForDeletion && /* @__PURE__ */ jsx11(
2720
- Button2,
2721
- {
2722
- variant: "secondary",
2723
- onClick: () => setSelectedVersion(version),
2724
- children: "Set as Default"
2725
- }
2726
- ),
2727
- /* @__PURE__ */ jsx11(
2728
- Button2,
2729
- {
2730
- variant: isMarkedForDeletion ? "secondary" : "secondary",
2731
- onClick: () => toggleVersionForDeletion(version),
2732
- children: isMarkedForDeletion ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
2733
- /* @__PURE__ */ jsx11(X, { size: 14 }),
2734
- "Undo"
2735
- ] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
2736
- /* @__PURE__ */ jsx11(Trash2, { size: 14 }),
2737
- "Delete"
2738
- ] })
2739
- }
2740
- )
2741
- ] })
2742
- ]
2743
- },
2744
- version
2745
- );
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);
2746
3107
  }) })
2747
3108
  ] }),
2748
3109
  versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
2749
3110
  /* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
2750
- /* @__PURE__ */ jsx11("p", { className: getClassName5("sectionDescription"), children: "Choose what to do with components using deleted versions" }),
2751
3111
  /* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsxs4(
2752
3112
  "select",
2753
3113
  {
@@ -2770,30 +3130,26 @@ var ComponentItem = (props) => {
2770
3130
  }
2771
3131
  ) })
2772
3132
  ] })
2773
- ] }),
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
+ ] }) }) }),
2774
3138
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("modalFooter"), children: [
2775
3139
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("footerLeft"), children: [
2776
- /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
3140
+ useVersioning ? /* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
2777
3141
  /* @__PURE__ */ jsx11(Check, { size: 16 }),
2778
- "Apply Changes"
2779
- ] }),
2780
- /* @__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: [
2781
3145
  /* @__PURE__ */ jsx11(X, { size: 16 }),
2782
- "Cancel"
3146
+ " Cancel"
2783
3147
  ] })
2784
3148
  ] }),
2785
- /* @__PURE__ */ jsx11("div", { className: getClassName5("footerRight"), children: /* @__PURE__ */ jsxs4(
2786
- Button2,
2787
- {
2788
- size: "medium",
2789
- variant: "secondary",
2790
- onClick: handleDemolishClick,
2791
- children: [
2792
- /* @__PURE__ */ jsx11(Trash2, { size: 16 }),
2793
- "Demolish Component"
2794
- ]
2795
- }
2796
- ) })
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
+ ] }) })
2797
3153
  ] })
2798
3154
  ] }) })
2799
3155
  ] });
@@ -2801,6 +3157,27 @@ var ComponentItem = (props) => {
2801
3157
  return /* @__PURE__ */ jsx11(Fragment5, { children: props.children });
2802
3158
  };
2803
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
+
2804
3181
  // src/puck/lib/dissolve-all-soft-components.ts
2805
3182
  function extractDependencies2(softComponents, componentName, version) {
2806
3183
  var _a, _b;
@@ -3009,6 +3386,7 @@ export {
3009
3386
  Modal,
3010
3387
  SoftConfigProvider,
3011
3388
  confirm,
3389
+ createActionCallback,
3012
3390
  createSoftConfigStore,
3013
3391
  createUseSoftConfig,
3014
3392
  notify,