@form-engine-ts/mui 2.9.2 → 2.9.4

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/dist/index.js CHANGED
@@ -1,333 +1,1258 @@
1
- // src/index.tsx
2
- import {
3
- Add,
4
- ArrowDownward,
5
- ArrowUpward,
6
- Close,
7
- Delete,
8
- DragHandle,
9
- Edit,
10
- Settings,
11
- Translate
12
- } from "@mui/icons-material";
13
- import {
14
- Alert,
15
- Box,
16
- Button,
17
- Checkbox,
18
- FormControl,
19
- FormControlLabel,
20
- FormHelperText,
21
- IconButton,
22
- InputLabel,
23
- MenuItem,
24
- Paper,
25
- Select,
26
- TextField,
27
- Typography
28
- } from "@mui/material";
29
- import { jsx, jsxs } from "react/jsx-runtime";
30
- function MuiButtonAdapter({
31
- id,
32
- className,
33
- disabled,
34
- "aria-label": ariaLabel,
35
- onClick,
36
- children,
37
- title,
38
- variant = "secondary",
39
- action,
40
- targetId
41
- }) {
42
- return /* @__PURE__ */ jsx(
43
- Button,
44
- {
45
- id,
46
- className,
47
- type: "button",
48
- disabled,
49
- "aria-label": ariaLabel,
50
- title,
51
- "data-builder-action": action,
52
- "data-target-id": targetId,
53
- onClick,
54
- color: variant === "danger" ? "error" : "primary",
55
- variant: variant === "primary" ? "contained" : "outlined",
56
- children
57
- }
58
- );
1
+ // src/adapters/Button.tsx
2
+ import { Button } from "@mui/material";
3
+
4
+ // src/types.ts
5
+ var DEFAULT_MUI_SECTION_ORDER = [
6
+ "basicSettings",
7
+ "questions",
8
+ "addQuestion",
9
+ "localization"
10
+ ];
11
+ function resolveMuiAdapterOptions(options = {}) {
12
+ const buttonVariant = options.buttonVariant ?? "contained";
13
+ return {
14
+ size: options.size ?? "medium",
15
+ variant: options.variant ?? "outlined",
16
+ buttonVariant,
17
+ buttonVariants: {
18
+ primary: options.buttonVariants?.primary ?? buttonVariant,
19
+ secondary: options.buttonVariants?.secondary ?? buttonVariant,
20
+ danger: options.buttonVariants?.danger ?? buttonVariant
21
+ },
22
+ fullWidth: options.fullWidth ?? true,
23
+ dense: options.dense ?? false,
24
+ getLocaleLabel: options.getLocaleLabel ?? ((locale) => locale),
25
+ ...options.getActionLabel === void 0 ? {} : { getActionLabel: options.getActionLabel },
26
+ layoutOptions: options.layoutOptions ?? {},
27
+ localizationOptions: {
28
+ collapsible: options.localizationOptions?.collapsible ?? false,
29
+ defaultExpanded: options.localizationOptions?.defaultExpanded ?? false
30
+ },
31
+ muiSlotProps: options.muiSlotProps ?? {}
32
+ };
59
33
  }
60
- function MuiIconButtonAdapter({
61
- id,
62
- className,
63
- disabled,
64
- readOnly,
65
- "aria-label": ariaLabel,
66
- "aria-describedby": ariaDescribedBy,
67
- "aria-labelledby": ariaLabelledBy,
68
- onClick,
69
- icon,
70
- title
71
- }) {
72
- return /* @__PURE__ */ jsx(
73
- IconButton,
74
- {
75
- id,
76
- className,
77
- component: "button",
78
- type: "button",
79
- disabled: disabled || readOnly,
80
- "aria-label": ariaLabel ?? title,
81
- "aria-describedby": ariaDescribedBy,
82
- "aria-labelledby": ariaLabelledBy,
83
- title,
84
- onClick,
85
- sx: { minWidth: 0, padding: 0.5 },
86
- children: icon
87
- }
88
- );
89
- }
90
- function MuiTextInputAdapter({
91
- id,
92
- className,
93
- disabled,
94
- readOnly,
95
- "aria-label": ariaLabel,
96
- "aria-describedby": ariaDescribedBy,
97
- "aria-labelledby": ariaLabelledBy,
98
- name,
99
- label,
100
- required,
101
- error,
102
- helperText,
103
- value,
104
- onChange,
105
- placeholder,
106
- maxLength,
107
- inputMode,
108
- type = "text",
109
- min,
110
- max,
111
- step
112
- }) {
113
- return /* @__PURE__ */ jsx(
114
- TextField,
115
- {
116
- id,
117
- className,
118
- name,
119
- label,
120
- required,
121
- error,
122
- helperText,
123
- value,
124
- disabled,
125
- slotProps: {
126
- htmlInput: { maxLength, min, max, step, inputMode },
127
- input: { readOnly },
128
- formHelperText: { id: ariaDescribedBy }
129
- },
130
- type,
131
- placeholder,
132
- "aria-label": ariaLabel,
133
- "aria-describedby": ariaDescribedBy,
134
- "aria-labelledby": ariaLabelledBy,
135
- fullWidth: true,
136
- variant: "outlined",
137
- onChange: (event) => onChange(event.currentTarget.value)
138
- }
139
- );
140
- }
141
- function MuiTextAreaAdapter({
142
- id,
143
- className,
144
- disabled,
145
- readOnly,
146
- "aria-label": ariaLabel,
147
- "aria-describedby": ariaDescribedBy,
148
- "aria-labelledby": ariaLabelledBy,
149
- name,
150
- label,
151
- required,
152
- error,
153
- helperText,
154
- value,
155
- onChange,
156
- placeholder,
157
- maxLength,
158
- rows
159
- }) {
160
- return /* @__PURE__ */ jsx(
161
- TextField,
162
- {
163
- id,
164
- className,
165
- name,
166
- label,
167
- required,
168
- error,
169
- helperText,
170
- value,
171
- disabled,
172
- slotProps: {
173
- htmlInput: { maxLength },
174
- input: { readOnly },
175
- formHelperText: { id: ariaDescribedBy }
176
- },
177
- multiline: true,
178
- rows,
179
- placeholder,
180
- "aria-label": ariaLabel,
181
- "aria-describedby": ariaDescribedBy,
182
- "aria-labelledby": ariaLabelledBy,
183
- fullWidth: true,
184
- variant: "outlined",
185
- onChange: (event) => onChange(event.currentTarget.value)
186
- }
187
- );
188
- }
189
- function MuiSelectAdapter({
190
- id,
191
- className,
192
- disabled,
193
- readOnly,
194
- "aria-label": ariaLabel,
195
- "aria-describedby": ariaDescribedBy,
196
- "aria-labelledby": ariaLabelledBy,
197
- name,
198
- label,
199
- required,
200
- error,
201
- helperText,
202
- value,
203
- onChange,
204
- options
205
- }) {
206
- const labelId = id === void 0 ? void 0 : `${id}-label`;
207
- const handleChange = (event) => onChange(event.target.value);
208
- return /* @__PURE__ */ jsxs(FormControl, { className, fullWidth: true, error, required, disabled, children: [
209
- label === void 0 ? null : /* @__PURE__ */ jsx(InputLabel, { id: labelId, children: label }),
210
- /* @__PURE__ */ jsx(
211
- Select,
34
+
35
+ // src/adapters/Button.tsx
36
+ import { jsx } from "react/jsx-runtime";
37
+ function createMuiButtonAdapter(options) {
38
+ const resolved = resolveMuiAdapterOptions(options);
39
+ return function MuiButton({
40
+ id,
41
+ className,
42
+ disabled,
43
+ readOnly,
44
+ "aria-label": ariaLabel,
45
+ "aria-describedby": ariaDescribedBy,
46
+ "aria-labelledby": ariaLabelledBy,
47
+ onClick,
48
+ children,
49
+ title,
50
+ variant,
51
+ action,
52
+ targetId
53
+ }) {
54
+ return /* @__PURE__ */ jsx(
55
+ Button,
212
56
  {
213
57
  id,
214
- labelId,
215
- name,
216
- label,
217
- value,
218
- onChange: handleChange,
219
- readOnly,
58
+ className,
59
+ type: "button",
60
+ size: resolved.size,
61
+ disabled: disabled || readOnly,
220
62
  "aria-label": ariaLabel,
221
63
  "aria-describedby": ariaDescribedBy,
222
64
  "aria-labelledby": ariaLabelledBy,
223
- variant: "outlined",
224
- children: options.map((option) => /* @__PURE__ */ jsx(MenuItem, { value: option.value, disabled: option.disabled, children: option.label }, option.value))
65
+ title,
66
+ "data-builder-action": action,
67
+ "data-target-id": targetId,
68
+ onClick,
69
+ color: variant === "danger" ? "error" : "primary",
70
+ variant: resolved.buttonVariants?.[variant ?? "primary"] ?? resolved.buttonVariant,
71
+ fullWidth: resolved.fullWidth,
72
+ children
225
73
  }
226
- ),
227
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx(FormHelperText, { id: ariaDescribedBy, children: helperText })
228
- ] });
74
+ );
75
+ };
229
76
  }
230
- function MuiCheckboxAdapter({
231
- id,
232
- className,
233
- disabled,
234
- readOnly,
235
- "aria-label": ariaLabel,
236
- checked,
237
- onChange,
238
- label
239
- }) {
240
- return /* @__PURE__ */ jsx(
241
- FormControlLabel,
242
- {
243
- className,
244
- label,
245
- control: /* @__PURE__ */ jsx(
246
- Checkbox,
77
+ var MuiButtonAdapter = createMuiButtonAdapter();
78
+
79
+ // src/adapters/Checkbox.tsx
80
+ import { Checkbox, FormControl, FormControlLabel, FormHelperText } from "@mui/material";
81
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
82
+ function createMuiCheckboxAdapter(options) {
83
+ const resolved = resolveMuiAdapterOptions(options);
84
+ return function MuiCheckbox({
85
+ id,
86
+ className,
87
+ disabled,
88
+ readOnly,
89
+ "aria-label": ariaLabel,
90
+ "aria-describedby": ariaDescribedBy,
91
+ "aria-labelledby": ariaLabelledBy,
92
+ name,
93
+ required,
94
+ error,
95
+ helperText,
96
+ checked,
97
+ onChange,
98
+ label
99
+ }) {
100
+ return /* @__PURE__ */ jsxs(FormControl, { className, error: Boolean(error), required, disabled: disabled || readOnly, children: [
101
+ /* @__PURE__ */ jsx2(
102
+ FormControlLabel,
247
103
  {
248
- id,
249
- checked,
250
- disabled: disabled || readOnly,
251
- inputProps: { "aria-label": ariaLabel },
252
- onChange: (event) => onChange(event.target.checked)
104
+ label,
105
+ control: /* @__PURE__ */ jsx2(
106
+ Checkbox,
107
+ {
108
+ id,
109
+ name,
110
+ size: resolved.size,
111
+ checked,
112
+ required,
113
+ disabled: disabled || readOnly,
114
+ inputProps: {
115
+ "aria-label": ariaLabel,
116
+ "aria-describedby": ariaDescribedBy,
117
+ "aria-labelledby": ariaLabelledBy
118
+ },
119
+ onChange: (event) => onChange(event.target.checked)
120
+ }
121
+ )
253
122
  }
254
- )
255
- }
256
- );
123
+ ),
124
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx2(FormHelperText, { id: ariaDescribedBy, children: helperText })
125
+ ] });
126
+ };
257
127
  }
258
- function MuiSectionAdapter({
259
- id,
260
- className,
261
- title,
262
- description,
263
- headingId,
264
- "aria-label": ariaLabel,
265
- children
266
- }) {
267
- return /* @__PURE__ */ jsxs(
268
- Paper,
269
- {
270
- id,
271
- className,
272
- "aria-label": ariaLabel,
273
- "aria-labelledby": title === void 0 ? void 0 : headingId,
274
- sx: { p: 2, mb: 2 },
275
- children: [
276
- title === void 0 ? null : /* @__PURE__ */ jsx(Typography, { id: headingId, variant: "h6", children: title }),
277
- description === void 0 ? null : /* @__PURE__ */ jsx(Typography, { variant: "body2", children: description }),
278
- children
279
- ]
280
- }
281
- );
128
+ var MuiCheckboxAdapter = createMuiCheckboxAdapter();
129
+
130
+ // src/adapters/ErrorMessage.tsx
131
+ import { Alert } from "@mui/material";
132
+ import { jsx as jsx3 } from "react/jsx-runtime";
133
+ function createMuiErrorMessageAdapter(_options) {
134
+ return function MuiErrorMessage({
135
+ id,
136
+ className,
137
+ "aria-label": ariaLabel,
138
+ "aria-describedby": ariaDescribedBy,
139
+ "aria-labelledby": ariaLabelledBy,
140
+ message
141
+ }) {
142
+ return /* @__PURE__ */ jsx3(
143
+ Alert,
144
+ {
145
+ id,
146
+ className,
147
+ severity: "error",
148
+ "aria-label": ariaLabel,
149
+ "aria-describedby": ariaDescribedBy,
150
+ "aria-labelledby": ariaLabelledBy,
151
+ sx: { my: 1 },
152
+ children: message
153
+ }
154
+ );
155
+ };
282
156
  }
283
- function MuiFieldsetAdapter({ className, legend, disabled, children }) {
284
- return /* @__PURE__ */ jsxs(Box, { component: "fieldset", className, disabled, sx: { border: 0, m: 0, p: 0 }, children: [
285
- legend === void 0 ? null : /* @__PURE__ */ jsx(Typography, { component: "legend", variant: "subtitle1", children: legend }),
157
+ var MuiErrorMessageAdapter = createMuiErrorMessageAdapter();
158
+
159
+ // src/adapters/Fieldset.tsx
160
+ import { Box, Typography } from "@mui/material";
161
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
162
+ function createMuiFieldsetAdapter(options) {
163
+ const resolved = resolveMuiAdapterOptions(options);
164
+ return function MuiFieldset({ className, legend, disabled, children }) {
165
+ return /* @__PURE__ */ jsxs2(
166
+ Box,
167
+ {
168
+ component: "fieldset",
169
+ className,
170
+ disabled,
171
+ sx: {
172
+ border: 0,
173
+ m: 0,
174
+ p: 0,
175
+ minWidth: 0,
176
+ display: "grid",
177
+ gap: resolved.dense ? 1 : 2,
178
+ "& > div:not(.MuiStack-root):not(.MuiPaper-root)": {
179
+ display: "grid",
180
+ gap: resolved.dense ? 1 : 2
181
+ }
182
+ },
183
+ children: [
184
+ legend === void 0 ? null : /* @__PURE__ */ jsx4(Typography, { component: "legend", variant: "subtitle1", fontWeight: "bold", sx: { mb: 1 }, children: legend }),
185
+ children
186
+ ]
187
+ }
188
+ );
189
+ };
190
+ }
191
+ var MuiFieldsetAdapter = createMuiFieldsetAdapter();
192
+
193
+ // src/adapters/IconButton.tsx
194
+ import { IconButton, Tooltip } from "@mui/material";
195
+ import { jsx as jsx5 } from "react/jsx-runtime";
196
+ var FALLBACK_ACTION_LABELS = {
197
+ moveUp: "Move up",
198
+ moveDown: "Move down",
199
+ delete: "Delete",
200
+ add: "Add",
201
+ edit: "Edit",
202
+ settings: "Settings",
203
+ translate: "Translate",
204
+ close: "Close",
205
+ dragHandle: "Reorder"
206
+ };
207
+ function createMuiIconButtonAdapter(options) {
208
+ const resolved = resolveMuiAdapterOptions(options);
209
+ return function MuiIconButton({
210
+ id,
211
+ className,
212
+ disabled,
213
+ readOnly,
214
+ "aria-label": ariaLabel,
215
+ "aria-describedby": ariaDescribedBy,
216
+ "aria-labelledby": ariaLabelledBy,
217
+ onClick,
218
+ icon,
219
+ actionType,
220
+ title
221
+ }) {
222
+ const actionLabel = actionType === void 0 ? "Action" : resolved.getActionLabel?.(actionType) ?? FALLBACK_ACTION_LABELS[actionType];
223
+ const tooltip = title ?? actionLabel;
224
+ const color = actionType === "delete" ? "error" : actionType === "add" ? "primary" : "default";
225
+ return /* @__PURE__ */ jsx5(Tooltip, { title: tooltip, children: /* @__PURE__ */ jsx5("span", { children: /* @__PURE__ */ jsx5(
226
+ IconButton,
227
+ {
228
+ id,
229
+ className,
230
+ type: "button",
231
+ size: resolved.size,
232
+ color,
233
+ disabled: disabled || readOnly,
234
+ "aria-label": ariaLabel ?? tooltip,
235
+ "aria-describedby": ariaDescribedBy,
236
+ "aria-labelledby": ariaLabelledBy,
237
+ onClick,
238
+ children: icon
239
+ }
240
+ ) }) });
241
+ };
242
+ }
243
+ var MuiIconButtonAdapter = createMuiIconButtonAdapter();
244
+
245
+ // src/adapters/Section.tsx
246
+ import { Paper, Typography as Typography2 } from "@mui/material";
247
+ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
248
+ function createMuiSectionAdapter(options) {
249
+ const resolved = resolveMuiAdapterOptions(options);
250
+ return function MuiSection({
251
+ id,
252
+ className,
253
+ title,
254
+ description,
255
+ headingId,
256
+ "aria-label": ariaLabel,
257
+ onClickCapture,
286
258
  children
287
- ] });
259
+ }) {
260
+ return /* @__PURE__ */ jsxs3(
261
+ Paper,
262
+ {
263
+ ...resolved.muiSlotProps?.paper,
264
+ id,
265
+ className,
266
+ elevation: 0,
267
+ "aria-label": ariaLabel,
268
+ "aria-labelledby": title === void 0 ? void 0 : headingId,
269
+ onClickCapture,
270
+ sx: resolved.muiSlotProps?.paper?.sx ?? {
271
+ p: resolved.dense ? 1.5 : 2,
272
+ mb: resolved.dense ? 1 : 2,
273
+ border: 1,
274
+ borderColor: "divider",
275
+ borderRadius: 1,
276
+ display: "grid",
277
+ gap: resolved.dense ? 1 : 2,
278
+ "& > div:not(.MuiStack-root):not(.MuiPaper-root)": {
279
+ display: "grid",
280
+ gap: resolved.dense ? 1 : 2
281
+ }
282
+ },
283
+ children: [
284
+ title === void 0 ? null : /* @__PURE__ */ jsx6(Typography2, { id: headingId, variant: "subtitle1", fontWeight: "bold", children: title }),
285
+ description === void 0 ? null : /* @__PURE__ */ jsx6(Typography2, { variant: "body2", color: "text.secondary", sx: { mb: resolved.dense ? 0.5 : 1.5 }, children: description }),
286
+ children
287
+ ]
288
+ }
289
+ );
290
+ };
288
291
  }
289
- function MuiErrorMessageAdapter({ className, message }) {
290
- return /* @__PURE__ */ jsx(Alert, { className, severity: "error", children: message });
292
+ var MuiSectionAdapter = createMuiSectionAdapter();
293
+
294
+ // src/adapters/Select.tsx
295
+ import { FormControl as FormControl2, FormHelperText as FormHelperText2, InputLabel, MenuItem, Select } from "@mui/material";
296
+ import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
297
+ function createMuiSelectAdapter(options) {
298
+ const resolved = resolveMuiAdapterOptions(options);
299
+ return function MuiSelect({
300
+ id,
301
+ className,
302
+ disabled,
303
+ readOnly,
304
+ "aria-label": ariaLabel,
305
+ "aria-describedby": ariaDescribedBy,
306
+ "aria-labelledby": ariaLabelledBy,
307
+ name,
308
+ label,
309
+ required,
310
+ error,
311
+ helperText,
312
+ value,
313
+ onChange,
314
+ options: selectOptions
315
+ }) {
316
+ const labelId = id === void 0 || label === void 0 ? void 0 : `${id}-label`;
317
+ const handleChange = (event) => onChange(event.target.value);
318
+ return /* @__PURE__ */ jsxs4(
319
+ FormControl2,
320
+ {
321
+ className,
322
+ fullWidth: resolved.fullWidth,
323
+ size: resolved.size,
324
+ variant: resolved.variant,
325
+ error: Boolean(error),
326
+ required,
327
+ disabled,
328
+ children: [
329
+ label === void 0 ? null : /* @__PURE__ */ jsx7(InputLabel, { id: labelId, children: label }),
330
+ /* @__PURE__ */ jsx7(
331
+ Select,
332
+ {
333
+ id,
334
+ labelId,
335
+ name,
336
+ label,
337
+ value,
338
+ onChange: handleChange,
339
+ required,
340
+ readOnly,
341
+ inputProps: {
342
+ "aria-label": ariaLabel,
343
+ "aria-describedby": ariaDescribedBy,
344
+ "aria-labelledby": ariaLabelledBy
345
+ },
346
+ children: selectOptions.map((option) => /* @__PURE__ */ jsx7(MenuItem, { value: option.value, disabled: option.disabled, children: option.label }, option.value))
347
+ }
348
+ ),
349
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx7(FormHelperText2, { id: ariaDescribedBy, children: helperText })
350
+ ]
351
+ }
352
+ );
353
+ };
354
+ }
355
+ var MuiSelectAdapter = createMuiSelectAdapter();
356
+
357
+ // src/adapters/TextArea.tsx
358
+ import { TextField } from "@mui/material";
359
+ import { jsx as jsx8 } from "react/jsx-runtime";
360
+ function createMuiTextAreaAdapter(options) {
361
+ const resolved = resolveMuiAdapterOptions(options);
362
+ return function MuiTextArea({
363
+ id,
364
+ className,
365
+ disabled,
366
+ readOnly,
367
+ "aria-label": ariaLabel,
368
+ "aria-describedby": ariaDescribedBy,
369
+ "aria-labelledby": ariaLabelledBy,
370
+ name,
371
+ label,
372
+ required,
373
+ error,
374
+ helperText,
375
+ value,
376
+ onChange,
377
+ placeholder,
378
+ maxLength,
379
+ rows
380
+ }) {
381
+ return /* @__PURE__ */ jsx8(
382
+ TextField,
383
+ {
384
+ id,
385
+ className,
386
+ name,
387
+ label,
388
+ required,
389
+ error: Boolean(error),
390
+ helperText,
391
+ value,
392
+ disabled,
393
+ slotProps: {
394
+ htmlInput: {
395
+ maxLength,
396
+ "aria-label": ariaLabel,
397
+ "aria-describedby": ariaDescribedBy,
398
+ "aria-labelledby": ariaLabelledBy
399
+ },
400
+ input: { readOnly },
401
+ formHelperText: { id: ariaDescribedBy }
402
+ },
403
+ multiline: true,
404
+ rows,
405
+ placeholder,
406
+ fullWidth: resolved.fullWidth,
407
+ size: resolved.size,
408
+ variant: resolved.variant,
409
+ onChange: (event) => onChange(event.currentTarget.value)
410
+ }
411
+ );
412
+ };
291
413
  }
414
+ var MuiTextAreaAdapter = createMuiTextAreaAdapter();
415
+
416
+ // src/adapters/TextInput.tsx
417
+ import { TextField as TextField2 } from "@mui/material";
418
+ import { jsx as jsx9 } from "react/jsx-runtime";
419
+ function createMuiTextInputAdapter(options) {
420
+ const resolved = resolveMuiAdapterOptions(options);
421
+ return function MuiTextInput({
422
+ id,
423
+ className,
424
+ disabled,
425
+ readOnly,
426
+ "aria-label": ariaLabel,
427
+ "aria-describedby": ariaDescribedBy,
428
+ "aria-labelledby": ariaLabelledBy,
429
+ name,
430
+ label,
431
+ required,
432
+ error,
433
+ helperText,
434
+ value,
435
+ onChange,
436
+ placeholder,
437
+ maxLength,
438
+ inputMode,
439
+ type = "text",
440
+ min,
441
+ max,
442
+ step
443
+ }) {
444
+ return /* @__PURE__ */ jsx9(
445
+ TextField2,
446
+ {
447
+ id,
448
+ className,
449
+ name,
450
+ label,
451
+ required,
452
+ error: Boolean(error),
453
+ helperText,
454
+ value,
455
+ disabled,
456
+ slotProps: {
457
+ htmlInput: {
458
+ maxLength,
459
+ min,
460
+ max,
461
+ step,
462
+ inputMode,
463
+ "aria-label": ariaLabel,
464
+ "aria-describedby": ariaDescribedBy,
465
+ "aria-labelledby": ariaLabelledBy
466
+ },
467
+ input: { readOnly },
468
+ formHelperText: { id: ariaDescribedBy }
469
+ },
470
+ type,
471
+ placeholder,
472
+ fullWidth: resolved.fullWidth,
473
+ size: resolved.size,
474
+ variant: resolved.variant,
475
+ onChange: (event) => onChange(event.currentTarget.value)
476
+ }
477
+ );
478
+ };
479
+ }
480
+ var MuiTextInputAdapter = createMuiTextInputAdapter();
481
+
482
+ // src/icons.tsx
483
+ import {
484
+ Add,
485
+ ArrowDownward,
486
+ ArrowUpward,
487
+ Close,
488
+ Delete,
489
+ DragHandle,
490
+ Edit,
491
+ Settings,
492
+ Translate
493
+ } from "@mui/icons-material";
494
+ import { jsx as jsx10 } from "react/jsx-runtime";
292
495
  function muiDefaultIconResolver(actionType) {
293
496
  switch (actionType) {
294
497
  case "moveUp":
295
- return /* @__PURE__ */ jsx(ArrowUpward, { fontSize: "small" });
498
+ return /* @__PURE__ */ jsx10(ArrowUpward, { fontSize: "small" });
296
499
  case "moveDown":
297
- return /* @__PURE__ */ jsx(ArrowDownward, { fontSize: "small" });
500
+ return /* @__PURE__ */ jsx10(ArrowDownward, { fontSize: "small" });
298
501
  case "delete":
299
- return /* @__PURE__ */ jsx(Delete, { fontSize: "small" });
502
+ return /* @__PURE__ */ jsx10(Delete, { fontSize: "small" });
300
503
  case "add":
301
- return /* @__PURE__ */ jsx(Add, { fontSize: "small" });
504
+ return /* @__PURE__ */ jsx10(Add, { fontSize: "small" });
302
505
  case "edit":
303
- return /* @__PURE__ */ jsx(Edit, { fontSize: "small" });
506
+ return /* @__PURE__ */ jsx10(Edit, { fontSize: "small" });
304
507
  case "settings":
305
- return /* @__PURE__ */ jsx(Settings, { fontSize: "small" });
508
+ return /* @__PURE__ */ jsx10(Settings, { fontSize: "small" });
306
509
  case "translate":
307
- return /* @__PURE__ */ jsx(Translate, { fontSize: "small" });
510
+ return /* @__PURE__ */ jsx10(Translate, { fontSize: "small" });
308
511
  case "close":
309
- return /* @__PURE__ */ jsx(Close, { fontSize: "small" });
512
+ return /* @__PURE__ */ jsx10(Close, { fontSize: "small" });
310
513
  case "dragHandle":
311
- return /* @__PURE__ */ jsx(DragHandle, { fontSize: "small" });
514
+ return /* @__PURE__ */ jsx10(DragHandle, { fontSize: "small" });
312
515
  }
313
516
  }
314
- var muiBuilderComponents = {
315
- Button: MuiButtonAdapter,
316
- IconButton: MuiIconButtonAdapter,
317
- TextInput: MuiTextInputAdapter,
318
- TextArea: MuiTextAreaAdapter,
319
- Select: MuiSelectAdapter,
320
- Checkbox: MuiCheckboxAdapter,
321
- Section: MuiSectionAdapter,
322
- Fieldset: MuiFieldsetAdapter,
323
- ErrorMessage: MuiErrorMessageAdapter,
324
- renderIcon: muiDefaultIconResolver
517
+
518
+ // src/components.ts
519
+ function isAdapterOptions(value) {
520
+ return "size" in value || "variant" in value || "buttonVariant" in value || "fullWidth" in value || "dense" in value;
521
+ }
522
+ function buildMuiBuilderComponents(options) {
523
+ return {
524
+ Button: createMuiButtonAdapter(options),
525
+ IconButton: createMuiIconButtonAdapter(options),
526
+ TextInput: createMuiTextInputAdapter(options),
527
+ TextArea: createMuiTextAreaAdapter(options),
528
+ Select: createMuiSelectAdapter(options),
529
+ Checkbox: createMuiCheckboxAdapter(options),
530
+ Section: createMuiSectionAdapter(options),
531
+ Fieldset: createMuiFieldsetAdapter(options),
532
+ ErrorMessage: createMuiErrorMessageAdapter(options),
533
+ renderIcon: muiDefaultIconResolver
534
+ };
535
+ }
536
+ var muiBuilderComponents = buildMuiBuilderComponents();
537
+ function createMuiBuilderComponents(optionsOrOverrides = {}, customOverrides) {
538
+ const options = isAdapterOptions(optionsOrOverrides) ? optionsOrOverrides : void 0;
539
+ const overrides = customOverrides ?? (options === void 0 ? optionsOrOverrides : {});
540
+ return { ...buildMuiBuilderComponents(options), ...overrides };
541
+ }
542
+
543
+ // src/slots/FieldEditor.tsx
544
+ import { Card, Stack as Stack3, Typography as Typography3 } from "@mui/material";
545
+
546
+ // src/slots/OptionEditor.tsx
547
+ import { Stack } from "@mui/material";
548
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
549
+ function createMuiOptionEditorSlot(options) {
550
+ const resolved = resolveMuiAdapterOptions(options);
551
+ return function MuiOptionEditor({
552
+ field,
553
+ option,
554
+ index,
555
+ currentLocale,
556
+ readOnly,
557
+ actions,
558
+ components,
559
+ translate
560
+ }) {
561
+ const { IconButton: IconButton2, TextInput } = components;
562
+ const describedBy = option.label.trim().length === 0 ? `mui-option-${option.id}-error` : void 0;
563
+ return /* @__PURE__ */ jsxs5(Stack, { ...resolved.muiSlotProps?.stack, "data-mui-slot": "option-editor", spacing: resolved.dense ? 0.75 : 1, children: [
564
+ /* @__PURE__ */ jsxs5(Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, alignItems: { sm: "flex-start" }, children: [
565
+ /* @__PURE__ */ jsx11(
566
+ TextInput,
567
+ {
568
+ id: `mui-option-${option.id}`,
569
+ label: translate("builder.optionLabel", { index: index + 1 }),
570
+ value: option.label,
571
+ required: true,
572
+ error: option.label.trim().length === 0,
573
+ helperText: option.label.trim().length === 0 ? translate("builder.required") : "",
574
+ "aria-describedby": describedBy,
575
+ disabled: readOnly,
576
+ onChange: (value) => actions.updateOption(field.id, option.id, (current) => ({ ...current, label: value }))
577
+ }
578
+ ),
579
+ /* @__PURE__ */ jsxs5(Stack, { direction: "row", spacing: 0.5, children: [
580
+ /* @__PURE__ */ jsx11(
581
+ IconButton2,
582
+ {
583
+ actionType: "moveUp",
584
+ title: translate("builder.moveUp", { title: option.label }),
585
+ disabled: readOnly || index === 0,
586
+ onClick: () => actions.moveOption(field.id, option.id, index - 1)
587
+ }
588
+ ),
589
+ /* @__PURE__ */ jsx11(
590
+ IconButton2,
591
+ {
592
+ actionType: "moveDown",
593
+ title: translate("builder.moveDown", { title: option.label }),
594
+ disabled: readOnly || index === field.options.length - 1,
595
+ onClick: () => actions.moveOption(field.id, option.id, index + 1)
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsx11(
599
+ IconButton2,
600
+ {
601
+ actionType: "delete",
602
+ title: translate("builder.delete", { title: option.label }),
603
+ disabled: readOnly || field.options.length <= 1,
604
+ onClick: () => actions.removeOption(field.id, option.id)
605
+ }
606
+ )
607
+ ] })
608
+ ] }),
609
+ currentLocale.length === 0 ? null : /* @__PURE__ */ jsx11(
610
+ TextInput,
611
+ {
612
+ id: `mui-option-${option.id}-${currentLocale}`,
613
+ label: translate("builder.translation", {
614
+ locale: resolved.getLocaleLabel?.(currentLocale) ?? currentLocale
615
+ }),
616
+ value: option.translations?.[currentLocale] ?? "",
617
+ disabled: readOnly,
618
+ onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "option", id: option.id }, "label", value)
619
+ }
620
+ )
621
+ ] });
622
+ };
623
+ }
624
+ var MuiOptionEditorSlot = createMuiOptionEditorSlot();
625
+
626
+ // src/slots/Toolbar.tsx
627
+ import { Stack as Stack2 } from "@mui/material";
628
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
629
+ function createMuiToolbarSlot(options) {
630
+ const resolved = resolveMuiAdapterOptions(options);
631
+ return function MuiToolbar({
632
+ kind,
633
+ index,
634
+ total,
635
+ title,
636
+ onMoveUp,
637
+ onMoveDown,
638
+ onRemove,
639
+ readOnly,
640
+ components,
641
+ translate
642
+ }) {
643
+ const { IconButton: IconButton2 } = components;
644
+ return /* @__PURE__ */ jsxs6(
645
+ Stack2,
646
+ {
647
+ ...resolved.muiSlotProps?.stack,
648
+ "data-mui-slot": "toolbar",
649
+ direction: "row",
650
+ spacing: resolved.dense ? 0.5 : 1,
651
+ alignItems: "center",
652
+ sx: resolved.muiSlotProps?.stack?.sx ?? { mb: resolved.dense ? 1 : 2 },
653
+ children: [
654
+ /* @__PURE__ */ jsx12(
655
+ IconButton2,
656
+ {
657
+ actionType: "moveUp",
658
+ title: translate("builder.moveUp", { title }),
659
+ disabled: readOnly || index === 0,
660
+ onClick: onMoveUp
661
+ }
662
+ ),
663
+ /* @__PURE__ */ jsx12(
664
+ IconButton2,
665
+ {
666
+ actionType: "moveDown",
667
+ title: translate("builder.moveDown", { title }),
668
+ disabled: readOnly || index === total - 1,
669
+ onClick: onMoveDown
670
+ }
671
+ ),
672
+ /* @__PURE__ */ jsx12(
673
+ IconButton2,
674
+ {
675
+ actionType: "delete",
676
+ title: translate("builder.delete", { title }),
677
+ disabled: readOnly || kind !== "page" && total <= 1,
678
+ onClick: onRemove
679
+ }
680
+ )
681
+ ]
682
+ }
683
+ );
684
+ };
685
+ }
686
+ var MuiToolbarSlot = createMuiToolbarSlot();
687
+
688
+ // src/slots/FieldEditor.tsx
689
+ import { Fragment, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
690
+ var FIELD_TYPES = [
691
+ "text",
692
+ "textarea",
693
+ "number",
694
+ "rating",
695
+ "select",
696
+ "multi-select",
697
+ "checkbox",
698
+ "radio"
699
+ ];
700
+ function isFieldType(value) {
701
+ return FIELD_TYPES.some((type) => type === value);
702
+ }
703
+ function conditionOperators(field) {
704
+ if (field.type === "multi-select") return ["contains", "not_empty"];
705
+ if (field.type === "text" || field.type === "textarea") {
706
+ return ["equals", "not_equals", "contains", "not_empty"];
707
+ }
708
+ return ["equals", "not_equals", "not_empty"];
709
+ }
710
+ function isConditionOperator(value) {
711
+ return ["equals", "not_equals", "contains", "not_empty"].some((operator) => operator === value);
712
+ }
713
+ function numericValue(value) {
714
+ if (value.trim().length === 0) return void 0;
715
+ const parsed = Number(value);
716
+ return Number.isFinite(parsed) ? parsed : void 0;
717
+ }
718
+ function updateBound(field, property, value) {
719
+ if (field.type !== "number" && field.type !== "rating") return field;
720
+ const nextValue = numericValue(value);
721
+ if (nextValue !== void 0) return { ...field, [property]: nextValue };
722
+ const { [property]: _removed, ...remaining } = field;
723
+ return remaining;
724
+ }
725
+ function createMuiFieldEditorSlot(options) {
726
+ const resolved = resolveMuiAdapterOptions(options);
727
+ const Toolbar = createMuiToolbarSlot(options);
728
+ const OptionEditor = createMuiOptionEditorSlot(options);
729
+ return function MuiFieldEditor({
730
+ schema,
731
+ field,
732
+ index,
733
+ currentLocale,
734
+ policy,
735
+ features,
736
+ readOnly,
737
+ actions,
738
+ components,
739
+ translate
740
+ }) {
741
+ const { Button: Button2, Checkbox: Checkbox2, Select: Select2, TextArea, TextInput } = components;
742
+ const allowedTypes = policy?.allowedFieldTypes ?? FIELD_TYPES;
743
+ const pageId = schema.pages?.find((page) => page.questionIds.includes(field.id))?.id ?? "";
744
+ const condition = field.displayCondition;
745
+ const conditionSources = schema.fields.slice(0, index);
746
+ const conditionSource = conditionSources.find((source) => source.id === condition?.questionId);
747
+ const titleErrorId = field.title.trim().length === 0 ? `mui-field-${field.id}-title-error` : void 0;
748
+ return /* @__PURE__ */ jsxs7(
749
+ Card,
750
+ {
751
+ ...resolved.muiSlotProps?.card,
752
+ "data-mui-slot": "field-editor",
753
+ variant: "outlined",
754
+ sx: resolved.muiSlotProps?.card?.sx ?? { mb: resolved.dense ? 1 : 2, p: resolved.dense ? 1.5 : 2 },
755
+ children: [
756
+ /* @__PURE__ */ jsx13(
757
+ Toolbar,
758
+ {
759
+ schema,
760
+ translate,
761
+ kind: "field",
762
+ targetId: field.id,
763
+ index,
764
+ total: schema.fields.length,
765
+ title: field.title,
766
+ onMoveUp: () => actions.moveField(field.id, index - 1),
767
+ onMoveDown: () => actions.moveField(field.id, index + 1),
768
+ onRemove: () => actions.removeField(field.id),
769
+ readOnly,
770
+ actions,
771
+ components
772
+ }
773
+ ),
774
+ /* @__PURE__ */ jsxs7(Stack3, { ...resolved.muiSlotProps?.stack, spacing: resolved.dense ? 1 : 2, children: [
775
+ /* @__PURE__ */ jsx13(Typography3, { variant: "subtitle1", fontWeight: "bold", children: field.title }),
776
+ /* @__PURE__ */ jsxs7(Stack3, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
777
+ /* @__PURE__ */ jsx13(
778
+ TextInput,
779
+ {
780
+ id: `mui-field-${field.id}-title`,
781
+ name: `fields.${field.id}.title`,
782
+ label: translate("builder.questionTitle"),
783
+ value: field.title,
784
+ required: true,
785
+ error: field.title.trim().length === 0,
786
+ helperText: field.title.trim().length === 0 ? translate("builder.required") : "",
787
+ "aria-describedby": titleErrorId,
788
+ disabled: readOnly,
789
+ onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "title", value)
790
+ }
791
+ ),
792
+ /* @__PURE__ */ jsx13(
793
+ Select2,
794
+ {
795
+ id: `mui-field-${field.id}-type`,
796
+ name: `fields.${field.id}.type`,
797
+ label: translate("builder.type"),
798
+ value: allowedTypes.includes(field.type) ? field.type : "",
799
+ options: FIELD_TYPES.filter((type) => allowedTypes.includes(type)).map((type) => ({
800
+ value: type,
801
+ label: translate(`builder.fieldType.${type}`)
802
+ })),
803
+ disabled: readOnly,
804
+ onChange: (value) => {
805
+ if (isFieldType(value)) actions.changeFieldType(field.id, value);
806
+ }
807
+ }
808
+ )
809
+ ] }),
810
+ /* @__PURE__ */ jsx13(
811
+ TextArea,
812
+ {
813
+ id: `mui-field-${field.id}-description`,
814
+ name: `fields.${field.id}.description`,
815
+ label: translate("builder.description"),
816
+ value: field.description ?? "",
817
+ rows: resolved.dense ? 2 : 3,
818
+ disabled: readOnly,
819
+ onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "description", value)
820
+ }
821
+ ),
822
+ /* @__PURE__ */ jsx13(
823
+ Checkbox2,
824
+ {
825
+ id: `mui-field-${field.id}-required`,
826
+ name: `fields.${field.id}.required`,
827
+ label: translate("builder.required"),
828
+ checked: field.required,
829
+ disabled: readOnly,
830
+ onChange: (checked) => actions.updateField(field.id, (current) => ({ ...current, required: checked }))
831
+ }
832
+ ),
833
+ features?.pages === false || schema.pages === void 0 ? null : /* @__PURE__ */ jsx13(
834
+ Select2,
835
+ {
836
+ id: `mui-field-${field.id}-page`,
837
+ label: translate("builder.questionPage"),
838
+ value: pageId,
839
+ options: [
840
+ { value: "", label: translate("builder.unassigned") },
841
+ ...schema.pages.map((page) => ({ value: page.id, label: page.title ?? page.id }))
842
+ ],
843
+ disabled: readOnly,
844
+ onChange: (value) => actions.assignFieldToPage(field.id, value.length === 0 ? null : value)
845
+ }
846
+ ),
847
+ field.type === "number" || field.type === "rating" ? /* @__PURE__ */ jsxs7(Stack3, { direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
848
+ /* @__PURE__ */ jsx13(
849
+ TextInput,
850
+ {
851
+ id: `mui-field-${field.id}-minimum`,
852
+ label: translate("builder.minimum"),
853
+ type: "number",
854
+ value: field.min === void 0 ? "" : String(field.min),
855
+ disabled: readOnly,
856
+ onChange: (value) => actions.updateField(field.id, (current) => updateBound(current, "min", value))
857
+ }
858
+ ),
859
+ /* @__PURE__ */ jsx13(
860
+ TextInput,
861
+ {
862
+ id: `mui-field-${field.id}-maximum`,
863
+ label: translate("builder.maximum"),
864
+ type: "number",
865
+ value: field.max === void 0 ? "" : String(field.max),
866
+ disabled: readOnly,
867
+ onChange: (value) => actions.updateField(field.id, (current) => updateBound(current, "max", value))
868
+ }
869
+ )
870
+ ] }) : null,
871
+ features?.conditions === false || conditionSources.length === 0 ? null : /* @__PURE__ */ jsxs7(Stack3, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
872
+ /* @__PURE__ */ jsx13(
873
+ Select2,
874
+ {
875
+ id: `mui-field-${field.id}-condition-source`,
876
+ label: translate("builder.displayCondition"),
877
+ value: condition?.questionId ?? "",
878
+ options: [
879
+ { value: "", label: translate("builder.alwaysVisible") },
880
+ ...conditionSources.map((source) => ({ value: source.id, label: source.title }))
881
+ ],
882
+ disabled: readOnly,
883
+ onChange: (value) => actions.setDisplayCondition(
884
+ field.id,
885
+ value.length === 0 ? void 0 : { questionId: value, operator: "equals", value: "" }
886
+ )
887
+ }
888
+ ),
889
+ condition === void 0 ? null : /* @__PURE__ */ jsxs7(Fragment, { children: [
890
+ /* @__PURE__ */ jsx13(
891
+ Select2,
892
+ {
893
+ id: `mui-field-${field.id}-condition-operator`,
894
+ label: translate("builder.conditionOperator"),
895
+ value: condition.operator,
896
+ options: (conditionSource === void 0 ? [] : conditionOperators(conditionSource)).map(
897
+ (operator) => ({ value: operator, label: translate(`builder.operator.${operator}`) })
898
+ ),
899
+ disabled: readOnly,
900
+ onChange: (value) => {
901
+ if (!isConditionOperator(value)) return;
902
+ actions.setDisplayCondition(
903
+ field.id,
904
+ value === "not_empty" ? { questionId: condition.questionId, operator: value } : { ...condition, operator: value, value: condition.value ?? "" }
905
+ );
906
+ }
907
+ }
908
+ ),
909
+ condition.operator === "not_empty" ? null : /* @__PURE__ */ jsx13(
910
+ TextInput,
911
+ {
912
+ id: `mui-field-${field.id}-condition-value`,
913
+ label: translate("builder.conditionValue"),
914
+ value: condition.value === void 0 ? "" : String(condition.value),
915
+ disabled: readOnly,
916
+ onChange: (value) => actions.setDisplayCondition(field.id, { ...condition, value })
917
+ }
918
+ )
919
+ ] })
920
+ ] }),
921
+ currentLocale.length === 0 ? null : /* @__PURE__ */ jsxs7(Stack3, { spacing: resolved.dense ? 1 : 2, children: [
922
+ /* @__PURE__ */ jsx13(Typography3, { variant: "subtitle2", children: translate("builder.translation", {
923
+ locale: resolved.getLocaleLabel?.(currentLocale) ?? currentLocale
924
+ }) }),
925
+ /* @__PURE__ */ jsx13(
926
+ TextInput,
927
+ {
928
+ id: `mui-field-${field.id}-${currentLocale}-title`,
929
+ label: translate("builder.translatedQuestionTitle"),
930
+ value: field.translations?.[currentLocale]?.title ?? "",
931
+ disabled: readOnly,
932
+ onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "field", id: field.id }, "title", value)
933
+ }
934
+ ),
935
+ /* @__PURE__ */ jsx13(
936
+ TextArea,
937
+ {
938
+ id: `mui-field-${field.id}-${currentLocale}-description`,
939
+ label: translate("builder.translatedDescription"),
940
+ value: field.translations?.[currentLocale]?.description ?? "",
941
+ disabled: readOnly,
942
+ onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "field", id: field.id }, "description", value)
943
+ }
944
+ )
945
+ ] }),
946
+ "options" in field ? /* @__PURE__ */ jsxs7(Stack3, { "data-mui-slot": "options", spacing: resolved.dense ? 1 : 2, children: [
947
+ /* @__PURE__ */ jsx13(Typography3, { variant: "subtitle2", children: translate("builder.options") }),
948
+ field.options.map((option, optionIndex) => /* @__PURE__ */ jsx13(
949
+ OptionEditor,
950
+ {
951
+ schema,
952
+ field,
953
+ option,
954
+ index: optionIndex,
955
+ currentLocale,
956
+ translate,
957
+ readOnly,
958
+ actions,
959
+ components
960
+ },
961
+ option.id
962
+ )),
963
+ /* @__PURE__ */ jsx13(
964
+ Button2,
965
+ {
966
+ action: "addOption",
967
+ targetId: field.id,
968
+ disabled: readOnly || policy?.maxOptionsPerField !== void 0 && field.options.length >= policy.maxOptionsPerField,
969
+ onClick: () => actions.addOption(field.id),
970
+ children: translate("builder.addOption")
971
+ }
972
+ )
973
+ ] }) : null
974
+ ] })
975
+ ]
976
+ }
977
+ );
978
+ };
979
+ }
980
+ var MuiFieldEditorSlot = createMuiFieldEditorSlot();
981
+
982
+ // src/slots/Localization.tsx
983
+ import { ExpandMore } from "@mui/icons-material";
984
+ import { Accordion, AccordionDetails, AccordionSummary, Box as Box2, Stack as Stack4, Tab, Tabs, Typography as Typography4 } from "@mui/material";
985
+ import { useState } from "react";
986
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
987
+ function createMuiLocalizationSlot(options) {
988
+ const resolved = resolveMuiAdapterOptions(options);
989
+ return function MuiLocalization({
990
+ schema,
991
+ currentLocale,
992
+ onCurrentLocaleChange,
993
+ onAutoTranslate,
994
+ isTranslating,
995
+ translationError,
996
+ policy,
997
+ translationAdapterAvailable,
998
+ readOnly,
999
+ actions,
1000
+ components,
1001
+ translate
1002
+ }) {
1003
+ const { Button: Button2, ErrorMessage, Select: Select2, TextArea, TextInput } = components;
1004
+ const [newLocale, setNewLocale] = useState("");
1005
+ const locales = Array.from(
1006
+ new Set((schema.supportedLocales ?? []).filter((locale) => locale !== schema.defaultLocale))
1007
+ );
1008
+ const editingLocaleConfigured = locales.includes(currentLocale);
1009
+ const registeredLocales = /* @__PURE__ */ new Set([
1010
+ ...schema.defaultLocale === void 0 ? [] : [schema.defaultLocale],
1011
+ ...schema.supportedLocales ?? []
1012
+ ]);
1013
+ const availableAllowedLocales = policy?.allowedLocales?.filter((locale) => !registeredLocales.has(locale));
1014
+ const localeLimitReached = policy?.maxLocales !== void 0 && registeredLocales.size >= policy.maxLocales;
1015
+ const normalizedLocale = newLocale.trim();
1016
+ const localeAllowed = policy?.allowedLocales === void 0 || policy.allowedLocales.includes(normalizedLocale);
1017
+ const canAddLocale = !readOnly && normalizedLocale.length > 0 && localeAllowed && !registeredLocales.has(normalizedLocale) && !localeLimitReached;
1018
+ const handleTabChange = (_event, value) => onCurrentLocaleChange(value);
1019
+ const addLocale = () => {
1020
+ if (!canAddLocale) return;
1021
+ const result = actions.addLocale(normalizedLocale);
1022
+ if (!result.success) return;
1023
+ onCurrentLocaleChange(normalizedLocale);
1024
+ setNewLocale("");
1025
+ };
1026
+ const stackProps = resolved.muiSlotProps?.stack;
1027
+ const collapsible = resolved.localizationOptions?.collapsible ?? false;
1028
+ const content = /* @__PURE__ */ jsxs8(Stack4, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
1029
+ !collapsible ? /* @__PURE__ */ jsx14(Typography4, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }) : null,
1030
+ /* @__PURE__ */ jsxs8(Stack4, { ...stackProps, direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1031
+ /* @__PURE__ */ jsx14(
1032
+ TextInput,
1033
+ {
1034
+ id: "mui-builder-default-locale",
1035
+ label: translate("builder.defaultLocale"),
1036
+ value: schema.defaultLocale ?? "",
1037
+ disabled: readOnly,
1038
+ onChange: (value) => {
1039
+ const result = actions.setDefaultLocale(value);
1040
+ if (result.success && value === currentLocale) onCurrentLocaleChange("");
1041
+ }
1042
+ }
1043
+ ),
1044
+ availableAllowedLocales === void 0 ? /* @__PURE__ */ jsx14(
1045
+ TextInput,
1046
+ {
1047
+ id: "mui-builder-new-locale",
1048
+ label: translate("builder.addLocale"),
1049
+ value: newLocale,
1050
+ disabled: readOnly || localeLimitReached,
1051
+ onChange: setNewLocale
1052
+ }
1053
+ ) : /* @__PURE__ */ jsx14(
1054
+ Select2,
1055
+ {
1056
+ id: "mui-builder-new-locale",
1057
+ label: translate("builder.addLocale"),
1058
+ value: newLocale,
1059
+ options: [
1060
+ { value: "", label: "\u2014" },
1061
+ ...availableAllowedLocales.map((locale) => ({
1062
+ value: locale,
1063
+ label: resolved.getLocaleLabel?.(locale) ?? locale
1064
+ }))
1065
+ ],
1066
+ disabled: readOnly || localeLimitReached || availableAllowedLocales.length === 0,
1067
+ onChange: setNewLocale
1068
+ }
1069
+ ),
1070
+ /* @__PURE__ */ jsx14(Button2, { variant: "primary", action: "addLocale", disabled: !canAddLocale, onClick: addLocale, children: translate("builder.addLocale") })
1071
+ ] }),
1072
+ locales.length === 0 ? null : /* @__PURE__ */ jsx14(
1073
+ Tabs,
1074
+ {
1075
+ value: editingLocaleConfigured ? currentLocale : false,
1076
+ onChange: handleTabChange,
1077
+ variant: "scrollable",
1078
+ scrollButtons: "auto",
1079
+ "aria-label": translate("builder.translationLocale"),
1080
+ children: locales.map((locale) => /* @__PURE__ */ jsx14(
1081
+ Tab,
1082
+ {
1083
+ value: locale,
1084
+ label: resolved.getLocaleLabel?.(locale) ?? locale,
1085
+ disabled: readOnly && locale !== currentLocale
1086
+ },
1087
+ locale
1088
+ ))
1089
+ }
1090
+ ),
1091
+ !translationAdapterAvailable ? null : /* @__PURE__ */ jsx14(
1092
+ Button2,
1093
+ {
1094
+ variant: "secondary",
1095
+ disabled: readOnly || !editingLocaleConfigured || isTranslating,
1096
+ onClick: onAutoTranslate,
1097
+ children: isTranslating ? translate("builder.translating") : translate("builder.autoTranslate")
1098
+ }
1099
+ ),
1100
+ translationError === void 0 ? null : /* @__PURE__ */ jsx14(ErrorMessage, { message: translationError }),
1101
+ !editingLocaleConfigured ? /* @__PURE__ */ jsx14(Typography4, { variant: "body2", color: "text.secondary", children: translate("builder.selectLocale") }) : /* @__PURE__ */ jsxs8(Stack4, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
1102
+ /* @__PURE__ */ jsx14(
1103
+ TextInput,
1104
+ {
1105
+ id: `mui-builder-${currentLocale}-form-title`,
1106
+ label: translate("builder.translatedFormTitle"),
1107
+ value: schema.translations?.[currentLocale]?.title ?? "",
1108
+ disabled: readOnly,
1109
+ onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "form" }, "title", value)
1110
+ }
1111
+ ),
1112
+ /* @__PURE__ */ jsx14(
1113
+ TextArea,
1114
+ {
1115
+ id: `mui-builder-${currentLocale}-form-description`,
1116
+ label: translate("builder.translatedFormDescription"),
1117
+ value: schema.translations?.[currentLocale]?.description ?? "",
1118
+ disabled: readOnly,
1119
+ onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "form" }, "description", value)
1120
+ }
1121
+ ),
1122
+ /* @__PURE__ */ jsx14(
1123
+ TextInput,
1124
+ {
1125
+ id: `mui-builder-${currentLocale}-completion-message`,
1126
+ label: translate("builder.translatedCompletionMessage"),
1127
+ value: schema.translations?.[currentLocale]?.completionMessage ?? "",
1128
+ disabled: readOnly,
1129
+ onChange: (value) => actions.setLocaleTranslation(currentLocale, { kind: "form" }, "completionMessage", value)
1130
+ }
1131
+ )
1132
+ ] })
1133
+ ] });
1134
+ const configured = locales.length > 0;
1135
+ const defaultExpanded = resolved.localizationOptions?.defaultExpanded === "when-configured" ? configured : resolved.localizationOptions?.defaultExpanded ?? false;
1136
+ if (collapsible) {
1137
+ return /* @__PURE__ */ jsxs8(Accordion, { ...resolved.muiSlotProps?.accordion, "data-mui-slot": "localization", defaultExpanded, children: [
1138
+ /* @__PURE__ */ jsx14(AccordionSummary, { expandIcon: /* @__PURE__ */ jsx14(ExpandMore, {}), children: /* @__PURE__ */ jsx14(Typography4, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }) }),
1139
+ /* @__PURE__ */ jsx14(AccordionDetails, { children: content })
1140
+ ] });
1141
+ }
1142
+ return /* @__PURE__ */ jsx14(
1143
+ Box2,
1144
+ {
1145
+ "data-mui-slot": "localization",
1146
+ sx: {
1147
+ mt: resolved.dense ? 1 : 2,
1148
+ p: resolved.dense ? 1.5 : 2,
1149
+ border: 1,
1150
+ borderColor: "divider",
1151
+ borderRadius: 1
1152
+ },
1153
+ children: content
1154
+ }
1155
+ );
1156
+ };
1157
+ }
1158
+ var MuiLocalizationSlot = createMuiLocalizationSlot();
1159
+
1160
+ // src/slots/index.ts
1161
+ var muiBuilderSlots = {
1162
+ sectionOrder: DEFAULT_MUI_SECTION_ORDER,
1163
+ toolbar: createMuiToolbarSlot(),
1164
+ fieldEditor: createMuiFieldEditorSlot(),
1165
+ optionEditor: createMuiOptionEditorSlot(),
1166
+ localization: createMuiLocalizationSlot()
325
1167
  };
326
- function createMuiBuilderComponents(customOverrides = {}) {
327
- return { ...muiBuilderComponents, ...customOverrides };
1168
+ function createMuiBuilderSlots(options, customOverrides = {}) {
1169
+ return {
1170
+ sectionOrder: options?.layoutOptions?.sectionOrder ?? DEFAULT_MUI_SECTION_ORDER,
1171
+ toolbar: createMuiToolbarSlot(options),
1172
+ fieldEditor: createMuiFieldEditorSlot(options),
1173
+ optionEditor: createMuiOptionEditorSlot(options),
1174
+ localization: createMuiLocalizationSlot(options),
1175
+ ...customOverrides
1176
+ };
1177
+ }
1178
+
1179
+ // src/builderProps.ts
1180
+ function createMuiBuilderProps(options, overrides = {}) {
1181
+ return {
1182
+ disableDefaultStyles: true,
1183
+ components: createMuiBuilderComponents(options, overrides.components),
1184
+ slots: createMuiBuilderSlots(options, overrides.slots)
1185
+ };
1186
+ }
1187
+
1188
+ // src/MuiFormBuilder.tsx
1189
+ import {
1190
+ FormBuilder
1191
+ } from "@form-engine-ts/react";
1192
+ import { useMemo } from "react";
1193
+ import { jsx as jsx15 } from "react/jsx-runtime";
1194
+ function MuiFormBuilder({
1195
+ muiOptions,
1196
+ layoutOptions,
1197
+ localizationOptions,
1198
+ muiSlotProps,
1199
+ components: customComponents,
1200
+ slots: customSlots,
1201
+ ...props
1202
+ }) {
1203
+ const resolvedMuiOptions = useMemo(
1204
+ () => ({
1205
+ ...muiOptions,
1206
+ ...layoutOptions === void 0 ? {} : { layoutOptions },
1207
+ ...localizationOptions === void 0 ? {} : { localizationOptions },
1208
+ ...muiSlotProps === void 0 ? {} : { muiSlotProps }
1209
+ }),
1210
+ [layoutOptions, localizationOptions, muiOptions, muiSlotProps]
1211
+ );
1212
+ const components = useMemo(
1213
+ () => createMuiBuilderComponents(resolvedMuiOptions, customComponents),
1214
+ [resolvedMuiOptions, customComponents]
1215
+ );
1216
+ const slots = useMemo(
1217
+ () => createMuiBuilderSlots(resolvedMuiOptions, customSlots),
1218
+ [resolvedMuiOptions, customSlots]
1219
+ );
1220
+ return /* @__PURE__ */ jsx15(FormBuilder, { ...props, components, disableDefaultStyles: true, slots });
328
1221
  }
329
1222
  export {
1223
+ DEFAULT_MUI_SECTION_ORDER,
1224
+ MuiButtonAdapter,
1225
+ MuiCheckboxAdapter,
1226
+ MuiErrorMessageAdapter,
1227
+ MuiFieldEditorSlot,
1228
+ MuiFieldsetAdapter,
1229
+ MuiFormBuilder,
1230
+ MuiIconButtonAdapter,
1231
+ MuiLocalizationSlot,
1232
+ MuiOptionEditorSlot,
1233
+ MuiSectionAdapter,
1234
+ MuiSelectAdapter,
1235
+ MuiTextAreaAdapter,
1236
+ MuiTextInputAdapter,
1237
+ MuiToolbarSlot,
330
1238
  createMuiBuilderComponents,
1239
+ createMuiBuilderProps,
1240
+ createMuiBuilderSlots,
1241
+ createMuiButtonAdapter,
1242
+ createMuiCheckboxAdapter,
1243
+ createMuiErrorMessageAdapter,
1244
+ createMuiFieldEditorSlot,
1245
+ createMuiFieldsetAdapter,
1246
+ createMuiIconButtonAdapter,
1247
+ createMuiLocalizationSlot,
1248
+ createMuiOptionEditorSlot,
1249
+ createMuiSectionAdapter,
1250
+ createMuiSelectAdapter,
1251
+ createMuiTextAreaAdapter,
1252
+ createMuiTextInputAdapter,
1253
+ createMuiToolbarSlot,
331
1254
  muiBuilderComponents,
332
- muiDefaultIconResolver
1255
+ muiBuilderSlots,
1256
+ muiDefaultIconResolver,
1257
+ resolveMuiAdapterOptions
333
1258
  };