@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.
@@ -23,18 +23,6 @@ var __spreadValues = (a, b) => {
23
23
  return a;
24
24
  };
25
25
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
26
- var __objRest = (source, exclude) => {
27
- var target = {};
28
- for (var prop in source)
29
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
30
- target[prop] = source[prop];
31
- if (source != null && __getOwnPropSymbols)
32
- for (var prop of __getOwnPropSymbols(source)) {
33
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
34
- target[prop] = source[prop];
35
- }
36
- return target;
37
- };
38
26
  var __export = (target, all) => {
39
27
  for (var name in all)
40
28
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -88,12 +76,18 @@ __export(puck_exports, {
88
76
  Header: () => Header,
89
77
  Modal: () => Modal,
90
78
  SoftConfigProvider: () => SoftConfigProvider,
79
+ applyMapping: () => applyMapping,
91
80
  confirm: () => confirm,
92
81
  createActionCallback: () => createActionCallback,
93
82
  createSoftConfigStore: () => createSoftConfigStore,
94
83
  createUseSoftConfig: () => createUseSoftConfig,
84
+ filterToOptionsForFrom: () => filterToOptionsForFrom,
85
+ getArrayBasePath: () => getArrayBasePath,
86
+ getArrayItemSubPath: () => getArrayItemSubPath,
87
+ isArrayMappingPath: () => isArrayMappingPath,
95
88
  notify: () => notify,
96
89
  resolveSoftConfig: () => resolveSoftConfig,
90
+ resolveValueByPath: () => resolveValueByPath,
97
91
  setConfirmHandler: () => setConfirmHandler,
98
92
  setNotificationHandler: () => setNotificationHandler,
99
93
  useBuild: () => useBuild,
@@ -119,63 +113,358 @@ var import_puck4 = require("@measured/puck");
119
113
  var getRootProps = (appState) => appState.data.root.props;
120
114
 
121
115
  // src/puck/lib/builder/root-config.tsx
116
+ var import_react2 = require("react");
117
+ var import_react_fast_compare2 = __toESM(require("react-fast-compare"));
122
118
  var import_puck2 = require("@measured/puck");
123
119
 
124
120
  // src/puck/lib/get-field-settings.tsx
125
121
  var import_puck = require("@measured/puck");
122
+
123
+ // src/puck/lib/get-settings-by-path.ts
124
+ function getFieldSettingsByPath(fieldSettings, path) {
125
+ return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
126
+ }
127
+
128
+ // src/puck/lib/array-field-utils.ts
129
+ var primitiveFieldTypes = /* @__PURE__ */ new Set([
130
+ "text",
131
+ "textarea",
132
+ "number",
133
+ "select",
134
+ "radio",
135
+ "reference"
136
+ ]);
137
+ var isPrimitiveValue = (value) => ["string", "number", "boolean"].includes(typeof value);
138
+ var getFallbackValueForField = (type) => {
139
+ switch (type) {
140
+ case "number":
141
+ return 0;
142
+ case "array":
143
+ return [];
144
+ case "object":
145
+ return {};
146
+ default:
147
+ return "";
148
+ }
149
+ };
150
+ var resolveExpressionSummary = (item, index, expression) => {
151
+ if (!expression) return "";
152
+ let isValid = true;
153
+ const result = expression.replace(/\{([^}]+)\}/g, (_match, token) => {
154
+ if (token === "index") {
155
+ return String(index);
156
+ }
157
+ if (token.startsWith("item.")) {
158
+ const value = getFieldSettingsByPath(item, token.slice(5));
159
+ if (isPrimitiveValue(value)) {
160
+ return String(value);
161
+ }
162
+ }
163
+ isValid = false;
164
+ return "";
165
+ });
166
+ return isValid ? result : "";
167
+ };
168
+ var isPrimitiveFieldType = (type) => primitiveFieldTypes.has(type);
169
+ var buildArrayDefaultItemProps = (subFields = [], subFieldSettings = {}) => {
170
+ if (!subFields.length) return void 0;
171
+ const item = {};
172
+ let hasValue = false;
173
+ subFields.forEach((subField) => {
174
+ const settings = subFieldSettings[subField.name];
175
+ if (settings && Object.prototype.hasOwnProperty.call(settings, "defaultValue") && settings.defaultValue !== void 0) {
176
+ item[subField.name] = settings.defaultValue;
177
+ hasValue = true;
178
+ return;
179
+ }
180
+ item[subField.name] = getFallbackValueForField(subField.type);
181
+ hasValue = true;
182
+ });
183
+ return hasValue ? item : void 0;
184
+ };
185
+ var buildArrayDefaultValue = (subFields = [], subFieldSettings = {}) => {
186
+ const item = buildArrayDefaultItemProps(subFields, subFieldSettings);
187
+ return item ? [item] : [];
188
+ };
189
+ var getArrayItemSummary = (item, index = 0, settings) => {
190
+ if ((settings == null ? void 0 : settings.summary) === "field" && settings.summaryField) {
191
+ const value = getFieldSettingsByPath(item, settings.summaryField);
192
+ if (isPrimitiveValue(value) && String(value).length > 0) {
193
+ return String(value);
194
+ }
195
+ return `Item ${(index || 0) + 1}`;
196
+ }
197
+ if ((settings == null ? void 0 : settings.summary) === "expression") {
198
+ const summary = resolveExpressionSummary(
199
+ item,
200
+ index,
201
+ settings.summaryExpression
202
+ );
203
+ return summary || `Item ${(index || 0) + 1}`;
204
+ }
205
+ return `Item ${(index || 0) + 1}`;
206
+ };
207
+ var isArrayMappingPath = (path) => {
208
+ return typeof path === "string" && /^[^.]+\[\]\.[^.]+$/.test(path);
209
+ };
210
+ var getArrayBasePath = (arrayPath) => {
211
+ if (!isArrayMappingPath(arrayPath)) return null;
212
+ const match = arrayPath.match(/^([^.]+)\[\]\./);
213
+ return match ? match[1] : null;
214
+ };
215
+ var getArrayItemSubPath = (arrayPath) => {
216
+ if (!isArrayMappingPath(arrayPath)) return null;
217
+ const match = arrayPath.match(/\[\]\.(.+)$/);
218
+ return match ? match[1] : null;
219
+ };
220
+
221
+ // src/puck/lib/custom-fields.ts
222
+ var builtInSoftFieldTypes = /* @__PURE__ */ new Set([
223
+ "text",
224
+ "textarea",
225
+ "number",
226
+ "select",
227
+ "radio",
228
+ "array",
229
+ "object",
230
+ "reference"
231
+ ]);
232
+ var warnedMessages = /* @__PURE__ */ new Set();
233
+ var warnOnce = (message) => {
234
+ if (warnedMessages.has(message)) {
235
+ return;
236
+ }
237
+ warnedMessages.add(message);
238
+ console.warn(message);
239
+ };
240
+ var isBuiltInSoftFieldType = (fieldType) => {
241
+ return builtInSoftFieldTypes.has(fieldType);
242
+ };
243
+ var resolveCustomFieldDefinition = (fieldType, customFields) => {
244
+ if (isBuiltInSoftFieldType(fieldType)) {
245
+ return void 0;
246
+ }
247
+ return customFields == null ? void 0 : customFields[fieldType];
248
+ };
249
+ var resolveCustomFieldReturnType = (fieldType, customFields) => {
250
+ const customField = resolveCustomFieldDefinition(fieldType, customFields);
251
+ if (!customField) {
252
+ return null;
253
+ }
254
+ if (!customField.returnType) {
255
+ warnOnce(
256
+ `[soft-config] Custom field "${fieldType}" is missing a required returnType and will be skipped from mapping options.`
257
+ );
258
+ return null;
259
+ }
260
+ return customField.returnType;
261
+ };
262
+ var resolveCustomFieldSchema = (fieldType, customFields) => {
263
+ const customField = resolveCustomFieldDefinition(fieldType, customFields);
264
+ if (!customField) {
265
+ return null;
266
+ }
267
+ const returnType = resolveCustomFieldReturnType(fieldType, customFields);
268
+ if (!returnType) {
269
+ return null;
270
+ }
271
+ if (returnType !== "array" && returnType !== "object") {
272
+ return null;
273
+ }
274
+ const subFields = customField.subFields || [];
275
+ if (!subFields.length) {
276
+ warnOnce(
277
+ `[soft-config] Custom field "${fieldType}" returns ${returnType} but does not define subFields. It will be skipped from mapping options.`
278
+ );
279
+ return null;
280
+ }
281
+ return {
282
+ subFields,
283
+ subFieldSettings: customField.subFieldSettings || {}
284
+ };
285
+ };
286
+ var getCustomFieldTypeOptions = (customFields) => {
287
+ if (!customFields) {
288
+ return [];
289
+ }
290
+ return Object.entries(customFields).filter(([fieldType]) => !isBuiltInSoftFieldType(fieldType)).map(([fieldType, definition]) => ({
291
+ label: typeof definition.field.label === "string" && definition.field.label ? definition.field.label : fieldType,
292
+ value: fieldType
293
+ }));
294
+ };
295
+ var mapCustomReturnTypeToMappingType = (returnType) => {
296
+ switch (returnType) {
297
+ case "string":
298
+ return "textarea";
299
+ case "number":
300
+ return "number";
301
+ case "boolean":
302
+ return "select";
303
+ case "array":
304
+ return "array";
305
+ case "object":
306
+ return "object";
307
+ default:
308
+ return "textarea";
309
+ }
310
+ };
311
+
312
+ // src/puck/lib/get-field-settings.tsx
126
313
  var import_jsx_runtime = require("react/jsx-runtime");
127
- var getFieldSettings = (_fields, _fieldSettings, deep) => {
314
+ var buildPuckField = (field, fieldSettings, customFields) => {
315
+ const customFieldDefinition = resolveCustomFieldDefinition(
316
+ field.type,
317
+ customFields
318
+ );
319
+ const customReturnType = resolveCustomFieldReturnType(field.type, customFields);
320
+ if (customFieldDefinition && customReturnType) {
321
+ return __spreadProps(__spreadValues({}, customFieldDefinition.field), {
322
+ type: "custom",
323
+ label: customFieldDefinition.field.label || field.name
324
+ });
325
+ }
326
+ const resolvedType = field.type;
327
+ switch (resolvedType) {
328
+ case "text":
329
+ case "textarea":
330
+ return { type: resolvedType, label: field.name };
331
+ case "number":
332
+ return {
333
+ type: resolvedType,
334
+ label: field.name,
335
+ min: fieldSettings == null ? void 0 : fieldSettings.min,
336
+ max: fieldSettings == null ? void 0 : fieldSettings.max,
337
+ step: fieldSettings == null ? void 0 : fieldSettings.step
338
+ };
339
+ case "select":
340
+ case "radio":
341
+ return {
342
+ type: resolvedType,
343
+ label: field.name,
344
+ options: (fieldSettings == null ? void 0 : fieldSettings.options) || []
345
+ };
346
+ case "array": {
347
+ const subFields = (fieldSettings == null ? void 0 : fieldSettings.subFields) || [];
348
+ const subFieldSettings = (fieldSettings == null ? void 0 : fieldSettings.subFieldSettings) || {};
349
+ return {
350
+ type: "array",
351
+ label: field.name,
352
+ min: fieldSettings == null ? void 0 : fieldSettings.min,
353
+ max: fieldSettings == null ? void 0 : fieldSettings.max,
354
+ arrayFields: buildDefaultEditorFields(
355
+ subFields,
356
+ subFieldSettings,
357
+ customFields
358
+ ),
359
+ defaultItemProps: buildArrayDefaultItemProps(subFields, subFieldSettings),
360
+ getItemSummary(item, index) {
361
+ return getArrayItemSummary(item, index, fieldSettings);
362
+ }
363
+ };
364
+ }
365
+ case "object":
366
+ return {
367
+ type: "object",
368
+ label: field.name,
369
+ objectFields: buildDefaultEditorFields(
370
+ (fieldSettings == null ? void 0 : fieldSettings.subFields) || [],
371
+ (fieldSettings == null ? void 0 : fieldSettings.subFieldSettings) || {},
372
+ customFields
373
+ )
374
+ };
375
+ default:
376
+ return { type: "text", label: field.name };
377
+ }
378
+ };
379
+ var buildDefaultEditorFields = (fields = [], fieldSettings = {}, customFields) => {
380
+ return fields.reduce((acc, field) => {
381
+ acc[field.name] = buildPuckField(
382
+ field,
383
+ fieldSettings[field.name],
384
+ customFields
385
+ );
386
+ return acc;
387
+ }, {});
388
+ };
389
+ var getFieldSettings = (_fields, _fieldSettings, customFields, deep) => {
390
+ const customTypeOptions = getCustomFieldTypeOptions(customFields);
128
391
  return (_fields || []).reduce((fields, field) => {
129
392
  const fieldSettings = {
130
393
  // placeholder: { type: "text", label: "Placeholder" },
131
394
  };
132
395
  const currentFieldSettings = _fieldSettings == null ? void 0 : _fieldSettings[field.name];
133
- switch (field.type) {
396
+ const customFieldDefinition = resolveCustomFieldDefinition(
397
+ field.type,
398
+ customFields
399
+ );
400
+ const customReturnType = resolveCustomFieldReturnType(
401
+ field.type,
402
+ customFields
403
+ );
404
+ const resolvedType = field.type;
405
+ const customSchema = resolveCustomFieldSchema(field.type, customFields);
406
+ const resolvedSubFields = (customSchema == null ? void 0 : customSchema.subFields) || (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || [];
407
+ const resolvedSubFieldSettings = (customSchema == null ? void 0 : customSchema.subFieldSettings) || (currentFieldSettings == null ? void 0 : currentFieldSettings.subFieldSettings) || {};
408
+ const customDefaultValueField = customFieldDefinition && customReturnType ? __spreadProps(__spreadValues({}, customFieldDefinition.field), {
409
+ type: "custom",
410
+ label: customFieldDefinition.field.label || "Default Value"
411
+ }) : null;
412
+ if (customDefaultValueField) {
413
+ fieldSettings.defaultValue = customDefaultValueField;
414
+ }
415
+ switch (resolvedType) {
134
416
  case "text":
135
417
  case "textarea":
136
- fieldSettings.defaultValue = {
137
- type: field.type,
138
- label: "Default Value"
139
- };
418
+ if (!customDefaultValueField) {
419
+ fieldSettings.defaultValue = {
420
+ type: resolvedType,
421
+ label: "Default Value"
422
+ };
423
+ }
140
424
  break;
141
425
  case "number":
142
- fieldSettings.defaultValue = {
143
- type: field.type,
144
- label: "Default Value"
145
- };
426
+ if (!customDefaultValueField) {
427
+ fieldSettings.defaultValue = {
428
+ type: resolvedType,
429
+ label: "Default Value"
430
+ };
431
+ }
146
432
  fieldSettings.min = {
147
- type: field.type,
433
+ type: resolvedType,
148
434
  label: "Minimum Value"
149
435
  };
150
436
  fieldSettings.max = {
151
- type: field.type,
437
+ type: resolvedType,
152
438
  label: "Maximum Value"
153
439
  };
154
440
  fieldSettings.step = {
155
- type: field.type,
441
+ type: resolvedType,
156
442
  label: "Step Size"
157
443
  };
158
444
  break;
159
445
  case "radio":
160
- case "select":
161
- fieldSettings.defaultValue = {
162
- type: "custom",
163
- label: "Default Value",
164
- render: ({ value, onChange, id }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
165
- import_puck.AutoField,
166
- {
167
- field: {
168
- type: field.type,
169
- label: "Default Value",
170
- options: (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || []
171
- },
172
- value,
173
- onChange,
174
- readOnly: false,
175
- id
176
- }
177
- )
178
- };
446
+ case "select": {
447
+ const selectOptions = (currentFieldSettings == null ? void 0 : currentFieldSettings.options) || [];
448
+ if (!customDefaultValueField) {
449
+ fieldSettings.defaultValue = {
450
+ type: "custom",
451
+ label: "Default Value",
452
+ render: ({ value, onChange, id }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
453
+ import_puck.AutoField,
454
+ {
455
+ field: {
456
+ type: resolvedType,
457
+ label: "Default Value",
458
+ options: selectOptions
459
+ },
460
+ value,
461
+ onChange,
462
+ readOnly: false,
463
+ id
464
+ }
465
+ )
466
+ };
467
+ }
179
468
  fieldSettings.options = {
180
469
  type: "array",
181
470
  label: "Options",
@@ -195,21 +484,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
195
484
  }
196
485
  };
197
486
  break;
487
+ }
198
488
  case "array":
199
- fieldSettings.summary = {
200
- type: "select",
201
- label: "Summary Field",
202
- options: [
203
- {
204
- label: "Default Numbering",
205
- value: ""
206
- },
207
- ...((currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) || []).map((f) => ({
208
- label: f.name,
209
- value: f.name
210
- }))
211
- ]
212
- };
213
489
  case "object":
214
490
  fieldSettings.subFields = {
215
491
  type: "array",
@@ -238,7 +514,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
238
514
  {
239
515
  label: "Radio",
240
516
  value: "radio"
241
- }
517
+ },
518
+ ...customTypeOptions
242
519
  ] : [
243
520
  {
244
521
  label: "Text",
@@ -267,7 +544,8 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
267
544
  {
268
545
  label: "Reference",
269
546
  value: "reference"
270
- }
547
+ },
548
+ ...customTypeOptions
271
549
  ]
272
550
  }
273
551
  },
@@ -279,44 +557,99 @@ var getFieldSettings = (_fields, _fieldSettings, deep) => {
279
557
  fieldSettings.subFieldSettings = {
280
558
  type: "object",
281
559
  label: "Sub Field Settings",
282
- objectFields: (currentFieldSettings == null ? void 0 : currentFieldSettings.subFields) ? getFieldSettings(
283
- currentFieldSettings.subFields,
284
- currentFieldSettings.subFieldSettings,
560
+ objectFields: resolvedSubFields ? getFieldSettings(
561
+ resolvedSubFields,
562
+ resolvedSubFieldSettings,
563
+ customFields,
285
564
  true
286
565
  ) : {}
287
566
  };
567
+ if (resolvedType === "array") {
568
+ if (!customDefaultValueField) {
569
+ fieldSettings.defaultValue = {
570
+ type: "array",
571
+ label: "Default Items",
572
+ arrayFields: buildDefaultEditorFields(
573
+ resolvedSubFields,
574
+ resolvedSubFieldSettings,
575
+ customFields
576
+ ),
577
+ defaultItemProps: buildArrayDefaultItemProps(
578
+ resolvedSubFields,
579
+ resolvedSubFieldSettings
580
+ ),
581
+ getItemSummary(item, index) {
582
+ return getArrayItemSummary(item, index, currentFieldSettings);
583
+ }
584
+ };
585
+ }
586
+ fieldSettings.min = {
587
+ type: "number",
588
+ label: "Minimum Items"
589
+ };
590
+ fieldSettings.max = {
591
+ type: "number",
592
+ label: "Maximum Items"
593
+ };
594
+ fieldSettings.summary = {
595
+ type: "select",
596
+ label: "Summary",
597
+ options: [
598
+ {
599
+ label: "Default Numbering / Count",
600
+ value: "count"
601
+ },
602
+ {
603
+ label: "Field",
604
+ value: "field"
605
+ },
606
+ {
607
+ label: "Expression",
608
+ value: "expression"
609
+ }
610
+ ]
611
+ };
612
+ if ((currentFieldSettings == null ? void 0 : currentFieldSettings.summary) === "field") {
613
+ fieldSettings.summaryField = {
614
+ type: "select",
615
+ label: "Summary Field",
616
+ options: [
617
+ {
618
+ label: "Select a field",
619
+ value: ""
620
+ },
621
+ ...resolvedSubFields.filter((subField) => isPrimitiveFieldType(subField.type)).map((subField) => ({
622
+ label: subField.name,
623
+ value: subField.name
624
+ }))
625
+ ]
626
+ };
627
+ }
628
+ if ((currentFieldSettings == null ? void 0 : currentFieldSettings.summary) === "expression") {
629
+ fieldSettings.summaryExpression = {
630
+ type: "text",
631
+ label: "Summary Expression"
632
+ };
633
+ }
634
+ }
288
635
  break;
289
636
  }
637
+ const overriddenFieldSettings = (customFieldDefinition == null ? void 0 : customFieldDefinition.fieldSettingsOverride) ? customFieldDefinition.fieldSettingsOverride({
638
+ fieldName: field.name,
639
+ fieldType: field.type,
640
+ fieldSettings: currentFieldSettings,
641
+ originalFieldSettings: fieldSettings
642
+ }) : fieldSettings;
290
643
  fields[field.name] = {
291
644
  type: "object",
292
645
  label: field.name,
293
- objectFields: fieldSettings
646
+ objectFields: overriddenFieldSettings
294
647
  };
295
648
  return fields;
296
649
  }, {});
297
650
  };
298
651
  var get_field_settings_default = getFieldSettings;
299
652
 
300
- // src/puck/lib/get-settings-by-path.ts
301
- function getFieldSettingsByPath(fieldSettings, path) {
302
- return path.split(".").reduce((o, key) => o ? o[key] : void 0, fieldSettings);
303
- }
304
-
305
- // src/puck/lib/set-prop-by-path.ts
306
- function setPropertyByPath(props, path, value) {
307
- const parts = path.split(".");
308
- const last = parts.pop();
309
- let cur = props;
310
- for (const p of parts) {
311
- if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
312
- cur = cur[p];
313
- }
314
- cur[last] = value;
315
- }
316
-
317
- // src/puck/lib/builder/root-config.tsx
318
- var import_react2 = require("react");
319
-
320
653
  // src/puck/context/useStore.ts
321
654
  var import_react = require("react");
322
655
  var import_zustand = require("zustand");
@@ -337,224 +670,356 @@ var createUseSoftConfig = () => {
337
670
  };
338
671
  var useSoftConfig = createUseSoftConfig();
339
672
 
340
- // src/puck/lib/builder/root-config.tsx
341
- var import_use_debounce = require("use-debounce");
342
- var import_jsx_runtime2 = require("react/jsx-runtime");
343
- var useCustomPuck = (0, import_puck2.createUsePuck)();
344
- var breakVersion = (version) => {
345
- const [major, minor, patch] = version.split(".").map((v) => parseInt(v));
346
- return [major, minor, patch];
347
- };
348
- var updateVersion = (version, increment) => {
349
- let [major, minor, patch] = breakVersion(version);
350
- if (increment === "major") {
351
- major += 1;
352
- minor = 0;
353
- patch = 0;
354
- } else if (increment === "minor") {
355
- minor += 1;
356
- patch = 0;
357
- } else {
358
- patch += 1;
673
+ // src/puck/lib/apply-mapping.ts
674
+ var import_react_fast_compare = __toESM(require("react-fast-compare"));
675
+
676
+ // src/puck/lib/set-prop-by-path.ts
677
+ function setPropertyByPath(props, path, value) {
678
+ const parts = path.split(".");
679
+ const last = parts.pop();
680
+ let cur = props;
681
+ for (const p of parts) {
682
+ if (typeof cur[p] !== "object" || cur[p] === null) cur[p] = {};
683
+ cur = cur[p];
359
684
  }
360
- return `${major}.${minor}.${patch}`;
685
+ cur[last] = value;
686
+ }
687
+
688
+ // src/puck/lib/apply-mapping.ts
689
+ var resolveValueByPath = (source, path) => {
690
+ if (!path) return source;
691
+ const segments = path.split(".");
692
+ const resolveSegments = (current, index) => {
693
+ if (current === null || current === void 0) return void 0;
694
+ if (index >= segments.length) return current;
695
+ const segment = segments[index];
696
+ if (segment.endsWith("[]")) {
697
+ const arrayKey = segment.slice(0, -2);
698
+ const arraySource = arrayKey ? current == null ? void 0 : current[arrayKey] : current;
699
+ const resolvedArray = Array.isArray(arraySource) ? arraySource : Array.isArray(arraySource == null ? void 0 : arraySource.defaultValue) ? arraySource.defaultValue : void 0;
700
+ if (!resolvedArray) return void 0;
701
+ if (index === segments.length - 1) return resolvedArray;
702
+ return resolvedArray.map((item) => resolveSegments(item, index + 1));
703
+ }
704
+ return resolveSegments(current[segment], index + 1);
705
+ };
706
+ return resolveSegments(source, 0);
361
707
  };
362
- var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true) => ({
363
- fields: {
364
- _name: overrides.name || {
365
- type: "text",
366
- label: "Soft Component Name"
367
- },
368
- _category: overrides.categories || {
369
- type: "select",
370
- label: "Category",
371
- options: [
372
- ...Object.keys(config.categories || {}).map((cat) => {
373
- var _a;
374
- return {
375
- label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
376
- value: cat
377
- };
378
- }) || [],
379
- {
380
- label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
381
- value: void 0
708
+ var resolveFieldSettingEntryByPath = (settings, path) => {
709
+ if (!path) return void 0;
710
+ const segments = path.split(".");
711
+ let currentSettings = settings;
712
+ let currentEntry;
713
+ for (const segmentWithArraySuffix of segments) {
714
+ const segment = segmentWithArraySuffix.endsWith("[]") ? segmentWithArraySuffix.slice(0, -2) : segmentWithArraySuffix;
715
+ if (!currentSettings || typeof currentSettings !== "object") {
716
+ return void 0;
717
+ }
718
+ currentEntry = currentSettings[segment];
719
+ if (currentEntry === void 0) {
720
+ return void 0;
721
+ }
722
+ currentSettings = currentEntry == null ? void 0 : currentEntry.subFieldSettings;
723
+ }
724
+ return currentEntry;
725
+ };
726
+ function applyMapping(props, fieldSettings, map, resolveInput = "fieldSettings", options) {
727
+ var _a, _b, _c;
728
+ const newProps = __spreadValues({}, props);
729
+ const sourceProps = (_a = options == null ? void 0 : options.sourceProps) != null ? _a : props;
730
+ const mappedArrayPaths = /* @__PURE__ */ new Set();
731
+ let changed = false;
732
+ const changedArrayBases = /* @__PURE__ */ new Set();
733
+ for (const entry of map) {
734
+ const { from, to, transform } = entry;
735
+ if (!from || !to) continue;
736
+ const fromPaths = Array.isArray(from) ? from : [from];
737
+ const toPaths = Array.isArray(to) ? to : [to];
738
+ const hasInvalidPair = fromPaths.some((fp, idx) => {
739
+ const tp = toPaths[idx] || toPaths[0];
740
+ if (typeof fp !== "string" || typeof tp !== "string") return false;
741
+ return isArrayMappingPath(fp) && !isArrayMappingPath(tp);
742
+ });
743
+ if (hasInvalidPair) continue;
744
+ const inputValues = fromPaths.map((f) => {
745
+ if (resolveInput === "propsFirst") {
746
+ const propVal = resolveValueByPath(sourceProps, f);
747
+ if (propVal !== void 0) return propVal;
748
+ const setting = resolveValueByPath(fieldSettings, f);
749
+ if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
750
+ return setting.defaultValue;
382
751
  }
383
- ]
384
- },
385
- _fields: {
386
- type: "array",
387
- label: "Fields",
388
- defaultItemProps: {
389
- name: "New Field",
390
- type: "text"
391
- },
392
- getItemSummary(item, index) {
393
- return item.name || `Field ${(index || 0) + 1}`;
394
- },
395
- arrayFields: {
396
- name: { type: "text", label: "Name" },
397
- type: {
398
- type: "select",
399
- label: "Type",
400
- options: [
401
- { label: "Text", value: "text" },
402
- { label: "Textarea", value: "textarea" },
403
- { label: "Number", value: "number" },
404
- { label: "Select", value: "select" },
405
- { label: "Radio", value: "radio" },
406
- { label: "Array", value: "array" },
407
- { label: "Object", value: "object" }
408
- // { label: "Reference", value: "reference" },
409
- ]
752
+ return propVal;
753
+ }
754
+ const directValue = resolveValueByPath(fieldSettings, f);
755
+ if (directValue !== void 0) {
756
+ return directValue;
757
+ }
758
+ return resolveFieldSettingEntryByPath(fieldSettings, f);
759
+ });
760
+ const resolvedInputs = inputValues.map(
761
+ (v) => resolveInput === "fieldSettings" ? v == null ? void 0 : v.defaultValue : v
762
+ );
763
+ let result = transform ? transform(resolvedInputs, newProps) : inputValues[0];
764
+ if (resolveInput === "fieldSettings" && !transform && result !== void 0 && typeof result === "object" && result !== null && "defaultValue" in result) {
765
+ result = result.defaultValue;
766
+ }
767
+ const isSingleArrayTarget = toPaths.length === 1 && typeof toPaths[0] === "string" && isArrayMappingPath(toPaths[0]);
768
+ if (isSingleArrayTarget) {
769
+ const toPath = toPaths[0];
770
+ const arrayBase = getArrayBasePath(toPath);
771
+ const subProp = getArrayItemSubPath(toPath) || "";
772
+ if (!arrayBase) continue;
773
+ 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] : [];
774
+ const currentArrayAtPath = resolveValueByPath(newProps, arrayBase);
775
+ const currentArray = Array.isArray(currentArrayAtPath) ? currentArrayAtPath : [];
776
+ const isFromArrayPath = typeof fromPaths[0] === "string" && isArrayMappingPath(fromPaths[0]);
777
+ const sourceArray = isFromArrayPath ? Array.isArray(result) ? result : result !== void 0 ? [result] : [] : Array.isArray(result) ? result : defaultArray.map(() => result);
778
+ let defaults = entry.unmappedArrayItemDefaultValues || entry.defaultOverrides || {};
779
+ if (typeof defaults === "string") {
780
+ try {
781
+ defaults = JSON.parse(defaults);
782
+ } catch (e) {
783
+ defaults = {};
410
784
  }
411
785
  }
786
+ const targetLength = sourceArray.length;
787
+ const constructed = Array.from({ length: targetLength }).map((_, idx) => {
788
+ const mappedValue = sourceArray[idx];
789
+ const defaultItem = defaultArray[idx] && typeof defaultArray[idx] === "object" ? defaultArray[idx] : {};
790
+ const currentItem = currentArray[idx] && typeof currentArray[idx] === "object" ? currentArray[idx] : {};
791
+ const item = __spreadValues(__spreadValues(__spreadValues({}, defaultItem), defaults), currentItem);
792
+ if (subProp && mappedValue !== void 0) {
793
+ setPropertyByPath(item, subProp, mappedValue);
794
+ }
795
+ return item;
796
+ });
797
+ const originalArray = resolveValueByPath(newProps, arrayBase);
798
+ if (!(0, import_react_fast_compare.default)(originalArray, constructed)) {
799
+ setPropertyByPath(newProps, arrayBase, constructed);
800
+ changedArrayBases.add(arrayBase);
801
+ }
802
+ mappedArrayPaths.add(arrayBase);
803
+ } else if (toPaths.length === 1 && Array.isArray(result) && toPaths[0].includes("array")) {
804
+ const toPath = toPaths[0];
805
+ const original = resolveValueByPath(newProps, toPath);
806
+ if (!(0, import_react_fast_compare.default)(original, result)) {
807
+ setPropertyByPath(newProps, toPath, result);
808
+ changed = true;
809
+ }
810
+ } else if (Array.isArray(result) && toPaths.length > 1) {
811
+ result.forEach((val, idx) => {
812
+ if (toPaths[idx]) {
813
+ const orig = resolveValueByPath(newProps, toPaths[idx]);
814
+ if (!(0, import_react_fast_compare.default)(orig, val)) {
815
+ setPropertyByPath(newProps, toPaths[idx], val);
816
+ changed = true;
817
+ }
818
+ }
819
+ });
820
+ } else if (toPaths[0]) {
821
+ const finalValue = result;
822
+ const originalValue = resolveValueByPath(newProps, toPaths[0]);
823
+ if (!(0, import_react_fast_compare.default)(originalValue, finalValue)) {
824
+ setPropertyByPath(newProps, toPaths[0], finalValue);
825
+ changed = true;
826
+ }
412
827
  }
413
- },
414
- resolveFields({ props: data }, { fields, changed }) {
415
- var _a, _b;
416
- if (!(data == null ? void 0 : data._fields) || changed._fields || changed._fieldSettings)
417
- if ((_a = data == null ? void 0 : data._fields) == null ? void 0 : _a.length)
418
- fields._fieldSettings = {
419
- type: "object",
420
- label: "Field Settings",
421
- objectFields: get_field_settings_default(
422
- data._fields || [],
423
- data._fieldSettings || {}
424
- )
425
- };
426
- else delete fields._fieldSettings;
427
- if (showVersionFields && ((_b = data == null ? void 0 : data._versions) == null ? void 0 : _b.length)) {
428
- const latestVersion = data._versions[data._versions.length - 1] || "1.0.0";
429
- delete fields._version;
430
- fields._version = {
828
+ }
829
+ const hasNetArrayChanges = Array.from(changedArrayBases).some(
830
+ (arrayBase) => !(0, import_react_fast_compare.default)(resolveValueByPath(props, arrayBase), resolveValueByPath(newProps, arrayBase))
831
+ );
832
+ return { newProps, mappedArrayPaths, changed: changed || hasNetArrayChanges };
833
+ }
834
+
835
+ // src/puck/lib/builder/root-config.tsx
836
+ var import_jsx_runtime2 = require("react/jsx-runtime");
837
+ var useCustomPuck = (0, import_puck2.createUsePuck)();
838
+ var getSerializableProps = (props) => {
839
+ const cleanProps = {
840
+ id: props.id
841
+ };
842
+ for (const key in props) {
843
+ const value = props[key];
844
+ if (["children", "puck", "editMode"].includes(key)) continue;
845
+ if (value && typeof value === "object" && value.$$typeof) continue;
846
+ if (typeof value === "function") continue;
847
+ cleanProps[key] = value;
848
+ }
849
+ return cleanProps;
850
+ };
851
+ var builderRootConfig = (config, overrides, editingComponent, showVersionFields = true, customFields) => {
852
+ const customTypeOptions = getCustomFieldTypeOptions(customFields);
853
+ return {
854
+ fields: __spreadValues({
855
+ _name: overrides.name || {
856
+ type: "text",
857
+ label: "Soft Component Name"
858
+ },
859
+ _category: overrides.categories || {
431
860
  type: "select",
432
- label: "Version",
861
+ label: "Category",
433
862
  options: [
434
- ...data._versions.map((v) => ({ label: v, value: v })),
435
- {
436
- label: `${updateVersion(latestVersion, "patch")} (Patch)`,
437
- value: updateVersion(latestVersion, "patch")
438
- },
439
- {
440
- label: `${updateVersion(latestVersion, "minor")} (Minor)`,
441
- value: updateVersion(latestVersion, "minor")
442
- },
863
+ ...Object.keys(config.categories || {}).map((cat) => {
864
+ var _a;
865
+ return {
866
+ label: ((_a = config.categories) == null ? void 0 : _a[cat].title) || cat,
867
+ value: cat
868
+ };
869
+ }) || [],
443
870
  {
444
- label: `${updateVersion(latestVersion, "major")} (Major)`,
445
- value: updateVersion(latestVersion, "major")
871
+ label: Object.keys(config.categories || {}).length ? "Other" : "Uncategorized",
872
+ value: void 0
446
873
  }
447
874
  ]
448
- };
449
- } else {
450
- delete fields._version;
451
- }
452
- return fields;
453
- },
454
- resolveData: (props, params) => {
455
- if (overrides.onRootsDataChange)
456
- overrides.onRootsDataChange(props, params);
457
- return {
458
- props,
459
- readOnly: Boolean(editingComponent) ? {
460
- _name: true
461
- } : void 0
462
- };
463
- },
464
- render: (props) => {
465
- const fieldSettings = props == null ? void 0 : props._fieldSettings;
466
- const data = useCustomPuck((s) => s.appState.data);
467
- const dispatch = useCustomPuck((s) => s.dispatch);
468
- const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
469
- const setVersion = useSoftConfig((s) => s.builder.setVersion);
470
- const state = useSoftConfig((s) => s.state);
471
- const [debouncedFieldSettings] = (0, import_use_debounce.useDebounce)(fieldSettings, 500);
472
- (0, import_react2.useEffect)(() => {
473
- if (!debouncedFieldSettings || Object.keys(debouncedFieldSettings).length === 0) return;
474
- (0, import_puck2.walkTree)(
475
- data,
476
- {
477
- components: config.components
875
+ },
876
+ _fields: {
877
+ type: "array",
878
+ label: "Fields",
879
+ defaultItemProps: {
880
+ name: "New Field",
881
+ type: "text"
478
882
  },
479
- (content) => content.map((child) => {
480
- var _a;
481
- const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
482
- if (map.length) {
483
- map.forEach(({ from, to, transform }) => {
484
- if (!from || !to) return;
485
- const fromPaths = Array.isArray(from) ? from : [from];
486
- const toPaths = Array.isArray(to) ? to : [to];
487
- const inputValues = fromPaths.map(
488
- (f) => getFieldSettingsByPath(props._fieldSettings || {}, f)
489
- );
490
- let value = transform ? transform(
491
- inputValues.map((v) => v == null ? void 0 : v.defaultValue),
492
- child.props
493
- ) : inputValues[0];
494
- if (Array.isArray(value)) {
495
- value.forEach((val, i) => {
496
- if (toPaths[i]) {
497
- const originalValue = getFieldSettingsByPath(
498
- child.props,
499
- toPaths[i]
500
- );
501
- if (originalValue !== val) {
502
- const itemSelector = getSelectorForId(child.props.id);
503
- if (!itemSelector) return;
504
- setPropertyByPath(child.props, toPaths[i], val);
505
- dispatch({
506
- type: "replace",
507
- data: child,
508
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
509
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
510
- });
511
- }
512
- }
513
- });
514
- } else if (toPaths[0]) {
515
- const setting = getFieldSettingsByPath(
516
- debouncedFieldSettings,
517
- fromPaths.length === 1 ? fromPaths[0] : fromPaths.join(".")
518
- );
519
- const defaultValue = setting == null ? void 0 : setting.defaultValue;
520
- const originalValue = getFieldSettingsByPath(
521
- child.props,
522
- toPaths[0]
523
- );
524
- const finalValue = transform !== void 0 && value !== void 0 ? value : defaultValue !== void 0 ? defaultValue : value;
525
- if (originalValue !== finalValue) {
526
- const itemSelector = getSelectorForId(child.props.id);
527
- if (!itemSelector) return;
528
- setPropertyByPath(child.props, toPaths[0], finalValue);
529
- dispatch({
530
- type: "replace",
531
- data: child,
532
- destinationIndex: itemSelector == null ? void 0 : itemSelector.index,
533
- destinationZone: itemSelector == null ? void 0 : itemSelector.zone
534
- });
535
- }
536
- }
537
- });
883
+ getItemSummary(item, index) {
884
+ return item.name || `Field ${(index || 0) + 1}`;
885
+ },
886
+ arrayFields: {
887
+ name: { type: "text", label: "Name" },
888
+ type: {
889
+ type: "select",
890
+ label: "Type",
891
+ options: [
892
+ { label: "Text", value: "text" },
893
+ { label: "Textarea", value: "textarea" },
894
+ { label: "Number", value: "number" },
895
+ { label: "Select", value: "select" },
896
+ { label: "Radio", value: "radio" },
897
+ { label: "Array", value: "array" },
898
+ { label: "Object", value: "object" },
899
+ // { label: "Reference", value: "reference" },
900
+ ...customTypeOptions
901
+ ]
538
902
  }
539
- return child;
540
- })
541
- );
542
- }, [debouncedFieldSettings, data, dispatch, getSelectorForId, props._fieldSettings]);
543
- (0, import_react2.useEffect)(() => {
544
- var _a;
545
- if (state !== "remodeling") return;
546
- if (!(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
547
- const currentVersion = props == null ? void 0 : props._version;
548
- if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
549
- setVersion(props._name, currentVersion, props, dispatch);
903
+ }
550
904
  }
551
- }, [props == null ? void 0 : props._version]);
552
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: props.children });
553
- }
554
- });
905
+ }, overrides.additionalRootFields || {}),
906
+ resolveFields({ props: data }, { fields, changed }) {
907
+ const newFields = __spreadValues({}, fields);
908
+ const rootFields = Array.isArray(
909
+ data == null ? void 0 : data._fields
910
+ ) ? (data == null ? void 0 : data._fields) || [] : [];
911
+ const rootFieldSettings = (data == null ? void 0 : data._fieldSettings) || {};
912
+ if (changed._fields || changed._fieldSettings) {
913
+ if (rootFields.length) {
914
+ newFields._fieldSettings = {
915
+ type: "object",
916
+ label: "Field Settings",
917
+ objectFields: get_field_settings_default(
918
+ rootFields,
919
+ rootFieldSettings,
920
+ customFields
921
+ )
922
+ };
923
+ } else {
924
+ delete newFields._fieldSettings;
925
+ }
926
+ }
927
+ return newFields;
928
+ },
929
+ // resolveData: (props, params) => {
930
+ // if (overrides.resolveRootData) {
931
+ // return overrides.resolveRootData(props, params, { editingComponent });
932
+ // }
933
+ // const result: {
934
+ // props: RootData<AsFieldProps<WithChildren<BuilderRootConfig>>>;
935
+ // readOnly: Readonly<Record<string, boolean>> | undefined;
936
+ // } = {
937
+ // props,
938
+ // readOnly: undefined,
939
+ // };
940
+ // return result;
941
+ // },
942
+ render: (props) => {
943
+ const fieldSettings = props == null ? void 0 : props._fieldSettings;
944
+ const data = useCustomPuck((s) => s.appState.data);
945
+ const dispatch = useCustomPuck((s) => s.dispatch);
946
+ const getSelectorForId = useCustomPuck((s) => s.getSelectorForId);
947
+ const setVersion = useSoftConfig((s) => s.builder.setVersion);
948
+ const state = useSoftConfig((s) => s.state);
949
+ (0, import_react2.useEffect)(() => {
950
+ if (!fieldSettings || Object.keys(fieldSettings).length === 0) return;
951
+ const replacements = [];
952
+ (0, import_puck2.walkTree)(
953
+ {
954
+ content: (data == null ? void 0 : data.content) || [],
955
+ root: (data == null ? void 0 : data.root) || {}
956
+ },
957
+ {
958
+ components: config.components
959
+ },
960
+ (content) => content.map((child) => {
961
+ var _a;
962
+ const map = ((_a = child.props) == null ? void 0 : _a._map) || [];
963
+ if (!map.length) return child;
964
+ const cleanProps = getSerializableProps(child.props);
965
+ const { newProps, changed } = applyMapping(
966
+ cleanProps,
967
+ fieldSettings,
968
+ map,
969
+ "fieldSettings"
970
+ );
971
+ if (!changed || (0, import_react_fast_compare2.default)(cleanProps, newProps)) return child;
972
+ replacements.push({
973
+ id: child.props.id,
974
+ data: __spreadProps(__spreadValues({}, child), { props: newProps })
975
+ });
976
+ return child;
977
+ })
978
+ );
979
+ if (!replacements.length) return;
980
+ replacements.forEach((replacement) => {
981
+ const itemSelector = getSelectorForId(replacement.id);
982
+ if (!itemSelector) return;
983
+ dispatch({
984
+ type: "replace",
985
+ data: replacement.data,
986
+ destinationIndex: itemSelector.index,
987
+ destinationZone: itemSelector.zone
988
+ });
989
+ });
990
+ }, [fieldSettings, data, dispatch, getSelectorForId]);
991
+ (0, import_react2.useEffect)(() => {
992
+ var _a;
993
+ if (state !== "remodeling" || !(props == null ? void 0 : props._version) || !(props == null ? void 0 : props._name)) return;
994
+ const currentVersion = props._version;
995
+ if (((_a = props._versions) == null ? void 0 : _a.includes(currentVersion)) && props._versions.length > 1) {
996
+ setVersion(props._name, currentVersion, props, dispatch);
997
+ }
998
+ }, [props == null ? void 0 : props._version]);
999
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: props.children });
1000
+ }
1001
+ };
1002
+ };
555
1003
 
556
1004
  // src/puck/lib/builder/generate-field-options.ts
557
- function generateFieldOptions(fields, selectedFields, prefix = "") {
1005
+ var hasArrayMappingPath = (value) => value.includes("[]");
1006
+ var isBareArrayPath = (value) => !hasArrayMappingPath(value) && !value.includes(".");
1007
+ function filterToOptionsForFrom(fromPath, toOptions) {
1008
+ if (!fromPath) return toOptions;
1009
+ const fromHasArrayMapping = hasArrayMappingPath(fromPath);
1010
+ const fromIsBareArray = isBareArrayPath(fromPath);
1011
+ return toOptions.filter((option) => {
1012
+ const optionHasArrayMapping = hasArrayMappingPath(option.value);
1013
+ if (fromHasArrayMapping) {
1014
+ return optionHasArrayMapping;
1015
+ }
1016
+ if (fromIsBareArray) {
1017
+ return isBareArrayPath(option.value);
1018
+ }
1019
+ return !optionHasArrayMapping;
1020
+ });
1021
+ }
1022
+ function generateFieldOptions(fields, prefix = "") {
558
1023
  const opts = [];
559
1024
  function recurse(current, prefix2) {
560
1025
  Object.entries(current).forEach(([key, fld]) => {
@@ -562,36 +1027,68 @@ function generateFieldOptions(fields, selectedFields, prefix = "") {
562
1027
  if (key === "_map") return;
563
1028
  if (key === "_slotEnabled") return;
564
1029
  const path = prefix2 ? `${prefix2}.${key}` : key;
565
- if (selectedFields.includes(path)) {
566
- return;
567
- }
568
- opts.push({ label: path, value: path, type: fld.type });
569
1030
  if (fld.type === "object" && fld.objectFields) {
570
1031
  recurse(fld.objectFields, path);
571
- }
572
- if (fld.type === "array" && fld.arrayFields) {
573
- recurse(fld.arrayFields, path);
1032
+ } else if (fld.type === "array" && fld.arrayFields) {
1033
+ recurse(
1034
+ fld.arrayFields,
1035
+ path + "[]"
1036
+ );
1037
+ } else {
1038
+ opts.push({ label: path, value: path, type: fld.type });
574
1039
  }
575
1040
  });
576
1041
  }
577
1042
  recurse(fields, prefix);
578
1043
  return opts;
579
1044
  }
580
- function generateDynamicFieldOptions(_fields, _fieldSettings, prefix = "") {
1045
+ function generateDynamicFieldOptions(_fields, _fieldSettings, customFields, prefix = "") {
581
1046
  const opts = [];
582
- if (!_fields || !_fieldSettings) return opts;
1047
+ if (!_fields) return opts;
583
1048
  function recurse(fields, fieldSettings, currentPrefix) {
584
1049
  fields.forEach((field) => {
585
1050
  var _a;
586
1051
  const settings = fieldSettings[field.name];
1052
+ const customReturnType = resolveCustomFieldReturnType(
1053
+ field.type,
1054
+ customFields
1055
+ );
587
1056
  const path = currentPrefix ? `${currentPrefix}.${field.name}` : field.name;
588
- opts.push({ label: path, value: path, type: field.type });
1057
+ if (customReturnType) {
1058
+ if (customReturnType === "array" || customReturnType === "object") {
1059
+ const customSchema = resolveCustomFieldSchema(field.type, customFields);
1060
+ if (!customSchema) {
1061
+ return;
1062
+ }
1063
+ recurse(
1064
+ customSchema.subFields,
1065
+ customSchema.subFieldSettings,
1066
+ path + (customReturnType === "array" ? "[]" : "")
1067
+ );
1068
+ return;
1069
+ }
1070
+ opts.push({
1071
+ label: path,
1072
+ value: path,
1073
+ type: mapCustomReturnTypeToMappingType(customReturnType)
1074
+ });
1075
+ return;
1076
+ }
1077
+ if (!isBuiltInSoftFieldType(field.type)) {
1078
+ return;
1079
+ }
589
1080
  if ((_a = settings == null ? void 0 : settings.subFields) == null ? void 0 : _a.length) {
590
- recurse(settings.subFields, settings.subFieldSettings || {}, path);
1081
+ recurse(
1082
+ settings.subFields,
1083
+ settings.subFieldSettings || {},
1084
+ path + (field.type === "array" ? "[]" : "")
1085
+ );
1086
+ } else if (field.type !== "array" && field.type !== "object") {
1087
+ opts.push({ label: path, value: path, type: field.type });
591
1088
  }
592
1089
  });
593
1090
  }
594
- recurse(_fields, _fieldSettings, prefix);
1091
+ recurse(_fields, _fieldSettings || {}, prefix);
595
1092
  return opts;
596
1093
  }
597
1094
 
@@ -683,8 +1180,14 @@ var ErrorBoundary = class extends import_react3.Component {
683
1180
 
684
1181
  // src/puck/lib/builder/builder-config.tsx
685
1182
  var import_jsx_runtime4 = require("react/jsx-runtime");
686
- var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents) => ({
687
- root: builderRootConfig(config, overrides, editingComponent, showVersionFields),
1183
+ var builderConfig = (config, overrides, editingComponent, showVersionFields = true, dependents, customFields) => ({
1184
+ root: builderRootConfig(
1185
+ config,
1186
+ overrides,
1187
+ editingComponent,
1188
+ showVersionFields,
1189
+ customFields
1190
+ ),
688
1191
  components: Object.entries(__spreadValues({}, config.components)).reduce(
689
1192
  (acc, [name, component]) => {
690
1193
  const tempComponent = __spreadProps(__spreadValues({}, component), {
@@ -693,6 +1196,7 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
693
1196
  },
694
1197
  resolveFields(data, params) {
695
1198
  return __async(this, null, function* () {
1199
+ var _a2;
696
1200
  let fields = {};
697
1201
  if (!fields._slot) {
698
1202
  const slotFields = Object.entries(params.fields).filter(
@@ -713,8 +1217,8 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
713
1217
  { label: "Select a slot", value: "" },
714
1218
  ...slotFields.filter(
715
1219
  ([fieldName, field]) => {
716
- var _a2;
717
- return field.type === "slot" && !(((_a2 = data.props) == null ? void 0 : _a2._slot) || []).some(
1220
+ var _a3;
1221
+ return field.type === "slot" && !(((_a3 = data.props) == null ? void 0 : _a3._slot) || []).some(
718
1222
  (s) => s.slot === fieldName
719
1223
  );
720
1224
  }
@@ -733,17 +1237,21 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
733
1237
  };
734
1238
  }
735
1239
  const defaultFields = component.resolveFields ? yield component.resolveFields(data, params) : component.fields || {};
736
- if (!fields._map) {
1240
+ if (!fields._map || params.changed._map) {
737
1241
  const rootProps = getRootProps(params.appState);
738
1242
  const fromOptions = generateDynamicFieldOptions(
739
1243
  (rootProps == null ? void 0 : rootProps._fields) || [],
740
- (rootProps == null ? void 0 : rootProps._fieldSettings) || {}
1244
+ (rootProps == null ? void 0 : rootProps._fieldSettings) || {},
1245
+ customFields
741
1246
  );
742
- const toOptions = generateFieldOptions(defaultFields, []);
1247
+ const toOptionsFields = component.resolveFields && ((_a2 = data.props) == null ? void 0 : _a2._map) ? yield component.resolveFields(
1248
+ __spreadProps(__spreadValues({}, data), { props: __spreadProps(__spreadValues({}, data.props), { _map: void 0 }) }),
1249
+ params
1250
+ ) : defaultFields;
1251
+ const toOptions = generateFieldOptions(toOptionsFields);
743
1252
  fields._map = overrides.map ? {
744
1253
  type: "custom",
745
1254
  render: ({ value, onChange, id }) => {
746
- const toOptions2 = generateFieldOptions(defaultFields, []);
747
1255
  const rootProps2 = getRootProps(params.appState);
748
1256
  return overrides.map({
749
1257
  rootProps: rootProps2,
@@ -752,13 +1260,39 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
752
1260
  id,
753
1261
  props: data.props || {},
754
1262
  fromOptions,
755
- toOptions: toOptions2
1263
+ toOptions
1264
+ });
1265
+ }
1266
+ } : (() => {
1267
+ var _a3;
1268
+ const mapEntries = ((_a3 = data.props) == null ? void 0 : _a3._map) || [];
1269
+ const toPaths = mapEntries.flatMap(
1270
+ (entry) => Array.isArray(entry.to) ? entry.to : entry.to ? [entry.to] : []
1271
+ );
1272
+ const toPath = toPaths.find(
1273
+ (path) => typeof path === "string" && isArrayMappingPath(path)
1274
+ );
1275
+ const arrayBaseName = toPath ? getArrayBasePath(toPath) : null;
1276
+ const targetArrayField = arrayBaseName ? defaultFields[arrayBaseName] : null;
1277
+ const mappedSubProps = /* @__PURE__ */ new Set();
1278
+ if (arrayBaseName) {
1279
+ toPaths.forEach((path) => {
1280
+ if (typeof path !== "string") return;
1281
+ if (getArrayBasePath(path) !== arrayBaseName) return;
1282
+ const subProp = getArrayItemSubPath(path);
1283
+ if (subProp) mappedSubProps.add(subProp);
1284
+ });
1285
+ }
1286
+ const defaultValueFields = {};
1287
+ if (targetArrayField && targetArrayField.type === "array" && targetArrayField.arrayFields) {
1288
+ const arrayFields = targetArrayField.arrayFields;
1289
+ Object.entries(arrayFields).forEach(([key, fld]) => {
1290
+ if (mappedSubProps.has(key)) return;
1291
+ if (fld.type === "array" || fld.type === "object" || fld.type === "slot") return;
1292
+ defaultValueFields[key] = __spreadProps(__spreadValues({}, fld), { label: fld.label || key });
756
1293
  });
757
1294
  }
758
- } : {
759
- type: "array",
760
- label: "Dynamic Field Map",
761
- arrayFields: {
1295
+ const baseArrayFields = {
762
1296
  from: {
763
1297
  type: "select",
764
1298
  label: "From",
@@ -781,47 +1315,57 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
781
1315
  }))
782
1316
  ]
783
1317
  }
1318
+ };
1319
+ if (arrayBaseName && Object.keys(defaultValueFields).length > 0) {
1320
+ baseArrayFields.unmappedArrayItemDefaultValues = {
1321
+ type: "object",
1322
+ label: "Default Item Values",
1323
+ objectFields: defaultValueFields
1324
+ };
784
1325
  }
785
- };
1326
+ return {
1327
+ type: "array",
1328
+ label: "Dynamic Field Map",
1329
+ arrayFields: baseArrayFields
1330
+ };
1331
+ })();
786
1332
  }
787
1333
  fields = __spreadValues(__spreadValues({}, fields), defaultFields);
788
1334
  return fields;
789
1335
  });
790
1336
  },
791
1337
  resolveData: ({ props }, { lastData }) => {
792
- var _a2;
793
- const _map = props._map || [];
1338
+ const _map = (props._map || []).map((item) => {
1339
+ const newItem = __spreadValues({}, item);
1340
+ if (typeof newItem.unmappedArrayItemDefaultValues === "string") {
1341
+ try {
1342
+ newItem.unmappedArrayItemDefaultValues = JSON.parse(
1343
+ newItem.unmappedArrayItemDefaultValues
1344
+ );
1345
+ } catch (e) {
1346
+ newItem.unmappedArrayItemDefaultValues = {};
1347
+ }
1348
+ } else if (!newItem.unmappedArrayItemDefaultValues) {
1349
+ newItem.unmappedArrayItemDefaultValues = {};
1350
+ }
1351
+ return newItem;
1352
+ });
794
1353
  const readOnlyFields = _map.flatMap((item) => item.to);
1354
+ const readOnlyArrayBases = readOnlyFields.filter((field) => typeof field === "string").map(getArrayBasePath).filter((base) => base !== null);
795
1355
  if (_map.length) {
796
1356
  return {
797
- props,
798
- readOnly: readOnlyFields.reduce(
1357
+ props: __spreadProps(__spreadValues({}, props), { _map }),
1358
+ readOnly: [
1359
+ ...readOnlyFields.map((f) => String(f)),
1360
+ ...readOnlyArrayBases
1361
+ ].reduce(
799
1362
  (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [field]: true }),
800
1363
  {}
801
1364
  )
802
1365
  };
803
1366
  }
804
- const prevMap = (_a2 = lastData == null ? void 0 : lastData.props) == null ? void 0 : _a2._map;
805
- if (prevMap && prevMap.length === 1) {
806
- const lastField = prevMap[0].to;
807
- if (typeof lastField === "string") {
808
- return {
809
- props,
810
- readOnly: { [lastField]: false }
811
- };
812
- }
813
- if (Array.isArray(lastField)) {
814
- return {
815
- props,
816
- readOnly: lastField.reduce(
817
- (acc2, field) => __spreadProps(__spreadValues({}, acc2), { [String(field)]: false }),
818
- {}
819
- )
820
- };
821
- }
822
- }
823
1367
  return {
824
- props,
1368
+ props: __spreadProps(__spreadValues({}, props), { _map }),
825
1369
  readOnly: {}
826
1370
  };
827
1371
  },
@@ -837,6 +1381,9 @@ var builderConfig = (config, overrides, editingComponent, showVersionFields = tr
837
1381
  categories: config.categories || {}
838
1382
  });
839
1383
 
1384
+ // src/puck/lib/soft-component-constants.ts
1385
+ var TECHNICAL_KEYS = /* @__PURE__ */ new Set(["_map", "_slot", "id", "_version"]);
1386
+
840
1387
  // src/puck/lib/strip-id.ts
841
1388
  var stripIdFromProps = (components, allowedTypes) => {
842
1389
  return components.map((component) => sanitizeComponent(component, allowedTypes));
@@ -860,7 +1407,7 @@ var sanitizeComponent = (component, allowedTypes) => {
860
1407
  var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
861
1408
  if (!content || !Array.isArray(content)) return [];
862
1409
  return content.map((componentProps) => {
863
- var _a, _b, _c;
1410
+ var _a, _b, _c, _d;
864
1411
  const componentConfig = componentConfigs[componentProps.type];
865
1412
  const enabledSlotNames = new Set(
866
1413
  (((_a = componentProps.props) == null ? void 0 : _a._slot) || []).map((s) => s.slot)
@@ -881,7 +1428,27 @@ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
881
1428
  },
882
1429
  {}
883
1430
  ) || {};
884
- const fixedProps = __spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props);
1431
+ const map = ((_b = componentProps.props) == null ? void 0 : _b._map) || [];
1432
+ const mappedPaths = /* @__PURE__ */ new Set();
1433
+ map.forEach((item) => {
1434
+ const to = Array.isArray(item.to) ? item.to : [item.to];
1435
+ to.forEach((path) => {
1436
+ if (path) {
1437
+ if (isArrayMappingPath(path)) {
1438
+ const basePath = getArrayBasePath(path);
1439
+ if (basePath) mappedPaths.add(basePath);
1440
+ } else {
1441
+ mappedPaths.add(path);
1442
+ }
1443
+ }
1444
+ });
1445
+ });
1446
+ const fixedProps = Object.entries(__spreadValues(__spreadValues({}, componentConfig == null ? void 0 : componentConfig.defaultProps), componentProps.props)).reduce((acc, [key, value]) => {
1447
+ if (!TECHNICAL_KEYS.has(key) && !mappedPaths.has(key)) {
1448
+ acc[key] = value;
1449
+ }
1450
+ return acc;
1451
+ }, {});
885
1452
  (componentProps.props._slot || []).forEach(
886
1453
  (s) => {
887
1454
  var _a2;
@@ -895,19 +1462,34 @@ var getSubComponents = (content, componentConfigs, fieldSettings, slots) => {
895
1462
  }
896
1463
  );
897
1464
  const subComponent = {
898
- map: ((_b = componentProps.props) == null ? void 0 : _b._map) || [],
1465
+ map: ((_c = componentProps.props) == null ? void 0 : _c._map) || [],
899
1466
  fixedProps,
900
1467
  type: componentProps.type,
901
1468
  components,
902
- enabledSlots: ((_c = componentProps.props) == null ? void 0 : _c._slot) || []
1469
+ enabledSlots: ((_d = componentProps.props) == null ? void 0 : _d._slot) || []
903
1470
  };
904
1471
  return subComponent;
905
1472
  });
906
1473
  };
907
- var softFieldsToPuckFields = (fields, fieldSettings) => {
1474
+ var softFieldsToPuckFields = (fields, fieldSettings, customFields) => {
908
1475
  return (fields == null ? void 0 : fields.reduce(
909
1476
  (acc, field) => {
910
- var _a, _b, _c, _d, _e, _f, _g, _h;
1477
+ var _a, _b, _c, _d, _e, _f;
1478
+ const customFieldDefinition = resolveCustomFieldDefinition(
1479
+ field.type,
1480
+ customFields
1481
+ );
1482
+ const customReturnType = resolveCustomFieldReturnType(
1483
+ field.type,
1484
+ customFields
1485
+ );
1486
+ if (customFieldDefinition && customReturnType) {
1487
+ acc[field.name] = __spreadProps(__spreadValues({}, customFieldDefinition.field), {
1488
+ type: "custom",
1489
+ label: customFieldDefinition.field.label || field.name
1490
+ });
1491
+ return acc;
1492
+ }
911
1493
  switch (field.type) {
912
1494
  case "text":
913
1495
  case "textarea":
@@ -932,13 +1514,24 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
932
1514
  break;
933
1515
  // TODO: Default item props
934
1516
  case "array":
1517
+ const currentArraySettings = (fieldSettings == null ? void 0 : fieldSettings[field.name]) || {};
935
1518
  acc[field.name] = {
936
1519
  type: field.type,
937
1520
  label: field.name,
1521
+ min: currentArraySettings.min,
1522
+ max: currentArraySettings.max,
938
1523
  arrayFields: softFieldsToPuckFields(
939
- ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
940
- ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {}
941
- )
1524
+ currentArraySettings.subFields || [],
1525
+ currentArraySettings.subFieldSettings || {},
1526
+ customFields
1527
+ ),
1528
+ defaultItemProps: buildArrayDefaultItemProps(
1529
+ currentArraySettings.subFields,
1530
+ currentArraySettings.subFieldSettings
1531
+ ),
1532
+ getItemSummary(item, index) {
1533
+ return getArrayItemSummary(item, index, currentArraySettings);
1534
+ }
942
1535
  };
943
1536
  break;
944
1537
  // TODO: Needs testing to see if it works
@@ -947,8 +1540,9 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
947
1540
  type: field.type,
948
1541
  label: field.name,
949
1542
  objectFields: softFieldsToPuckFields(
950
- ((_g = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _g.subFields) || [],
951
- ((_h = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _h.subFieldSettings) || {}
1543
+ ((_e = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _e.subFields) || [],
1544
+ ((_f = fieldSettings == null ? void 0 : fieldSettings[field.name]) == null ? void 0 : _f.subFieldSettings) || {},
1545
+ customFields
952
1546
  )
953
1547
  };
954
1548
  break;
@@ -960,21 +1554,69 @@ var softFieldsToPuckFields = (fields, fieldSettings) => {
960
1554
  {}
961
1555
  )) || {};
962
1556
  };
963
- var softComponentFromAppState = (appState, configComponents, editedItem, metadata) => {
1557
+ var softComponentFromAppState = (appState, configComponents, editedItem, metadata, customFields) => {
964
1558
  var _a;
965
1559
  const rootProps = ((_a = appState.data.root) == null ? void 0 : _a.props) || {};
966
1560
  const fields = rootProps._fields || [];
967
1561
  const field_settings = rootProps._fieldSettings || {};
1562
+ const normalizedFieldSettings = __spreadValues({}, field_settings);
1563
+ (fields || []).forEach((field) => {
1564
+ const customFieldDefinition = resolveCustomFieldDefinition(
1565
+ field.type,
1566
+ customFields
1567
+ );
1568
+ const customReturnType = resolveCustomFieldReturnType(
1569
+ field.type,
1570
+ customFields
1571
+ );
1572
+ if (!customFieldDefinition || !customReturnType) {
1573
+ return;
1574
+ }
1575
+ const schema = resolveCustomFieldSchema(field.type, customFields);
1576
+ const existingSettings = normalizedFieldSettings[field.name] || {};
1577
+ normalizedFieldSettings[field.name] = __spreadValues(__spreadProps(__spreadValues({}, existingSettings), {
1578
+ customFieldType: field.type,
1579
+ customFieldReturnType: customReturnType
1580
+ }), schema ? {
1581
+ subFields: schema.subFields,
1582
+ subFieldSettings: schema.subFieldSettings
1583
+ } : {});
1584
+ });
1585
+ const builtInRootProps = /* @__PURE__ */ new Set([
1586
+ "_name",
1587
+ "_category",
1588
+ "_version",
1589
+ "_versions",
1590
+ "_fields",
1591
+ "_fieldSettings"
1592
+ ]);
1593
+ const customRootProps = Object.keys(rootProps).filter((key) => key.startsWith("_") && !builtInRootProps.has(key)).reduce(
1594
+ (acc, key) => {
1595
+ acc[key] = rootProps[key];
1596
+ return acc;
1597
+ },
1598
+ {}
1599
+ );
968
1600
  const slots = {};
969
1601
  const components = getSubComponents(
970
1602
  [editedItem],
971
1603
  configComponents,
972
- field_settings,
1604
+ normalizedFieldSettings,
973
1605
  slots
974
1606
  );
975
- const defaultProps = __spreadValues(__spreadValues({}, Object.keys(field_settings).reduce(
1607
+ const defaultProps = __spreadValues(__spreadValues({}, Object.keys(normalizedFieldSettings).reduce(
976
1608
  (acc, field) => {
977
- acc[field] = field_settings[field].defaultValue;
1609
+ var _a2;
1610
+ const fieldDefinition = (fields || []).find((item) => item.name === field);
1611
+ const customFieldReturnType = (_a2 = normalizedFieldSettings[field]) == null ? void 0 : _a2.customFieldReturnType;
1612
+ if ((fieldDefinition == null ? void 0 : fieldDefinition.type) === "array" || customFieldReturnType === "array") {
1613
+ acc[field] = normalizedFieldSettings[field].defaultValue !== void 0 ? normalizedFieldSettings[field].defaultValue : buildArrayDefaultValue(
1614
+ normalizedFieldSettings[field].subFields,
1615
+ normalizedFieldSettings[field].subFieldSettings
1616
+ );
1617
+ return acc;
1618
+ }
1619
+ acc[field] = normalizedFieldSettings[field].defaultValue;
978
1620
  return acc;
979
1621
  },
980
1622
  {}
@@ -983,12 +1625,13 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
983
1625
  {
984
1626
  name: metadata.name,
985
1627
  category: metadata.category,
986
- fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, field_settings)), Object.keys(slots).reduce((acc, slot) => {
1628
+ fields: __spreadValues(__spreadValues({}, softFieldsToPuckFields(fields, normalizedFieldSettings, customFields)), Object.keys(slots).reduce((acc, slot) => {
987
1629
  acc[slot] = { type: "slot", label: slot };
988
1630
  return acc;
989
1631
  }, {})),
990
- fieldSettings: field_settings,
1632
+ fieldSettings: normalizedFieldSettings,
991
1633
  defaultProps,
1634
+ rootProps: customRootProps,
992
1635
  components,
993
1636
  slots
994
1637
  },
@@ -1000,17 +1643,67 @@ var softComponentFromAppState = (appState, configComponents, editedItem, metadat
1000
1643
  var import_uuid = require("uuid");
1001
1644
  var generateId = (type) => type ? `${type}-${(0, import_uuid.v4)()}` : (0, import_uuid.v4)();
1002
1645
 
1646
+ // src/puck/lib/component-key.ts
1647
+ var defaultToCamelCase = (value) => {
1648
+ const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1649
+ if (tokens.length === 0) return "";
1650
+ const [first, ...rest] = tokens;
1651
+ return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1652
+ };
1653
+ var createComponentKeyFromName = (displayName, overrides, context) => {
1654
+ const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1655
+ return key.trim();
1656
+ };
1657
+ var getComponentNameFromKey = (key, overrides) => {
1658
+ if (overrides == null ? void 0 : overrides.componentKeyToName) {
1659
+ return overrides.componentKeyToName(key);
1660
+ }
1661
+ return key;
1662
+ };
1663
+
1003
1664
  // src/puck/lib/soft-component-to-appstate.ts
1004
- var puckFieldsToSoftFields = (fields, slots) => {
1665
+ var mergeFieldSettings = (generated = {}, persisted = {}) => {
1666
+ return Object.entries(persisted).reduce((acc, [fieldName, value]) => {
1667
+ const current = acc[fieldName] || {};
1668
+ acc[fieldName] = __spreadProps(__spreadValues(__spreadValues({}, current), value), {
1669
+ subFieldSettings: current.subFieldSettings || (value == null ? void 0 : value.subFieldSettings) ? mergeFieldSettings(
1670
+ current.subFieldSettings || {},
1671
+ (value == null ? void 0 : value.subFieldSettings) || {}
1672
+ ) : void 0
1673
+ });
1674
+ return acc;
1675
+ }, __spreadValues({}, generated));
1676
+ };
1677
+ var puckFieldsToSoftFields = (fields, slots, persistedFieldSettings = {}, customFields) => {
1005
1678
  const softFields = [];
1006
1679
  const fieldSettings = {};
1007
1680
  Object.entries(fields).forEach(([fieldName, field]) => {
1681
+ var _a;
1682
+ const persistedSettings = persistedFieldSettings == null ? void 0 : persistedFieldSettings[fieldName];
1683
+ const fieldWithMeta = field;
1684
+ const customFieldType = fieldWithMeta.customFieldType || (persistedSettings == null ? void 0 : persistedSettings.customFieldType);
1685
+ 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);
1008
1686
  if (slots.has(fieldName)) {
1009
1687
  return;
1010
1688
  }
1011
1689
  if (fieldName === "_version") {
1012
1690
  return;
1013
1691
  }
1692
+ if (field.type === "custom" && customFieldType) {
1693
+ softFields.push({ name: fieldName, type: customFieldType });
1694
+ const customSchema = resolveCustomFieldSchema(customFieldType, customFields);
1695
+ fieldSettings[fieldName] = __spreadValues(__spreadProps(__spreadValues({}, persistedSettings || {}), {
1696
+ customFieldType,
1697
+ customFieldReturnType
1698
+ }), customSchema ? {
1699
+ subFields: customSchema.subFields,
1700
+ subFieldSettings: customSchema.subFieldSettings
1701
+ } : {});
1702
+ if (!Object.prototype.hasOwnProperty.call(fieldSettings[fieldName], "defaultValue")) {
1703
+ fieldSettings[fieldName].defaultValue = void 0;
1704
+ }
1705
+ return;
1706
+ }
1014
1707
  switch (field.type) {
1015
1708
  case "text":
1016
1709
  case "textarea":
@@ -1028,67 +1721,81 @@ var puckFieldsToSoftFields = (fields, slots) => {
1028
1721
  case "radio":
1029
1722
  softFields.push({ name: fieldName, type: field.type });
1030
1723
  fieldSettings[fieldName] = {
1031
- options: field.options || []
1724
+ options: field.options ? [...field.options] : []
1032
1725
  };
1033
1726
  break;
1034
1727
  case "array":
1035
1728
  softFields.push({ name: fieldName, type: "array" });
1036
1729
  const arrayFieldsResult = puckFieldsToSoftFields(
1037
1730
  field.arrayFields || {},
1038
- /* @__PURE__ */ new Set()
1731
+ /* @__PURE__ */ new Set(),
1732
+ persistedSettings == null ? void 0 : persistedSettings.subFieldSettings,
1733
+ customFields
1039
1734
  );
1040
- fieldSettings[fieldName] = {
1735
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, persistedSettings || {}), {
1041
1736
  subFields: arrayFieldsResult.fields,
1042
1737
  subFieldSettings: arrayFieldsResult.fieldSettings
1043
- };
1738
+ });
1044
1739
  break;
1045
1740
  case "object":
1046
1741
  softFields.push({ name: fieldName, type: "object" });
1047
1742
  const objectFieldsResult = puckFieldsToSoftFields(
1048
1743
  field.objectFields || {},
1049
- /* @__PURE__ */ new Set()
1744
+ /* @__PURE__ */ new Set(),
1745
+ persistedSettings == null ? void 0 : persistedSettings.subFieldSettings,
1746
+ customFields
1050
1747
  );
1051
- fieldSettings[fieldName] = {
1748
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, persistedSettings || {}), {
1052
1749
  subFields: objectFieldsResult.fields,
1053
1750
  subFieldSettings: objectFieldsResult.fieldSettings
1054
- };
1751
+ });
1055
1752
  break;
1056
1753
  default:
1057
1754
  softFields.push({ name: fieldName, type: "text" });
1058
1755
  }
1059
- if (fieldSettings[fieldName]) {
1060
- fieldSettings[fieldName].defaultValue = void 0;
1061
- } else {
1062
- fieldSettings[fieldName] = { defaultValue: void 0 };
1063
- }
1756
+ fieldSettings[fieldName] = __spreadProps(__spreadValues({}, fieldSettings[fieldName] || persistedSettings || {}), {
1757
+ defaultValue: Object.prototype.hasOwnProperty.call(
1758
+ fieldSettings[fieldName] || persistedSettings || {},
1759
+ "defaultValue"
1760
+ ) ? (fieldSettings[fieldName] || persistedSettings || {}).defaultValue : void 0
1761
+ });
1064
1762
  });
1065
1763
  return { fields: softFields, fieldSettings };
1066
1764
  };
1067
1765
  var reconstructComponents = (subComponents, componentConfigs, softComponentProps) => {
1068
1766
  return subComponents.map((subComponent) => {
1069
- var _a;
1070
- const props = __spreadValues({}, subComponent.fixedProps);
1071
- (_a = subComponent.map) == null ? void 0 : _a.forEach((mapItem, i) => {
1072
- var _a2;
1073
- const { from, to, transform } = mapItem || {};
1074
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1075
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1076
- const inputs = fromPaths.map(
1077
- (path) => getFieldSettingsByPath(softComponentProps || {}, path)
1078
- );
1079
- const runner = transform;
1080
- const result = runner ? runner(inputs, softComponentProps) : inputs[0];
1081
- if (Array.isArray(result)) {
1082
- result.forEach((val, idx) => {
1083
- if (toPaths[idx]) setPropertyByPath(props, toPaths[idx], val);
1767
+ const componentConfig = componentConfigs[subComponent.type];
1768
+ const props = __spreadProps(__spreadValues({}, subComponent.fixedProps), {
1769
+ _map: subComponent.map
1770
+ });
1771
+ const arrayDefaults = (subComponent.map || []).reduce(
1772
+ (acc, mapEntry) => {
1773
+ const toPaths = Array.isArray(mapEntry.to) ? mapEntry.to : [mapEntry.to];
1774
+ toPaths.forEach((path) => {
1775
+ var _a;
1776
+ if (typeof path !== "string" || !isArrayMappingPath(path)) return;
1777
+ const arrayBase = getArrayBasePath(path);
1778
+ if (!arrayBase || acc[arrayBase]) return;
1779
+ const defaultValue = (_a = componentConfig == null ? void 0 : componentConfig.defaultProps) == null ? void 0 : _a[arrayBase];
1780
+ if (Array.isArray(defaultValue)) acc[arrayBase] = defaultValue;
1084
1781
  });
1085
- } else {
1086
- toPaths.forEach((toPath) => setPropertyByPath(props, toPath, result));
1087
- }
1088
- if (transform && ((_a2 = props._map) == null ? void 0 : _a2[i])) {
1089
- props._map[i].transform = transform;
1782
+ return acc;
1783
+ },
1784
+ {}
1785
+ );
1786
+ const sourceProps = __spreadValues(__spreadValues(__spreadValues({}, (componentConfig == null ? void 0 : componentConfig.defaultProps) || {}), softComponentProps), props);
1787
+ const { newProps } = applyMapping(
1788
+ props,
1789
+ {},
1790
+ // fieldSettings not needed for "propsFirst" mode as it resolves from propsFirst
1791
+ subComponent.map || [],
1792
+ "propsFirst",
1793
+ {
1794
+ sourceProps,
1795
+ arrayDefaults
1090
1796
  }
1091
- });
1797
+ );
1798
+ Object.assign(props, newProps);
1092
1799
  if (subComponent.enabledSlots.length > 0) {
1093
1800
  props._slot = subComponent.enabledSlots;
1094
1801
  subComponent.enabledSlots.forEach(({ slot, name }) => {
@@ -1118,25 +1825,45 @@ var reconstructComponents = (subComponents, componentConfigs, softComponentProps
1118
1825
  return componentData;
1119
1826
  });
1120
1827
  };
1121
- var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, displayName, category) => {
1828
+ var softComponentToAppState = (softComponent, componentName, version, versions, componentProps, componentConfigs, overrides, displayName, category, customFields) => {
1122
1829
  const slots = new Set(Object.keys(softComponent.slots));
1123
1830
  const { fields, fieldSettings } = puckFieldsToSoftFields(
1124
1831
  softComponent.fields,
1125
- slots
1832
+ slots,
1833
+ softComponent.fieldSettings,
1834
+ customFields
1126
1835
  );
1836
+ const mergedFieldSettings = mergeFieldSettings(
1837
+ fieldSettings,
1838
+ softComponent.fieldSettings || {}
1839
+ ) || {};
1127
1840
  Object.entries(softComponent.defaultProps).forEach(([key, value]) => {
1128
- if (fieldSettings && fieldSettings[key] && !slots.has(key)) {
1129
- fieldSettings[key].defaultValue = value;
1841
+ if (mergedFieldSettings && mergedFieldSettings[key] && !slots.has(key)) {
1842
+ mergedFieldSettings[key].defaultValue = value;
1130
1843
  }
1131
1844
  });
1132
- const rootProps = {
1133
- _name: displayName || componentName,
1845
+ (fields || []).forEach((field) => {
1846
+ if (field.type !== "array" || slots.has(field.name)) return;
1847
+ const settings = mergedFieldSettings[field.name] || {};
1848
+ if (settings.defaultValue === void 0) {
1849
+ settings.defaultValue = buildArrayDefaultValue(
1850
+ settings.subFields,
1851
+ settings.subFieldSettings
1852
+ );
1853
+ }
1854
+ mergedFieldSettings[field.name] = settings;
1855
+ });
1856
+ let rootProps = __spreadValues({
1857
+ _name: displayName || getComponentNameFromKey(componentName, overrides),
1134
1858
  _category: category,
1135
1859
  _version: version,
1136
1860
  _versions: versions,
1137
1861
  _fields: fields,
1138
- _fieldSettings: fieldSettings
1139
- };
1862
+ _fieldSettings: mergedFieldSettings
1863
+ }, softComponent.rootProps || {});
1864
+ if (overrides.onRemodel) {
1865
+ rootProps = __spreadValues(__spreadValues({}, rootProps), overrides.onRemodel(componentName));
1866
+ }
1140
1867
  const content = reconstructComponents(
1141
1868
  softComponent.components,
1142
1869
  componentConfigs,
@@ -1158,114 +1885,102 @@ var rootZone = "default-zone";
1158
1885
  var rootDroppableId = `${rootAreaId}:${rootZone}`;
1159
1886
 
1160
1887
  // src/puck/components/soft-render/index.tsx
1161
- var import_react4 = require("react");
1162
- var import_uuid2 = require("uuid");
1163
- var import_fast_deep_equal = __toESM(require("fast-deep-equal"));
1888
+ var import_react4 = __toESM(require("react"));
1889
+ var import_react_fast_compare3 = __toESM(require("react-fast-compare"));
1164
1890
  var import_jsx_runtime5 = require("react/jsx-runtime");
1165
- function SoftRender({
1166
- softComponentFields,
1167
- softComponentFieldSettings,
1168
- softSubComponent,
1169
- configComponents,
1170
- props,
1171
- depth = 0
1172
- }) {
1173
- const _a = props, { id, puck, editMode } = _a, rest = __objRest(_a, ["id", "puck", "editMode"]);
1174
- const mapCacheRef = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
1175
- const prevPropsRef = (0, import_react4.useRef)(null);
1176
- if (!(0, import_fast_deep_equal.default)(prevPropsRef.current, props)) {
1177
- mapCacheRef.current.clear();
1178
- prevPropsRef.current = props;
1179
- }
1180
- const subComponentRootProps = (0, import_react4.useMemo)(
1181
- () => Object.entries(softComponentFields || {}).filter(([_, field]) => field.type !== "slot").reduce(
1182
- (acc, [fieldKey]) => {
1183
- acc[fieldKey] = props[fieldKey];
1184
- return acc;
1185
- },
1186
- {}
1187
- ),
1188
- [softComponentFields, props]
1891
+ function isPlainObject(val) {
1892
+ if (typeof val !== "object" || val === null) return false;
1893
+ if (import_react4.default.isValidElement(val)) return false;
1894
+ if ("$$typeof" in val) return false;
1895
+ const proto = Object.getPrototypeOf(val);
1896
+ return proto === Object.prototype || proto === null;
1897
+ }
1898
+ function cloneData(value) {
1899
+ if (value === null || value === void 0) return value;
1900
+ if (typeof value === "function") return value;
1901
+ if (Array.isArray(value)) return value.map(cloneData);
1902
+ if (!isPlainObject(value)) return value;
1903
+ return Object.fromEntries(
1904
+ Object.entries(value).map(([k, v]) => [k, cloneData(v)])
1189
1905
  );
1190
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: (softSubComponent == null ? void 0 : softSubComponent.length) > 0 && softSubComponent.map((subComponent, index) => {
1191
- var _a2;
1906
+ }
1907
+ var SubComponentRenderer = (0, import_react4.memo)(
1908
+ ({
1909
+ subComponent,
1910
+ softComponentFields,
1911
+ softComponentFieldSettings,
1912
+ configComponents,
1913
+ props,
1914
+ depth,
1915
+ index
1916
+ }) => {
1917
+ const { id, puck, editMode } = props;
1192
1918
  const componentConfig = configComponents[subComponent == null ? void 0 : subComponent.type];
1193
- if (!componentConfig) return null;
1194
- const resolvedProps = subComponent.fixedProps || {};
1195
1919
  const stableId = (0, import_react4.useMemo)(
1196
- () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-${(0, import_uuid2.v4)()}`,
1197
- [id, depth, subComponent.type]
1920
+ () => depth === 0 ? id : `${subComponent.type}-${id}-d${depth}-i${index}`,
1921
+ [id, depth, subComponent.type, index]
1198
1922
  );
1199
- if ((_a2 = subComponent.map) == null ? void 0 : _a2.length) {
1200
- subComponent.map.forEach((mapItem) => {
1201
- const { from, to, transform } = mapItem || {};
1202
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1203
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1204
- const inputValues = fromPaths.map((f) => {
1205
- const propValue = getFieldSettingsByPath(props || {}, f);
1206
- if (propValue !== void 0) return propValue;
1207
- const setting = getFieldSettingsByPath(
1208
- softComponentFieldSettings || {},
1209
- f
1210
- );
1211
- if (setting && Object.prototype.hasOwnProperty.call(setting, "defaultValue")) {
1212
- return setting.defaultValue;
1923
+ const finalProps = (0, import_react4.useMemo)(() => {
1924
+ var _a;
1925
+ if (!componentConfig) return {};
1926
+ const clonedProps = cloneData(subComponent.fixedProps || {});
1927
+ if ((_a = subComponent.map) == null ? void 0 : _a.length) {
1928
+ const mergedInput = __spreadValues(__spreadValues({}, clonedProps), props);
1929
+ const { newProps } = applyMapping(
1930
+ mergedInput,
1931
+ softComponentFieldSettings || {},
1932
+ subComponent.map,
1933
+ "propsFirst"
1934
+ );
1935
+ const parentKeys = new Set(Object.keys(props));
1936
+ for (const [key, value] of Object.entries(newProps)) {
1937
+ if (!parentKeys.has(key) || key in clonedProps) {
1938
+ clonedProps[key] = value;
1213
1939
  }
1214
- return propValue;
1215
- });
1216
- const cacheKey = inputValues.map((v, i) => `${i}:${typeof v === "object" ? JSON.stringify(v) : v}`).join("|");
1217
- let result = mapCacheRef.current.get(cacheKey);
1218
- if (!result) {
1219
- const runner = transform;
1220
- result = runner ? runner(inputValues, props) : inputValues[0];
1221
- mapCacheRef.current.set(cacheKey, result);
1222
1940
  }
1223
- if (Array.isArray(result)) {
1224
- result.forEach(
1225
- (val, i) => toPaths[i] && setPropertyByPath(resolvedProps, toPaths[i], val)
1226
- );
1227
- } else if (toPaths[0]) {
1228
- setPropertyByPath(resolvedProps, toPaths[0], result);
1229
- }
1230
- });
1231
- }
1232
- Object.entries(componentConfig.fields || {}).forEach(
1233
- ([slotKey, field]) => {
1234
- var _a3, _b;
1235
- if (field.type === "slot") {
1236
- const enabledSlot = (_a3 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a3.find(
1941
+ }
1942
+ Object.entries(componentConfig.fields || {}).forEach(
1943
+ ([slotKey, field]) => {
1944
+ var _a2, _b, _c;
1945
+ if (field.type !== "slot") return;
1946
+ const enabledSlot = (_a2 = subComponent == null ? void 0 : subComponent.enabledSlots) == null ? void 0 : _a2.find(
1237
1947
  (s) => s.slot === slotKey
1238
1948
  );
1239
1949
  if (enabledSlot) {
1240
1950
  const slotName = enabledSlot.name || `${(_b = subComponent.fixedProps) == null ? void 0 : _b.id}-${slotKey}`;
1241
- resolvedProps[slotKey] = (0, import_react4.useMemo)(
1242
- () => rest[slotName] || (() => null),
1243
- [slotName, rest[slotName]]
1244
- );
1951
+ clonedProps[slotKey] = (_c = props[slotName]) != null ? _c : (() => null);
1245
1952
  } else {
1246
- resolvedProps[slotKey] = (0, import_react4.useMemo)(() => {
1247
- return ({
1248
- className,
1249
- style
1250
- }) => {
1251
- var _a4, _b2;
1252
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1253
- SoftRender,
1254
- {
1255
- softComponentFields,
1256
- softSubComponent: (_b2 = (_a4 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a4[slotKey]) != null ? _b2 : [],
1257
- configComponents,
1258
- props,
1259
- depth: depth + 1
1260
- },
1261
- slotKey
1262
- ) });
1263
- };
1264
- }, [slotKey, subComponentRootProps]);
1953
+ clonedProps[slotKey] = ({
1954
+ className,
1955
+ style
1956
+ }) => {
1957
+ var _a3, _b2;
1958
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1959
+ SoftRender,
1960
+ {
1961
+ softComponentFields,
1962
+ softComponentFieldSettings,
1963
+ softSubComponent: (_b2 = (_a3 = subComponent == null ? void 0 : subComponent.components) == null ? void 0 : _a3[slotKey]) != null ? _b2 : [],
1964
+ configComponents,
1965
+ props,
1966
+ depth: depth + 1
1967
+ }
1968
+ ) });
1969
+ };
1265
1970
  }
1266
1971
  }
1267
- }
1268
- );
1972
+ );
1973
+ return clonedProps;
1974
+ }, [
1975
+ componentConfig,
1976
+ subComponent,
1977
+ props,
1978
+ softComponentFields,
1979
+ softComponentFieldSettings,
1980
+ configComponents,
1981
+ depth
1982
+ ]);
1983
+ if (!componentConfig) return null;
1269
1984
  const ComponentRender = componentConfig.render;
1270
1985
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ErrorBoundary, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1271
1986
  ComponentRender,
@@ -1273,14 +1988,76 @@ function SoftRender({
1273
1988
  id: stableId,
1274
1989
  editMode,
1275
1990
  puck
1276
- }, resolvedProps)
1277
- ) }, index);
1278
- }) });
1279
- }
1991
+ }, finalProps)
1992
+ ) });
1993
+ },
1994
+ // Custom comparator for SubComponentRenderer.
1995
+ //
1996
+ // Uses deep equality on subComponent (it may be a new reference even when
1997
+ // semantically unchanged if the parent SoftRender array is reconstructed)
1998
+ // and on props (the primary driver of field-mapping changes).
1999
+ // configComponents and softComponentFields are treated as stable config
2000
+ // references — reference equality is intentional and fast here.
2001
+ (prev, next) => prev.depth === next.depth && prev.index === next.index && prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && (0, import_react_fast_compare3.default)(prev.props, next.props) && (0, import_react_fast_compare3.default)(prev.subComponent, next.subComponent) && (0, import_react_fast_compare3.default)(prev.softComponentFieldSettings, next.softComponentFieldSettings)
2002
+ );
2003
+ SubComponentRenderer.displayName = "SubComponentRenderer";
2004
+ var SoftRender = (0, import_react4.memo)(
2005
+ ({
2006
+ softComponentFields,
2007
+ softComponentFieldSettings,
2008
+ softSubComponent,
2009
+ configComponents,
2010
+ props,
2011
+ depth = 0
2012
+ }) => {
2013
+ if (!(softSubComponent == null ? void 0 : softSubComponent.length)) return null;
2014
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: softSubComponent.map((subComponent, index) => {
2015
+ var _a;
2016
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2017
+ SubComponentRenderer,
2018
+ {
2019
+ subComponent,
2020
+ softComponentFields,
2021
+ softComponentFieldSettings: softComponentFieldSettings || {},
2022
+ configComponents,
2023
+ props,
2024
+ depth,
2025
+ index
2026
+ },
2027
+ `${(_a = subComponent == null ? void 0 : subComponent.type) != null ? _a : "comp"}-${index}-${depth}`
2028
+ );
2029
+ }) });
2030
+ },
2031
+ // Covers all five props — not just `props` and `softSubComponent`.
2032
+ // configComponents / softComponentFields: reference equality (stable config).
2033
+ // softComponentFieldSettings: deep equality (may carry dynamic defaults).
2034
+ // props / softSubComponent: deep equality (primary render drivers).
2035
+ (prev, next) => prev.configComponents === next.configComponents && prev.softComponentFields === next.softComponentFields && (0, import_react_fast_compare3.default)(prev.props, next.props) && (0, import_react_fast_compare3.default)(prev.softSubComponent, next.softSubComponent) && (0, import_react_fast_compare3.default)(prev.softComponentFieldSettings, next.softComponentFieldSettings)
2036
+ );
2037
+ SoftRender.displayName = "SoftRender";
1280
2038
 
1281
2039
  // src/puck/lib/create-versioned-component-config.tsx
1282
2040
  var import_jsx_runtime6 = require("react/jsx-runtime");
1283
- var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true) => {
2041
+ var hydrateCustomField = (fieldName, field, fieldSettings, customFields) => {
2042
+ var _a;
2043
+ if (field.type !== "custom") {
2044
+ return field;
2045
+ }
2046
+ const fieldWithMeta = field;
2047
+ const customFieldType = fieldWithMeta.customFieldType || ((_a = fieldSettings == null ? void 0 : fieldSettings[fieldName]) == null ? void 0 : _a.customFieldType);
2048
+ if (!customFieldType) {
2049
+ return field;
2050
+ }
2051
+ const customField = customFields == null ? void 0 : customFields[customFieldType];
2052
+ if (!customField) {
2053
+ return field;
2054
+ }
2055
+ return __spreadProps(__spreadValues(__spreadValues({}, field), customField.field), {
2056
+ type: "custom",
2057
+ label: field.label || customField.field.label || fieldName
2058
+ });
2059
+ };
2060
+ var createVersionedComponentConfig = (componentName, displayName, version, allVersions, config, softComponents, defaultProps, showVersioning = true, customFields) => {
1284
2061
  var _a, _b;
1285
2062
  const softConfig = config;
1286
2063
  return {
@@ -1308,7 +2085,12 @@ var createVersionedComponentConfig = (componentName, displayName, version, allVe
1308
2085
  };
1309
2086
  }
1310
2087
  Object.entries((versionedComponent == null ? void 0 : versionedComponent.fields) || {}).filter(([, field]) => field.type !== "slot").forEach(([key, field]) => {
1311
- fields[key] = field;
2088
+ fields[key] = hydrateCustomField(
2089
+ key,
2090
+ field,
2091
+ versionedComponent == null ? void 0 : versionedComponent.fieldSettings,
2092
+ customFields
2093
+ );
1312
2094
  });
1313
2095
  return fields;
1314
2096
  },
@@ -1335,21 +2117,16 @@ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1335
2117
  var _a;
1336
2118
  const resolvedProps = __spreadValues({}, softSubComponent.fixedProps);
1337
2119
  (_a = softSubComponent.map) == null ? void 0 : _a.forEach((mapItem) => {
1338
- const { from, to, transform } = mapItem || {};
1339
- const fromPaths = Array.isArray(from) ? from : from ? [from] : [];
1340
- const toPaths = Array.isArray(to) ? to : to ? [to] : [];
1341
- const inputs = fromPaths.map(
1342
- (path) => getFieldSettingsByPath(componentRootData.props || {}, path)
2120
+ const { newProps } = applyMapping(
2121
+ resolvedProps,
2122
+ {},
2123
+ [mapItem],
2124
+ "propsFirst",
2125
+ {
2126
+ sourceProps: componentRootData.props || {}
2127
+ }
1343
2128
  );
1344
- const runner = transform;
1345
- const result = runner ? runner(inputs, componentRootData.props) : inputs[0];
1346
- if (Array.isArray(result)) {
1347
- result.forEach((val, idx) => {
1348
- if (toPaths[idx]) setPropertyByPath(resolvedProps, toPaths[idx], val);
1349
- });
1350
- } else if (toPaths[0]) {
1351
- setPropertyByPath(resolvedProps, toPaths[0], result);
1352
- }
2129
+ Object.assign(resolvedProps, newProps);
1353
2130
  });
1354
2131
  softSubComponent.enabledSlots.forEach(({ slot, name }) => {
1355
2132
  var _a2, _b;
@@ -1372,9 +2149,22 @@ var subComponentDecomposer = (componentRootData, softSubComponent) => {
1372
2149
  return accItem;
1373
2150
  };
1374
2151
 
2152
+ // src/puck/lib/builder/resolve-soft-component-data.ts
2153
+ var resolveSoftComponentData = (props, _fieldSettings = {}) => {
2154
+ const map = props._map;
2155
+ if (!(map == null ? void 0 : map.length)) return __spreadValues({}, props);
2156
+ const { newProps } = applyMapping(
2157
+ props,
2158
+ _fieldSettings,
2159
+ map,
2160
+ "propsFirst"
2161
+ );
2162
+ return newProps;
2163
+ };
2164
+
1375
2165
  // src/puck/lib/decompose-soft-component.ts
1376
- function decomposeSoftComponent(componentData, softComponents) {
1377
- var _a, _b;
2166
+ function decomposeSoftComponent(componentData, softComponents, fieldSettings) {
2167
+ var _a, _b, _c, _d;
1378
2168
  if (!(componentData == null ? void 0 : componentData.type) || !(componentData == null ? void 0 : componentData.props.id)) {
1379
2169
  throw new Error("Component data must have type and id to decompose.");
1380
2170
  }
@@ -1385,9 +2175,19 @@ function decomposeSoftComponent(componentData, softComponents) {
1385
2175
  `Soft component "${componentData.type}" version "${version}" not found.`
1386
2176
  );
1387
2177
  }
2178
+ let resolvedComponentData = componentData;
2179
+ if (fieldSettings && ((_d = (_c = componentData.props) == null ? void 0 : _c._map) == null ? void 0 : _d.length)) {
2180
+ const resolvedProps = resolveSoftComponentData(
2181
+ componentData.props,
2182
+ fieldSettings
2183
+ );
2184
+ resolvedComponentData = __spreadProps(__spreadValues({}, componentData), {
2185
+ props: resolvedProps
2186
+ });
2187
+ }
1388
2188
  const decomposedComponentData = softComponent.components.map(
1389
2189
  (softSubComponent) => {
1390
- return subComponentDecomposer(componentData, softSubComponent);
2190
+ return subComponentDecomposer(resolvedComponentData, softSubComponent);
1391
2191
  }
1392
2192
  );
1393
2193
  return decomposedComponentData;
@@ -1430,18 +2230,6 @@ function demolishSoftComponent(componentName, data, config, softComponents) {
1430
2230
  };
1431
2231
  }
1432
2232
 
1433
- // src/puck/lib/component-key.ts
1434
- var defaultToCamelCase = (value) => {
1435
- const tokens = value.trim().replace(/[^a-zA-Z0-9\s_-]/g, " ").split(/[\s_-]+/).filter(Boolean);
1436
- if (tokens.length === 0) return "";
1437
- const [first, ...rest] = tokens;
1438
- return `${first.toLowerCase()}${rest.map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase()).join("")}`;
1439
- };
1440
- var createComponentKeyFromName = (displayName, overrides, context) => {
1441
- const key = overrides.componentNameToKey ? overrides.componentNameToKey(displayName, context) : defaultToCamelCase(displayName);
1442
- return key.trim();
1443
- };
1444
-
1445
2233
  // src/puck/store/slices/builder.tsx
1446
2234
  var createBuildersSlice = (set, get, initialConfig) => ({
1447
2235
  build: (history, selectedItem, itemSelector, puckDispatch, name) => {
@@ -1469,7 +2257,14 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1469
2257
  });
1470
2258
  const config = __spreadValues({}, get().softConfig);
1471
2259
  const overrides = get().overrides;
1472
- const buildConfig = builderConfig(config, overrides, void 0, get().showVersionFields);
2260
+ const buildConfig = builderConfig(
2261
+ config,
2262
+ overrides,
2263
+ void 0,
2264
+ get().showVersionFields,
2265
+ void 0,
2266
+ get().customFields
2267
+ );
1473
2268
  const editableIds = /* @__PURE__ */ new Set([selectedItem.props.id]);
1474
2269
  const initialContent = [__spreadValues({}, selectedItem)];
1475
2270
  (0, import_puck4.walkTree)(
@@ -1541,13 +2336,22 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1541
2336
  versions,
1542
2337
  selectedItem.props,
1543
2338
  get().softConfig.components,
2339
+ get().overrides,
1544
2340
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || softComponentName,
1545
- softComponentMeta == null ? void 0 : softComponentMeta.category
2341
+ softComponentMeta == null ? void 0 : softComponentMeta.category,
2342
+ get().customFields
1546
2343
  );
1547
2344
  const config = __spreadValues({}, get().softConfig);
1548
2345
  const overrides = get().overrides;
1549
2346
  const dependents = get().dependencyGraph.get(softComponentName) || /* @__PURE__ */ new Set();
1550
- const buildConfig = builderConfig(config, overrides, softComponentName, get().showVersionFields, dependents);
2347
+ const buildConfig = builderConfig(
2348
+ config,
2349
+ overrides,
2350
+ softComponentName,
2351
+ get().showVersionFields,
2352
+ dependents,
2353
+ get().customFields
2354
+ );
1551
2355
  const editableIds = /* @__PURE__ */ new Set([]);
1552
2356
  const decomposedComponents = get().builder.decompose(selectedItem);
1553
2357
  (0, import_puck4.walkTree)(
@@ -1593,6 +2397,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1593
2397
  zone: itemSelector.zone || rootDroppableId
1594
2398
  },
1595
2399
  editingComponentId: selectedItem.props.id,
2400
+ editingComponent: softComponentName,
1596
2401
  editableComponentIds: editableIds,
1597
2402
  state: "remodeling"
1598
2403
  }));
@@ -1609,7 +2414,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1609
2414
  );
1610
2415
  },
1611
2416
  complete: (appState, setHistories, getItemBySelector) => {
1612
- var _a, _b, _c, _d, _e, _f;
2417
+ var _a, _b, _c, _d, _e, _f, _g;
1613
2418
  if (get().state === "ready") {
1614
2419
  throw new Error("Not building or remodeling a component.");
1615
2420
  }
@@ -1628,10 +2433,11 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1628
2433
  throw new Error("Cannot find item being edited");
1629
2434
  }
1630
2435
  const rootCategory = (_e = (_d = appState.data.root) == null ? void 0 : _d.props) == null ? void 0 : _e._category;
1631
- const componentName = createComponentKeyFromName(displayName, get().overrides, {
2436
+ const rootProps = (_f = appState.data.root) == null ? void 0 : _f.props;
2437
+ const componentName = createComponentKeyFromName(displayName, get().overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
1632
2438
  existingKeys: Object.keys(get().softComponents),
1633
2439
  state: get().state
1634
- });
2440
+ }));
1635
2441
  if (!componentName) {
1636
2442
  throw new Error("Failed to generate component key from name.");
1637
2443
  }
@@ -1690,6 +2496,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1690
2496
  storedConfig: void 0,
1691
2497
  state: "inspecting",
1692
2498
  originalHistory: [],
2499
+ editingComponent: null,
1693
2500
  editingComponentId: null,
1694
2501
  editableComponentIds: /* @__PURE__ */ new Set()
1695
2502
  });
@@ -1697,7 +2504,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1697
2504
  if (!version) {
1698
2505
  throw new Error("Failed to resolve completed component version.");
1699
2506
  }
1700
- const completedSoftComponent = (_f = get().softComponents[componentName]) == null ? void 0 : _f.versions[version];
2507
+ const completedSoftComponent = (_g = get().softComponents[componentName]) == null ? void 0 : _g.versions[version];
1701
2508
  if (!completedSoftComponent) {
1702
2509
  throw new Error(
1703
2510
  `Completed soft component "${componentName}" version "${version}" not found.`
@@ -1749,6 +2556,7 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1749
2556
  itemSelector: null,
1750
2557
  originalItem: null,
1751
2558
  state: "ready",
2559
+ editingComponent: null,
1752
2560
  editingComponentId: null,
1753
2561
  editableComponentIds: /* @__PURE__ */ new Set()
1754
2562
  }));
@@ -1770,7 +2578,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1770
2578
  {
1771
2579
  name: displayName,
1772
2580
  category
1773
- }
2581
+ },
2582
+ get().customFields
1774
2583
  );
1775
2584
  const existingComponent = get().softComponents[componentName];
1776
2585
  const allVersions = Object.keys((existingComponent == null ? void 0 : existingComponent.versions) || {});
@@ -1789,7 +2598,8 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1789
2598
  })
1790
2599
  }),
1791
2600
  softComponent.defaultProps,
1792
- get().showVersionFields
2601
+ get().showVersionFields,
2602
+ get().customFields
1793
2603
  );
1794
2604
  get().setSoftComponent(componentName, version, softComponent);
1795
2605
  return [newSoftComponentConfig, version];
@@ -1841,8 +2651,10 @@ var createBuildersSlice = (set, get, initialConfig) => ({
1841
2651
  versions,
1842
2652
  currentProps,
1843
2653
  get().softConfig.components,
2654
+ get().overrides,
1844
2655
  (softComponentMeta == null ? void 0 : softComponentMeta.name) || componentName,
1845
- softComponentMeta == null ? void 0 : softComponentMeta.category
2656
+ softComponentMeta == null ? void 0 : softComponentMeta.category,
2657
+ get().customFields
1846
2658
  );
1847
2659
  puckDispatch({
1848
2660
  type: "setData",
@@ -1989,7 +2801,7 @@ function topologicalSort(softComponents, hardComponentNames) {
1989
2801
  }
1990
2802
  return sorted;
1991
2803
  }
1992
- function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false) {
2804
+ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showVersioning = false, customFields) {
1993
2805
  var _a, _b;
1994
2806
  if (!softComponents || Object.keys(softComponents).length === 0) {
1995
2807
  return {};
@@ -2025,7 +2837,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showV
2025
2837
  // Pass the accumulating config
2026
2838
  hydratedSoftComponents,
2027
2839
  versionedComponent.defaultProps,
2028
- showVersioning
2840
+ showVersioning,
2841
+ customFields
2029
2842
  );
2030
2843
  componentConfigs[name] = newSoftComponentConfig;
2031
2844
  buildingConfig.components[name] = newSoftComponentConfig;
@@ -2053,7 +2866,8 @@ function buildInitialSoftComponents(hardConfig, softComponents, overrides, showV
2053
2866
  hardConfig,
2054
2867
  hydratedSoftComponents,
2055
2868
  versionedComponent.defaultProps,
2056
- showVersioning
2869
+ showVersioning,
2870
+ customFields
2057
2871
  );
2058
2872
  componentConfigs[name] = newSoftComponentConfig;
2059
2873
  }
@@ -2119,9 +2933,9 @@ var clearEditVisibility = (doc) => {
2119
2933
  // src/puck/store/index.tsx
2120
2934
  var createSoftConfigStore = (hardConfig = {
2121
2935
  components: {}
2122
- }, softComponents = {}, overrides = {}, onActions, showVersionFields = true) => {
2936
+ }, softComponents = {}, overrides = {}, onActions, showVersionFields = true, customFields = {}) => {
2123
2937
  const normalizedSoftComponents = Object.fromEntries(
2124
- Object.entries(softComponents || {}).map(([key, value]) => [
2938
+ Object.entries(softComponents || {}).filter(([key]) => !hardConfig.components || !hardConfig.components[key]).map(([key, value]) => [
2125
2939
  key,
2126
2940
  __spreadProps(__spreadValues({}, value), {
2127
2941
  name: value.name || key
@@ -2142,9 +2956,11 @@ var createSoftConfigStore = (hardConfig = {
2142
2956
  state: "ready",
2143
2957
  originalHistory: [],
2144
2958
  overrides,
2959
+ customFields,
2145
2960
  onActions,
2146
2961
  iframeDocRef,
2147
2962
  showVersionFields,
2963
+ editingComponent: null,
2148
2964
  setShowVersionFields: (show) => set({ showVersionFields: show }),
2149
2965
  getIframeDoc: () => iframeDocRef.current,
2150
2966
  setIframeDoc: (doc) => {
@@ -2182,11 +2998,17 @@ var createSoftConfigStore = (hardConfig = {
2182
2998
  components: __spreadValues(__spreadValues({}, hardConfig.components), buildInitialSoftComponents(
2183
2999
  hardConfig,
2184
3000
  hydratedSoftComponents,
2185
- overrides
3001
+ overrides,
3002
+ showVersionFields,
3003
+ customFields
2186
3004
  )),
2187
3005
  categories: __spreadValues({}, hardConfig.categories || {})
2188
3006
  }),
2189
3007
  setSoftComponent: (name, version, component) => {
3008
+ if (hardConfig.components && hardConfig.components[name]) {
3009
+ console.warn(`Cannot set soft component "${name}" because it conflicts with a base hardConfig component.`);
3010
+ return;
3011
+ }
2190
3012
  const existing = get().softComponents[name];
2191
3013
  set((state) => {
2192
3014
  var _a, _b;
@@ -2209,6 +3031,9 @@ var createSoftConfigStore = (hardConfig = {
2209
3031
  const nextSoftComponents = __spreadValues({}, state.softComponents);
2210
3032
  const nextConfigComponents = __spreadValues({}, state.softConfig.components);
2211
3033
  Object.entries(incomingComponents).forEach(([name, data]) => {
3034
+ if (hardConfig.components && hardConfig.components[name]) {
3035
+ return;
3036
+ }
2212
3037
  const existing = nextSoftComponents[name];
2213
3038
  const finalComponentData = existing ? __spreadProps(__spreadValues(__spreadValues({}, existing), data), {
2214
3039
  name: data.name || existing.name || name,
@@ -2227,7 +3052,8 @@ var createSoftConfigStore = (hardConfig = {
2227
3052
  state.softConfig,
2228
3053
  nextSoftComponents,
2229
3054
  activeVersionData.defaultProps,
2230
- state.showVersionFields
3055
+ state.showVersionFields,
3056
+ state.customFields
2231
3057
  );
2232
3058
  }
2233
3059
  });
@@ -2258,7 +3084,8 @@ var createSoftConfigStore = (hardConfig = {
2258
3084
  softConfig,
2259
3085
  hydratedComponents,
2260
3086
  activeVersionData.defaultProps,
2261
- get().showVersionFields
3087
+ get().showVersionFields,
3088
+ get().customFields
2262
3089
  );
2263
3090
  }
2264
3091
  });
@@ -2289,7 +3116,8 @@ var createSoftConfigStore = (hardConfig = {
2289
3116
  get().softConfig,
2290
3117
  get().softComponents,
2291
3118
  softComponent.defaultProps,
2292
- get().showVersionFields
3119
+ get().showVersionFields,
3120
+ get().customFields
2293
3121
  );
2294
3122
  set((state) => ({
2295
3123
  softConfig: __spreadProps(__spreadValues({}, state.softConfig), {
@@ -2426,7 +3254,8 @@ var createSoftConfigStore = (hardConfig = {
2426
3254
  config,
2427
3255
  softComponents2,
2428
3256
  versionedComponent.defaultProps,
2429
- state.showVersionFields
3257
+ state.showVersionFields,
3258
+ state.customFields
2430
3259
  );
2431
3260
  config.components[dependentName] = newConfig;
2432
3261
  }
@@ -2444,14 +3273,29 @@ var SoftConfigProvider = ({
2444
3273
  children,
2445
3274
  hardConfig,
2446
3275
  softComponents,
3276
+ customFields,
2447
3277
  overrides,
2448
3278
  value,
2449
3279
  onActions,
2450
3280
  useVersioning = false
2451
3281
  }) => {
2452
3282
  const store = value != null ? value : (0, import_react5.useMemo)(
2453
- () => createSoftConfigStore(hardConfig, softComponents, overrides, onActions, useVersioning),
2454
- [hardConfig, softComponents, overrides, onActions, useVersioning]
3283
+ () => createSoftConfigStore(
3284
+ hardConfig,
3285
+ softComponents,
3286
+ overrides,
3287
+ onActions,
3288
+ useVersioning,
3289
+ customFields
3290
+ ),
3291
+ [
3292
+ hardConfig,
3293
+ softComponents,
3294
+ overrides,
3295
+ onActions,
3296
+ useVersioning,
3297
+ customFields
3298
+ ]
2455
3299
  );
2456
3300
  const [softConfig, setSoftConfig] = (0, import_react5.useState)(
2457
3301
  () => store.getState().softConfig
@@ -2465,14 +3309,19 @@ var SoftConfigProvider = ({
2465
3309
  );
2466
3310
  const validateAction = (0, import_react5.useMemo)(
2467
3311
  () => (action) => {
3312
+ var _a;
2468
3313
  const currentState = store.getState();
2469
3314
  if (currentState.state === "ready") {
2470
3315
  return true;
2471
3316
  }
2472
3317
  const editableIds = currentState.editableComponentIds;
2473
3318
  if (action.type === "replace") {
3319
+ const parentId = (_a = action.destinationZone) == null ? void 0 : _a.split(":")[0];
2474
3320
  if (action.data.props.id && editableIds.has(action.data.props.id)) {
2475
3321
  return true;
3322
+ } else if (parentId && editableIds.has(parentId)) {
3323
+ currentState.addEditableComponentId(action.data.props.id);
3324
+ return true;
2476
3325
  }
2477
3326
  return false;
2478
3327
  }
@@ -3041,32 +3890,50 @@ var import_jsx_runtime9 = require("react/jsx-runtime");
3041
3890
  var getClassName3 = get_class_name_factory_default("ActionBar", ActionBar_module_default);
3042
3891
  var usePuck2 = (0, import_puck14.createUsePuck)();
3043
3892
  var ActionBarOverride = (props) => {
3044
- var _a;
3045
- const { handleBuild } = useBuild("Custom Name");
3893
+ var _a, _b;
3894
+ const { handleBuild } = useBuild(props.label ? props.label + " Soft Component" : "New Soft Component");
3046
3895
  const { handleRemodel } = useRemodel();
3047
3896
  const { handleDecompose } = useDecompose();
3048
3897
  const overrides = useSoftConfig((s) => s.overrides);
3049
3898
  const softComponents = useSoftConfig((s) => s.softComponents, import_shallow.shallow);
3050
3899
  const editableIds = useSoftConfig((s) => s.editableComponentIds);
3051
3900
  const selectedItem = usePuck2((s) => s.selectedItem);
3901
+ const rootProps = usePuck2((s) => s.appState.data.root.props);
3052
3902
  const status = useSoftConfig((s) => s.state);
3903
+ const itemSelector = usePuck2((s) => s.appState.ui.itemSelector);
3053
3904
  const softKeys = Object.keys(softComponents);
3054
- const key = (0, import_react9.useMemo)(() => createComponentKeyFromName(props.label || "", overrides, {
3055
- existingKeys: softKeys,
3056
- state: status
3057
- }), [
3905
+ const key = (0, import_react9.useMemo)(() => {
3906
+ const selectedType = selectedItem == null ? void 0 : selectedItem.type;
3907
+ if (selectedType && softKeys.includes(selectedType)) {
3908
+ return selectedType;
3909
+ }
3910
+ return createComponentKeyFromName(props.label || "", overrides, __spreadProps(__spreadValues({}, rootProps || {}), {
3911
+ existingKeys: softKeys,
3912
+ state: status
3913
+ }));
3914
+ }, [
3058
3915
  props.label,
3059
3916
  overrides,
3917
+ selectedItem == null ? void 0 : selectedItem.type,
3060
3918
  softKeys,
3061
- status
3919
+ status,
3920
+ rootProps
3062
3921
  ]);
3063
3922
  const isSoftComponent2 = softKeys.includes(key);
3064
3923
  const selectedId = (_a = selectedItem == null ? void 0 : selectedItem.props) == null ? void 0 : _a.id;
3065
- const isEditable = Boolean(selectedId && editableIds.has(selectedId));
3924
+ const parentId = (_b = itemSelector == null ? void 0 : itemSelector.zone) == null ? void 0 : _b.split(":")[0];
3925
+ const isEditable = Boolean(selectedId && (editableIds.has(selectedId) || parentId && editableIds.has(parentId)));
3926
+ const displayName = (0, import_react9.useMemo)(() => {
3927
+ var _a2;
3928
+ if (isSoftComponent2) {
3929
+ return ((_a2 = softComponents[key]) == null ? void 0 : _a2.name) || getComponentNameFromKey(key, overrides);
3930
+ }
3931
+ return props.label || "";
3932
+ }, [isSoftComponent2, key, props.label, overrides, softComponents]);
3066
3933
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: getClassName3(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar, { children: [
3067
3934
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar.Group, { children: [
3068
3935
  props.parentAction,
3069
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_puck14.ActionBar.Label, { label: props.label })
3936
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_puck14.ActionBar.Label, { label: displayName })
3070
3937
  ] }),
3071
3938
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_puck14.ActionBar.Group, { children: [
3072
3939
  status === "ready" ? isSoftComponent2 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
@@ -3191,7 +4058,7 @@ var getClassName5 = get_class_name_factory_default("DrawerItem", DrawerItem_modu
3191
4058
  var usePuck3 = (0, import_puck15.createUsePuck)();
3192
4059
  var DrawerItem = (props) => {
3193
4060
  const componentMeta = useSoftConfig((s) => s.softComponents[props.name]);
3194
- const displayName = (componentMeta == null ? void 0 : componentMeta.name) || props.name;
4061
+ const displayName = props.label || (componentMeta == null ? void 0 : componentMeta.name) || props.name;
3195
4062
  const softComponents = new Set(
3196
4063
  Object.keys(useSoftConfig((s) => s.softComponents, import_shallow2.shallow))
3197
4064
  );
@@ -3287,6 +4154,7 @@ var DrawerItem = (props) => {
3287
4154
  onMouseEnter: () => setIsHovering(true),
3288
4155
  onMouseLeave: () => setIsHovering(false),
3289
4156
  children: [
4157
+ props.label,
3290
4158
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: getClassName5("content"), children: [
3291
4159
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: getClassName5("name"), children: displayName }),
3292
4160
  useVersioning && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: getClassName5("version"), children: [
@@ -3463,6 +4331,10 @@ var Drawer = (_props) => {
3463
4331
  })
3464
4332
  );
3465
4333
  const allKeys = Object.keys(config.components);
4334
+ const labels = Object.entries(config.components).reduce((acc, [key, comp]) => {
4335
+ acc[key] = comp.label || key;
4336
+ return acc;
4337
+ }, {});
3466
4338
  const otherKeys = allKeys.filter((k) => !categorised.has(k));
3467
4339
  const categoryEntries = Object.entries(categories).filter(
3468
4340
  ([, cat]) => cat.visible !== false
@@ -3481,6 +4353,7 @@ var Drawer = (_props) => {
3481
4353
  import_puck16.Drawer.Item,
3482
4354
  {
3483
4355
  name: key,
4356
+ label: labels[key],
3484
4357
  isDragDisabled: !getPermissions({ type: key }).insert,
3485
4358
  children: DrawerItem
3486
4359
  },
@@ -3565,9 +4438,6 @@ function extractDependencies2(softComponents, componentName, version) {
3565
4438
  return dependencies;
3566
4439
  }
3567
4440
  function reverseTopologicalSort(softComponents, hardComponentNames) {
3568
- const sorted = [];
3569
- const visiting = /* @__PURE__ */ new Set();
3570
- const visited = /* @__PURE__ */ new Set();
3571
4441
  const dependencyGraph = /* @__PURE__ */ new Map();
3572
4442
  const dependents = /* @__PURE__ */ new Map();
3573
4443
  for (const [componentName, component] of Object.entries(softComponents)) {
@@ -3615,7 +4485,7 @@ function reverseTopologicalSort(softComponents, hardComponentNames) {
3615
4485
  const sortedByDepth = [...depths.entries()].sort(([, depthA], [, depthB]) => depthB - depthA).map(([name]) => name);
3616
4486
  return sortedByDepth;
3617
4487
  }
3618
- function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0) {
4488
+ function dissolveComponentRecursively(componentData, softComponents, hardComponentNames, depth = 0, fieldSettings) {
3619
4489
  const MAX_DEPTH = 50;
3620
4490
  if (depth > MAX_DEPTH) {
3621
4491
  console.error(
@@ -3625,11 +4495,11 @@ function dissolveComponentRecursively(componentData, softComponents, hardCompone
3625
4495
  }
3626
4496
  const componentType = componentData.type;
3627
4497
  if (!isSoftComponent(componentType, softComponents)) {
3628
- return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth)];
4498
+ return [dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth, fieldSettings)];
3629
4499
  }
3630
4500
  let decomposed;
3631
4501
  try {
3632
- decomposed = decomposeSoftComponent(componentData, softComponents);
4502
+ decomposed = decomposeSoftComponent(componentData, softComponents, fieldSettings);
3633
4503
  } catch (error) {
3634
4504
  console.warn(
3635
4505
  `Failed to decompose soft component "${componentType}":`,
@@ -3643,13 +4513,14 @@ function dissolveComponentRecursively(componentData, softComponents, hardCompone
3643
4513
  component,
3644
4514
  softComponents,
3645
4515
  hardComponentNames,
3646
- depth + 1
4516
+ depth + 1,
4517
+ fieldSettings
3647
4518
  );
3648
4519
  fullyDissolved.push(...dissolved);
3649
4520
  }
3650
4521
  return fullyDissolved;
3651
4522
  }
3652
- function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth) {
4523
+ function dissolveComponentSlots(componentData, softComponents, hardComponentNames, depth, fieldSettings) {
3653
4524
  const newProps = __spreadValues({}, componentData.props);
3654
4525
  Object.entries(newProps).forEach(([key, value]) => {
3655
4526
  var _a;
@@ -3659,7 +4530,8 @@ function dissolveComponentSlots(componentData, softComponents, hardComponentName
3659
4530
  slotComponent,
3660
4531
  softComponents,
3661
4532
  hardComponentNames,
3662
- depth
4533
+ depth,
4534
+ fieldSettings
3663
4535
  )
3664
4536
  );
3665
4537
  }
@@ -3669,22 +4541,23 @@ function dissolveComponentSlots(componentData, softComponents, hardComponentName
3669
4541
  });
3670
4542
  }
3671
4543
  function dissolveAllSoftComponents(data, softComponents, config) {
4544
+ var _a;
3672
4545
  const hardComponentNames = new Set(
3673
4546
  Object.keys(config.components || {}).filter(
3674
4547
  (name) => !isSoftComponent(name, softComponents)
3675
4548
  )
3676
4549
  );
3677
- const dissolutionOrder = reverseTopologicalSort(
3678
- softComponents,
3679
- hardComponentNames
3680
- );
4550
+ reverseTopologicalSort(softComponents, hardComponentNames);
4551
+ const rootParams = ((_a = data.root) == null ? void 0 : _a.props) || {};
4552
+ const fieldSettings = __spreadValues(__spreadValues({}, rootParams._fieldSettings || {}), rootParams);
3681
4553
  const dissolveComponents = (components) => {
3682
4554
  return components.flatMap((componentData) => {
3683
4555
  return dissolveComponentRecursively(
3684
4556
  componentData,
3685
4557
  softComponents,
3686
4558
  hardComponentNames,
3687
- 0
4559
+ 0,
4560
+ fieldSettings
3688
4561
  );
3689
4562
  });
3690
4563
  };
@@ -3751,12 +4624,18 @@ var resolveSoftConfig = (data, softComponents, config) => {
3751
4624
  Header,
3752
4625
  Modal,
3753
4626
  SoftConfigProvider,
4627
+ applyMapping,
3754
4628
  confirm,
3755
4629
  createActionCallback,
3756
4630
  createSoftConfigStore,
3757
4631
  createUseSoftConfig,
4632
+ filterToOptionsForFrom,
4633
+ getArrayBasePath,
4634
+ getArrayItemSubPath,
4635
+ isArrayMappingPath,
3758
4636
  notify,
3759
4637
  resolveSoftConfig,
4638
+ resolveValueByPath,
3760
4639
  setConfirmHandler,
3761
4640
  setNotificationHandler,
3762
4641
  useBuild,