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