@netlisian/softconfig 0.0.0-alpha-20251026130436
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 +83 -0
- package/dist/index.css +337 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +1 -0
- package/dist/puck/index.css +337 -0
- package/dist/puck/index.d.mts +345 -0
- package/dist/puck/index.d.ts +345 -0
- package/dist/puck/index.js +2842 -0
- package/dist/puck/index.mjs +2792 -0
- package/package.json +65 -0
|
@@ -0,0 +1,2792 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
+
var __objRest = (source, exclude) => {
|
|
22
|
+
var target = {};
|
|
23
|
+
for (var prop in source)
|
|
24
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
if (source != null && __getOwnPropSymbols)
|
|
27
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
var __async = (__this, __arguments, generator) => {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
var fulfilled = (value) => {
|
|
36
|
+
try {
|
|
37
|
+
step(generator.next(value));
|
|
38
|
+
} catch (e) {
|
|
39
|
+
reject(e);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var rejected = (value) => {
|
|
43
|
+
try {
|
|
44
|
+
step(generator.throw(value));
|
|
45
|
+
} catch (e) {
|
|
46
|
+
reject(e);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
50
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// src/puck/store/index.tsx
|
|
55
|
+
import { create } from "zustand";
|
|
56
|
+
import { subscribeWithSelector, devtools } from "zustand/middleware";
|
|
57
|
+
|
|
58
|
+
// src/puck/lib/get-root-props.ts
|
|
59
|
+
var getRootProps = (appState) => appState.data.root.props;
|
|
60
|
+
|
|
61
|
+
// src/puck/lib/builder/root-config.tsx
|
|
62
|
+
import {
|
|
63
|
+
createUsePuck,
|
|
64
|
+
walkTree
|
|
65
|
+
} from "@measured/puck";
|
|
66
|
+
|
|
67
|
+
// src/puck/lib/get-field-settings.tsx
|
|
68
|
+
import { AutoField } from "@measured/puck";
|
|
69
|
+
import { jsx } from "react/jsx-runtime";
|
|
70
|
+
var getFieldSettings = (_fields, _fieldSettings, deep) => {
|
|
71
|
+
return (_fields || []).reduce((fields, field) => {
|
|
72
|
+
const fieldSettings = {
|
|
73
|
+
// placeholder: { type: "text", label: "Placeholder" },
|
|
74
|
+
};
|
|
75
|
+
const currentFieldSettings = _fieldSettings == null ? void 0 : _fieldSettings[field.name];
|
|
76
|
+
switch (field.type) {
|
|
77
|
+
case "text":
|
|
78
|
+
case "textarea":
|
|
79
|
+
fieldSettings.defaultValue = {
|
|
80
|
+
type: field.type,
|
|
81
|
+
label: "Default Value"
|
|
82
|
+
};
|
|
83
|
+
break;
|
|
84
|
+
case "number":
|
|
85
|
+
fieldSettings.defaultValue = {
|
|
86
|
+
type: field.type,
|
|
87
|
+
label: "Default Value"
|
|
88
|
+
};
|
|
89
|
+
fieldSettings.min = {
|
|
90
|
+
type: field.type,
|
|
91
|
+
label: "Minimum Value"
|
|
92
|
+
};
|
|
93
|
+
fieldSettings.max = {
|
|
94
|
+
type: field.type,
|
|
95
|
+
label: "Maximum Value"
|
|
96
|
+
};
|
|
97
|
+
fieldSettings.step = {
|
|
98
|
+
type: field.type,
|
|
99
|
+
label: "Step Size"
|
|
100
|
+
};
|
|
101
|
+
break;
|
|
102
|
+
case "radio":
|
|
103
|
+
case "select":
|
|
104
|
+
fieldSettings.defaultValue = {
|
|
105
|
+
type: "custom",
|
|
106
|
+
label: "Default Value",
|
|
107
|
+
render: ({ value, onChange, id }) => /* @__PURE__ */ jsx(
|
|
108
|
+
AutoField,
|
|
109
|
+
{
|
|
110
|
+
field: {
|
|
111
|
+
type: field.type,
|
|
112
|
+
label: "Default Value",
|
|
113
|
+
options: (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || []
|
|
114
|
+
},
|
|
115
|
+
value,
|
|
116
|
+
onChange,
|
|
117
|
+
readOnly: false,
|
|
118
|
+
id
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
};
|
|
122
|
+
fieldSettings.options = {
|
|
123
|
+
type: "array",
|
|
124
|
+
label: "Options",
|
|
125
|
+
defaultItemProps: {
|
|
126
|
+
label: "New Option",
|
|
127
|
+
value: "new"
|
|
128
|
+
},
|
|
129
|
+
arrayFields: {
|
|
130
|
+
label: { type: "text", label: "Label" },
|
|
131
|
+
value: {
|
|
132
|
+
type: "text",
|
|
133
|
+
label: "Value"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
getItemSummary(item, index) {
|
|
137
|
+
return item.label || `Option ${(index || 0) + 1}`;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
break;
|
|
141
|
+
case "array":
|
|
142
|
+
fieldSettings.summary = {
|
|
143
|
+
type: "select",
|
|
144
|
+
label: "Summary Field",
|
|
145
|
+
options: [
|
|
146
|
+
{
|
|
147
|
+
label: "Default Numbering",
|
|
148
|
+
value: ""
|
|
149
|
+
},
|
|
150
|
+
...((currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || []).map((f) => ({
|
|
151
|
+
label: f.name,
|
|
152
|
+
value: f.name
|
|
153
|
+
}))
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
case "object":
|
|
157
|
+
fieldSettings.subFields = {
|
|
158
|
+
type: "array",
|
|
159
|
+
label: "Sub Fields",
|
|
160
|
+
defaultItemProps: {
|
|
161
|
+
name: "New Sub Field",
|
|
162
|
+
type: "text"
|
|
163
|
+
},
|
|
164
|
+
arrayFields: {
|
|
165
|
+
name: { type: "text", label: "Name" },
|
|
166
|
+
type: {
|
|
167
|
+
type: "select",
|
|
168
|
+
options: deep ? [
|
|
169
|
+
{
|
|
170
|
+
label: "Text",
|
|
171
|
+
value: "text"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
label: "Number",
|
|
175
|
+
value: "number"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
label: "Select",
|
|
179
|
+
value: "select"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
label: "Radio",
|
|
183
|
+
value: "radio"
|
|
184
|
+
}
|
|
185
|
+
] : [
|
|
186
|
+
{
|
|
187
|
+
label: "Text",
|
|
188
|
+
value: "text"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
label: "Number",
|
|
192
|
+
value: "number"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
label: "Select",
|
|
196
|
+
value: "select"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
label: "Radio",
|
|
200
|
+
value: "radio"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
label: "Array",
|
|
204
|
+
value: "array"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
label: "Object",
|
|
208
|
+
value: "object"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
label: "Reference",
|
|
212
|
+
value: "reference"
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
getItemSummary(item, index) {
|
|
218
|
+
return item.name || `Field ${(index || 0) + 1}`;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
if (!deep)
|
|
222
|
+
fieldSettings.subFieldSettings = {
|
|
223
|
+
type: "object",
|
|
224
|
+
label: "Sub Field Settings",
|
|
225
|
+
objectFields: (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) ? getFieldSettings(
|
|
226
|
+
currentFieldSettings.subFields,
|
|
227
|
+
currentFieldSettings.subFieldSettings,
|
|
228
|
+
true
|
|
229
|
+
) : {}
|
|
230
|
+
};
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
fields[field.name] = {
|
|
234
|
+
type: "object",
|
|
235
|
+
label: field.name,
|
|
236
|
+
objectFields: fieldSettings
|
|
237
|
+
};
|
|
238
|
+
return fields;
|
|
239
|
+
}, {});
|
|
240
|
+
};
|
|
241
|
+
var get_field_settings_default = getFieldSettings;
|
|
242
|
+
|
|
243
|
+
// src/puck/lib/get-settings-by-path.ts
|
|
244
|
+
function getFieldSettingsByPath(fieldSettings, path) {
|
|
245
|
+
return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// src/puck/lib/set-prop-by-path.ts
|
|
249
|
+
function setPropertyByPath(props, path, value) {
|
|
250
|
+
const parts = path.split(".");
|
|
251
|
+
const last = parts.pop();
|
|
252
|
+
let cur = props;
|
|
253
|
+
for (const p of parts) {
|
|
254
|
+
if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
|
|
255
|
+
cur = cur[p];
|
|
256
|
+
}
|
|
257
|
+
cur[last] = value;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// src/puck/lib/builder/root-config.tsx
|
|
261
|
+
import { useEffect } from "react";
|
|
262
|
+
|
|
263
|
+
// src/puck/context/useStore.ts
|
|
264
|
+
import { createContext, useContext } from "react";
|
|
265
|
+
import { useStore } from "zustand";
|
|
266
|
+
var appStoreContext = createContext(createSoftConfigStore());
|
|
267
|
+
var createUseSoftConfig = () => {
|
|
268
|
+
return function useSoftConfig2(selector) {
|
|
269
|
+
const context = useContext(appStoreContext);
|
|
270
|
+
return useStore(context, selector);
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
var useSoftConfig = createUseSoftConfig();
|
|
274
|
+
|
|
275
|
+
// src/puck/lib/builder/root-config.tsx
|
|
276
|
+
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
277
|
+
var useCustomPuck = createUsePuck();
|
|
278
|
+
var breakVersion = (version) => {
|
|
279
|
+
const [major, minor, patch] = version.split(".").map((v) => parseInt(v));
|
|
280
|
+
return [major, minor, patch];
|
|
281
|
+
};
|
|
282
|
+
var updateVersion = (version, increment) => {
|
|
283
|
+
let [major, minor, patch] = breakVersion(version);
|
|
284
|
+
if (increment === "major") {
|
|
285
|
+
major += 1;
|
|
286
|
+
minor = 0;
|
|
287
|
+
patch = 0;
|
|
288
|
+
} else if (increment === "minor") {
|
|
289
|
+
minor += 1;
|
|
290
|
+
patch = 0;
|
|
291
|
+
} else {
|
|
292
|
+
patch += 1;
|
|
293
|
+
}
|
|
294
|
+
return `${major}.${minor}.${patch}`;
|
|
295
|
+
};
|
|
296
|
+
var builderRootConfig = (config, overrides, editingComponent) => ({
|
|
297
|
+
fields: {
|
|
298
|
+
_name: {
|
|
299
|
+
type: "text",
|
|
300
|
+
label: "Soft Component Name"
|
|
301
|
+
},
|
|
302
|
+
_fields: {
|
|
303
|
+
type: "array",
|
|
304
|
+
label: "Fields",
|
|
305
|
+
defaultItemProps: {
|
|
306
|
+
name: "New Field",
|
|
307
|
+
type: "text"
|
|
308
|
+
},
|
|
309
|
+
getItemSummary(item, index) {
|
|
310
|
+
return item.name || `Field ${(index || 0) + 1}`;
|
|
311
|
+
},
|
|
312
|
+
arrayFields: {
|
|
313
|
+
name: { type: "text", label: "Name" },
|
|
314
|
+
type: {
|
|
315
|
+
type: "select",
|
|
316
|
+
label: "Type",
|
|
317
|
+
options: [
|
|
318
|
+
{ label: "Text", value: "text" },
|
|
319
|
+
{ label: "Textarea", value: "textarea" },
|
|
320
|
+
{ label: "Number", value: "number" },
|
|
321
|
+
{ label: "Select", value: "select" },
|
|
322
|
+
{ label: "Radio", value: "radio" },
|
|
323
|
+
{ label: "Array", value: "array" },
|
|
324
|
+
{ label: "Object", value: "object" }
|
|
325
|
+
// { label: "Reference", value: "reference" },
|
|
326
|
+
]
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
resolveFields({ props: data }, { fields, changed }) {
|
|
332
|
+
var _a, _b;
|
|
333
|
+
if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
|
|
334
|
+
if ((_a = data == null ? void 0 : data._fields) == null ? void 0 : _a.length)
|
|
335
|
+
fields._fieldSettings = {
|
|
336
|
+
type: "object",
|
|
337
|
+
label: "Field Settings",
|
|
338
|
+
objectFields: get_field_settings_default(
|
|
339
|
+
data._fields || [],
|
|
340
|
+
data._fieldSettings || {}
|
|
341
|
+
)
|
|
342
|
+
};
|
|
343
|
+
else delete fields._fieldSettings;
|
|
344
|
+
if (((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length) && (!(data == null ? void 0 : data._version) || changed._version || changed._fieldSettings)) {
|
|
345
|
+
const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
|
|
346
|
+
delete fields._version;
|
|
347
|
+
fields._version = {
|
|
348
|
+
type: "select",
|
|
349
|
+
label: "Version",
|
|
350
|
+
options: [
|
|
351
|
+
...data._versions.map((v) => ({ label: v, value: v })),
|
|
352
|
+
{
|
|
353
|
+
label: `${updateVersion(latestVersion, "patch")} (Patch)`,
|
|
354
|
+
value: updateVersion(latestVersion, "patch")
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
label: `${updateVersion(latestVersion, "minor")} (Minor)`,
|
|
358
|
+
value: updateVersion(latestVersion, "minor")
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
label: `${updateVersion(latestVersion, "major")} (Major)`,
|
|
362
|
+
value: updateVersion(latestVersion, "major")
|
|
363
|
+
}
|
|
364
|
+
]
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
return fields;
|
|
368
|
+
},
|
|
369
|
+
resolveData: (props) => {
|
|
370
|
+
return {
|
|
371
|
+
props,
|
|
372
|
+
readOnly: Boolean(editingComponent) ? {
|
|
373
|
+
_name: true
|
|
374
|
+
} : void 0
|
|
375
|
+
};
|
|
376
|
+
},
|
|
377
|
+
render: (props) => {
|
|
378
|
+
const fieldSettings = props == null ? void 0 : props._fieldSettings;
|
|
379
|
+
const data = useCustomPuck((s) => s.appState.data);
|
|
380
|
+
const dispatch = useCustomPuck((s) => s.dispatch);
|
|
381
|
+
const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
|
|
382
|
+
const setVersion = useSoftConfig((s) => s.builder.setVersion);
|
|
383
|
+
const state = useSoftConfig((s) => s.state);
|
|
384
|
+
useEffect(() => {
|
|
385
|
+
const propagateChanges = setTimeout(() => {
|
|
386
|
+
if (!fieldSettings || Object.keys(fieldSettings).length === 0) return;
|
|
387
|
+
walkTree(
|
|
388
|
+
data,
|
|
389
|
+
{
|
|
390
|
+
components: config.components
|
|
391
|
+
},
|
|
392
|
+
(content) => content.map((child) => {
|
|
393
|
+
var _a;
|
|
394
|
+
const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
|
|
395
|
+
if (map.length) {
|
|
396
|
+
map.forEach(({ from, to, transform }) => {
|
|
397
|
+
if (!from || !to) return;
|
|
398
|
+
const fromPaths = Array.isArray(from) ? from : [from];
|
|
399
|
+
const toPaths = Array.isArray(to) ? to : [to];
|
|
400
|
+
const inputValues = fromPaths.map(
|
|
401
|
+
(f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
|
|
402
|
+
);
|
|
403
|
+
console.log(inputValues);
|
|
404
|
+
let value = transform ? transform(
|
|
405
|
+
inputValues.map((v) => v == null ? void 0 : v.defaultValue),
|
|
406
|
+
child.props
|
|
407
|
+
) : inputValues[0];
|
|
408
|
+
if (Array.isArray(value)) {
|
|
409
|
+
value.forEach((val, i) => {
|
|
410
|
+
if (toPaths[i]) {
|
|
411
|
+
const originalValue = getFieldSettingsByPath(
|
|
412
|
+
child.props,
|
|
413
|
+
toPaths[i]
|
|
414
|
+
);
|
|
415
|
+
if (originalValue !== val) {
|
|
416
|
+
const itemSelector = getSelectorForId(child.props.id);
|
|
417
|
+
if (!itemSelector) return;
|
|
418
|
+
setPropertyByPath(child.props, toPaths[i], val);
|
|
419
|
+
dispatch({
|
|
420
|
+
type: "replace",
|
|
421
|
+
data: child,
|
|
422
|
+
destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
|
|
423
|
+
destinationZone: itemSelector == null ? void 0 : itemSelector.zone
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
} else if (toPaths[0]) {
|
|
429
|
+
const setting = getFieldSettingsByPath(
|
|
430
|
+
fieldSettings,
|
|
431
|
+
fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
|
|
432
|
+
);
|
|
433
|
+
const defaultValue = setting == null ? void 0 : setting.defaultValue;
|
|
434
|
+
const originalValue = getFieldSettingsByPath(
|
|
435
|
+
child.props,
|
|
436
|
+
toPaths[0]
|
|
437
|
+
);
|
|
438
|
+
const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
|
|
439
|
+
if (originalValue !== finalValue) {
|
|
440
|
+
const itemSelector = getSelectorForId(child.props.id);
|
|
441
|
+
if (!itemSelector) return;
|
|
442
|
+
setPropertyByPath(child.props, toPaths[0], finalValue);
|
|
443
|
+
dispatch({
|
|
444
|
+
type: "replace",
|
|
445
|
+
data: child,
|
|
446
|
+
destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
|
|
447
|
+
destinationZone: itemSelector == null ? void 0 : itemSelector.zone
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return child;
|
|
454
|
+
})
|
|
455
|
+
);
|
|
456
|
+
}, 300);
|
|
457
|
+
return () => clearTimeout(propagateChanges);
|
|
458
|
+
}, [fieldSettings]);
|
|
459
|
+
useEffect(() => {
|
|
460
|
+
var _a;
|
|
461
|
+
if (state !== "remodeling") return;
|
|
462
|
+
if (!(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
|
|
463
|
+
const currentVersion = props == null ? void 0 : props._version;
|
|
464
|
+
if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
|
|
465
|
+
setVersion(props._name, currentVersion, props, dispatch);
|
|
466
|
+
}
|
|
467
|
+
}, [props == null ? void 0 : props._version]);
|
|
468
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: props.children });
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// src/puck/lib/builder/generate-field-options.ts
|
|
473
|
+
function generateFieldOptions(fields, selectedFields, prefix = "") {
|
|
474
|
+
const opts = [];
|
|
475
|
+
function recurse(current, prefix2) {
|
|
476
|
+
Object.entries(current).forEach(([key, fld]) => {
|
|
477
|
+
if (fld.type === "slot") return;
|
|
478
|
+
if (key === "_map") return;
|
|
479
|
+
if (key === "_slotEnabled") return;
|
|
480
|
+
const path = prefix2 ? `${prefix2}.${key}` : key;
|
|
481
|
+
if (selectedFields.includes(path)) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
opts.push({ label: path, value: path });
|
|
485
|
+
if (fld.type === "object" && fld.objectFields) {
|
|
486
|
+
recurse(fld.objectFields, path);
|
|
487
|
+
}
|
|
488
|
+
if (fld.type === "array" && fld.arrayFields) {
|
|
489
|
+
recurse(fld.arrayFields, path);
|
|
490
|
+
}
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
recurse(fields, prefix);
|
|
494
|
+
return opts;
|
|
495
|
+
}
|
|
496
|
+
function generateDynamicFieldOptions(_fields, _fieldSettings, prefix = "") {
|
|
497
|
+
const opts = [];
|
|
498
|
+
if (!_fields || !_fieldSettings) return opts;
|
|
499
|
+
function recurse(fields, fieldSettings, currentPrefix) {
|
|
500
|
+
fields.forEach((field) => {
|
|
501
|
+
var _a;
|
|
502
|
+
const settings = fieldSettings[field.name];
|
|
503
|
+
const path = currentPrefix ? `${currentPrefix}.${field.name}` : field.name;
|
|
504
|
+
opts.push({ label: path, value: path });
|
|
505
|
+
if ((_a = settings == null ? void 0 : settings.subFields) == null ? void 0 : _a.length) {
|
|
506
|
+
recurse(settings.subFields, settings.subFieldSettings || {}, path);
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
recurse(_fields, _fieldSettings, prefix);
|
|
511
|
+
return opts;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// src/puck/components/error-boundary/index.tsx
|
|
515
|
+
import { Component } from "react";
|
|
516
|
+
|
|
517
|
+
// src/puck/lib/get-class-name-factory.ts
|
|
518
|
+
import classnames from "classnames";
|
|
519
|
+
var getClassNameFactory = (rootClass, styles, config = { baseClass: "" }) => (options = {}) => {
|
|
520
|
+
if (typeof options === "string") {
|
|
521
|
+
const descendant = options;
|
|
522
|
+
const style = styles[`${rootClass}-${descendant}`];
|
|
523
|
+
if (style) {
|
|
524
|
+
return config.baseClass + styles[`${rootClass}-${descendant}`] || "";
|
|
525
|
+
}
|
|
526
|
+
return "";
|
|
527
|
+
} else if (typeof options === "object") {
|
|
528
|
+
const modifiers = options;
|
|
529
|
+
const prefixedModifiers = {};
|
|
530
|
+
for (let modifier in modifiers) {
|
|
531
|
+
prefixedModifiers[styles[`${rootClass}--${modifier}`]] = modifiers[modifier];
|
|
532
|
+
}
|
|
533
|
+
const c = styles[rootClass];
|
|
534
|
+
return config.baseClass + classnames(__spreadValues({
|
|
535
|
+
[c]: !!c
|
|
536
|
+
}, prefixedModifiers));
|
|
537
|
+
} else {
|
|
538
|
+
return config.baseClass + styles[rootClass] || "";
|
|
539
|
+
}
|
|
540
|
+
};
|
|
541
|
+
var get_class_name_factory_default = getClassNameFactory;
|
|
542
|
+
|
|
543
|
+
// src/puck/components/error-boundary/styles.module.css
|
|
544
|
+
var styles_default = {};
|
|
545
|
+
|
|
546
|
+
// src/puck/components/error-boundary/index.tsx
|
|
547
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
548
|
+
var getClassName = get_class_name_factory_default("ErrorBoundary", styles_default);
|
|
549
|
+
var ErrorBoundary = class extends Component {
|
|
550
|
+
constructor(props) {
|
|
551
|
+
super(props);
|
|
552
|
+
this.resetError = () => {
|
|
553
|
+
this.setState({
|
|
554
|
+
hasError: false,
|
|
555
|
+
error: null
|
|
556
|
+
});
|
|
557
|
+
};
|
|
558
|
+
this.state = {
|
|
559
|
+
hasError: false,
|
|
560
|
+
error: null
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
static getDerivedStateFromError(error) {
|
|
564
|
+
return {
|
|
565
|
+
hasError: true,
|
|
566
|
+
error
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
componentDidCatch(error, errorInfo) {
|
|
570
|
+
console.error("Error caught by ErrorBoundary:", error, errorInfo);
|
|
571
|
+
}
|
|
572
|
+
render() {
|
|
573
|
+
if (this.state.hasError) {
|
|
574
|
+
if (typeof this.props.fallback === "function") {
|
|
575
|
+
return this.props.fallback(this.state.error, this.resetError);
|
|
576
|
+
}
|
|
577
|
+
if (this.props.fallback) {
|
|
578
|
+
return this.props.fallback;
|
|
579
|
+
}
|
|
580
|
+
return /* @__PURE__ */ jsxs("div", { className: getClassName(), children: [
|
|
581
|
+
/* @__PURE__ */ jsx3("h3", { className: getClassName("title"), children: "Component Error" }),
|
|
582
|
+
/* @__PURE__ */ jsxs("details", { className: getClassName("details"), children: [
|
|
583
|
+
/* @__PURE__ */ jsx3("summary", { children: "Show error details" }),
|
|
584
|
+
this.state.error && this.state.error.toString()
|
|
585
|
+
] }),
|
|
586
|
+
/* @__PURE__ */ jsx3(
|
|
587
|
+
"button",
|
|
588
|
+
{
|
|
589
|
+
onClick: this.resetError,
|
|
590
|
+
className: getClassName("button"),
|
|
591
|
+
children: "Try Again"
|
|
592
|
+
}
|
|
593
|
+
)
|
|
594
|
+
] });
|
|
595
|
+
}
|
|
596
|
+
return this.props.children;
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
|
|
600
|
+
// src/puck/lib/builder/builder-config.tsx
|
|
601
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
602
|
+
var builderConfig = (config, overrides, editingComponent) => ({
|
|
603
|
+
root: builderRootConfig(config, overrides, editingComponent),
|
|
604
|
+
components: Object.entries(__spreadValues({}, config.components)).reduce(
|
|
605
|
+
(acc, [name, component]) => {
|
|
606
|
+
if (!editingComponent || name !== editingComponent) {
|
|
607
|
+
let _a;
|
|
608
|
+
const tempComponent = __spreadProps(__spreadValues({}, component), {
|
|
609
|
+
resolveFields(data, params) {
|
|
610
|
+
return __async(this, null, function* () {
|
|
611
|
+
let fields = {};
|
|
612
|
+
if (!fields._slot) {
|
|
613
|
+
const slotFields = Object.entries(params.fields).filter(
|
|
614
|
+
([_, field]) => field.type === "slot"
|
|
615
|
+
);
|
|
616
|
+
if (slotFields.length)
|
|
617
|
+
fields._slot = {
|
|
618
|
+
type: "array",
|
|
619
|
+
label: "Enable Dropdown Slots",
|
|
620
|
+
getItemSummary(item, index) {
|
|
621
|
+
return item.slot || `Slot ${(index || 0) + 1}`;
|
|
622
|
+
},
|
|
623
|
+
arrayFields: {
|
|
624
|
+
slot: {
|
|
625
|
+
type: "select",
|
|
626
|
+
label: "Slot",
|
|
627
|
+
options: [
|
|
628
|
+
{ label: "Select a slot", value: "" },
|
|
629
|
+
...slotFields.filter(
|
|
630
|
+
([fieldName, field]) => {
|
|
631
|
+
var _a2;
|
|
632
|
+
return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
|
|
633
|
+
(s) => s.slot === fieldName
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
).map(([fieldName, field]) => ({
|
|
637
|
+
label: field.label || fieldName,
|
|
638
|
+
value: fieldName
|
|
639
|
+
}))
|
|
640
|
+
]
|
|
641
|
+
},
|
|
642
|
+
name: {
|
|
643
|
+
type: "text",
|
|
644
|
+
label: "Name",
|
|
645
|
+
placeholder: "Optional Slot Name"
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
|
|
651
|
+
if (!fields._map) {
|
|
652
|
+
const rootProps = getRootProps(params.appState);
|
|
653
|
+
fields._map = overrides.map ? {
|
|
654
|
+
type: "custom",
|
|
655
|
+
render: ({ value, onChange, id }) => {
|
|
656
|
+
return overrides.map({
|
|
657
|
+
rootProps,
|
|
658
|
+
value,
|
|
659
|
+
onChange,
|
|
660
|
+
id,
|
|
661
|
+
props: data.props || {},
|
|
662
|
+
fromOptions: generateDynamicFieldOptions(
|
|
663
|
+
(rootProps == null ? void 0 : rootProps._fields) || [],
|
|
664
|
+
(rootProps == null ? void 0 : rootProps._fieldSettings) || {}
|
|
665
|
+
),
|
|
666
|
+
toOptions: generateFieldOptions(defaultFields, [])
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
} : {
|
|
670
|
+
type: "array",
|
|
671
|
+
label: "Dynamic Field Map",
|
|
672
|
+
arrayFields: {
|
|
673
|
+
from: {
|
|
674
|
+
type: "select",
|
|
675
|
+
label: "From",
|
|
676
|
+
options: [
|
|
677
|
+
{ label: "Select a field", value: "" },
|
|
678
|
+
...generateDynamicFieldOptions(
|
|
679
|
+
(rootProps == null ? void 0 : rootProps._fields) || [],
|
|
680
|
+
(rootProps == null ? void 0 : rootProps._fieldSettings) || {}
|
|
681
|
+
)
|
|
682
|
+
]
|
|
683
|
+
},
|
|
684
|
+
to: {
|
|
685
|
+
type: "select",
|
|
686
|
+
label: "To",
|
|
687
|
+
options: [
|
|
688
|
+
{ label: "Select a field", value: "" },
|
|
689
|
+
...generateFieldOptions(defaultFields, [])
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
fields = __spreadValues(__spreadValues({}, fields), defaultFields);
|
|
696
|
+
return fields;
|
|
697
|
+
});
|
|
698
|
+
},
|
|
699
|
+
resolveData: ({ props }, { lastData }) => {
|
|
700
|
+
var _a2;
|
|
701
|
+
const _map = props._map || [];
|
|
702
|
+
const readOnlyFields = _map.flatMap((item) => item.to);
|
|
703
|
+
if (_map.length) {
|
|
704
|
+
return {
|
|
705
|
+
props,
|
|
706
|
+
readOnly: readOnlyFields.reduce(
|
|
707
|
+
(acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
|
|
708
|
+
{}
|
|
709
|
+
)
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
|
|
713
|
+
if (prevMap && prevMap.length === 1) {
|
|
714
|
+
const lastField = prevMap[0].to;
|
|
715
|
+
if (typeof lastField === "string") {
|
|
716
|
+
return {
|
|
717
|
+
props,
|
|
718
|
+
readOnly: { [lastField]: false }
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
if (Array.isArray(lastField)) {
|
|
722
|
+
return {
|
|
723
|
+
props,
|
|
724
|
+
readOnly: lastField.reduce(
|
|
725
|
+
(acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
|
|
726
|
+
{}
|
|
727
|
+
)
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
return {
|
|
732
|
+
props,
|
|
733
|
+
readOnly: {}
|
|
734
|
+
};
|
|
735
|
+
},
|
|
736
|
+
render: (props) => {
|
|
737
|
+
return /* @__PURE__ */ jsx4(ErrorBoundary, { children: component.render(props) });
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
acc[name] = tempComponent;
|
|
741
|
+
}
|
|
742
|
+
return acc;
|
|
743
|
+
},
|
|
744
|
+
{}
|
|
745
|
+
)
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
// src/puck/lib/soft-component-from-appstate.ts
|
|
749
|
+
var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
|
|
750
|
+
if (!content || !Array.isArray(content)) return [];
|
|
751
|
+
return content.map((componentProps) => {
|
|
752
|
+
var _a, _b, _c;
|
|
753
|
+
const componentConfig = componentConfigs[componentProps.type];
|
|
754
|
+
const enabledSlotNames = new Set(
|
|
755
|
+
(((_a = componentProps.props) == null ? void 0 : _a._slot) || []).map((s) => s.slot)
|
|
756
|
+
);
|
|
757
|
+
const components = Object.entries((componentConfig == null ? void 0 : componentConfig.fields) || {}).filter(
|
|
758
|
+
([key, field]) => field.type === "slot" && !enabledSlotNames.has(key)
|
|
759
|
+
// Skip if slot is enabled
|
|
760
|
+
).reduce(
|
|
761
|
+
(acc, [fieldKey, _]) => {
|
|
762
|
+
var _a2;
|
|
763
|
+
acc[fieldKey] = getSubComponents(
|
|
764
|
+
((_a2 = componentProps.props) == null ? void 0 : _a2[fieldKey]) || [],
|
|
765
|
+
componentConfigs,
|
|
766
|
+
fieldSettings,
|
|
767
|
+
slots
|
|
768
|
+
);
|
|
769
|
+
return acc;
|
|
770
|
+
},
|
|
771
|
+
{}
|
|
772
|
+
) || {};
|
|
773
|
+
const fixedProps = __spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props);
|
|
774
|
+
(componentProps.props._slot || []).forEach(
|
|
775
|
+
(s) => {
|
|
776
|
+
var _a2;
|
|
777
|
+
if (s.slot)
|
|
778
|
+
slots[s.name || `${componentProps.props.id}-${s.slot}`] = componentProps.props[s.slot] || ((_a2 = componentConfig == null ? void 0 : componentConfig.defaultProps) == null ? void 0 : _a2[s.slot]);
|
|
779
|
+
}
|
|
780
|
+
);
|
|
781
|
+
const subComponent = {
|
|
782
|
+
map: ((_b = componentProps.props) == null ? void 0 : _b._map) || [],
|
|
783
|
+
fixedProps,
|
|
784
|
+
type: componentProps.type,
|
|
785
|
+
components,
|
|
786
|
+
enabledSlots: ((_c = componentProps.props) == null ? void 0 : _c._slot) || []
|
|
787
|
+
};
|
|
788
|
+
return subComponent;
|
|
789
|
+
});
|
|
790
|
+
};
|
|
791
|
+
var softFieldsToPuckFields = (fields, fieldSettings) => {
|
|
792
|
+
return (fields == null ? void 0 : fields.reduce(
|
|
793
|
+
(acc, field) => {
|
|
794
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
795
|
+
switch (field.type) {
|
|
796
|
+
case "text":
|
|
797
|
+
case "textarea":
|
|
798
|
+
acc[field.name] = { type: field.type, label: field.name };
|
|
799
|
+
break;
|
|
800
|
+
case "number":
|
|
801
|
+
acc[field.name] = {
|
|
802
|
+
type: field.type,
|
|
803
|
+
label: field.name,
|
|
804
|
+
min: (_a = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _a.min,
|
|
805
|
+
max: (_b = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _b.max,
|
|
806
|
+
step: (_c = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _c.step
|
|
807
|
+
};
|
|
808
|
+
break;
|
|
809
|
+
case "select":
|
|
810
|
+
case "radio":
|
|
811
|
+
acc[field.name] = {
|
|
812
|
+
type: field.type,
|
|
813
|
+
label: field.name,
|
|
814
|
+
options: ((_d = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _d.options) || []
|
|
815
|
+
};
|
|
816
|
+
break;
|
|
817
|
+
// TODO: Default item props
|
|
818
|
+
case "array":
|
|
819
|
+
acc[field.name] = {
|
|
820
|
+
type: field.type,
|
|
821
|
+
label: field.name,
|
|
822
|
+
arrayFields: softFieldsToPuckFields(
|
|
823
|
+
((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
|
|
824
|
+
((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {}
|
|
825
|
+
)
|
|
826
|
+
};
|
|
827
|
+
break;
|
|
828
|
+
// TODO: Needs testing to see if it works
|
|
829
|
+
case "object":
|
|
830
|
+
acc[field.name] = {
|
|
831
|
+
type: field.type,
|
|
832
|
+
label: field.name,
|
|
833
|
+
objectFields: softFieldsToPuckFields(
|
|
834
|
+
((_g = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _g.subFields) || [],
|
|
835
|
+
((_h = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _h.subFieldSettings) || {}
|
|
836
|
+
)
|
|
837
|
+
};
|
|
838
|
+
break;
|
|
839
|
+
default:
|
|
840
|
+
acc[field.name] = { type: "text", label: field.name };
|
|
841
|
+
}
|
|
842
|
+
return acc;
|
|
843
|
+
},
|
|
844
|
+
{}
|
|
845
|
+
)) || {};
|
|
846
|
+
};
|
|
847
|
+
var softComponentFromAppState = (appState, configComponents) => {
|
|
848
|
+
var _a;
|
|
849
|
+
const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
|
|
850
|
+
const fields = rootProps._fields || [];
|
|
851
|
+
const field_settings = rootProps._fieldSettings || {};
|
|
852
|
+
const slots = {};
|
|
853
|
+
const components = getSubComponents(
|
|
854
|
+
appState.data.content || [],
|
|
855
|
+
configComponents,
|
|
856
|
+
field_settings,
|
|
857
|
+
slots
|
|
858
|
+
);
|
|
859
|
+
const defaultProps = __spreadValues(__spreadValues({}, Object.keys(field_settings).reduce(
|
|
860
|
+
(acc, field) => {
|
|
861
|
+
acc[field] = field_settings[field].defaultValue;
|
|
862
|
+
return acc;
|
|
863
|
+
},
|
|
864
|
+
{}
|
|
865
|
+
)), slots);
|
|
866
|
+
return [
|
|
867
|
+
{
|
|
868
|
+
fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, field_settings)), Object.keys(slots).reduce((acc, slot) => {
|
|
869
|
+
acc[slot] = { type: "slot", label: slot };
|
|
870
|
+
return acc;
|
|
871
|
+
}, {})),
|
|
872
|
+
defaultProps,
|
|
873
|
+
components,
|
|
874
|
+
slots
|
|
875
|
+
},
|
|
876
|
+
rootProps._version || "1.0.0"
|
|
877
|
+
];
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
// src/puck/lib/soft-component-to-appstate.ts
|
|
881
|
+
var puckFieldsToSoftFields = (fields, slots) => {
|
|
882
|
+
const softFields = [];
|
|
883
|
+
const fieldSettings = {};
|
|
884
|
+
Object.entries(fields).forEach(([fieldName, field]) => {
|
|
885
|
+
if (slots.has(fieldName)) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
if (fieldName === "_version") {
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
switch (field.type) {
|
|
892
|
+
case "text":
|
|
893
|
+
case "textarea":
|
|
894
|
+
softFields.push({ name: fieldName, type: field.type });
|
|
895
|
+
break;
|
|
896
|
+
case "number":
|
|
897
|
+
softFields.push({ name: fieldName, type: "number" });
|
|
898
|
+
fieldSettings[fieldName] = {
|
|
899
|
+
min: field.min,
|
|
900
|
+
max: field.max,
|
|
901
|
+
step: field.step
|
|
902
|
+
};
|
|
903
|
+
break;
|
|
904
|
+
case "select":
|
|
905
|
+
case "radio":
|
|
906
|
+
softFields.push({ name: fieldName, type: field.type });
|
|
907
|
+
fieldSettings[fieldName] = {
|
|
908
|
+
options: field.options || []
|
|
909
|
+
};
|
|
910
|
+
break;
|
|
911
|
+
case "array":
|
|
912
|
+
softFields.push({ name: fieldName, type: "array" });
|
|
913
|
+
const arrayFieldsResult = puckFieldsToSoftFields(
|
|
914
|
+
field.arrayFields || {},
|
|
915
|
+
/* @__PURE__ */ new Set()
|
|
916
|
+
);
|
|
917
|
+
fieldSettings[fieldName] = {
|
|
918
|
+
subFields: arrayFieldsResult.fields,
|
|
919
|
+
subFieldSettings: arrayFieldsResult.fieldSettings
|
|
920
|
+
};
|
|
921
|
+
break;
|
|
922
|
+
case "object":
|
|
923
|
+
softFields.push({ name: fieldName, type: "object" });
|
|
924
|
+
const objectFieldsResult = puckFieldsToSoftFields(
|
|
925
|
+
field.objectFields || {},
|
|
926
|
+
/* @__PURE__ */ new Set()
|
|
927
|
+
);
|
|
928
|
+
fieldSettings[fieldName] = {
|
|
929
|
+
subFields: objectFieldsResult.fields,
|
|
930
|
+
subFieldSettings: objectFieldsResult.fieldSettings
|
|
931
|
+
};
|
|
932
|
+
break;
|
|
933
|
+
default:
|
|
934
|
+
softFields.push({ name: fieldName, type: "text" });
|
|
935
|
+
}
|
|
936
|
+
if (fieldSettings[fieldName]) {
|
|
937
|
+
fieldSettings[fieldName].defaultValue = void 0;
|
|
938
|
+
} else {
|
|
939
|
+
fieldSettings[fieldName] = { defaultValue: void 0 };
|
|
940
|
+
}
|
|
941
|
+
});
|
|
942
|
+
return { fields: softFields, fieldSettings };
|
|
943
|
+
};
|
|
944
|
+
var reconstructComponents = (subComponents, componentConfigs, softComponentProps) => {
|
|
945
|
+
return subComponents.map((subComponent) => {
|
|
946
|
+
const componentConfig = componentConfigs[subComponent.type];
|
|
947
|
+
const props = __spreadValues({}, subComponent.fixedProps);
|
|
948
|
+
subComponent.map.forEach(({ from, to }) => {
|
|
949
|
+
if (softComponentProps[from] !== void 0) {
|
|
950
|
+
props[to] = softComponentProps[from];
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
if (subComponent.enabledSlots.length > 0) {
|
|
954
|
+
props._slot = subComponent.enabledSlots;
|
|
955
|
+
subComponent.enabledSlots.forEach(({ slot, name }) => {
|
|
956
|
+
const slotName = name || `${props.id}-${slot}`;
|
|
957
|
+
if (softComponentProps[slotName] !== void 0) {
|
|
958
|
+
props[slot] = softComponentProps[slotName];
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
Object.entries(subComponent.components).forEach(([slotKey, nestedComponents]) => {
|
|
963
|
+
if (nestedComponents.length > 0) {
|
|
964
|
+
props[slotKey] = reconstructComponents(
|
|
965
|
+
nestedComponents,
|
|
966
|
+
componentConfigs,
|
|
967
|
+
softComponentProps
|
|
968
|
+
);
|
|
969
|
+
} else {
|
|
970
|
+
props[slotKey] = [];
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
const componentData = {
|
|
974
|
+
type: subComponent.type,
|
|
975
|
+
props: __spreadValues({
|
|
976
|
+
id: props.id || ""
|
|
977
|
+
}, props)
|
|
978
|
+
};
|
|
979
|
+
return componentData;
|
|
980
|
+
});
|
|
981
|
+
};
|
|
982
|
+
var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs) => {
|
|
983
|
+
const slots = new Set(Object.keys(softComponent.slots));
|
|
984
|
+
const { fields, fieldSettings } = puckFieldsToSoftFields(
|
|
985
|
+
softComponent.fields,
|
|
986
|
+
slots
|
|
987
|
+
);
|
|
988
|
+
Object.entries(softComponent.defaultProps).forEach(([key, value]) => {
|
|
989
|
+
if (fieldSettings && fieldSettings[key] && !slots.has(key)) {
|
|
990
|
+
fieldSettings[key].defaultValue = value;
|
|
991
|
+
}
|
|
992
|
+
});
|
|
993
|
+
const rootProps = {
|
|
994
|
+
_name: componentName,
|
|
995
|
+
_version: version,
|
|
996
|
+
_versions: versions,
|
|
997
|
+
_fields: fields,
|
|
998
|
+
_fieldSettings: fieldSettings
|
|
999
|
+
};
|
|
1000
|
+
const content = reconstructComponents(
|
|
1001
|
+
softComponent.components,
|
|
1002
|
+
componentConfigs,
|
|
1003
|
+
componentProps
|
|
1004
|
+
);
|
|
1005
|
+
return {
|
|
1006
|
+
root: {
|
|
1007
|
+
props: __spreadValues({
|
|
1008
|
+
title: "Soft Component Builder"
|
|
1009
|
+
}, rootProps)
|
|
1010
|
+
},
|
|
1011
|
+
content
|
|
1012
|
+
};
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
// src/puck/lib/root-droppable-id.ts
|
|
1016
|
+
var rootAreaId = "root";
|
|
1017
|
+
var rootZone = "default-zone";
|
|
1018
|
+
var rootDroppableId = `${rootAreaId}:${rootZone}`;
|
|
1019
|
+
|
|
1020
|
+
// src/puck/components/soft-render/index.tsx
|
|
1021
|
+
import { useMemo, useRef } from "react";
|
|
1022
|
+
import { v4 as uuidv4 } from "uuid";
|
|
1023
|
+
import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
|
|
1024
|
+
function SoftRender({
|
|
1025
|
+
softComponentFields,
|
|
1026
|
+
softSubComponent,
|
|
1027
|
+
configComponents,
|
|
1028
|
+
props,
|
|
1029
|
+
depth = 0
|
|
1030
|
+
}) {
|
|
1031
|
+
const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
|
|
1032
|
+
const mapCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
1033
|
+
const prevPropsRef = useRef("");
|
|
1034
|
+
const propsSnapshot = JSON.stringify(props);
|
|
1035
|
+
if (prevPropsRef.current !== propsSnapshot) {
|
|
1036
|
+
mapCacheRef.current.clear();
|
|
1037
|
+
prevPropsRef.current = propsSnapshot;
|
|
1038
|
+
}
|
|
1039
|
+
const subComponentRootProps = useMemo(
|
|
1040
|
+
() => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
|
|
1041
|
+
(acc, [fieldKey]) => {
|
|
1042
|
+
acc[fieldKey] = props[fieldKey];
|
|
1043
|
+
return acc;
|
|
1044
|
+
},
|
|
1045
|
+
{}
|
|
1046
|
+
),
|
|
1047
|
+
[softComponentFields, props]
|
|
1048
|
+
);
|
|
1049
|
+
const valuesToUpdateKey = useMemo(
|
|
1050
|
+
() => JSON.stringify(subComponentRootProps),
|
|
1051
|
+
[subComponentRootProps]
|
|
1052
|
+
);
|
|
1053
|
+
return /* @__PURE__ */ jsx5(Fragment2, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
|
|
1054
|
+
var _a2;
|
|
1055
|
+
const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
|
|
1056
|
+
if (!componentConfig) return null;
|
|
1057
|
+
const resolvedProps = subComponent.fixedProps || {};
|
|
1058
|
+
const stableId = useMemo(
|
|
1059
|
+
() => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-${uuidv4()}`,
|
|
1060
|
+
[id, depth, subComponent.type]
|
|
1061
|
+
);
|
|
1062
|
+
if ((_a2 = subComponent.map) == null ? void 0 : _a2.length) {
|
|
1063
|
+
subComponent.map.forEach(({ from, to, transform }) => {
|
|
1064
|
+
const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
|
|
1065
|
+
const toPaths = Array.isArray(to) ? to : to ? [to] : [];
|
|
1066
|
+
const inputValues = fromPaths.map(
|
|
1067
|
+
(f) => getFieldSettingsByPath(props || {}, f)
|
|
1068
|
+
);
|
|
1069
|
+
const cacheKey = JSON.stringify(inputValues);
|
|
1070
|
+
let result = mapCacheRef.current.get(cacheKey);
|
|
1071
|
+
if (!result) {
|
|
1072
|
+
result = transform ? transform(inputValues, props) : inputValues[0];
|
|
1073
|
+
mapCacheRef.current.set(cacheKey, result);
|
|
1074
|
+
}
|
|
1075
|
+
if (Array.isArray(result)) {
|
|
1076
|
+
result.forEach(
|
|
1077
|
+
(val, i) => toPaths[i] && setPropertyByPath(resolvedProps, toPaths[i], val)
|
|
1078
|
+
);
|
|
1079
|
+
} else if (toPaths[0]) {
|
|
1080
|
+
setPropertyByPath(resolvedProps, toPaths[0], result);
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
Object.entries(componentConfig.fields || {}).forEach(
|
|
1085
|
+
([slotKey, field]) => {
|
|
1086
|
+
var _a3, _b;
|
|
1087
|
+
if (field.type === "slot") {
|
|
1088
|
+
const enabledSlot = (_a3 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a3.find(
|
|
1089
|
+
(s) => s.slot === slotKey
|
|
1090
|
+
);
|
|
1091
|
+
if (enabledSlot) {
|
|
1092
|
+
const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
|
|
1093
|
+
resolvedProps[slotKey] = useMemo(
|
|
1094
|
+
() => rest[slotName] || (() => null),
|
|
1095
|
+
[slotName]
|
|
1096
|
+
);
|
|
1097
|
+
} else {
|
|
1098
|
+
resolvedProps[slotKey] = useMemo(() => {
|
|
1099
|
+
return ({
|
|
1100
|
+
className,
|
|
1101
|
+
style
|
|
1102
|
+
}) => {
|
|
1103
|
+
var _a4, _b2;
|
|
1104
|
+
return /* @__PURE__ */ jsx5("div", { className, style, children: /* @__PURE__ */ jsx5(
|
|
1105
|
+
SoftRender,
|
|
1106
|
+
{
|
|
1107
|
+
softComponentFields,
|
|
1108
|
+
softSubComponent: (_b2 = (_a4 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a4[slotKey]) != null ? _b2 : [],
|
|
1109
|
+
configComponents,
|
|
1110
|
+
props,
|
|
1111
|
+
depth: depth + 1
|
|
1112
|
+
},
|
|
1113
|
+
slotKey
|
|
1114
|
+
) });
|
|
1115
|
+
};
|
|
1116
|
+
}, [valuesToUpdateKey]);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
);
|
|
1121
|
+
const ComponentRender = componentConfig.render;
|
|
1122
|
+
return /* @__PURE__ */ jsx5(ErrorBoundary, { children: /* @__PURE__ */ jsx5(
|
|
1123
|
+
ComponentRender,
|
|
1124
|
+
__spreadValues({
|
|
1125
|
+
id: stableId,
|
|
1126
|
+
editMode,
|
|
1127
|
+
puck
|
|
1128
|
+
}, resolvedProps)
|
|
1129
|
+
) }, index);
|
|
1130
|
+
}) });
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// src/puck/lib/create-versioned-component-config.tsx
|
|
1134
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1135
|
+
var createVersionedComponentConfig = (componentName, version, allVersions, config, softComponents, defaultProps) => {
|
|
1136
|
+
var _a, _b;
|
|
1137
|
+
const softConfig = config;
|
|
1138
|
+
return {
|
|
1139
|
+
fields: Object.fromEntries(
|
|
1140
|
+
(Object.entries(
|
|
1141
|
+
(_b = (_a = softComponents[componentName].versions) == null ? void 0 : _a[version]) == null ? void 0 : _b.fields
|
|
1142
|
+
) || []).filter(
|
|
1143
|
+
([key, field]) => field.type === "slot"
|
|
1144
|
+
).map(([key, field]) => [key, __spreadValues({}, field)])
|
|
1145
|
+
),
|
|
1146
|
+
defaultProps: __spreadProps(__spreadValues({}, defaultProps), {
|
|
1147
|
+
version
|
|
1148
|
+
}),
|
|
1149
|
+
resolveFields: (data) => {
|
|
1150
|
+
var _a2, _b2;
|
|
1151
|
+
const selectedVersion = ((_a2 = data.props) == null ? void 0 : _a2.version) || version;
|
|
1152
|
+
const versionedComponent = (_b2 = softComponents[componentName]) == null ? void 0 : _b2.versions[selectedVersion];
|
|
1153
|
+
const fieldsWithoutSlots = Object.fromEntries(
|
|
1154
|
+
Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").map(([key, field]) => [key, __spreadValues({}, field)])
|
|
1155
|
+
);
|
|
1156
|
+
return __spreadValues({
|
|
1157
|
+
version: {
|
|
1158
|
+
label: "Version",
|
|
1159
|
+
type: "select",
|
|
1160
|
+
options: allVersions.map((v) => ({ label: v, value: v }))
|
|
1161
|
+
}
|
|
1162
|
+
}, fieldsWithoutSlots);
|
|
1163
|
+
},
|
|
1164
|
+
render: (props) => {
|
|
1165
|
+
var _a2;
|
|
1166
|
+
const selectedVersion = props.version || version;
|
|
1167
|
+
const versionedComponent = (_a2 = softComponents[componentName]) == null ? void 0 : _a2.versions[selectedVersion];
|
|
1168
|
+
return /* @__PURE__ */ jsx6(
|
|
1169
|
+
SoftRender,
|
|
1170
|
+
{
|
|
1171
|
+
softComponentFields: versionedComponent.fields,
|
|
1172
|
+
softSubComponent: versionedComponent.components,
|
|
1173
|
+
configComponents: softConfig.components,
|
|
1174
|
+
props
|
|
1175
|
+
}
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
};
|
|
1180
|
+
|
|
1181
|
+
// src/puck/lib/generate-id.ts
|
|
1182
|
+
import { v4 as uuidv42 } from "uuid";
|
|
1183
|
+
var generateId = (type) => type ? `${type}-${uuidv42()}` : uuidv42();
|
|
1184
|
+
|
|
1185
|
+
// src/puck/lib/builder/sub-component-decomposer.tsx
|
|
1186
|
+
var subComponentDecomposer = (componentRootData, softSubComponent) => {
|
|
1187
|
+
const resolvedProps = __spreadValues({}, softSubComponent.fixedProps);
|
|
1188
|
+
softSubComponent.map.forEach((mapItem) => {
|
|
1189
|
+
var _a;
|
|
1190
|
+
const value = (_a = componentRootData.props) == null ? void 0 : _a[mapItem.from || ""];
|
|
1191
|
+
if (value !== void 0) {
|
|
1192
|
+
resolvedProps[mapItem.to] = value;
|
|
1193
|
+
}
|
|
1194
|
+
});
|
|
1195
|
+
softSubComponent.enabledSlots.forEach(({ slot, name }) => {
|
|
1196
|
+
var _a, _b;
|
|
1197
|
+
const referenceName = name || `${(_a = softSubComponent.fixedProps) == null ? void 0 : _a.id}-${slot}`;
|
|
1198
|
+
resolvedProps[slot] = ((_b = componentRootData.props) == null ? void 0 : _b[referenceName]) || [];
|
|
1199
|
+
});
|
|
1200
|
+
Object.entries(softSubComponent.components).forEach(
|
|
1201
|
+
([slotKey, subComponents]) => {
|
|
1202
|
+
resolvedProps[slotKey] = subComponents.map(
|
|
1203
|
+
(subComponent) => subComponentDecomposer(componentRootData, subComponent)
|
|
1204
|
+
);
|
|
1205
|
+
}
|
|
1206
|
+
);
|
|
1207
|
+
const accItem = {
|
|
1208
|
+
type: softSubComponent.type,
|
|
1209
|
+
props: __spreadProps(__spreadValues({}, resolvedProps), {
|
|
1210
|
+
id: generateId(softSubComponent.type)
|
|
1211
|
+
})
|
|
1212
|
+
};
|
|
1213
|
+
return accItem;
|
|
1214
|
+
};
|
|
1215
|
+
|
|
1216
|
+
// src/puck/lib/decompose-soft-component.ts
|
|
1217
|
+
function decomposeSoftComponent(componentData, softComponents) {
|
|
1218
|
+
var _a, _b;
|
|
1219
|
+
if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
|
|
1220
|
+
throw new Error("Component data must have type and id to decompose.");
|
|
1221
|
+
}
|
|
1222
|
+
const version = ((_a = componentData.props) == null ? void 0 : _a.version) || "1.0.0";
|
|
1223
|
+
const softComponent = (_b = softComponents[componentData.type]) == null ? void 0 : _b.versions[version];
|
|
1224
|
+
if (!softComponent) {
|
|
1225
|
+
throw new Error(
|
|
1226
|
+
`Soft component "${componentData.type}" version "${version}" not found.`
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
const decomposedComponentData = softComponent.components.map(
|
|
1230
|
+
(softSubComponent) => {
|
|
1231
|
+
return subComponentDecomposer(componentData, softSubComponent);
|
|
1232
|
+
}
|
|
1233
|
+
);
|
|
1234
|
+
return decomposedComponentData;
|
|
1235
|
+
}
|
|
1236
|
+
function isSoftComponent(componentType, softComponents) {
|
|
1237
|
+
return componentType in softComponents;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// src/puck/lib/demolish-soft-component.ts
|
|
1241
|
+
import { walkTree as walkTree2 } from "@measured/puck";
|
|
1242
|
+
function demolishSoftComponent(componentName, data, config, softComponents) {
|
|
1243
|
+
const resolvedData = walkTree2(data, config, (components) => {
|
|
1244
|
+
components.forEach((componentData, index) => {
|
|
1245
|
+
if (componentData.type === componentName) {
|
|
1246
|
+
const decomposed = decomposeSoftComponent(componentData, softComponents);
|
|
1247
|
+
if (decomposed.length) {
|
|
1248
|
+
components.splice(index, 1, ...decomposed);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
return components;
|
|
1253
|
+
});
|
|
1254
|
+
const newSoftComponents = __spreadValues({}, softComponents);
|
|
1255
|
+
delete newSoftComponents[componentName];
|
|
1256
|
+
const newConfig = __spreadProps(__spreadValues({}, config), {
|
|
1257
|
+
components: Object.entries(config.components).reduce(
|
|
1258
|
+
(acc, [name, component]) => {
|
|
1259
|
+
if (name !== componentName) {
|
|
1260
|
+
acc[name] = component;
|
|
1261
|
+
}
|
|
1262
|
+
return acc;
|
|
1263
|
+
},
|
|
1264
|
+
{}
|
|
1265
|
+
)
|
|
1266
|
+
});
|
|
1267
|
+
return {
|
|
1268
|
+
data: resolvedData,
|
|
1269
|
+
config: newConfig,
|
|
1270
|
+
softComponents: newSoftComponents
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
// src/puck/store/slices/builder.tsx
|
|
1275
|
+
var createBuildersSlice = (set, get, initialConfig) => ({
|
|
1276
|
+
build: (history, selectedItem, itemSelector, puckDispatch) => {
|
|
1277
|
+
if (!selectedItem || !itemSelector) {
|
|
1278
|
+
throw new Error("No item selected to build from.");
|
|
1279
|
+
}
|
|
1280
|
+
puckDispatch({
|
|
1281
|
+
type: "set",
|
|
1282
|
+
state: (previous) => ({
|
|
1283
|
+
ui: __spreadProps(__spreadValues({}, previous.ui), {
|
|
1284
|
+
itemSelector: null
|
|
1285
|
+
}),
|
|
1286
|
+
data: __spreadProps(__spreadValues({}, previous.data), {
|
|
1287
|
+
root: {
|
|
1288
|
+
props: {
|
|
1289
|
+
_name: "New Soft Component"
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
content: [__spreadValues({}, selectedItem)]
|
|
1293
|
+
})
|
|
1294
|
+
})
|
|
1295
|
+
});
|
|
1296
|
+
const config = __spreadValues({}, get().softConfig);
|
|
1297
|
+
const overrides = get().overrides;
|
|
1298
|
+
const buildConfig = builderConfig(config, overrides);
|
|
1299
|
+
set((s) => __spreadProps(__spreadValues({}, s), {
|
|
1300
|
+
softConfig: buildConfig,
|
|
1301
|
+
storedConfig: config,
|
|
1302
|
+
originalHistory: history,
|
|
1303
|
+
itemSelector: {
|
|
1304
|
+
index: itemSelector.index,
|
|
1305
|
+
zone: itemSelector.zone || rootDroppableId
|
|
1306
|
+
},
|
|
1307
|
+
state: "building"
|
|
1308
|
+
}));
|
|
1309
|
+
setTimeout(
|
|
1310
|
+
() => puckDispatch({
|
|
1311
|
+
type: "replaceRoot",
|
|
1312
|
+
root: {
|
|
1313
|
+
title: "Soft Component Builder",
|
|
1314
|
+
_name: "New Soft Component"
|
|
1315
|
+
}
|
|
1316
|
+
}),
|
|
1317
|
+
100
|
|
1318
|
+
);
|
|
1319
|
+
},
|
|
1320
|
+
remodel: (history, selectedItem, itemSelector, puckDispatch) => {
|
|
1321
|
+
var _a, _b;
|
|
1322
|
+
if (!selectedItem || !itemSelector) {
|
|
1323
|
+
throw new Error("No item selected to build from.");
|
|
1324
|
+
}
|
|
1325
|
+
const softComponentName = selectedItem.type;
|
|
1326
|
+
if (!softComponentName) {
|
|
1327
|
+
throw new Error("Selected item must have a valid component type.");
|
|
1328
|
+
}
|
|
1329
|
+
const softComponentVersion = ((_a = selectedItem.props) == null ? void 0 : _a.version) || "1.0.0";
|
|
1330
|
+
const softComponent = (_b = get().softComponents[softComponentName]) == null ? void 0 : _b.versions[softComponentVersion];
|
|
1331
|
+
const versions = Object.keys(
|
|
1332
|
+
get().softComponents[softComponentName].versions || {}
|
|
1333
|
+
);
|
|
1334
|
+
if (!softComponent) {
|
|
1335
|
+
throw new Error(
|
|
1336
|
+
`Soft component "${softComponentName}" with version "${softComponentVersion}" not found.`
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1339
|
+
puckDispatch({
|
|
1340
|
+
type: "setUi",
|
|
1341
|
+
ui: (previous) => __spreadProps(__spreadValues({}, previous), {
|
|
1342
|
+
itemSelector: void 0
|
|
1343
|
+
})
|
|
1344
|
+
});
|
|
1345
|
+
const { root, content } = softComponentToAppState(
|
|
1346
|
+
softComponent,
|
|
1347
|
+
softComponentName,
|
|
1348
|
+
softComponentVersion,
|
|
1349
|
+
versions,
|
|
1350
|
+
selectedItem.props,
|
|
1351
|
+
get().softConfig.components
|
|
1352
|
+
);
|
|
1353
|
+
puckDispatch({
|
|
1354
|
+
type: "setData",
|
|
1355
|
+
data: (previous) => __spreadProps(__spreadValues({}, previous), {
|
|
1356
|
+
root: __spreadProps(__spreadValues({}, root), { _versions: versions }),
|
|
1357
|
+
content: content || []
|
|
1358
|
+
})
|
|
1359
|
+
});
|
|
1360
|
+
const config = __spreadValues({}, get().softConfig);
|
|
1361
|
+
const overrides = get().overrides;
|
|
1362
|
+
const buildConfig = builderConfig(config, overrides, softComponentName);
|
|
1363
|
+
set((s) => __spreadProps(__spreadValues({}, s), {
|
|
1364
|
+
storedConfig: config,
|
|
1365
|
+
softConfig: buildConfig,
|
|
1366
|
+
originalHistory: history,
|
|
1367
|
+
itemSelector: {
|
|
1368
|
+
index: itemSelector.index,
|
|
1369
|
+
zone: itemSelector.zone || rootDroppableId
|
|
1370
|
+
},
|
|
1371
|
+
state: "remodeling"
|
|
1372
|
+
}));
|
|
1373
|
+
setTimeout(
|
|
1374
|
+
() => puckDispatch({
|
|
1375
|
+
type: "replaceRoot",
|
|
1376
|
+
root: {
|
|
1377
|
+
title: "Soft Component Builder",
|
|
1378
|
+
_name: "New Soft Component"
|
|
1379
|
+
}
|
|
1380
|
+
}),
|
|
1381
|
+
100
|
|
1382
|
+
);
|
|
1383
|
+
},
|
|
1384
|
+
complete: (appState, setHistories) => {
|
|
1385
|
+
var _a, _b;
|
|
1386
|
+
if (get().state === "ready") {
|
|
1387
|
+
throw new Error("Not building or remodeling a component.");
|
|
1388
|
+
}
|
|
1389
|
+
const componentName = (_b = (_a = appState.data.root) == null ? void 0 : _a.props) == null ? void 0 : _b._name;
|
|
1390
|
+
if (!componentName) {
|
|
1391
|
+
throw new Error("Root component must have a name to compose.");
|
|
1392
|
+
}
|
|
1393
|
+
const [newSoftComponentConfig, version] = get().builder.compose(appState, componentName) || [];
|
|
1394
|
+
if (!newSoftComponentConfig) {
|
|
1395
|
+
throw new Error("Failed to compose new soft component config.");
|
|
1396
|
+
}
|
|
1397
|
+
const storedHistories = get().originalHistory;
|
|
1398
|
+
setHistories([...storedHistories]);
|
|
1399
|
+
const config = __spreadValues({}, get().softConfig || initialConfig);
|
|
1400
|
+
set((s) => __spreadProps(__spreadValues({}, s), {
|
|
1401
|
+
softConfig: __spreadProps(__spreadValues({}, config), {
|
|
1402
|
+
root: __spreadValues({}, initialConfig.root),
|
|
1403
|
+
components: __spreadProps(__spreadValues({}, Object.entries(config.components).reduce(
|
|
1404
|
+
(acc, [name, component]) => {
|
|
1405
|
+
var _a2;
|
|
1406
|
+
let tempComponent = (_a2 = config.components) == null ? void 0 : _a2[name];
|
|
1407
|
+
if (tempComponent) {
|
|
1408
|
+
acc[name] = tempComponent;
|
|
1409
|
+
acc[name].render = tempComponent.render;
|
|
1410
|
+
} else {
|
|
1411
|
+
tempComponent = __spreadValues({}, component);
|
|
1412
|
+
tempComponent == null ? true : delete tempComponent.resolvePermissions;
|
|
1413
|
+
tempComponent == null ? true : delete tempComponent.resolveData;
|
|
1414
|
+
acc[name] = tempComponent;
|
|
1415
|
+
}
|
|
1416
|
+
return acc;
|
|
1417
|
+
},
|
|
1418
|
+
{}
|
|
1419
|
+
)), {
|
|
1420
|
+
[componentName]: __spreadValues({}, newSoftComponentConfig)
|
|
1421
|
+
})
|
|
1422
|
+
}),
|
|
1423
|
+
storedConfig: void 0,
|
|
1424
|
+
state: "inspecting",
|
|
1425
|
+
originalHistory: []
|
|
1426
|
+
}));
|
|
1427
|
+
return componentName;
|
|
1428
|
+
},
|
|
1429
|
+
inspect: (componentName, puckDispatch) => {
|
|
1430
|
+
if (get().state !== "inspecting") {
|
|
1431
|
+
throw new Error("Not in inspecting state.");
|
|
1432
|
+
}
|
|
1433
|
+
const selector = __spreadValues({}, get().itemSelector);
|
|
1434
|
+
if ((selector == null ? void 0 : selector.index) === void 0 || !(selector == null ? void 0 : selector.zone)) {
|
|
1435
|
+
throw new Error("No selector found for last item.");
|
|
1436
|
+
}
|
|
1437
|
+
setTimeout(() => {
|
|
1438
|
+
puckDispatch({
|
|
1439
|
+
type: "remove",
|
|
1440
|
+
index: selector.index,
|
|
1441
|
+
zone: selector.zone
|
|
1442
|
+
});
|
|
1443
|
+
puckDispatch({
|
|
1444
|
+
type: "insert",
|
|
1445
|
+
destinationIndex: selector.index,
|
|
1446
|
+
destinationZone: selector.zone,
|
|
1447
|
+
componentType: componentName
|
|
1448
|
+
});
|
|
1449
|
+
}, 500);
|
|
1450
|
+
set((s) => __spreadProps(__spreadValues({}, s), {
|
|
1451
|
+
state: "ready",
|
|
1452
|
+
setItemSelector: void 0,
|
|
1453
|
+
setOriginalItem: void 0
|
|
1454
|
+
}));
|
|
1455
|
+
},
|
|
1456
|
+
cancel: (setHistories) => {
|
|
1457
|
+
const storedHistories = get().originalHistory;
|
|
1458
|
+
setTimeout(() => setHistories([...storedHistories]), 100);
|
|
1459
|
+
set((s) => __spreadProps(__spreadValues({}, s), {
|
|
1460
|
+
softConfig: get().storedConfig || initialConfig,
|
|
1461
|
+
storedConfig: void 0,
|
|
1462
|
+
originalHistory: [],
|
|
1463
|
+
itemSelector: null,
|
|
1464
|
+
originalItem: null,
|
|
1465
|
+
state: "ready"
|
|
1466
|
+
}));
|
|
1467
|
+
},
|
|
1468
|
+
compose: (appState, componentName) => {
|
|
1469
|
+
if (!componentName) {
|
|
1470
|
+
throw new Error("Root component must have a name to compose.");
|
|
1471
|
+
}
|
|
1472
|
+
const componentConfigs = get().softConfig.components;
|
|
1473
|
+
if (get().state === "building" && Object.keys(componentConfigs).includes(componentName)) {
|
|
1474
|
+
throw new Error(
|
|
1475
|
+
`Component name "${componentName}" already exists in the configuration.`
|
|
1476
|
+
);
|
|
1477
|
+
}
|
|
1478
|
+
const [softComponent, version] = softComponentFromAppState(appState, componentConfigs);
|
|
1479
|
+
const existingComponent = get().softComponents[componentName];
|
|
1480
|
+
const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
|
|
1481
|
+
const isNewVersion = !allVersions.includes(version);
|
|
1482
|
+
const newSoftComponentConfig = createVersionedComponentConfig(
|
|
1483
|
+
componentName,
|
|
1484
|
+
version,
|
|
1485
|
+
isNewVersion ? [...allVersions, version] : allVersions,
|
|
1486
|
+
get().softConfig,
|
|
1487
|
+
__spreadProps(__spreadValues({}, get().softComponents), {
|
|
1488
|
+
[componentName]: __spreadProps(__spreadValues({}, existingComponent), {
|
|
1489
|
+
versions: __spreadProps(__spreadValues({}, existingComponent == null ? void 0 : existingComponent.versions), {
|
|
1490
|
+
[version]: softComponent
|
|
1491
|
+
})
|
|
1492
|
+
})
|
|
1493
|
+
}),
|
|
1494
|
+
softComponent.defaultProps
|
|
1495
|
+
);
|
|
1496
|
+
get().setSoftComponent(componentName, version, softComponent);
|
|
1497
|
+
return [newSoftComponentConfig, version];
|
|
1498
|
+
},
|
|
1499
|
+
decompose: (componentData) => {
|
|
1500
|
+
if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
|
|
1501
|
+
throw new Error("Component data must have type and id to decompose.");
|
|
1502
|
+
}
|
|
1503
|
+
return decomposeSoftComponent(componentData, get().softComponents);
|
|
1504
|
+
},
|
|
1505
|
+
demolish: (componentName, data, puckDispatch) => {
|
|
1506
|
+
if (get().state !== "ready") {
|
|
1507
|
+
throw new Error("Components can only be demolished in ready state.");
|
|
1508
|
+
}
|
|
1509
|
+
const result = demolishSoftComponent(
|
|
1510
|
+
componentName,
|
|
1511
|
+
data,
|
|
1512
|
+
get().softConfig,
|
|
1513
|
+
get().softComponents
|
|
1514
|
+
);
|
|
1515
|
+
puckDispatch({
|
|
1516
|
+
type: "setData",
|
|
1517
|
+
data: result.data
|
|
1518
|
+
});
|
|
1519
|
+
set((s) => __spreadProps(__spreadValues({}, s), {
|
|
1520
|
+
softComponents: result.softComponents,
|
|
1521
|
+
softConfig: result.config
|
|
1522
|
+
}));
|
|
1523
|
+
},
|
|
1524
|
+
setVersion: (componentName, newVersion, currentProps, puckDispatch) => {
|
|
1525
|
+
var _a;
|
|
1526
|
+
if (get().state !== "remodeling") {
|
|
1527
|
+
throw new Error("Can only switch versions during remodeling.");
|
|
1528
|
+
}
|
|
1529
|
+
const softComponent = (_a = get().softComponents[componentName]) == null ? void 0 : _a.versions[newVersion];
|
|
1530
|
+
if (!softComponent) {
|
|
1531
|
+
throw new Error(
|
|
1532
|
+
`Soft component "${componentName}" with version "${newVersion}" not found.`
|
|
1533
|
+
);
|
|
1534
|
+
}
|
|
1535
|
+
const versions = Object.keys(
|
|
1536
|
+
get().softComponents[componentName].versions || {}
|
|
1537
|
+
);
|
|
1538
|
+
const { root, content } = softComponentToAppState(
|
|
1539
|
+
softComponent,
|
|
1540
|
+
componentName,
|
|
1541
|
+
newVersion,
|
|
1542
|
+
versions,
|
|
1543
|
+
currentProps,
|
|
1544
|
+
get().softConfig.components
|
|
1545
|
+
);
|
|
1546
|
+
puckDispatch({
|
|
1547
|
+
type: "setData",
|
|
1548
|
+
data: (previous) => __spreadProps(__spreadValues({}, previous), {
|
|
1549
|
+
root: __spreadProps(__spreadValues({}, root), { props: __spreadProps(__spreadValues({}, root.props), { _versions: versions }) }),
|
|
1550
|
+
content: content || []
|
|
1551
|
+
})
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
});
|
|
1555
|
+
|
|
1556
|
+
// src/puck/lib/build-initial-soft-components.ts
|
|
1557
|
+
function extractDependencies(softComponents, componentName, version) {
|
|
1558
|
+
var _a, _b;
|
|
1559
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
1560
|
+
const component = (_b = (_a = softComponents[componentName]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
|
|
1561
|
+
if (!component) {
|
|
1562
|
+
return dependencies;
|
|
1563
|
+
}
|
|
1564
|
+
const processSubComponents = (subComponents) => {
|
|
1565
|
+
if (!Array.isArray(subComponents)) return;
|
|
1566
|
+
for (const subComponent of subComponents) {
|
|
1567
|
+
if (subComponent == null ? void 0 : subComponent.type) {
|
|
1568
|
+
dependencies.add(subComponent.type);
|
|
1569
|
+
if (subComponent.components) {
|
|
1570
|
+
Object.values(subComponent.components).forEach((nestedComponents) => {
|
|
1571
|
+
processSubComponents(nestedComponents);
|
|
1572
|
+
});
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
};
|
|
1577
|
+
processSubComponents(component.components);
|
|
1578
|
+
return dependencies;
|
|
1579
|
+
}
|
|
1580
|
+
function topologicalSort(softComponents, hardComponentNames) {
|
|
1581
|
+
const sorted = [];
|
|
1582
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
1583
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1584
|
+
const dependencyGraph = /* @__PURE__ */ new Map();
|
|
1585
|
+
for (const [componentName, component] of Object.entries(softComponents)) {
|
|
1586
|
+
const defaultVersion = component.defaultVersion || Object.keys(component.versions || {}).pop();
|
|
1587
|
+
if (!defaultVersion) continue;
|
|
1588
|
+
const allDeps = extractDependencies(
|
|
1589
|
+
softComponents,
|
|
1590
|
+
componentName,
|
|
1591
|
+
defaultVersion
|
|
1592
|
+
);
|
|
1593
|
+
const softDeps = new Set(
|
|
1594
|
+
[...allDeps].filter((dep) => !hardComponentNames.has(dep))
|
|
1595
|
+
);
|
|
1596
|
+
dependencyGraph.set(componentName, softDeps);
|
|
1597
|
+
}
|
|
1598
|
+
function visit(componentName) {
|
|
1599
|
+
if (visited.has(componentName)) return;
|
|
1600
|
+
if (visiting.has(componentName)) {
|
|
1601
|
+
throw new Error(
|
|
1602
|
+
`Circular dependency detected involving component: ${componentName}`
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
visiting.add(componentName);
|
|
1606
|
+
const dependencies = dependencyGraph.get(componentName) || /* @__PURE__ */ new Set();
|
|
1607
|
+
for (const dep of dependencies) {
|
|
1608
|
+
if (softComponents[dep]) {
|
|
1609
|
+
visit(dep);
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
visiting.delete(componentName);
|
|
1613
|
+
visited.add(componentName);
|
|
1614
|
+
sorted.push(componentName);
|
|
1615
|
+
}
|
|
1616
|
+
for (const componentName of Object.keys(softComponents)) {
|
|
1617
|
+
if (!visited.has(componentName)) {
|
|
1618
|
+
visit(componentName);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
return sorted;
|
|
1622
|
+
}
|
|
1623
|
+
function buildInitialSoftComponents(hardConfig, softComponents) {
|
|
1624
|
+
var _a, _b;
|
|
1625
|
+
if (!softComponents || Object.keys(softComponents).length === 0) {
|
|
1626
|
+
return {};
|
|
1627
|
+
}
|
|
1628
|
+
const hardComponentNames = new Set(Object.keys(hardConfig.components || {}));
|
|
1629
|
+
try {
|
|
1630
|
+
const sortedComponentNames = topologicalSort(
|
|
1631
|
+
softComponents,
|
|
1632
|
+
hardComponentNames
|
|
1633
|
+
);
|
|
1634
|
+
const buildingConfig = __spreadProps(__spreadValues({}, hardConfig), {
|
|
1635
|
+
components: __spreadValues({}, hardConfig.components)
|
|
1636
|
+
});
|
|
1637
|
+
const componentConfigs = {};
|
|
1638
|
+
for (const name of sortedComponentNames) {
|
|
1639
|
+
const comp = softComponents[name];
|
|
1640
|
+
const defaultVersion = comp.defaultVersion || Object.keys(comp.versions || {}).pop();
|
|
1641
|
+
const versionedComponent = (_a = comp.versions) == null ? void 0 : _a[defaultVersion || ""];
|
|
1642
|
+
const allVersions = Object.keys(comp.versions || {});
|
|
1643
|
+
if (!versionedComponent) {
|
|
1644
|
+
console.warn(
|
|
1645
|
+
`Soft component "${name}" does not have a valid default version. Skipping.`
|
|
1646
|
+
);
|
|
1647
|
+
continue;
|
|
1648
|
+
}
|
|
1649
|
+
const newSoftComponentConfig = createVersionedComponentConfig(
|
|
1650
|
+
name,
|
|
1651
|
+
defaultVersion || "1.0.0",
|
|
1652
|
+
allVersions,
|
|
1653
|
+
buildingConfig,
|
|
1654
|
+
// Pass the accumulating config
|
|
1655
|
+
softComponents,
|
|
1656
|
+
versionedComponent.defaultProps
|
|
1657
|
+
);
|
|
1658
|
+
componentConfigs[name] = newSoftComponentConfig;
|
|
1659
|
+
buildingConfig.components[name] = newSoftComponentConfig;
|
|
1660
|
+
}
|
|
1661
|
+
return componentConfigs;
|
|
1662
|
+
} catch (error) {
|
|
1663
|
+
console.error("Error building soft components:", error);
|
|
1664
|
+
console.warn("Falling back to unordered component building");
|
|
1665
|
+
const componentConfigs = {};
|
|
1666
|
+
for (const [name, comp] of Object.entries(softComponents)) {
|
|
1667
|
+
const defaultVersion = comp.defaultVersion || Object.keys(comp.versions || {}).pop();
|
|
1668
|
+
const versionedComponent = (_b = comp.versions) == null ? void 0 : _b[defaultVersion || ""];
|
|
1669
|
+
const allVersions = Object.keys(comp.versions || {});
|
|
1670
|
+
if (!versionedComponent) {
|
|
1671
|
+
console.warn(
|
|
1672
|
+
`Soft component "${name}" does not have a valid default version. Skipping.`
|
|
1673
|
+
);
|
|
1674
|
+
continue;
|
|
1675
|
+
}
|
|
1676
|
+
const newSoftComponentConfig = createVersionedComponentConfig(
|
|
1677
|
+
name,
|
|
1678
|
+
defaultVersion || "1.0.0",
|
|
1679
|
+
allVersions,
|
|
1680
|
+
hardConfig,
|
|
1681
|
+
softComponents,
|
|
1682
|
+
versionedComponent.defaultProps
|
|
1683
|
+
);
|
|
1684
|
+
componentConfigs[name] = newSoftComponentConfig;
|
|
1685
|
+
}
|
|
1686
|
+
return componentConfigs;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
// src/puck/store/index.tsx
|
|
1691
|
+
var createSoftConfigStore = (hardConfig = {
|
|
1692
|
+
components: {}
|
|
1693
|
+
}, softComponents = {}, overrides = {}) => create()(
|
|
1694
|
+
subscribeWithSelector(
|
|
1695
|
+
devtools((set, get) => ({
|
|
1696
|
+
state: "ready",
|
|
1697
|
+
originalHistory: [],
|
|
1698
|
+
overrides,
|
|
1699
|
+
storeHistory: (history) => set({ originalHistory: history }),
|
|
1700
|
+
removeHistory: () => set({ originalHistory: [] }),
|
|
1701
|
+
itemSelector: null,
|
|
1702
|
+
setItemSelector: (selector) => set({ itemSelector: selector }),
|
|
1703
|
+
originalItem: null,
|
|
1704
|
+
setOriginalItem: (item) => set({ originalItem: item }),
|
|
1705
|
+
softComponents: __spreadValues({}, softComponents),
|
|
1706
|
+
softConfig: __spreadProps(__spreadValues({}, hardConfig), {
|
|
1707
|
+
components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(hardConfig, softComponents))
|
|
1708
|
+
}),
|
|
1709
|
+
setSoftComponent: (name, version, component) => {
|
|
1710
|
+
set((state) => {
|
|
1711
|
+
var _a;
|
|
1712
|
+
return {
|
|
1713
|
+
softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
|
|
1714
|
+
[name]: {
|
|
1715
|
+
defaultVersion: version,
|
|
1716
|
+
versions: __spreadProps(__spreadValues({}, ((_a = state.softComponents[name]) == null ? void 0 : _a.versions) || {}), {
|
|
1717
|
+
[version]: component
|
|
1718
|
+
})
|
|
1719
|
+
}
|
|
1720
|
+
})
|
|
1721
|
+
};
|
|
1722
|
+
});
|
|
1723
|
+
},
|
|
1724
|
+
setSoftComponentDefaultVersion: (name, version) => {
|
|
1725
|
+
var _a, _b, _c;
|
|
1726
|
+
const softComponent = (_b = (_a = get().softComponents[name]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
|
|
1727
|
+
const allVersions = Object.keys(
|
|
1728
|
+
((_c = get().softComponents[name]) == null ? void 0 : _c.versions) || {}
|
|
1729
|
+
);
|
|
1730
|
+
if (!softComponent) {
|
|
1731
|
+
throw new Error(
|
|
1732
|
+
`Soft component "${name}" version "${version}" does not exist.`
|
|
1733
|
+
);
|
|
1734
|
+
}
|
|
1735
|
+
const newSoftComponentConfig = createVersionedComponentConfig(
|
|
1736
|
+
name,
|
|
1737
|
+
version,
|
|
1738
|
+
allVersions,
|
|
1739
|
+
get().softConfig,
|
|
1740
|
+
get().softComponents,
|
|
1741
|
+
softComponent.defaultProps
|
|
1742
|
+
);
|
|
1743
|
+
set((state) => ({
|
|
1744
|
+
softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
|
|
1745
|
+
components: __spreadProps(__spreadValues({}, state.softConfig.components), {
|
|
1746
|
+
[name]: newSoftComponentConfig
|
|
1747
|
+
})
|
|
1748
|
+
}),
|
|
1749
|
+
softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
|
|
1750
|
+
[name]: __spreadProps(__spreadValues({}, state.softComponents[name]), {
|
|
1751
|
+
defaultVersion: version
|
|
1752
|
+
})
|
|
1753
|
+
})
|
|
1754
|
+
}));
|
|
1755
|
+
},
|
|
1756
|
+
removeSoftComponentVersion: (key, version) => {
|
|
1757
|
+
set((state) => {
|
|
1758
|
+
const component = state.softComponents[key];
|
|
1759
|
+
if (!component) return {};
|
|
1760
|
+
const newVersions = Object.fromEntries(
|
|
1761
|
+
Object.entries(component.versions || {}).filter(
|
|
1762
|
+
([k, _]) => k !== version
|
|
1763
|
+
)
|
|
1764
|
+
);
|
|
1765
|
+
let newDefaultVersion = component.defaultVersion;
|
|
1766
|
+
if (component.defaultVersion === version) {
|
|
1767
|
+
const versionKeys = Object.keys(newVersions);
|
|
1768
|
+
newDefaultVersion = versionKeys.length > 0 ? versionKeys[versionKeys.length - 1] : "";
|
|
1769
|
+
}
|
|
1770
|
+
return {
|
|
1771
|
+
softComponents: __spreadProps(__spreadValues({}, state.softComponents), {
|
|
1772
|
+
[key]: __spreadProps(__spreadValues({}, component), {
|
|
1773
|
+
versions: newVersions,
|
|
1774
|
+
defaultVersion: newDefaultVersion
|
|
1775
|
+
})
|
|
1776
|
+
})
|
|
1777
|
+
};
|
|
1778
|
+
});
|
|
1779
|
+
},
|
|
1780
|
+
removeSoftComponent: (key) => {
|
|
1781
|
+
set((state) => ({
|
|
1782
|
+
softComponents: Object.fromEntries(
|
|
1783
|
+
Object.entries(state.softComponents).filter(([k, _]) => k !== key)
|
|
1784
|
+
)
|
|
1785
|
+
}));
|
|
1786
|
+
},
|
|
1787
|
+
setSoftComponentConfig: (key, config, category) => {
|
|
1788
|
+
set((state) => {
|
|
1789
|
+
var _a;
|
|
1790
|
+
return {
|
|
1791
|
+
softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
|
|
1792
|
+
components: __spreadProps(__spreadValues({}, state.softConfig.components), {
|
|
1793
|
+
[key]: __spreadValues({}, config)
|
|
1794
|
+
}),
|
|
1795
|
+
categories: category && state.softConfig.categories ? __spreadProps(__spreadValues({}, state.softConfig.categories), {
|
|
1796
|
+
[category]: __spreadProps(__spreadValues({}, state.softConfig.categories[category]), {
|
|
1797
|
+
components: [
|
|
1798
|
+
...((_a = state.softConfig.categories[category]) == null ? void 0 : _a.components) || [],
|
|
1799
|
+
key
|
|
1800
|
+
]
|
|
1801
|
+
})
|
|
1802
|
+
}) : state.softConfig.categories
|
|
1803
|
+
})
|
|
1804
|
+
};
|
|
1805
|
+
});
|
|
1806
|
+
},
|
|
1807
|
+
removeSoftComponentConfig: (key) => {
|
|
1808
|
+
set((state) => ({
|
|
1809
|
+
softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
|
|
1810
|
+
components: Object.fromEntries(
|
|
1811
|
+
Object.entries(state.softConfig.components).filter(
|
|
1812
|
+
([k, _]) => k !== key
|
|
1813
|
+
)
|
|
1814
|
+
)
|
|
1815
|
+
})
|
|
1816
|
+
}));
|
|
1817
|
+
},
|
|
1818
|
+
setSoftCategoryConfig: (key, category) => {
|
|
1819
|
+
set((state) => {
|
|
1820
|
+
var _a;
|
|
1821
|
+
return {
|
|
1822
|
+
softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
|
|
1823
|
+
categories: __spreadProps(__spreadValues({}, state.softConfig.categories), {
|
|
1824
|
+
[key]: __spreadValues(__spreadValues({}, (_a = state.softConfig.categories) == null ? void 0 : _a[key]), category)
|
|
1825
|
+
})
|
|
1826
|
+
})
|
|
1827
|
+
};
|
|
1828
|
+
});
|
|
1829
|
+
},
|
|
1830
|
+
removeSoftCategoryConfig: (key) => {
|
|
1831
|
+
set((state) => ({
|
|
1832
|
+
softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
|
|
1833
|
+
categories: Object.fromEntries(
|
|
1834
|
+
Object.entries(state.softConfig.categories || {}).filter(
|
|
1835
|
+
([k, _]) => k !== key
|
|
1836
|
+
)
|
|
1837
|
+
)
|
|
1838
|
+
})
|
|
1839
|
+
}));
|
|
1840
|
+
},
|
|
1841
|
+
builder: createBuildersSlice(set, get, hardConfig)
|
|
1842
|
+
}))
|
|
1843
|
+
)
|
|
1844
|
+
);
|
|
1845
|
+
|
|
1846
|
+
// src/puck/context/storeProvider.tsx
|
|
1847
|
+
import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
|
|
1848
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1849
|
+
var SoftConfigProvider = ({
|
|
1850
|
+
children,
|
|
1851
|
+
hardConfig,
|
|
1852
|
+
softComponents,
|
|
1853
|
+
overrides
|
|
1854
|
+
}) => {
|
|
1855
|
+
const store = useMemo2(
|
|
1856
|
+
() => createSoftConfigStore(hardConfig, softComponents, overrides),
|
|
1857
|
+
[hardConfig, softComponents, overrides]
|
|
1858
|
+
);
|
|
1859
|
+
const [softConfig, setSoftConfig] = useState2(
|
|
1860
|
+
() => store.getState().softConfig
|
|
1861
|
+
);
|
|
1862
|
+
const [internalSoftComponents, setSoftComponents] = useState2(
|
|
1863
|
+
() => store.getState().softComponents
|
|
1864
|
+
);
|
|
1865
|
+
useEffect2(() => {
|
|
1866
|
+
const unsubscribe = store.subscribe(() => {
|
|
1867
|
+
setSoftConfig(store.getState().softConfig);
|
|
1868
|
+
setSoftComponents(store.getState().softComponents);
|
|
1869
|
+
});
|
|
1870
|
+
return () => {
|
|
1871
|
+
unsubscribe();
|
|
1872
|
+
};
|
|
1873
|
+
}, [store]);
|
|
1874
|
+
return /* @__PURE__ */ jsx7(appStoreContext.Provider, { value: store, children: children(softConfig, internalSoftComponents) });
|
|
1875
|
+
};
|
|
1876
|
+
|
|
1877
|
+
// src/puck/actions/useBuild.tsx
|
|
1878
|
+
import { createUsePuck as createUsePuck2 } from "@measured/puck";
|
|
1879
|
+
|
|
1880
|
+
// src/puck/lib/notify.ts
|
|
1881
|
+
var customHandler = null;
|
|
1882
|
+
var defaultHandler = (message, type) => {
|
|
1883
|
+
if (type === "error") {
|
|
1884
|
+
console.error(`[Error] ${message}`);
|
|
1885
|
+
} else {
|
|
1886
|
+
console.log(`[Success] ${message}`);
|
|
1887
|
+
}
|
|
1888
|
+
};
|
|
1889
|
+
var setNotificationHandler = (handler) => {
|
|
1890
|
+
customHandler = handler;
|
|
1891
|
+
};
|
|
1892
|
+
var notify = {
|
|
1893
|
+
error: (message) => {
|
|
1894
|
+
const handler = customHandler || defaultHandler;
|
|
1895
|
+
handler(message, "error");
|
|
1896
|
+
},
|
|
1897
|
+
success: (message) => {
|
|
1898
|
+
const handler = customHandler || defaultHandler;
|
|
1899
|
+
handler(message, "success");
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
|
|
1903
|
+
// src/puck/actions/useBuild.tsx
|
|
1904
|
+
var useCustomPuck2 = createUsePuck2();
|
|
1905
|
+
var useBuild = () => {
|
|
1906
|
+
const build = useSoftConfig((s) => s.builder.build);
|
|
1907
|
+
const history = useCustomPuck2((s) => s.history.histories);
|
|
1908
|
+
const selectedItem = useCustomPuck2((s) => s.selectedItem);
|
|
1909
|
+
const itemSelector = useCustomPuck2((s) => s.appState.ui.itemSelector);
|
|
1910
|
+
const dispatch = useCustomPuck2((s) => s.dispatch);
|
|
1911
|
+
const status = useSoftConfig((s) => s.state);
|
|
1912
|
+
const handleBuild = () => {
|
|
1913
|
+
if (status !== "ready") {
|
|
1914
|
+
notify.error("Can only build when in ready state.");
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
try {
|
|
1918
|
+
build(history, selectedItem, itemSelector, dispatch);
|
|
1919
|
+
} catch (error) {
|
|
1920
|
+
console.error("Failed to build:", error);
|
|
1921
|
+
notify.error(
|
|
1922
|
+
"Failed to build: " + (error instanceof Error ? error.message : String(error))
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
};
|
|
1926
|
+
return { handleBuild, canBuild: status === "ready" };
|
|
1927
|
+
};
|
|
1928
|
+
|
|
1929
|
+
// src/puck/actions/useRemodel.tsx
|
|
1930
|
+
import { createUsePuck as createUsePuck3 } from "@measured/puck";
|
|
1931
|
+
var useCustomPuck3 = createUsePuck3();
|
|
1932
|
+
var useRemodel = () => {
|
|
1933
|
+
const remodel = useSoftConfig((s) => s.builder.remodel);
|
|
1934
|
+
const history = useCustomPuck3((s) => s.history.histories);
|
|
1935
|
+
const selectedItem = useCustomPuck3((s) => s.selectedItem);
|
|
1936
|
+
const itemSelector = useCustomPuck3((s) => s.appState.ui.itemSelector);
|
|
1937
|
+
const dispatch = useCustomPuck3((s) => s.dispatch);
|
|
1938
|
+
const status = useSoftConfig((s) => s.state);
|
|
1939
|
+
const softComponents = useSoftConfig((s) => s.softComponents);
|
|
1940
|
+
const handleRemodel = (componentName) => {
|
|
1941
|
+
if (status !== "ready") {
|
|
1942
|
+
notify.error("Can only remodel when in ready state.");
|
|
1943
|
+
return;
|
|
1944
|
+
}
|
|
1945
|
+
const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
|
|
1946
|
+
if (!name || !Object.keys(softComponents).includes(name)) {
|
|
1947
|
+
notify.error("Selected component is not a soft component.");
|
|
1948
|
+
return;
|
|
1949
|
+
}
|
|
1950
|
+
try {
|
|
1951
|
+
remodel(history, selectedItem, itemSelector, dispatch);
|
|
1952
|
+
} catch (error) {
|
|
1953
|
+
console.error("Failed to remodel:", error);
|
|
1954
|
+
notify.error(
|
|
1955
|
+
"Failed to remodel: " + (error instanceof Error ? error.message : String(error))
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
};
|
|
1959
|
+
const canRemodel = (componentName) => {
|
|
1960
|
+
const name = componentName || (selectedItem == null ? void 0 : selectedItem.type);
|
|
1961
|
+
return status === "ready" && name !== void 0 && Object.keys(softComponents).includes(name);
|
|
1962
|
+
};
|
|
1963
|
+
return { handleRemodel, canRemodel };
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
|
+
// src/puck/actions/useComplete.tsx
|
|
1967
|
+
import { createUsePuck as createUsePuck4 } from "@measured/puck";
|
|
1968
|
+
import { useState as useState3, useCallback } from "react";
|
|
1969
|
+
var useCustomPuck4 = createUsePuck4();
|
|
1970
|
+
var useComplete = () => {
|
|
1971
|
+
const complete = useSoftConfig((s) => s.builder.complete);
|
|
1972
|
+
const appState = useCustomPuck4((s) => s.appState);
|
|
1973
|
+
const setHistories = useCustomPuck4((s) => s.history.setHistories);
|
|
1974
|
+
const status = useSoftConfig((s) => s.state);
|
|
1975
|
+
const [newComponent, setNewComponent] = useState3(null);
|
|
1976
|
+
const handleComplete = useCallback(() => {
|
|
1977
|
+
if (status === "ready") {
|
|
1978
|
+
notify.error("Not building or remodeling a component.");
|
|
1979
|
+
return null;
|
|
1980
|
+
}
|
|
1981
|
+
try {
|
|
1982
|
+
const componentName = complete(appState, setHistories);
|
|
1983
|
+
setNewComponent(componentName);
|
|
1984
|
+
return componentName;
|
|
1985
|
+
} catch (error) {
|
|
1986
|
+
console.error("Failed to complete:", error);
|
|
1987
|
+
notify.error(
|
|
1988
|
+
"Failed to complete: " + (error instanceof Error ? error.message : String(error))
|
|
1989
|
+
);
|
|
1990
|
+
return null;
|
|
1991
|
+
}
|
|
1992
|
+
}, [complete, appState, setHistories, status]);
|
|
1993
|
+
const canComplete = status === "building" || status === "remodeling";
|
|
1994
|
+
return { handleComplete, canComplete, newComponent, setNewComponent };
|
|
1995
|
+
};
|
|
1996
|
+
|
|
1997
|
+
// src/puck/actions/useCancel.tsx
|
|
1998
|
+
import { createUsePuck as createUsePuck5 } from "@measured/puck";
|
|
1999
|
+
var useCustomPuck5 = createUsePuck5();
|
|
2000
|
+
var useCancel = () => {
|
|
2001
|
+
const cancel = useSoftConfig((s) => s.builder.cancel);
|
|
2002
|
+
const setHistories = useCustomPuck5((s) => s.history.setHistories);
|
|
2003
|
+
const status = useSoftConfig((s) => s.state);
|
|
2004
|
+
const handleCancel = () => {
|
|
2005
|
+
if (status === "ready") {
|
|
2006
|
+
notify.error("Nothing to cancel.");
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
2009
|
+
try {
|
|
2010
|
+
cancel(setHistories);
|
|
2011
|
+
} catch (error) {
|
|
2012
|
+
console.error("Failed to cancel:", error);
|
|
2013
|
+
notify.error(
|
|
2014
|
+
"Failed to cancel: " + (error instanceof Error ? error.message : String(error))
|
|
2015
|
+
);
|
|
2016
|
+
}
|
|
2017
|
+
};
|
|
2018
|
+
const canCancel = status === "building" || status === "remodeling";
|
|
2019
|
+
return { handleCancel, canCancel };
|
|
2020
|
+
};
|
|
2021
|
+
|
|
2022
|
+
// src/puck/actions/useInspect.tsx
|
|
2023
|
+
import { createUsePuck as createUsePuck6 } from "@measured/puck";
|
|
2024
|
+
import { useEffect as useEffect3 } from "react";
|
|
2025
|
+
var useCustomPuck6 = createUsePuck6();
|
|
2026
|
+
var useInspect = (componentName) => {
|
|
2027
|
+
const inspect = useSoftConfig((s) => s.builder.inspect);
|
|
2028
|
+
const dispatch = useCustomPuck6((s) => s.dispatch);
|
|
2029
|
+
const status = useSoftConfig((s) => s.state);
|
|
2030
|
+
useEffect3(() => {
|
|
2031
|
+
if (status !== "inspecting") return;
|
|
2032
|
+
if (!componentName) {
|
|
2033
|
+
notify.error("No component to inspect.");
|
|
2034
|
+
return;
|
|
2035
|
+
}
|
|
2036
|
+
try {
|
|
2037
|
+
inspect(componentName, dispatch);
|
|
2038
|
+
} catch (error) {
|
|
2039
|
+
console.error("Failed to inspect:", error);
|
|
2040
|
+
notify.error(
|
|
2041
|
+
"Failed to inspect: " + (error instanceof Error ? error.message : String(error))
|
|
2042
|
+
);
|
|
2043
|
+
}
|
|
2044
|
+
}, [status, componentName, inspect, dispatch]);
|
|
2045
|
+
};
|
|
2046
|
+
|
|
2047
|
+
// src/puck/actions/useDecompose.tsx
|
|
2048
|
+
import { createUsePuck as createUsePuck7, walkTree as walkTree3 } from "@measured/puck";
|
|
2049
|
+
var useCustomPuck7 = createUsePuck7();
|
|
2050
|
+
var useDecompose = () => {
|
|
2051
|
+
const decompose = useSoftConfig((s) => s.builder.decompose);
|
|
2052
|
+
const appState = useCustomPuck7((s) => s.appState);
|
|
2053
|
+
const dispatch = useCustomPuck7((s) => s.dispatch);
|
|
2054
|
+
const selectedItem = useCustomPuck7((s) => s.selectedItem);
|
|
2055
|
+
const status = useSoftConfig((s) => s.state);
|
|
2056
|
+
const softComponents = useSoftConfig((s) => s.softComponents);
|
|
2057
|
+
const config = useSoftConfig((s) => s.softConfig);
|
|
2058
|
+
const handleDecompose = (componentData) => {
|
|
2059
|
+
if (status !== "ready") {
|
|
2060
|
+
notify.error("Can only decompose when in ready state.");
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
const target = componentData || selectedItem;
|
|
2064
|
+
if (!target) {
|
|
2065
|
+
notify.error("No component selected to decompose.");
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
const componentName = target.type;
|
|
2069
|
+
if (!Object.keys(softComponents).includes(componentName)) {
|
|
2070
|
+
notify.error("Selected component is not a soft component.");
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
try {
|
|
2074
|
+
const decomposedComponents = decompose(target);
|
|
2075
|
+
if (!decomposedComponents || decomposedComponents.length === 0) {
|
|
2076
|
+
notify.error("Nothing to decompose.");
|
|
2077
|
+
return;
|
|
2078
|
+
}
|
|
2079
|
+
const newData = walkTree3(appState.data, config, (components) => {
|
|
2080
|
+
const index = components.findIndex((c) => c.props.id === target.props.id);
|
|
2081
|
+
if (index !== -1) {
|
|
2082
|
+
components.splice(index, 1, ...decomposedComponents);
|
|
2083
|
+
}
|
|
2084
|
+
return components;
|
|
2085
|
+
});
|
|
2086
|
+
dispatch({
|
|
2087
|
+
type: "setData",
|
|
2088
|
+
data: newData
|
|
2089
|
+
});
|
|
2090
|
+
} catch (error) {
|
|
2091
|
+
console.error("Failed to decompose:", error);
|
|
2092
|
+
notify.error(
|
|
2093
|
+
"Failed to decompose: " + (error instanceof Error ? error.message : String(error))
|
|
2094
|
+
);
|
|
2095
|
+
}
|
|
2096
|
+
};
|
|
2097
|
+
const canDecompose = (componentData) => {
|
|
2098
|
+
const target = componentData || selectedItem;
|
|
2099
|
+
return status === "ready" && target !== null && Object.keys(softComponents).includes((target == null ? void 0 : target.type) || "");
|
|
2100
|
+
};
|
|
2101
|
+
return { handleDecompose, canDecompose };
|
|
2102
|
+
};
|
|
2103
|
+
|
|
2104
|
+
// src/puck/actions/useDemolish.tsx
|
|
2105
|
+
import { createUsePuck as createUsePuck8 } from "@measured/puck";
|
|
2106
|
+
var useCustomPuck8 = createUsePuck8();
|
|
2107
|
+
var useDemolish = () => {
|
|
2108
|
+
const demolish = useSoftConfig((s) => s.builder.demolish);
|
|
2109
|
+
const dispatch = useCustomPuck8((s) => s.dispatch);
|
|
2110
|
+
const data = useCustomPuck8((s) => s.appState.data);
|
|
2111
|
+
const status = useSoftConfig((s) => s.state);
|
|
2112
|
+
const softComponents = useSoftConfig((s) => s.softComponents);
|
|
2113
|
+
const handleDemolish = (componentName) => {
|
|
2114
|
+
if (status !== "ready") {
|
|
2115
|
+
notify.error("Can only demolish when in ready state.");
|
|
2116
|
+
return;
|
|
2117
|
+
}
|
|
2118
|
+
if (!Object.keys(softComponents).includes(componentName)) {
|
|
2119
|
+
notify.error("Component is not a soft component.");
|
|
2120
|
+
return;
|
|
2121
|
+
}
|
|
2122
|
+
try {
|
|
2123
|
+
demolish(componentName, data, dispatch);
|
|
2124
|
+
} catch (error) {
|
|
2125
|
+
console.error("Failed to demolish:", error);
|
|
2126
|
+
notify.error(
|
|
2127
|
+
"Failed to demolish: " + (error instanceof Error ? error.message : String(error))
|
|
2128
|
+
);
|
|
2129
|
+
}
|
|
2130
|
+
};
|
|
2131
|
+
const canDemolish = (componentName) => {
|
|
2132
|
+
return status === "ready" && Object.keys(softComponents).includes(componentName);
|
|
2133
|
+
};
|
|
2134
|
+
return { handleDemolish, canDemolish };
|
|
2135
|
+
};
|
|
2136
|
+
|
|
2137
|
+
// src/puck/actions/useSetDefaultVersion.tsx
|
|
2138
|
+
var useSetDefaultVersion = () => {
|
|
2139
|
+
const setSoftComponentDefaultVersion = useSoftConfig(
|
|
2140
|
+
(s) => s.setSoftComponentDefaultVersion
|
|
2141
|
+
);
|
|
2142
|
+
const softComponents = useSoftConfig((s) => s.softComponents);
|
|
2143
|
+
const status = useSoftConfig((s) => s.state);
|
|
2144
|
+
const handleSetDefaultVersion = (componentName, version) => {
|
|
2145
|
+
if (status !== "ready") {
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
if (!Object.keys(softComponents).includes(componentName)) {
|
|
2149
|
+
return;
|
|
2150
|
+
}
|
|
2151
|
+
const component = softComponents[componentName];
|
|
2152
|
+
if (!(component == null ? void 0 : component.versions[version])) {
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2155
|
+
setSoftComponentDefaultVersion(componentName, version);
|
|
2156
|
+
};
|
|
2157
|
+
const canSetDefaultVersion = (componentName, version) => {
|
|
2158
|
+
const component = softComponents[componentName];
|
|
2159
|
+
return status === "ready" && component !== void 0 && component.versions[version] !== void 0 && component.defaultVersion !== version;
|
|
2160
|
+
};
|
|
2161
|
+
const getVersions = (componentName) => {
|
|
2162
|
+
var _a;
|
|
2163
|
+
return Object.keys(((_a = softComponents[componentName]) == null ? void 0 : _a.versions) || {});
|
|
2164
|
+
};
|
|
2165
|
+
const getDefaultVersion = (componentName) => {
|
|
2166
|
+
var _a;
|
|
2167
|
+
return (_a = softComponents[componentName]) == null ? void 0 : _a.defaultVersion;
|
|
2168
|
+
};
|
|
2169
|
+
return {
|
|
2170
|
+
handleSetDefaultVersion,
|
|
2171
|
+
canSetDefaultVersion,
|
|
2172
|
+
getVersions,
|
|
2173
|
+
getDefaultVersion
|
|
2174
|
+
};
|
|
2175
|
+
};
|
|
2176
|
+
|
|
2177
|
+
// src/puck/overrides/Header.tsx
|
|
2178
|
+
import { Button } from "@measured/puck";
|
|
2179
|
+
|
|
2180
|
+
// src/puck/overrides/Header.module.css
|
|
2181
|
+
var Header_default = {};
|
|
2182
|
+
|
|
2183
|
+
// src/puck/actions/usePublish.tsx
|
|
2184
|
+
import { createUsePuck as createUsePuck9 } from "@measured/puck";
|
|
2185
|
+
var useCustomPuck9 = createUsePuck9();
|
|
2186
|
+
var usePublish = () => {
|
|
2187
|
+
const components = useSoftConfig((s) => s.softComponents);
|
|
2188
|
+
const data = useCustomPuck9((s) => s.appState.data);
|
|
2189
|
+
const status = useSoftConfig((s) => s.state);
|
|
2190
|
+
const handlePublish = (publish) => {
|
|
2191
|
+
if (status !== "ready") {
|
|
2192
|
+
notify.error("Can only publish when in ready state.");
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
if (!data) {
|
|
2196
|
+
notify.error("No data to publish.");
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
publish(data, components);
|
|
2200
|
+
};
|
|
2201
|
+
const canPublish = status === "ready";
|
|
2202
|
+
return { handlePublish, canPublish };
|
|
2203
|
+
};
|
|
2204
|
+
|
|
2205
|
+
// src/puck/overrides/Header.tsx
|
|
2206
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2207
|
+
var getClassName2 = get_class_name_factory_default("Header", Header_default);
|
|
2208
|
+
var Header = ({
|
|
2209
|
+
onPublish,
|
|
2210
|
+
children
|
|
2211
|
+
}) => {
|
|
2212
|
+
const { handleComplete, canComplete, newComponent, setNewComponent } = useComplete();
|
|
2213
|
+
const { handleCancel, canCancel } = useCancel();
|
|
2214
|
+
const { handlePublish } = usePublish();
|
|
2215
|
+
useInspect(newComponent);
|
|
2216
|
+
return /* @__PURE__ */ jsx8("div", { className: getClassName2(), children: canCancel ? /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
2217
|
+
/* @__PURE__ */ jsx8(Button, { onClick: handleCancel, children: "Cancel" }),
|
|
2218
|
+
/* @__PURE__ */ jsx8(
|
|
2219
|
+
Button,
|
|
2220
|
+
{
|
|
2221
|
+
variant: "primary",
|
|
2222
|
+
onClick: () => {
|
|
2223
|
+
const name = handleComplete();
|
|
2224
|
+
if (name) {
|
|
2225
|
+
setNewComponent(name);
|
|
2226
|
+
}
|
|
2227
|
+
},
|
|
2228
|
+
children: "Complete"
|
|
2229
|
+
}
|
|
2230
|
+
)
|
|
2231
|
+
] }) : children ? children : /* @__PURE__ */ jsx8(
|
|
2232
|
+
Button,
|
|
2233
|
+
{
|
|
2234
|
+
variant: "primary",
|
|
2235
|
+
onClick: () => {
|
|
2236
|
+
if (onPublish) {
|
|
2237
|
+
handlePublish(onPublish);
|
|
2238
|
+
}
|
|
2239
|
+
},
|
|
2240
|
+
children: "Publish"
|
|
2241
|
+
}
|
|
2242
|
+
) });
|
|
2243
|
+
};
|
|
2244
|
+
|
|
2245
|
+
// src/puck/overrides/ActionBar.tsx
|
|
2246
|
+
import { ActionBar } from "@measured/puck";
|
|
2247
|
+
import { Combine, ComponentIcon, EditIcon } from "lucide-react";
|
|
2248
|
+
|
|
2249
|
+
// src/puck/overrides/ActionBar.module.css
|
|
2250
|
+
var ActionBar_default = {};
|
|
2251
|
+
|
|
2252
|
+
// src/puck/overrides/ActionBar.tsx
|
|
2253
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2254
|
+
var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_default);
|
|
2255
|
+
var ActionBarOverride = (props) => {
|
|
2256
|
+
const { handleBuild, canBuild } = useBuild();
|
|
2257
|
+
const { handleRemodel, canRemodel } = useRemodel();
|
|
2258
|
+
const { handleDecompose, canDecompose } = useDecompose();
|
|
2259
|
+
const softComponents = useSoftConfig((s) => s.softComponents);
|
|
2260
|
+
const status = useSoftConfig((s) => s.state);
|
|
2261
|
+
const isSoftComponent2 = Object.keys(softComponents || {}).includes(props.label);
|
|
2262
|
+
return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
|
|
2263
|
+
/* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
|
|
2264
|
+
props.parentAction,
|
|
2265
|
+
/* @__PURE__ */ jsx9(ActionBar.Label, { label: props.label })
|
|
2266
|
+
] }),
|
|
2267
|
+
/* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
|
|
2268
|
+
status === "ready" ? isSoftComponent2 ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
2269
|
+
/* @__PURE__ */ jsx9(
|
|
2270
|
+
ActionBar.Action,
|
|
2271
|
+
{
|
|
2272
|
+
onClick: () => handleRemodel(props.label),
|
|
2273
|
+
label: "Remodel Soft Component",
|
|
2274
|
+
children: /* @__PURE__ */ jsx9(EditIcon, { size: 16 })
|
|
2275
|
+
}
|
|
2276
|
+
),
|
|
2277
|
+
/* @__PURE__ */ jsx9(
|
|
2278
|
+
ActionBar.Action,
|
|
2279
|
+
{
|
|
2280
|
+
onClick: () => handleDecompose(),
|
|
2281
|
+
label: "Decompose Soft Component",
|
|
2282
|
+
children: /* @__PURE__ */ jsx9(Combine, { size: 16 })
|
|
2283
|
+
}
|
|
2284
|
+
)
|
|
2285
|
+
] }) : /* @__PURE__ */ jsx9(ActionBar.Action, { onClick: handleBuild, label: "Build Soft Component", children: /* @__PURE__ */ jsx9(ComponentIcon, { size: 16 }) }) : null,
|
|
2286
|
+
props.children
|
|
2287
|
+
] })
|
|
2288
|
+
] }) });
|
|
2289
|
+
};
|
|
2290
|
+
|
|
2291
|
+
// src/puck/overrides/ComponentItem.tsx
|
|
2292
|
+
import { useState as useState5 } from "react";
|
|
2293
|
+
import { Button as Button2, IconButton } from "@measured/puck";
|
|
2294
|
+
import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
|
|
2295
|
+
|
|
2296
|
+
// src/puck/lib/confirm.ts
|
|
2297
|
+
var confirmHandler = (message) => {
|
|
2298
|
+
return window.confirm(message);
|
|
2299
|
+
};
|
|
2300
|
+
var setConfirmHandler = (handler) => {
|
|
2301
|
+
confirmHandler = handler;
|
|
2302
|
+
};
|
|
2303
|
+
var confirm = (message) => __async(null, null, function* () {
|
|
2304
|
+
try {
|
|
2305
|
+
const result = confirmHandler(message);
|
|
2306
|
+
return result instanceof Promise ? yield result : result;
|
|
2307
|
+
} catch (error) {
|
|
2308
|
+
console.error("Confirm handler error:", error);
|
|
2309
|
+
return false;
|
|
2310
|
+
}
|
|
2311
|
+
});
|
|
2312
|
+
|
|
2313
|
+
// src/puck/overrides/ComponentItem.module.css
|
|
2314
|
+
var ComponentItem_default = {};
|
|
2315
|
+
|
|
2316
|
+
// src/puck/components/modal/index.tsx
|
|
2317
|
+
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
2318
|
+
import { createPortal } from "react-dom";
|
|
2319
|
+
|
|
2320
|
+
// src/puck/components/modal/styles.module.css
|
|
2321
|
+
var styles_default2 = {};
|
|
2322
|
+
|
|
2323
|
+
// src/puck/components/modal/index.tsx
|
|
2324
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2325
|
+
var getClassName4 = get_class_name_factory_default("Modal", styles_default2);
|
|
2326
|
+
var Modal = ({
|
|
2327
|
+
children,
|
|
2328
|
+
onClose,
|
|
2329
|
+
isOpen
|
|
2330
|
+
}) => {
|
|
2331
|
+
const [rootEl, setRootEl] = useState4(null);
|
|
2332
|
+
useEffect4(() => {
|
|
2333
|
+
setRootEl(document.getElementById("puck-portal-root"));
|
|
2334
|
+
}, []);
|
|
2335
|
+
if (!rootEl) {
|
|
2336
|
+
return /* @__PURE__ */ jsx10("div", {});
|
|
2337
|
+
}
|
|
2338
|
+
return createPortal(
|
|
2339
|
+
/* @__PURE__ */ jsx10("div", { className: getClassName4({ isOpen }), onClick: onClose, children: /* @__PURE__ */ jsx10(
|
|
2340
|
+
"div",
|
|
2341
|
+
{
|
|
2342
|
+
className: getClassName4("inner"),
|
|
2343
|
+
onClick: (e) => e.stopPropagation(),
|
|
2344
|
+
children
|
|
2345
|
+
}
|
|
2346
|
+
) }),
|
|
2347
|
+
rootEl
|
|
2348
|
+
);
|
|
2349
|
+
};
|
|
2350
|
+
|
|
2351
|
+
// src/puck/overrides/ComponentItem.tsx
|
|
2352
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2353
|
+
var getClassName5 = get_class_name_factory_default("ComponentItem", ComponentItem_default);
|
|
2354
|
+
var ComponentItem = (props) => {
|
|
2355
|
+
const softComponents = new Set(
|
|
2356
|
+
Object.keys(useSoftConfig((s) => s.softComponents))
|
|
2357
|
+
);
|
|
2358
|
+
const removeSoftComponentVersion = useSoftConfig(
|
|
2359
|
+
(s) => s.removeSoftComponentVersion
|
|
2360
|
+
);
|
|
2361
|
+
const { handleDemolish } = useDemolish();
|
|
2362
|
+
const { handleSetDefaultVersion, getVersions, getDefaultVersion } = useSetDefaultVersion();
|
|
2363
|
+
const [isEditing, setIsEditing] = useState5(false);
|
|
2364
|
+
const [isHovering, setIsHovering] = useState5(false);
|
|
2365
|
+
const [selectedVersion, setSelectedVersion] = useState5("");
|
|
2366
|
+
const [versionsToDelete, setVersionsToDelete] = useState5(
|
|
2367
|
+
/* @__PURE__ */ new Set()
|
|
2368
|
+
);
|
|
2369
|
+
const [migrateVersionMap, setMigrateVersionMap] = useState5({});
|
|
2370
|
+
const versions = getVersions(props.name);
|
|
2371
|
+
const defaultVersion = getDefaultVersion(props.name);
|
|
2372
|
+
const handleApply = () => __async(null, null, function* () {
|
|
2373
|
+
if (selectedVersion && selectedVersion !== defaultVersion) {
|
|
2374
|
+
handleSetDefaultVersion(props.name, selectedVersion);
|
|
2375
|
+
}
|
|
2376
|
+
if (versionsToDelete.size > 0) {
|
|
2377
|
+
for (const version of versionsToDelete) {
|
|
2378
|
+
const remaining = versions.filter((v) => !versionsToDelete.has(v));
|
|
2379
|
+
if (remaining.length === 0) {
|
|
2380
|
+
const shouldDemolish = yield confirm(
|
|
2381
|
+
`Deleting all versions will remove "${props.name}" entirely. Continue?`
|
|
2382
|
+
);
|
|
2383
|
+
if (shouldDemolish) {
|
|
2384
|
+
handleDemolish(props.name);
|
|
2385
|
+
}
|
|
2386
|
+
break;
|
|
2387
|
+
} else {
|
|
2388
|
+
removeSoftComponentVersion(props.name, version);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
setIsEditing(false);
|
|
2393
|
+
setSelectedVersion("");
|
|
2394
|
+
setVersionsToDelete(/* @__PURE__ */ new Set());
|
|
2395
|
+
setMigrateVersionMap({});
|
|
2396
|
+
});
|
|
2397
|
+
const handleCancel = () => {
|
|
2398
|
+
setIsEditing(false);
|
|
2399
|
+
setSelectedVersion("");
|
|
2400
|
+
setVersionsToDelete(/* @__PURE__ */ new Set());
|
|
2401
|
+
setMigrateVersionMap({});
|
|
2402
|
+
};
|
|
2403
|
+
const toggleVersionForDeletion = (version) => {
|
|
2404
|
+
const newSet = new Set(versionsToDelete);
|
|
2405
|
+
if (newSet.has(version)) {
|
|
2406
|
+
newSet.delete(version);
|
|
2407
|
+
} else {
|
|
2408
|
+
newSet.add(version);
|
|
2409
|
+
}
|
|
2410
|
+
setVersionsToDelete(newSet);
|
|
2411
|
+
};
|
|
2412
|
+
const handleDemolishClick = () => __async(null, null, function* () {
|
|
2413
|
+
const confirmed = yield confirm(
|
|
2414
|
+
`Demolish "${props.name}" entirely? This will remove all versions.`
|
|
2415
|
+
);
|
|
2416
|
+
if (confirmed) {
|
|
2417
|
+
handleDemolish(props.name);
|
|
2418
|
+
setIsEditing(false);
|
|
2419
|
+
}
|
|
2420
|
+
});
|
|
2421
|
+
if (softComponents.has(props.name)) {
|
|
2422
|
+
const availableVersions = versions.filter((v) => !versionsToDelete.has(v));
|
|
2423
|
+
return /* @__PURE__ */ jsxs4(Fragment5, { children: [
|
|
2424
|
+
/* @__PURE__ */ jsxs4(
|
|
2425
|
+
"div",
|
|
2426
|
+
{
|
|
2427
|
+
className: getClassName5(),
|
|
2428
|
+
onMouseEnter: () => setIsHovering(true),
|
|
2429
|
+
onMouseLeave: () => setIsHovering(false),
|
|
2430
|
+
children: [
|
|
2431
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
|
|
2432
|
+
/* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: props.name }),
|
|
2433
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
|
|
2434
|
+
"v",
|
|
2435
|
+
defaultVersion
|
|
2436
|
+
] })
|
|
2437
|
+
] }),
|
|
2438
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("actions"), children: [
|
|
2439
|
+
isHovering && /* @__PURE__ */ jsx11("div", { className: getClassName5("settingsButton"), children: /* @__PURE__ */ jsx11(
|
|
2440
|
+
IconButton,
|
|
2441
|
+
{
|
|
2442
|
+
title: "Settings",
|
|
2443
|
+
variant: "secondary",
|
|
2444
|
+
onClick: (e) => {
|
|
2445
|
+
e.stopPropagation();
|
|
2446
|
+
setIsEditing(true);
|
|
2447
|
+
setSelectedVersion(defaultVersion || "");
|
|
2448
|
+
},
|
|
2449
|
+
children: /* @__PURE__ */ jsx11(Cog, { size: 14 })
|
|
2450
|
+
}
|
|
2451
|
+
) }),
|
|
2452
|
+
/* @__PURE__ */ jsx11("div", { className: getClassName5("grip"), children: /* @__PURE__ */ jsx11(GripVertical, { size: 16 }) })
|
|
2453
|
+
] })
|
|
2454
|
+
]
|
|
2455
|
+
}
|
|
2456
|
+
),
|
|
2457
|
+
/* @__PURE__ */ jsx11(Modal, { isOpen: isEditing, onClose: handleCancel, children: /* @__PURE__ */ jsxs4("div", { className: getClassName5("modal"), children: [
|
|
2458
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("modalHeader"), children: [
|
|
2459
|
+
/* @__PURE__ */ jsx11("h2", { className: getClassName5("modalTitle"), children: props.name }),
|
|
2460
|
+
/* @__PURE__ */ jsx11("p", { className: getClassName5("modalSubtitle"), children: "Manage versions and settings" })
|
|
2461
|
+
] }),
|
|
2462
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("modalBody"), children: [
|
|
2463
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
|
|
2464
|
+
/* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Versions" }),
|
|
2465
|
+
/* @__PURE__ */ jsx11("div", { className: getClassName5("versionList"), children: versions.map((version) => {
|
|
2466
|
+
const isDefault = version === (selectedVersion || defaultVersion);
|
|
2467
|
+
const isMarkedForDeletion = versionsToDelete.has(version);
|
|
2468
|
+
let rowClass = getClassName5("versionRow");
|
|
2469
|
+
if (isDefault) rowClass += " " + getClassName5("versionRow--isDefault");
|
|
2470
|
+
if (isMarkedForDeletion) rowClass += " " + getClassName5("versionRow--isMarkedForDeletion");
|
|
2471
|
+
return /* @__PURE__ */ jsxs4(
|
|
2472
|
+
"div",
|
|
2473
|
+
{
|
|
2474
|
+
className: rowClass,
|
|
2475
|
+
children: [
|
|
2476
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("versionInfo"), children: [
|
|
2477
|
+
/* @__PURE__ */ jsxs4("span", { className: getClassName5("versionNumber"), children: [
|
|
2478
|
+
"Version ",
|
|
2479
|
+
version
|
|
2480
|
+
] }),
|
|
2481
|
+
isDefault && /* @__PURE__ */ jsx11("span", { className: getClassName5("defaultBadge"), children: "Default" }),
|
|
2482
|
+
isMarkedForDeletion && /* @__PURE__ */ jsx11("span", { className: getClassName5("deleteBadge"), children: "Marked for deletion" })
|
|
2483
|
+
] }),
|
|
2484
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("versionActions"), children: [
|
|
2485
|
+
!isDefault && !isMarkedForDeletion && /* @__PURE__ */ jsx11(
|
|
2486
|
+
Button2,
|
|
2487
|
+
{
|
|
2488
|
+
variant: "secondary",
|
|
2489
|
+
onClick: () => setSelectedVersion(version),
|
|
2490
|
+
children: "Set as Default"
|
|
2491
|
+
}
|
|
2492
|
+
),
|
|
2493
|
+
/* @__PURE__ */ jsx11(
|
|
2494
|
+
Button2,
|
|
2495
|
+
{
|
|
2496
|
+
variant: isMarkedForDeletion ? "secondary" : "secondary",
|
|
2497
|
+
onClick: () => toggleVersionForDeletion(version),
|
|
2498
|
+
children: isMarkedForDeletion ? /* @__PURE__ */ jsxs4(Fragment5, { children: [
|
|
2499
|
+
/* @__PURE__ */ jsx11(X, { size: 14 }),
|
|
2500
|
+
"Undo"
|
|
2501
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment5, { children: [
|
|
2502
|
+
/* @__PURE__ */ jsx11(Trash2, { size: 14 }),
|
|
2503
|
+
"Delete"
|
|
2504
|
+
] })
|
|
2505
|
+
}
|
|
2506
|
+
)
|
|
2507
|
+
] })
|
|
2508
|
+
]
|
|
2509
|
+
},
|
|
2510
|
+
version
|
|
2511
|
+
);
|
|
2512
|
+
}) })
|
|
2513
|
+
] }),
|
|
2514
|
+
versionsToDelete.size > 0 && availableVersions.length > 0 && /* @__PURE__ */ jsxs4("div", { className: getClassName5("section"), children: [
|
|
2515
|
+
/* @__PURE__ */ jsx11("h3", { className: getClassName5("sectionTitle"), children: "Migration Settings" }),
|
|
2516
|
+
/* @__PURE__ */ jsx11("p", { className: getClassName5("sectionDescription"), children: "Choose what to do with components using deleted versions" }),
|
|
2517
|
+
/* @__PURE__ */ jsx11("div", { className: getClassName5("migrationOptions"), children: /* @__PURE__ */ jsxs4(
|
|
2518
|
+
"select",
|
|
2519
|
+
{
|
|
2520
|
+
className: getClassName5("select"),
|
|
2521
|
+
value: migrateVersionMap[Array.from(versionsToDelete)[0]] || "decompose",
|
|
2522
|
+
onChange: (e) => {
|
|
2523
|
+
const newMap = __spreadValues({}, migrateVersionMap);
|
|
2524
|
+
versionsToDelete.forEach((v) => {
|
|
2525
|
+
newMap[v] = e.target.value;
|
|
2526
|
+
});
|
|
2527
|
+
setMigrateVersionMap(newMap);
|
|
2528
|
+
},
|
|
2529
|
+
children: [
|
|
2530
|
+
/* @__PURE__ */ jsx11("option", { value: "decompose", children: "Decompose to basic elements" }),
|
|
2531
|
+
availableVersions.map((v) => /* @__PURE__ */ jsxs4("option", { value: v, children: [
|
|
2532
|
+
"Migrate to Version ",
|
|
2533
|
+
v
|
|
2534
|
+
] }, v))
|
|
2535
|
+
]
|
|
2536
|
+
}
|
|
2537
|
+
) })
|
|
2538
|
+
] })
|
|
2539
|
+
] }),
|
|
2540
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("modalFooter"), children: [
|
|
2541
|
+
/* @__PURE__ */ jsxs4("div", { className: getClassName5("footerLeft"), children: [
|
|
2542
|
+
/* @__PURE__ */ jsxs4(Button2, { size: "medium", onClick: handleApply, children: [
|
|
2543
|
+
/* @__PURE__ */ jsx11(Check, { size: 16 }),
|
|
2544
|
+
"Apply Changes"
|
|
2545
|
+
] }),
|
|
2546
|
+
/* @__PURE__ */ jsxs4(Button2, { size: "medium", variant: "secondary", onClick: handleCancel, children: [
|
|
2547
|
+
/* @__PURE__ */ jsx11(X, { size: 16 }),
|
|
2548
|
+
"Cancel"
|
|
2549
|
+
] })
|
|
2550
|
+
] }),
|
|
2551
|
+
/* @__PURE__ */ jsx11("div", { className: getClassName5("footerRight"), children: /* @__PURE__ */ jsxs4(
|
|
2552
|
+
Button2,
|
|
2553
|
+
{
|
|
2554
|
+
size: "medium",
|
|
2555
|
+
variant: "secondary",
|
|
2556
|
+
onClick: handleDemolishClick,
|
|
2557
|
+
children: [
|
|
2558
|
+
/* @__PURE__ */ jsx11(Trash2, { size: 16 }),
|
|
2559
|
+
"Demolish Component"
|
|
2560
|
+
]
|
|
2561
|
+
}
|
|
2562
|
+
) })
|
|
2563
|
+
] })
|
|
2564
|
+
] }) })
|
|
2565
|
+
] });
|
|
2566
|
+
}
|
|
2567
|
+
return /* @__PURE__ */ jsx11(Fragment5, { children: props.children });
|
|
2568
|
+
};
|
|
2569
|
+
|
|
2570
|
+
// src/puck/lib/dissolve-all-soft-components.ts
|
|
2571
|
+
function extractDependencies2(softComponents, componentName, version) {
|
|
2572
|
+
var _a, _b;
|
|
2573
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
2574
|
+
const component = (_b = (_a = softComponents[componentName]) == null ? void 0 : _a.versions) == null ? void 0 : _b[version];
|
|
2575
|
+
if (!component) {
|
|
2576
|
+
return dependencies;
|
|
2577
|
+
}
|
|
2578
|
+
const processSubComponents = (subComponents) => {
|
|
2579
|
+
if (!Array.isArray(subComponents)) return;
|
|
2580
|
+
for (const subComponent of subComponents) {
|
|
2581
|
+
if (subComponent == null ? void 0 : subComponent.type) {
|
|
2582
|
+
dependencies.add(subComponent.type);
|
|
2583
|
+
if (subComponent.components) {
|
|
2584
|
+
Object.values(subComponent.components).forEach((nestedComponents) => {
|
|
2585
|
+
processSubComponents(nestedComponents);
|
|
2586
|
+
});
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
};
|
|
2591
|
+
processSubComponents(component.components);
|
|
2592
|
+
return dependencies;
|
|
2593
|
+
}
|
|
2594
|
+
function reverseTopologicalSort(softComponents, hardComponentNames) {
|
|
2595
|
+
const sorted = [];
|
|
2596
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
2597
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2598
|
+
const dependencyGraph = /* @__PURE__ */ new Map();
|
|
2599
|
+
const dependents = /* @__PURE__ */ new Map();
|
|
2600
|
+
for (const [componentName, component] of Object.entries(softComponents)) {
|
|
2601
|
+
const defaultVersion = component.defaultVersion || Object.keys(component.versions || {}).pop();
|
|
2602
|
+
if (!defaultVersion) continue;
|
|
2603
|
+
const allDeps = extractDependencies2(
|
|
2604
|
+
softComponents,
|
|
2605
|
+
componentName,
|
|
2606
|
+
defaultVersion
|
|
2607
|
+
);
|
|
2608
|
+
const softDeps = new Set(
|
|
2609
|
+
[...allDeps].filter((dep) => !hardComponentNames.has(dep))
|
|
2610
|
+
);
|
|
2611
|
+
dependencyGraph.set(componentName, softDeps);
|
|
2612
|
+
for (const dep of softDeps) {
|
|
2613
|
+
if (!dependents.has(dep)) {
|
|
2614
|
+
dependents.set(dep, /* @__PURE__ */ new Set());
|
|
2615
|
+
}
|
|
2616
|
+
dependents.get(dep).add(componentName);
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
const depths = /* @__PURE__ */ new Map();
|
|
2620
|
+
function calculateDepth(componentName) {
|
|
2621
|
+
if (depths.has(componentName)) {
|
|
2622
|
+
return depths.get(componentName);
|
|
2623
|
+
}
|
|
2624
|
+
const deps = dependencyGraph.get(componentName) || /* @__PURE__ */ new Set();
|
|
2625
|
+
if (deps.size === 0) {
|
|
2626
|
+
depths.set(componentName, 0);
|
|
2627
|
+
return 0;
|
|
2628
|
+
}
|
|
2629
|
+
let maxDepth = -1;
|
|
2630
|
+
for (const dep of deps) {
|
|
2631
|
+
if (softComponents[dep]) {
|
|
2632
|
+
maxDepth = Math.max(maxDepth, calculateDepth(dep));
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
const depth = maxDepth + 1;
|
|
2636
|
+
depths.set(componentName, depth);
|
|
2637
|
+
return depth;
|
|
2638
|
+
}
|
|
2639
|
+
for (const componentName of Object.keys(softComponents)) {
|
|
2640
|
+
calculateDepth(componentName);
|
|
2641
|
+
}
|
|
2642
|
+
const sortedByDepth = [...depths.entries()].sort(([, depthA], [, depthB]) => depthB - depthA).map(([name]) => name);
|
|
2643
|
+
return sortedByDepth;
|
|
2644
|
+
}
|
|
2645
|
+
function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0) {
|
|
2646
|
+
const MAX_DEPTH = 50;
|
|
2647
|
+
if (depth > MAX_DEPTH) {
|
|
2648
|
+
console.error(
|
|
2649
|
+
`Maximum dissolution depth (${MAX_DEPTH}) exceeded for component ${componentData.type}. Possible circular dependency.`
|
|
2650
|
+
);
|
|
2651
|
+
return [componentData];
|
|
2652
|
+
}
|
|
2653
|
+
const componentType = componentData.type;
|
|
2654
|
+
if (!isSoftComponent(componentType, softComponents)) {
|
|
2655
|
+
return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth)];
|
|
2656
|
+
}
|
|
2657
|
+
let decomposed;
|
|
2658
|
+
try {
|
|
2659
|
+
decomposed = decomposeSoftComponent(componentData, softComponents);
|
|
2660
|
+
} catch (error) {
|
|
2661
|
+
console.warn(
|
|
2662
|
+
`Failed to decompose soft component "${componentType}":`,
|
|
2663
|
+
error
|
|
2664
|
+
);
|
|
2665
|
+
return [componentData];
|
|
2666
|
+
}
|
|
2667
|
+
const fullyDissolved = [];
|
|
2668
|
+
for (const component of decomposed) {
|
|
2669
|
+
const dissolved = dissolveComponentRecursively(
|
|
2670
|
+
component,
|
|
2671
|
+
softComponents,
|
|
2672
|
+
hardComponentNames,
|
|
2673
|
+
depth + 1
|
|
2674
|
+
);
|
|
2675
|
+
fullyDissolved.push(...dissolved);
|
|
2676
|
+
}
|
|
2677
|
+
return fullyDissolved;
|
|
2678
|
+
}
|
|
2679
|
+
function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth) {
|
|
2680
|
+
const newProps = __spreadValues({}, componentData.props);
|
|
2681
|
+
Object.entries(newProps).forEach(([key, value]) => {
|
|
2682
|
+
var _a;
|
|
2683
|
+
if (Array.isArray(value) && value.length > 0 && ((_a = value[0]) == null ? void 0 : _a.type)) {
|
|
2684
|
+
newProps[key] = value.flatMap(
|
|
2685
|
+
(slotComponent) => dissolveComponentRecursively(
|
|
2686
|
+
slotComponent,
|
|
2687
|
+
softComponents,
|
|
2688
|
+
hardComponentNames,
|
|
2689
|
+
depth
|
|
2690
|
+
)
|
|
2691
|
+
);
|
|
2692
|
+
}
|
|
2693
|
+
});
|
|
2694
|
+
return __spreadProps(__spreadValues({}, componentData), {
|
|
2695
|
+
props: newProps
|
|
2696
|
+
});
|
|
2697
|
+
}
|
|
2698
|
+
function dissolveAllSoftComponents(data, softComponents, config) {
|
|
2699
|
+
const hardComponentNames = new Set(
|
|
2700
|
+
Object.keys(config.components || {}).filter(
|
|
2701
|
+
(name) => !isSoftComponent(name, softComponents)
|
|
2702
|
+
)
|
|
2703
|
+
);
|
|
2704
|
+
const dissolutionOrder = reverseTopologicalSort(
|
|
2705
|
+
softComponents,
|
|
2706
|
+
hardComponentNames
|
|
2707
|
+
);
|
|
2708
|
+
const dissolveComponents = (components) => {
|
|
2709
|
+
return components.flatMap((componentData) => {
|
|
2710
|
+
return dissolveComponentRecursively(
|
|
2711
|
+
componentData,
|
|
2712
|
+
softComponents,
|
|
2713
|
+
hardComponentNames,
|
|
2714
|
+
0
|
|
2715
|
+
);
|
|
2716
|
+
});
|
|
2717
|
+
};
|
|
2718
|
+
const newContent = dissolveComponents(data.content || []);
|
|
2719
|
+
const newZones = {};
|
|
2720
|
+
if (data.zones) {
|
|
2721
|
+
Object.entries(data.zones).forEach(([zoneName, zoneComponents]) => {
|
|
2722
|
+
newZones[zoneName] = dissolveComponents(zoneComponents);
|
|
2723
|
+
});
|
|
2724
|
+
}
|
|
2725
|
+
const result = __spreadValues(__spreadProps(__spreadValues({}, data), {
|
|
2726
|
+
content: newContent
|
|
2727
|
+
}), data.zones && { zones: newZones });
|
|
2728
|
+
return result;
|
|
2729
|
+
}
|
|
2730
|
+
function validateOnlyHardComponents(data, softComponents) {
|
|
2731
|
+
const softComponentsFound = [];
|
|
2732
|
+
const checkComponents = (components) => {
|
|
2733
|
+
for (const component of components) {
|
|
2734
|
+
if (isSoftComponent(component.type, softComponents)) {
|
|
2735
|
+
softComponentsFound.push(component.type);
|
|
2736
|
+
}
|
|
2737
|
+
Object.values(component.props || {}).forEach((value) => {
|
|
2738
|
+
var _a;
|
|
2739
|
+
if (Array.isArray(value) && value.length > 0 && ((_a = value[0]) == null ? void 0 : _a.type)) {
|
|
2740
|
+
checkComponents(value);
|
|
2741
|
+
}
|
|
2742
|
+
});
|
|
2743
|
+
}
|
|
2744
|
+
};
|
|
2745
|
+
checkComponents(data.content || []);
|
|
2746
|
+
if (data.zones) {
|
|
2747
|
+
Object.values(data.zones).forEach((zoneComponents) => {
|
|
2748
|
+
checkComponents(zoneComponents);
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2751
|
+
return {
|
|
2752
|
+
isValid: softComponentsFound.length === 0,
|
|
2753
|
+
softComponentsFound: [...new Set(softComponentsFound)]
|
|
2754
|
+
};
|
|
2755
|
+
}
|
|
2756
|
+
|
|
2757
|
+
// src/puck/lib/resolve-soft-config.ts
|
|
2758
|
+
var resolveSoftConfig = (data, softComponents, config) => {
|
|
2759
|
+
const dissolved = dissolveAllSoftComponents(data, softComponents, config);
|
|
2760
|
+
if (process.env.NODE_ENV === "development") {
|
|
2761
|
+
const validation = validateOnlyHardComponents(dissolved, softComponents);
|
|
2762
|
+
if (!validation.isValid) {
|
|
2763
|
+
console.warn(
|
|
2764
|
+
"Warning: Soft components still present after dissolution:",
|
|
2765
|
+
validation.softComponentsFound
|
|
2766
|
+
);
|
|
2767
|
+
}
|
|
2768
|
+
}
|
|
2769
|
+
return dissolved;
|
|
2770
|
+
};
|
|
2771
|
+
export {
|
|
2772
|
+
ActionBarOverride as ActionBar,
|
|
2773
|
+
ComponentItem,
|
|
2774
|
+
Header,
|
|
2775
|
+
SoftConfigProvider,
|
|
2776
|
+
confirm,
|
|
2777
|
+
createSoftConfigStore,
|
|
2778
|
+
createUseSoftConfig,
|
|
2779
|
+
notify,
|
|
2780
|
+
resolveSoftConfig,
|
|
2781
|
+
setConfirmHandler,
|
|
2782
|
+
setNotificationHandler,
|
|
2783
|
+
useBuild,
|
|
2784
|
+
useCancel,
|
|
2785
|
+
useComplete,
|
|
2786
|
+
useDecompose,
|
|
2787
|
+
useDemolish,
|
|
2788
|
+
useInspect,
|
|
2789
|
+
useRemodel,
|
|
2790
|
+
useSetDefaultVersion,
|
|
2791
|
+
useSoftConfig
|
|
2792
|
+
};
|