@netlisian/softconfig 0.1.2 → 0.1.3

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.
@@ -1,10 +1,91 @@
1
1
  import * as zustand from 'zustand';
2
2
  import { StoreApi } from 'zustand';
3
- import { History, AppState, PuckApi, ComponentData, ComponentConfig, DefaultComponentProps, Field, Config, Fields, RootData, AsFieldProps, WithChildren, Metadata, ResolveDataTrigger, PuckAction, Data } from '@measured/puck';
3
+ import * as _measured_puck from '@measured/puck';
4
+ import { DefaultComponentProps, Field, Config, Fields, History, AppState, PuckApi, ComponentData, ComponentConfig, RootData, AsFieldProps, WithChildren, Metadata, ResolveDataTrigger, PuckAction, Data } from '@measured/puck';
4
5
  import * as React$1 from 'react';
5
6
  import React__default, { ReactNode, ReactElement } from 'react';
6
7
  import * as react_jsx_runtime from 'react/jsx-runtime';
7
8
 
9
+ type BuilderRootConfig = {
10
+ _name: string;
11
+ _category?: string;
12
+ _version?: string;
13
+ _versions?: string[];
14
+ _fields?: {
15
+ name: string;
16
+ type: Field["type"];
17
+ }[];
18
+ _fieldSettings?: {
19
+ [key: string]: any;
20
+ };
21
+ };
22
+ type BuilderComponentConfig = {
23
+ _slot?: {
24
+ slot: string;
25
+ }[];
26
+ _map?: {
27
+ to: string | string[];
28
+ from: string | string[];
29
+ transform?: (inputs: any[], props: DefaultComponentProps) => any;
30
+ [key: string]: any;
31
+ }[];
32
+ [key: string]: any;
33
+ };
34
+ type BuilderConfig = Config<any, BuilderRootConfig>;
35
+
36
+ type SoftSubComponent = {
37
+ type: string;
38
+ map: BuilderComponentConfig['_map'];
39
+ components: {
40
+ [slot: string]: SoftSubComponent;
41
+ };
42
+ fixedProps?: DefaultComponentProps;
43
+ enabledSlots: {
44
+ slot: string;
45
+ name?: string;
46
+ }[];
47
+ }[];
48
+ type SoftComponent = {
49
+ name: string;
50
+ category?: string;
51
+ fields: Fields;
52
+ fieldSettings?: Record<string, any>;
53
+ defaultProps: DefaultComponentProps;
54
+ components: SoftSubComponent;
55
+ slots: {
56
+ [slot: string]: DefaultComponentProps;
57
+ };
58
+ };
59
+ type VersionedSoftComponent = {
60
+ defaultVersion: string;
61
+ name: string;
62
+ category?: string;
63
+ versions: {
64
+ [version: string]: {
65
+ fields: Fields;
66
+ fieldSettings?: Record<string, any>;
67
+ defaultProps: DefaultComponentProps;
68
+ components: SoftSubComponent;
69
+ slots: {
70
+ [slot: string]: DefaultComponentProps;
71
+ };
72
+ };
73
+ };
74
+ /**
75
+ * Dependencies map: version -> Set of component names this component depends on
76
+ * Automatically inferred from component structure but can be overridden
77
+ */
78
+ dependencies?: {
79
+ [version: string]: Set<string>;
80
+ };
81
+ };
82
+ type SoftComponents = Record<string, VersionedSoftComponent>;
83
+
84
+ type CompletedComponentResult = {
85
+ id: string;
86
+ version: string;
87
+ softComponent: VersionedSoftComponent["versions"][string];
88
+ };
8
89
  type BuildersSlice = {
9
90
  /**
10
91
  * Build a new soft component based on the selected item in history.
@@ -61,7 +142,7 @@ type BuildersSlice = {
61
142
  * - Strip the build settings fields
62
143
  * - Apply modified history to puck data.
63
144
  */
64
- complete: (appState: AppState<any>, setHistories: PuckApi["history"]["setHistories"], getItemBySelector: PuckApi["getItemBySelector"]) => string;
145
+ complete: (appState: AppState<any>, setHistories: PuckApi["history"]["setHistories"], getItemBySelector: PuckApi["getItemBySelector"]) => CompletedComponentResult;
65
146
  demolish: (componentName: string, data: AppState["data"], puckDispatch: PuckApi["dispatch"]) => void;
66
147
  inspect: (componentName: string, puckDispatch: PuckApi["dispatch"]) => void;
67
148
  /**
@@ -86,81 +167,6 @@ type BuildersSlice = {
86
167
  decompose: (componentData: ComponentData) => ComponentData[];
87
168
  };
88
169
 
89
- type BuilderRootConfig = {
90
- _name: string;
91
- _category?: string;
92
- _version?: string;
93
- _versions?: string[];
94
- _fields?: {
95
- name: string;
96
- type: Field["type"];
97
- }[];
98
- _fieldSettings?: {
99
- [key: string]: any;
100
- };
101
- };
102
- type BuilderComponentConfig = {
103
- _slot?: {
104
- slot: string;
105
- }[];
106
- _map?: {
107
- to: string | string[];
108
- from: string | string[];
109
- transform?: (inputs: any[], props: DefaultComponentProps) => any;
110
- [key: string]: any;
111
- }[];
112
- [key: string]: any;
113
- };
114
- type BuilderConfig = Config<any, BuilderRootConfig>;
115
-
116
- type SoftSubComponent = {
117
- type: string;
118
- map: BuilderComponentConfig['_map'];
119
- components: {
120
- [slot: string]: SoftSubComponent;
121
- };
122
- fixedProps?: DefaultComponentProps;
123
- enabledSlots: {
124
- slot: string;
125
- name?: string;
126
- }[];
127
- }[];
128
- type SoftComponent = {
129
- name: string;
130
- category?: string;
131
- fields: Fields;
132
- fieldSettings?: Record<string, any>;
133
- defaultProps: DefaultComponentProps;
134
- components: SoftSubComponent;
135
- slots: {
136
- [slot: string]: DefaultComponentProps;
137
- };
138
- };
139
- type VersionedSoftComponent = {
140
- defaultVersion: string;
141
- name: string;
142
- category?: string;
143
- versions: {
144
- [version: string]: {
145
- fields: Fields;
146
- fieldSettings?: Record<string, any>;
147
- defaultProps: DefaultComponentProps;
148
- components: SoftSubComponent;
149
- slots: {
150
- [slot: string]: DefaultComponentProps;
151
- };
152
- };
153
- };
154
- /**
155
- * Dependencies map: version -> Set of component names this component depends on
156
- * Automatically inferred from component structure but can be overridden
157
- */
158
- dependencies?: {
159
- [version: string]: Set<string>;
160
- };
161
- };
162
- type SoftComponents = Record<string, VersionedSoftComponent>;
163
-
164
170
  type ActionEventPayload = {
165
171
  type: "build";
166
172
  payload: {
@@ -170,11 +176,14 @@ type ActionEventPayload = {
170
176
  type: "remodel";
171
177
  payload: {
172
178
  id: string;
179
+ version?: string;
180
+ softComponent?: VersionedSoftComponent["versions"][string];
173
181
  };
174
182
  } | {
175
183
  type: "complete";
176
184
  payload: {
177
185
  id: string;
186
+ version: string;
178
187
  componentData: Record<string, any>;
179
188
  softComponent: VersionedSoftComponent["versions"][string];
180
189
  };
@@ -192,10 +201,19 @@ type ActionEventPayload = {
192
201
  id: string;
193
202
  version: string;
194
203
  };
204
+ } | {
205
+ type: "deleteVersion";
206
+ payload: {
207
+ id: string;
208
+ version: string;
209
+ migrateToVersion?: string;
210
+ };
195
211
  } | {
196
212
  type: "inspect";
197
213
  payload: {
198
214
  id: string;
215
+ version?: string;
216
+ softComponent?: VersionedSoftComponent["versions"][string];
199
217
  };
200
218
  } | {
201
219
  type: "decompose";
@@ -367,15 +385,31 @@ declare const useBuild: (name?: string) => {
367
385
  };
368
386
 
369
387
  declare const useRemodel: () => {
370
- handleRemodel: (componentName?: string) => void;
388
+ handleRemodel: (componentName?: string) => {
389
+ id: string;
390
+ version: string;
391
+ softComponent: {
392
+ fields: _measured_puck.Fields;
393
+ fieldSettings?: Record<string, any>;
394
+ defaultProps: DefaultComponentProps;
395
+ components: SoftSubComponent;
396
+ slots: {
397
+ [slot: string]: DefaultComponentProps;
398
+ };
399
+ };
400
+ } | {
401
+ id: string;
402
+ version: string;
403
+ softComponent?: undefined;
404
+ } | null;
371
405
  canRemodel: (componentName?: string) => boolean;
372
406
  };
373
407
 
374
408
  declare const useComplete: () => {
375
- handleComplete: () => string | null;
409
+ handleComplete: () => CompletedComponentResult | null;
376
410
  canComplete: boolean;
377
- newComponent: string | null;
378
- setNewComponent: React$1.Dispatch<React$1.SetStateAction<string | null>>;
411
+ newComponent: CompletedComponentResult | null;
412
+ setNewComponent: React$1.Dispatch<React$1.SetStateAction<CompletedComponentResult | null>>;
379
413
  };
380
414
 
381
415
  declare const useCancel: () => {
@@ -383,7 +417,7 @@ declare const useCancel: () => {
383
417
  canCancel: boolean;
384
418
  };
385
419
 
386
- declare const useInspect: (componentName: string | null) => void;
420
+ declare const useInspect: (component: CompletedComponentResult | null) => void;
387
421
 
388
422
  declare const useDecompose: () => {
389
423
  handleDecompose: (componentData?: ComponentData) => void;
@@ -424,7 +424,7 @@ var builderRootConfig = (config, overrides, editingComponent, showVersionFields
424
424
  )
425
425
  };
426
426
  else delete fields._fieldSettings;
427
- if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length) && (!(data == null ? void 0 : data._version) || changed._version || changed._fieldSettings)) {
427
+ if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length)) {
428
428
  const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
429
429
  delete fields._version;
430
430
  fields._version = {
@@ -1609,7 +1609,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1609
1609
  );
1610
1610
  },
1611
1611
  complete: (appState, setHistories, getItemBySelector) => {
1612
- var _a, _b, _c, _d, _e;
1612
+ var _a, _b, _c, _d, _e, _f;
1613
1613
  if (get().state === "ready") {
1614
1614
  throw new Error("Not building or remodeling a component.");
1615
1615
  }
@@ -1694,8 +1694,21 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1694
1694
  editableComponentIds: /* @__PURE__ */ new Set()
1695
1695
  });
1696
1696
  });
1697
+ if (!version) {
1698
+ throw new Error("Failed to resolve completed component version.");
1699
+ }
1700
+ const completedSoftComponent = (_f = get().softComponents[componentName]) == null ? void 0 : _f.versions[version];
1701
+ if (!completedSoftComponent) {
1702
+ throw new Error(
1703
+ `Completed soft component "${componentName}" version "${version}" not found.`
1704
+ );
1705
+ }
1697
1706
  get().rebuildDependents(componentName, version);
1698
- return componentName;
1707
+ return {
1708
+ id: componentName,
1709
+ version,
1710
+ softComponent: completedSoftComponent
1711
+ };
1699
1712
  },
1700
1713
  inspect: (componentName, puckDispatch) => {
1701
1714
  if (get().state !== "inspecting") {
@@ -2625,28 +2638,42 @@ var useRemodel = () => {
2625
2638
  const refreshPermissions = useCustomPuck3((s) => s.refreshPermissions);
2626
2639
  const { triggerAction } = useActionEvent();
2627
2640
  const handleRemodel = (componentName) => {
2641
+ var _a, _b, _c;
2628
2642
  if (status !== "ready") {
2629
2643
  notify.error("Can only remodel when in ready state.");
2630
- return;
2644
+ return null;
2631
2645
  }
2632
2646
  const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
2633
2647
  if (!name || !Object.keys(softComponents).includes(name)) {
2634
2648
  notify.error("Selected component is not a soft component.");
2635
- return;
2649
+ return null;
2636
2650
  }
2651
+ const selectedVersion = ((_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.version) || ((_b = softComponents[name]) == null ? void 0 : _b.defaultVersion);
2652
+ const selectedSoftComponent = selectedVersion ? (_c = softComponents[name]) == null ? void 0 : _c.versions[selectedVersion] : void 0;
2637
2653
  try {
2638
2654
  remodel(history, selectedItem, itemSelector, dispatch, refreshPermissions);
2639
2655
  void triggerAction({
2640
2656
  type: "remodel",
2641
2657
  payload: {
2642
- id: name
2658
+ id: name,
2659
+ version: selectedVersion,
2660
+ softComponent: selectedSoftComponent
2643
2661
  }
2644
2662
  });
2663
+ if (selectedVersion && selectedSoftComponent) {
2664
+ return {
2665
+ id: name,
2666
+ version: selectedVersion,
2667
+ softComponent: selectedSoftComponent
2668
+ };
2669
+ }
2670
+ return { id: name, version: selectedVersion };
2645
2671
  } catch (error) {
2646
2672
  console.error("Failed to remodel:", error);
2647
2673
  notify.error(
2648
2674
  "Failed to remodel: " + (error instanceof Error ? error.message : String(error))
2649
2675
  );
2676
+ return null;
2650
2677
  }
2651
2678
  };
2652
2679
  const canRemodel = (componentName) => {
@@ -2666,31 +2693,29 @@ var useComplete = () => {
2666
2693
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2667
2694
  const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2668
2695
  const status = useSoftConfig((s) => s.state);
2669
- const softComponents = useSoftConfig((s) => s.softComponents);
2670
2696
  const [newComponent, setNewComponent] = (0, import_react7.useState)(null);
2671
2697
  const { triggerAction } = useActionEvent();
2672
2698
  const handleComplete = (0, import_react7.useCallback)(() => {
2673
- var _a, _b;
2674
2699
  if (status === "ready") {
2675
2700
  notify.error("Not building or remodeling a component.");
2676
2701
  return null;
2677
2702
  }
2678
2703
  try {
2679
- const componentName = complete(appState, setHistories, getItemBySelector);
2680
- setNewComponent(componentName);
2704
+ const completedComponent = complete(appState, setHistories, getItemBySelector);
2705
+ setNewComponent(completedComponent);
2681
2706
  const componentData = appState.data.root;
2682
- const softComponent = (_b = softComponents[componentName]) == null ? void 0 : _b.versions[(_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion];
2683
- if (softComponent && componentData) {
2707
+ if (componentData) {
2684
2708
  void triggerAction({
2685
2709
  type: "complete",
2686
2710
  payload: {
2687
- id: componentName,
2711
+ id: completedComponent.id,
2712
+ version: completedComponent.version,
2688
2713
  componentData,
2689
- softComponent
2714
+ softComponent: completedComponent.softComponent
2690
2715
  }
2691
2716
  });
2692
2717
  }
2693
- return componentName;
2718
+ return completedComponent;
2694
2719
  } catch (error) {
2695
2720
  console.error("Failed to complete:", error);
2696
2721
  notify.error(
@@ -2698,7 +2723,7 @@ var useComplete = () => {
2698
2723
  );
2699
2724
  return null;
2700
2725
  }
2701
- }, [complete, appState, setHistories, status, softComponents, triggerAction, getItemBySelector]);
2726
+ }, [complete, appState, setHistories, status, triggerAction, getItemBySelector]);
2702
2727
  const canComplete = status === "building" || status === "remodeling";
2703
2728
  return { handleComplete, canComplete, newComponent, setNewComponent };
2704
2729
  };
@@ -2737,23 +2762,25 @@ var useCancel = () => {
2737
2762
  var import_puck9 = require("@measured/puck");
2738
2763
  var import_react8 = require("react");
2739
2764
  var useCustomPuck6 = (0, import_puck9.createUsePuck)();
2740
- var useInspect = (componentName) => {
2765
+ var useInspect = (component) => {
2741
2766
  const inspect = useSoftConfig((s) => s.builder.inspect);
2742
2767
  const dispatch = useCustomPuck6((s) => s.dispatch);
2743
2768
  const status = useSoftConfig((s) => s.state);
2744
2769
  const { triggerAction } = useActionEvent();
2745
2770
  (0, import_react8.useEffect)(() => {
2746
2771
  if (status !== "inspecting") return;
2747
- if (!componentName) {
2772
+ if (!component) {
2748
2773
  notify.error("No component to inspect.");
2749
2774
  return;
2750
2775
  }
2751
2776
  try {
2752
- inspect(componentName, dispatch);
2777
+ inspect(component.id, dispatch);
2753
2778
  void triggerAction({
2754
2779
  type: "inspect",
2755
2780
  payload: {
2756
- id: componentName
2781
+ id: component.id,
2782
+ version: component.version,
2783
+ softComponent: component.softComponent
2757
2784
  }
2758
2785
  });
2759
2786
  } catch (error) {
@@ -2762,7 +2789,7 @@ var useInspect = (componentName) => {
2762
2789
  "Failed to inspect: " + (error instanceof Error ? error.message : String(error))
2763
2790
  );
2764
2791
  }
2765
- }, [status, componentName, inspect, dispatch, triggerAction]);
2792
+ }, [status, component, inspect, dispatch, triggerAction]);
2766
2793
  };
2767
2794
 
2768
2795
  // src/puck/actions/useDecompose.tsx
@@ -2978,9 +3005,9 @@ var Header = ({
2978
3005
  {
2979
3006
  variant: "primary",
2980
3007
  onClick: () => {
2981
- const name = handleComplete();
2982
- if (name) {
2983
- setNewComponent(name);
3008
+ const completedComponent = handleComplete();
3009
+ if (completedComponent) {
3010
+ setNewComponent(completedComponent);
2984
3011
  }
2985
3012
  },
2986
3013
  children: "Complete"
@@ -3095,14 +3122,14 @@ var confirm = (message) => __async(null, null, function* () {
3095
3122
  });
3096
3123
 
3097
3124
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/DrawerItem.module.css#css-module
3098
- var DrawerItem_module_default = { "DrawerItem": "_DrawerItem_29z19_1", "DrawerItem--insertDisabled": "_DrawerItem--insertDisabled_29z19_14", "DrawerItem-content": "_DrawerItem-content_29z19_21", "DrawerItem-name": "_DrawerItem-name_29z19_31", "DrawerItem-version": "_DrawerItem-version_29z19_35", "DrawerItem-actions": "_DrawerItem-actions_29z19_40", "DrawerItem-settingsButton": "_DrawerItem-settingsButton_29z19_46", "DrawerItem-grip": "_DrawerItem-grip_29z19_56", "DrawerItem-modal": "_DrawerItem-modal_29z19_63", "DrawerItem-modalHeader": "_DrawerItem-modalHeader_29z19_70", "DrawerItem-modalTitle": "_DrawerItem-modalTitle_29z19_75", "DrawerItem-modalSubtitle": "_DrawerItem-modalSubtitle_29z19_82", "DrawerItem-modalBody": "_DrawerItem-modalBody_29z19_88", "DrawerItem-section": "_DrawerItem-section_29z19_97", "DrawerItem-sectionTitle": "_DrawerItem-sectionTitle_29z19_103", "DrawerItem-sectionDescription": "_DrawerItem-sectionDescription_29z19_110", "DrawerItem-versionList": "_DrawerItem-versionList_29z19_116", "DrawerItem-versionRow": "_DrawerItem-versionRow_29z19_122", "DrawerItem-versionRow--isDefault": "_DrawerItem-versionRow--isDefault_29z19_133", "DrawerItem-versionRow--isMarkedForDeletion": "_DrawerItem-versionRow--isMarkedForDeletion_29z19_138", "DrawerItem-versionInfo": "_DrawerItem-versionInfo_29z19_143", "DrawerItem-versionNumber": "_DrawerItem-versionNumber_29z19_150", "DrawerItem-defaultBadge": "_DrawerItem-defaultBadge_29z19_156", "DrawerItem-deleteBadge": "_DrawerItem-deleteBadge_29z19_167", "DrawerItem-versionActions": "_DrawerItem-versionActions_29z19_178", "DrawerItem-migrationOptions": "_DrawerItem-migrationOptions_29z19_184", "DrawerItem-select": "_DrawerItem-select_29z19_188", "DrawerItem-modalFooter": "_DrawerItem-modalFooter_29z19_209", "DrawerItem-footerLeft": "_DrawerItem-footerLeft_29z19_218", "DrawerItem-footerRight": "_DrawerItem-footerRight_29z19_223" };
3125
+ var DrawerItem_module_default = { "DrawerItem": "_DrawerItem_182aj_1", "DrawerItem--insertDisabled": "_DrawerItem--insertDisabled_182aj_14", "DrawerItem-content": "_DrawerItem-content_182aj_21", "DrawerItem-name": "_DrawerItem-name_182aj_31", "DrawerItem-version": "_DrawerItem-version_182aj_35", "DrawerItem-actions": "_DrawerItem-actions_182aj_40", "DrawerItem-settingsButton": "_DrawerItem-settingsButton_182aj_46", "DrawerItem-grip": "_DrawerItem-grip_182aj_56", "DrawerItem-modal": "_DrawerItem-modal_182aj_63", "DrawerItem-modalHeader": "_DrawerItem-modalHeader_182aj_71", "DrawerItem-modalTitle": "_DrawerItem-modalTitle_182aj_77", "DrawerItem-modalSubtitle": "_DrawerItem-modalSubtitle_182aj_84", "DrawerItem-modalBody": "_DrawerItem-modalBody_182aj_90", "DrawerItem-section": "_DrawerItem-section_182aj_100", "DrawerItem-sectionTitle": "_DrawerItem-sectionTitle_182aj_106", "DrawerItem-sectionDescription": "_DrawerItem-sectionDescription_182aj_113", "DrawerItem-versionList": "_DrawerItem-versionList_182aj_119", "DrawerItem-versionRow": "_DrawerItem-versionRow_182aj_125", "DrawerItem-versionRow--isDefault": "_DrawerItem-versionRow--isDefault_182aj_136", "DrawerItem-versionRow--isMarkedForDeletion": "_DrawerItem-versionRow--isMarkedForDeletion_182aj_141", "DrawerItem-versionInfo": "_DrawerItem-versionInfo_182aj_146", "DrawerItem-versionNumber": "_DrawerItem-versionNumber_182aj_153", "DrawerItem-defaultBadge": "_DrawerItem-defaultBadge_182aj_159", "DrawerItem-deleteBadge": "_DrawerItem-deleteBadge_182aj_170", "DrawerItem-versionActions": "_DrawerItem-versionActions_182aj_181", "DrawerItem-migrationOptions": "_DrawerItem-migrationOptions_182aj_187", "DrawerItem-migrationList": "_DrawerItem-migrationList_182aj_191", "DrawerItem-migrationOption": "_DrawerItem-migrationOption_182aj_187", "DrawerItem-migrationOption--isSelected": "_DrawerItem-migrationOption--isSelected_182aj_229", "DrawerItem-migrationOptionLabel": "_DrawerItem-migrationOptionLabel_182aj_234", "DrawerItem-modalFooter": "_DrawerItem-modalFooter_182aj_240", "DrawerItem-footerLeft": "_DrawerItem-footerLeft_182aj_250", "DrawerItem-footerRight": "_DrawerItem-footerRight_182aj_255" };
3099
3126
 
3100
3127
  // src/puck/components/modal/index.tsx
3101
3128
  var import_react10 = require("react");
3102
3129
  var import_react_dom = require("react-dom");
3103
3130
 
3104
3131
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css#css-module
3105
- var styles_module_default2 = { "Modal": "_Modal_pvj02_1", "Modal--isOpen": "_Modal--isOpen_pvj02_29", "Modal-inner": "_Modal-inner_pvj02_37" };
3132
+ var styles_module_default2 = { "Modal": "_Modal_1t9ot_1", "Modal--isOpen": "_Modal--isOpen_1t9ot_29", "Modal-inner": "_Modal-inner_1t9ot_37" };
3106
3133
 
3107
3134
  // src/puck/components/modal/index.tsx
3108
3135
  var import_jsx_runtime10 = require("react/jsx-runtime");
@@ -3116,18 +3143,43 @@ var Modal = ({
3116
3143
  (0, import_react10.useEffect)(() => {
3117
3144
  setRootEl(document.getElementById("puck-portal-root"));
3118
3145
  }, []);
3146
+ (0, import_react10.useEffect)(() => {
3147
+ if (!isOpen) {
3148
+ return;
3149
+ }
3150
+ const handleEscape = (event) => {
3151
+ if (event.key === "Escape") {
3152
+ onClose();
3153
+ }
3154
+ };
3155
+ document.addEventListener("keydown", handleEscape);
3156
+ return () => document.removeEventListener("keydown", handleEscape);
3157
+ }, [isOpen, onClose]);
3119
3158
  if (!rootEl) {
3120
3159
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", {});
3121
3160
  }
3122
3161
  return (0, import_react_dom.createPortal)(
3123
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: getClassName4({ isOpen }), onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3162
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3124
3163
  "div",
3125
3164
  {
3126
- className: getClassName4("inner"),
3127
- onClick: (e) => e.stopPropagation(),
3128
- children
3165
+ className: getClassName4({ isOpen }),
3166
+ onClick: (event) => {
3167
+ if (event.target === event.currentTarget) {
3168
+ onClose();
3169
+ }
3170
+ },
3171
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
3172
+ "div",
3173
+ {
3174
+ className: getClassName4("inner"),
3175
+ role: "dialog",
3176
+ "aria-modal": "true",
3177
+ onClick: (e) => e.stopPropagation(),
3178
+ children
3179
+ }
3180
+ )
3129
3181
  }
3130
- ) }),
3182
+ ),
3131
3183
  rootEl
3132
3184
  );
3133
3185
  };
@@ -3150,13 +3202,14 @@ var DrawerItem = (props) => {
3150
3202
  );
3151
3203
  const { handleDemolish } = useDemolish();
3152
3204
  const { handleSetDefaultVersion, getVersions, getDefaultVersion } = useSetDefaultVersion();
3205
+ const { triggerAction } = useActionEvent();
3153
3206
  const [isEditing, setIsEditing] = (0, import_react11.useState)(false);
3154
3207
  const [isHovering, setIsHovering] = (0, import_react11.useState)(false);
3155
3208
  const [selectedVersion, setSelectedVersion] = (0, import_react11.useState)("");
3156
3209
  const [versionsToDelete, setVersionsToDelete] = (0, import_react11.useState)(
3157
3210
  /* @__PURE__ */ new Set()
3158
3211
  );
3159
- const [migrateVersionMap, setMigrateVersionMap] = (0, import_react11.useState)({});
3212
+ const [migrationTarget, setMigrationTarget] = (0, import_react11.useState)("decompose");
3160
3213
  const useVersioning = useSoftConfig((s) => s.showVersionFields);
3161
3214
  const versions = getVersions(props.name);
3162
3215
  const defaultVersion = getDefaultVersion(props.name);
@@ -3177,19 +3230,27 @@ var DrawerItem = (props) => {
3177
3230
  break;
3178
3231
  } else {
3179
3232
  removeSoftComponentVersion(props.name, version);
3233
+ void triggerAction({
3234
+ type: "deleteVersion",
3235
+ payload: {
3236
+ id: props.name,
3237
+ version,
3238
+ migrateToVersion: migrationTarget
3239
+ }
3240
+ });
3180
3241
  }
3181
3242
  }
3182
3243
  }
3183
3244
  setIsEditing(false);
3184
3245
  setSelectedVersion("");
3185
3246
  setVersionsToDelete(/* @__PURE__ */ new Set());
3186
- setMigrateVersionMap({});
3247
+ setMigrationTarget("decompose");
3187
3248
  });
3188
3249
  const handleCancel = () => {
3189
3250
  setIsEditing(false);
3190
3251
  setSelectedVersion("");
3191
3252
  setVersionsToDelete(/* @__PURE__ */ new Set());
3192
- setMigrateVersionMap({});
3253
+ setMigrationTarget("decompose");
3193
3254
  };
3194
3255
  const toggleVersionForDeletion = (version) => {
3195
3256
  const newSet = new Set(versionsToDelete);
@@ -3211,6 +3272,13 @@ var DrawerItem = (props) => {
3211
3272
  });
3212
3273
  if (softComponents.has(props.name)) {
3213
3274
  const availableVersions = versions.filter((v) => !versionsToDelete.has(v));
3275
+ const migrationTargets = [
3276
+ { value: "decompose", label: "Decompose to basic elements" },
3277
+ ...availableVersions.map((version) => ({
3278
+ value: version,
3279
+ label: `Migrate to Version ${version}`
3280
+ }))
3281
+ ];
3214
3282
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
3215
3283
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3216
3284
  "div",
@@ -3281,30 +3349,35 @@ var DrawerItem = (props) => {
3281
3349
  ] }, version);
3282
3350
  }) })
3283
3351
  ] }),
3284
- versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: getClassName5("section"), children: [
3352
+ versionsToDelete.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: getClassName5("section"), children: [
3285
3353
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
3286
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3287
- "select",
3354
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
3355
+ "div",
3288
3356
  {
3289
- title: "Select migration version",
3290
- className: getClassName5("select"),
3291
- value: migrateVersionMap[Array.from(versionsToDelete)[0]] || "decompose",
3292
- onChange: (e) => {
3293
- const newMap = __spreadValues({}, migrateVersionMap);
3294
- versionsToDelete.forEach((v) => {
3295
- newMap[v] = e.target.value;
3296
- });
3297
- setMigrateVersionMap(newMap);
3298
- },
3299
- children: [
3300
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "decompose", children: "Decompose to basic elements" }),
3301
- availableVersions.map((v) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("option", { value: v, children: [
3302
- "Migrate to Version ",
3303
- v
3304
- ] }, v))
3305
- ]
3357
+ className: getClassName5("migrationList"),
3358
+ role: "radiogroup",
3359
+ "aria-label": "Migration target",
3360
+ children: migrationTargets.map((target) => {
3361
+ const isSelected = migrationTarget === target.value;
3362
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
3363
+ "button",
3364
+ {
3365
+ type: "button",
3366
+ role: "radio",
3367
+ "aria-checked": isSelected,
3368
+ className: `${getClassName5("migrationOption")} ${isSelected ? getClassName5("migrationOption--isSelected") : ""}`,
3369
+ onClick: () => setMigrationTarget(target.value),
3370
+ children: [
3371
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: getClassName5("migrationOptionLabel"), children: target.label }),
3372
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react2.Check, { size: 14 })
3373
+ ]
3374
+ },
3375
+ target.value
3376
+ );
3377
+ })
3306
3378
  }
3307
- ) })
3379
+ ) }),
3380
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: getClassName5("helpText"), children: "Choose where to move existing instances of the deleted versions." })
3308
3381
  ] })
3309
3382
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("section"), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { children: [
3310
3383
  "Manage high-level settings for the ",
@@ -3414,11 +3487,6 @@ var Drawer = (_props) => {
3414
3487
  key
3415
3488
  )) });
3416
3489
  }
3417
- console.log(
3418
- getClassName6(),
3419
- getCategoryClassName(),
3420
- getCategoryClassName({ isExpanded: true })
3421
- );
3422
3490
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: getClassName6(), children: [
3423
3491
  categoryEntries.map(([id, cat]) => {
3424
3492
  var _a2, _b2, _c;