@dynamic-field-kit/react 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +180 -0
- package/LICENSE +21 -0
- package/README.md +161 -4
- package/dist/index.d.mts +88 -18
- package/dist/index.d.ts +88 -18
- package/dist/index.js +843 -62
- package/dist/index.mjs +832 -48
- package/package.json +38 -24
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -30,11 +30,26 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
DynamicFormDevTools: () => DynamicFormDevTools,
|
|
33
34
|
DynamicInput: () => DynamicInput_default,
|
|
34
35
|
FieldInput: () => FieldInput_default,
|
|
36
|
+
FieldRegistry: () => import_core6.FieldRegistry,
|
|
37
|
+
FieldRegistryProvider: () => FieldRegistryProvider,
|
|
35
38
|
MultiFieldInput: () => MultiFieldInput_default,
|
|
39
|
+
defaultRenderersMap: () => defaultRenderersMap,
|
|
36
40
|
fieldRegistry: () => fieldRegistry,
|
|
37
|
-
|
|
41
|
+
getDefaultRenderer: () => getDefaultRenderer,
|
|
42
|
+
layoutRegistry: () => layoutRegistry,
|
|
43
|
+
resolveDisabled: () => import_core7.resolveDisabled,
|
|
44
|
+
resolveOptions: () => import_core7.resolveOptions,
|
|
45
|
+
resolveReadOnly: () => import_core7.resolveReadOnly,
|
|
46
|
+
useDynamicForm: () => useDynamicForm,
|
|
47
|
+
useFieldRegistry: () => useFieldRegistry,
|
|
48
|
+
validateField: () => import_core7.validateField,
|
|
49
|
+
validateFieldAsync: () => import_core7.validateFieldAsync,
|
|
50
|
+
validateFields: () => import_core7.validateFields,
|
|
51
|
+
validateFieldsAsync: () => import_core7.validateFieldsAsync,
|
|
52
|
+
validators: () => import_core7.validators
|
|
38
53
|
});
|
|
39
54
|
module.exports = __toCommonJS(index_exports);
|
|
40
55
|
|
|
@@ -101,17 +116,36 @@ function resolve(layout) {
|
|
|
101
116
|
return { type: layout.type, config: layout };
|
|
102
117
|
}
|
|
103
118
|
function checkIsMobile(breakpoint) {
|
|
104
|
-
|
|
119
|
+
if (typeof window === "undefined") {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
if (typeof window.matchMedia === "function") {
|
|
123
|
+
return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;
|
|
124
|
+
}
|
|
125
|
+
return window.innerWidth < breakpoint;
|
|
105
126
|
}
|
|
106
127
|
layoutRegistry.register("responsive", ({ children, config }) => {
|
|
107
128
|
const responsiveConfig = config;
|
|
108
129
|
const breakpoint = responsiveConfig.breakpoint ?? 768;
|
|
109
130
|
const [isMobile, setIsMobile] = (0, import_react.useState)(() => checkIsMobile(breakpoint));
|
|
110
131
|
(0, import_react.useEffect)(() => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
132
|
+
if (typeof window === "undefined") {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (typeof window.matchMedia !== "function") {
|
|
136
|
+
const handleResize = () => setIsMobile(checkIsMobile(breakpoint));
|
|
137
|
+
window.addEventListener("resize", handleResize);
|
|
138
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
139
|
+
}
|
|
140
|
+
const mediaQuery = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
141
|
+
const handleChange = (e) => setIsMobile(e.matches);
|
|
142
|
+
setIsMobile(mediaQuery.matches);
|
|
143
|
+
if (mediaQuery.addEventListener) {
|
|
144
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
145
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
146
|
+
}
|
|
147
|
+
mediaQuery.addListener(handleChange);
|
|
148
|
+
return () => mediaQuery.removeListener(handleChange);
|
|
115
149
|
}, [breakpoint]);
|
|
116
150
|
const current = isMobile ? responsiveConfig.mobile : responsiveConfig.desktop;
|
|
117
151
|
if (!current) {
|
|
@@ -132,58 +166,399 @@ layoutRegistry.register("responsive", ({ children, config }) => {
|
|
|
132
166
|
});
|
|
133
167
|
|
|
134
168
|
// src/components/DynamicInput.tsx
|
|
135
|
-
var
|
|
169
|
+
var import_react3 = __toESM(require("react"));
|
|
170
|
+
|
|
171
|
+
// src/defaultRenderers.tsx
|
|
172
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
173
|
+
var DefaultTextRenderer = ({
|
|
174
|
+
value,
|
|
175
|
+
onValueChange,
|
|
176
|
+
onBlur,
|
|
177
|
+
disabled,
|
|
178
|
+
readOnly,
|
|
179
|
+
required,
|
|
180
|
+
placeholder,
|
|
181
|
+
id,
|
|
182
|
+
className,
|
|
183
|
+
ariaInvalid,
|
|
184
|
+
ariaDescribedBy,
|
|
185
|
+
ariaRequired,
|
|
186
|
+
inputType = "text"
|
|
187
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
188
|
+
"input",
|
|
189
|
+
{
|
|
190
|
+
type: inputType,
|
|
191
|
+
id,
|
|
192
|
+
className,
|
|
193
|
+
value: value ?? "",
|
|
194
|
+
onChange: (e) => onValueChange?.(e.target.value),
|
|
195
|
+
onBlur,
|
|
196
|
+
disabled,
|
|
197
|
+
readOnly,
|
|
198
|
+
required,
|
|
199
|
+
placeholder,
|
|
200
|
+
"aria-invalid": ariaInvalid,
|
|
201
|
+
"aria-describedby": ariaDescribedBy,
|
|
202
|
+
"aria-required": ariaRequired
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
var DefaultNumberRenderer = ({
|
|
206
|
+
value,
|
|
207
|
+
onValueChange,
|
|
208
|
+
onBlur,
|
|
209
|
+
disabled,
|
|
210
|
+
readOnly,
|
|
211
|
+
required,
|
|
212
|
+
placeholder,
|
|
213
|
+
id,
|
|
214
|
+
className,
|
|
215
|
+
ariaInvalid,
|
|
216
|
+
ariaDescribedBy,
|
|
217
|
+
ariaRequired
|
|
218
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
219
|
+
"input",
|
|
220
|
+
{
|
|
221
|
+
type: "number",
|
|
222
|
+
id,
|
|
223
|
+
className,
|
|
224
|
+
value: value ?? "",
|
|
225
|
+
onChange: (e) => onValueChange?.(
|
|
226
|
+
e.target.value === "" ? void 0 : Number(e.target.value)
|
|
227
|
+
),
|
|
228
|
+
onBlur,
|
|
229
|
+
disabled,
|
|
230
|
+
readOnly,
|
|
231
|
+
required,
|
|
232
|
+
placeholder,
|
|
233
|
+
"aria-invalid": ariaInvalid,
|
|
234
|
+
"aria-describedby": ariaDescribedBy,
|
|
235
|
+
"aria-required": ariaRequired
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
var DefaultPasswordRenderer = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultTextRenderer, { ...props, inputType: "password" });
|
|
239
|
+
var DefaultEmailRenderer = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultTextRenderer, { ...props, inputType: "email" });
|
|
240
|
+
var DefaultTextareaRenderer = ({
|
|
241
|
+
value,
|
|
242
|
+
onValueChange,
|
|
243
|
+
onBlur,
|
|
244
|
+
disabled,
|
|
245
|
+
readOnly,
|
|
246
|
+
required,
|
|
247
|
+
placeholder,
|
|
248
|
+
id,
|
|
249
|
+
className,
|
|
250
|
+
ariaInvalid,
|
|
251
|
+
ariaDescribedBy,
|
|
252
|
+
ariaRequired
|
|
253
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
254
|
+
"textarea",
|
|
255
|
+
{
|
|
256
|
+
id,
|
|
257
|
+
className,
|
|
258
|
+
value: value ?? "",
|
|
259
|
+
onChange: (e) => onValueChange?.(e.target.value),
|
|
260
|
+
onBlur,
|
|
261
|
+
disabled,
|
|
262
|
+
readOnly,
|
|
263
|
+
required,
|
|
264
|
+
placeholder,
|
|
265
|
+
"aria-invalid": ariaInvalid,
|
|
266
|
+
"aria-describedby": ariaDescribedBy,
|
|
267
|
+
"aria-required": ariaRequired
|
|
268
|
+
}
|
|
269
|
+
);
|
|
270
|
+
var DefaultCheckboxRenderer = ({
|
|
271
|
+
value,
|
|
272
|
+
onValueChange,
|
|
273
|
+
onBlur,
|
|
274
|
+
disabled,
|
|
275
|
+
readOnly,
|
|
276
|
+
required,
|
|
277
|
+
id,
|
|
278
|
+
className,
|
|
279
|
+
ariaInvalid,
|
|
280
|
+
ariaDescribedBy,
|
|
281
|
+
ariaRequired
|
|
282
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
283
|
+
"input",
|
|
284
|
+
{
|
|
285
|
+
type: "checkbox",
|
|
286
|
+
id,
|
|
287
|
+
className,
|
|
288
|
+
checked: Boolean(value),
|
|
289
|
+
onChange: (e) => onValueChange?.(e.target.checked),
|
|
290
|
+
onBlur,
|
|
291
|
+
disabled: disabled || readOnly,
|
|
292
|
+
required,
|
|
293
|
+
"aria-invalid": ariaInvalid,
|
|
294
|
+
"aria-describedby": ariaDescribedBy,
|
|
295
|
+
"aria-required": ariaRequired
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
var DefaultSelectRenderer = ({
|
|
299
|
+
value,
|
|
300
|
+
onValueChange,
|
|
301
|
+
onBlur,
|
|
302
|
+
disabled,
|
|
303
|
+
readOnly,
|
|
304
|
+
required,
|
|
305
|
+
options = [],
|
|
306
|
+
id,
|
|
307
|
+
className,
|
|
308
|
+
ariaInvalid,
|
|
309
|
+
ariaDescribedBy,
|
|
310
|
+
ariaRequired
|
|
311
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
312
|
+
"select",
|
|
313
|
+
{
|
|
314
|
+
id,
|
|
315
|
+
className,
|
|
316
|
+
value: value ?? "",
|
|
317
|
+
onChange: (e) => onValueChange?.(e.target.value),
|
|
318
|
+
onBlur,
|
|
319
|
+
disabled: disabled || readOnly,
|
|
320
|
+
required,
|
|
321
|
+
"aria-invalid": ariaInvalid,
|
|
322
|
+
"aria-describedby": ariaDescribedBy,
|
|
323
|
+
"aria-required": ariaRequired,
|
|
324
|
+
children: [
|
|
325
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", disabled: true, children: "-- Select --" }),
|
|
326
|
+
options.map((opt, i) => {
|
|
327
|
+
const optVal = opt.value ?? opt.id ?? opt;
|
|
328
|
+
const optLabel = opt.label ?? opt.name ?? String(optVal);
|
|
329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: String(optVal), children: String(optLabel) }, String(optVal) + i);
|
|
330
|
+
})
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
);
|
|
334
|
+
var DefaultRadioRenderer = ({
|
|
335
|
+
value,
|
|
336
|
+
onValueChange,
|
|
337
|
+
onBlur,
|
|
338
|
+
disabled,
|
|
339
|
+
readOnly,
|
|
340
|
+
required,
|
|
341
|
+
options = [],
|
|
342
|
+
id,
|
|
343
|
+
className,
|
|
344
|
+
ariaInvalid,
|
|
345
|
+
ariaDescribedBy
|
|
346
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: `dfk-radio-group ${className || ""}`, id, onBlur, children: options.map((opt, i) => {
|
|
347
|
+
const optVal = opt.value ?? opt.id ?? opt;
|
|
348
|
+
const optLabel = opt.label ?? opt.name ?? String(optVal);
|
|
349
|
+
const isChecked = String(value) === String(optVal);
|
|
350
|
+
const radioId = `${id || "radio"}-${i}`;
|
|
351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
352
|
+
"label",
|
|
353
|
+
{
|
|
354
|
+
htmlFor: radioId,
|
|
355
|
+
style: {
|
|
356
|
+
marginRight: "12px",
|
|
357
|
+
display: "inline-flex",
|
|
358
|
+
alignItems: "center"
|
|
359
|
+
},
|
|
360
|
+
children: [
|
|
361
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
362
|
+
"input",
|
|
363
|
+
{
|
|
364
|
+
type: "radio",
|
|
365
|
+
id: radioId,
|
|
366
|
+
name: id,
|
|
367
|
+
value: String(optVal),
|
|
368
|
+
checked: isChecked,
|
|
369
|
+
onChange: () => onValueChange?.(optVal),
|
|
370
|
+
disabled: disabled || readOnly,
|
|
371
|
+
required,
|
|
372
|
+
"aria-invalid": ariaInvalid,
|
|
373
|
+
"aria-describedby": ariaDescribedBy
|
|
374
|
+
}
|
|
375
|
+
),
|
|
376
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { marginLeft: "4px" }, children: String(optLabel) })
|
|
377
|
+
]
|
|
378
|
+
},
|
|
379
|
+
String(optVal) + i
|
|
380
|
+
);
|
|
381
|
+
}) });
|
|
382
|
+
var DefaultRangeRenderer = ({
|
|
383
|
+
value,
|
|
384
|
+
onValueChange,
|
|
385
|
+
onBlur,
|
|
386
|
+
disabled,
|
|
387
|
+
readOnly,
|
|
388
|
+
required,
|
|
389
|
+
min,
|
|
390
|
+
max,
|
|
391
|
+
step,
|
|
392
|
+
id,
|
|
393
|
+
className,
|
|
394
|
+
ariaInvalid,
|
|
395
|
+
ariaDescribedBy
|
|
396
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
397
|
+
"input",
|
|
398
|
+
{
|
|
399
|
+
type: "range",
|
|
400
|
+
id,
|
|
401
|
+
className,
|
|
402
|
+
value: value ?? min ?? 0,
|
|
403
|
+
min,
|
|
404
|
+
max,
|
|
405
|
+
step,
|
|
406
|
+
onChange: (e) => onValueChange?.(Number(e.target.value)),
|
|
407
|
+
onBlur,
|
|
408
|
+
disabled: disabled || readOnly,
|
|
409
|
+
required,
|
|
410
|
+
"aria-invalid": ariaInvalid,
|
|
411
|
+
"aria-describedby": ariaDescribedBy
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
var DefaultFileRenderer = ({
|
|
415
|
+
onValueChange,
|
|
416
|
+
onBlur,
|
|
417
|
+
disabled,
|
|
418
|
+
readOnly,
|
|
419
|
+
required,
|
|
420
|
+
accept,
|
|
421
|
+
multiple,
|
|
422
|
+
id,
|
|
423
|
+
className,
|
|
424
|
+
ariaInvalid,
|
|
425
|
+
ariaDescribedBy
|
|
426
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
427
|
+
"input",
|
|
428
|
+
{
|
|
429
|
+
type: "file",
|
|
430
|
+
id,
|
|
431
|
+
className,
|
|
432
|
+
accept,
|
|
433
|
+
multiple,
|
|
434
|
+
onChange: (e) => {
|
|
435
|
+
const files = e.target.files;
|
|
436
|
+
if (!files) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
onValueChange?.(multiple ? Array.from(files) : files[0] || null);
|
|
440
|
+
},
|
|
441
|
+
onBlur,
|
|
442
|
+
disabled: disabled || readOnly,
|
|
443
|
+
required,
|
|
444
|
+
"aria-invalid": ariaInvalid,
|
|
445
|
+
"aria-describedby": ariaDescribedBy
|
|
446
|
+
}
|
|
447
|
+
);
|
|
448
|
+
var DefaultDateRenderer = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultTextRenderer, { ...props, inputType: "date" });
|
|
449
|
+
var DefaultTimeRenderer = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultTextRenderer, { ...props, inputType: "time" });
|
|
450
|
+
var DefaultDateTimeLocalRenderer = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultTextRenderer, { ...props, inputType: "datetime-local" });
|
|
451
|
+
var DefaultSwitchRenderer = (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DefaultCheckboxRenderer, { ...props });
|
|
452
|
+
var defaultRenderersMap = {
|
|
453
|
+
text: DefaultTextRenderer,
|
|
454
|
+
number: DefaultNumberRenderer,
|
|
455
|
+
password: DefaultPasswordRenderer,
|
|
456
|
+
email: DefaultEmailRenderer,
|
|
457
|
+
textarea: DefaultTextareaRenderer,
|
|
458
|
+
checkbox: DefaultCheckboxRenderer,
|
|
459
|
+
select: DefaultSelectRenderer,
|
|
460
|
+
radio: DefaultRadioRenderer,
|
|
461
|
+
range: DefaultRangeRenderer,
|
|
462
|
+
file: DefaultFileRenderer,
|
|
463
|
+
date: DefaultDateRenderer,
|
|
464
|
+
time: DefaultTimeRenderer,
|
|
465
|
+
"datetime-local": DefaultDateTimeLocalRenderer,
|
|
466
|
+
switch: DefaultSwitchRenderer
|
|
467
|
+
};
|
|
468
|
+
function getDefaultRenderer(type) {
|
|
469
|
+
return defaultRenderersMap[type];
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// src/FieldRegistryContext.tsx
|
|
473
|
+
var import_react2 = require("react");
|
|
136
474
|
|
|
137
475
|
// src/fieldRegistry.ts
|
|
138
476
|
var import_core = require("@dynamic-field-kit/core");
|
|
139
477
|
var fieldRegistry = import_core.fieldRegistry;
|
|
140
478
|
|
|
479
|
+
// src/FieldRegistryContext.tsx
|
|
480
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
481
|
+
var FieldRegistryContext = (0, import_react2.createContext)(fieldRegistry);
|
|
482
|
+
var FieldRegistryProvider = ({
|
|
483
|
+
registry,
|
|
484
|
+
children
|
|
485
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FieldRegistryContext.Provider, { value: registry, children });
|
|
486
|
+
function useFieldRegistry() {
|
|
487
|
+
return (0, import_react2.useContext)(FieldRegistryContext);
|
|
488
|
+
}
|
|
489
|
+
|
|
141
490
|
// src/components/DynamicInput.tsx
|
|
142
|
-
var
|
|
491
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
143
492
|
var DynamicInputInner = ({
|
|
144
493
|
type,
|
|
145
494
|
value,
|
|
146
495
|
onChange,
|
|
496
|
+
onBlur,
|
|
147
497
|
label,
|
|
148
498
|
options,
|
|
149
499
|
className,
|
|
150
|
-
description
|
|
500
|
+
description,
|
|
501
|
+
disabled,
|
|
502
|
+
readOnly,
|
|
503
|
+
required,
|
|
504
|
+
touched,
|
|
505
|
+
dirty,
|
|
506
|
+
error,
|
|
507
|
+
id,
|
|
508
|
+
ariaInvalid,
|
|
509
|
+
ariaDescribedBy,
|
|
510
|
+
ariaRequired,
|
|
511
|
+
extraProps
|
|
151
512
|
}) => {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
513
|
+
const registry = useFieldRegistry();
|
|
514
|
+
const Renderer = (0, import_react3.useMemo)(
|
|
515
|
+
() => registry.get(type) || getDefaultRenderer(type),
|
|
516
|
+
[registry, type]
|
|
155
517
|
);
|
|
156
518
|
if (!Renderer) {
|
|
157
|
-
return /* @__PURE__ */ (0,
|
|
519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
|
|
158
520
|
"Unknown field type: ",
|
|
159
521
|
type
|
|
160
522
|
] });
|
|
161
523
|
}
|
|
162
|
-
return
|
|
524
|
+
return import_react3.default.createElement(Renderer, {
|
|
525
|
+
...extraProps,
|
|
163
526
|
value,
|
|
164
527
|
onValueChange: onChange,
|
|
528
|
+
onBlur,
|
|
165
529
|
label,
|
|
166
530
|
options,
|
|
167
531
|
className,
|
|
168
|
-
description
|
|
532
|
+
description,
|
|
533
|
+
disabled,
|
|
534
|
+
readOnly,
|
|
535
|
+
required,
|
|
536
|
+
touched,
|
|
537
|
+
dirty,
|
|
538
|
+
error,
|
|
539
|
+
id,
|
|
540
|
+
ariaInvalid,
|
|
541
|
+
ariaDescribedBy,
|
|
542
|
+
ariaRequired
|
|
169
543
|
});
|
|
170
544
|
};
|
|
171
|
-
var DynamicInput =
|
|
545
|
+
var DynamicInput = /* @__PURE__ */ import_react3.default.memo(
|
|
172
546
|
DynamicInputInner
|
|
173
547
|
);
|
|
174
548
|
var DynamicInput_default = DynamicInput;
|
|
175
549
|
|
|
176
550
|
// src/components/FieldInput.tsx
|
|
177
|
-
var
|
|
551
|
+
var import_core4 = require("@dynamic-field-kit/core");
|
|
552
|
+
var import_react6 = __toESM(require("react"));
|
|
178
553
|
|
|
179
554
|
// src/components/FieldGroupInput.tsx
|
|
180
555
|
var import_core3 = require("@dynamic-field-kit/core");
|
|
181
|
-
var
|
|
556
|
+
var import_react5 = require("react");
|
|
182
557
|
|
|
183
558
|
// src/components/MultiFieldInput.tsx
|
|
184
559
|
var import_core2 = require("@dynamic-field-kit/core");
|
|
185
|
-
var
|
|
186
|
-
var
|
|
560
|
+
var import_react4 = require("react");
|
|
561
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
187
562
|
function resolveLayout(layout) {
|
|
188
563
|
if (!layout) {
|
|
189
564
|
return { type: "column", config: {} };
|
|
@@ -197,45 +572,74 @@ var MultiFieldInput = ({
|
|
|
197
572
|
fieldDescriptions,
|
|
198
573
|
properties,
|
|
199
574
|
onChange,
|
|
200
|
-
layout
|
|
575
|
+
layout,
|
|
576
|
+
rootData,
|
|
577
|
+
onValidityChange,
|
|
578
|
+
onBlurField
|
|
201
579
|
}) => {
|
|
202
|
-
const [data, setData] = (0,
|
|
203
|
-
(0,
|
|
580
|
+
const [data, setData] = (0, import_react4.useState)({});
|
|
581
|
+
const [touchedFields, setTouchedFields] = (0, import_react4.useState)(
|
|
582
|
+
{}
|
|
583
|
+
);
|
|
584
|
+
const initialPropertiesRef = (0, import_react4.useRef)(properties ?? {});
|
|
585
|
+
(0, import_react4.useEffect)(() => {
|
|
204
586
|
if (properties) {
|
|
205
|
-
setData((0, import_core2.applyComputedValues)(fieldDescriptions, properties));
|
|
587
|
+
setData((0, import_core2.applyComputedValues)(fieldDescriptions, properties, rootData));
|
|
206
588
|
}
|
|
207
589
|
}, [properties]);
|
|
208
|
-
const
|
|
590
|
+
const effectiveRoot = rootData ?? data;
|
|
591
|
+
const visibleFields = (0, import_react4.useMemo)(
|
|
209
592
|
() => fieldDescriptions.filter(
|
|
210
|
-
(f) => !f.appearCondition || f.appearCondition(data)
|
|
593
|
+
(f) => !f.appearCondition || f.appearCondition(data, effectiveRoot)
|
|
211
594
|
),
|
|
212
|
-
[fieldDescriptions, data]
|
|
595
|
+
[fieldDescriptions, data, effectiveRoot]
|
|
213
596
|
);
|
|
214
|
-
const dataRef = (0,
|
|
597
|
+
const dataRef = (0, import_react4.useRef)(data);
|
|
215
598
|
dataRef.current = data;
|
|
216
|
-
const onChangeRef = (0,
|
|
599
|
+
const onChangeRef = (0, import_react4.useRef)(onChange);
|
|
217
600
|
onChangeRef.current = onChange;
|
|
218
|
-
const fieldDescriptionsRef = (0,
|
|
601
|
+
const fieldDescriptionsRef = (0, import_react4.useRef)(fieldDescriptions);
|
|
219
602
|
fieldDescriptionsRef.current = fieldDescriptions;
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
603
|
+
const rootDataRef = (0, import_react4.useRef)(rootData);
|
|
604
|
+
rootDataRef.current = rootData;
|
|
605
|
+
const onValidityChangeRef = (0, import_react4.useRef)(onValidityChange);
|
|
606
|
+
onValidityChangeRef.current = onValidityChange;
|
|
607
|
+
const onBlurFieldRef = (0, import_react4.useRef)(onBlurField);
|
|
608
|
+
onBlurFieldRef.current = onBlurField;
|
|
609
|
+
(0, import_react4.useEffect)(() => {
|
|
610
|
+
onValidityChangeRef.current?.(
|
|
611
|
+
(0, import_core2.validateFields)(fieldDescriptions, data, rootData)
|
|
612
|
+
);
|
|
613
|
+
}, [data, fieldDescriptions, rootData]);
|
|
614
|
+
const handleValueChangeField = (0, import_react4.useCallback)((value, key) => {
|
|
615
|
+
const merged = { ...dataRef.current, [key]: value };
|
|
616
|
+
const next = (0, import_core2.applyComputedValues)(
|
|
617
|
+
fieldDescriptionsRef.current,
|
|
618
|
+
merged,
|
|
619
|
+
rootDataRef.current
|
|
620
|
+
);
|
|
225
621
|
dataRef.current = next;
|
|
226
622
|
setData(next);
|
|
227
623
|
onChangeRef.current?.(next);
|
|
228
624
|
}, []);
|
|
625
|
+
const handleBlurField = (0, import_react4.useCallback)((key) => {
|
|
626
|
+
setTouchedFields((prev) => prev[key] ? prev : { ...prev, [key]: true });
|
|
627
|
+
onBlurFieldRef.current?.(key);
|
|
628
|
+
}, []);
|
|
229
629
|
const { type, config } = resolveLayout(layout);
|
|
230
630
|
const Layout = layoutRegistry.get(type);
|
|
231
631
|
if (!Layout) {
|
|
232
632
|
throw new Error(`Unknown layout: ${type}`);
|
|
233
633
|
}
|
|
234
|
-
return /* @__PURE__ */ (0,
|
|
634
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Layout, { config, children: visibleFields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
235
635
|
FieldInput_default,
|
|
236
636
|
{
|
|
237
637
|
fieldDescription: f,
|
|
238
638
|
renderInfos: data,
|
|
639
|
+
rootData: effectiveRoot,
|
|
640
|
+
touched: Boolean(touchedFields[f.name]),
|
|
641
|
+
dirty: data[f.name] !== initialPropertiesRef.current[f.name],
|
|
642
|
+
onBlurField: handleBlurField,
|
|
239
643
|
onValueChangeField: handleValueChangeField
|
|
240
644
|
},
|
|
241
645
|
f.name
|
|
@@ -244,10 +648,25 @@ var MultiFieldInput = ({
|
|
|
244
648
|
var MultiFieldInput_default = MultiFieldInput;
|
|
245
649
|
|
|
246
650
|
// src/components/FieldGroupInput.tsx
|
|
247
|
-
var
|
|
248
|
-
var FieldGroupInput = ({
|
|
249
|
-
|
|
250
|
-
|
|
651
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
652
|
+
var FieldGroupInput = ({
|
|
653
|
+
fieldDescription,
|
|
654
|
+
items,
|
|
655
|
+
rootData,
|
|
656
|
+
onChange
|
|
657
|
+
}) => {
|
|
658
|
+
const {
|
|
659
|
+
fields = [],
|
|
660
|
+
label,
|
|
661
|
+
addLabel,
|
|
662
|
+
removeLabel,
|
|
663
|
+
keyField
|
|
664
|
+
} = fieldDescription;
|
|
665
|
+
const itemKey = (item, index) => keyField ? item[keyField] ?? index : index;
|
|
666
|
+
const addText = addLabel ?? "Add";
|
|
667
|
+
const removeText = removeLabel ?? "Remove";
|
|
668
|
+
const groupName = label ?? fieldDescription.name;
|
|
669
|
+
const handleItemChange = (0, import_react5.useCallback)(
|
|
251
670
|
(index, next) => {
|
|
252
671
|
const nextItems = items.slice();
|
|
253
672
|
nextItems[index] = next;
|
|
@@ -255,13 +674,13 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
255
674
|
},
|
|
256
675
|
[items, onChange]
|
|
257
676
|
);
|
|
258
|
-
const handleAdd = (0,
|
|
677
|
+
const handleAdd = (0, import_react5.useCallback)(() => {
|
|
259
678
|
if (!(0, import_core3.canAddGroupItem)(fieldDescription, items)) {
|
|
260
679
|
return;
|
|
261
680
|
}
|
|
262
681
|
onChange([...items, (0, import_core3.createGroupItem)(fieldDescription)]);
|
|
263
682
|
}, [fieldDescription, items, onChange]);
|
|
264
|
-
const handleRemove = (0,
|
|
683
|
+
const handleRemove = (0, import_react5.useCallback)(
|
|
265
684
|
(index) => {
|
|
266
685
|
if (!(0, import_core3.canRemoveGroupItem)(fieldDescription, items)) {
|
|
267
686
|
return;
|
|
@@ -270,41 +689,44 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
270
689
|
},
|
|
271
690
|
[fieldDescription, items, onChange]
|
|
272
691
|
);
|
|
273
|
-
return /* @__PURE__ */ (0,
|
|
274
|
-
label && /* @__PURE__ */ (0,
|
|
275
|
-
items.map((item, index) => /* @__PURE__ */ (0,
|
|
692
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: fieldDescription.className, children: [
|
|
693
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: label }),
|
|
694
|
+
items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
276
695
|
"div",
|
|
277
696
|
{
|
|
278
697
|
style: { display: "flex", alignItems: "flex-start", gap: 8 },
|
|
279
698
|
children: [
|
|
280
|
-
/* @__PURE__ */ (0,
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
281
700
|
MultiFieldInput_default,
|
|
282
701
|
{
|
|
283
702
|
fieldDescriptions: fields,
|
|
284
703
|
properties: item,
|
|
704
|
+
rootData,
|
|
285
705
|
onChange: (next) => handleItemChange(index, next)
|
|
286
706
|
}
|
|
287
707
|
) }),
|
|
288
|
-
/* @__PURE__ */ (0,
|
|
708
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
289
709
|
"button",
|
|
290
710
|
{
|
|
291
711
|
type: "button",
|
|
712
|
+
"aria-label": `${removeText} ${groupName} ${index + 1}`,
|
|
292
713
|
onClick: () => handleRemove(index),
|
|
293
714
|
disabled: !(0, import_core3.canRemoveGroupItem)(fieldDescription, items),
|
|
294
|
-
children:
|
|
715
|
+
children: removeText
|
|
295
716
|
}
|
|
296
717
|
)
|
|
297
718
|
]
|
|
298
719
|
},
|
|
299
|
-
index
|
|
720
|
+
itemKey(item, index)
|
|
300
721
|
)),
|
|
301
|
-
/* @__PURE__ */ (0,
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
302
723
|
"button",
|
|
303
724
|
{
|
|
304
725
|
type: "button",
|
|
726
|
+
"aria-label": `${addText} ${groupName}`,
|
|
305
727
|
onClick: handleAdd,
|
|
306
728
|
disabled: !(0, import_core3.canAddGroupItem)(fieldDescription, items),
|
|
307
|
-
children:
|
|
729
|
+
children: addText
|
|
308
730
|
}
|
|
309
731
|
)
|
|
310
732
|
] });
|
|
@@ -312,52 +734,411 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
312
734
|
var FieldGroupInput_default = FieldGroupInput;
|
|
313
735
|
|
|
314
736
|
// src/components/FieldInput.tsx
|
|
315
|
-
var
|
|
737
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
316
738
|
var FieldInputInner = ({
|
|
317
739
|
fieldDescription,
|
|
318
740
|
renderInfos,
|
|
741
|
+
rootData,
|
|
742
|
+
touched,
|
|
743
|
+
dirty,
|
|
744
|
+
onBlurField,
|
|
319
745
|
onValueChangeField
|
|
320
746
|
}) => {
|
|
321
|
-
const { name, type, label,
|
|
322
|
-
const handleChange = (0,
|
|
747
|
+
const { name, type, label, className, description, props, fields, required } = fieldDescription;
|
|
748
|
+
const handleChange = (0, import_react6.useCallback)(
|
|
323
749
|
(v) => onValueChangeField(v, name),
|
|
324
750
|
[onValueChangeField, name]
|
|
325
751
|
);
|
|
752
|
+
const handleBlur = (0, import_react6.useCallback)(
|
|
753
|
+
() => onBlurField?.(name),
|
|
754
|
+
[onBlurField, name]
|
|
755
|
+
);
|
|
326
756
|
if (fields) {
|
|
327
757
|
const items = Array.isArray(renderInfos[name]) ? renderInfos[name] : [];
|
|
328
|
-
return /* @__PURE__ */ (0,
|
|
758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
329
759
|
FieldGroupInput_default,
|
|
330
760
|
{
|
|
331
761
|
fieldDescription,
|
|
332
762
|
items,
|
|
763
|
+
rootData,
|
|
333
764
|
onChange: handleChange
|
|
334
765
|
}
|
|
335
766
|
);
|
|
336
767
|
}
|
|
337
|
-
|
|
768
|
+
const effectiveDisabled = (0, import_core4.resolveDisabled)(
|
|
769
|
+
fieldDescription,
|
|
770
|
+
renderInfos,
|
|
771
|
+
rootData
|
|
772
|
+
);
|
|
773
|
+
const readOnly = (0, import_core4.resolveReadOnly)(fieldDescription, renderInfos, rootData);
|
|
774
|
+
const resolvedOptionsList = (0, import_core4.resolveOptions)(
|
|
775
|
+
fieldDescription,
|
|
776
|
+
renderInfos,
|
|
777
|
+
rootData
|
|
778
|
+
);
|
|
779
|
+
const errors = effectiveDisabled ? [] : (0, import_core4.validateField)(fieldDescription, renderInfos[name], renderInfos, rootData);
|
|
780
|
+
const error = errors.length > 0 ? errors : void 0;
|
|
781
|
+
const fieldId = `dfk-field-${name}`;
|
|
782
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
338
783
|
DynamicInput_default,
|
|
339
784
|
{
|
|
785
|
+
id: fieldId,
|
|
340
786
|
type,
|
|
341
787
|
label,
|
|
342
788
|
value: renderInfos[name],
|
|
343
|
-
options,
|
|
789
|
+
options: resolvedOptionsList,
|
|
344
790
|
className,
|
|
345
791
|
description,
|
|
346
|
-
|
|
792
|
+
disabled: effectiveDisabled,
|
|
793
|
+
readOnly,
|
|
794
|
+
required,
|
|
795
|
+
touched,
|
|
796
|
+
dirty,
|
|
797
|
+
error,
|
|
798
|
+
ariaInvalid: Boolean(error),
|
|
799
|
+
ariaRequired: Boolean(required),
|
|
800
|
+
extraProps: props,
|
|
801
|
+
onChange: handleChange,
|
|
802
|
+
onBlur: handleBlur
|
|
347
803
|
}
|
|
348
804
|
);
|
|
349
805
|
};
|
|
350
|
-
var FieldInput =
|
|
806
|
+
var FieldInput = /* @__PURE__ */ import_react6.default.memo(FieldInputInner, (prev, next) => {
|
|
351
807
|
const name = prev.fieldDescription.name;
|
|
352
|
-
return prev.fieldDescription === next.fieldDescription && prev.onValueChangeField === next.onValueChangeField && prev.renderInfos[name] === next.renderInfos[name];
|
|
808
|
+
return prev.fieldDescription === next.fieldDescription && prev.onValueChangeField === next.onValueChangeField && prev.onBlurField === next.onBlurField && prev.rootData === next.rootData && prev.touched === next.touched && prev.dirty === next.dirty && prev.renderInfos[name] === next.renderInfos[name];
|
|
353
809
|
});
|
|
354
810
|
var FieldInput_default = FieldInput;
|
|
811
|
+
|
|
812
|
+
// src/components/DynamicFormDevTools.tsx
|
|
813
|
+
var import_react7 = require("react");
|
|
814
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
815
|
+
var DynamicFormDevTools = ({
|
|
816
|
+
data,
|
|
817
|
+
errors = {},
|
|
818
|
+
touched = {},
|
|
819
|
+
isDirty = false,
|
|
820
|
+
fields = [],
|
|
821
|
+
position = "bottom-right"
|
|
822
|
+
}) => {
|
|
823
|
+
const [isOpen, setIsOpen] = (0, import_react7.useState)(false);
|
|
824
|
+
const [activeTab, setActiveTab] = (0, import_react7.useState)("data");
|
|
825
|
+
const errorCount = Object.keys(errors).length;
|
|
826
|
+
const posStyle = position === "bottom-left" ? { left: "16px", bottom: "16px" } : { right: "16px", bottom: "16px" };
|
|
827
|
+
if (!isOpen) {
|
|
828
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
829
|
+
"button",
|
|
830
|
+
{
|
|
831
|
+
type: "button",
|
|
832
|
+
onClick: () => setIsOpen(true),
|
|
833
|
+
style: {
|
|
834
|
+
position: "fixed",
|
|
835
|
+
...posStyle,
|
|
836
|
+
zIndex: 99999,
|
|
837
|
+
background: "#1e293b",
|
|
838
|
+
color: "#f8fafc",
|
|
839
|
+
border: "1px solid #334155",
|
|
840
|
+
borderRadius: "20px",
|
|
841
|
+
padding: "8px 14px",
|
|
842
|
+
fontSize: "12px",
|
|
843
|
+
fontWeight: 600,
|
|
844
|
+
cursor: "pointer",
|
|
845
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
846
|
+
display: "flex",
|
|
847
|
+
alignItems: "center",
|
|
848
|
+
gap: "6px"
|
|
849
|
+
},
|
|
850
|
+
children: [
|
|
851
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "\u{1F50D} DevTools" }),
|
|
852
|
+
errorCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
853
|
+
"span",
|
|
854
|
+
{
|
|
855
|
+
style: {
|
|
856
|
+
background: "#ef4444",
|
|
857
|
+
color: "#fff",
|
|
858
|
+
borderRadius: "10px",
|
|
859
|
+
padding: "2px 6px",
|
|
860
|
+
fontSize: "10px"
|
|
861
|
+
},
|
|
862
|
+
children: errorCount
|
|
863
|
+
}
|
|
864
|
+
)
|
|
865
|
+
]
|
|
866
|
+
}
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
870
|
+
"div",
|
|
871
|
+
{
|
|
872
|
+
style: {
|
|
873
|
+
position: "fixed",
|
|
874
|
+
...posStyle,
|
|
875
|
+
zIndex: 99999,
|
|
876
|
+
width: "360px",
|
|
877
|
+
maxHeight: "420px",
|
|
878
|
+
background: "#0f172a",
|
|
879
|
+
color: "#f8fafc",
|
|
880
|
+
border: "1px solid #334155",
|
|
881
|
+
borderRadius: "12px",
|
|
882
|
+
boxShadow: "0 10px 25px rgba(0,0,0,0.3)",
|
|
883
|
+
display: "flex",
|
|
884
|
+
flexDirection: "column",
|
|
885
|
+
fontFamily: "monospace, sans-serif",
|
|
886
|
+
fontSize: "12px",
|
|
887
|
+
overflow: "hidden"
|
|
888
|
+
},
|
|
889
|
+
children: [
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
891
|
+
"div",
|
|
892
|
+
{
|
|
893
|
+
style: {
|
|
894
|
+
padding: "10px 14px",
|
|
895
|
+
background: "#1e293b",
|
|
896
|
+
display: "flex",
|
|
897
|
+
justifyContent: "space-between",
|
|
898
|
+
alignItems: "center",
|
|
899
|
+
borderBottom: "1px solid #334155"
|
|
900
|
+
},
|
|
901
|
+
children: [
|
|
902
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { fontWeight: "bold", color: "#38bdf8" }, children: "\u{1F6E0}\uFE0F Form DevTools" }),
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
904
|
+
"button",
|
|
905
|
+
{
|
|
906
|
+
type: "button",
|
|
907
|
+
onClick: () => setIsOpen(false),
|
|
908
|
+
style: {
|
|
909
|
+
background: "transparent",
|
|
910
|
+
border: "none",
|
|
911
|
+
color: "#94a3b8",
|
|
912
|
+
fontSize: "14px",
|
|
913
|
+
cursor: "pointer"
|
|
914
|
+
},
|
|
915
|
+
children: "\u2715"
|
|
916
|
+
}
|
|
917
|
+
)
|
|
918
|
+
]
|
|
919
|
+
}
|
|
920
|
+
),
|
|
921
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
922
|
+
"div",
|
|
923
|
+
{
|
|
924
|
+
style: {
|
|
925
|
+
display: "flex",
|
|
926
|
+
background: "#1e293b",
|
|
927
|
+
borderBottom: "1px solid #334155"
|
|
928
|
+
},
|
|
929
|
+
children: ["data", "errors", "meta", "fields"].map((tab) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
930
|
+
"button",
|
|
931
|
+
{
|
|
932
|
+
type: "button",
|
|
933
|
+
onClick: () => setActiveTab(tab),
|
|
934
|
+
style: {
|
|
935
|
+
flex: 1,
|
|
936
|
+
padding: "6px 0",
|
|
937
|
+
background: activeTab === tab ? "#0f172a" : "transparent",
|
|
938
|
+
color: activeTab === tab ? "#38bdf8" : "#94a3b8",
|
|
939
|
+
border: "none",
|
|
940
|
+
cursor: "pointer",
|
|
941
|
+
textTransform: "capitalize",
|
|
942
|
+
fontSize: "11px",
|
|
943
|
+
fontWeight: activeTab === tab ? "bold" : "normal"
|
|
944
|
+
},
|
|
945
|
+
children: [
|
|
946
|
+
tab,
|
|
947
|
+
" ",
|
|
948
|
+
tab === "errors" && errorCount > 0 ? `(${errorCount})` : ""
|
|
949
|
+
]
|
|
950
|
+
},
|
|
951
|
+
tab
|
|
952
|
+
))
|
|
953
|
+
}
|
|
954
|
+
),
|
|
955
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { padding: "12px", overflowY: "auto", flex: 1 }, children: [
|
|
956
|
+
activeTab === "data" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
957
|
+
"pre",
|
|
958
|
+
{
|
|
959
|
+
style: {
|
|
960
|
+
margin: 0,
|
|
961
|
+
whiteSpace: "pre-wrap",
|
|
962
|
+
wordBreak: "break-all",
|
|
963
|
+
color: "#a7f3d0"
|
|
964
|
+
},
|
|
965
|
+
children: JSON.stringify(data, null, 2)
|
|
966
|
+
}
|
|
967
|
+
),
|
|
968
|
+
activeTab === "errors" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: Object.keys(errors).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#4ade80" }, children: "\u2713 No validation errors" }) : Object.entries(errors).map(([field, msgs]) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginBottom: "8px" }, children: [
|
|
969
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { style: { color: "#f87171", fontWeight: "bold" }, children: [
|
|
970
|
+
field,
|
|
971
|
+
":"
|
|
972
|
+
] }),
|
|
973
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { style: { margin: "4px 0 0 16px", padding: 0 }, children: msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { style: { color: "#fca5a5" }, children: m }, i)) })
|
|
974
|
+
] }, field)) }),
|
|
975
|
+
activeTab === "meta" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
976
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { marginBottom: "6px" }, children: [
|
|
977
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#94a3b8" }, children: "isDirty: " }),
|
|
978
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: isDirty ? "#facc15" : "#4ade80" }, children: String(isDirty) })
|
|
979
|
+
] }),
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#94a3b8" }, children: "Touched Fields:" }),
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("pre", { style: { margin: "4px 0 0 0", color: "#cbd5e1" }, children: JSON.stringify(touched, null, 2) })
|
|
983
|
+
] })
|
|
984
|
+
] }),
|
|
985
|
+
activeTab === "fields" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: { color: "#94a3b8" }, children: "No field descriptions passed" }) : fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
986
|
+
"div",
|
|
987
|
+
{
|
|
988
|
+
style: {
|
|
989
|
+
padding: "6px",
|
|
990
|
+
marginBottom: "6px",
|
|
991
|
+
background: "#1e293b",
|
|
992
|
+
borderRadius: "4px"
|
|
993
|
+
},
|
|
994
|
+
children: [
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { color: "#38bdf8", fontWeight: "bold" }, children: f.name }),
|
|
996
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { color: "#94a3b8", fontSize: "10px" }, children: [
|
|
997
|
+
"type: ",
|
|
998
|
+
f.type,
|
|
999
|
+
" | required: ",
|
|
1000
|
+
String(Boolean(f.required))
|
|
1001
|
+
] })
|
|
1002
|
+
]
|
|
1003
|
+
},
|
|
1004
|
+
f.name
|
|
1005
|
+
)) })
|
|
1006
|
+
] })
|
|
1007
|
+
]
|
|
1008
|
+
}
|
|
1009
|
+
);
|
|
1010
|
+
};
|
|
1011
|
+
|
|
1012
|
+
// src/useDynamicForm.ts
|
|
1013
|
+
var import_core5 = require("@dynamic-field-kit/core");
|
|
1014
|
+
var import_react8 = require("react");
|
|
1015
|
+
function useDynamicForm({
|
|
1016
|
+
fields,
|
|
1017
|
+
initialValues = {},
|
|
1018
|
+
validateOnBlur = true,
|
|
1019
|
+
validateOnChange = false
|
|
1020
|
+
}) {
|
|
1021
|
+
const [data, setData] = (0, import_react8.useState)(
|
|
1022
|
+
() => (0, import_core5.applyComputedValues)(fields, initialValues)
|
|
1023
|
+
);
|
|
1024
|
+
const [errors, setErrors] = (0, import_react8.useState)({});
|
|
1025
|
+
const [isDirty, setIsDirty] = (0, import_react8.useState)(false);
|
|
1026
|
+
const [touched, setTouched] = (0, import_react8.useState)({});
|
|
1027
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react8.useState)(false);
|
|
1028
|
+
const [isSubmitted, setIsSubmitted] = (0, import_react8.useState)(false);
|
|
1029
|
+
const validate = (0, import_react8.useCallback)(() => {
|
|
1030
|
+
const res = (0, import_core5.validateFields)(fields, data);
|
|
1031
|
+
setErrors(res.errors);
|
|
1032
|
+
return res.valid;
|
|
1033
|
+
}, [fields, data]);
|
|
1034
|
+
const handleChange = (0, import_react8.useCallback)(
|
|
1035
|
+
(newData) => {
|
|
1036
|
+
const next = (0, import_core5.applyComputedValues)(fields, newData);
|
|
1037
|
+
setData(next);
|
|
1038
|
+
setIsDirty(true);
|
|
1039
|
+
if (validateOnChange) {
|
|
1040
|
+
const res = (0, import_core5.validateFields)(fields, next);
|
|
1041
|
+
setErrors(res.errors);
|
|
1042
|
+
}
|
|
1043
|
+
},
|
|
1044
|
+
[fields, validateOnChange]
|
|
1045
|
+
);
|
|
1046
|
+
const setFieldValue = (0, import_react8.useCallback)(
|
|
1047
|
+
(name, value) => {
|
|
1048
|
+
handleChange({ ...data, [name]: value });
|
|
1049
|
+
},
|
|
1050
|
+
[data, handleChange]
|
|
1051
|
+
);
|
|
1052
|
+
const setFieldTouched = (0, import_react8.useCallback)((name, isTouched = true) => {
|
|
1053
|
+
setTouched((prev) => ({ ...prev, [name]: isTouched }));
|
|
1054
|
+
}, []);
|
|
1055
|
+
const handleBlur = (0, import_react8.useCallback)(
|
|
1056
|
+
(fieldName) => {
|
|
1057
|
+
setFieldTouched(fieldName, true);
|
|
1058
|
+
if (validateOnBlur) {
|
|
1059
|
+
const res = (0, import_core5.validateFields)(fields, data);
|
|
1060
|
+
setErrors(res.errors);
|
|
1061
|
+
}
|
|
1062
|
+
},
|
|
1063
|
+
[fields, data, validateOnBlur, setFieldTouched]
|
|
1064
|
+
);
|
|
1065
|
+
const reset = (0, import_react8.useCallback)(
|
|
1066
|
+
(newValues) => {
|
|
1067
|
+
const seed = newValues ?? initialValues;
|
|
1068
|
+
const next = (0, import_core5.applyComputedValues)(fields, seed);
|
|
1069
|
+
setData(next);
|
|
1070
|
+
setErrors({});
|
|
1071
|
+
setIsDirty(false);
|
|
1072
|
+
setTouched({});
|
|
1073
|
+
setIsSubmitting(false);
|
|
1074
|
+
setIsSubmitted(false);
|
|
1075
|
+
},
|
|
1076
|
+
[fields, initialValues]
|
|
1077
|
+
);
|
|
1078
|
+
const handleSubmit = (0, import_react8.useCallback)(
|
|
1079
|
+
(onValid, onInvalid) => async (e) => {
|
|
1080
|
+
if (e && typeof e.preventDefault === "function") {
|
|
1081
|
+
e.preventDefault();
|
|
1082
|
+
}
|
|
1083
|
+
setIsSubmitting(true);
|
|
1084
|
+
try {
|
|
1085
|
+
const res = (0, import_core5.validateFields)(fields, data);
|
|
1086
|
+
setErrors(res.errors);
|
|
1087
|
+
setIsSubmitted(true);
|
|
1088
|
+
if (res.valid) {
|
|
1089
|
+
await onValid(data);
|
|
1090
|
+
} else if (onInvalid) {
|
|
1091
|
+
onInvalid(res.errors);
|
|
1092
|
+
}
|
|
1093
|
+
} finally {
|
|
1094
|
+
setIsSubmitting(false);
|
|
1095
|
+
}
|
|
1096
|
+
},
|
|
1097
|
+
[fields, data]
|
|
1098
|
+
);
|
|
1099
|
+
const isValid = Object.keys(errors).length === 0;
|
|
1100
|
+
return {
|
|
1101
|
+
data,
|
|
1102
|
+
errors,
|
|
1103
|
+
isValid,
|
|
1104
|
+
isDirty,
|
|
1105
|
+
isSubmitting,
|
|
1106
|
+
isSubmitted,
|
|
1107
|
+
touched,
|
|
1108
|
+
setData,
|
|
1109
|
+
setFieldValue,
|
|
1110
|
+
setFieldTouched,
|
|
1111
|
+
handleChange,
|
|
1112
|
+
handleBlur,
|
|
1113
|
+
reset,
|
|
1114
|
+
validate,
|
|
1115
|
+
handleSubmit
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// src/index.ts
|
|
1120
|
+
var import_core6 = require("@dynamic-field-kit/core");
|
|
1121
|
+
var import_core7 = require("@dynamic-field-kit/core");
|
|
355
1122
|
// Annotate the CommonJS export names for ESM import in node:
|
|
356
1123
|
0 && (module.exports = {
|
|
1124
|
+
DynamicFormDevTools,
|
|
357
1125
|
DynamicInput,
|
|
358
1126
|
FieldInput,
|
|
1127
|
+
FieldRegistry,
|
|
1128
|
+
FieldRegistryProvider,
|
|
359
1129
|
MultiFieldInput,
|
|
1130
|
+
defaultRenderersMap,
|
|
360
1131
|
fieldRegistry,
|
|
361
|
-
|
|
1132
|
+
getDefaultRenderer,
|
|
1133
|
+
layoutRegistry,
|
|
1134
|
+
resolveDisabled,
|
|
1135
|
+
resolveOptions,
|
|
1136
|
+
resolveReadOnly,
|
|
1137
|
+
useDynamicForm,
|
|
1138
|
+
useFieldRegistry,
|
|
1139
|
+
validateField,
|
|
1140
|
+
validateFieldAsync,
|
|
1141
|
+
validateFields,
|
|
1142
|
+
validateFieldsAsync,
|
|
1143
|
+
validators
|
|
362
1144
|
});
|
|
363
|
-
//# sourceMappingURL=index.js.map
|