@form-engine-ts/mui 2.9.3 → 2.9.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.
- package/README.md +40 -3
- package/dist/index.cjs +388 -204
- package/dist/index.d.cts +60 -3
- package/dist/index.d.ts +60 -3
- package/dist/index.js +381 -201
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,21 +1,69 @@
|
|
|
1
1
|
// src/adapters/Button.tsx
|
|
2
2
|
import { Button } from "@mui/material";
|
|
3
3
|
|
|
4
|
+
// src/context.ts
|
|
5
|
+
import { createContext, useContext } from "react";
|
|
6
|
+
|
|
4
7
|
// src/types.ts
|
|
8
|
+
var DEFAULT_MUI_SECTION_ORDER = [
|
|
9
|
+
"basicSettings",
|
|
10
|
+
"questions",
|
|
11
|
+
"addQuestion",
|
|
12
|
+
"localization"
|
|
13
|
+
];
|
|
5
14
|
function resolveMuiAdapterOptions(options = {}) {
|
|
15
|
+
const buttonVariant = options.buttonVariant ?? "contained";
|
|
6
16
|
return {
|
|
7
17
|
size: options.size ?? "medium",
|
|
8
18
|
variant: options.variant ?? "outlined",
|
|
9
|
-
buttonVariant
|
|
19
|
+
buttonVariant,
|
|
20
|
+
buttonVariants: {
|
|
21
|
+
primary: options.buttonVariants?.primary ?? buttonVariant,
|
|
22
|
+
secondary: options.buttonVariants?.secondary ?? buttonVariant,
|
|
23
|
+
danger: options.buttonVariants?.danger ?? buttonVariant
|
|
24
|
+
},
|
|
10
25
|
fullWidth: options.fullWidth ?? true,
|
|
11
|
-
|
|
26
|
+
inputFullWidth: options.inputFullWidth ?? options.fullWidth ?? true,
|
|
27
|
+
buttonFullWidth: options.buttonFullWidth ?? options.fullWidth ?? false,
|
|
28
|
+
dense: options.dense ?? false,
|
|
29
|
+
getLocaleLabel: options.getLocaleLabel ?? ((locale) => locale),
|
|
30
|
+
...options.getActionLabel === void 0 ? {} : { getActionLabel: options.getActionLabel },
|
|
31
|
+
layoutOptions: options.layoutOptions ?? {},
|
|
32
|
+
fieldEditorOptions: {
|
|
33
|
+
description: options.fieldEditorOptions?.description ?? "editable"
|
|
34
|
+
},
|
|
35
|
+
localizationOptions: {
|
|
36
|
+
collapsible: options.localizationOptions?.collapsible ?? false,
|
|
37
|
+
defaultExpanded: options.localizationOptions?.defaultExpanded ?? false,
|
|
38
|
+
defaultLocaleControl: options.localizationOptions?.defaultLocaleControl ?? "editable"
|
|
39
|
+
},
|
|
40
|
+
muiSlotProps: options.muiSlotProps ?? {}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/context.ts
|
|
45
|
+
var MuiFormBuilderContext = createContext({ options: {} });
|
|
46
|
+
function mergeMuiAdapterOptions(base = {}, overrides = {}) {
|
|
47
|
+
return {
|
|
48
|
+
...base,
|
|
49
|
+
...overrides,
|
|
50
|
+
...base.buttonVariants === void 0 && overrides.buttonVariants === void 0 ? {} : { buttonVariants: { ...base.buttonVariants, ...overrides.buttonVariants } },
|
|
51
|
+
...base.layoutOptions === void 0 && overrides.layoutOptions === void 0 ? {} : { layoutOptions: { ...base.layoutOptions, ...overrides.layoutOptions } },
|
|
52
|
+
...base.fieldEditorOptions === void 0 && overrides.fieldEditorOptions === void 0 ? {} : { fieldEditorOptions: { ...base.fieldEditorOptions, ...overrides.fieldEditorOptions } },
|
|
53
|
+
...base.localizationOptions === void 0 && overrides.localizationOptions === void 0 ? {} : { localizationOptions: { ...base.localizationOptions, ...overrides.localizationOptions } },
|
|
54
|
+
...base.muiSlotProps === void 0 && overrides.muiSlotProps === void 0 ? {} : { muiSlotProps: { ...base.muiSlotProps, ...overrides.muiSlotProps } }
|
|
12
55
|
};
|
|
13
56
|
}
|
|
57
|
+
function useResolvedMuiAdapterOptions(overrides) {
|
|
58
|
+
const context = useContext(MuiFormBuilderContext);
|
|
59
|
+
return resolveMuiAdapterOptions(
|
|
60
|
+
overrides === void 0 ? context.options : mergeMuiAdapterOptions(context.options, overrides)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
14
63
|
|
|
15
64
|
// src/adapters/Button.tsx
|
|
16
65
|
import { jsx } from "react/jsx-runtime";
|
|
17
66
|
function createMuiButtonAdapter(options) {
|
|
18
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
19
67
|
return function MuiButton({
|
|
20
68
|
id,
|
|
21
69
|
className,
|
|
@@ -31,6 +79,7 @@ function createMuiButtonAdapter(options) {
|
|
|
31
79
|
action,
|
|
32
80
|
targetId
|
|
33
81
|
}) {
|
|
82
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
34
83
|
return /* @__PURE__ */ jsx(
|
|
35
84
|
Button,
|
|
36
85
|
{
|
|
@@ -47,8 +96,8 @@ function createMuiButtonAdapter(options) {
|
|
|
47
96
|
"data-target-id": targetId,
|
|
48
97
|
onClick,
|
|
49
98
|
color: variant === "danger" ? "error" : "primary",
|
|
50
|
-
variant: resolved.buttonVariant,
|
|
51
|
-
fullWidth: resolved.
|
|
99
|
+
variant: resolved.buttonVariants?.[variant ?? "primary"] ?? resolved.buttonVariant,
|
|
100
|
+
fullWidth: resolved.buttonFullWidth ?? false,
|
|
52
101
|
children
|
|
53
102
|
}
|
|
54
103
|
);
|
|
@@ -60,7 +109,6 @@ var MuiButtonAdapter = createMuiButtonAdapter();
|
|
|
60
109
|
import { Checkbox, FormControl, FormControlLabel, FormHelperText } from "@mui/material";
|
|
61
110
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
62
111
|
function createMuiCheckboxAdapter(options) {
|
|
63
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
64
112
|
return function MuiCheckbox({
|
|
65
113
|
id,
|
|
66
114
|
className,
|
|
@@ -77,6 +125,7 @@ function createMuiCheckboxAdapter(options) {
|
|
|
77
125
|
onChange,
|
|
78
126
|
label
|
|
79
127
|
}) {
|
|
128
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
80
129
|
return /* @__PURE__ */ jsxs(FormControl, { className, error: Boolean(error), required, disabled: disabled || readOnly, children: [
|
|
81
130
|
/* @__PURE__ */ jsx2(
|
|
82
131
|
FormControlLabel,
|
|
@@ -140,8 +189,8 @@ var MuiErrorMessageAdapter = createMuiErrorMessageAdapter();
|
|
|
140
189
|
import { Box, Typography } from "@mui/material";
|
|
141
190
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
142
191
|
function createMuiFieldsetAdapter(options) {
|
|
143
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
144
192
|
return function MuiFieldset({ className, legend, disabled, children }) {
|
|
193
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
145
194
|
return /* @__PURE__ */ jsxs2(
|
|
146
195
|
Box,
|
|
147
196
|
{
|
|
@@ -173,19 +222,18 @@ var MuiFieldsetAdapter = createMuiFieldsetAdapter();
|
|
|
173
222
|
// src/adapters/IconButton.tsx
|
|
174
223
|
import { IconButton, Tooltip } from "@mui/material";
|
|
175
224
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
176
|
-
var
|
|
177
|
-
moveUp: "
|
|
178
|
-
moveDown: "
|
|
179
|
-
delete: "
|
|
180
|
-
add: "
|
|
181
|
-
edit: "
|
|
182
|
-
settings: "
|
|
183
|
-
translate: "
|
|
184
|
-
close: "
|
|
185
|
-
dragHandle: "
|
|
225
|
+
var FALLBACK_ACTION_LABELS = {
|
|
226
|
+
moveUp: "Move up",
|
|
227
|
+
moveDown: "Move down",
|
|
228
|
+
delete: "Delete",
|
|
229
|
+
add: "Add",
|
|
230
|
+
edit: "Edit",
|
|
231
|
+
settings: "Settings",
|
|
232
|
+
translate: "Translate",
|
|
233
|
+
close: "Close",
|
|
234
|
+
dragHandle: "Reorder"
|
|
186
235
|
};
|
|
187
236
|
function createMuiIconButtonAdapter(options) {
|
|
188
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
189
237
|
return function MuiIconButton({
|
|
190
238
|
id,
|
|
191
239
|
className,
|
|
@@ -199,7 +247,8 @@ function createMuiIconButtonAdapter(options) {
|
|
|
199
247
|
actionType,
|
|
200
248
|
title
|
|
201
249
|
}) {
|
|
202
|
-
const
|
|
250
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
251
|
+
const actionLabel = actionType === void 0 ? "Action" : resolved.getActionLabel?.(actionType) ?? FALLBACK_ACTION_LABELS[actionType];
|
|
203
252
|
const tooltip = title ?? actionLabel;
|
|
204
253
|
const color = actionType === "delete" ? "error" : actionType === "add" ? "primary" : "default";
|
|
205
254
|
return /* @__PURE__ */ jsx5(Tooltip, { title: tooltip, children: /* @__PURE__ */ jsx5("span", { children: /* @__PURE__ */ jsx5(
|
|
@@ -226,7 +275,6 @@ var MuiIconButtonAdapter = createMuiIconButtonAdapter();
|
|
|
226
275
|
import { Paper, Typography as Typography2 } from "@mui/material";
|
|
227
276
|
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
228
277
|
function createMuiSectionAdapter(options) {
|
|
229
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
230
278
|
return function MuiSection({
|
|
231
279
|
id,
|
|
232
280
|
className,
|
|
@@ -237,16 +285,18 @@ function createMuiSectionAdapter(options) {
|
|
|
237
285
|
onClickCapture,
|
|
238
286
|
children
|
|
239
287
|
}) {
|
|
288
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
240
289
|
return /* @__PURE__ */ jsxs3(
|
|
241
290
|
Paper,
|
|
242
291
|
{
|
|
292
|
+
...resolved.muiSlotProps?.paper,
|
|
243
293
|
id,
|
|
244
294
|
className,
|
|
245
295
|
elevation: 0,
|
|
246
296
|
"aria-label": ariaLabel,
|
|
247
297
|
"aria-labelledby": title === void 0 ? void 0 : headingId,
|
|
248
298
|
onClickCapture,
|
|
249
|
-
sx: {
|
|
299
|
+
sx: resolved.muiSlotProps?.paper?.sx ?? {
|
|
250
300
|
p: resolved.dense ? 1.5 : 2,
|
|
251
301
|
mb: resolved.dense ? 1 : 2,
|
|
252
302
|
border: 1,
|
|
@@ -274,7 +324,6 @@ var MuiSectionAdapter = createMuiSectionAdapter();
|
|
|
274
324
|
import { FormControl as FormControl2, FormHelperText as FormHelperText2, InputLabel, MenuItem, Select } from "@mui/material";
|
|
275
325
|
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
276
326
|
function createMuiSelectAdapter(options) {
|
|
277
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
278
327
|
return function MuiSelect({
|
|
279
328
|
id,
|
|
280
329
|
className,
|
|
@@ -292,13 +341,14 @@ function createMuiSelectAdapter(options) {
|
|
|
292
341
|
onChange,
|
|
293
342
|
options: selectOptions
|
|
294
343
|
}) {
|
|
344
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
295
345
|
const labelId = id === void 0 || label === void 0 ? void 0 : `${id}-label`;
|
|
296
346
|
const handleChange = (event) => onChange(event.target.value);
|
|
297
347
|
return /* @__PURE__ */ jsxs4(
|
|
298
348
|
FormControl2,
|
|
299
349
|
{
|
|
300
350
|
className,
|
|
301
|
-
fullWidth: resolved.fullWidth,
|
|
351
|
+
fullWidth: resolved.inputFullWidth ?? resolved.fullWidth,
|
|
302
352
|
size: resolved.size,
|
|
303
353
|
variant: resolved.variant,
|
|
304
354
|
error: Boolean(error),
|
|
@@ -337,7 +387,6 @@ var MuiSelectAdapter = createMuiSelectAdapter();
|
|
|
337
387
|
import { TextField } from "@mui/material";
|
|
338
388
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
339
389
|
function createMuiTextAreaAdapter(options) {
|
|
340
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
341
390
|
return function MuiTextArea({
|
|
342
391
|
id,
|
|
343
392
|
className,
|
|
@@ -357,6 +406,7 @@ function createMuiTextAreaAdapter(options) {
|
|
|
357
406
|
maxLength,
|
|
358
407
|
rows
|
|
359
408
|
}) {
|
|
409
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
360
410
|
return /* @__PURE__ */ jsx8(
|
|
361
411
|
TextField,
|
|
362
412
|
{
|
|
@@ -372,6 +422,7 @@ function createMuiTextAreaAdapter(options) {
|
|
|
372
422
|
slotProps: {
|
|
373
423
|
htmlInput: {
|
|
374
424
|
maxLength,
|
|
425
|
+
readOnly,
|
|
375
426
|
"aria-label": ariaLabel,
|
|
376
427
|
"aria-describedby": ariaDescribedBy,
|
|
377
428
|
"aria-labelledby": ariaLabelledBy
|
|
@@ -382,7 +433,7 @@ function createMuiTextAreaAdapter(options) {
|
|
|
382
433
|
multiline: true,
|
|
383
434
|
rows,
|
|
384
435
|
placeholder,
|
|
385
|
-
fullWidth: resolved.fullWidth,
|
|
436
|
+
fullWidth: resolved.inputFullWidth ?? resolved.fullWidth,
|
|
386
437
|
size: resolved.size,
|
|
387
438
|
variant: resolved.variant,
|
|
388
439
|
onChange: (event) => onChange(event.currentTarget.value)
|
|
@@ -396,7 +447,6 @@ var MuiTextAreaAdapter = createMuiTextAreaAdapter();
|
|
|
396
447
|
import { TextField as TextField2 } from "@mui/material";
|
|
397
448
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
398
449
|
function createMuiTextInputAdapter(options) {
|
|
399
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
400
450
|
return function MuiTextInput({
|
|
401
451
|
id,
|
|
402
452
|
className,
|
|
@@ -420,6 +470,7 @@ function createMuiTextInputAdapter(options) {
|
|
|
420
470
|
max,
|
|
421
471
|
step
|
|
422
472
|
}) {
|
|
473
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
423
474
|
return /* @__PURE__ */ jsx9(
|
|
424
475
|
TextField2,
|
|
425
476
|
{
|
|
@@ -439,6 +490,7 @@ function createMuiTextInputAdapter(options) {
|
|
|
439
490
|
max,
|
|
440
491
|
step,
|
|
441
492
|
inputMode,
|
|
493
|
+
readOnly,
|
|
442
494
|
"aria-label": ariaLabel,
|
|
443
495
|
"aria-describedby": ariaDescribedBy,
|
|
444
496
|
"aria-labelledby": ariaLabelledBy
|
|
@@ -448,7 +500,7 @@ function createMuiTextInputAdapter(options) {
|
|
|
448
500
|
},
|
|
449
501
|
type,
|
|
450
502
|
placeholder,
|
|
451
|
-
fullWidth: resolved.fullWidth,
|
|
503
|
+
fullWidth: resolved.inputFullWidth ?? resolved.fullWidth,
|
|
452
504
|
size: resolved.size,
|
|
453
505
|
variant: resolved.variant,
|
|
454
506
|
onChange: (event) => onChange(event.currentTarget.value)
|
|
@@ -496,7 +548,7 @@ function muiDefaultIconResolver(actionType) {
|
|
|
496
548
|
|
|
497
549
|
// src/components.ts
|
|
498
550
|
function isAdapterOptions(value) {
|
|
499
|
-
return "size" in value || "variant" in value || "buttonVariant" in value || "fullWidth" in value || "dense" in value;
|
|
551
|
+
return "size" in value || "variant" in value || "buttonVariant" in value || "buttonVariants" in value || "fullWidth" in value || "inputFullWidth" in value || "buttonFullWidth" in value || "dense" in value || "fieldEditorOptions" in value || "localizationOptions" in value || "layoutOptions" in value || "muiSlotProps" in value || "getLocaleLabel" in value || "getActionLabel" in value;
|
|
500
552
|
}
|
|
501
553
|
function buildMuiBuilderComponents(options) {
|
|
502
554
|
return {
|
|
@@ -512,11 +564,22 @@ function buildMuiBuilderComponents(options) {
|
|
|
512
564
|
renderIcon: muiDefaultIconResolver
|
|
513
565
|
};
|
|
514
566
|
}
|
|
515
|
-
var muiBuilderComponents =
|
|
567
|
+
var muiBuilderComponents = {
|
|
568
|
+
Button: MuiButtonAdapter,
|
|
569
|
+
IconButton: MuiIconButtonAdapter,
|
|
570
|
+
TextInput: MuiTextInputAdapter,
|
|
571
|
+
TextArea: MuiTextAreaAdapter,
|
|
572
|
+
Select: MuiSelectAdapter,
|
|
573
|
+
Checkbox: MuiCheckboxAdapter,
|
|
574
|
+
Section: MuiSectionAdapter,
|
|
575
|
+
Fieldset: MuiFieldsetAdapter,
|
|
576
|
+
ErrorMessage: MuiErrorMessageAdapter,
|
|
577
|
+
renderIcon: muiDefaultIconResolver
|
|
578
|
+
};
|
|
516
579
|
function createMuiBuilderComponents(optionsOrOverrides = {}, customOverrides) {
|
|
517
580
|
const options = isAdapterOptions(optionsOrOverrides) ? optionsOrOverrides : void 0;
|
|
518
581
|
const overrides = customOverrides ?? (options === void 0 ? optionsOrOverrides : {});
|
|
519
|
-
return { ...buildMuiBuilderComponents(options), ...overrides };
|
|
582
|
+
return { ...options === void 0 ? muiBuilderComponents : buildMuiBuilderComponents(options), ...overrides };
|
|
520
583
|
}
|
|
521
584
|
|
|
522
585
|
// src/slots/FieldEditor.tsx
|
|
@@ -526,7 +589,6 @@ import { Card, Stack as Stack3, Typography as Typography3 } from "@mui/material"
|
|
|
526
589
|
import { Stack } from "@mui/material";
|
|
527
590
|
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
528
591
|
function createMuiOptionEditorSlot(options) {
|
|
529
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
530
592
|
return function MuiOptionEditor({
|
|
531
593
|
field,
|
|
532
594
|
option,
|
|
@@ -534,21 +596,23 @@ function createMuiOptionEditorSlot(options) {
|
|
|
534
596
|
currentLocale,
|
|
535
597
|
readOnly,
|
|
536
598
|
actions,
|
|
537
|
-
components
|
|
599
|
+
components,
|
|
600
|
+
translate
|
|
538
601
|
}) {
|
|
602
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
539
603
|
const { IconButton: IconButton2, TextInput } = components;
|
|
540
604
|
const describedBy = option.label.trim().length === 0 ? `mui-option-${option.id}-error` : void 0;
|
|
541
|
-
return /* @__PURE__ */ jsxs5(Stack, { "data-mui-slot": "option-editor", spacing: resolved.dense ? 0.75 : 1, children: [
|
|
605
|
+
return /* @__PURE__ */ jsxs5(Stack, { ...resolved.muiSlotProps?.stack, "data-mui-slot": "option-editor", spacing: resolved.dense ? 0.75 : 1, children: [
|
|
542
606
|
/* @__PURE__ */ jsxs5(Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, alignItems: { sm: "flex-start" }, children: [
|
|
543
607
|
/* @__PURE__ */ jsx11(
|
|
544
608
|
TextInput,
|
|
545
609
|
{
|
|
546
610
|
id: `mui-option-${option.id}`,
|
|
547
|
-
label:
|
|
611
|
+
label: translate("builder.optionLabel", { index: index + 1 }),
|
|
548
612
|
value: option.label,
|
|
549
613
|
required: true,
|
|
550
614
|
error: option.label.trim().length === 0,
|
|
551
|
-
helperText: option.label.trim().length === 0 ? "
|
|
615
|
+
helperText: option.label.trim().length === 0 ? translate("builder.required") : "",
|
|
552
616
|
"aria-describedby": describedBy,
|
|
553
617
|
disabled: readOnly,
|
|
554
618
|
onChange: (value) => actions.updateOption(field.id, option.id, (current) => ({ ...current, label: value }))
|
|
@@ -559,7 +623,7 @@ function createMuiOptionEditorSlot(options) {
|
|
|
559
623
|
IconButton2,
|
|
560
624
|
{
|
|
561
625
|
actionType: "moveUp",
|
|
562
|
-
title:
|
|
626
|
+
title: translate("builder.moveUp", { title: option.label }),
|
|
563
627
|
disabled: readOnly || index === 0,
|
|
564
628
|
onClick: () => actions.moveOption(field.id, option.id, index - 1)
|
|
565
629
|
}
|
|
@@ -568,7 +632,7 @@ function createMuiOptionEditorSlot(options) {
|
|
|
568
632
|
IconButton2,
|
|
569
633
|
{
|
|
570
634
|
actionType: "moveDown",
|
|
571
|
-
title:
|
|
635
|
+
title: translate("builder.moveDown", { title: option.label }),
|
|
572
636
|
disabled: readOnly || index === field.options.length - 1,
|
|
573
637
|
onClick: () => actions.moveOption(field.id, option.id, index + 1)
|
|
574
638
|
}
|
|
@@ -577,7 +641,7 @@ function createMuiOptionEditorSlot(options) {
|
|
|
577
641
|
IconButton2,
|
|
578
642
|
{
|
|
579
643
|
actionType: "delete",
|
|
580
|
-
title:
|
|
644
|
+
title: translate("builder.delete", { title: option.label }),
|
|
581
645
|
disabled: readOnly || field.options.length <= 1,
|
|
582
646
|
onClick: () => actions.removeOption(field.id, option.id)
|
|
583
647
|
}
|
|
@@ -588,10 +652,12 @@ function createMuiOptionEditorSlot(options) {
|
|
|
588
652
|
TextInput,
|
|
589
653
|
{
|
|
590
654
|
id: `mui-option-${option.id}-${currentLocale}`,
|
|
591
|
-
label:
|
|
655
|
+
label: translate("builder.translation", {
|
|
656
|
+
locale: resolved.getLocaleLabel?.(currentLocale) ?? currentLocale
|
|
657
|
+
}),
|
|
592
658
|
value: option.translations?.[currentLocale] ?? "",
|
|
593
659
|
disabled: readOnly,
|
|
594
|
-
onChange: (value) => actions.
|
|
660
|
+
onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "option", id: option.id }, "label", value)
|
|
595
661
|
}
|
|
596
662
|
)
|
|
597
663
|
] });
|
|
@@ -603,7 +669,6 @@ var MuiOptionEditorSlot = createMuiOptionEditorSlot();
|
|
|
603
669
|
import { Stack as Stack2 } from "@mui/material";
|
|
604
670
|
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
605
671
|
function createMuiToolbarSlot(options) {
|
|
606
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
607
672
|
return function MuiToolbar({
|
|
608
673
|
kind,
|
|
609
674
|
index,
|
|
@@ -613,23 +678,26 @@ function createMuiToolbarSlot(options) {
|
|
|
613
678
|
onMoveDown,
|
|
614
679
|
onRemove,
|
|
615
680
|
readOnly,
|
|
616
|
-
components
|
|
681
|
+
components,
|
|
682
|
+
translate
|
|
617
683
|
}) {
|
|
684
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
618
685
|
const { IconButton: IconButton2 } = components;
|
|
619
686
|
return /* @__PURE__ */ jsxs6(
|
|
620
687
|
Stack2,
|
|
621
688
|
{
|
|
689
|
+
...resolved.muiSlotProps?.stack,
|
|
622
690
|
"data-mui-slot": "toolbar",
|
|
623
691
|
direction: "row",
|
|
624
692
|
spacing: resolved.dense ? 0.5 : 1,
|
|
625
693
|
alignItems: "center",
|
|
626
|
-
sx: { mb: resolved.dense ? 1 : 2 },
|
|
694
|
+
sx: resolved.muiSlotProps?.stack?.sx ?? { mb: resolved.dense ? 1 : 2 },
|
|
627
695
|
children: [
|
|
628
696
|
/* @__PURE__ */ jsx12(
|
|
629
697
|
IconButton2,
|
|
630
698
|
{
|
|
631
699
|
actionType: "moveUp",
|
|
632
|
-
title:
|
|
700
|
+
title: translate("builder.moveUp", { title }),
|
|
633
701
|
disabled: readOnly || index === 0,
|
|
634
702
|
onClick: onMoveUp
|
|
635
703
|
}
|
|
@@ -638,7 +706,7 @@ function createMuiToolbarSlot(options) {
|
|
|
638
706
|
IconButton2,
|
|
639
707
|
{
|
|
640
708
|
actionType: "moveDown",
|
|
641
|
-
title:
|
|
709
|
+
title: translate("builder.moveDown", { title }),
|
|
642
710
|
disabled: readOnly || index === total - 1,
|
|
643
711
|
onClick: onMoveDown
|
|
644
712
|
}
|
|
@@ -647,7 +715,7 @@ function createMuiToolbarSlot(options) {
|
|
|
647
715
|
IconButton2,
|
|
648
716
|
{
|
|
649
717
|
actionType: "delete",
|
|
650
|
-
title:
|
|
718
|
+
title: translate("builder.delete", { title }),
|
|
651
719
|
disabled: readOnly || kind !== "page" && total <= 1,
|
|
652
720
|
onClick: onRemove
|
|
653
721
|
}
|
|
@@ -660,7 +728,7 @@ function createMuiToolbarSlot(options) {
|
|
|
660
728
|
var MuiToolbarSlot = createMuiToolbarSlot();
|
|
661
729
|
|
|
662
730
|
// src/slots/FieldEditor.tsx
|
|
663
|
-
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
731
|
+
import { Fragment, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
664
732
|
var FIELD_TYPES = [
|
|
665
733
|
"text",
|
|
666
734
|
"textarea",
|
|
@@ -674,6 +742,16 @@ var FIELD_TYPES = [
|
|
|
674
742
|
function isFieldType(value) {
|
|
675
743
|
return FIELD_TYPES.some((type) => type === value);
|
|
676
744
|
}
|
|
745
|
+
function conditionOperators(field) {
|
|
746
|
+
if (field.type === "multi-select") return ["contains", "not_empty"];
|
|
747
|
+
if (field.type === "text" || field.type === "textarea") {
|
|
748
|
+
return ["equals", "not_equals", "contains", "not_empty"];
|
|
749
|
+
}
|
|
750
|
+
return ["equals", "not_equals", "not_empty"];
|
|
751
|
+
}
|
|
752
|
+
function isConditionOperator(value) {
|
|
753
|
+
return ["equals", "not_equals", "contains", "not_empty"].some((operator) => operator === value);
|
|
754
|
+
}
|
|
677
755
|
function numericValue(value) {
|
|
678
756
|
if (value.trim().length === 0) return void 0;
|
|
679
757
|
const parsed = Number(value);
|
|
@@ -687,7 +765,6 @@ function updateBound(field, property, value) {
|
|
|
687
765
|
return remaining;
|
|
688
766
|
}
|
|
689
767
|
function createMuiFieldEditorSlot(options) {
|
|
690
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
691
768
|
const Toolbar = createMuiToolbarSlot(options);
|
|
692
769
|
const OptionEditor = createMuiOptionEditorSlot(options);
|
|
693
770
|
return function MuiFieldEditor({
|
|
@@ -696,27 +773,34 @@ function createMuiFieldEditorSlot(options) {
|
|
|
696
773
|
index,
|
|
697
774
|
currentLocale,
|
|
698
775
|
policy,
|
|
776
|
+
features,
|
|
699
777
|
readOnly,
|
|
700
778
|
actions,
|
|
701
|
-
components
|
|
779
|
+
components,
|
|
780
|
+
translate
|
|
702
781
|
}) {
|
|
782
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
703
783
|
const { Button: Button2, Checkbox: Checkbox2, Select: Select2, TextArea, TextInput } = components;
|
|
704
784
|
const allowedTypes = policy?.allowedFieldTypes ?? FIELD_TYPES;
|
|
705
785
|
const pageId = schema.pages?.find((page) => page.questionIds.includes(field.id))?.id ?? "";
|
|
706
786
|
const condition = field.displayCondition;
|
|
707
787
|
const conditionSources = schema.fields.slice(0, index);
|
|
788
|
+
const conditionSource = conditionSources.find((source) => source.id === condition?.questionId);
|
|
789
|
+
const descriptionMode = resolved.fieldEditorOptions?.description ?? "editable";
|
|
708
790
|
const titleErrorId = field.title.trim().length === 0 ? `mui-field-${field.id}-title-error` : void 0;
|
|
709
791
|
return /* @__PURE__ */ jsxs7(
|
|
710
792
|
Card,
|
|
711
793
|
{
|
|
794
|
+
...resolved.muiSlotProps?.card,
|
|
712
795
|
"data-mui-slot": "field-editor",
|
|
713
796
|
variant: "outlined",
|
|
714
|
-
sx: { mb: resolved.dense ? 1 : 2, p: resolved.dense ? 1.5 : 2 },
|
|
797
|
+
sx: resolved.muiSlotProps?.card?.sx ?? { mb: resolved.dense ? 1 : 2, p: resolved.dense ? 1.5 : 2 },
|
|
715
798
|
children: [
|
|
716
799
|
/* @__PURE__ */ jsx13(
|
|
717
800
|
Toolbar,
|
|
718
801
|
{
|
|
719
802
|
schema,
|
|
803
|
+
translate,
|
|
720
804
|
kind: "field",
|
|
721
805
|
targetId: field.id,
|
|
722
806
|
index,
|
|
@@ -730,7 +814,7 @@ function createMuiFieldEditorSlot(options) {
|
|
|
730
814
|
components
|
|
731
815
|
}
|
|
732
816
|
),
|
|
733
|
-
/* @__PURE__ */ jsxs7(Stack3, { spacing: resolved.dense ? 1 : 2, children: [
|
|
817
|
+
/* @__PURE__ */ jsxs7(Stack3, { ...resolved.muiSlotProps?.stack, spacing: resolved.dense ? 1 : 2, children: [
|
|
734
818
|
/* @__PURE__ */ jsx13(Typography3, { variant: "subtitle1", fontWeight: "bold", children: field.title }),
|
|
735
819
|
/* @__PURE__ */ jsxs7(Stack3, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
|
|
736
820
|
/* @__PURE__ */ jsx13(
|
|
@@ -738,11 +822,11 @@ function createMuiFieldEditorSlot(options) {
|
|
|
738
822
|
{
|
|
739
823
|
id: `mui-field-${field.id}-title`,
|
|
740
824
|
name: `fields.${field.id}.title`,
|
|
741
|
-
label: "
|
|
825
|
+
label: translate("builder.questionTitle"),
|
|
742
826
|
value: field.title,
|
|
743
827
|
required: true,
|
|
744
828
|
error: field.title.trim().length === 0,
|
|
745
|
-
helperText: field.title.trim().length === 0 ? "
|
|
829
|
+
helperText: field.title.trim().length === 0 ? translate("builder.required") : "",
|
|
746
830
|
"aria-describedby": titleErrorId,
|
|
747
831
|
disabled: readOnly,
|
|
748
832
|
onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "title", value)
|
|
@@ -753,12 +837,11 @@ function createMuiFieldEditorSlot(options) {
|
|
|
753
837
|
{
|
|
754
838
|
id: `mui-field-${field.id}-type`,
|
|
755
839
|
name: `fields.${field.id}.type`,
|
|
756
|
-
label: "
|
|
757
|
-
value: field.type,
|
|
758
|
-
options: FIELD_TYPES.map((type) => ({
|
|
840
|
+
label: translate("builder.type"),
|
|
841
|
+
value: allowedTypes.includes(field.type) ? field.type : "",
|
|
842
|
+
options: FIELD_TYPES.filter((type) => allowedTypes.includes(type)).map((type) => ({
|
|
759
843
|
value: type,
|
|
760
|
-
label: type
|
|
761
|
-
disabled: !allowedTypes.includes(type)
|
|
844
|
+
label: translate(`builder.fieldType.${type}`)
|
|
762
845
|
})),
|
|
763
846
|
disabled: readOnly,
|
|
764
847
|
onChange: (value) => {
|
|
@@ -767,15 +850,16 @@ function createMuiFieldEditorSlot(options) {
|
|
|
767
850
|
}
|
|
768
851
|
)
|
|
769
852
|
] }),
|
|
770
|
-
/* @__PURE__ */ jsx13(
|
|
853
|
+
descriptionMode === "hidden" ? null : /* @__PURE__ */ jsx13(
|
|
771
854
|
TextArea,
|
|
772
855
|
{
|
|
773
856
|
id: `mui-field-${field.id}-description`,
|
|
774
857
|
name: `fields.${field.id}.description`,
|
|
775
|
-
label: "
|
|
858
|
+
label: translate("builder.description"),
|
|
776
859
|
value: field.description ?? "",
|
|
777
860
|
rows: resolved.dense ? 2 : 3,
|
|
778
861
|
disabled: readOnly,
|
|
862
|
+
readOnly: descriptionMode === "readOnly",
|
|
779
863
|
onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "description", value)
|
|
780
864
|
}
|
|
781
865
|
),
|
|
@@ -784,20 +868,20 @@ function createMuiFieldEditorSlot(options) {
|
|
|
784
868
|
{
|
|
785
869
|
id: `mui-field-${field.id}-required`,
|
|
786
870
|
name: `fields.${field.id}.required`,
|
|
787
|
-
label: "
|
|
871
|
+
label: translate("builder.required"),
|
|
788
872
|
checked: field.required,
|
|
789
873
|
disabled: readOnly,
|
|
790
874
|
onChange: (checked) => actions.updateField(field.id, (current) => ({ ...current, required: checked }))
|
|
791
875
|
}
|
|
792
876
|
),
|
|
793
|
-
schema.pages === void 0 ? null : /* @__PURE__ */ jsx13(
|
|
877
|
+
features?.pages === false || schema.pages === void 0 ? null : /* @__PURE__ */ jsx13(
|
|
794
878
|
Select2,
|
|
795
879
|
{
|
|
796
880
|
id: `mui-field-${field.id}-page`,
|
|
797
|
-
label: "
|
|
881
|
+
label: translate("builder.questionPage"),
|
|
798
882
|
value: pageId,
|
|
799
883
|
options: [
|
|
800
|
-
{ value: "", label: "
|
|
884
|
+
{ value: "", label: translate("builder.unassigned") },
|
|
801
885
|
...schema.pages.map((page) => ({ value: page.id, label: page.title ?? page.id }))
|
|
802
886
|
],
|
|
803
887
|
disabled: readOnly,
|
|
@@ -809,7 +893,7 @@ function createMuiFieldEditorSlot(options) {
|
|
|
809
893
|
TextInput,
|
|
810
894
|
{
|
|
811
895
|
id: `mui-field-${field.id}-minimum`,
|
|
812
|
-
label: "
|
|
896
|
+
label: translate("builder.minimum"),
|
|
813
897
|
type: "number",
|
|
814
898
|
value: field.min === void 0 ? "" : String(field.min),
|
|
815
899
|
disabled: readOnly,
|
|
@@ -820,7 +904,7 @@ function createMuiFieldEditorSlot(options) {
|
|
|
820
904
|
TextInput,
|
|
821
905
|
{
|
|
822
906
|
id: `mui-field-${field.id}-maximum`,
|
|
823
|
-
label: "
|
|
907
|
+
label: translate("builder.maximum"),
|
|
824
908
|
type: "number",
|
|
825
909
|
value: field.max === void 0 ? "" : String(field.max),
|
|
826
910
|
disabled: readOnly,
|
|
@@ -828,15 +912,15 @@ function createMuiFieldEditorSlot(options) {
|
|
|
828
912
|
}
|
|
829
913
|
)
|
|
830
914
|
] }) : null,
|
|
831
|
-
conditionSources.length === 0 ? null : /* @__PURE__ */ jsxs7(Stack3, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
|
|
915
|
+
features?.conditions === false || conditionSources.length === 0 ? null : /* @__PURE__ */ jsxs7(Stack3, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
|
|
832
916
|
/* @__PURE__ */ jsx13(
|
|
833
917
|
Select2,
|
|
834
918
|
{
|
|
835
919
|
id: `mui-field-${field.id}-condition-source`,
|
|
836
|
-
label: "
|
|
920
|
+
label: translate("builder.displayCondition"),
|
|
837
921
|
value: condition?.questionId ?? "",
|
|
838
922
|
options: [
|
|
839
|
-
{ value: "", label: "
|
|
923
|
+
{ value: "", label: translate("builder.alwaysVisible") },
|
|
840
924
|
...conditionSources.map((source) => ({ value: source.id, label: source.title }))
|
|
841
925
|
],
|
|
842
926
|
disabled: readOnly,
|
|
@@ -846,45 +930,66 @@ function createMuiFieldEditorSlot(options) {
|
|
|
846
930
|
)
|
|
847
931
|
}
|
|
848
932
|
),
|
|
849
|
-
condition === void 0 ? null : /* @__PURE__ */
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
933
|
+
condition === void 0 ? null : /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
934
|
+
/* @__PURE__ */ jsx13(
|
|
935
|
+
Select2,
|
|
936
|
+
{
|
|
937
|
+
id: `mui-field-${field.id}-condition-operator`,
|
|
938
|
+
label: translate("builder.conditionOperator"),
|
|
939
|
+
value: condition.operator,
|
|
940
|
+
options: (conditionSource === void 0 ? [] : conditionOperators(conditionSource)).map(
|
|
941
|
+
(operator) => ({ value: operator, label: translate(`builder.operator.${operator}`) })
|
|
942
|
+
),
|
|
943
|
+
disabled: readOnly,
|
|
944
|
+
onChange: (value) => {
|
|
945
|
+
if (!isConditionOperator(value)) return;
|
|
946
|
+
actions.setDisplayCondition(
|
|
947
|
+
field.id,
|
|
948
|
+
value === "not_empty" ? { questionId: condition.questionId, operator: value } : { ...condition, operator: value, value: condition.value ?? "" }
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
),
|
|
953
|
+
condition.operator === "not_empty" ? null : /* @__PURE__ */ jsx13(
|
|
954
|
+
TextInput,
|
|
955
|
+
{
|
|
956
|
+
id: `mui-field-${field.id}-condition-value`,
|
|
957
|
+
label: translate("builder.conditionValue"),
|
|
958
|
+
value: condition.value === void 0 ? "" : String(condition.value),
|
|
959
|
+
disabled: readOnly,
|
|
960
|
+
onChange: (value) => actions.setDisplayCondition(field.id, { ...condition, value })
|
|
961
|
+
}
|
|
962
|
+
)
|
|
963
|
+
] })
|
|
859
964
|
] }),
|
|
860
965
|
currentLocale.length === 0 ? null : /* @__PURE__ */ jsxs7(Stack3, { spacing: resolved.dense ? 1 : 2, children: [
|
|
861
|
-
/* @__PURE__ */
|
|
862
|
-
currentLocale
|
|
863
|
-
|
|
864
|
-
] }),
|
|
966
|
+
/* @__PURE__ */ jsx13(Typography3, { variant: "subtitle2", children: translate("builder.translation", {
|
|
967
|
+
locale: resolved.getLocaleLabel?.(currentLocale) ?? currentLocale
|
|
968
|
+
}) }),
|
|
865
969
|
/* @__PURE__ */ jsx13(
|
|
866
970
|
TextInput,
|
|
867
971
|
{
|
|
868
972
|
id: `mui-field-${field.id}-${currentLocale}-title`,
|
|
869
|
-
label: "
|
|
973
|
+
label: translate("builder.translatedQuestionTitle"),
|
|
870
974
|
value: field.translations?.[currentLocale]?.title ?? "",
|
|
871
975
|
disabled: readOnly,
|
|
872
|
-
onChange: (value) => actions.
|
|
976
|
+
onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "field", id: field.id }, "title", value)
|
|
873
977
|
}
|
|
874
978
|
),
|
|
875
|
-
/* @__PURE__ */ jsx13(
|
|
979
|
+
descriptionMode === "hidden" ? null : /* @__PURE__ */ jsx13(
|
|
876
980
|
TextArea,
|
|
877
981
|
{
|
|
878
982
|
id: `mui-field-${field.id}-${currentLocale}-description`,
|
|
879
|
-
label: "
|
|
983
|
+
label: translate("builder.translatedDescription"),
|
|
880
984
|
value: field.translations?.[currentLocale]?.description ?? "",
|
|
881
985
|
disabled: readOnly,
|
|
882
|
-
|
|
986
|
+
readOnly: descriptionMode === "readOnly",
|
|
987
|
+
onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "field", id: field.id }, "description", value)
|
|
883
988
|
}
|
|
884
989
|
)
|
|
885
990
|
] }),
|
|
886
991
|
"options" in field ? /* @__PURE__ */ jsxs7(Stack3, { "data-mui-slot": "options", spacing: resolved.dense ? 1 : 2, children: [
|
|
887
|
-
/* @__PURE__ */ jsx13(Typography3, { variant: "subtitle2", children: "
|
|
992
|
+
/* @__PURE__ */ jsx13(Typography3, { variant: "subtitle2", children: translate("builder.options") }),
|
|
888
993
|
field.options.map((option, optionIndex) => /* @__PURE__ */ jsx13(
|
|
889
994
|
OptionEditor,
|
|
890
995
|
{
|
|
@@ -893,6 +998,7 @@ function createMuiFieldEditorSlot(options) {
|
|
|
893
998
|
option,
|
|
894
999
|
index: optionIndex,
|
|
895
1000
|
currentLocale,
|
|
1001
|
+
translate,
|
|
896
1002
|
readOnly,
|
|
897
1003
|
actions,
|
|
898
1004
|
components
|
|
@@ -906,7 +1012,7 @@ function createMuiFieldEditorSlot(options) {
|
|
|
906
1012
|
targetId: field.id,
|
|
907
1013
|
disabled: readOnly || policy?.maxOptionsPerField !== void 0 && field.options.length >= policy.maxOptionsPerField,
|
|
908
1014
|
onClick: () => actions.addOption(field.id),
|
|
909
|
-
children: "
|
|
1015
|
+
children: translate("builder.addOption")
|
|
910
1016
|
}
|
|
911
1017
|
)
|
|
912
1018
|
] }) : null
|
|
@@ -919,11 +1025,11 @@ function createMuiFieldEditorSlot(options) {
|
|
|
919
1025
|
var MuiFieldEditorSlot = createMuiFieldEditorSlot();
|
|
920
1026
|
|
|
921
1027
|
// src/slots/Localization.tsx
|
|
922
|
-
import {
|
|
1028
|
+
import { ExpandMore } from "@mui/icons-material";
|
|
1029
|
+
import { Accordion, AccordionDetails, AccordionSummary, Box as Box2, Chip, Stack as Stack4, Tab, Tabs, Typography as Typography4 } from "@mui/material";
|
|
923
1030
|
import { useState } from "react";
|
|
924
1031
|
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
925
1032
|
function createMuiLocalizationSlot(options) {
|
|
926
|
-
const resolved = resolveMuiAdapterOptions(options);
|
|
927
1033
|
return function MuiLocalization({
|
|
928
1034
|
schema,
|
|
929
1035
|
currentLocale,
|
|
@@ -931,27 +1037,163 @@ function createMuiLocalizationSlot(options) {
|
|
|
931
1037
|
onAutoTranslate,
|
|
932
1038
|
isTranslating,
|
|
933
1039
|
translationError,
|
|
1040
|
+
policy,
|
|
1041
|
+
translationAdapterAvailable,
|
|
934
1042
|
readOnly,
|
|
935
1043
|
actions,
|
|
936
|
-
components
|
|
1044
|
+
components,
|
|
1045
|
+
translate
|
|
937
1046
|
}) {
|
|
938
|
-
const
|
|
1047
|
+
const resolved = useResolvedMuiAdapterOptions(options);
|
|
1048
|
+
const { Button: Button2, ErrorMessage, Select: Select2, TextArea, TextInput } = components;
|
|
939
1049
|
const [newLocale, setNewLocale] = useState("");
|
|
940
1050
|
const locales = Array.from(
|
|
941
|
-
|
|
942
|
-
...schema.supportedLocales ?? [],
|
|
943
|
-
...schema.defaultLocale === void 0 ? [] : [schema.defaultLocale]
|
|
944
|
-
])
|
|
1051
|
+
new Set((schema.supportedLocales ?? []).filter((locale) => locale !== schema.defaultLocale))
|
|
945
1052
|
);
|
|
1053
|
+
const editingLocaleConfigured = locales.includes(currentLocale);
|
|
1054
|
+
const registeredLocales = /* @__PURE__ */ new Set([
|
|
1055
|
+
...schema.defaultLocale === void 0 ? [] : [schema.defaultLocale],
|
|
1056
|
+
...schema.supportedLocales ?? []
|
|
1057
|
+
]);
|
|
1058
|
+
const availableAllowedLocales = policy?.allowedLocales?.filter((locale) => !registeredLocales.has(locale));
|
|
1059
|
+
const localeLimitReached = policy?.maxLocales !== void 0 && registeredLocales.size >= policy.maxLocales;
|
|
1060
|
+
const normalizedLocale = newLocale.trim();
|
|
1061
|
+
const localeAllowed = policy?.allowedLocales === void 0 || policy.allowedLocales.includes(normalizedLocale);
|
|
1062
|
+
const canAddLocale = !readOnly && normalizedLocale.length > 0 && localeAllowed && !registeredLocales.has(normalizedLocale) && !localeLimitReached;
|
|
946
1063
|
const handleTabChange = (_event, value) => onCurrentLocaleChange(value);
|
|
947
1064
|
const addLocale = () => {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
const result = actions.addLocale(normalized);
|
|
1065
|
+
if (!canAddLocale) return;
|
|
1066
|
+
const result = actions.addLocale(normalizedLocale);
|
|
951
1067
|
if (!result.success) return;
|
|
952
|
-
onCurrentLocaleChange(
|
|
1068
|
+
onCurrentLocaleChange(normalizedLocale);
|
|
953
1069
|
setNewLocale("");
|
|
954
1070
|
};
|
|
1071
|
+
const stackProps = resolved.muiSlotProps?.stack;
|
|
1072
|
+
const collapsible = resolved.localizationOptions?.collapsible ?? false;
|
|
1073
|
+
const defaultLocaleControl = resolved.localizationOptions?.defaultLocaleControl ?? "editable";
|
|
1074
|
+
const content = /* @__PURE__ */ jsxs8(Stack4, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
|
|
1075
|
+
!collapsible ? /* @__PURE__ */ jsx14(Typography4, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }) : null,
|
|
1076
|
+
/* @__PURE__ */ jsxs8(Stack4, { ...stackProps, direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
|
|
1077
|
+
defaultLocaleControl === "hidden" ? null : defaultLocaleControl === "readOnly" ? /* @__PURE__ */ jsxs8(Stack4, { spacing: 0.5, children: [
|
|
1078
|
+
/* @__PURE__ */ jsx14(Typography4, { variant: "caption", color: "text.secondary", children: translate("builder.defaultLocale") }),
|
|
1079
|
+
/* @__PURE__ */ jsx14(
|
|
1080
|
+
Chip,
|
|
1081
|
+
{
|
|
1082
|
+
label: resolved.getLocaleLabel?.(schema.defaultLocale ?? "") ?? schema.defaultLocale ?? "",
|
|
1083
|
+
size: resolved.size
|
|
1084
|
+
}
|
|
1085
|
+
)
|
|
1086
|
+
] }) : /* @__PURE__ */ jsx14(
|
|
1087
|
+
TextInput,
|
|
1088
|
+
{
|
|
1089
|
+
id: "mui-builder-default-locale",
|
|
1090
|
+
label: translate("builder.defaultLocale"),
|
|
1091
|
+
value: schema.defaultLocale ?? "",
|
|
1092
|
+
disabled: readOnly,
|
|
1093
|
+
onChange: (value) => {
|
|
1094
|
+
const result = actions.setDefaultLocale(value);
|
|
1095
|
+
if (result.success && value === currentLocale) onCurrentLocaleChange("");
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
),
|
|
1099
|
+
availableAllowedLocales === void 0 ? /* @__PURE__ */ jsx14(
|
|
1100
|
+
TextInput,
|
|
1101
|
+
{
|
|
1102
|
+
id: "mui-builder-new-locale",
|
|
1103
|
+
label: translate("builder.addLocale"),
|
|
1104
|
+
value: newLocale,
|
|
1105
|
+
disabled: readOnly || localeLimitReached,
|
|
1106
|
+
onChange: setNewLocale
|
|
1107
|
+
}
|
|
1108
|
+
) : /* @__PURE__ */ jsx14(
|
|
1109
|
+
Select2,
|
|
1110
|
+
{
|
|
1111
|
+
id: "mui-builder-new-locale",
|
|
1112
|
+
label: translate("builder.addLocale"),
|
|
1113
|
+
value: newLocale,
|
|
1114
|
+
options: [
|
|
1115
|
+
{ value: "", label: "\u2014" },
|
|
1116
|
+
...availableAllowedLocales.map((locale) => ({
|
|
1117
|
+
value: locale,
|
|
1118
|
+
label: resolved.getLocaleLabel?.(locale) ?? locale
|
|
1119
|
+
}))
|
|
1120
|
+
],
|
|
1121
|
+
disabled: readOnly || localeLimitReached || availableAllowedLocales.length === 0,
|
|
1122
|
+
onChange: setNewLocale
|
|
1123
|
+
}
|
|
1124
|
+
),
|
|
1125
|
+
/* @__PURE__ */ jsx14(Button2, { variant: "primary", action: "addLocale", disabled: !canAddLocale, onClick: addLocale, children: translate("builder.addLocale") })
|
|
1126
|
+
] }),
|
|
1127
|
+
locales.length === 0 ? null : /* @__PURE__ */ jsx14(
|
|
1128
|
+
Tabs,
|
|
1129
|
+
{
|
|
1130
|
+
value: editingLocaleConfigured ? currentLocale : false,
|
|
1131
|
+
onChange: handleTabChange,
|
|
1132
|
+
variant: "scrollable",
|
|
1133
|
+
scrollButtons: "auto",
|
|
1134
|
+
"aria-label": translate("builder.translationLocale"),
|
|
1135
|
+
children: locales.map((locale) => /* @__PURE__ */ jsx14(
|
|
1136
|
+
Tab,
|
|
1137
|
+
{
|
|
1138
|
+
value: locale,
|
|
1139
|
+
label: resolved.getLocaleLabel?.(locale) ?? locale,
|
|
1140
|
+
disabled: readOnly && locale !== currentLocale
|
|
1141
|
+
},
|
|
1142
|
+
locale
|
|
1143
|
+
))
|
|
1144
|
+
}
|
|
1145
|
+
),
|
|
1146
|
+
!translationAdapterAvailable ? null : /* @__PURE__ */ jsx14(
|
|
1147
|
+
Button2,
|
|
1148
|
+
{
|
|
1149
|
+
variant: "secondary",
|
|
1150
|
+
disabled: readOnly || !editingLocaleConfigured || isTranslating,
|
|
1151
|
+
onClick: onAutoTranslate,
|
|
1152
|
+
children: isTranslating ? translate("builder.translating") : translate("builder.autoTranslate")
|
|
1153
|
+
}
|
|
1154
|
+
),
|
|
1155
|
+
translationError === void 0 ? null : /* @__PURE__ */ jsx14(ErrorMessage, { message: translationError }),
|
|
1156
|
+
!editingLocaleConfigured ? /* @__PURE__ */ jsx14(Typography4, { variant: "body2", color: "text.secondary", children: translate("builder.selectLocale") }) : /* @__PURE__ */ jsxs8(Stack4, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
|
|
1157
|
+
/* @__PURE__ */ jsx14(
|
|
1158
|
+
TextInput,
|
|
1159
|
+
{
|
|
1160
|
+
id: `mui-builder-${currentLocale}-form-title`,
|
|
1161
|
+
label: translate("builder.translatedFormTitle"),
|
|
1162
|
+
value: schema.translations?.[currentLocale]?.title ?? "",
|
|
1163
|
+
disabled: readOnly,
|
|
1164
|
+
onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "form" }, "title", value)
|
|
1165
|
+
}
|
|
1166
|
+
),
|
|
1167
|
+
/* @__PURE__ */ jsx14(
|
|
1168
|
+
TextArea,
|
|
1169
|
+
{
|
|
1170
|
+
id: `mui-builder-${currentLocale}-form-description`,
|
|
1171
|
+
label: translate("builder.translatedFormDescription"),
|
|
1172
|
+
value: schema.translations?.[currentLocale]?.description ?? "",
|
|
1173
|
+
disabled: readOnly,
|
|
1174
|
+
onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "form" }, "description", value)
|
|
1175
|
+
}
|
|
1176
|
+
),
|
|
1177
|
+
/* @__PURE__ */ jsx14(
|
|
1178
|
+
TextInput,
|
|
1179
|
+
{
|
|
1180
|
+
id: `mui-builder-${currentLocale}-completion-message`,
|
|
1181
|
+
label: translate("builder.translatedCompletionMessage"),
|
|
1182
|
+
value: schema.translations?.[currentLocale]?.completionMessage ?? "",
|
|
1183
|
+
disabled: readOnly,
|
|
1184
|
+
onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "form" }, "completionMessage", value)
|
|
1185
|
+
}
|
|
1186
|
+
)
|
|
1187
|
+
] })
|
|
1188
|
+
] });
|
|
1189
|
+
const configured = locales.length > 0;
|
|
1190
|
+
const defaultExpanded = resolved.localizationOptions?.defaultExpanded === "when-configured" ? configured : resolved.localizationOptions?.defaultExpanded ?? false;
|
|
1191
|
+
if (collapsible) {
|
|
1192
|
+
return /* @__PURE__ */ jsxs8(Accordion, { ...resolved.muiSlotProps?.accordion, "data-mui-slot": "localization", defaultExpanded, children: [
|
|
1193
|
+
/* @__PURE__ */ jsx14(AccordionSummary, { expandIcon: /* @__PURE__ */ jsx14(ExpandMore, {}), children: /* @__PURE__ */ jsx14(Typography4, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }) }),
|
|
1194
|
+
/* @__PURE__ */ jsx14(AccordionDetails, { children: content })
|
|
1195
|
+
] });
|
|
1196
|
+
}
|
|
955
1197
|
return /* @__PURE__ */ jsx14(
|
|
956
1198
|
Box2,
|
|
957
1199
|
{
|
|
@@ -963,95 +1205,7 @@ function createMuiLocalizationSlot(options) {
|
|
|
963
1205
|
borderColor: "divider",
|
|
964
1206
|
borderRadius: 1
|
|
965
1207
|
},
|
|
966
|
-
children:
|
|
967
|
-
/* @__PURE__ */ jsx14(Typography4, { variant: "subtitle1", fontWeight: "bold", children: "Localization" }),
|
|
968
|
-
/* @__PURE__ */ jsx14(
|
|
969
|
-
TextInput,
|
|
970
|
-
{
|
|
971
|
-
id: "mui-builder-completion-message",
|
|
972
|
-
label: "Completion message",
|
|
973
|
-
value: schema.completionMessage ?? "",
|
|
974
|
-
disabled: readOnly,
|
|
975
|
-
onChange: (value) => actions.setSourceText({ kind: "form" }, "completionMessage", value)
|
|
976
|
-
}
|
|
977
|
-
),
|
|
978
|
-
/* @__PURE__ */ jsxs8(Stack4, { direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
|
|
979
|
-
/* @__PURE__ */ jsx14(
|
|
980
|
-
TextInput,
|
|
981
|
-
{
|
|
982
|
-
id: "mui-builder-default-locale",
|
|
983
|
-
label: "Default locale",
|
|
984
|
-
value: schema.defaultLocale ?? "",
|
|
985
|
-
disabled: readOnly,
|
|
986
|
-
onChange: (value) => actions.setDefaultLocale(value)
|
|
987
|
-
}
|
|
988
|
-
),
|
|
989
|
-
/* @__PURE__ */ jsx14(
|
|
990
|
-
TextInput,
|
|
991
|
-
{
|
|
992
|
-
id: "mui-builder-new-locale",
|
|
993
|
-
label: "Add locale",
|
|
994
|
-
value: newLocale,
|
|
995
|
-
disabled: readOnly,
|
|
996
|
-
onChange: setNewLocale
|
|
997
|
-
}
|
|
998
|
-
),
|
|
999
|
-
/* @__PURE__ */ jsx14(Button2, { disabled: readOnly || newLocale.trim().length === 0, onClick: addLocale, children: "Add locale" })
|
|
1000
|
-
] }),
|
|
1001
|
-
locales.length === 0 ? null : /* @__PURE__ */ jsx14(
|
|
1002
|
-
Tabs,
|
|
1003
|
-
{
|
|
1004
|
-
value: locales.includes(currentLocale) ? currentLocale : false,
|
|
1005
|
-
onChange: handleTabChange,
|
|
1006
|
-
variant: "scrollable",
|
|
1007
|
-
scrollButtons: "auto",
|
|
1008
|
-
"aria-label": "Translation locale",
|
|
1009
|
-
children: locales.map((locale) => /* @__PURE__ */ jsx14(Tab, { value: locale, label: locale, disabled: readOnly && locale !== currentLocale }, locale))
|
|
1010
|
-
}
|
|
1011
|
-
),
|
|
1012
|
-
/* @__PURE__ */ jsx14(
|
|
1013
|
-
Button2,
|
|
1014
|
-
{
|
|
1015
|
-
variant: "secondary",
|
|
1016
|
-
disabled: readOnly || currentLocale.length === 0 || isTranslating,
|
|
1017
|
-
onClick: onAutoTranslate,
|
|
1018
|
-
children: isTranslating ? "Translating\u2026" : "Translate all text"
|
|
1019
|
-
}
|
|
1020
|
-
),
|
|
1021
|
-
translationError === void 0 ? null : /* @__PURE__ */ jsx14(ErrorMessage, { message: translationError }),
|
|
1022
|
-
currentLocale.length === 0 ? /* @__PURE__ */ jsx14(Typography4, { variant: "body2", color: "text.secondary", children: "Select a locale to edit translations." }) : /* @__PURE__ */ jsxs8(Stack4, { spacing: resolved.dense ? 1 : 2, children: [
|
|
1023
|
-
/* @__PURE__ */ jsx14(
|
|
1024
|
-
TextInput,
|
|
1025
|
-
{
|
|
1026
|
-
id: `mui-builder-${currentLocale}-form-title`,
|
|
1027
|
-
label: "Translated form title",
|
|
1028
|
-
value: schema.translations?.[currentLocale]?.title ?? "",
|
|
1029
|
-
disabled: readOnly,
|
|
1030
|
-
onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "form" }, "title", value)
|
|
1031
|
-
}
|
|
1032
|
-
),
|
|
1033
|
-
/* @__PURE__ */ jsx14(
|
|
1034
|
-
TextArea,
|
|
1035
|
-
{
|
|
1036
|
-
id: `mui-builder-${currentLocale}-form-description`,
|
|
1037
|
-
label: "Translated form description",
|
|
1038
|
-
value: schema.translations?.[currentLocale]?.description ?? "",
|
|
1039
|
-
disabled: readOnly,
|
|
1040
|
-
onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "form" }, "description", value)
|
|
1041
|
-
}
|
|
1042
|
-
),
|
|
1043
|
-
/* @__PURE__ */ jsx14(
|
|
1044
|
-
TextInput,
|
|
1045
|
-
{
|
|
1046
|
-
id: `mui-builder-${currentLocale}-completion-message`,
|
|
1047
|
-
label: "Translated completion message",
|
|
1048
|
-
value: schema.translations?.[currentLocale]?.completionMessage ?? "",
|
|
1049
|
-
disabled: readOnly,
|
|
1050
|
-
onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "form" }, "completionMessage", value)
|
|
1051
|
-
}
|
|
1052
|
-
)
|
|
1053
|
-
] })
|
|
1054
|
-
] })
|
|
1208
|
+
children: content
|
|
1055
1209
|
}
|
|
1056
1210
|
);
|
|
1057
1211
|
};
|
|
@@ -1060,13 +1214,15 @@ var MuiLocalizationSlot = createMuiLocalizationSlot();
|
|
|
1060
1214
|
|
|
1061
1215
|
// src/slots/index.ts
|
|
1062
1216
|
var muiBuilderSlots = {
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1217
|
+
sectionOrder: DEFAULT_MUI_SECTION_ORDER,
|
|
1218
|
+
toolbar: MuiToolbarSlot,
|
|
1219
|
+
fieldEditor: MuiFieldEditorSlot,
|
|
1220
|
+
optionEditor: MuiOptionEditorSlot,
|
|
1221
|
+
localization: MuiLocalizationSlot
|
|
1067
1222
|
};
|
|
1068
1223
|
function createMuiBuilderSlots(options, customOverrides = {}) {
|
|
1069
1224
|
return {
|
|
1225
|
+
sectionOrder: options?.layoutOptions?.sectionOrder ?? DEFAULT_MUI_SECTION_ORDER,
|
|
1070
1226
|
toolbar: createMuiToolbarSlot(options),
|
|
1071
1227
|
fieldEditor: createMuiFieldEditorSlot(options),
|
|
1072
1228
|
optionEditor: createMuiOptionEditorSlot(options),
|
|
@@ -1092,24 +1248,46 @@ import { useMemo } from "react";
|
|
|
1092
1248
|
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1093
1249
|
function MuiFormBuilder({
|
|
1094
1250
|
muiOptions,
|
|
1251
|
+
layoutOptions,
|
|
1252
|
+
localizationOptions,
|
|
1253
|
+
muiSlotProps,
|
|
1095
1254
|
components: customComponents,
|
|
1096
1255
|
slots: customSlots,
|
|
1256
|
+
sectionOrder,
|
|
1097
1257
|
...props
|
|
1098
1258
|
}) {
|
|
1099
|
-
const
|
|
1100
|
-
() =>
|
|
1101
|
-
|
|
1259
|
+
const contextOptions = useMemo(
|
|
1260
|
+
() => mergeMuiAdapterOptions(muiOptions, {
|
|
1261
|
+
...layoutOptions === void 0 ? {} : { layoutOptions },
|
|
1262
|
+
...localizationOptions === void 0 ? {} : { localizationOptions },
|
|
1263
|
+
...muiSlotProps === void 0 ? {} : { muiSlotProps }
|
|
1264
|
+
}),
|
|
1265
|
+
[layoutOptions, localizationOptions, muiOptions, muiSlotProps]
|
|
1102
1266
|
);
|
|
1103
|
-
const
|
|
1104
|
-
|
|
1267
|
+
const contextValue = useMemo(() => ({ options: contextOptions }), [contextOptions]);
|
|
1268
|
+
const components = useMemo(() => ({ ...muiBuilderComponents, ...customComponents }), [customComponents]);
|
|
1269
|
+
const slots = useMemo(() => ({ ...muiBuilderSlots, ...customSlots }), [customSlots]);
|
|
1270
|
+
const resolvedSectionOrder = sectionOrder ?? contextOptions.layoutOptions?.sectionOrder;
|
|
1271
|
+
return /* @__PURE__ */ jsx15(MuiFormBuilderContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx15(
|
|
1272
|
+
FormBuilder,
|
|
1273
|
+
{
|
|
1274
|
+
...props,
|
|
1275
|
+
components,
|
|
1276
|
+
disableDefaultStyles: true,
|
|
1277
|
+
slots,
|
|
1278
|
+
...resolvedSectionOrder === void 0 ? {} : { sectionOrder: resolvedSectionOrder }
|
|
1279
|
+
}
|
|
1280
|
+
) });
|
|
1105
1281
|
}
|
|
1106
1282
|
export {
|
|
1283
|
+
DEFAULT_MUI_SECTION_ORDER,
|
|
1107
1284
|
MuiButtonAdapter,
|
|
1108
1285
|
MuiCheckboxAdapter,
|
|
1109
1286
|
MuiErrorMessageAdapter,
|
|
1110
1287
|
MuiFieldEditorSlot,
|
|
1111
1288
|
MuiFieldsetAdapter,
|
|
1112
1289
|
MuiFormBuilder,
|
|
1290
|
+
MuiFormBuilderContext,
|
|
1113
1291
|
MuiIconButtonAdapter,
|
|
1114
1292
|
MuiLocalizationSlot,
|
|
1115
1293
|
MuiOptionEditorSlot,
|
|
@@ -1134,8 +1312,10 @@ export {
|
|
|
1134
1312
|
createMuiTextAreaAdapter,
|
|
1135
1313
|
createMuiTextInputAdapter,
|
|
1136
1314
|
createMuiToolbarSlot,
|
|
1315
|
+
mergeMuiAdapterOptions,
|
|
1137
1316
|
muiBuilderComponents,
|
|
1138
1317
|
muiBuilderSlots,
|
|
1139
1318
|
muiDefaultIconResolver,
|
|
1140
|
-
resolveMuiAdapterOptions
|
|
1319
|
+
resolveMuiAdapterOptions,
|
|
1320
|
+
useResolvedMuiAdapterOptions
|
|
1141
1321
|
};
|