@netlisian/softconfig 0.0.11 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
File without changes
package/dist/index.css CHANGED
File without changes
package/dist/index.d.mts CHANGED
File without changes
package/dist/index.d.ts CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
package/dist/index.mjs CHANGED
File without changes
@@ -1,5 +1,4 @@
1
- /* css-module:D:osamuProjects
2
- etlisianpackagessoft-configsrcpuckcomponentserror-boundarystyles.module.css\#css-module-data */
1
+ /* css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/error-boundary/styles.module.css/#css-module-data */
3
2
  ._ErrorBoundary_1xl05_5 {
4
3
  padding: 20px;
5
4
  border: 1px solid #ff5858;
@@ -27,8 +26,7 @@ etlisianpackagessoft-configsrcpuckcomponentserror-boundarystyles.module.css\#css
27
26
  background-color: #b71c1c;
28
27
  }
29
28
 
30
- /* css-module:D:osamuProjects
31
- etlisianpackagessoft-configsrcpuckoverridesHeader.module.css\#css-module-data */
29
+ /* css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/Header.module.css/#css-module-data */
32
30
  ._Header_19oj9_1 {
33
31
  display: flex;
34
32
  justify-content: space-between;
@@ -37,8 +35,7 @@ etlisianpackagessoft-configsrcpuckoverridesHeader.module.css\#css-module-data */
37
35
  flex-wrap: wrap;
38
36
  }
39
37
 
40
- /* css-module:D:osamuProjects
41
- etlisianpackagessoft-configsrcpuckoverridesActionBar.module.css\#css-module-data */
38
+ /* css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/ActionBar.module.css/#css-module-data */
42
39
  ._ActionBar_pvuie_5 {
43
40
  align-items: center;
44
41
  cursor: default;
@@ -122,9 +119,8 @@ etlisianpackagessoft-configsrcpuckoverridesActionBar.module.css\#css-module-data
122
119
  margin: 0;
123
120
  }
124
121
 
125
- /* css-module:D:osamuProjects
126
- etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-data */
127
- ._ComponentItem_lp9eh_1 {
122
+ /* css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/overrides/ComponentItem.module.css/#css-module-data */
123
+ ._ComponentItem_1kbi2_1 {
128
124
  background: var(--puck-color-white);
129
125
  cursor: grab;
130
126
  border: 1px solid var(--puck-color-grey-09);
@@ -136,7 +132,13 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
136
132
  transition: background-color 50ms ease-in, color 50ms ease-in;
137
133
  display: flex;
138
134
  }
139
- ._ComponentItem-content_lp9eh_14 {
135
+ ._ComponentItem--insertDisabled_1kbi2_14 {
136
+ cursor: not-allowed;
137
+ color: var(--puck-color-grey-5);
138
+ background: var(--puck-color-grey-11);
139
+ pointer-events: none;
140
+ }
141
+ ._ComponentItem-content_1kbi2_21 {
140
142
  flex: 1;
141
143
  display: flex;
142
144
  flex-direction: column;
@@ -145,53 +147,53 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
145
147
  white-space: nowrap;
146
148
  overflow-x: hidden;
147
149
  }
148
- ._ComponentItem-name_lp9eh_24 {
149
- font-weight: 500;
150
+ ._ComponentItem-name_1kbi2_31 {
151
+ font-weight: 400;
150
152
  }
151
- ._ComponentItem-version_lp9eh_28 {
153
+ ._ComponentItem-version_1kbi2_35 {
152
154
  font-size: 10px;
153
155
  color: var(--puck-color-grey-05);
154
156
  }
155
- ._ComponentItem-actions_lp9eh_33 {
157
+ ._ComponentItem-actions_1kbi2_40 {
156
158
  display: flex;
157
159
  align-items: center;
158
160
  gap: 8px;
159
161
  }
160
- ._ComponentItem-settingsButton_lp9eh_39 {
162
+ ._ComponentItem-settingsButton_1kbi2_46 {
161
163
  opacity: 0;
162
164
  transition: opacity 120ms ease;
163
165
  color: var(--puck-color-grey-05);
164
166
  }
165
- ._ComponentItem_lp9eh_1:hover ._ComponentItem-settingsButton_lp9eh_39 {
167
+ ._ComponentItem_1kbi2_1:hover ._ComponentItem-settingsButton_1kbi2_46 {
166
168
  opacity: 1;
167
169
  }
168
- ._ComponentItem-grip_lp9eh_49 {
170
+ ._ComponentItem-grip_1kbi2_56 {
169
171
  color: var(--puck-color-grey-05);
170
172
  display: flex;
171
173
  align-items: center;
172
174
  }
173
- ._ComponentItem-modal_lp9eh_56 {
175
+ ._ComponentItem-modal_1kbi2_63 {
174
176
  background: var(--puck-color-white);
175
177
  display: flex;
176
178
  flex-direction: column;
177
179
  height: 100%;
178
180
  }
179
- ._ComponentItem-modalHeader_lp9eh_63 {
181
+ ._ComponentItem-modalHeader_1kbi2_70 {
180
182
  padding: 24px 32px;
181
183
  border-bottom: 1px solid var(--puck-color-grey-09);
182
184
  }
183
- ._ComponentItem-modalTitle_lp9eh_68 {
185
+ ._ComponentItem-modalTitle_1kbi2_75 {
184
186
  margin: 0 0 4px 0;
185
187
  font-size: 24px;
186
188
  font-weight: 600;
187
189
  color: var(--puck-color-black);
188
190
  }
189
- ._ComponentItem-modalSubtitle_lp9eh_75 {
191
+ ._ComponentItem-modalSubtitle_1kbi2_82 {
190
192
  margin: 0;
191
193
  font-size: 14px;
192
194
  color: var(--puck-color-grey-04);
193
195
  }
194
- ._ComponentItem-modalBody_lp9eh_81 {
196
+ ._ComponentItem-modalBody_1kbi2_88 {
195
197
  flex: 1;
196
198
  padding: 32px;
197
199
  overflow-y: auto;
@@ -199,28 +201,28 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
199
201
  flex-direction: column;
200
202
  gap: 32px;
201
203
  }
202
- ._ComponentItem-section_lp9eh_90 {
204
+ ._ComponentItem-section_1kbi2_97 {
203
205
  display: flex;
204
206
  flex-direction: column;
205
207
  gap: 16px;
206
208
  }
207
- ._ComponentItem-sectionTitle_lp9eh_96 {
209
+ ._ComponentItem-sectionTitle_1kbi2_103 {
208
210
  margin: 0;
209
211
  font-size: 16px;
210
212
  font-weight: 600;
211
213
  color: var(--puck-color-black);
212
214
  }
213
- ._ComponentItem-sectionDescription_lp9eh_103 {
215
+ ._ComponentItem-sectionDescription_1kbi2_110 {
214
216
  margin: 0;
215
217
  font-size: 14px;
216
218
  color: var(--puck-color-grey-04);
217
219
  }
218
- ._ComponentItem-versionList_lp9eh_109 {
220
+ ._ComponentItem-versionList_1kbi2_116 {
219
221
  display: flex;
220
222
  flex-direction: column;
221
223
  gap: 8px;
222
224
  }
223
- ._ComponentItem-versionRow_lp9eh_115 {
225
+ ._ComponentItem-versionRow_1kbi2_122 {
224
226
  display: flex;
225
227
  justify-content: space-between;
226
228
  align-items: center;
@@ -230,26 +232,26 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
230
232
  background: var(--puck-color-white);
231
233
  transition: all 150ms ease;
232
234
  }
233
- ._ComponentItem-versionRow--isDefault_lp9eh_126 {
235
+ ._ComponentItem-versionRow--isDefault_1kbi2_133 {
234
236
  border-color: var(--puck-color-azure-07);
235
237
  background: var(--puck-color-azure-10);
236
238
  }
237
- ._ComponentItem-versionRow--isMarkedForDeletion_lp9eh_131 {
239
+ ._ComponentItem-versionRow--isMarkedForDeletion_1kbi2_138 {
238
240
  opacity: 0.6;
239
241
  background: var(--puck-color-grey-11);
240
242
  }
241
- ._ComponentItem-versionInfo_lp9eh_136 {
243
+ ._ComponentItem-versionInfo_1kbi2_143 {
242
244
  display: flex;
243
245
  align-items: center;
244
246
  gap: 12px;
245
247
  flex: 1;
246
248
  }
247
- ._ComponentItem-versionNumber_lp9eh_143 {
249
+ ._ComponentItem-versionNumber_1kbi2_150 {
248
250
  font-size: 14px;
249
251
  font-weight: 500;
250
252
  color: var(--puck-color-black);
251
253
  }
252
- ._ComponentItem-defaultBadge_lp9eh_149 {
254
+ ._ComponentItem-defaultBadge_1kbi2_156 {
253
255
  font-size: 11px;
254
256
  padding: 3px 8px;
255
257
  border-radius: 4px;
@@ -259,7 +261,7 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
259
261
  text-transform: uppercase;
260
262
  letter-spacing: 0.5px;
261
263
  }
262
- ._ComponentItem-deleteBadge_lp9eh_160 {
264
+ ._ComponentItem-deleteBadge_1kbi2_167 {
263
265
  font-size: 11px;
264
266
  padding: 3px 8px;
265
267
  border-radius: 4px;
@@ -269,15 +271,15 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
269
271
  text-transform: uppercase;
270
272
  letter-spacing: 0.5px;
271
273
  }
272
- ._ComponentItem-versionActions_lp9eh_171 {
274
+ ._ComponentItem-versionActions_1kbi2_178 {
273
275
  display: flex;
274
276
  gap: 8px;
275
277
  align-items: center;
276
278
  }
277
- ._ComponentItem-migrationOptions_lp9eh_177 {
279
+ ._ComponentItem-migrationOptions_1kbi2_184 {
278
280
  width: 100%;
279
281
  }
280
- ._ComponentItem-select_lp9eh_181 {
282
+ ._ComponentItem-select_1kbi2_188 {
281
283
  width: 100%;
282
284
  padding: 10px 12px;
283
285
  border: 1px solid var(--puck-color-grey-09);
@@ -288,14 +290,14 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
288
290
  cursor: pointer;
289
291
  transition: border-color 150ms ease;
290
292
  }
291
- ._ComponentItem-select_lp9eh_181:hover {
293
+ ._ComponentItem-select_1kbi2_188:hover {
292
294
  border-color: var(--puck-color-grey-07);
293
295
  }
294
- ._ComponentItem-select_lp9eh_181:focus {
296
+ ._ComponentItem-select_1kbi2_188:focus {
295
297
  outline: none;
296
298
  border-color: var(--puck-color-azure-07);
297
299
  }
298
- ._ComponentItem-modalFooter_lp9eh_202 {
300
+ ._ComponentItem-modalFooter_1kbi2_209 {
299
301
  padding: 20px 32px;
300
302
  border-top: 1px solid var(--puck-color-grey-09);
301
303
  display: flex;
@@ -303,17 +305,16 @@ etlisianpackagessoft-configsrcpuckoverridesComponentItem.module.css\#css-module-
303
305
  align-items: center;
304
306
  background: var(--puck-color-grey-11);
305
307
  }
306
- ._ComponentItem-footerLeft_lp9eh_211 {
308
+ ._ComponentItem-footerLeft_1kbi2_218 {
307
309
  display: flex;
308
310
  gap: 12px;
309
311
  }
310
- ._ComponentItem-footerRight_lp9eh_216 {
312
+ ._ComponentItem-footerRight_1kbi2_223 {
311
313
  display: flex;
312
314
  gap: 12px;
313
315
  }
314
316
 
315
- /* css-module:D:osamuProjects
316
- etlisianpackagessoft-configsrcpuckcomponentsmodalstyles.module.css\#css-module-data */
317
+ /* css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css/#css-module-data */
317
318
  ._Modal_pvj02_1 {
318
319
  background: color-mix(in srgb, var(--puck-color-black) 75%, transparent);
319
320
  display: none;
@@ -1,6 +1,6 @@
1
1
  import * as zustand from 'zustand';
2
2
  import { StoreApi } from 'zustand';
3
- import { History, AppState, PuckApi, ComponentConfig, ComponentData, DefaultComponentProps, Field, Config, Fields, Data } from '@measured/puck';
3
+ import { History, AppState, PuckApi, ComponentData, ComponentConfig, DefaultComponentProps, Field, Config, Fields, RootData, AsFieldProps, WithChildren, Metadata, ResolveDataTrigger, PuckAction, Data } from '@measured/puck';
4
4
  import * as react from 'react';
5
5
  import react__default, { ReactNode, ReactElement } from 'react';
6
6
  import * as react_jsx_runtime from 'react/jsx-runtime';
@@ -21,7 +21,7 @@ type BuildersSlice = {
21
21
  build: (history: History<AppState>[], selectedItem: PuckApi["selectedItem"], itemSelector: {
22
22
  index: number;
23
23
  zone?: string;
24
- } | null, puckDispatch: PuckApi["dispatch"]) => void | null;
24
+ } | null, puckDispatch: PuckApi["dispatch"], name?: string) => void | null;
25
25
  /**
26
26
  * Remodel the selected soft component by decomposing it and resetting as root.
27
27
  *
@@ -38,7 +38,7 @@ type BuildersSlice = {
38
38
  remodel: (history: History<AppState>[], selectedItem: PuckApi["selectedItem"], itemSelector: {
39
39
  index: number;
40
40
  zone?: string;
41
- } | null, puckDispatch: PuckApi["dispatch"]) => void;
41
+ } | null, puckDispatch: PuckApi["dispatch"], refreshPermission: () => void) => void;
42
42
  /**
43
43
  * Switch to a different version of the soft component being remodeled.
44
44
  *
@@ -61,7 +61,7 @@ type BuildersSlice = {
61
61
  * - Strip the build settings fields
62
62
  * - Apply modified history to puck data.
63
63
  */
64
- complete: (appState: AppState<any>, setHistories: PuckApi["history"]["setHistories"]) => string;
64
+ complete: (appState: AppState<any>, setHistories: PuckApi["history"]["setHistories"], getItemBySelector: PuckApi["getItemBySelector"]) => string;
65
65
  demolish: (componentName: string, data: AppState["data"], puckDispatch: PuckApi["dispatch"]) => void;
66
66
  inspect: (componentName: string, puckDispatch: PuckApi["dispatch"]) => void;
67
67
  /**
@@ -77,7 +77,7 @@ type BuildersSlice = {
77
77
  /** Compose multiple components into a soft component.
78
78
  * 1. SoftComponent: Get soft fields + default values from the appState.root + sub-component maps + fixedProps
79
79
  */
80
- compose: (appState: AppState, componentName: string) => [ComponentConfig, string] | undefined;
80
+ compose: (appState: AppState, componentName: string, editedItem: ComponentData, displayName: string, category?: string) => [ComponentConfig, string] | undefined;
81
81
  /** Break down a composed component into its parts.
82
82
  * 1. Get softComponentProps
83
83
  * 2. Create a virtual component with all the props from soft-component.
@@ -88,6 +88,7 @@ type BuildersSlice = {
88
88
 
89
89
  type BuilderRootConfig = {
90
90
  _name: string;
91
+ _category?: string;
91
92
  _version?: string;
92
93
  _versions?: string[];
93
94
  _fields?: {
@@ -125,6 +126,8 @@ type SoftSubComponent = {
125
126
  }[];
126
127
  }[];
127
128
  type SoftComponent = {
129
+ name: string;
130
+ category?: string;
128
131
  fields: Fields;
129
132
  fieldSettings?: Record<string, any>;
130
133
  defaultProps: DefaultComponentProps;
@@ -135,6 +138,8 @@ type SoftComponent = {
135
138
  };
136
139
  type VersionedSoftComponent = {
137
140
  defaultVersion: string;
141
+ name: string;
142
+ category?: string;
138
143
  versions: {
139
144
  [version: string]: {
140
145
  fields: Fields;
@@ -146,6 +151,13 @@ type VersionedSoftComponent = {
146
151
  };
147
152
  };
148
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
+ };
149
161
  };
150
162
  type SoftComponents = Record<string, VersionedSoftComponent>;
151
163
 
@@ -163,8 +175,8 @@ type ActionEventPayload = {
163
175
  type: "complete";
164
176
  payload: {
165
177
  id: string;
166
- componentData: DefaultComponentProps;
167
- softComponent: SoftComponent;
178
+ componentData: Record<string, any>;
179
+ softComponent: VersionedSoftComponent["versions"][string];
168
180
  };
169
181
  } | {
170
182
  type: "cancel";
@@ -205,6 +217,10 @@ type RenderFunc<Props extends {
205
217
  children: ReactNode;
206
218
  }> = (props: Props) => ReactElement;
207
219
  type Overrides = {
220
+ componentNameToKey?: (displayName: string, context: {
221
+ existingKeys: string[];
222
+ state: "building" | "remodeling" | "ready" | "inspecting";
223
+ }) => string;
208
224
  map?: RenderFunc<{
209
225
  rootProps: BuilderRootConfig;
210
226
  toOptions: {
@@ -229,6 +245,16 @@ type Overrides = {
229
245
  softComponent: VersionedSoftComponent["versions"][string];
230
246
  }) => ((inputs: any[], props: DefaultComponentProps) => any) | undefined;
231
247
  onActions?: OnActionsCallback;
248
+ name?: Field<string>;
249
+ categories?: Field<string | undefined>;
250
+ onRootsDataChange?: (data: RootData<AsFieldProps<WithChildren<BuilderRootConfig>>>, params: {
251
+ changed: Partial<Record<keyof BuilderRootConfig, boolean> & {
252
+ id: string;
253
+ }>;
254
+ lastData: RootData<AsFieldProps<WithChildren<BuilderRootConfig>>> | null;
255
+ metadata: Metadata;
256
+ trigger: ResolveDataTrigger;
257
+ }) => void;
232
258
  };
233
259
 
234
260
  type Status = "building" | "remodeling" | "ready" | "inspecting";
@@ -269,9 +295,50 @@ type AppStore = {
269
295
  hydrateTransforms: () => void;
270
296
  setSoftComponentDefaultVersion: (key: string, version: string) => void;
271
297
  removeSoftComponent: (key: string) => void;
298
+ editingComponentId: string | null;
299
+ editableComponentIds: Set<string>;
300
+ setEditableComponentIds: (ids: Set<string>) => void;
301
+ addEditableComponentId: (id: string) => void;
302
+ clearEditingState: () => void;
303
+ /**
304
+ * Reverse dependency graph: componentName -> Set of components that depend on it
305
+ * Used to efficiently rebuild dependent components when a soft component is updated
306
+ */
307
+ dependencyGraph: Map<string, Set<string>>;
308
+ /**
309
+ * Rebuild all dependent components after a soft component is updated
310
+ * Only rebuilds components that depend on the changed component
311
+ *
312
+ * @param componentName - The component that was updated
313
+ * @param version - The version that was updated
314
+ */
315
+ rebuildDependents: (componentName: string, version: string) => void;
316
+ /**
317
+ * Iframe document reference for applying styling and edit visibility
318
+ * Stored as a mutable ref to avoid triggering store updates.
319
+ */
320
+ iframeDocRef: {
321
+ current: Document | null;
322
+ };
323
+ /**
324
+ * Get the current iframe document reference
325
+ */
326
+ getIframeDoc: () => Document | null;
327
+ /**
328
+ * Set the iframe document reference without causing re-renders
329
+ */
330
+ setIframeDoc: (doc: Document | null) => void;
331
+ /**
332
+ * Flag to control visibility of version config fields
333
+ */
334
+ showVersionFields: boolean;
335
+ /**
336
+ * Toggle the visibility of version config fields
337
+ */
338
+ setShowVersionFields: (show: boolean) => void;
272
339
  };
273
340
  type AppStoreApi = StoreApi<AppStore>;
274
- declare const createSoftConfigStore: (hardConfig?: Config, softComponents?: SoftComponents, overrides?: Overrides, onActions?: OnActionsCallback) => zustand.UseBoundStore<Omit<Omit<StoreApi<AppStore>, "subscribe"> & {
341
+ declare const createSoftConfigStore: (hardConfig?: Config, softComponents?: SoftComponents, overrides?: Overrides, onActions?: OnActionsCallback, showVersionFields?: boolean) => zustand.UseBoundStore<Omit<StoreApi<AppStore>, "subscribe"> & {
275
342
  subscribe: {
276
343
  (listener: (selectedState: AppStore, previousSelectedState: AppStore) => void): () => void;
277
344
  <U>(selector: (state: AppStore) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
@@ -279,35 +346,20 @@ declare const createSoftConfigStore: (hardConfig?: Config, softComponents?: Soft
279
346
  fireImmediately?: boolean;
280
347
  } | undefined): () => void;
281
348
  };
282
- }, "setState" | "devtools"> & {
283
- setState(partial: AppStore | Partial<AppStore> | ((state: AppStore) => AppStore | Partial<AppStore>), replace?: false | undefined, action?: (string | {
284
- [x: string]: unknown;
285
- [x: number]: unknown;
286
- [x: symbol]: unknown;
287
- type: string;
288
- }) | undefined): void;
289
- setState(state: AppStore | ((state: AppStore) => AppStore), replace: true, action?: (string | {
290
- [x: string]: unknown;
291
- [x: number]: unknown;
292
- [x: symbol]: unknown;
293
- type: string;
294
- }) | undefined): void;
295
- devtools: {
296
- cleanup: () => void;
297
- };
298
349
  }>;
299
350
 
300
- declare const SoftConfigProvider: ({ children, hardConfig, softComponents, overrides, value, onActions, }: {
301
- children: (softConfig: Config, softComponents: SoftComponents) => ReactNode;
351
+ declare const SoftConfigProvider: ({ children, hardConfig, softComponents, overrides, value, onActions, useVersioning, }: {
352
+ children: (softConfig: Config, softComponents: SoftComponents, iframeDoc: AppStore["setIframeDoc"], validateAction: (action: PuckAction) => boolean) => ReactNode;
302
353
  hardConfig: Config;
303
354
  softComponents: SoftComponents;
304
- overrides: Overrides;
355
+ overrides?: Overrides;
305
356
  value?: StoreApi<AppStore>;
306
357
  onActions?: OnActionsCallback;
358
+ useVersioning?: boolean;
307
359
  }) => react_jsx_runtime.JSX.Element;
308
360
 
309
- declare const createUseSoftConfig: () => <T>(selector: (state: AppStore) => T) => T;
310
- declare const useSoftConfig: <T>(selector: (state: AppStore) => T) => T;
361
+ declare const createUseSoftConfig: () => <T>(selector: (state: AppStore) => T, equalityFn?: (a: T, b: T) => boolean) => T;
362
+ declare const useSoftConfig: <T>(selector: (state: AppStore) => T, equalityFn?: (a: T, b: T) => boolean) => T;
311
363
 
312
364
  declare const useBuild: () => {
313
365
  handleBuild: () => void;
@@ -386,6 +438,15 @@ declare const setConfirmHandler: (handler: ConfirmHandler) => void;
386
438
  */
387
439
  declare const confirm: (message: string) => Promise<boolean>;
388
440
 
441
+ /**
442
+ * Create an action callback that validates and handles actions with undo support
443
+ *
444
+ * @param validateAction Function to validate if an action is allowed
445
+ * @param undo Function to undo the last action (from Puck's history)
446
+ * @returns Action handler function
447
+ */
448
+ declare const createActionCallback: (validateAction: (action: PuckAction) => boolean, undo: PuckApi["history"]["back"]) => (action: PuckAction) => void;
449
+
389
450
  /**
390
451
  * Resolves soft components in data by dissolving them to hard components only.
391
452
  *
@@ -411,4 +472,4 @@ declare const Modal: ({ children, onClose, isOpen, }: {
411
472
  isOpen: boolean;
412
473
  }) => react_jsx_runtime.JSX.Element;
413
474
 
414
- export { ActionBarOverride as ActionBar, type ActionEventPayload, type AppStore, type AppStoreApi, type BuilderComponentConfig, type BuilderConfig, type BuilderRootConfig, ComponentItem, Header, Modal, type OnActionsCallback, type Overrides, type SoftComponent, type SoftComponents, SoftConfigProvider, type VersionedSoftComponent, confirm, createSoftConfigStore, createUseSoftConfig, notify, resolveSoftConfig, setConfirmHandler, setNotificationHandler, useBuild, useCancel, useComplete, useDecompose, useDemolish, useInspect, useRemodel, useSetDefaultVersion, useSoftConfig };
475
+ export { ActionBarOverride as ActionBar, type ActionEventPayload, type AppStore, type AppStoreApi, type BuilderComponentConfig, type BuilderConfig, type BuilderRootConfig, ComponentItem, Header, Modal, type OnActionsCallback, type Overrides, type SoftComponent, type SoftComponents, SoftConfigProvider, type VersionedSoftComponent, confirm, createActionCallback, createSoftConfigStore, createUseSoftConfig, notify, resolveSoftConfig, setConfirmHandler, setNotificationHandler, useBuild, useCancel, useComplete, useDecompose, useDemolish, useInspect, useRemodel, useSetDefaultVersion, useSoftConfig };