@form-engine-ts/mui 2.9.2 → 2.9.3

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