@netlisian/softconfig 0.1.3 → 0.1.5

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.
@@ -18,18 +18,6 @@ var __spreadValues = (a, b) => {
18
18
  return a;
19
19
  };
20
20
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
- var __objRest = (source, exclude) => {
22
- var target = {};
23
- for (var prop in source)
24
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
- target[prop] = source[prop];
26
- if (source != null && __getOwnPropSymbols)
27
- for (var prop of __getOwnPropSymbols(source)) {
28
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
- target[prop] = source[prop];
30
- }
31
- return target;
32
- };
33
21
  var __async = (__this, __arguments, generator) => {
34
22
  return new Promise((resolve, reject) => {
35
23
  var fulfilled = (value) => {
@@ -64,6 +52,8 @@ import {
64
52
  var getRootProps = (appState) => appState.data.root.props;
65
53
 
66
54
  // src/puck/lib/builder/root-config.tsx
55
+ import { useEffect } from "react";
56
+ import equal2 from "react-fast-compare";
67
57
  import {
68
58
  createUsePuck,
69
59
  walkTree
@@ -71,59 +61,352 @@ import {
71
61
 
72
62
  // src/puck/lib/get-field-settings.tsx
73
63
  import { AutoField } from "@measured/puck";
64
+
65
+ // src/puck/lib/get-settings-by-path.ts
66
+ function getFieldSettingsByPath(fieldSettings, path) {
67
+ return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
68
+ }
69
+
70
+ // src/puck/lib/array-field-utils.ts
71
+ var primitiveFieldTypes = /* @__PURE__ */ new Set([
72
+ "text",
73
+ "textarea",
74
+ "number",
75
+ "select",
76
+ "radio",
77
+ "reference"
78
+ ]);
79
+ var isPrimitiveValue = (value) => ["string", "number", "boolean"].includes(typeof value);
80
+ var getFallbackValueForField = (type) => {
81
+ switch (type) {
82
+ case "number":
83
+ return 0;
84
+ case "array":
85
+ return [];
86
+ case "object":
87
+ return {};
88
+ default:
89
+ return "";
90
+ }
91
+ };
92
+ var resolveExpressionSummary = (item, index, expression) => {
93
+ if (!expression) return "";
94
+ let isValid = true;
95
+ const result = expression.replace(/\{([^}]+)\}/g, (_match, token) => {
96
+ if (token === "index") {
97
+ return String(index);
98
+ }
99
+ if (token.startsWith("item.")) {
100
+ const value = getFieldSettingsByPath(item, token.slice(5));
101
+ if (isPrimitiveValue(value)) {
102
+ return String(value);
103
+ }
104
+ }
105
+ isValid = false;
106
+ return "";
107
+ });
108
+ return isValid ? result : "";
109
+ };
110
+ var isPrimitiveFieldType = (type) => primitiveFieldTypes.has(type);
111
+ var buildArrayDefaultItemProps = (subFields = [], subFieldSettings = {}) => {
112
+ if (!subFields.length) return void 0;
113
+ const item = {};
114
+ let hasValue = false;
115
+ subFields.forEach((subField) => {
116
+ const settings = subFieldSettings[subField.name];
117
+ if (settings && Object.prototype.hasOwnProperty.call(settings, "defaultValue") && settings.defaultValue !== void 0) {
118
+ item[subField.name] = settings.defaultValue;
119
+ hasValue = true;
120
+ return;
121
+ }
122
+ item[subField.name] = getFallbackValueForField(subField.type);
123
+ hasValue = true;
124
+ });
125
+ return hasValue ? item : void 0;
126
+ };
127
+ var buildArrayDefaultValue = (subFields = [], subFieldSettings = {}) => {
128
+ const item = buildArrayDefaultItemProps(subFields, subFieldSettings);
129
+ return item ? [item] : [];
130
+ };
131
+ var getArrayItemSummary = (item, index = 0, settings) => {
132
+ if ((settings == null ? void 0 : settings.summary) === "field" && settings.summaryField) {
133
+ const value = getFieldSettingsByPath(item, settings.summaryField);
134
+ if (isPrimitiveValue(value) && String(value).length > 0) {
135
+ return String(value);
136
+ }
137
+ return `Item ${(index || 0) + 1}`;
138
+ }
139
+ if ((settings == null ? void 0 : settings.summary) === "expression") {
140
+ const summary = resolveExpressionSummary(
141
+ item,
142
+ index,
143
+ settings.summaryExpression
144
+ );
145
+ return summary || `Item ${(index || 0) + 1}`;
146
+ }
147
+ return `Item ${(index || 0) + 1}`;
148
+ };
149
+ var isArrayMappingPath = (path) => {
150
+ return typeof path === "string" && /^[^.]+\[\]\.[^.]+$/.test(path);
151
+ };
152
+ var getArrayBasePath = (arrayPath) => {
153
+ if (!isArrayMappingPath(arrayPath)) return null;
154
+ const match = arrayPath.match(/^([^.]+)\[\]\./);
155
+ return match ? match[1] : null;
156
+ };
157
+ var getArrayItemSubPath = (arrayPath) => {
158
+ if (!isArrayMappingPath(arrayPath)) return null;
159
+ const match = arrayPath.match(/\[\]\.(.+)$/);
160
+ return match ? match[1] : null;
161
+ };
162
+
163
+ // src/puck/lib/custom-fields.ts
164
+ var builtInSoftFieldTypes = /* @__PURE__ */ new Set([
165
+ "text",
166
+ "textarea",
167
+ "number",
168
+ "select",
169
+ "radio",
170
+ "array",
171
+ "object",
172
+ "reference"
173
+ ]);
174
+ var warnedMessages = /* @__PURE__ */ new Set();
175
+ var warnOnce = (message) => {
176
+ if (warnedMessages.has(message)) {
177
+ return;
178
+ }
179
+ warnedMessages.add(message);
180
+ console.warn(message);
181
+ };
182
+ var isBuiltInSoftFieldType = (fieldType) => {
183
+ return builtInSoftFieldTypes.has(fieldType);
184
+ };
185
+ var resolveCustomFieldDefinition = (fieldType, customFields) => {
186
+ if (isBuiltInSoftFieldType(fieldType)) {
187
+ return void 0;
188
+ }
189
+ return customFields == null ? void 0 : customFields[fieldType];
190
+ };
191
+ var resolveCustomFieldReturnType = (fieldType, customFields) => {
192
+ const customField = resolveCustomFieldDefinition(fieldType, customFields);
193
+ if (!customField) {
194
+ return null;
195
+ }
196
+ if (!customField.returnType) {
197
+ warnOnce(
198
+ `[soft-config] Custom field "${fieldType}" is missing a required returnType and will be skipped from mapping options.`
199
+ );
200
+ return null;
201
+ }
202
+ return customField.returnType;
203
+ };
204
+ var resolveCustomFieldSchema = (fieldType, customFields) => {
205
+ const customField = resolveCustomFieldDefinition(fieldType, customFields);
206
+ if (!customField) {
207
+ return null;
208
+ }
209
+ const returnType = resolveCustomFieldReturnType(fieldType, customFields);
210
+ if (!returnType) {
211
+ return null;
212
+ }
213
+ if (returnType !== "array" && returnType !== "object") {
214
+ return null;
215
+ }
216
+ const subFields = customField.subFields || [];
217
+ if (!subFields.length) {
218
+ warnOnce(
219
+ `[soft-config] Custom field "${fieldType}" returns ${returnType} but does not define subFields. It will be skipped from mapping options.`
220
+ );
221
+ return null;
222
+ }
223
+ return {
224
+ subFields,
225
+ subFieldSettings: customField.subFieldSettings || {}
226
+ };
227
+ };
228
+ var getCustomFieldTypeOptions = (customFields) => {
229
+ if (!customFields) {
230
+ return [];
231
+ }
232
+ return Object.entries(customFields).filter(([fieldType]) => !isBuiltInSoftFieldType(fieldType)).map(([fieldType, definition]) => ({
233
+ label: typeof definition.field.label === "string" && definition.field.label ? definition.field.label : fieldType,
234
+ value: fieldType
235
+ }));
236
+ };
237
+ var mapCustomReturnTypeToMappingType = (returnType) => {
238
+ switch (returnType) {
239
+ case "string":
240
+ return "textarea";
241
+ case "number":
242
+ return "number";
243
+ case "boolean":
244
+ return "select";
245
+ case "array":
246
+ return "array";
247
+ case "object":
248
+ return "object";
249
+ default:
250
+ return "textarea";
251
+ }
252
+ };
253
+
254
+ // src/puck/lib/get-field-settings.tsx
74
255
  import { jsx } from "react/jsx-runtime";
75
- var getFieldSettings = (_fields, _fieldSettings, deep) => {
256
+ var buildPuckField = (field, fieldSettings, customFields) => {
257
+ const customFieldDefinition = resolveCustomFieldDefinition(
258
+ field.type,
259
+ customFields
260
+ );
261
+ const customReturnType = resolveCustomFieldReturnType(field.type, customFields);
262
+ if (customFieldDefinition && customReturnType) {
263
+ return __spreadProps(__spreadValues({}, customFieldDefinition.field), {
264
+ type: "custom",
265
+ label: customFieldDefinition.field.label || field.name
266
+ });
267
+ }
268
+ const resolvedType = field.type;
269
+ switch (resolvedType) {
270
+ case "text":
271
+ case "textarea":
272
+ return { type: resolvedType, label: field.name };
273
+ case "number":
274
+ return {
275
+ type: resolvedType,
276
+ label: field.name,
277
+ min: fieldSettings == null ? void 0 : fieldSettings.min,
278
+ max: fieldSettings == null ? void 0 : fieldSettings.max,
279
+ step: fieldSettings == null ? void 0 : fieldSettings.step
280
+ };
281
+ case "select":
282
+ case "radio":
283
+ return {
284
+ type: resolvedType,
285
+ label: field.name,
286
+ options: (fieldSettings == null ? void 0 : fieldSettings.options) || []
287
+ };
288
+ case "array": {
289
+ const subFields = (fieldSettings == null ? void 0 : fieldSettings.subFields) || [];
290
+ const subFieldSettings = (fieldSettings == null ? void 0 : fieldSettings.subFieldSettings) || {};
291
+ return {
292
+ type: "array",
293
+ label: field.name,
294
+ min: fieldSettings == null ? void 0 : fieldSettings.min,
295
+ max: fieldSettings == null ? void 0 : fieldSettings.max,
296
+ arrayFields: buildDefaultEditorFields(
297
+ subFields,
298
+ subFieldSettings,
299
+ customFields
300
+ ),
301
+ defaultItemProps: buildArrayDefaultItemProps(subFields, subFieldSettings),
302
+ getItemSummary(item, index) {
303
+ return getArrayItemSummary(item, index, fieldSettings);
304
+ }
305
+ };
306
+ }
307
+ case "object":
308
+ return {
309
+ type: "object",
310
+ label: field.name,
311
+ objectFields: buildDefaultEditorFields(
312
+ (fieldSettings == null ? void 0 : fieldSettings.subFields) || [],
313
+ (fieldSettings == null ? void 0 : fieldSettings.subFieldSettings) || {},
314
+ customFields
315
+ )
316
+ };
317
+ default:
318
+ return { type: "text", label: field.name };
319
+ }
320
+ };
321
+ var buildDefaultEditorFields = (fields = [], fieldSettings = {}, customFields) => {
322
+ return fields.reduce((acc, field) => {
323
+ acc[field.name] = buildPuckField(
324
+ field,
325
+ fieldSettings[field.name],
326
+ customFields
327
+ );
328
+ return acc;
329
+ }, {});
330
+ };
331
+ var getFieldSettings = (_fields, _fieldSettings, customFields, deep) => {
332
+ const customTypeOptions = getCustomFieldTypeOptions(customFields);
76
333
  return (_fields || []).reduce((fields, field) => {
77
334
  const fieldSettings = {
78
335
  // placeholder: { type: "text", label: "Placeholder" },
79
336
  };
80
337
  const currentFieldSettings = _fieldSettings == null ? void 0 : _fieldSettings[field.name];
81
- switch (field.type) {
338
+ const customFieldDefinition = resolveCustomFieldDefinition(
339
+ field.type,
340
+ customFields
341
+ );
342
+ const customReturnType = resolveCustomFieldReturnType(
343
+ field.type,
344
+ customFields
345
+ );
346
+ const resolvedType = field.type;
347
+ const customSchema = resolveCustomFieldSchema(field.type, customFields);
348
+ const resolvedSubFields = (customSchema == null ? void 0 : customSchema.subFields) || (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || [];
349
+ const resolvedSubFieldSettings = (customSchema == null ? void 0 : customSchema.subFieldSettings) || (currentFieldSettings == null ? void 0 : currentFieldSettings.subFieldSettings) || {};
350
+ const customDefaultValueField = customFieldDefinition && customReturnType ? __spreadProps(__spreadValues({}, customFieldDefinition.field), {
351
+ type: "custom",
352
+ label: customFieldDefinition.field.label || "Default Value"
353
+ }) : null;
354
+ if (customDefaultValueField) {
355
+ fieldSettings.defaultValue = customDefaultValueField;
356
+ }
357
+ switch (resolvedType) {
82
358
  case "text":
83
359
  case "textarea":
84
- fieldSettings.defaultValue = {
85
- type: field.type,
86
- label: "Default Value"
87
- };
360
+ if (!customDefaultValueField) {
361
+ fieldSettings.defaultValue = {
362
+ type: resolvedType,
363
+ label: "Default Value"
364
+ };
365
+ }
88
366
  break;
89
367
  case "number":
90
- fieldSettings.defaultValue = {
91
- type: field.type,
92
- label: "Default Value"
93
- };
368
+ if (!customDefaultValueField) {
369
+ fieldSettings.defaultValue = {
370
+ type: resolvedType,
371
+ label: "Default Value"
372
+ };
373
+ }
94
374
  fieldSettings.min = {
95
- type: field.type,
375
+ type: resolvedType,
96
376
  label: "Minimum Value"
97
377
  };
98
378
  fieldSettings.max = {
99
- type: field.type,
379
+ type: resolvedType,
100
380
  label: "Maximum Value"
101
381
  };
102
382
  fieldSettings.step = {
103
- type: field.type,
383
+ type: resolvedType,
104
384
  label: "Step Size"
105
385
  };
106
386
  break;
107
387
  case "radio":
108
- case "select":
109
- fieldSettings.defaultValue = {
110
- type: "custom",
111
- label: "Default Value",
112
- render: ({ value, onChange, id }) => /* @__PURE__ */ jsx(
113
- AutoField,
114
- {
115
- field: {
116
- type: field.type,
117
- label: "Default Value",
118
- options: (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || []
119
- },
120
- value,
121
- onChange,
122
- readOnly: false,
123
- id
124
- }
125
- )
126
- };
388
+ case "select": {
389
+ const selectOptions = (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || [];
390
+ if (!customDefaultValueField) {
391
+ fieldSettings.defaultValue = {
392
+ type: "custom",
393
+ label: "Default Value",
394
+ render: ({ value, onChange, id }) => /* @__PURE__ */ jsx(
395
+ AutoField,
396
+ {
397
+ field: {
398
+ type: resolvedType,
399
+ label: "Default Value",
400
+ options: selectOptions
401
+ },
402
+ value,
403
+ onChange,
404
+ readOnly: false,
405
+ id
406
+ }
407
+ )
408
+ };
409
+ }
127
410
  fieldSettings.options = {
128
411
  type: "array",
129
412
  label: "Options",
@@ -143,21 +426,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
143
426
  }
144
427
  };
145
428
  break;
429
+ }
146
430
  case "array":
147
- fieldSettings.summary = {
148
- type: "select",
149
- label: "Summary Field",
150
- options: [
151
- {
152
- label: "Default Numbering",
153
- value: ""
154
- },
155
- ...((currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || []).map((f) => ({
156
- label: f.name,
157
- value: f.name
158
- }))
159
- ]
160
- };
161
431
  case "object":
162
432
  fieldSettings.subFields = {
163
433
  type: "array",
@@ -186,7 +456,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
186
456
  {
187
457
  label: "Radio",
188
458
  value: "radio"
189
- }
459
+ },
460
+ ...customTypeOptions
190
461
  ] : [
191
462
  {
192
463
  label: "Text",
@@ -215,7 +486,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
215
486
  {
216
487
  label: "Reference",
217
488
  value: "reference"
218
- }
489
+ },
490
+ ...customTypeOptions
219
491
  ]
220
492
  }
221
493
  },
@@ -227,44 +499,99 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
227
499
  fieldSettings.subFieldSettings = {
228
500
  type: "object",
229
501
  label: "Sub Field Settings",
230
- objectFields: (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) ? getFieldSettings(
231
- currentFieldSettings.subFields,
232
- currentFieldSettings.subFieldSettings,
502
+ objectFields: resolvedSubFields ? getFieldSettings(
503
+ resolvedSubFields,
504
+ resolvedSubFieldSettings,
505
+ customFields,
233
506
  true
234
507
  ) : {}
235
508
  };
509
+ if (resolvedType === "array") {
510
+ if (!customDefaultValueField) {
511
+ fieldSettings.defaultValue = {
512
+ type: "array",
513
+ label: "Default Items",
514
+ arrayFields: buildDefaultEditorFields(
515
+ resolvedSubFields,
516
+ resolvedSubFieldSettings,
517
+ customFields
518
+ ),
519
+ defaultItemProps: buildArrayDefaultItemProps(
520
+ resolvedSubFields,
521
+ resolvedSubFieldSettings
522
+ ),
523
+ getItemSummary(item, index) {
524
+ return getArrayItemSummary(item, index, currentFieldSettings);
525
+ }
526
+ };
527
+ }
528
+ fieldSettings.min = {
529
+ type: "number",
530
+ label: "Minimum Items"
531
+ };
532
+ fieldSettings.max = {
533
+ type: "number",
534
+ label: "Maximum Items"
535
+ };
536
+ fieldSettings.summary = {
537
+ type: "select",
538
+ label: "Summary",
539
+ options: [
540
+ {
541
+ label: "Default Numbering / Count",
542
+ value: "count"
543
+ },
544
+ {
545
+ label: "Field",
546
+ value: "field"
547
+ },
548
+ {
549
+ label: "Expression",
550
+ value: "expression"
551
+ }
552
+ ]
553
+ };
554
+ if ((currentFieldSettings == null ? void 0 : currentFieldSettings.summary) === "field") {
555
+ fieldSettings.summaryField = {
556
+ type: "select",
557
+ label: "Summary Field",
558
+ options: [
559
+ {
560
+ label: "Select a field",
561
+ value: ""
562
+ },
563
+ ...resolvedSubFields.filter((subField) => isPrimitiveFieldType(subField.type)).map((subField) => ({
564
+ label: subField.name,
565
+ value: subField.name
566
+ }))
567
+ ]
568
+ };
569
+ }
570
+ if ((currentFieldSettings == null ? void 0 : currentFieldSettings.summary) === "expression") {
571
+ fieldSettings.summaryExpression = {
572
+ type: "text",
573
+ label: "Summary Expression"
574
+ };
575
+ }
576
+ }
236
577
  break;
237
578
  }
579
+ const overriddenFieldSettings = (customFieldDefinition == null ? void 0 : customFieldDefinition.fieldSettingsOverride) ? customFieldDefinition.fieldSettingsOverride({
580
+ fieldName: field.name,
581
+ fieldType: field.type,
582
+ fieldSettings: currentFieldSettings,
583
+ originalFieldSettings: fieldSettings
584
+ }) : fieldSettings;
238
585
  fields[field.name] = {
239
586
  type: "object",
240
587
  label: field.name,
241
- objectFields: fieldSettings
588
+ objectFields: overriddenFieldSettings
242
589
  };
243
590
  return fields;
244
591
  }, {});
245
592
  };
246
593
  var get_field_settings_default = getFieldSettings;
247
594
 
248
- // src/puck/lib/get-settings-by-path.ts
249
- function getFieldSettingsByPath(fieldSettings, path) {
250
- return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
251
- }
252
-
253
- // src/puck/lib/set-prop-by-path.ts
254
- function setPropertyByPath(props, path, value) {
255
- const parts = path.split(".");
256
- const last = parts.pop();
257
- let cur = props;
258
- for (const p of parts) {
259
- if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
260
- cur = cur[p];
261
- }
262
- cur[last] = value;
263
- }
264
-
265
- // src/puck/lib/builder/root-config.tsx
266
- import { useEffect } from "react";
267
-
268
595
  // src/puck/context/useStore.ts
269
596
  import { createContext, useContext } from "react";
270
597
  import { useStore } from "zustand";
@@ -285,224 +612,356 @@ var createUseSoftConfig = () => {
285
612
  };
286
613
  var useSoftConfig = createUseSoftConfig();
287
614
 
288
- // src/puck/lib/builder/root-config.tsx
289
- import { useDebounce } from "use-debounce";
290
- import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
291
- var useCustomPuck = createUsePuck();
292
- var breakVersion = (version) => {
293
- const [major, minor, patch] = version.split(".").map((v) => parseInt(v));
294
- return [major, minor, patch];
295
- };
296
- var updateVersion = (version, increment) => {
297
- let [major, minor, patch] = breakVersion(version);
298
- if (increment === "major") {
299
- major += 1;
300
- minor = 0;
301
- patch = 0;
302
- } else if (increment === "minor") {
303
- minor += 1;
304
- patch = 0;
305
- } else {
306
- patch += 1;
615
+ // src/puck/lib/apply-mapping.ts
616
+ import equal from "react-fast-compare";
617
+
618
+ // src/puck/lib/set-prop-by-path.ts
619
+ function setPropertyByPath(props, path, value) {
620
+ const parts = path.split(".");
621
+ const last = parts.pop();
622
+ let cur = props;
623
+ for (const p of parts) {
624
+ if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
625
+ cur = cur[p];
307
626
  }
308
- return `${major}.${minor}.${patch}`;
627
+ cur[last] = value;
628
+ }
629
+
630
+ // src/puck/lib/apply-mapping.ts
631
+ var resolveValueByPath = (source, path) => {
632
+ if (!path) return source;
633
+ const segments = path.split(".");
634
+ const resolveSegments = (current, index) => {
635
+ if (current === null || current === void 0) return void 0;
636
+ if (index >= segments.length) return current;
637
+ const segment = segments[index];
638
+ if (segment.endsWith("[]")) {
639
+ const arrayKey = segment.slice(0, -2);
640
+ const arraySource = arrayKey ? current == null ? void 0 : current[arrayKey] : current;
641
+ const resolvedArray = Array.isArray(arraySource) ? arraySource : Array.isArray(arraySource == null ? void 0 : arraySource.defaultValue) ? arraySource.defaultValue : void 0;
642
+ if (!resolvedArray) return void 0;
643
+ if (index === segments.length - 1) return resolvedArray;
644
+ return resolvedArray.map((item) => resolveSegments(item, index + 1));
645
+ }
646
+ return resolveSegments(current[segment], index + 1);
647
+ };
648
+ return resolveSegments(source, 0);
309
649
  };
310
- var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true) => ({
311
- fields: {
312
- _name: overrides.name || {
313
- type: "text",
314
- label: "Soft Component Name"
315
- },
316
- _category: overrides.categories || {
317
- type: "select",
318
- label: "Category",
319
- options: [
320
- ...Object.keys(config.categories || {}).map((cat) => {
321
- var _a;
322
- return {
323
- label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
324
- value: cat
325
- };
326
- }) || [],
327
- {
328
- label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
329
- value: void 0
650
+ var resolveFieldSettingEntryByPath = (settings, path) => {
651
+ if (!path) return void 0;
652
+ const segments = path.split(".");
653
+ let currentSettings = settings;
654
+ let currentEntry;
655
+ for (const segmentWithArraySuffix of segments) {
656
+ const segment = segmentWithArraySuffix.endsWith("[]") ? segmentWithArraySuffix.slice(0, -2) : segmentWithArraySuffix;
657
+ if (!currentSettings || typeof currentSettings !== "object") {
658
+ return void 0;
659
+ }
660
+ currentEntry = currentSettings[segment];
661
+ if (currentEntry === void 0) {
662
+ return void 0;
663
+ }
664
+ currentSettings = currentEntry == null ? void 0 : currentEntry.subFieldSettings;
665
+ }
666
+ return currentEntry;
667
+ };
668
+ function applyMapping(props, fieldSettings, map, resolveInput = "fieldSettings", options) {
669
+ var _a, _b, _c;
670
+ const newProps = __spreadValues({}, props);
671
+ const sourceProps = (_a = options == null ? void 0 : options.sourceProps) != null ? _a : props;
672
+ const mappedArrayPaths = /* @__PURE__ */ new Set();
673
+ let changed = false;
674
+ const changedArrayBases = /* @__PURE__ */ new Set();
675
+ for (const entry of map) {
676
+ const { from, to, transform } = entry;
677
+ if (!from || !to) continue;
678
+ const fromPaths = Array.isArray(from) ? from : [from];
679
+ const toPaths = Array.isArray(to) ? to : [to];
680
+ const hasInvalidPair = fromPaths.some((fp, idx) => {
681
+ const tp = toPaths[idx] || toPaths[0];
682
+ if (typeof fp !== "string" || typeof tp !== "string") return false;
683
+ return isArrayMappingPath(fp) && !isArrayMappingPath(tp);
684
+ });
685
+ if (hasInvalidPair) continue;
686
+ const inputValues = fromPaths.map((f) => {
687
+ if (resolveInput === "propsFirst") {
688
+ const propVal = resolveValueByPath(sourceProps, f);
689
+ if (propVal !== void 0) return propVal;
690
+ const setting = resolveValueByPath(fieldSettings, f);
691
+ if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
692
+ return setting.defaultValue;
330
693
  }
331
- ]
332
- },
333
- _fields: {
334
- type: "array",
335
- label: "Fields",
336
- defaultItemProps: {
337
- name: "New Field",
338
- type: "text"
339
- },
340
- getItemSummary(item, index) {
341
- return item.name || `Field ${(index || 0) + 1}`;
342
- },
343
- arrayFields: {
344
- name: { type: "text", label: "Name" },
345
- type: {
346
- type: "select",
347
- label: "Type",
348
- options: [
349
- { label: "Text", value: "text" },
350
- { label: "Textarea", value: "textarea" },
351
- { label: "Number", value: "number" },
352
- { label: "Select", value: "select" },
353
- { label: "Radio", value: "radio" },
354
- { label: "Array", value: "array" },
355
- { label: "Object", value: "object" }
356
- // { label: "Reference", value: "reference" },
357
- ]
694
+ return propVal;
695
+ }
696
+ const directValue = resolveValueByPath(fieldSettings, f);
697
+ if (directValue !== void 0) {
698
+ return directValue;
699
+ }
700
+ return resolveFieldSettingEntryByPath(fieldSettings, f);
701
+ });
702
+ const resolvedInputs = inputValues.map(
703
+ (v) => resolveInput === "fieldSettings" ? v == null ? void 0 : v.defaultValue : v
704
+ );
705
+ let result = transform ? transform(resolvedInputs, newProps) : inputValues[0];
706
+ if (resolveInput === "fieldSettings" && !transform && result !== void 0 && typeof result === "object" && result !== null && "defaultValue" in result) {
707
+ result = result.defaultValue;
708
+ }
709
+ const isSingleArrayTarget = toPaths.length === 1 && typeof toPaths[0] === "string" && isArrayMappingPath(toPaths[0]);
710
+ if (isSingleArrayTarget) {
711
+ const toPath = toPaths[0];
712
+ const arrayBase = getArrayBasePath(toPath);
713
+ const subProp = getArrayItemSubPath(toPath) || "";
714
+ if (!arrayBase) continue;
715
+ const defaultArray = Array.isArray((_b = options == null ? void 0 : options.arrayDefaults) == null ? void 0 : _b[arrayBase]) ? (_c = options == null ? void 0 : options.arrayDefaults) == null ? void 0 : _c[arrayBase] : [];
716
+ const currentArrayAtPath = resolveValueByPath(newProps, arrayBase);
717
+ const currentArray = Array.isArray(currentArrayAtPath) ? currentArrayAtPath : [];
718
+ const isFromArrayPath = typeof fromPaths[0] === "string" && isArrayMappingPath(fromPaths[0]);
719
+ const sourceArray = isFromArrayPath ? Array.isArray(result) ? result : result !== void 0 ? [result] : [] : Array.isArray(result) ? result : defaultArray.map(() => result);
720
+ let defaults = entry.unmappedArrayItemDefaultValues || entry.defaultOverrides || {};
721
+ if (typeof defaults === "string") {
722
+ try {
723
+ defaults = JSON.parse(defaults);
724
+ } catch (e) {
725
+ defaults = {};
726
+ }
727
+ }
728
+ const targetLength = sourceArray.length;
729
+ const constructed = Array.from({ length: targetLength }).map((_, idx) => {
730
+ const mappedValue = sourceArray[idx];
731
+ const defaultItem = defaultArray[idx] && typeof defaultArray[idx] === "object" ? defaultArray[idx] : {};
732
+ const currentItem = currentArray[idx] && typeof currentArray[idx] === "object" ? currentArray[idx] : {};
733
+ const item = __spreadValues(__spreadValues(__spreadValues({}, defaultItem), defaults), currentItem);
734
+ if (subProp && mappedValue !== void 0) {
735
+ setPropertyByPath(item, subProp, mappedValue);
736
+ }
737
+ return item;
738
+ });
739
+ const originalArray = resolveValueByPath(newProps, arrayBase);
740
+ if (!equal(originalArray, constructed)) {
741
+ setPropertyByPath(newProps, arrayBase, constructed);
742
+ changedArrayBases.add(arrayBase);
743
+ }
744
+ mappedArrayPaths.add(arrayBase);
745
+ } else if (toPaths.length === 1 && Array.isArray(result) && toPaths[0].includes("array")) {
746
+ const toPath = toPaths[0];
747
+ const original = resolveValueByPath(newProps, toPath);
748
+ if (!equal(original, result)) {
749
+ setPropertyByPath(newProps, toPath, result);
750
+ changed = true;
751
+ }
752
+ } else if (Array.isArray(result) && toPaths.length > 1) {
753
+ result.forEach((val, idx) => {
754
+ if (toPaths[idx]) {
755
+ const orig = resolveValueByPath(newProps, toPaths[idx]);
756
+ if (!equal(orig, val)) {
757
+ setPropertyByPath(newProps, toPaths[idx], val);
758
+ changed = true;
759
+ }
358
760
  }
761
+ });
762
+ } else if (toPaths[0]) {
763
+ const finalValue = result;
764
+ const originalValue = resolveValueByPath(newProps, toPaths[0]);
765
+ if (!equal(originalValue, finalValue)) {
766
+ setPropertyByPath(newProps, toPaths[0], finalValue);
767
+ changed = true;
359
768
  }
360
769
  }
361
- },
362
- resolveFields({ props: data }, { fields, changed }) {
363
- var _a, _b;
364
- if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
365
- if ((_a = data == null ? void 0 : data._fields) == null ? void 0 : _a.length)
366
- fields._fieldSettings = {
367
- type: "object",
368
- label: "Field Settings",
369
- objectFields: get_field_settings_default(
370
- data._fields || [],
371
- data._fieldSettings || {}
372
- )
373
- };
374
- else delete fields._fieldSettings;
375
- if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length)) {
376
- const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
377
- delete fields._version;
378
- fields._version = {
770
+ }
771
+ const hasNetArrayChanges = Array.from(changedArrayBases).some(
772
+ (arrayBase) => !equal(resolveValueByPath(props, arrayBase), resolveValueByPath(newProps, arrayBase))
773
+ );
774
+ return { newProps, mappedArrayPaths, changed: changed || hasNetArrayChanges };
775
+ }
776
+
777
+ // src/puck/lib/builder/root-config.tsx
778
+ import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
779
+ var useCustomPuck = createUsePuck();
780
+ var getSerializableProps = (props) => {
781
+ const cleanProps = {
782
+ id: props.id
783
+ };
784
+ for (const key in props) {
785
+ const value = props[key];
786
+ if (["children", "puck", "editMode"].includes(key)) continue;
787
+ if (value && typeof value === "object" && value.$$typeof) continue;
788
+ if (typeof value === "function") continue;
789
+ cleanProps[key] = value;
790
+ }
791
+ return cleanProps;
792
+ };
793
+ var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true, customFields) => {
794
+ const customTypeOptions = getCustomFieldTypeOptions(customFields);
795
+ return {
796
+ fields: __spreadValues({
797
+ _name: overrides.name || {
798
+ type: "text",
799
+ label: "Soft Component Name"
800
+ },
801
+ _category: overrides.categories || {
379
802
  type: "select",
380
- label: "Version",
803
+ label: "Category",
381
804
  options: [
382
- ...data._versions.map((v) => ({ label: v, value: v })),
383
- {
384
- label: `${updateVersion(latestVersion, "patch")} (Patch)`,
385
- value: updateVersion(latestVersion, "patch")
386
- },
387
- {
388
- label: `${updateVersion(latestVersion, "minor")} (Minor)`,
389
- value: updateVersion(latestVersion, "minor")
390
- },
805
+ ...Object.keys(config.categories || {}).map((cat) => {
806
+ var _a;
807
+ return {
808
+ label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
809
+ value: cat
810
+ };
811
+ }) || [],
391
812
  {
392
- label: `${updateVersion(latestVersion, "major")} (Major)`,
393
- value: updateVersion(latestVersion, "major")
813
+ label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
814
+ value: void 0
394
815
  }
395
816
  ]
396
- };
397
- } else {
398
- delete fields._version;
399
- }
400
- return fields;
401
- },
402
- resolveData: (props, params) => {
403
- if (overrides.onRootsDataChange)
404
- overrides.onRootsDataChange(props, params);
405
- return {
406
- props,
407
- readOnly: Boolean(editingComponent) ? {
408
- _name: true
409
- } : void 0
410
- };
411
- },
412
- render: (props) => {
413
- const fieldSettings = props == null ? void 0 : props._fieldSettings;
414
- const data = useCustomPuck((s) => s.appState.data);
415
- const dispatch = useCustomPuck((s) => s.dispatch);
416
- const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
417
- const setVersion = useSoftConfig((s) => s.builder.setVersion);
418
- const state = useSoftConfig((s) => s.state);
419
- const [debouncedFieldSettings] = useDebounce(fieldSettings, 500);
420
- useEffect(() => {
421
- if (!debouncedFieldSettings || Object.keys(debouncedFieldSettings).length === 0) return;
422
- walkTree(
423
- data,
424
- {
425
- components: config.components
817
+ },
818
+ _fields: {
819
+ type: "array",
820
+ label: "Fields",
821
+ defaultItemProps: {
822
+ name: "New Field",
823
+ type: "text"
426
824
  },
427
- (content) => content.map((child) => {
428
- var _a;
429
- const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
430
- if (map.length) {
431
- map.forEach(({ from, to, transform }) => {
432
- if (!from || !to) return;
433
- const fromPaths = Array.isArray(from) ? from : [from];
434
- const toPaths = Array.isArray(to) ? to : [to];
435
- const inputValues = fromPaths.map(
436
- (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
437
- );
438
- let value = transform ? transform(
439
- inputValues.map((v) => v == null ? void 0 : v.defaultValue),
440
- child.props
441
- ) : inputValues[0];
442
- if (Array.isArray(value)) {
443
- value.forEach((val, i) => {
444
- if (toPaths[i]) {
445
- const originalValue = getFieldSettingsByPath(
446
- child.props,
447
- toPaths[i]
448
- );
449
- if (originalValue !== val) {
450
- const itemSelector = getSelectorForId(child.props.id);
451
- if (!itemSelector) return;
452
- setPropertyByPath(child.props, toPaths[i], val);
453
- dispatch({
454
- type: "replace",
455
- data: child,
456
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
457
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
458
- });
459
- }
460
- }
461
- });
462
- } else if (toPaths[0]) {
463
- const setting = getFieldSettingsByPath(
464
- debouncedFieldSettings,
465
- fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
466
- );
467
- const defaultValue = setting == null ? void 0 : setting.defaultValue;
468
- const originalValue = getFieldSettingsByPath(
469
- child.props,
470
- toPaths[0]
471
- );
472
- const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
473
- if (originalValue !== finalValue) {
474
- const itemSelector = getSelectorForId(child.props.id);
475
- if (!itemSelector) return;
476
- setPropertyByPath(child.props, toPaths[0], finalValue);
477
- dispatch({
478
- type: "replace",
479
- data: child,
480
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
481
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
482
- });
483
- }
484
- }
485
- });
825
+ getItemSummary(item, index) {
826
+ return item.name || `Field ${(index || 0) + 1}`;
827
+ },
828
+ arrayFields: {
829
+ name: { type: "text", label: "Name" },
830
+ type: {
831
+ type: "select",
832
+ label: "Type",
833
+ options: [
834
+ { label: "Text", value: "text" },
835
+ { label: "Textarea", value: "textarea" },
836
+ { label: "Number", value: "number" },
837
+ { label: "Select", value: "select" },
838
+ { label: "Radio", value: "radio" },
839
+ { label: "Array", value: "array" },
840
+ { label: "Object", value: "object" },
841
+ // { label: "Reference", value: "reference" },
842
+ ...customTypeOptions
843
+ ]
486
844
  }
487
- return child;
488
- })
489
- );
490
- }, [debouncedFieldSettings, data, dispatch, getSelectorForId, props._fieldSettings]);
491
- useEffect(() => {
492
- var _a;
493
- if (state !== "remodeling") return;
494
- if (!(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
495
- const currentVersion = props == null ? void 0 : props._version;
496
- if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
497
- setVersion(props._name, currentVersion, props, dispatch);
845
+ }
498
846
  }
499
- }, [props == null ? void 0 : props._version]);
500
- return /* @__PURE__ */ jsx2(Fragment, { children: props.children });
501
- }
502
- });
847
+ }, overrides.additionalRootFields || {}),
848
+ resolveFields({ props: data }, { fields, changed }) {
849
+ const newFields = __spreadValues({}, fields);
850
+ const rootFields = Array.isArray(
851
+ data == null ? void 0 : data._fields
852
+ ) ? (data == null ? void 0 : data._fields) || [] : [];
853
+ const rootFieldSettings = (data == null ? void 0 : data._fieldSettings) || {};
854
+ if (changed._fields || changed._fieldSettings) {
855
+ if (rootFields.length) {
856
+ newFields._fieldSettings = {
857
+ type: "object",
858
+ label: "Field Settings",
859
+ objectFields: get_field_settings_default(
860
+ rootFields,
861
+ rootFieldSettings,
862
+ customFields
863
+ )
864
+ };
865
+ } else {
866
+ delete newFields._fieldSettings;
867
+ }
868
+ }
869
+ return newFields;
870
+ },
871
+ // resolveData: (props, params) => {
872
+ // if (overrides.resolveRootData) {
873
+ // return overrides.resolveRootData(props, params, { editingComponent });
874
+ // }
875
+ // const result: {
876
+ // props: RootData<AsFieldProps<WithChildren<BuilderRootConfig>>>;
877
+ // readOnly: Readonly<Record<string, boolean>> | undefined;
878
+ // } = {
879
+ // props,
880
+ // readOnly: undefined,
881
+ // };
882
+ // return result;
883
+ // },
884
+ render: (props) => {
885
+ const fieldSettings = props == null ? void 0 : props._fieldSettings;
886
+ const data = useCustomPuck((s) => s.appState.data);
887
+ const dispatch = useCustomPuck((s) => s.dispatch);
888
+ const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
889
+ const setVersion = useSoftConfig((s) => s.builder.setVersion);
890
+ const state = useSoftConfig((s) => s.state);
891
+ useEffect(() => {
892
+ if (!fieldSettings || Object.keys(fieldSettings).length === 0) return;
893
+ const replacements = [];
894
+ walkTree(
895
+ {
896
+ content: (data == null ? void 0 : data.content) || [],
897
+ root: (data == null ? void 0 : data.root) || {}
898
+ },
899
+ {
900
+ components: config.components
901
+ },
902
+ (content) => content.map((child) => {
903
+ var _a;
904
+ const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
905
+ if (!map.length) return child;
906
+ const cleanProps = getSerializableProps(child.props);
907
+ const { newProps, changed } = applyMapping(
908
+ cleanProps,
909
+ fieldSettings,
910
+ map,
911
+ "fieldSettings"
912
+ );
913
+ if (!changed || equal2(cleanProps, newProps)) return child;
914
+ replacements.push({
915
+ id: child.props.id,
916
+ data: __spreadProps(__spreadValues({}, child), { props: newProps })
917
+ });
918
+ return child;
919
+ })
920
+ );
921
+ if (!replacements.length) return;
922
+ replacements.forEach((replacement) => {
923
+ const itemSelector = getSelectorForId(replacement.id);
924
+ if (!itemSelector) return;
925
+ dispatch({
926
+ type: "replace",
927
+ data: replacement.data,
928
+ destinationIndex: itemSelector.index,
929
+ destinationZone: itemSelector.zone
930
+ });
931
+ });
932
+ }, [fieldSettings, data, dispatch, getSelectorForId]);
933
+ useEffect(() => {
934
+ var _a;
935
+ if (state !== "remodeling" || !(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
936
+ const currentVersion = props._version;
937
+ if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
938
+ setVersion(props._name, currentVersion, props, dispatch);
939
+ }
940
+ }, [props == null ? void 0 : props._version]);
941
+ return /* @__PURE__ */ jsx2(Fragment, { children: props.children });
942
+ }
943
+ };
944
+ };
503
945
 
504
946
  // src/puck/lib/builder/generate-field-options.ts
505
- function generateFieldOptions(fields, selectedFields, prefix = "") {
947
+ var hasArrayMappingPath = (value) => value.includes("[]");
948
+ var isBareArrayPath = (value) => !hasArrayMappingPath(value) && !value.includes(".");
949
+ function filterToOptionsForFrom(fromPath, toOptions) {
950
+ if (!fromPath) return toOptions;
951
+ const fromHasArrayMapping = hasArrayMappingPath(fromPath);
952
+ const fromIsBareArray = isBareArrayPath(fromPath);
953
+ return toOptions.filter((option) => {
954
+ const optionHasArrayMapping = hasArrayMappingPath(option.value);
955
+ if (fromHasArrayMapping) {
956
+ return optionHasArrayMapping;
957
+ }
958
+ if (fromIsBareArray) {
959
+ return isBareArrayPath(option.value);
960
+ }
961
+ return !optionHasArrayMapping;
962
+ });
963
+ }
964
+ function generateFieldOptions(fields, prefix = "") {
506
965
  const opts = [];
507
966
  function recurse(current, prefix2) {
508
967
  Object.entries(current).forEach(([key, fld]) => {
@@ -510,36 +969,68 @@ function generateFieldOptions(fields, selectedFields, prefix = "") {
510
969
  if (key === "_map") return;
511
970
  if (key === "_slotEnabled") return;
512
971
  const path = prefix2 ? `${prefix2}.${key}` : key;
513
- if (selectedFields.includes(path)) {
514
- return;
515
- }
516
- opts.push({ label: path, value: path, type: fld.type });
517
972
  if (fld.type === "object" && fld.objectFields) {
518
973
  recurse(fld.objectFields, path);
519
- }
520
- if (fld.type === "array" && fld.arrayFields) {
521
- recurse(fld.arrayFields, path);
974
+ } else if (fld.type === "array" && fld.arrayFields) {
975
+ recurse(
976
+ fld.arrayFields,
977
+ path + "[]"
978
+ );
979
+ } else {
980
+ opts.push({ label: path, value: path, type: fld.type });
522
981
  }
523
982
  });
524
983
  }
525
984
  recurse(fields, prefix);
526
985
  return opts;
527
986
  }
528
- function generateDynamicFieldOptions(_fields, _fieldSettings, prefix = "") {
987
+ function generateDynamicFieldOptions(_fields, _fieldSettings, customFields, prefix = "") {
529
988
  const opts = [];
530
- if (!_fields || !_fieldSettings) return opts;
989
+ if (!_fields) return opts;
531
990
  function recurse(fields, fieldSettings, currentPrefix) {
532
991
  fields.forEach((field) => {
533
992
  var _a;
534
993
  const settings = fieldSettings[field.name];
994
+ const customReturnType = resolveCustomFieldReturnType(
995
+ field.type,
996
+ customFields
997
+ );
535
998
  const path = currentPrefix ? `${currentPrefix}.${field.name}` : field.name;
536
- opts.push({ label: path, value: path, type: field.type });
999
+ if (customReturnType) {
1000
+ if (customReturnType === "array" || customReturnType === "object") {
1001
+ const customSchema = resolveCustomFieldSchema(field.type, customFields);
1002
+ if (!customSchema) {
1003
+ return;
1004
+ }
1005
+ recurse(
1006
+ customSchema.subFields,
1007
+ customSchema.subFieldSettings,
1008
+ path + (customReturnType === "array" ? "[]" : "")
1009
+ );
1010
+ return;
1011
+ }
1012
+ opts.push({
1013
+ label: path,
1014
+ value: path,
1015
+ type: mapCustomReturnTypeToMappingType(customReturnType)
1016
+ });
1017
+ return;
1018
+ }
1019
+ if (!isBuiltInSoftFieldType(field.type)) {
1020
+ return;
1021
+ }
537
1022
  if ((_a = settings == null ? void 0 : settings.subFields) == null ? void 0 : _a.length) {
538
- recurse(settings.subFields, settings.subFieldSettings || {}, path);
1023
+ recurse(
1024
+ settings.subFields,
1025
+ settings.subFieldSettings || {},
1026
+ path + (field.type === "array" ? "[]" : "")
1027
+ );
1028
+ } else if (field.type !== "array" && field.type !== "object") {
1029
+ opts.push({ label: path, value: path, type: field.type });
539
1030
  }
540
1031
  });
541
1032
  }
542
- recurse(_fields, _fieldSettings, prefix);
1033
+ recurse(_fields, _fieldSettings || {}, prefix);
543
1034
  return opts;
544
1035
  }
545
1036
 
@@ -631,8 +1122,14 @@ var ErrorBoundary = class extends Component {
631
1122
 
632
1123
  // src/puck/lib/builder/builder-config.tsx
633
1124
  import { jsx as jsx4 } from "react/jsx-runtime";
634
- var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents) => ({
635
- root: builderRootConfig(config, overrides, editingComponent, showVersionFields),
1125
+ var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents, customFields) => ({
1126
+ root: builderRootConfig(
1127
+ config,
1128
+ overrides,
1129
+ editingComponent,
1130
+ showVersionFields,
1131
+ customFields
1132
+ ),
636
1133
  components: Object.entries(__spreadValues({}, config.components)).reduce(
637
1134
  (acc, [name, component]) => {
638
1135
  const tempComponent = __spreadProps(__spreadValues({}, component), {
@@ -641,6 +1138,7 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
641
1138
  },
642
1139
  resolveFields(data, params) {
643
1140
  return __async(this, null, function* () {
1141
+ var _a2;
644
1142
  let fields = {};
645
1143
  if (!fields._slot) {
646
1144
  const slotFields = Object.entries(params.fields).filter(
@@ -661,8 +1159,8 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
661
1159
  { label: "Select a slot", value: "" },
662
1160
  ...slotFields.filter(
663
1161
  ([fieldName, field]) => {
664
- var _a2;
665
- return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
1162
+ var _a3;
1163
+ return field.type === "slot" && !(((_a3 = data.props) == null ? void 0 : _a3._slot) || []).some(
666
1164
  (s) => s.slot === fieldName
667
1165
  );
668
1166
  }
@@ -681,17 +1179,21 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
681
1179
  };
682
1180
  }
683
1181
  const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
684
- if (!fields._map) {
1182
+ if (!fields._map || params.changed._map) {
685
1183
  const rootProps = getRootProps(params.appState);
686
1184
  const fromOptions = generateDynamicFieldOptions(
687
1185
  (rootProps == null ? void 0 : rootProps._fields) || [],
688
- (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
1186
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {},
1187
+ customFields
689
1188
  );
690
- const toOptions = generateFieldOptions(defaultFields, []);
1189
+ const toOptionsFields = component.resolveFields && ((_a2 = data.props) == null ? void 0 : _a2._map) ? yield component.resolveFields(
1190
+ __spreadProps(__spreadValues({}, data), { props: __spreadProps(__spreadValues({}, data.props), { _map: void 0 }) }),
1191
+ params
1192
+ ) : defaultFields;
1193
+ const toOptions = generateFieldOptions(toOptionsFields);
691
1194
  fields._map = overrides.map ? {
692
1195
  type: "custom",
693
1196
  render: ({ value, onChange, id }) => {
694
- const toOptions2 = generateFieldOptions(defaultFields, []);
695
1197
  const rootProps2 = getRootProps(params.appState);
696
1198
  return overrides.map({
697
1199
  rootProps: rootProps2,
@@ -700,13 +1202,39 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
700
1202
  id,
701
1203
  props: data.props || {},
702
1204
  fromOptions,
703
- toOptions: toOptions2
1205
+ toOptions
704
1206
  });
705
1207
  }
706
- } : {
707
- type: "array",
708
- label: "Dynamic Field Map",
709
- arrayFields: {
1208
+ } : (() => {
1209
+ var _a3;
1210
+ const mapEntries = ((_a3 = data.props) == null ? void 0 : _a3._map) || [];
1211
+ const toPaths = mapEntries.flatMap(
1212
+ (entry) => Array.isArray(entry.to) ? entry.to : entry.to ? [entry.to] : []
1213
+ );
1214
+ const toPath = toPaths.find(
1215
+ (path) => typeof path === "string" && isArrayMappingPath(path)
1216
+ );
1217
+ const arrayBaseName = toPath ? getArrayBasePath(toPath) : null;
1218
+ const targetArrayField = arrayBaseName ? defaultFields[arrayBaseName] : null;
1219
+ const mappedSubProps = /* @__PURE__ */ new Set();
1220
+ if (arrayBaseName) {
1221
+ toPaths.forEach((path) => {
1222
+ if (typeof path !== "string") return;
1223
+ if (getArrayBasePath(path) !== arrayBaseName) return;
1224
+ const subProp = getArrayItemSubPath(path);
1225
+ if (subProp) mappedSubProps.add(subProp);
1226
+ });
1227
+ }
1228
+ const defaultValueFields = {};
1229
+ if (targetArrayField && targetArrayField.type === "array" && targetArrayField.arrayFields) {
1230
+ const arrayFields = targetArrayField.arrayFields;
1231
+ Object.entries(arrayFields).forEach(([key, fld]) => {
1232
+ if (mappedSubProps.has(key)) return;
1233
+ if (fld.type === "array" || fld.type === "object" || fld.type === "slot") return;
1234
+ defaultValueFields[key] = __spreadProps(__spreadValues({}, fld), { label: fld.label || key });
1235
+ });
1236
+ }
1237
+ const baseArrayFields = {
710
1238
  from: {
711
1239
  type: "select",
712
1240
  label: "From",
@@ -729,47 +1257,57 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
729
1257
  }))
730
1258
  ]
731
1259
  }
1260
+ };
1261
+ if (arrayBaseName && Object.keys(defaultValueFields).length > 0) {
1262
+ baseArrayFields.unmappedArrayItemDefaultValues = {
1263
+ type: "object",
1264
+ label: "Default Item Values",
1265
+ objectFields: defaultValueFields
1266
+ };
732
1267
  }
733
- };
1268
+ return {
1269
+ type: "array",
1270
+ label: "Dynamic Field Map",
1271
+ arrayFields: baseArrayFields
1272
+ };
1273
+ })();
734
1274
  }
735
1275
  fields = __spreadValues(__spreadValues({}, fields), defaultFields);
736
1276
  return fields;
737
1277
  });
738
1278
  },
739
1279
  resolveData: ({ props }, { lastData }) => {
740
- var _a2;
741
- const _map = props._map || [];
1280
+ const _map = (props._map || []).map((item) => {
1281
+ const newItem = __spreadValues({}, item);
1282
+ if (typeof newItem.unmappedArrayItemDefaultValues === "string") {
1283
+ try {
1284
+ newItem.unmappedArrayItemDefaultValues = JSON.parse(
1285
+ newItem.unmappedArrayItemDefaultValues
1286
+ );
1287
+ } catch (e) {
1288
+ newItem.unmappedArrayItemDefaultValues = {};
1289
+ }
1290
+ } else if (!newItem.unmappedArrayItemDefaultValues) {
1291
+ newItem.unmappedArrayItemDefaultValues = {};
1292
+ }
1293
+ return newItem;
1294
+ });
742
1295
  const readOnlyFields = _map.flatMap((item) => item.to);
1296
+ const readOnlyArrayBases = readOnlyFields.filter((field) => typeof field === "string").map(getArrayBasePath).filter((base) => base !== null);
743
1297
  if (_map.length) {
744
1298
  return {
745
- props,
746
- readOnly: readOnlyFields.reduce(
1299
+ props: __spreadProps(__spreadValues({}, props), { _map }),
1300
+ readOnly: [
1301
+ ...readOnlyFields.map((f) => String(f)),
1302
+ ...readOnlyArrayBases
1303
+ ].reduce(
747
1304
  (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
748
1305
  {}
749
1306
  )
750
1307
  };
751
1308
  }
752
- const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
753
- if (prevMap && prevMap.length === 1) {
754
- const lastField = prevMap[0].to;
755
- if (typeof lastField === "string") {
756
- return {
757
- props,
758
- readOnly: { [lastField]: false }
759
- };
760
- }
761
- if (Array.isArray(lastField)) {
762
- return {
763
- props,
764
- readOnly: lastField.reduce(
765
- (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
766
- {}
767
- )
768
- };
769
- }
770
- }
771
1309
  return {
772
- props,
1310
+ props: __spreadProps(__spreadValues({}, props), { _map }),
773
1311
  readOnly: {}
774
1312
  };
775
1313
  },
@@ -785,6 +1323,9 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
785
1323
  categories: config.categories || {}
786
1324
  });
787
1325
 
1326
+ // src/puck/lib/soft-component-constants.ts
1327
+ var TECHNICAL_KEYS = /* @__PURE__ */ new Set(["_map", "_slot", "id", "_version"]);
1328
+
788
1329
  // src/puck/lib/strip-id.ts
789
1330
  var stripIdFromProps = (components, allowedTypes) => {
790
1331
  return components.map((component) => sanitizeComponent(component, allowedTypes));
@@ -808,7 +1349,7 @@ var sanitizeComponent = (component, allowedTypes) => {
808
1349
  var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
809
1350
  if (!content || !Array.isArray(content)) return [];
810
1351
  return content.map((componentProps) => {
811
- var _a, _b, _c;
1352
+ var _a, _b, _c, _d;
812
1353
  const componentConfig = componentConfigs[componentProps.type];
813
1354
  const enabledSlotNames = new Set(
814
1355
  (((_a = componentProps.props) == null ? void 0 : _a._slot) || []).map((s) => s.slot)
@@ -829,7 +1370,27 @@ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
829
1370
  },
830
1371
  {}
831
1372
  ) || {};
832
- const fixedProps = __spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props);
1373
+ const map = ((_b = componentProps.props) == null ? void 0 : _b._map) || [];
1374
+ const mappedPaths = /* @__PURE__ */ new Set();
1375
+ map.forEach((item) => {
1376
+ const to = Array.isArray(item.to) ? item.to : [item.to];
1377
+ to.forEach((path) => {
1378
+ if (path) {
1379
+ if (isArrayMappingPath(path)) {
1380
+ const basePath = getArrayBasePath(path);
1381
+ if (basePath) mappedPaths.add(basePath);
1382
+ } else {
1383
+ mappedPaths.add(path);
1384
+ }
1385
+ }
1386
+ });
1387
+ });
1388
+ const fixedProps = Object.entries(__spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props)).reduce((acc, [key, value]) => {
1389
+ if (!TECHNICAL_KEYS.has(key) && !mappedPaths.has(key)) {
1390
+ acc[key] = value;
1391
+ }
1392
+ return acc;
1393
+ }, {});
833
1394
  (componentProps.props._slot || []).forEach(
834
1395
  (s) => {
835
1396
  var _a2;
@@ -843,19 +1404,34 @@ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
843
1404
  }
844
1405
  );
845
1406
  const subComponent = {
846
- map: ((_b = componentProps.props) == null ? void 0 : _b._map) || [],
1407
+ map: ((_c = componentProps.props) == null ? void 0 : _c._map) || [],
847
1408
  fixedProps,
848
1409
  type: componentProps.type,
849
1410
  components,
850
- enabledSlots: ((_c = componentProps.props) == null ? void 0 : _c._slot) || []
1411
+ enabledSlots: ((_d = componentProps.props) == null ? void 0 : _d._slot) || []
851
1412
  };
852
1413
  return subComponent;
853
1414
  });
854
1415
  };
855
- var softFieldsToPuckFields = (fields, fieldSettings) => {
1416
+ var softFieldsToPuckFields = (fields, fieldSettings, customFields) => {
856
1417
  return (fields == null ? void 0 : fields.reduce(
857
1418
  (acc, field) => {
858
- var _a, _b, _c, _d, _e, _f, _g, _h;
1419
+ var _a, _b, _c, _d, _e, _f;
1420
+ const customFieldDefinition = resolveCustomFieldDefinition(
1421
+ field.type,
1422
+ customFields
1423
+ );
1424
+ const customReturnType = resolveCustomFieldReturnType(
1425
+ field.type,
1426
+ customFields
1427
+ );
1428
+ if (customFieldDefinition && customReturnType) {
1429
+ acc[field.name] = __spreadProps(__spreadValues({}, customFieldDefinition.field), {
1430
+ type: "custom",
1431
+ label: customFieldDefinition.field.label || field.name
1432
+ });
1433
+ return acc;
1434
+ }
859
1435
  switch (field.type) {
860
1436
  case "text":
861
1437
  case "textarea":
@@ -880,13 +1456,24 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
880
1456
  break;
881
1457
  // TODO: Default item props
882
1458
  case "array":
1459
+ const currentArraySettings = (fieldSettings == null ? void 0 : fieldSettings[field.name]) || {};
883
1460
  acc[field.name] = {
884
1461
  type: field.type,
885
1462
  label: field.name,
1463
+ min: currentArraySettings.min,
1464
+ max: currentArraySettings.max,
886
1465
  arrayFields: softFieldsToPuckFields(
887
- ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
888
- ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {}
889
- )
1466
+ currentArraySettings.subFields || [],
1467
+ currentArraySettings.subFieldSettings || {},
1468
+ customFields
1469
+ ),
1470
+ defaultItemProps: buildArrayDefaultItemProps(
1471
+ currentArraySettings.subFields,
1472
+ currentArraySettings.subFieldSettings
1473
+ ),
1474
+ getItemSummary(item, index) {
1475
+ return getArrayItemSummary(item, index, currentArraySettings);
1476
+ }
890
1477
  };
891
1478
  break;
892
1479
  // TODO: Needs testing to see if it works
@@ -895,8 +1482,9 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
895
1482
  type: field.type,
896
1483
  label: field.name,
897
1484
  objectFields: softFieldsToPuckFields(
898
- ((_g = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _g.subFields) || [],
899
- ((_h = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _h.subFieldSettings) || {}
1485
+ ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
1486
+ ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {},
1487
+ customFields
900
1488
  )
901
1489
  };
902
1490
  break;
@@ -908,21 +1496,69 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
908
1496
  {}
909
1497
  )) || {};
910
1498
  };
911
- var softComponentFromAppState = (appState, configComponents, editedItem, metadata) => {
1499
+ var softComponentFromAppState = (appState, configComponents, editedItem, metadata, customFields) => {
912
1500
  var _a;
913
1501
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
914
1502
  const fields = rootProps._fields || [];
915
1503
  const field_settings = rootProps._fieldSettings || {};
1504
+ const normalizedFieldSettings = __spreadValues({}, field_settings);
1505
+ (fields || []).forEach((field) => {
1506
+ const customFieldDefinition = resolveCustomFieldDefinition(
1507
+ field.type,
1508
+ customFields
1509
+ );
1510
+ const customReturnType = resolveCustomFieldReturnType(
1511
+ field.type,
1512
+ customFields
1513
+ );
1514
+ if (!customFieldDefinition || !customReturnType) {
1515
+ return;
1516
+ }
1517
+ const schema = resolveCustomFieldSchema(field.type, customFields);
1518
+ const existingSettings = normalizedFieldSettings[field.name] || {};
1519
+ normalizedFieldSettings[field.name] = __spreadValues(__spreadProps(__spreadValues({}, existingSettings), {
1520
+ customFieldType: field.type,
1521
+ customFieldReturnType: customReturnType
1522
+ }), schema ? {
1523
+ subFields: schema.subFields,
1524
+ subFieldSettings: schema.subFieldSettings
1525
+ } : {});
1526
+ });
1527
+ const builtInRootProps = /* @__PURE__ */ new Set([
1528
+ "_name",
1529
+ "_category",
1530
+ "_version",
1531
+ "_versions",
1532
+ "_fields",
1533
+ "_fieldSettings"
1534
+ ]);
1535
+ const customRootProps = Object.keys(rootProps).filter((key) => key.startsWith("_") && !builtInRootProps.has(key)).reduce(
1536
+ (acc, key) => {
1537
+ acc[key] = rootProps[key];
1538
+ return acc;
1539
+ },
1540
+ {}
1541
+ );
916
1542
  const slots = {};
917
1543
  const components = getSubComponents(
918
1544
  [editedItem],
919
1545
  configComponents,
920
- field_settings,
1546
+ normalizedFieldSettings,
921
1547
  slots
922
1548
  );
923
- const defaultProps = __spreadValues(__spreadValues({}, Object.keys(field_settings).reduce(
1549
+ const defaultProps = __spreadValues(__spreadValues({}, Object.keys(normalizedFieldSettings).reduce(
924
1550
  (acc, field) => {
925
- acc[field] = field_settings[field].defaultValue;
1551
+ var _a2;
1552
+ const fieldDefinition = (fields || []).find((item) => item.name === field);
1553
+ const customFieldReturnType = (_a2 = normalizedFieldSettings[field]) == null ? void 0 : _a2.customFieldReturnType;
1554
+ if ((fieldDefinition == null ? void 0 : fieldDefinition.type) === "array" || customFieldReturnType === "array") {
1555
+ acc[field] = normalizedFieldSettings[field].defaultValue !== void 0 ? normalizedFieldSettings[field].defaultValue : buildArrayDefaultValue(
1556
+ normalizedFieldSettings[field].subFields,
1557
+ normalizedFieldSettings[field].subFieldSettings
1558
+ );
1559
+ return acc;
1560
+ }
1561
+ acc[field] = normalizedFieldSettings[field].defaultValue;
926
1562
  return acc;
927
1563
  },
928
1564
  {}
@@ -931,12 +1567,13 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
931
1567
  {
932
1568
  name: metadata.name,
933
1569
  category: metadata.category,
934
- fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, field_settings)), Object.keys(slots).reduce((acc, slot) => {
1570
+ fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, normalizedFieldSettings, customFields)), Object.keys(slots).reduce((acc, slot) => {
935
1571
  acc[slot] = { type: "slot", label: slot };
936
1572
  return acc;
937
1573
  }, {})),
938
- fieldSettings: field_settings,
1574
+ fieldSettings: normalizedFieldSettings,
939
1575
  defaultProps,
1576
+ rootProps: customRootProps,
940
1577
  components,
941
1578
  slots
942
1579
  },
@@ -948,17 +1585,67 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
948
1585
  import { v4 as uuidv4 } from "uuid";
949
1586
  var generateId = (type) => type ? `${type}-${uuidv4()}` : uuidv4();
950
1587
 
1588
+ // src/puck/lib/component-key.ts
1589
+ var defaultToCamelCase = (value) => {
1590
+ const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1591
+ if (tokens.length === 0) return "";
1592
+ const [first, ...rest] = tokens;
1593
+ return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1594
+ };
1595
+ var createComponentKeyFromName = (displayName, overrides, context) => {
1596
+ const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1597
+ return key.trim();
1598
+ };
1599
+ var getComponentNameFromKey = (key, overrides) => {
1600
+ if (overrides == null ? void 0 : overrides.componentKeyToName) {
1601
+ return overrides.componentKeyToName(key);
1602
+ }
1603
+ return key;
1604
+ };
1605
+
951
1606
  // src/puck/lib/soft-component-to-appstate.ts
952
- var puckFieldsToSoftFields = (fields, slots) => {
1607
+ var mergeFieldSettings = (generated = {}, persisted = {}) => {
1608
+ return Object.entries(persisted).reduce((acc, [fieldName, value]) => {
1609
+ const current = acc[fieldName] || {};
1610
+ acc[fieldName] = __spreadProps(__spreadValues(__spreadValues({}, current), value), {
1611
+ subFieldSettings: current.subFieldSettings || (value == null ? void 0 : value.subFieldSettings) ? mergeFieldSettings(
1612
+ current.subFieldSettings || {},
1613
+ (value == null ? void 0 : value.subFieldSettings) || {}
1614
+ ) : void 0
1615
+ });
1616
+ return acc;
1617
+ }, __spreadValues({}, generated));
1618
+ };
1619
+ var puckFieldsToSoftFields = (fields, slots, persistedFieldSettings = {}, customFields) => {
953
1620
  const softFields = [];
954
1621
  const fieldSettings = {};
955
1622
  Object.entries(fields).forEach(([fieldName, field]) => {
1623
+ var _a;
1624
+ const persistedSettings = persistedFieldSettings == null ? void 0 : persistedFieldSettings[fieldName];
1625
+ const fieldWithMeta = field;
1626
+ const customFieldType = fieldWithMeta.customFieldType || (persistedSettings == null ? void 0 : persistedSettings.customFieldType);
1627
+ const customFieldReturnType = fieldWithMeta.customFieldReturnType || (persistedSettings == null ? void 0 : persistedSettings.customFieldReturnType) || (customFieldType ? (_a = customFields == null ? void 0 : customFields[customFieldType]) == null ? void 0 : _a.returnType : void 0);
956
1628
  if (slots.has(fieldName)) {
957
1629
  return;
958
1630
  }
959
1631
  if (fieldName === "_version") {
960
1632
  return;
961
1633
  }
1634
+ if (field.type === "custom" && customFieldType) {
1635
+ softFields.push({ name: fieldName, type: customFieldType });
1636
+ const customSchema = resolveCustomFieldSchema(customFieldType, customFields);
1637
+ fieldSettings[fieldName] = __spreadValues(__spreadProps(__spreadValues({}, persistedSettings || {}), {
1638
+ customFieldType,
1639
+ customFieldReturnType
1640
+ }), customSchema ? {
1641
+ subFields: customSchema.subFields,
1642
+ subFieldSettings: customSchema.subFieldSettings
1643
+ } : {});
1644
+ if (!Object.prototype.hasOwnProperty.call(fieldSettings[fieldName], "defaultValue")) {
1645
+ fieldSettings[fieldName].defaultValue = void 0;
1646
+ }
1647
+ return;
1648
+ }
962
1649
  switch (field.type) {
963
1650
  case "text":
964
1651
  case "textarea":
@@ -976,67 +1663,81 @@ var puckFieldsToSoftFields = (fields, slots) => {
976
1663
  case "radio":
977
1664
  softFields.push({ name: fieldName, type: field.type });
978
1665
  fieldSettings[fieldName] = {
979
- options: field.options || []
1666
+ options: field.options ? [...field.options] : []
980
1667
  };
981
1668
  break;
982
1669
  case "array":
983
1670
  softFields.push({ name: fieldName, type: "array" });
984
1671
  const arrayFieldsResult = puckFieldsToSoftFields(
985
1672
  field.arrayFields || {},
986
- /* @__PURE__ */ new Set()
1673
+ /* @__PURE__ */ new Set(),
1674
+ persistedSettings == null ? void 0 : persistedSettings.subFieldSettings,
1675
+ customFields
987
1676
  );
988
- fieldSettings[fieldName] = {
1677
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, persistedSettings || {}), {
989
1678
  subFields: arrayFieldsResult.fields,
990
1679
  subFieldSettings: arrayFieldsResult.fieldSettings
991
- };
1680
+ });
992
1681
  break;
993
1682
  case "object":
994
1683
  softFields.push({ name: fieldName, type: "object" });
995
1684
  const objectFieldsResult = puckFieldsToSoftFields(
996
1685
  field.objectFields || {},
997
- /* @__PURE__ */ new Set()
1686
+ /* @__PURE__ */ new Set(),
1687
+ persistedSettings == null ? void 0 : persistedSettings.subFieldSettings,
1688
+ customFields
998
1689
  );
999
- fieldSettings[fieldName] = {
1690
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, persistedSettings || {}), {
1000
1691
  subFields: objectFieldsResult.fields,
1001
1692
  subFieldSettings: objectFieldsResult.fieldSettings
1002
- };
1693
+ });
1003
1694
  break;
1004
1695
  default:
1005
1696
  softFields.push({ name: fieldName, type: "text" });
1006
1697
  }
1007
- if (fieldSettings[fieldName]) {
1008
- fieldSettings[fieldName].defaultValue = void 0;
1009
- } else {
1010
- fieldSettings[fieldName] = { defaultValue: void 0 };
1011
- }
1698
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, fieldSettings[fieldName] || persistedSettings || {}), {
1699
+ defaultValue: Object.prototype.hasOwnProperty.call(
1700
+ fieldSettings[fieldName] || persistedSettings || {},
1701
+ "defaultValue"
1702
+ ) ? (fieldSettings[fieldName] || persistedSettings || {}).defaultValue : void 0
1703
+ });
1012
1704
  });
1013
1705
  return { fields: softFields, fieldSettings };
1014
1706
  };
1015
1707
  var reconstructComponents = (subComponents, componentConfigs, softComponentProps) => {
1016
1708
  return subComponents.map((subComponent) => {
1017
- var _a;
1018
- const props = __spreadValues({}, subComponent.fixedProps);
1019
- (_a = subComponent.map) == null ? void 0 : _a.forEach((mapItem, i) => {
1020
- var _a2;
1021
- const { from, to, transform } = mapItem || {};
1022
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1023
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1024
- const inputs = fromPaths.map(
1025
- (path) => getFieldSettingsByPath(softComponentProps || {}, path)
1026
- );
1027
- const runner = transform;
1028
- const result = runner ? runner(inputs, softComponentProps) : inputs[0];
1029
- if (Array.isArray(result)) {
1030
- result.forEach((val, idx) => {
1031
- if (toPaths[idx]) setPropertyByPath(props, toPaths[idx], val);
1709
+ const componentConfig = componentConfigs[subComponent.type];
1710
+ const props = __spreadProps(__spreadValues({}, subComponent.fixedProps), {
1711
+ _map: subComponent.map
1712
+ });
1713
+ const arrayDefaults = (subComponent.map || []).reduce(
1714
+ (acc, mapEntry) => {
1715
+ const toPaths = Array.isArray(mapEntry.to) ? mapEntry.to : [mapEntry.to];
1716
+ toPaths.forEach((path) => {
1717
+ var _a;
1718
+ if (typeof path !== "string" || !isArrayMappingPath(path)) return;
1719
+ const arrayBase = getArrayBasePath(path);
1720
+ if (!arrayBase || acc[arrayBase]) return;
1721
+ const defaultValue = (_a = componentConfig == null ? void 0 : componentConfig.defaultProps) == null ? void 0 : _a[arrayBase];
1722
+ if (Array.isArray(defaultValue)) acc[arrayBase] = defaultValue;
1032
1723
  });
1033
- } else {
1034
- toPaths.forEach((toPath) => setPropertyByPath(props, toPath, result));
1035
- }
1036
- if (transform && ((_a2 = props._map) == null ? void 0 : _a2[i])) {
1037
- props._map[i].transform = transform;
1724
+ return acc;
1725
+ },
1726
+ {}
1727
+ );
1728
+ const sourceProps = __spreadValues(__spreadValues(__spreadValues({}, (componentConfig == null ? void 0 : componentConfig.defaultProps) || {}), softComponentProps), props);
1729
+ const { newProps } = applyMapping(
1730
+ props,
1731
+ {},
1732
+ // fieldSettings not needed for "propsFirst" mode as it resolves from propsFirst
1733
+ subComponent.map || [],
1734
+ "propsFirst",
1735
+ {
1736
+ sourceProps,
1737
+ arrayDefaults
1038
1738
  }
1039
- });
1739
+ );
1740
+ Object.assign(props, newProps);
1040
1741
  if (subComponent.enabledSlots.length > 0) {
1041
1742
  props._slot = subComponent.enabledSlots;
1042
1743
  subComponent.enabledSlots.forEach(({ slot, name }) => {
@@ -1066,25 +1767,45 @@ var reconstructComponents = (subComponents, componentConfigs, softComponentProps
1066
1767
  return componentData;
1067
1768
  });
1068
1769
  };
1069
- var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, displayName, category) => {
1770
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, overrides, displayName, category, customFields) => {
1070
1771
  const slots = new Set(Object.keys(softComponent.slots));
1071
1772
  const { fields, fieldSettings } = puckFieldsToSoftFields(
1072
1773
  softComponent.fields,
1073
- slots
1774
+ slots,
1775
+ softComponent.fieldSettings,
1776
+ customFields
1074
1777
  );
1778
+ const mergedFieldSettings = mergeFieldSettings(
1779
+ fieldSettings,
1780
+ softComponent.fieldSettings || {}
1781
+ ) || {};
1075
1782
  Object.entries(softComponent.defaultProps).forEach(([key, value]) => {
1076
- if (fieldSettings && fieldSettings[key] && !slots.has(key)) {
1077
- fieldSettings[key].defaultValue = value;
1783
+ if (mergedFieldSettings && mergedFieldSettings[key] && !slots.has(key)) {
1784
+ mergedFieldSettings[key].defaultValue = value;
1785
+ }
1786
+ });
1787
+ (fields || []).forEach((field) => {
1788
+ if (field.type !== "array" || slots.has(field.name)) return;
1789
+ const settings = mergedFieldSettings[field.name] || {};
1790
+ if (settings.defaultValue === void 0) {
1791
+ settings.defaultValue = buildArrayDefaultValue(
1792
+ settings.subFields,
1793
+ settings.subFieldSettings
1794
+ );
1078
1795
  }
1796
+ mergedFieldSettings[field.name] = settings;
1079
1797
  });
1080
- const rootProps = {
1081
- _name: displayName || componentName,
1798
+ let rootProps = __spreadValues({
1799
+ _name: displayName || getComponentNameFromKey(componentName, overrides),
1082
1800
  _category: category,
1083
1801
  _version: version,
1084
1802
  _versions: versions,
1085
1803
  _fields: fields,
1086
- _fieldSettings: fieldSettings
1087
- };
1804
+ _fieldSettings: mergedFieldSettings
1805
+ }, softComponent.rootProps || {});
1806
+ if (overrides.onRemodel) {
1807
+ rootProps = __spreadValues(__spreadValues({}, rootProps), overrides.onRemodel(componentName));
1808
+ }
1088
1809
  const content = reconstructComponents(
1089
1810
  softComponent.components,
1090
1811
  componentConfigs,
@@ -1106,114 +1827,102 @@ var rootZone = "default-zone";
1106
1827
  var rootDroppableId = `${rootAreaId}:${rootZone}`;
1107
1828
 
1108
1829
  // src/puck/components/soft-render/index.tsx
1109
- import { useMemo, useRef } from "react";
1110
- import { v4 as uuidv42 } from "uuid";
1111
- import equal from "fast-deep-equal";
1830
+ import React3, { useMemo, memo } from "react";
1831
+ import equal3 from "react-fast-compare";
1112
1832
  import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
1113
- function SoftRender({
1114
- softComponentFields,
1115
- softComponentFieldSettings,
1116
- softSubComponent,
1117
- configComponents,
1118
- props,
1119
- depth = 0
1120
- }) {
1121
- const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1122
- const mapCacheRef = useRef(/* @__PURE__ */ new Map());
1123
- const prevPropsRef = useRef(null);
1124
- if (!equal(prevPropsRef.current, props)) {
1125
- mapCacheRef.current.clear();
1126
- prevPropsRef.current = props;
1127
- }
1128
- const subComponentRootProps = useMemo(
1129
- () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
1130
- (acc, [fieldKey]) => {
1131
- acc[fieldKey] = props[fieldKey];
1132
- return acc;
1133
- },
1134
- {}
1135
- ),
1136
- [softComponentFields, props]
1833
+ function isPlainObject(val) {
1834
+ if (typeof val !== "object" || val === null) return false;
1835
+ if (React3.isValidElement(val)) return false;
1836
+ if ("$$typeof" in val) return false;
1837
+ const proto = Object.getPrototypeOf(val);
1838
+ return proto === Object.prototype || proto === null;
1839
+ }
1840
+ function cloneData(value) {
1841
+ if (value === null || value === void 0) return value;
1842
+ if (typeof value === "function") return value;
1843
+ if (Array.isArray(value)) return value.map(cloneData);
1844
+ if (!isPlainObject(value)) return value;
1845
+ return Object.fromEntries(
1846
+ Object.entries(value).map(([k, v]) => [k, cloneData(v)])
1137
1847
  );
1138
- return /* @__PURE__ */ jsx5(Fragment2, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1139
- var _a2;
1848
+ }
1849
+ var SubComponentRenderer = memo(
1850
+ ({
1851
+ subComponent,
1852
+ softComponentFields,
1853
+ softComponentFieldSettings,
1854
+ configComponents,
1855
+ props,
1856
+ depth,
1857
+ index
1858
+ }) => {
1859
+ const { id, puck, editMode } = props;
1140
1860
  const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
1141
- if (!componentConfig) return null;
1142
- const resolvedProps = subComponent.fixedProps || {};
1143
1861
  const stableId = useMemo(
1144
- () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-${uuidv42()}`,
1145
- [id, depth, subComponent.type]
1862
+ () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-i${index}`,
1863
+ [id, depth, subComponent.type, index]
1146
1864
  );
1147
- if ((_a2 = subComponent.map) == null ? void 0 : _a2.length) {
1148
- subComponent.map.forEach((mapItem) => {
1149
- const { from, to, transform } = mapItem || {};
1150
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1151
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1152
- const inputValues = fromPaths.map((f) => {
1153
- const propValue = getFieldSettingsByPath(props || {}, f);
1154
- if (propValue !== void 0) return propValue;
1155
- const setting = getFieldSettingsByPath(
1156
- softComponentFieldSettings || {},
1157
- f
1158
- );
1159
- if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1160
- return setting.defaultValue;
1865
+ const finalProps = useMemo(() => {
1866
+ var _a;
1867
+ if (!componentConfig) return {};
1868
+ const clonedProps = cloneData(subComponent.fixedProps || {});
1869
+ if ((_a = subComponent.map) == null ? void 0 : _a.length) {
1870
+ const mergedInput = __spreadValues(__spreadValues({}, clonedProps), props);
1871
+ const { newProps } = applyMapping(
1872
+ mergedInput,
1873
+ softComponentFieldSettings || {},
1874
+ subComponent.map,
1875
+ "propsFirst"
1876
+ );
1877
+ const parentKeys = new Set(Object.keys(props));
1878
+ for (const [key, value] of Object.entries(newProps)) {
1879
+ if (!parentKeys.has(key) || key in clonedProps) {
1880
+ clonedProps[key] = value;
1161
1881
  }
1162
- return propValue;
1163
- });
1164
- const cacheKey = inputValues.map((v, i) => `${i}:${typeof v === "object" ? JSON.stringify(v) : v}`).join("|");
1165
- let result = mapCacheRef.current.get(cacheKey);
1166
- if (!result) {
1167
- const runner = transform;
1168
- result = runner ? runner(inputValues, props) : inputValues[0];
1169
- mapCacheRef.current.set(cacheKey, result);
1170
1882
  }
1171
- if (Array.isArray(result)) {
1172
- result.forEach(
1173
- (val, i) => toPaths[i] && setPropertyByPath(resolvedProps, toPaths[i], val)
1174
- );
1175
- } else if (toPaths[0]) {
1176
- setPropertyByPath(resolvedProps, toPaths[0], result);
1177
- }
1178
- });
1179
- }
1180
- Object.entries(componentConfig.fields || {}).forEach(
1181
- ([slotKey, field]) => {
1182
- var _a3, _b;
1183
- if (field.type === "slot") {
1184
- const enabledSlot = (_a3 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a3.find(
1883
+ }
1884
+ Object.entries(componentConfig.fields || {}).forEach(
1885
+ ([slotKey, field]) => {
1886
+ var _a2, _b, _c;
1887
+ if (field.type !== "slot") return;
1888
+ const enabledSlot = (_a2 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a2.find(
1185
1889
  (s) => s.slot === slotKey
1186
1890
  );
1187
1891
  if (enabledSlot) {
1188
1892
  const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1189
- resolvedProps[slotKey] = useMemo(
1190
- () => rest[slotName] || (() => null),
1191
- [slotName, rest[slotName]]
1192
- );
1893
+ clonedProps[slotKey] = (_c = props[slotName]) != null ? _c : (() => null);
1193
1894
  } else {
1194
- resolvedProps[slotKey] = useMemo(() => {
1195
- return ({
1196
- className,
1197
- style
1198
- }) => {
1199
- var _a4, _b2;
1200
- return /* @__PURE__ */ jsx5("div", { className, style, children: /* @__PURE__ */ jsx5(
1201
- SoftRender,
1202
- {
1203
- softComponentFields,
1204
- softSubComponent: (_b2 = (_a4 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a4[slotKey]) != null ? _b2 : [],
1205
- configComponents,
1206
- props,
1207
- depth: depth + 1
1208
- },
1209
- slotKey
1210
- ) });
1211
- };
1212
- }, [slotKey, subComponentRootProps]);
1895
+ clonedProps[slotKey] = ({
1896
+ className,
1897
+ style
1898
+ }) => {
1899
+ var _a3, _b2;
1900
+ return /* @__PURE__ */ jsx5("div", { className, style, children: /* @__PURE__ */ jsx5(
1901
+ SoftRender,
1902
+ {
1903
+ softComponentFields,
1904
+ softComponentFieldSettings,
1905
+ softSubComponent: (_b2 = (_a3 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a3[slotKey]) != null ? _b2 : [],
1906
+ configComponents,
1907
+ props,
1908
+ depth: depth + 1
1909
+ }
1910
+ ) });
1911
+ };
1213
1912
  }
1214
1913
  }
1215
- }
1216
- );
1914
+ );
1915
+ return clonedProps;
1916
+ }, [
1917
+ componentConfig,
1918
+ subComponent,
1919
+ props,
1920
+ softComponentFields,
1921
+ softComponentFieldSettings,
1922
+ configComponents,
1923
+ depth
1924
+ ]);
1925
+ if (!componentConfig) return null;
1217
1926
  const ComponentRender = componentConfig.render;
1218
1927
  return /* @__PURE__ */ jsx5(ErrorBoundary, { children: /* @__PURE__ */ jsx5(
1219
1928
  ComponentRender,
@@ -1221,14 +1930,76 @@ function SoftRender({
1221
1930
  id: stableId,
1222
1931
  editMode,
1223
1932
  puck
1224
- }, resolvedProps)
1225
- ) }, index);
1226
- }) });
1227
- }
1933
+ }, finalProps)
1934
+ ) });
1935
+ },
1936
+ // Custom comparator for SubComponentRenderer.
1937
+ //
1938
+ // Uses deep equality on subComponent (it may be a new reference even when
1939
+ // semantically unchanged if the parent SoftRender array is reconstructed)
1940
+ // and on props (the primary driver of field-mapping changes).
1941
+ // configComponents and softComponentFields are treated as stable config
1942
+ // references — reference equality is intentional and fast here.
1943
+ (prev, next) => prev.depth === next.depth && prev.index === next.index && prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal3(prev.props, next.props) && equal3(prev.subComponent, next.subComponent) && equal3(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1944
+ );
1945
+ SubComponentRenderer.displayName = "SubComponentRenderer";
1946
+ var SoftRender = memo(
1947
+ ({
1948
+ softComponentFields,
1949
+ softComponentFieldSettings,
1950
+ softSubComponent,
1951
+ configComponents,
1952
+ props,
1953
+ depth = 0
1954
+ }) => {
1955
+ if (!(softSubComponent == null ? void 0 : softSubComponent.length)) return null;
1956
+ return /* @__PURE__ */ jsx5(Fragment2, { children: softSubComponent.map((subComponent, index) => {
1957
+ var _a;
1958
+ return /* @__PURE__ */ jsx5(
1959
+ SubComponentRenderer,
1960
+ {
1961
+ subComponent,
1962
+ softComponentFields,
1963
+ softComponentFieldSettings: softComponentFieldSettings || {},
1964
+ configComponents,
1965
+ props,
1966
+ depth,
1967
+ index
1968
+ },
1969
+ `${(_a = subComponent == null ? void 0 : subComponent.type) != null ? _a : "comp"}-${index}-${depth}`
1970
+ );
1971
+ }) });
1972
+ },
1973
+ // Covers all five props — not just `props` and `softSubComponent`.
1974
+ // configComponents / softComponentFields: reference equality (stable config).
1975
+ // softComponentFieldSettings: deep equality (may carry dynamic defaults).
1976
+ // props / softSubComponent: deep equality (primary render drivers).
1977
+ (prev, next) => prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && equal3(prev.props, next.props) && equal3(prev.softSubComponent, next.softSubComponent) && equal3(prev.softComponentFieldSettings, next.softComponentFieldSettings)
1978
+ );
1979
+ SoftRender.displayName = "SoftRender";
1228
1980
 
1229
1981
  // src/puck/lib/create-versioned-component-config.tsx
1230
1982
  import { jsx as jsx6 } from "react/jsx-runtime";
1231
- var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true) => {
1983
+ var hydrateCustomField = (fieldName, field, fieldSettings, customFields) => {
1984
+ var _a;
1985
+ if (field.type !== "custom") {
1986
+ return field;
1987
+ }
1988
+ const fieldWithMeta = field;
1989
+ const customFieldType = fieldWithMeta.customFieldType || ((_a = fieldSettings == null ? void 0 : fieldSettings[fieldName]) == null ? void 0 : _a.customFieldType);
1990
+ if (!customFieldType) {
1991
+ return field;
1992
+ }
1993
+ const customField = customFields == null ? void 0 : customFields[customFieldType];
1994
+ if (!customField) {
1995
+ return field;
1996
+ }
1997
+ return __spreadProps(__spreadValues(__spreadValues({}, field), customField.field), {
1998
+ type: "custom",
1999
+ label: field.label || customField.field.label || fieldName
2000
+ });
2001
+ };
2002
+ var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true, customFields) => {
1232
2003
  var _a, _b;
1233
2004
  const softConfig = config;
1234
2005
  return {
@@ -1256,7 +2027,12 @@ var createVersionedComponentConfig = (componentName, displayName, version, allVe
1256
2027
  };
1257
2028
  }
1258
2029
  Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").forEach(([key, field]) => {
1259
- fields[key] = field;
2030
+ fields[key] = hydrateCustomField(
2031
+ key,
2032
+ field,
2033
+ versionedComponent == null ? void 0 : versionedComponent.fieldSettings,
2034
+ customFields
2035
+ );
1260
2036
  });
1261
2037
  return fields;
1262
2038
  },
@@ -1283,21 +2059,16 @@ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1283
2059
  var _a;
1284
2060
  const resolvedProps = __spreadValues({}, softSubComponent.fixedProps);
1285
2061
  (_a = softSubComponent.map) == null ? void 0 : _a.forEach((mapItem) => {
1286
- const { from, to, transform } = mapItem || {};
1287
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1288
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1289
- const inputs = fromPaths.map(
1290
- (path) => getFieldSettingsByPath(componentRootData.props || {}, path)
2062
+ const { newProps } = applyMapping(
2063
+ resolvedProps,
2064
+ {},
2065
+ [mapItem],
2066
+ "propsFirst",
2067
+ {
2068
+ sourceProps: componentRootData.props || {}
2069
+ }
1291
2070
  );
1292
- const runner = transform;
1293
- const result = runner ? runner(inputs, componentRootData.props) : inputs[0];
1294
- if (Array.isArray(result)) {
1295
- result.forEach((val, idx) => {
1296
- if (toPaths[idx]) setPropertyByPath(resolvedProps, toPaths[idx], val);
1297
- });
1298
- } else if (toPaths[0]) {
1299
- setPropertyByPath(resolvedProps, toPaths[0], result);
1300
- }
2071
+ Object.assign(resolvedProps, newProps);
1301
2072
  });
1302
2073
  softSubComponent.enabledSlots.forEach(({ slot, name }) => {
1303
2074
  var _a2, _b;
@@ -1320,9 +2091,22 @@ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1320
2091
  return accItem;
1321
2092
  };
1322
2093
 
2094
+ // src/puck/lib/builder/resolve-soft-component-data.ts
2095
+ var resolveSoftComponentData = (props, _fieldSettings = {}) => {
2096
+ const map = props._map;
2097
+ if (!(map == null ? void 0 : map.length)) return __spreadValues({}, props);
2098
+ const { newProps } = applyMapping(
2099
+ props,
2100
+ _fieldSettings,
2101
+ map,
2102
+ "propsFirst"
2103
+ );
2104
+ return newProps;
2105
+ };
2106
+
1323
2107
  // src/puck/lib/decompose-soft-component.ts
1324
- function decomposeSoftComponent(componentData, softComponents) {
1325
- var _a, _b;
2108
+ function decomposeSoftComponent(componentData, softComponents, fieldSettings) {
2109
+ var _a, _b, _c, _d;
1326
2110
  if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
1327
2111
  throw new Error("Component data must have type and id to decompose.");
1328
2112
  }
@@ -1333,9 +2117,19 @@ function decomposeSoftComponent(componentData, softComponents) {
1333
2117
  `Soft component "${componentData.type}" version "${version}" not found.`
1334
2118
  );
1335
2119
  }
2120
+ let resolvedComponentData = componentData;
2121
+ if (fieldSettings && ((_d = (_c = componentData.props) == null ? void 0 : _c._map) == null ? void 0 : _d.length)) {
2122
+ const resolvedProps = resolveSoftComponentData(
2123
+ componentData.props,
2124
+ fieldSettings
2125
+ );
2126
+ resolvedComponentData = __spreadProps(__spreadValues({}, componentData), {
2127
+ props: resolvedProps
2128
+ });
2129
+ }
1336
2130
  const decomposedComponentData = softComponent.components.map(
1337
2131
  (softSubComponent) => {
1338
- return subComponentDecomposer(componentData, softSubComponent);
2132
+ return subComponentDecomposer(resolvedComponentData, softSubComponent);
1339
2133
  }
1340
2134
  );
1341
2135
  return decomposedComponentData;
@@ -1378,18 +2172,6 @@ function demolishSoftComponent(componentName, data, config, softComponents) {
1378
2172
  };
1379
2173
  }
1380
2174
 
1381
- // src/puck/lib/component-key.ts
1382
- var defaultToCamelCase = (value) => {
1383
- const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1384
- if (tokens.length === 0) return "";
1385
- const [first, ...rest] = tokens;
1386
- return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1387
- };
1388
- var createComponentKeyFromName = (displayName, overrides, context) => {
1389
- const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1390
- return key.trim();
1391
- };
1392
-
1393
2175
  // src/puck/store/slices/builder.tsx
1394
2176
  var createBuildersSlice = (set, get, initialConfig) => ({
1395
2177
  build: (history, selectedItem, itemSelector, puckDispatch, name) => {
@@ -1417,7 +2199,14 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1417
2199
  });
1418
2200
  const config = __spreadValues({}, get().softConfig);
1419
2201
  const overrides = get().overrides;
1420
- const buildConfig = builderConfig(config, overrides, void 0, get().showVersionFields);
2202
+ const buildConfig = builderConfig(
2203
+ config,
2204
+ overrides,
2205
+ void 0,
2206
+ get().showVersionFields,
2207
+ void 0,
2208
+ get().customFields
2209
+ );
1421
2210
  const editableIds = /* @__PURE__ */ new Set([selectedItem.props.id]);
1422
2211
  const initialContent = [__spreadValues({}, selectedItem)];
1423
2212
  walkTree3(
@@ -1489,13 +2278,22 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1489
2278
  versions,
1490
2279
  selectedItem.props,
1491
2280
  get().softConfig.components,
2281
+ get().overrides,
1492
2282
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || softComponentName,
1493
- softComponentMeta == null ? void 0 : softComponentMeta.category
2283
+ softComponentMeta == null ? void 0 : softComponentMeta.category,
2284
+ get().customFields
1494
2285
  );
1495
2286
  const config = __spreadValues({}, get().softConfig);
1496
2287
  const overrides = get().overrides;
1497
2288
  const dependents = get().dependencyGraph.get(softComponentName) || /* @__PURE__ */ new Set();
1498
- const buildConfig = builderConfig(config, overrides, softComponentName, get().showVersionFields, dependents);
2289
+ const buildConfig = builderConfig(
2290
+ config,
2291
+ overrides,
2292
+ softComponentName,
2293
+ get().showVersionFields,
2294
+ dependents,
2295
+ get().customFields
2296
+ );
1499
2297
  const editableIds = /* @__PURE__ */ new Set([]);
1500
2298
  const decomposedComponents = get().builder.decompose(selectedItem);
1501
2299
  walkTree3(
@@ -1541,6 +2339,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1541
2339
  zone: itemSelector.zone || rootDroppableId
1542
2340
  },
1543
2341
  editingComponentId: selectedItem.props.id,
2342
+ editingComponent: softComponentName,
1544
2343
  editableComponentIds: editableIds,
1545
2344
  state: "remodeling"
1546
2345
  }));
@@ -1557,7 +2356,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1557
2356
  );
1558
2357
  },
1559
2358
  complete: (appState, setHistories, getItemBySelector) => {
1560
- var _a, _b, _c, _d, _e, _f;
2359
+ var _a, _b, _c, _d, _e, _f, _g;
1561
2360
  if (get().state === "ready") {
1562
2361
  throw new Error("Not building or remodeling a component.");
1563
2362
  }
@@ -1576,10 +2375,11 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1576
2375
  throw new Error("Cannot find item being edited");
1577
2376
  }
1578
2377
  const rootCategory = (_e = (_d = appState.data.root) == null ? void 0 : _d.props) == null ? void 0 : _e._category;
1579
- const componentName = createComponentKeyFromName(displayName, get().overrides, {
2378
+ const rootProps = (_f = appState.data.root) == null ? void 0 : _f.props;
2379
+ const componentName = createComponentKeyFromName(displayName, get().overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
1580
2380
  existingKeys: Object.keys(get().softComponents),
1581
2381
  state: get().state
1582
- });
2382
+ }));
1583
2383
  if (!componentName) {
1584
2384
  throw new Error("Failed to generate component key from name.");
1585
2385
  }
@@ -1638,6 +2438,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1638
2438
  storedConfig: void 0,
1639
2439
  state: "inspecting",
1640
2440
  originalHistory: [],
2441
+ editingComponent: null,
1641
2442
  editingComponentId: null,
1642
2443
  editableComponentIds: /* @__PURE__ */ new Set()
1643
2444
  });
@@ -1645,7 +2446,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1645
2446
  if (!version) {
1646
2447
  throw new Error("Failed to resolve completed component version.");
1647
2448
  }
1648
- const completedSoftComponent = (_f = get().softComponents[componentName]) == null ? void 0 : _f.versions[version];
2449
+ const completedSoftComponent = (_g = get().softComponents[componentName]) == null ? void 0 : _g.versions[version];
1649
2450
  if (!completedSoftComponent) {
1650
2451
  throw new Error(
1651
2452
  `Completed soft component "${componentName}" version "${version}" not found.`
@@ -1697,6 +2498,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1697
2498
  itemSelector: null,
1698
2499
  originalItem: null,
1699
2500
  state: "ready",
2501
+ editingComponent: null,
1700
2502
  editingComponentId: null,
1701
2503
  editableComponentIds: /* @__PURE__ */ new Set()
1702
2504
  }));
@@ -1718,7 +2520,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1718
2520
  {
1719
2521
  name: displayName,
1720
2522
  category
1721
- }
2523
+ },
2524
+ get().customFields
1722
2525
  );
1723
2526
  const existingComponent = get().softComponents[componentName];
1724
2527
  const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
@@ -1737,7 +2540,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1737
2540
  })
1738
2541
  }),
1739
2542
  softComponent.defaultProps,
1740
- get().showVersionFields
2543
+ get().showVersionFields,
2544
+ get().customFields
1741
2545
  );
1742
2546
  get().setSoftComponent(componentName, version, softComponent);
1743
2547
  return [newSoftComponentConfig, version];
@@ -1789,8 +2593,10 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1789
2593
  versions,
1790
2594
  currentProps,
1791
2595
  get().softConfig.components,
2596
+ get().overrides,
1792
2597
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1793
- softComponentMeta == null ? void 0 : softComponentMeta.category
2598
+ softComponentMeta == null ? void 0 : softComponentMeta.category,
2599
+ get().customFields
1794
2600
  );
1795
2601
  puckDispatch({
1796
2602
  type: "setData",
@@ -1937,7 +2743,7 @@ function topologicalSort(softComponents, hardComponentNames) {
1937
2743
  }
1938
2744
  return sorted;
1939
2745
  }
1940
- function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false) {
2746
+ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false, customFields) {
1941
2747
  var _a, _b;
1942
2748
  if (!softComponents || Object.keys(softComponents).length === 0) {
1943
2749
  return {};
@@ -1973,7 +2779,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showV
1973
2779
  // Pass the accumulating config
1974
2780
  hydratedSoftComponents,
1975
2781
  versionedComponent.defaultProps,
1976
- showVersioning
2782
+ showVersioning,
2783
+ customFields
1977
2784
  );
1978
2785
  componentConfigs[name] = newSoftComponentConfig;
1979
2786
  buildingConfig.components[name] = newSoftComponentConfig;
@@ -2001,7 +2808,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showV
2001
2808
  hardConfig,
2002
2809
  hydratedSoftComponents,
2003
2810
  versionedComponent.defaultProps,
2004
- showVersioning
2811
+ showVersioning,
2812
+ customFields
2005
2813
  );
2006
2814
  componentConfigs[name] = newSoftComponentConfig;
2007
2815
  }
@@ -2067,9 +2875,9 @@ var clearEditVisibility = (doc) => {
2067
2875
  // src/puck/store/index.tsx
2068
2876
  var createSoftConfigStore = (hardConfig = {
2069
2877
  components: {}
2070
- }, softComponents = {}, overrides = {}, onActions, showVersionFields = true) => {
2878
+ }, softComponents = {}, overrides = {}, onActions, showVersionFields = true, customFields = {}) => {
2071
2879
  const normalizedSoftComponents = Object.fromEntries(
2072
- Object.entries(softComponents || {}).map(([key, value]) => [
2880
+ Object.entries(softComponents || {}).filter(([key]) => !hardConfig.components || !hardConfig.components[key]).map(([key, value]) => [
2073
2881
  key,
2074
2882
  __spreadProps(__spreadValues({}, value), {
2075
2883
  name: value.name || key
@@ -2090,9 +2898,11 @@ var createSoftConfigStore = (hardConfig = {
2090
2898
  state: "ready",
2091
2899
  originalHistory: [],
2092
2900
  overrides,
2901
+ customFields,
2093
2902
  onActions,
2094
2903
  iframeDocRef,
2095
2904
  showVersionFields,
2905
+ editingComponent: null,
2096
2906
  setShowVersionFields: (show) => set({ showVersionFields: show }),
2097
2907
  getIframeDoc: () => iframeDocRef.current,
2098
2908
  setIframeDoc: (doc) => {
@@ -2130,11 +2940,17 @@ var createSoftConfigStore = (hardConfig = {
2130
2940
  components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(
2131
2941
  hardConfig,
2132
2942
  hydratedSoftComponents,
2133
- overrides
2943
+ overrides,
2944
+ showVersionFields,
2945
+ customFields
2134
2946
  )),
2135
2947
  categories: __spreadValues({}, hardConfig.categories || {})
2136
2948
  }),
2137
2949
  setSoftComponent: (name, version, component) => {
2950
+ if (hardConfig.components && hardConfig.components[name]) {
2951
+ console.warn(`Cannot set soft component "${name}" because it conflicts with a base hardConfig component.`);
2952
+ return;
2953
+ }
2138
2954
  const existing = get().softComponents[name];
2139
2955
  set((state) => {
2140
2956
  var _a, _b;
@@ -2157,6 +2973,9 @@ var createSoftConfigStore = (hardConfig = {
2157
2973
  const nextSoftComponents = __spreadValues({}, state.softComponents);
2158
2974
  const nextConfigComponents = __spreadValues({}, state.softConfig.components);
2159
2975
  Object.entries(incomingComponents).forEach(([name, data]) => {
2976
+ if (hardConfig.components && hardConfig.components[name]) {
2977
+ return;
2978
+ }
2160
2979
  const existing = nextSoftComponents[name];
2161
2980
  const finalComponentData = existing ? __spreadProps(__spreadValues(__spreadValues({}, existing), data), {
2162
2981
  name: data.name || existing.name || name,
@@ -2175,7 +2994,8 @@ var createSoftConfigStore = (hardConfig = {
2175
2994
  state.softConfig,
2176
2995
  nextSoftComponents,
2177
2996
  activeVersionData.defaultProps,
2178
- state.showVersionFields
2997
+ state.showVersionFields,
2998
+ state.customFields
2179
2999
  );
2180
3000
  }
2181
3001
  });
@@ -2206,7 +3026,8 @@ var createSoftConfigStore = (hardConfig = {
2206
3026
  softConfig,
2207
3027
  hydratedComponents,
2208
3028
  activeVersionData.defaultProps,
2209
- get().showVersionFields
3029
+ get().showVersionFields,
3030
+ get().customFields
2210
3031
  );
2211
3032
  }
2212
3033
  });
@@ -2237,7 +3058,8 @@ var createSoftConfigStore = (hardConfig = {
2237
3058
  get().softConfig,
2238
3059
  get().softComponents,
2239
3060
  softComponent.defaultProps,
2240
- get().showVersionFields
3061
+ get().showVersionFields,
3062
+ get().customFields
2241
3063
  );
2242
3064
  set((state) => ({
2243
3065
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
@@ -2374,7 +3196,8 @@ var createSoftConfigStore = (hardConfig = {
2374
3196
  config,
2375
3197
  softComponents2,
2376
3198
  versionedComponent.defaultProps,
2377
- state.showVersionFields
3199
+ state.showVersionFields,
3200
+ state.customFields
2378
3201
  );
2379
3202
  config.components[dependentName] = newConfig;
2380
3203
  }
@@ -2386,25 +3209,40 @@ var createSoftConfigStore = (hardConfig = {
2386
3209
  };
2387
3210
 
2388
3211
  // src/puck/context/storeProvider.tsx
2389
- import { useEffect as useEffect2, useMemo as useMemo2, useState as useState2 } from "react";
3212
+ import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
2390
3213
  import { jsx as jsx7 } from "react/jsx-runtime";
2391
3214
  var SoftConfigProvider = ({
2392
3215
  children,
2393
3216
  hardConfig,
2394
3217
  softComponents,
3218
+ customFields,
2395
3219
  overrides,
2396
3220
  value,
2397
3221
  onActions,
2398
3222
  useVersioning = false
2399
3223
  }) => {
2400
3224
  const store = value != null ? value : useMemo2(
2401
- () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2402
- [hardConfig, softComponents, overrides, onActions, useVersioning]
3225
+ () => createSoftConfigStore(
3226
+ hardConfig,
3227
+ softComponents,
3228
+ overrides,
3229
+ onActions,
3230
+ useVersioning,
3231
+ customFields
3232
+ ),
3233
+ [
3234
+ hardConfig,
3235
+ softComponents,
3236
+ overrides,
3237
+ onActions,
3238
+ useVersioning,
3239
+ customFields
3240
+ ]
2403
3241
  );
2404
- const [softConfig, setSoftConfig] = useState2(
3242
+ const [softConfig, setSoftConfig] = useState(
2405
3243
  () => store.getState().softConfig
2406
3244
  );
2407
- const [internalSoftComponents, setSoftComponents] = useState2(
3245
+ const [internalSoftComponents, setSoftComponents] = useState(
2408
3246
  () => store.getState().softComponents
2409
3247
  );
2410
3248
  const storeSetIframeDoc = useMemo2(
@@ -2413,14 +3251,19 @@ var SoftConfigProvider = ({
2413
3251
  );
2414
3252
  const validateAction = useMemo2(
2415
3253
  () => (action) => {
3254
+ var _a;
2416
3255
  const currentState = store.getState();
2417
3256
  if (currentState.state === "ready") {
2418
3257
  return true;
2419
3258
  }
2420
3259
  const editableIds = currentState.editableComponentIds;
2421
3260
  if (action.type === "replace") {
3261
+ const parentId = (_a = action.destinationZone) == null ? void 0 : _a.split(":")[0];
2422
3262
  if (action.data.props.id && editableIds.has(action.data.props.id)) {
2423
3263
  return true;
3264
+ } else if (parentId && editableIds.has(parentId)) {
3265
+ currentState.addEditableComponentId(action.data.props.id);
3266
+ return true;
2424
3267
  }
2425
3268
  return false;
2426
3269
  }
@@ -2633,7 +3476,7 @@ var useRemodel = () => {
2633
3476
 
2634
3477
  // src/puck/actions/useComplete.tsx
2635
3478
  import { createUsePuck as createUsePuck4 } from "@measured/puck";
2636
- import { useState as useState3, useCallback as useCallback2 } from "react";
3479
+ import { useState as useState2, useCallback as useCallback2 } from "react";
2637
3480
  var useCustomPuck4 = createUsePuck4();
2638
3481
  var useComplete = () => {
2639
3482
  const complete = useSoftConfig((s) => s.builder.complete);
@@ -2641,7 +3484,7 @@ var useComplete = () => {
2641
3484
  const setHistories = useCustomPuck4((s) => s.history.setHistories);
2642
3485
  const getItemBySelector = useCustomPuck4((s) => s.getItemBySelector);
2643
3486
  const status = useSoftConfig((s) => s.state);
2644
- const [newComponent, setNewComponent] = useState3(null);
3487
+ const [newComponent, setNewComponent] = useState2(null);
2645
3488
  const { triggerAction } = useActionEvent();
2646
3489
  const handleComplete = useCallback2(() => {
2647
3490
  if (status === "ready") {
@@ -2989,32 +3832,50 @@ import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-run
2989
3832
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
2990
3833
  var usePuck2 = createUsePuck11();
2991
3834
  var ActionBarOverride = (props) => {
2992
- var _a;
2993
- const { handleBuild } = useBuild("Custom Name");
3835
+ var _a, _b;
3836
+ const { handleBuild } = useBuild(props.label ? props.label + " Soft Component" : "New Soft Component");
2994
3837
  const { handleRemodel } = useRemodel();
2995
3838
  const { handleDecompose } = useDecompose();
2996
3839
  const overrides = useSoftConfig((s) => s.overrides);
2997
3840
  const softComponents = useSoftConfig((s) => s.softComponents, shallow);
2998
3841
  const editableIds = useSoftConfig((s) => s.editableComponentIds);
2999
3842
  const selectedItem = usePuck2((s) => s.selectedItem);
3843
+ const rootProps = usePuck2((s) => s.appState.data.root.props);
3000
3844
  const status = useSoftConfig((s) => s.state);
3845
+ const itemSelector = usePuck2((s) => s.appState.ui.itemSelector);
3001
3846
  const softKeys = Object.keys(softComponents);
3002
- const key = useMemo3(() => createComponentKeyFromName(props.label || "", overrides, {
3003
- existingKeys: softKeys,
3004
- state: status
3005
- }), [
3847
+ const key = useMemo3(() => {
3848
+ const selectedType = selectedItem == null ? void 0 : selectedItem.type;
3849
+ if (selectedType && softKeys.includes(selectedType)) {
3850
+ return selectedType;
3851
+ }
3852
+ return createComponentKeyFromName(props.label || "", overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
3853
+ existingKeys: softKeys,
3854
+ state: status
3855
+ }));
3856
+ }, [
3006
3857
  props.label,
3007
3858
  overrides,
3859
+ selectedItem == null ? void 0 : selectedItem.type,
3008
3860
  softKeys,
3009
- status
3861
+ status,
3862
+ rootProps
3010
3863
  ]);
3011
3864
  const isSoftComponent2 = softKeys.includes(key);
3012
3865
  const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
3013
- const isEditable = Boolean(selectedId && editableIds.has(selectedId));
3866
+ const parentId = (_b = itemSelector == null ? void 0 : itemSelector.zone) == null ? void 0 : _b.split(":")[0];
3867
+ const isEditable = Boolean(selectedId && (editableIds.has(selectedId) || parentId && editableIds.has(parentId)));
3868
+ const displayName = useMemo3(() => {
3869
+ var _a2;
3870
+ if (isSoftComponent2) {
3871
+ return ((_a2 = softComponents[key]) == null ? void 0 : _a2.name) || getComponentNameFromKey(key, overrides);
3872
+ }
3873
+ return props.label || "";
3874
+ }, [isSoftComponent2, key, props.label, overrides, softComponents]);
3014
3875
  return /* @__PURE__ */ jsx9("div", { className: getClassName3(), children: /* @__PURE__ */ jsxs3(ActionBar, { children: [
3015
3876
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
3016
3877
  props.parentAction,
3017
- /* @__PURE__ */ jsx9(ActionBar.Label, { label: props.label })
3878
+ /* @__PURE__ */ jsx9(ActionBar.Label, { label: displayName })
3018
3879
  ] }),
3019
3880
  /* @__PURE__ */ jsxs3(ActionBar.Group, { children: [
3020
3881
  status === "ready" ? isSoftComponent2 ? /* @__PURE__ */ jsxs3(Fragment4, { children: [
@@ -3048,7 +3909,7 @@ var ActionBarOverride = (props) => {
3048
3909
  };
3049
3910
 
3050
3911
  // src/puck/overrides/DrawerItem.tsx
3051
- import { useState as useState5 } from "react";
3912
+ import { useState as useState4 } from "react";
3052
3913
  import { Button as Button2, IconButton, createUsePuck as createUsePuck12 } from "@measured/puck";
3053
3914
  import { GripVertical, Check, X, Trash2, Cog } from "lucide-react";
3054
3915
 
@@ -3073,7 +3934,7 @@ var confirm = (message) => __async(null, null, function* () {
3073
3934
  var DrawerItem_module_default = { "DrawerItem": "_DrawerItem_182aj_1", "DrawerItem--insertDisabled": "_DrawerItem--insertDisabled_182aj_14", "DrawerItem-content": "_DrawerItem-content_182aj_21", "DrawerItem-name": "_DrawerItem-name_182aj_31", "DrawerItem-version": "_DrawerItem-version_182aj_35", "DrawerItem-actions": "_DrawerItem-actions_182aj_40", "DrawerItem-settingsButton": "_DrawerItem-settingsButton_182aj_46", "DrawerItem-grip": "_DrawerItem-grip_182aj_56", "DrawerItem-modal": "_DrawerItem-modal_182aj_63", "DrawerItem-modalHeader": "_DrawerItem-modalHeader_182aj_71", "DrawerItem-modalTitle": "_DrawerItem-modalTitle_182aj_77", "DrawerItem-modalSubtitle": "_DrawerItem-modalSubtitle_182aj_84", "DrawerItem-modalBody": "_DrawerItem-modalBody_182aj_90", "DrawerItem-section": "_DrawerItem-section_182aj_100", "DrawerItem-sectionTitle": "_DrawerItem-sectionTitle_182aj_106", "DrawerItem-sectionDescription": "_DrawerItem-sectionDescription_182aj_113", "DrawerItem-versionList": "_DrawerItem-versionList_182aj_119", "DrawerItem-versionRow": "_DrawerItem-versionRow_182aj_125", "DrawerItem-versionRow--isDefault": "_DrawerItem-versionRow--isDefault_182aj_136", "DrawerItem-versionRow--isMarkedForDeletion": "_DrawerItem-versionRow--isMarkedForDeletion_182aj_141", "DrawerItem-versionInfo": "_DrawerItem-versionInfo_182aj_146", "DrawerItem-versionNumber": "_DrawerItem-versionNumber_182aj_153", "DrawerItem-defaultBadge": "_DrawerItem-defaultBadge_182aj_159", "DrawerItem-deleteBadge": "_DrawerItem-deleteBadge_182aj_170", "DrawerItem-versionActions": "_DrawerItem-versionActions_182aj_181", "DrawerItem-migrationOptions": "_DrawerItem-migrationOptions_182aj_187", "DrawerItem-migrationList": "_DrawerItem-migrationList_182aj_191", "DrawerItem-migrationOption": "_DrawerItem-migrationOption_182aj_187", "DrawerItem-migrationOption--isSelected": "_DrawerItem-migrationOption--isSelected_182aj_229", "DrawerItem-migrationOptionLabel": "_DrawerItem-migrationOptionLabel_182aj_234", "DrawerItem-modalFooter": "_DrawerItem-modalFooter_182aj_240", "DrawerItem-footerLeft": "_DrawerItem-footerLeft_182aj_250", "DrawerItem-footerRight": "_DrawerItem-footerRight_182aj_255" };
3074
3935
 
3075
3936
  // src/puck/components/modal/index.tsx
3076
- import { useEffect as useEffect4, useState as useState4 } from "react";
3937
+ import { useEffect as useEffect4, useState as useState3 } from "react";
3077
3938
  import { createPortal } from "react-dom";
3078
3939
 
3079
3940
  // css-module:/media/manual_mount/osamuProjects/netlisian/packages/soft-config/src/puck/components/modal/styles.module.css#css-module
@@ -3087,7 +3948,7 @@ var Modal = ({
3087
3948
  onClose,
3088
3949
  isOpen
3089
3950
  }) => {
3090
- const [rootEl, setRootEl] = useState4(null);
3951
+ const [rootEl, setRootEl] = useState3(null);
3091
3952
  useEffect4(() => {
3092
3953
  setRootEl(document.getElementById("puck-portal-root"));
3093
3954
  }, []);
@@ -3139,7 +4000,7 @@ var getClassName5 = get_class_name_factory_default("DrawerItem", DrawerItem_modu
3139
4000
  var usePuck3 = createUsePuck12();
3140
4001
  var DrawerItem = (props) => {
3141
4002
  const componentMeta = useSoftConfig((s) => s.softComponents[props.name]);
3142
- const displayName = (componentMeta == null ? void 0 : componentMeta.name) || props.name;
4003
+ const displayName = props.label || (componentMeta == null ? void 0 : componentMeta.name) || props.name;
3143
4004
  const softComponents = new Set(
3144
4005
  Object.keys(useSoftConfig((s) => s.softComponents, shallow2))
3145
4006
  );
@@ -3151,13 +4012,13 @@ var DrawerItem = (props) => {
3151
4012
  const { handleDemolish } = useDemolish();
3152
4013
  const { handleSetDefaultVersion, getVersions, getDefaultVersion } = useSetDefaultVersion();
3153
4014
  const { triggerAction } = useActionEvent();
3154
- const [isEditing, setIsEditing] = useState5(false);
3155
- const [isHovering, setIsHovering] = useState5(false);
3156
- const [selectedVersion, setSelectedVersion] = useState5("");
3157
- const [versionsToDelete, setVersionsToDelete] = useState5(
4015
+ const [isEditing, setIsEditing] = useState4(false);
4016
+ const [isHovering, setIsHovering] = useState4(false);
4017
+ const [selectedVersion, setSelectedVersion] = useState4("");
4018
+ const [versionsToDelete, setVersionsToDelete] = useState4(
3158
4019
  /* @__PURE__ */ new Set()
3159
4020
  );
3160
- const [migrationTarget, setMigrationTarget] = useState5("decompose");
4021
+ const [migrationTarget, setMigrationTarget] = useState4("decompose");
3161
4022
  const useVersioning = useSoftConfig((s) => s.showVersionFields);
3162
4023
  const versions = getVersions(props.name);
3163
4024
  const defaultVersion = getDefaultVersion(props.name);
@@ -3235,6 +4096,7 @@ var DrawerItem = (props) => {
3235
4096
  onMouseEnter: () => setIsHovering(true),
3236
4097
  onMouseLeave: () => setIsHovering(false),
3237
4098
  children: [
4099
+ props.label,
3238
4100
  /* @__PURE__ */ jsxs4("div", { className: getClassName5("content"), children: [
3239
4101
  /* @__PURE__ */ jsx11("div", { className: getClassName5("name"), children: displayName }),
3240
4102
  useVersioning && /* @__PURE__ */ jsxs4("div", { className: getClassName5("version"), children: [
@@ -3356,7 +4218,7 @@ var DrawerItem = (props) => {
3356
4218
  var ComponentItem = DrawerItem;
3357
4219
 
3358
4220
  // src/puck/overrides/Drawer.tsx
3359
- import { useState as useState6 } from "react";
4221
+ import { useState as useState5 } from "react";
3360
4222
  import { createUsePuck as createUsePuck13, Drawer as PuckDrawer } from "@measured/puck";
3361
4223
  import { ChevronDown, ChevronUp } from "lucide-react";
3362
4224
 
@@ -3411,11 +4273,15 @@ var Drawer = (_props) => {
3411
4273
  })
3412
4274
  );
3413
4275
  const allKeys = Object.keys(config.components);
4276
+ const labels = Object.entries(config.components).reduce((acc, [key, comp]) => {
4277
+ acc[key] = comp.label || key;
4278
+ return acc;
4279
+ }, {});
3414
4280
  const otherKeys = allKeys.filter((k) => !categorised.has(k));
3415
4281
  const categoryEntries = Object.entries(categories).filter(
3416
4282
  ([, cat]) => cat.visible !== false
3417
4283
  );
3418
- const [expanded, setExpanded] = useState6(() => {
4284
+ const [expanded, setExpanded] = useState5(() => {
3419
4285
  const init = {};
3420
4286
  categoryEntries.forEach(([id, cat]) => {
3421
4287
  init[id] = cat.defaultExpanded !== false;
@@ -3429,6 +4295,7 @@ var Drawer = (_props) => {
3429
4295
  PuckDrawer.Item,
3430
4296
  {
3431
4297
  name: key,
4298
+ label: labels[key],
3432
4299
  isDragDisabled: !getPermissions({ type: key }).insert,
3433
4300
  children: DrawerItem
3434
4301
  },
@@ -3513,9 +4380,6 @@ function extractDependencies2(softComponents, componentName, version) {
3513
4380
  return dependencies;
3514
4381
  }
3515
4382
  function reverseTopologicalSort(softComponents, hardComponentNames) {
3516
- const sorted = [];
3517
- const visiting = /* @__PURE__ */ new Set();
3518
- const visited = /* @__PURE__ */ new Set();
3519
4383
  const dependencyGraph = /* @__PURE__ */ new Map();
3520
4384
  const dependents = /* @__PURE__ */ new Map();
3521
4385
  for (const [componentName, component] of Object.entries(softComponents)) {
@@ -3563,7 +4427,7 @@ function reverseTopologicalSort(softComponents, hardComponentNames) {
3563
4427
  const sortedByDepth = [...depths.entries()].sort(([, depthA], [, depthB]) => depthB - depthA).map(([name]) => name);
3564
4428
  return sortedByDepth;
3565
4429
  }
3566
- function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0) {
4430
+ function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0, fieldSettings) {
3567
4431
  const MAX_DEPTH = 50;
3568
4432
  if (depth > MAX_DEPTH) {
3569
4433
  console.error(
@@ -3573,11 +4437,11 @@ function dissolveComponentRecursively(componentData, softComponents, hardCompone
3573
4437
  }
3574
4438
  const componentType = componentData.type;
3575
4439
  if (!isSoftComponent(componentType, softComponents)) {
3576
- return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth)];
4440
+ return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth, fieldSettings)];
3577
4441
  }
3578
4442
  let decomposed;
3579
4443
  try {
3580
- decomposed = decomposeSoftComponent(componentData, softComponents);
4444
+ decomposed = decomposeSoftComponent(componentData, softComponents, fieldSettings);
3581
4445
  } catch (error) {
3582
4446
  console.warn(
3583
4447
  `Failed to decompose soft component "${componentType}":`,
@@ -3591,13 +4455,14 @@ function dissolveComponentRecursively(componentData, softComponents, hardCompone
3591
4455
  component,
3592
4456
  softComponents,
3593
4457
  hardComponentNames,
3594
- depth + 1
4458
+ depth + 1,
4459
+ fieldSettings
3595
4460
  );
3596
4461
  fullyDissolved.push(...dissolved);
3597
4462
  }
3598
4463
  return fullyDissolved;
3599
4464
  }
3600
- function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth) {
4465
+ function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth, fieldSettings) {
3601
4466
  const newProps = __spreadValues({}, componentData.props);
3602
4467
  Object.entries(newProps).forEach(([key, value]) => {
3603
4468
  var _a;
@@ -3607,7 +4472,8 @@ function dissolveComponentSlots(componentData, softComponents, hardComponentName
3607
4472
  slotComponent,
3608
4473
  softComponents,
3609
4474
  hardComponentNames,
3610
- depth
4475
+ depth,
4476
+ fieldSettings
3611
4477
  )
3612
4478
  );
3613
4479
  }
@@ -3617,22 +4483,23 @@ function dissolveComponentSlots(componentData, softComponents, hardComponentName
3617
4483
  });
3618
4484
  }
3619
4485
  function dissolveAllSoftComponents(data, softComponents, config) {
4486
+ var _a;
3620
4487
  const hardComponentNames = new Set(
3621
4488
  Object.keys(config.components || {}).filter(
3622
4489
  (name) => !isSoftComponent(name, softComponents)
3623
4490
  )
3624
4491
  );
3625
- const dissolutionOrder = reverseTopologicalSort(
3626
- softComponents,
3627
- hardComponentNames
3628
- );
4492
+ reverseTopologicalSort(softComponents, hardComponentNames);
4493
+ const rootParams = ((_a = data.root) == null ? void 0 : _a.props) || {};
4494
+ const fieldSettings = __spreadValues(__spreadValues({}, rootParams._fieldSettings || {}), rootParams);
3629
4495
  const dissolveComponents = (components) => {
3630
4496
  return components.flatMap((componentData) => {
3631
4497
  return dissolveComponentRecursively(
3632
4498
  componentData,
3633
4499
  softComponents,
3634
4500
  hardComponentNames,
3635
- 0
4501
+ 0,
4502
+ fieldSettings
3636
4503
  );
3637
4504
  });
3638
4505
  };
@@ -3698,12 +4565,18 @@ export {
3698
4565
  Header,
3699
4566
  Modal,
3700
4567
  SoftConfigProvider,
4568
+ applyMapping,
3701
4569
  confirm,
3702
4570
  createActionCallback,
3703
4571
  createSoftConfigStore,
3704
4572
  createUseSoftConfig,
4573
+ filterToOptionsForFrom,
4574
+ getArrayBasePath,
4575
+ getArrayItemSubPath,
4576
+ isArrayMappingPath,
3705
4577
  notify,
3706
4578
  resolveSoftConfig,
4579
+ resolveValueByPath,
3707
4580
  setConfirmHandler,
3708
4581
  setNotificationHandler,
3709
4582
  useBuild,