@form-engine-ts/mui 2.9.6 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -4
- package/dist/index.cjs +230 -71
- package/dist/index.d.cts +38 -5
- package/dist/index.d.ts +38 -5
- package/dist/index.js +264 -80
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
DEFAULT_MUI_SECTION_ORDER: () => DEFAULT_MUI_SECTION_ORDER,
|
|
24
|
+
MUI_LOCALIZATION_SECTION_ORDERS: () => MUI_LOCALIZATION_SECTION_ORDERS,
|
|
24
25
|
MuiButtonAdapter: () => MuiButtonAdapter,
|
|
25
26
|
MuiCheckboxAdapter: () => MuiCheckboxAdapter,
|
|
26
27
|
MuiErrorMessageAdapter: () => MuiErrorMessageAdapter,
|
|
@@ -55,6 +56,7 @@ __export(index_exports, {
|
|
|
55
56
|
mergeMuiAdapterOptions: () => mergeMuiAdapterOptions,
|
|
56
57
|
muiBuilderComponents: () => muiBuilderComponents,
|
|
57
58
|
muiBuilderSlots: () => muiBuilderSlots,
|
|
59
|
+
muiDefaultFieldTypeIcon: () => muiDefaultFieldTypeIcon,
|
|
58
60
|
muiDefaultIconResolver: () => muiDefaultIconResolver,
|
|
59
61
|
resolveMuiAdapterOptions: () => resolveMuiAdapterOptions,
|
|
60
62
|
useResolvedMuiAdapterOptions: () => useResolvedMuiAdapterOptions
|
|
@@ -72,8 +74,15 @@ var DEFAULT_MUI_SECTION_ORDER = [
|
|
|
72
74
|
"basicSettings",
|
|
73
75
|
"questions",
|
|
74
76
|
"addQuestion",
|
|
75
|
-
"localization"
|
|
77
|
+
"localization",
|
|
78
|
+
"completionMessage"
|
|
76
79
|
];
|
|
80
|
+
var MUI_LOCALIZATION_SECTION_ORDERS = {
|
|
81
|
+
top: ["localization", "basicSettings", "completionMessage", "questions", "addQuestion"],
|
|
82
|
+
beforeQuestions: ["basicSettings", "localization", "completionMessage", "questions", "addQuestion"],
|
|
83
|
+
afterQuestions: ["basicSettings", "questions", "addQuestion", "localization", "completionMessage"],
|
|
84
|
+
bottom: ["basicSettings", "completionMessage", "questions", "addQuestion", "localization"]
|
|
85
|
+
};
|
|
77
86
|
function resolveMuiAdapterOptions(options = {}) {
|
|
78
87
|
const buttonVariant = options.buttonVariant ?? "contained";
|
|
79
88
|
return {
|
|
@@ -99,8 +108,13 @@ function resolveMuiAdapterOptions(options = {}) {
|
|
|
99
108
|
collapsible: options.localizationOptions?.collapsible ?? false,
|
|
100
109
|
defaultExpanded: options.localizationOptions?.defaultExpanded ?? false,
|
|
101
110
|
showSummary: options.localizationOptions?.showSummary ?? false,
|
|
111
|
+
...options.localizationOptions?.availableLocales === void 0 ? {} : { availableLocales: options.localizationOptions.availableLocales },
|
|
112
|
+
...options.localizationOptions?.placement === void 0 ? {} : { placement: options.localizationOptions.placement },
|
|
113
|
+
...options.localizationOptions?.renderSummary === void 0 ? {} : { renderSummary: options.localizationOptions.renderSummary },
|
|
102
114
|
...options.localizationOptions?.emptyStateMessage === void 0 ? {} : { emptyStateMessage: options.localizationOptions.emptyStateMessage },
|
|
103
|
-
defaultLocaleControl: options.localizationOptions?.defaultLocaleControl ?? "editable"
|
|
115
|
+
defaultLocaleControl: options.localizationOptions?.defaultLocaleControl ?? "editable",
|
|
116
|
+
noWrapActions: options.localizationOptions?.noWrapActions ?? true,
|
|
117
|
+
autoFocusNewTab: options.localizationOptions?.autoFocusNewTab ?? true
|
|
104
118
|
},
|
|
105
119
|
muiSlotProps: options.muiSlotProps ?? {}
|
|
106
120
|
};
|
|
@@ -138,6 +152,7 @@ function createMuiButtonAdapter(options) {
|
|
|
138
152
|
"aria-describedby": ariaDescribedBy,
|
|
139
153
|
"aria-labelledby": ariaLabelledBy,
|
|
140
154
|
onClick,
|
|
155
|
+
noWrap,
|
|
141
156
|
children,
|
|
142
157
|
title,
|
|
143
158
|
variant,
|
|
@@ -145,9 +160,11 @@ function createMuiButtonAdapter(options) {
|
|
|
145
160
|
targetId
|
|
146
161
|
}) {
|
|
147
162
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
163
|
+
const buttonSlotProps = resolved.muiSlotProps?.button;
|
|
148
164
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
149
165
|
import_material.Button,
|
|
150
166
|
{
|
|
167
|
+
...buttonSlotProps,
|
|
151
168
|
id,
|
|
152
169
|
className,
|
|
153
170
|
type: "button",
|
|
@@ -161,9 +178,9 @@ function createMuiButtonAdapter(options) {
|
|
|
161
178
|
"data-target-id": targetId,
|
|
162
179
|
onClick,
|
|
163
180
|
color: variant === "danger" ? "error" : "primary",
|
|
164
|
-
variant: resolved.buttonVariants?.[variant ?? "primary"] ?? resolved.buttonVariant,
|
|
181
|
+
variant: buttonSlotProps?.variant ?? resolved.buttonVariants?.[variant ?? "primary"] ?? resolved.buttonVariant,
|
|
165
182
|
fullWidth: resolved.buttonFullWidth ?? false,
|
|
166
|
-
sx: { whiteSpace: "nowrap" },
|
|
183
|
+
sx: { whiteSpace: noWrap === false ? "normal" : "nowrap" },
|
|
167
184
|
children
|
|
168
185
|
}
|
|
169
186
|
);
|
|
@@ -192,6 +209,7 @@ function createMuiCheckboxAdapter(options) {
|
|
|
192
209
|
label
|
|
193
210
|
}) {
|
|
194
211
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
212
|
+
const checkboxSlotProps = resolved.muiSlotProps?.checkbox;
|
|
195
213
|
const helperId = id === void 0 ? void 0 : ariaDescribedBy?.split(/\s+/u)[0] ?? `${id}-helper-text`;
|
|
196
214
|
const describedBy = ariaDescribedBy ?? (helperText === void 0 || helperText.length === 0 ? void 0 : helperId);
|
|
197
215
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_material2.FormControl, { className, error: Boolean(error), required, disabled: disabled || readOnly, children: [
|
|
@@ -202,9 +220,10 @@ function createMuiCheckboxAdapter(options) {
|
|
|
202
220
|
control: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
203
221
|
import_material2.Checkbox,
|
|
204
222
|
{
|
|
223
|
+
...checkboxSlotProps,
|
|
205
224
|
id,
|
|
206
225
|
name,
|
|
207
|
-
size: resolved.size,
|
|
226
|
+
size: checkboxSlotProps?.size ?? resolved.size,
|
|
208
227
|
checked,
|
|
209
228
|
required,
|
|
210
229
|
disabled: disabled || readOnly,
|
|
@@ -316,16 +335,18 @@ function createMuiIconButtonAdapter(options) {
|
|
|
316
335
|
title
|
|
317
336
|
}) {
|
|
318
337
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
338
|
+
const iconButtonSlotProps = resolved.muiSlotProps?.iconButton;
|
|
319
339
|
const actionLabel = actionType === void 0 ? "Action" : resolved.getActionLabel?.(actionType) ?? FALLBACK_ACTION_LABELS[actionType];
|
|
320
340
|
const tooltip = title ?? actionLabel;
|
|
321
341
|
const color = actionType === "delete" ? "error" : actionType === "add" ? "primary" : "default";
|
|
322
342
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_material5.Tooltip, { title: tooltip, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
323
343
|
import_material5.IconButton,
|
|
324
344
|
{
|
|
345
|
+
...iconButtonSlotProps,
|
|
325
346
|
id,
|
|
326
347
|
className,
|
|
327
348
|
type: "button",
|
|
328
|
-
size: resolved.size,
|
|
349
|
+
size: iconButtonSlotProps?.size ?? resolved.size,
|
|
329
350
|
color,
|
|
330
351
|
disabled: disabled || readOnly,
|
|
331
352
|
"aria-label": ariaLabel ?? tooltip,
|
|
@@ -391,6 +412,9 @@ var MuiSectionAdapter = createMuiSectionAdapter();
|
|
|
391
412
|
// src/adapters/Select.tsx
|
|
392
413
|
var import_material7 = require("@mui/material");
|
|
393
414
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
415
|
+
function normalizeOptions(options) {
|
|
416
|
+
return options.map((option) => typeof option === "string" ? { value: option, label: option } : option);
|
|
417
|
+
}
|
|
394
418
|
function createMuiSelectAdapter(options) {
|
|
395
419
|
return function MuiSelect({
|
|
396
420
|
id,
|
|
@@ -407,13 +431,19 @@ function createMuiSelectAdapter(options) {
|
|
|
407
431
|
helperText,
|
|
408
432
|
value,
|
|
409
433
|
onChange,
|
|
410
|
-
|
|
434
|
+
onKeyDown,
|
|
435
|
+
options: selectOptions,
|
|
436
|
+
renderOption,
|
|
437
|
+
renderValue
|
|
411
438
|
}) {
|
|
412
439
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
440
|
+
const normalizedOptions = normalizeOptions(selectOptions);
|
|
441
|
+
const selectSlotProps = resolved.muiSlotProps?.select;
|
|
442
|
+
const menuProps = { ...selectSlotProps?.MenuProps, ...resolved.muiSlotProps?.selectMenu };
|
|
413
443
|
const labelId = id === void 0 || label === void 0 ? void 0 : `${id}-label`;
|
|
414
444
|
const helperId = id === void 0 ? void 0 : ariaDescribedBy?.split(/\s+/u)[0] ?? `${id}-helper-text`;
|
|
415
445
|
const describedBy = ariaDescribedBy ?? (helperText === void 0 || helperText.length === 0 ? void 0 : helperId);
|
|
416
|
-
const handleChange = (event) => onChange(event.target.value);
|
|
446
|
+
const handleChange = (event) => onChange(String(event.target.value));
|
|
417
447
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
418
448
|
import_material7.FormControl,
|
|
419
449
|
{
|
|
@@ -429,20 +459,39 @@ function createMuiSelectAdapter(options) {
|
|
|
429
459
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
430
460
|
import_material7.Select,
|
|
431
461
|
{
|
|
462
|
+
...selectSlotProps,
|
|
432
463
|
id,
|
|
433
464
|
labelId,
|
|
434
465
|
name,
|
|
435
466
|
label,
|
|
436
467
|
value,
|
|
468
|
+
disabled,
|
|
437
469
|
onChange: handleChange,
|
|
470
|
+
onKeyDown,
|
|
438
471
|
required,
|
|
439
472
|
readOnly,
|
|
473
|
+
variant: selectSlotProps?.variant ?? resolved.variant,
|
|
474
|
+
...Object.keys(menuProps).length === 0 ? {} : { MenuProps: menuProps },
|
|
475
|
+
renderValue: (selected) => {
|
|
476
|
+
const selectedValue = typeof selected === "string" ? selected : String(selected ?? "");
|
|
477
|
+
const option = normalizedOptions.find((candidate) => candidate.value === selectedValue);
|
|
478
|
+
if (renderValue !== void 0) return renderValue(option);
|
|
479
|
+
if (option === void 0) return selectedValue;
|
|
480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_material7.Box, { display: "flex", alignItems: "center", gap: 0.75, children: [
|
|
481
|
+
option.icon,
|
|
482
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: option.label })
|
|
483
|
+
] });
|
|
484
|
+
},
|
|
440
485
|
inputProps: {
|
|
486
|
+
...selectSlotProps?.inputProps,
|
|
441
487
|
"aria-label": ariaLabel,
|
|
442
488
|
"aria-describedby": describedBy,
|
|
443
489
|
"aria-labelledby": ariaLabelledBy
|
|
444
490
|
},
|
|
445
|
-
children:
|
|
491
|
+
children: normalizedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material7.MenuItem, { value: option.value, disabled: option.disabled, children: renderOption === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
492
|
+
option.icon === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material7.ListItemIcon, { sx: { minWidth: 32 }, children: option.icon }),
|
|
493
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material7.ListItemText, { primary: option.label, secondary: option.description })
|
|
494
|
+
] }) : renderOption(option) }, option.value))
|
|
446
495
|
}
|
|
447
496
|
),
|
|
448
497
|
helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_material7.FormHelperText, { id: helperId, children: helperText })
|
|
@@ -477,9 +526,11 @@ function createMuiTextAreaAdapter(options) {
|
|
|
477
526
|
rows
|
|
478
527
|
}) {
|
|
479
528
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
529
|
+
const textFieldSlotProps = resolved.muiSlotProps?.textField;
|
|
480
530
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
481
531
|
import_material8.TextField,
|
|
482
532
|
{
|
|
533
|
+
...textFieldSlotProps,
|
|
483
534
|
id,
|
|
484
535
|
className,
|
|
485
536
|
name,
|
|
@@ -505,7 +556,7 @@ function createMuiTextAreaAdapter(options) {
|
|
|
505
556
|
placeholder,
|
|
506
557
|
fullWidth: resolved.inputFullWidth ?? resolved.fullWidth,
|
|
507
558
|
size: resolved.size,
|
|
508
|
-
variant: resolved.variant,
|
|
559
|
+
variant: textFieldSlotProps?.variant ?? resolved.variant,
|
|
509
560
|
onChange: (event) => onChange(event.currentTarget.value)
|
|
510
561
|
}
|
|
511
562
|
);
|
|
@@ -532,6 +583,7 @@ function createMuiTextInputAdapter(options) {
|
|
|
532
583
|
helperText,
|
|
533
584
|
value,
|
|
534
585
|
onChange,
|
|
586
|
+
onKeyDown,
|
|
535
587
|
placeholder,
|
|
536
588
|
maxLength,
|
|
537
589
|
inputMode,
|
|
@@ -541,9 +593,11 @@ function createMuiTextInputAdapter(options) {
|
|
|
541
593
|
step
|
|
542
594
|
}) {
|
|
543
595
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
596
|
+
const textFieldSlotProps = resolved.muiSlotProps?.textField;
|
|
544
597
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
545
598
|
import_material9.TextField,
|
|
546
599
|
{
|
|
600
|
+
...textFieldSlotProps,
|
|
547
601
|
id,
|
|
548
602
|
className,
|
|
549
603
|
name,
|
|
@@ -572,8 +626,9 @@ function createMuiTextInputAdapter(options) {
|
|
|
572
626
|
placeholder,
|
|
573
627
|
fullWidth: resolved.inputFullWidth ?? resolved.fullWidth,
|
|
574
628
|
size: resolved.size,
|
|
575
|
-
variant: resolved.variant,
|
|
576
|
-
onChange: (event) => onChange(event.currentTarget.value)
|
|
629
|
+
variant: textFieldSlotProps?.variant ?? resolved.variant,
|
|
630
|
+
onChange: (event) => onChange(event.currentTarget.value),
|
|
631
|
+
onKeyDown
|
|
577
632
|
}
|
|
578
633
|
);
|
|
579
634
|
};
|
|
@@ -605,6 +660,26 @@ function muiDefaultIconResolver(actionType) {
|
|
|
605
660
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.DragHandle, { fontSize: "small" });
|
|
606
661
|
}
|
|
607
662
|
}
|
|
663
|
+
function muiDefaultFieldTypeIcon(type) {
|
|
664
|
+
switch (type) {
|
|
665
|
+
case "text":
|
|
666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.TextFields, { fontSize: "small" });
|
|
667
|
+
case "textarea":
|
|
668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.Subject, { fontSize: "small" });
|
|
669
|
+
case "number":
|
|
670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.Numbers, { fontSize: "small" });
|
|
671
|
+
case "rating":
|
|
672
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.Star, { fontSize: "small" });
|
|
673
|
+
case "select":
|
|
674
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.ArrowDropDown, { fontSize: "small" });
|
|
675
|
+
case "multi-select":
|
|
676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.CheckBox, { fontSize: "small" });
|
|
677
|
+
case "checkbox":
|
|
678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.CheckBox, { fontSize: "small" });
|
|
679
|
+
case "radio":
|
|
680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons_material.RadioButtonChecked, { fontSize: "small" });
|
|
681
|
+
}
|
|
682
|
+
}
|
|
608
683
|
|
|
609
684
|
// src/components.ts
|
|
610
685
|
function isAdapterOptions(value) {
|
|
@@ -621,7 +696,8 @@ function buildMuiBuilderComponents(options) {
|
|
|
621
696
|
Section: createMuiSectionAdapter(options),
|
|
622
697
|
Fieldset: createMuiFieldsetAdapter(options),
|
|
623
698
|
ErrorMessage: createMuiErrorMessageAdapter(options),
|
|
624
|
-
renderIcon: muiDefaultIconResolver
|
|
699
|
+
renderIcon: muiDefaultIconResolver,
|
|
700
|
+
renderFieldTypeIcon: muiDefaultFieldTypeIcon
|
|
625
701
|
};
|
|
626
702
|
}
|
|
627
703
|
var muiBuilderComponents = {
|
|
@@ -634,7 +710,8 @@ var muiBuilderComponents = {
|
|
|
634
710
|
Section: MuiSectionAdapter,
|
|
635
711
|
Fieldset: MuiFieldsetAdapter,
|
|
636
712
|
ErrorMessage: MuiErrorMessageAdapter,
|
|
637
|
-
renderIcon: muiDefaultIconResolver
|
|
713
|
+
renderIcon: muiDefaultIconResolver,
|
|
714
|
+
renderFieldTypeIcon: muiDefaultFieldTypeIcon
|
|
638
715
|
};
|
|
639
716
|
function createMuiBuilderComponents(optionsOrOverrides = {}, customOverrides) {
|
|
640
717
|
const options = isAdapterOptions(optionsOrOverrides) ? optionsOrOverrides : void 0;
|
|
@@ -643,6 +720,7 @@ function createMuiBuilderComponents(optionsOrOverrides = {}, customOverrides) {
|
|
|
643
720
|
}
|
|
644
721
|
|
|
645
722
|
// src/slots/FieldEditor.tsx
|
|
723
|
+
var import_core = require("@form-engine-ts/core");
|
|
646
724
|
var import_material12 = require("@mui/material");
|
|
647
725
|
|
|
648
726
|
// src/slots/OptionEditor.tsx
|
|
@@ -789,16 +867,7 @@ var MuiToolbarSlot = createMuiToolbarSlot();
|
|
|
789
867
|
|
|
790
868
|
// src/slots/FieldEditor.tsx
|
|
791
869
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
792
|
-
var FIELD_TYPES =
|
|
793
|
-
"text",
|
|
794
|
-
"textarea",
|
|
795
|
-
"number",
|
|
796
|
-
"rating",
|
|
797
|
-
"select",
|
|
798
|
-
"multi-select",
|
|
799
|
-
"checkbox",
|
|
800
|
-
"radio"
|
|
801
|
-
];
|
|
870
|
+
var FIELD_TYPES = import_core.DEFAULT_FIELD_TYPE_DEFINITIONS.map((definition) => definition.type);
|
|
802
871
|
function isFieldType(value) {
|
|
803
872
|
return FIELD_TYPES.some((type) => type === value);
|
|
804
873
|
}
|
|
@@ -837,7 +906,8 @@ function createMuiFieldEditorSlot(options) {
|
|
|
837
906
|
readOnly,
|
|
838
907
|
actions,
|
|
839
908
|
components,
|
|
840
|
-
translate
|
|
909
|
+
translate,
|
|
910
|
+
slots
|
|
841
911
|
}) {
|
|
842
912
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
843
913
|
const { Button: Button2, Checkbox: Checkbox2, Select: Select2, TextArea, TextInput } = components;
|
|
@@ -848,6 +918,11 @@ function createMuiFieldEditorSlot(options) {
|
|
|
848
918
|
const conditionSource = conditionSources.find((source) => source.id === condition?.questionId);
|
|
849
919
|
const descriptionMode = resolved.fieldEditorOptions?.description ?? "editable";
|
|
850
920
|
const titleErrorId = field.title.trim().length === 0 ? `mui-field-${field.id}-title-error` : void 0;
|
|
921
|
+
const FieldTypeSelect = slots?.fieldTypeSelect;
|
|
922
|
+
const FieldEditorHeader = slots?.fieldEditorHeader;
|
|
923
|
+
const changeFieldType = (nextType) => {
|
|
924
|
+
if (allowedTypes.includes(nextType)) actions.changeFieldType(field.id, nextType);
|
|
925
|
+
};
|
|
851
926
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
852
927
|
import_material12.Card,
|
|
853
928
|
{
|
|
@@ -856,26 +931,28 @@ function createMuiFieldEditorSlot(options) {
|
|
|
856
931
|
variant: "outlined",
|
|
857
932
|
sx: resolved.muiSlotProps?.card?.sx ?? { mb: resolved.dense ? 1 : 2, p: resolved.dense ? 1.5 : 2 },
|
|
858
933
|
children: [
|
|
859
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
934
|
+
FieldEditorHeader === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
936
|
+
Toolbar,
|
|
937
|
+
{
|
|
938
|
+
schema,
|
|
939
|
+
translate,
|
|
940
|
+
kind: "field",
|
|
941
|
+
targetId: field.id,
|
|
942
|
+
index,
|
|
943
|
+
total: schema.fields.length,
|
|
944
|
+
title: field.title,
|
|
945
|
+
onMoveUp: () => actions.moveField(field.id, index - 1),
|
|
946
|
+
onMoveDown: () => actions.moveField(field.id, index + 1),
|
|
947
|
+
onRemove: () => actions.removeField(field.id),
|
|
948
|
+
readOnly,
|
|
949
|
+
actions,
|
|
950
|
+
components
|
|
951
|
+
}
|
|
952
|
+
),
|
|
953
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material12.Typography, { variant: "subtitle1", fontWeight: "bold", children: field.title })
|
|
954
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FieldEditorHeader, { field, index, totalFields: schema.fields.length, actions }),
|
|
877
955
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { ...resolved.muiSlotProps?.stack, spacing: resolved.dense ? 1 : 2, children: [
|
|
878
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material12.Typography, { variant: "subtitle1", fontWeight: "bold", children: field.title }),
|
|
879
956
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
|
|
880
957
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
881
958
|
TextInput,
|
|
@@ -892,22 +969,37 @@ function createMuiFieldEditorSlot(options) {
|
|
|
892
969
|
onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "title", value)
|
|
893
970
|
}
|
|
894
971
|
),
|
|
895
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
972
|
+
FieldTypeSelect === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
896
973
|
Select2,
|
|
897
974
|
{
|
|
898
975
|
id: `mui-field-${field.id}-type`,
|
|
899
976
|
name: `fields.${field.id}.type`,
|
|
900
977
|
label: translate("builder.type"),
|
|
901
978
|
value: allowedTypes.includes(field.type) ? field.type : "",
|
|
902
|
-
options: FIELD_TYPES.filter((type) => allowedTypes.includes(type)).map((type) =>
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
979
|
+
options: FIELD_TYPES.filter((type) => allowedTypes.includes(type)).map((type) => {
|
|
980
|
+
const definition = import_core.DEFAULT_FIELD_TYPE_DEFINITIONS.find((candidate) => candidate.type === type);
|
|
981
|
+
return {
|
|
982
|
+
value: type,
|
|
983
|
+
label: translate(definition?.labelKey ?? `builder.fieldType.${type}`),
|
|
984
|
+
icon: components.renderFieldTypeIcon(type),
|
|
985
|
+
...definition?.category === void 0 ? {} : { kind: definition.category }
|
|
986
|
+
};
|
|
987
|
+
}),
|
|
906
988
|
disabled: readOnly,
|
|
907
989
|
onChange: (value) => {
|
|
908
|
-
if (isFieldType(value))
|
|
990
|
+
if (isFieldType(value)) changeFieldType(value);
|
|
909
991
|
}
|
|
910
992
|
}
|
|
993
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
994
|
+
FieldTypeSelect,
|
|
995
|
+
{
|
|
996
|
+
currentType: field.type,
|
|
997
|
+
allowedTypes,
|
|
998
|
+
onChangeType: changeFieldType,
|
|
999
|
+
disabled: readOnly,
|
|
1000
|
+
readOnly,
|
|
1001
|
+
renderIcon: components.renderFieldTypeIcon
|
|
1002
|
+
}
|
|
911
1003
|
)
|
|
912
1004
|
] }),
|
|
913
1005
|
descriptionMode === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
@@ -1090,6 +1182,17 @@ var import_material13 = require("@mui/material");
|
|
|
1090
1182
|
var import_react2 = require("react");
|
|
1091
1183
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1092
1184
|
var DEFAULT_EMPTY_STATE_MESSAGE = "No translation locales have been added yet. Select a language from the dropdown above to add one.";
|
|
1185
|
+
function normalizeLocaleOptions(options, getLocaleLabel) {
|
|
1186
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1187
|
+
const normalized = [];
|
|
1188
|
+
for (const item of options) {
|
|
1189
|
+
const value = typeof item === "string" ? item : item.value;
|
|
1190
|
+
if (value.length === 0 || seen.has(value)) continue;
|
|
1191
|
+
seen.add(value);
|
|
1192
|
+
normalized.push({ value, label: typeof item === "string" ? getLocaleLabel?.(value) ?? value : item.label });
|
|
1193
|
+
}
|
|
1194
|
+
return normalized;
|
|
1195
|
+
}
|
|
1093
1196
|
function createMuiLocalizationSlot(options) {
|
|
1094
1197
|
return function MuiLocalization({
|
|
1095
1198
|
schema,
|
|
@@ -1108,6 +1211,7 @@ function createMuiLocalizationSlot(options) {
|
|
|
1108
1211
|
const resolved = useResolvedMuiAdapterOptions(options);
|
|
1109
1212
|
const { Button: Button2, ErrorMessage, Select: Select2, TextArea, TextInput } = components;
|
|
1110
1213
|
const [newLocale, setNewLocale] = (0, import_react2.useState)("");
|
|
1214
|
+
const [pendingFocusLocale, setPendingFocusLocale] = (0, import_react2.useState)(null);
|
|
1111
1215
|
const locales = Array.from(
|
|
1112
1216
|
new Set((schema.supportedLocales ?? []).filter((locale) => locale !== schema.defaultLocale))
|
|
1113
1217
|
);
|
|
@@ -1116,21 +1220,44 @@ function createMuiLocalizationSlot(options) {
|
|
|
1116
1220
|
...schema.defaultLocale === void 0 ? [] : [schema.defaultLocale],
|
|
1117
1221
|
...schema.supportedLocales ?? []
|
|
1118
1222
|
]);
|
|
1119
|
-
const
|
|
1223
|
+
const localizationOptions = resolved.localizationOptions ?? {};
|
|
1224
|
+
const availableLocaleSource = localizationOptions.availableLocales;
|
|
1225
|
+
const availableLocaleOptions = availableLocaleSource === void 0 ? policy?.allowedLocales?.map((value) => ({
|
|
1226
|
+
value,
|
|
1227
|
+
label: resolved.getLocaleLabel?.(value) ?? value
|
|
1228
|
+
})) : normalizeLocaleOptions(availableLocaleSource, resolved.getLocaleLabel);
|
|
1229
|
+
const filteredAvailableLocales = availableLocaleOptions?.filter(
|
|
1230
|
+
(locale) => !registeredLocales.has(locale.value) && (policy?.allowedLocales === void 0 || policy.allowedLocales.includes(locale.value))
|
|
1231
|
+
);
|
|
1232
|
+
const hasLocaleSelector = filteredAvailableLocales !== void 0;
|
|
1120
1233
|
const localeLimitReached = policy?.maxLocales !== void 0 && registeredLocales.size >= policy.maxLocales;
|
|
1121
1234
|
const normalizedLocale = newLocale.trim();
|
|
1235
|
+
const selectedLocaleAvailable = !hasLocaleSelector || filteredAvailableLocales.some((locale) => locale.value === normalizedLocale);
|
|
1122
1236
|
const localeAllowed = policy?.allowedLocales === void 0 || policy.allowedLocales.includes(normalizedLocale);
|
|
1123
|
-
const canAddLocale = !readOnly && normalizedLocale.length > 0 && localeAllowed && !registeredLocales.has(normalizedLocale) && !localeLimitReached;
|
|
1237
|
+
const canAddLocale = !readOnly && normalizedLocale.length > 0 && selectedLocaleAvailable && localeAllowed && !registeredLocales.has(normalizedLocale) && !localeLimitReached;
|
|
1124
1238
|
const handleTabChange = (_event, value) => onCurrentLocaleChange(value);
|
|
1125
1239
|
const addLocale = () => {
|
|
1126
1240
|
if (!canAddLocale) return;
|
|
1127
1241
|
const result = actions.addLocale(normalizedLocale);
|
|
1128
1242
|
if (!result.success) return;
|
|
1129
1243
|
onCurrentLocaleChange(normalizedLocale);
|
|
1244
|
+
if (localizationOptions.autoFocusNewTab ?? true) setPendingFocusLocale(normalizedLocale);
|
|
1130
1245
|
setNewLocale("");
|
|
1131
1246
|
};
|
|
1247
|
+
const handleAddKeyDown = (event) => {
|
|
1248
|
+
if (event.key !== "Enter" || !canAddLocale) return;
|
|
1249
|
+
event.preventDefault();
|
|
1250
|
+
event.stopPropagation();
|
|
1251
|
+
addLocale();
|
|
1252
|
+
};
|
|
1253
|
+
(0, import_react2.useEffect)(() => {
|
|
1254
|
+
if (pendingFocusLocale === null || currentLocale !== pendingFocusLocale) return;
|
|
1255
|
+
const tab = document.getElementById(`mui-builder-locale-tab-${pendingFocusLocale}`);
|
|
1256
|
+
if (tab === null) return;
|
|
1257
|
+
tab.focus();
|
|
1258
|
+
setPendingFocusLocale(null);
|
|
1259
|
+
}, [currentLocale, pendingFocusLocale]);
|
|
1132
1260
|
const stackProps = resolved.muiSlotProps?.stack;
|
|
1133
|
-
const localizationOptions = resolved.localizationOptions ?? {};
|
|
1134
1261
|
const collapsible = localizationOptions.collapsible ?? false;
|
|
1135
1262
|
const defaultLocaleControl = localizationOptions.defaultLocaleControl ?? "editable";
|
|
1136
1263
|
const configuredTranslationLocales = locales.filter((locale) => locale !== schema.defaultLocale);
|
|
@@ -1138,24 +1265,35 @@ function createMuiLocalizationSlot(options) {
|
|
|
1138
1265
|
...schema.defaultLocale === void 0 ? [] : [schema.defaultLocale],
|
|
1139
1266
|
...configuredTranslationLocales
|
|
1140
1267
|
];
|
|
1141
|
-
const
|
|
1268
|
+
const legacySummaryLabel = configuredTranslationLocales.length === 0 ? "Translations not configured" : `${configuredLocales.length} ${configuredLocales.length === 1 ? "language" : "languages"} configured: ${configuredLocales.map(
|
|
1142
1269
|
(locale) => locale === schema.defaultLocale ? `${resolved.getLocaleLabel?.(locale) ?? locale} (default)` : resolved.getLocaleLabel?.(locale) ?? locale
|
|
1143
1270
|
).join(", ")}`;
|
|
1144
1271
|
const emptyStateMessage = localizationOptions.emptyStateMessage === void 0 ? DEFAULT_EMPTY_STATE_MESSAGE : translate(localizationOptions.emptyStateMessage);
|
|
1272
|
+
const summaryContext = {
|
|
1273
|
+
defaultLocale: schema.defaultLocale ?? "",
|
|
1274
|
+
supportedLocales: schema.supportedLocales ?? [],
|
|
1275
|
+
totalLocales: registeredLocales.size
|
|
1276
|
+
};
|
|
1277
|
+
const summary = localizationOptions.renderSummary === void 0 ? localizationOptions.showSummary ? configuredTranslationLocales.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Alert, { severity: "success", sx: { mb: 2 }, children: translate("builder.localization.localesConfiguredSummary", {
|
|
1278
|
+
count: schema.supportedLocales?.length ?? 0
|
|
1279
|
+
}) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Alert, { severity: "info", sx: { mb: 2 }, children: translate("builder.localization.noLocalesConfigured") }) : null : localizationOptions.renderSummary(summaryContext);
|
|
1145
1280
|
const title = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { alignItems: "center", direction: "row", spacing: 1, children: [
|
|
1146
1281
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }),
|
|
1147
|
-
localizationOptions.showSummary ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1282
|
+
localizationOptions.renderSummary === void 0 && localizationOptions.showSummary && configuredTranslationLocales.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1148
1283
|
import_material13.Chip,
|
|
1149
1284
|
{
|
|
1150
|
-
label:
|
|
1285
|
+
label: legacySummaryLabel,
|
|
1151
1286
|
size: "small",
|
|
1152
1287
|
color: configuredTranslationLocales.length > 0 ? "primary" : "default",
|
|
1153
1288
|
variant: "outlined"
|
|
1154
1289
|
}
|
|
1155
1290
|
) : null
|
|
1156
1291
|
] });
|
|
1292
|
+
const noCandidateLocales = hasLocaleSelector && filteredAvailableLocales.length === 0;
|
|
1293
|
+
const candidateHelperText = localeLimitReached ? void 0 : noCandidateLocales ? translate("builder.localization.allLocalesAdded") : void 0;
|
|
1157
1294
|
const content = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
|
|
1158
1295
|
!collapsible ? title : null,
|
|
1296
|
+
summary,
|
|
1159
1297
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1160
1298
|
import_material13.Stack,
|
|
1161
1299
|
{
|
|
@@ -1187,36 +1325,52 @@ function createMuiLocalizationSlot(options) {
|
|
|
1187
1325
|
}
|
|
1188
1326
|
}
|
|
1189
1327
|
) }),
|
|
1190
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Box, { sx: { flexGrow: 1, minWidth: 0, width: { xs: "100%", sm: "auto" } },
|
|
1191
|
-
|
|
1328
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Box, { sx: { flexGrow: 1, minWidth: 0, width: { xs: "100%", sm: "auto" } }, onKeyDownCapture: handleAddKeyDown, children: hasLocaleSelector ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1329
|
+
Select2,
|
|
1192
1330
|
{
|
|
1193
1331
|
id: "mui-builder-new-locale",
|
|
1194
|
-
label: translate("builder.
|
|
1332
|
+
label: translate("builder.localization.selectLocaleToAdd"),
|
|
1195
1333
|
value: newLocale,
|
|
1196
|
-
|
|
1334
|
+
options: filteredAvailableLocales.map((locale) => ({ value: locale.value, label: locale.label })),
|
|
1335
|
+
...candidateHelperText === void 0 ? {} : { helperText: candidateHelperText },
|
|
1336
|
+
disabled: readOnly || localeLimitReached || noCandidateLocales,
|
|
1197
1337
|
onChange: setNewLocale
|
|
1198
1338
|
}
|
|
1199
1339
|
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1200
|
-
|
|
1340
|
+
TextInput,
|
|
1201
1341
|
{
|
|
1202
1342
|
id: "mui-builder-new-locale",
|
|
1203
1343
|
label: translate("builder.addLocale"),
|
|
1204
1344
|
value: newLocale,
|
|
1205
|
-
|
|
1206
|
-
{ value: "", label: "\u2014" },
|
|
1207
|
-
...availableAllowedLocales.map((locale) => ({
|
|
1208
|
-
value: locale,
|
|
1209
|
-
label: resolved.getLocaleLabel?.(locale) ?? locale
|
|
1210
|
-
}))
|
|
1211
|
-
],
|
|
1212
|
-
disabled: readOnly || localeLimitReached || availableAllowedLocales.length === 0,
|
|
1345
|
+
disabled: readOnly || localeLimitReached,
|
|
1213
1346
|
onChange: setNewLocale
|
|
1214
1347
|
}
|
|
1215
1348
|
) }),
|
|
1216
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1349
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1350
|
+
import_material13.Box,
|
|
1351
|
+
{
|
|
1352
|
+
sx: {
|
|
1353
|
+
flexShrink: 0,
|
|
1354
|
+
minWidth: "max-content",
|
|
1355
|
+
...localizationOptions.noWrapActions ?? true ? { whiteSpace: "nowrap" } : {}
|
|
1356
|
+
},
|
|
1357
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1358
|
+
Button2,
|
|
1359
|
+
{
|
|
1360
|
+
variant: "primary",
|
|
1361
|
+
action: "addLocale",
|
|
1362
|
+
noWrap: localizationOptions.noWrapActions ?? true,
|
|
1363
|
+
disabled: !canAddLocale,
|
|
1364
|
+
onClick: addLocale,
|
|
1365
|
+
children: translate("builder.addLocale")
|
|
1366
|
+
}
|
|
1367
|
+
)
|
|
1368
|
+
}
|
|
1369
|
+
)
|
|
1217
1370
|
]
|
|
1218
1371
|
}
|
|
1219
1372
|
),
|
|
1373
|
+
localeLimitReached ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "body2", color: "text.secondary", children: translate("builder.localization.maxLocalesReached", { max: policy?.maxLocales ?? 0 }) }) : null,
|
|
1220
1374
|
locales.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1221
1375
|
import_material13.Tabs,
|
|
1222
1376
|
{
|
|
@@ -1228,6 +1382,7 @@ function createMuiLocalizationSlot(options) {
|
|
|
1228
1382
|
children: locales.map((locale) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1229
1383
|
import_material13.Tab,
|
|
1230
1384
|
{
|
|
1385
|
+
id: `mui-builder-locale-tab-${locale}`,
|
|
1231
1386
|
value: locale,
|
|
1232
1387
|
label: resolved.getLocaleLabel?.(locale) ?? locale,
|
|
1233
1388
|
disabled: readOnly && locale !== currentLocale,
|
|
@@ -1241,6 +1396,7 @@ function createMuiLocalizationSlot(options) {
|
|
|
1241
1396
|
Button2,
|
|
1242
1397
|
{
|
|
1243
1398
|
variant: "secondary",
|
|
1399
|
+
noWrap: localizationOptions.noWrapActions ?? true,
|
|
1244
1400
|
disabled: readOnly || !editingLocaleConfigured || isTranslating,
|
|
1245
1401
|
onClick: onAutoTranslate,
|
|
1246
1402
|
children: isTranslating ? translate("builder.translating") : translate("builder.autoTranslate")
|
|
@@ -1359,7 +1515,8 @@ function MuiFormBuilder({
|
|
|
1359
1515
|
const contextValue = (0, import_react4.useMemo)(() => ({ options: contextOptions }), [contextOptions]);
|
|
1360
1516
|
const components = (0, import_react4.useMemo)(() => ({ ...muiBuilderComponents, ...customComponents }), [customComponents]);
|
|
1361
1517
|
const slots = (0, import_react4.useMemo)(() => ({ ...muiBuilderSlots, ...customSlots }), [customSlots]);
|
|
1362
|
-
const
|
|
1518
|
+
const placement = contextOptions.localizationOptions?.placement;
|
|
1519
|
+
const resolvedSectionOrder = sectionOrder ?? (placement === void 0 ? contextOptions.layoutOptions?.sectionOrder : MUI_LOCALIZATION_SECTION_ORDERS[placement]);
|
|
1363
1520
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MuiFormBuilderContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1364
1521
|
import_react3.FormBuilder,
|
|
1365
1522
|
{
|
|
@@ -1374,6 +1531,7 @@ function MuiFormBuilder({
|
|
|
1374
1531
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1375
1532
|
0 && (module.exports = {
|
|
1376
1533
|
DEFAULT_MUI_SECTION_ORDER,
|
|
1534
|
+
MUI_LOCALIZATION_SECTION_ORDERS,
|
|
1377
1535
|
MuiButtonAdapter,
|
|
1378
1536
|
MuiCheckboxAdapter,
|
|
1379
1537
|
MuiErrorMessageAdapter,
|
|
@@ -1408,6 +1566,7 @@ function MuiFormBuilder({
|
|
|
1408
1566
|
mergeMuiAdapterOptions,
|
|
1409
1567
|
muiBuilderComponents,
|
|
1410
1568
|
muiBuilderSlots,
|
|
1569
|
+
muiDefaultFieldTypeIcon,
|
|
1411
1570
|
muiDefaultIconResolver,
|
|
1412
1571
|
resolveMuiAdapterOptions,
|
|
1413
1572
|
useResolvedMuiAdapterOptions
|