@dynamic-field-kit/react 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -3
- package/dist/index.d.mts +43 -17
- package/dist/index.d.ts +43 -17
- package/dist/index.js +223 -61
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +209 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -9
package/dist/index.mjs
CHANGED
|
@@ -61,17 +61,36 @@ function resolve(layout) {
|
|
|
61
61
|
return { type: layout.type, config: layout };
|
|
62
62
|
}
|
|
63
63
|
function checkIsMobile(breakpoint) {
|
|
64
|
-
|
|
64
|
+
if (typeof window === "undefined") {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (typeof window.matchMedia === "function") {
|
|
68
|
+
return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;
|
|
69
|
+
}
|
|
70
|
+
return window.innerWidth < breakpoint;
|
|
65
71
|
}
|
|
66
72
|
layoutRegistry.register("responsive", ({ children, config }) => {
|
|
67
73
|
const responsiveConfig = config;
|
|
68
74
|
const breakpoint = responsiveConfig.breakpoint ?? 768;
|
|
69
75
|
const [isMobile, setIsMobile] = useState(() => checkIsMobile(breakpoint));
|
|
70
76
|
useEffect(() => {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
if (typeof window === "undefined") {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (typeof window.matchMedia !== "function") {
|
|
81
|
+
const handleResize = () => setIsMobile(checkIsMobile(breakpoint));
|
|
82
|
+
window.addEventListener("resize", handleResize);
|
|
83
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
84
|
+
}
|
|
85
|
+
const mediaQuery = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
86
|
+
const handleChange = (e) => setIsMobile(e.matches);
|
|
87
|
+
setIsMobile(mediaQuery.matches);
|
|
88
|
+
if (mediaQuery.addEventListener) {
|
|
89
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
90
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
91
|
+
}
|
|
92
|
+
mediaQuery.addListener(handleChange);
|
|
93
|
+
return () => mediaQuery.removeListener(handleChange);
|
|
75
94
|
}, [breakpoint]);
|
|
76
95
|
const current = isMobile ? responsiveConfig.mobile : responsiveConfig.desktop;
|
|
77
96
|
if (!current) {
|
|
@@ -92,7 +111,10 @@ layoutRegistry.register("responsive", ({ children, config }) => {
|
|
|
92
111
|
});
|
|
93
112
|
|
|
94
113
|
// src/components/DynamicInput.tsx
|
|
95
|
-
import
|
|
114
|
+
import React3, { useMemo } from "react";
|
|
115
|
+
|
|
116
|
+
// src/FieldRegistryContext.tsx
|
|
117
|
+
import { createContext, useContext } from "react";
|
|
96
118
|
|
|
97
119
|
// src/fieldRegistry.ts
|
|
98
120
|
import {
|
|
@@ -100,20 +122,44 @@ import {
|
|
|
100
122
|
} from "@dynamic-field-kit/core";
|
|
101
123
|
var fieldRegistry = coreFieldRegistry;
|
|
102
124
|
|
|
125
|
+
// src/FieldRegistryContext.tsx
|
|
126
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
127
|
+
var FieldRegistryContext = createContext(fieldRegistry);
|
|
128
|
+
var FieldRegistryProvider = ({
|
|
129
|
+
registry,
|
|
130
|
+
children
|
|
131
|
+
}) => /* @__PURE__ */ jsx3(FieldRegistryContext.Provider, { value: registry, children });
|
|
132
|
+
function useFieldRegistry() {
|
|
133
|
+
return useContext(FieldRegistryContext);
|
|
134
|
+
}
|
|
135
|
+
|
|
103
136
|
// src/components/DynamicInput.tsx
|
|
104
137
|
import { jsxs as jsxs2 } from "react/jsx-runtime";
|
|
105
138
|
var DynamicInputInner = ({
|
|
106
139
|
type,
|
|
107
140
|
value,
|
|
108
141
|
onChange,
|
|
142
|
+
onBlur,
|
|
109
143
|
label,
|
|
110
144
|
options,
|
|
111
145
|
className,
|
|
112
|
-
description
|
|
146
|
+
description,
|
|
147
|
+
disabled,
|
|
148
|
+
readOnly,
|
|
149
|
+
required,
|
|
150
|
+
touched,
|
|
151
|
+
dirty,
|
|
152
|
+
error,
|
|
153
|
+
id,
|
|
154
|
+
ariaInvalid,
|
|
155
|
+
ariaDescribedBy,
|
|
156
|
+
ariaRequired,
|
|
157
|
+
extraProps
|
|
113
158
|
}) => {
|
|
159
|
+
const registry = useFieldRegistry();
|
|
114
160
|
const Renderer = useMemo(
|
|
115
|
-
() =>
|
|
116
|
-
[type]
|
|
161
|
+
() => registry.get(type),
|
|
162
|
+
[registry, type]
|
|
117
163
|
);
|
|
118
164
|
if (!Renderer) {
|
|
119
165
|
return /* @__PURE__ */ jsxs2("div", { children: [
|
|
@@ -121,22 +167,40 @@ var DynamicInputInner = ({
|
|
|
121
167
|
type
|
|
122
168
|
] });
|
|
123
169
|
}
|
|
124
|
-
return
|
|
170
|
+
return React3.createElement(Renderer, {
|
|
171
|
+
...extraProps,
|
|
125
172
|
value,
|
|
126
173
|
onValueChange: onChange,
|
|
174
|
+
onBlur,
|
|
127
175
|
label,
|
|
128
176
|
options,
|
|
129
177
|
className,
|
|
130
|
-
description
|
|
178
|
+
description,
|
|
179
|
+
disabled,
|
|
180
|
+
readOnly,
|
|
181
|
+
required,
|
|
182
|
+
touched,
|
|
183
|
+
dirty,
|
|
184
|
+
error,
|
|
185
|
+
id,
|
|
186
|
+
ariaInvalid,
|
|
187
|
+
ariaDescribedBy,
|
|
188
|
+
ariaRequired
|
|
131
189
|
});
|
|
132
190
|
};
|
|
133
|
-
var DynamicInput =
|
|
191
|
+
var DynamicInput = React3.memo(
|
|
134
192
|
DynamicInputInner
|
|
135
193
|
);
|
|
136
194
|
var DynamicInput_default = DynamicInput;
|
|
137
195
|
|
|
138
196
|
// src/components/FieldInput.tsx
|
|
139
|
-
import
|
|
197
|
+
import {
|
|
198
|
+
resolveDisabled,
|
|
199
|
+
resolveOptions,
|
|
200
|
+
resolveReadOnly,
|
|
201
|
+
validateField
|
|
202
|
+
} from "@dynamic-field-kit/core";
|
|
203
|
+
import React6, { useCallback as useCallback3 } from "react";
|
|
140
204
|
|
|
141
205
|
// src/components/FieldGroupInput.tsx
|
|
142
206
|
import {
|
|
@@ -148,7 +212,8 @@ import { useCallback as useCallback2 } from "react";
|
|
|
148
212
|
|
|
149
213
|
// src/components/MultiFieldInput.tsx
|
|
150
214
|
import {
|
|
151
|
-
applyComputedValues
|
|
215
|
+
applyComputedValues,
|
|
216
|
+
validateFields
|
|
152
217
|
} from "@dynamic-field-kit/core";
|
|
153
218
|
import {
|
|
154
219
|
useCallback,
|
|
@@ -157,7 +222,7 @@ import {
|
|
|
157
222
|
useRef,
|
|
158
223
|
useState as useState2
|
|
159
224
|
} from "react";
|
|
160
|
-
import { jsx as
|
|
225
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
161
226
|
function resolveLayout(layout) {
|
|
162
227
|
if (!layout) {
|
|
163
228
|
return { type: "column", config: {} };
|
|
@@ -171,19 +236,26 @@ var MultiFieldInput = ({
|
|
|
171
236
|
fieldDescriptions,
|
|
172
237
|
properties,
|
|
173
238
|
onChange,
|
|
174
|
-
layout
|
|
239
|
+
layout,
|
|
240
|
+
rootData,
|
|
241
|
+
onValidityChange
|
|
175
242
|
}) => {
|
|
176
243
|
const [data, setData] = useState2({});
|
|
244
|
+
const [touchedFields, setTouchedFields] = useState2(
|
|
245
|
+
{}
|
|
246
|
+
);
|
|
247
|
+
const initialPropertiesRef = useRef(properties ?? {});
|
|
177
248
|
useEffect2(() => {
|
|
178
249
|
if (properties) {
|
|
179
|
-
setData(applyComputedValues(fieldDescriptions, properties));
|
|
250
|
+
setData(applyComputedValues(fieldDescriptions, properties, rootData));
|
|
180
251
|
}
|
|
181
252
|
}, [properties]);
|
|
253
|
+
const effectiveRoot = rootData ?? data;
|
|
182
254
|
const visibleFields = useMemo2(
|
|
183
255
|
() => fieldDescriptions.filter(
|
|
184
|
-
(f) => !f.appearCondition || f.appearCondition(data)
|
|
256
|
+
(f) => !f.appearCondition || f.appearCondition(data, effectiveRoot)
|
|
185
257
|
),
|
|
186
|
-
[fieldDescriptions, data]
|
|
258
|
+
[fieldDescriptions, data, effectiveRoot]
|
|
187
259
|
);
|
|
188
260
|
const dataRef = useRef(data);
|
|
189
261
|
dataRef.current = data;
|
|
@@ -191,25 +263,43 @@ var MultiFieldInput = ({
|
|
|
191
263
|
onChangeRef.current = onChange;
|
|
192
264
|
const fieldDescriptionsRef = useRef(fieldDescriptions);
|
|
193
265
|
fieldDescriptionsRef.current = fieldDescriptions;
|
|
266
|
+
const rootDataRef = useRef(rootData);
|
|
267
|
+
rootDataRef.current = rootData;
|
|
268
|
+
const onValidityChangeRef = useRef(onValidityChange);
|
|
269
|
+
onValidityChangeRef.current = onValidityChange;
|
|
270
|
+
useEffect2(() => {
|
|
271
|
+
onValidityChangeRef.current?.(
|
|
272
|
+
validateFields(fieldDescriptions, data, rootData)
|
|
273
|
+
);
|
|
274
|
+
}, [data, fieldDescriptions, rootData]);
|
|
194
275
|
const handleValueChangeField = useCallback((value, key) => {
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
276
|
+
const merged = { ...dataRef.current, [key]: value };
|
|
277
|
+
const next = applyComputedValues(
|
|
278
|
+
fieldDescriptionsRef.current,
|
|
279
|
+
merged,
|
|
280
|
+
rootDataRef.current
|
|
281
|
+
);
|
|
199
282
|
dataRef.current = next;
|
|
200
283
|
setData(next);
|
|
201
284
|
onChangeRef.current?.(next);
|
|
202
285
|
}, []);
|
|
286
|
+
const handleBlurField = useCallback((key) => {
|
|
287
|
+
setTouchedFields((prev) => prev[key] ? prev : { ...prev, [key]: true });
|
|
288
|
+
}, []);
|
|
203
289
|
const { type, config } = resolveLayout(layout);
|
|
204
290
|
const Layout = layoutRegistry.get(type);
|
|
205
291
|
if (!Layout) {
|
|
206
292
|
throw new Error(`Unknown layout: ${type}`);
|
|
207
293
|
}
|
|
208
|
-
return /* @__PURE__ */
|
|
294
|
+
return /* @__PURE__ */ jsx4(Layout, { config, children: visibleFields.map((f) => /* @__PURE__ */ jsx4(
|
|
209
295
|
FieldInput_default,
|
|
210
296
|
{
|
|
211
297
|
fieldDescription: f,
|
|
212
298
|
renderInfos: data,
|
|
299
|
+
rootData: effectiveRoot,
|
|
300
|
+
touched: Boolean(touchedFields[f.name]),
|
|
301
|
+
dirty: data[f.name] !== initialPropertiesRef.current[f.name],
|
|
302
|
+
onBlurField: handleBlurField,
|
|
213
303
|
onValueChangeField: handleValueChangeField
|
|
214
304
|
},
|
|
215
305
|
f.name
|
|
@@ -218,9 +308,24 @@ var MultiFieldInput = ({
|
|
|
218
308
|
var MultiFieldInput_default = MultiFieldInput;
|
|
219
309
|
|
|
220
310
|
// src/components/FieldGroupInput.tsx
|
|
221
|
-
import { jsx as
|
|
222
|
-
var FieldGroupInput = ({
|
|
223
|
-
|
|
311
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
312
|
+
var FieldGroupInput = ({
|
|
313
|
+
fieldDescription,
|
|
314
|
+
items,
|
|
315
|
+
rootData,
|
|
316
|
+
onChange
|
|
317
|
+
}) => {
|
|
318
|
+
const {
|
|
319
|
+
fields = [],
|
|
320
|
+
label,
|
|
321
|
+
addLabel,
|
|
322
|
+
removeLabel,
|
|
323
|
+
keyField
|
|
324
|
+
} = fieldDescription;
|
|
325
|
+
const itemKey = (item, index) => keyField ? item[keyField] ?? index : index;
|
|
326
|
+
const addText = addLabel ?? "Add";
|
|
327
|
+
const removeText = removeLabel ?? "Remove";
|
|
328
|
+
const groupName = label ?? fieldDescription.name;
|
|
224
329
|
const handleItemChange = useCallback2(
|
|
225
330
|
(index, next) => {
|
|
226
331
|
const nextItems = items.slice();
|
|
@@ -245,40 +350,43 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
245
350
|
[fieldDescription, items, onChange]
|
|
246
351
|
);
|
|
247
352
|
return /* @__PURE__ */ jsxs3("div", { className: fieldDescription.className, children: [
|
|
248
|
-
label && /* @__PURE__ */
|
|
353
|
+
label && /* @__PURE__ */ jsx5("div", { children: label }),
|
|
249
354
|
items.map((item, index) => /* @__PURE__ */ jsxs3(
|
|
250
355
|
"div",
|
|
251
356
|
{
|
|
252
357
|
style: { display: "flex", alignItems: "flex-start", gap: 8 },
|
|
253
358
|
children: [
|
|
254
|
-
/* @__PURE__ */
|
|
359
|
+
/* @__PURE__ */ jsx5("div", { style: { flex: 1 }, children: /* @__PURE__ */ jsx5(
|
|
255
360
|
MultiFieldInput_default,
|
|
256
361
|
{
|
|
257
362
|
fieldDescriptions: fields,
|
|
258
363
|
properties: item,
|
|
364
|
+
rootData,
|
|
259
365
|
onChange: (next) => handleItemChange(index, next)
|
|
260
366
|
}
|
|
261
367
|
) }),
|
|
262
|
-
/* @__PURE__ */
|
|
368
|
+
/* @__PURE__ */ jsx5(
|
|
263
369
|
"button",
|
|
264
370
|
{
|
|
265
371
|
type: "button",
|
|
372
|
+
"aria-label": `${removeText} ${groupName} ${index + 1}`,
|
|
266
373
|
onClick: () => handleRemove(index),
|
|
267
374
|
disabled: !canRemoveGroupItem(fieldDescription, items),
|
|
268
|
-
children:
|
|
375
|
+
children: removeText
|
|
269
376
|
}
|
|
270
377
|
)
|
|
271
378
|
]
|
|
272
379
|
},
|
|
273
|
-
index
|
|
380
|
+
itemKey(item, index)
|
|
274
381
|
)),
|
|
275
|
-
/* @__PURE__ */
|
|
382
|
+
/* @__PURE__ */ jsx5(
|
|
276
383
|
"button",
|
|
277
384
|
{
|
|
278
385
|
type: "button",
|
|
386
|
+
"aria-label": `${addText} ${groupName}`,
|
|
279
387
|
onClick: handleAdd,
|
|
280
388
|
disabled: !canAddGroupItem(fieldDescription, items),
|
|
281
|
-
children:
|
|
389
|
+
children: addText
|
|
282
390
|
}
|
|
283
391
|
)
|
|
284
392
|
] });
|
|
@@ -286,51 +394,109 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
286
394
|
var FieldGroupInput_default = FieldGroupInput;
|
|
287
395
|
|
|
288
396
|
// src/components/FieldInput.tsx
|
|
289
|
-
import { jsx as
|
|
397
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
290
398
|
var FieldInputInner = ({
|
|
291
399
|
fieldDescription,
|
|
292
400
|
renderInfos,
|
|
401
|
+
rootData,
|
|
402
|
+
touched,
|
|
403
|
+
dirty,
|
|
404
|
+
onBlurField,
|
|
293
405
|
onValueChangeField
|
|
294
406
|
}) => {
|
|
295
|
-
const { name, type, label,
|
|
407
|
+
const { name, type, label, className, description, props, fields, required } = fieldDescription;
|
|
296
408
|
const handleChange = useCallback3(
|
|
297
409
|
(v) => onValueChangeField(v, name),
|
|
298
410
|
[onValueChangeField, name]
|
|
299
411
|
);
|
|
412
|
+
const handleBlur = useCallback3(
|
|
413
|
+
() => onBlurField?.(name),
|
|
414
|
+
[onBlurField, name]
|
|
415
|
+
);
|
|
300
416
|
if (fields) {
|
|
301
417
|
const items = Array.isArray(renderInfos[name]) ? renderInfos[name] : [];
|
|
302
|
-
return /* @__PURE__ */
|
|
418
|
+
return /* @__PURE__ */ jsx6(
|
|
303
419
|
FieldGroupInput_default,
|
|
304
420
|
{
|
|
305
421
|
fieldDescription,
|
|
306
422
|
items,
|
|
423
|
+
rootData,
|
|
307
424
|
onChange: handleChange
|
|
308
425
|
}
|
|
309
426
|
);
|
|
310
427
|
}
|
|
311
|
-
|
|
428
|
+
const effectiveDisabled = resolveDisabled(
|
|
429
|
+
fieldDescription,
|
|
430
|
+
renderInfos,
|
|
431
|
+
rootData
|
|
432
|
+
);
|
|
433
|
+
const readOnly = resolveReadOnly(fieldDescription, renderInfos, rootData);
|
|
434
|
+
const resolvedOptionsList = resolveOptions(
|
|
435
|
+
fieldDescription,
|
|
436
|
+
renderInfos,
|
|
437
|
+
rootData
|
|
438
|
+
);
|
|
439
|
+
const errors = effectiveDisabled ? [] : validateField(fieldDescription, renderInfos[name], renderInfos, rootData);
|
|
440
|
+
const error = errors.length > 0 ? errors : void 0;
|
|
441
|
+
const fieldId = `dfk-field-${name}`;
|
|
442
|
+
return /* @__PURE__ */ jsx6(
|
|
312
443
|
DynamicInput_default,
|
|
313
444
|
{
|
|
445
|
+
id: fieldId,
|
|
314
446
|
type,
|
|
315
447
|
label,
|
|
316
448
|
value: renderInfos[name],
|
|
317
|
-
options,
|
|
449
|
+
options: resolvedOptionsList,
|
|
318
450
|
className,
|
|
319
451
|
description,
|
|
320
|
-
|
|
452
|
+
disabled: effectiveDisabled,
|
|
453
|
+
readOnly,
|
|
454
|
+
required,
|
|
455
|
+
touched,
|
|
456
|
+
dirty,
|
|
457
|
+
error,
|
|
458
|
+
ariaInvalid: Boolean(error),
|
|
459
|
+
ariaRequired: Boolean(required),
|
|
460
|
+
extraProps: props,
|
|
461
|
+
onChange: handleChange,
|
|
462
|
+
onBlur: handleBlur
|
|
321
463
|
}
|
|
322
464
|
);
|
|
323
465
|
};
|
|
324
|
-
var FieldInput =
|
|
466
|
+
var FieldInput = React6.memo(FieldInputInner, (prev, next) => {
|
|
325
467
|
const name = prev.fieldDescription.name;
|
|
326
|
-
return prev.fieldDescription === next.fieldDescription && prev.onValueChangeField === next.onValueChangeField && prev.renderInfos[name] === next.renderInfos[name];
|
|
468
|
+
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];
|
|
327
469
|
});
|
|
328
470
|
var FieldInput_default = FieldInput;
|
|
471
|
+
|
|
472
|
+
// src/index.ts
|
|
473
|
+
import { FieldRegistry } from "@dynamic-field-kit/core";
|
|
474
|
+
import {
|
|
475
|
+
validateField as validateField2,
|
|
476
|
+
validateFieldAsync,
|
|
477
|
+
validateFields as validateFields2,
|
|
478
|
+
validateFieldsAsync,
|
|
479
|
+
resolveDisabled as resolveDisabled2,
|
|
480
|
+
resolveReadOnly as resolveReadOnly2,
|
|
481
|
+
resolveOptions as resolveOptions2,
|
|
482
|
+
validators
|
|
483
|
+
} from "@dynamic-field-kit/core";
|
|
329
484
|
export {
|
|
330
485
|
DynamicInput_default as DynamicInput,
|
|
331
486
|
FieldInput_default as FieldInput,
|
|
487
|
+
FieldRegistry,
|
|
488
|
+
FieldRegistryProvider,
|
|
332
489
|
MultiFieldInput_default as MultiFieldInput,
|
|
333
490
|
fieldRegistry,
|
|
334
|
-
layoutRegistry
|
|
491
|
+
layoutRegistry,
|
|
492
|
+
resolveDisabled2 as resolveDisabled,
|
|
493
|
+
resolveOptions2 as resolveOptions,
|
|
494
|
+
resolveReadOnly2 as resolveReadOnly,
|
|
495
|
+
useFieldRegistry,
|
|
496
|
+
validateField2 as validateField,
|
|
497
|
+
validateFieldAsync,
|
|
498
|
+
validateFields2 as validateFields,
|
|
499
|
+
validateFieldsAsync,
|
|
500
|
+
validators
|
|
335
501
|
};
|
|
336
502
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/layout/layoutRegistry.ts","../src/layout/defaultLayouts.tsx","../src/layout/responsiveLayout.tsx","../src/components/DynamicInput.tsx","../src/fieldRegistry.ts","../src/components/FieldInput.tsx","../src/components/FieldGroupInput.tsx","../src/components/MultiFieldInput.tsx"],"sourcesContent":["import React from 'react';\n\nexport type BaseLayout =\n | 'column'\n | 'row'\n | {\n type: 'grid';\n columns?: number;\n gap?: number;\n };\n\nexport type ResponsiveLayout = {\n type: 'responsive';\n mobile: BaseLayout;\n desktop: BaseLayout;\n breakpoint?: number;\n};\n\nexport type LayoutConfig = BaseLayout | ResponsiveLayout;\n\nexport type LayoutRenderer<C = unknown> = (props: {\n children: React.ReactNode;\n config?: C;\n}) => React.ReactElement;\n\nexport class LayoutRegistry {\n private layouts = new Map<string, LayoutRenderer>();\n\n register(type: string, renderer: LayoutRenderer) {\n if (this.layouts.has(type)) {\n console.warn(`[dynamic-field-kit] Layout \"${type}\" already exists`);\n }\n this.layouts.set(type, renderer);\n }\n\n get(type: string): LayoutRenderer | undefined {\n return this.layouts.get(type);\n }\n}\n\nexport const layoutRegistry = new LayoutRegistry();\n","import { layoutRegistry } from './layoutRegistry';\n\ninterface GridConfig {\n gap?: number;\n columns?: number;\n}\n\nlayoutRegistry.register('column', ({ children, config }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: (config as { gap?: number })?.gap ?? 12,\n }}\n >\n {children}\n </div>\n));\n\nlayoutRegistry.register('row', ({ children, config }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n gap: (config as { gap?: number })?.gap ?? 12,\n }}\n >\n {children}\n </div>\n));\n\nlayoutRegistry.register('grid', ({ children, config }) => (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${\n (config as GridConfig)?.columns ?? 2\n }, 1fr)`,\n gap: (config as GridConfig)?.gap ?? 12,\n }}\n >\n {children}\n </div>\n));\n","import React, { useEffect, useState } from 'react';\nimport {\n LayoutConfig,\n ResponsiveLayout,\n layoutRegistry,\n} from './layoutRegistry';\n\nfunction resolve(layout: LayoutConfig) {\n if (typeof layout === 'string') {\n return { type: layout, config: {} };\n }\n return { type: layout.type, config: layout };\n}\n\nfunction checkIsMobile(breakpoint: number) {\n return typeof window !== 'undefined' && window.innerWidth < breakpoint;\n}\n\nlayoutRegistry.register('responsive', ({ children, config }) => {\n const responsiveConfig = config as ResponsiveLayout;\n const breakpoint = responsiveConfig.breakpoint ?? 768;\n\n // Registered as a real component (invoked via JSX in MultiFieldInput), so\n // hooks are safe here and let the layout react to viewport resizes instead\n // of freezing whatever the width happened to be on first render.\n const [isMobile, setIsMobile] = useState(() => checkIsMobile(breakpoint));\n\n useEffect(() => {\n const handleResize = () => setIsMobile(checkIsMobile(breakpoint));\n handleResize();\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [breakpoint]);\n\n const current = isMobile ? responsiveConfig.mobile : responsiveConfig.desktop;\n if (!current) {\n return <>{children} </>;\n }\n\n const { type, config: childConfig } = resolve(current);\n const Renderer = layoutRegistry.get(type);\n\n if (!Renderer) {\n return <>{children} </>;\n }\n\n return <Renderer config={childConfig}>{children}</Renderer>;\n});\n","import {\n FieldRendererProps,\n FieldTypeKey,\n Properties,\n} from '@dynamic-field-kit/core';\nimport React, { ReactNode, useMemo } from 'react';\nimport { fieldRegistry } from '../fieldRegistry';\n\ninterface Props<T extends FieldTypeKey> {\n type: T;\n value?: unknown;\n onChange?: (value: unknown) => void;\n label?: string;\n options?: Properties[];\n className?: string;\n description?: ReactNode;\n}\n\nconst DynamicInputInner = <T extends FieldTypeKey>({\n type,\n value,\n onChange,\n label,\n options,\n className,\n description,\n}: Props<T>) => {\n // Memoize renderer lookup to avoid unnecessary work on re-renders\n const Renderer = useMemo(\n () => fieldRegistry.get(type) as React.ComponentType<FieldRendererProps>,\n [type]\n );\n\n if (!Renderer) {\n return <div>Unknown field type: {type}</div>;\n }\n\n return React.createElement(Renderer, {\n value,\n onValueChange: onChange,\n label,\n options,\n className,\n description,\n });\n};\n\n// Skip re-render when none of the rendered props actually changed, so\n// unaffected fields don't re-render every time a sibling field's value changes.\n// React.memo erases the generic signature, so restore it via an `unknown`\n// round-trip (plain `as typeof DynamicInputInner` fails dts generation).\nconst DynamicInput = React.memo(\n DynamicInputInner\n) as unknown as typeof DynamicInputInner;\n\nexport default DynamicInput;\n","import {\n fieldRegistry as coreFieldRegistry,\n type FieldRendererProps,\n type FieldTypeMap,\n} from '@dynamic-field-kit/core';\nimport type { ComponentType } from 'react';\n\nexport type ReactFieldRenderer<T = unknown> = ComponentType<\n FieldRendererProps<T>\n>;\n\nexport interface ReactFieldRegistry {\n register<K extends keyof FieldTypeMap>(\n type: K,\n renderer: ReactFieldRenderer<FieldTypeMap[K]>\n ): void;\n get<K extends keyof FieldTypeMap>(\n type: K\n ): ReactFieldRenderer<FieldTypeMap[K]> | undefined;\n}\n\nexport const fieldRegistry = coreFieldRegistry as ReactFieldRegistry;\n","import { FieldDescription, Properties } from '@dynamic-field-kit/core';\nimport React, { useCallback } from 'react';\nimport DynamicInput from './DynamicInput';\nimport FieldGroupInput from './FieldGroupInput';\n\ninterface Props {\n fieldDescription: FieldDescription;\n renderInfos: Properties;\n onValueChangeField: (value: unknown, key: string) => void;\n}\n\nconst FieldInputInner = ({\n fieldDescription,\n renderInfos,\n onValueChangeField,\n}: Props) => {\n const { name, type, label, options, className, description, fields } =\n fieldDescription;\n\n // Stable per-field handler so DynamicInput's memoization isn't defeated\n // by a freshly-allocated closure on every parent render.\n const handleChange = useCallback(\n (v: unknown) => onValueChangeField(v, name),\n [onValueChangeField, name]\n );\n\n if (fields) {\n const items = Array.isArray(renderInfos[name])\n ? (renderInfos[name] as Properties[])\n : [];\n\n return (\n <FieldGroupInput\n fieldDescription={fieldDescription}\n items={items}\n onChange={handleChange}\n />\n );\n }\n\n return (\n <DynamicInput\n type={type}\n label={label}\n value={renderInfos[name]}\n options={options}\n className={className}\n description={description as React.ReactNode}\n onChange={handleChange}\n />\n );\n};\n\n// `renderInfos` covers every field, so the default shallow-prop compare would\n// re-render all fields whenever any one of them changes. Compare only the\n// slice this field actually reads instead.\nconst FieldInput = React.memo(FieldInputInner, (prev, next) => {\n const name = prev.fieldDescription.name;\n return (\n prev.fieldDescription === next.fieldDescription &&\n prev.onValueChangeField === next.onValueChangeField &&\n prev.renderInfos[name] === next.renderInfos[name]\n );\n});\n\nexport default FieldInput;\n","import {\n canAddGroupItem,\n canRemoveGroupItem,\n createGroupItem,\n FieldDescription,\n Properties,\n} from '@dynamic-field-kit/core';\nimport React, { useCallback } from 'react';\nimport MultiFieldInput from './MultiFieldInput';\n\ninterface Props {\n fieldDescription: FieldDescription;\n items: Properties[];\n onChange: (items: Properties[]) => void;\n}\n\nconst FieldGroupInput = ({ fieldDescription, items, onChange }: Props) => {\n const { fields = [], label, addLabel, removeLabel } = fieldDescription;\n\n const handleItemChange = useCallback(\n (index: number, next: Properties) => {\n const nextItems = items.slice();\n nextItems[index] = next;\n onChange(nextItems);\n },\n [items, onChange]\n );\n\n const handleAdd = useCallback(() => {\n if (!canAddGroupItem(fieldDescription, items)) {\n return;\n }\n onChange([...items, createGroupItem(fieldDescription)]);\n }, [fieldDescription, items, onChange]);\n\n const handleRemove = useCallback(\n (index: number) => {\n if (!canRemoveGroupItem(fieldDescription, items)) {\n return;\n }\n onChange(items.filter((_, i) => i !== index));\n },\n [fieldDescription, items, onChange]\n );\n\n return (\n <div className={fieldDescription.className}>\n {label && <div>{label}</div>}\n {items.map((item, index) => (\n <div\n key={index}\n style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}\n >\n <div style={{ flex: 1 }}>\n <MultiFieldInput\n fieldDescriptions={fields}\n properties={item}\n onChange={(next) => handleItemChange(index, next)}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => handleRemove(index)}\n disabled={!canRemoveGroupItem(fieldDescription, items)}\n >\n {removeLabel ?? 'Remove'}\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n onClick={handleAdd}\n disabled={!canAddGroupItem(fieldDescription, items)}\n >\n {addLabel ?? 'Add'}\n </button>\n </div>\n );\n};\n\nexport default FieldGroupInput;\n","import {\r\n applyComputedValues,\r\n FieldDescription,\r\n Properties,\r\n} from '@dynamic-field-kit/core';\r\nimport React, {\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from 'react';\r\n\r\nimport { layoutRegistry, LayoutConfig } from '../layout';\r\nimport FieldInput from './FieldInput';\r\n\r\ninterface Props {\r\n fieldDescriptions: FieldDescription[];\r\n properties?: Properties;\r\n onChange?: (data: Properties) => void;\r\n layout?: LayoutConfig;\r\n}\r\n\r\nfunction resolveLayout(layout?: LayoutConfig) {\r\n if (!layout) {\r\n return { type: 'column', config: {} };\r\n }\r\n if (typeof layout === 'string') {\r\n return { type: layout, config: {} };\r\n }\r\n return { type: layout.type, config: layout };\r\n}\r\n\r\nconst MultiFieldInput = ({\r\n fieldDescriptions,\r\n properties,\r\n onChange,\r\n layout,\r\n}: Props) => {\r\n const [data, setData] = useState<Properties>({});\r\n\r\n useEffect(() => {\r\n if (properties) {\r\n setData(applyComputedValues(fieldDescriptions, properties));\r\n }\r\n // Only re-run when `properties` itself changes; recomputing on every\r\n // fieldDescriptions identity change would fight user edits mid-session.\r\n }, [properties]);\r\n\r\n const visibleFields = useMemo(\r\n () =>\r\n fieldDescriptions.filter(\r\n (f) => !f.appearCondition || f.appearCondition(data)\r\n ),\r\n [fieldDescriptions, data]\r\n );\r\n\r\n // Keep the latest data/onChange in refs so handleValueChangeField can stay\r\n // referentially stable (empty deps) without defeating FieldInput's memoization,\r\n // and without calling onChange from inside a setState updater (must stay pure).\r\n const dataRef = useRef(data);\r\n dataRef.current = data;\r\n const onChangeRef = useRef(onChange);\r\n onChangeRef.current = onChange;\r\n const fieldDescriptionsRef = useRef(fieldDescriptions);\r\n fieldDescriptionsRef.current = fieldDescriptions;\r\n\r\n const handleValueChangeField = useCallback((value: unknown, key: string) => {\r\n const next = applyComputedValues(fieldDescriptionsRef.current, {\r\n ...dataRef.current,\r\n [key]: value,\r\n });\r\n dataRef.current = next;\r\n setData(next);\r\n onChangeRef.current?.(next);\r\n }, []);\r\n\r\n const { type, config } = resolveLayout(layout);\r\n\r\n const Layout = layoutRegistry.get(type);\r\n\r\n if (!Layout) {\r\n throw new Error(`Unknown layout: ${type}`);\r\n }\r\n\r\n return (\r\n <Layout config={config}>\r\n {visibleFields.map((f) => (\r\n <FieldInput\r\n key={f.name}\r\n fieldDescription={f}\r\n renderInfos={data}\r\n onValueChangeField={handleValueChangeField}\r\n />\r\n ))}\r\n </Layout>\r\n );\r\n};\r\n\r\nexport default MultiFieldInput;\r\n"],"mappings":"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","names":["jsx","React","jsxs","React","React","useCallback","useCallback","useEffect","useMemo","useState","jsx","useState","useEffect","useMemo","jsx","jsxs","useCallback","jsx","useCallback","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/layout/layoutRegistry.ts","../src/layout/defaultLayouts.tsx","../src/layout/responsiveLayout.tsx","../src/components/DynamicInput.tsx","../src/FieldRegistryContext.tsx","../src/fieldRegistry.ts","../src/components/FieldInput.tsx","../src/components/FieldGroupInput.tsx","../src/components/MultiFieldInput.tsx","../src/index.ts"],"sourcesContent":["import React from 'react';\n\n// Single source of truth for layout config shapes.\nexport type {\n BaseLayout,\n ResponsiveLayout,\n LayoutConfig,\n} from '@dynamic-field-kit/core';\n\nexport type LayoutRenderer<C = unknown> = (props: {\n children: React.ReactNode;\n config?: C;\n}) => React.ReactElement;\n\nexport class LayoutRegistry {\n private layouts = new Map<string, LayoutRenderer>();\n\n register(type: string, renderer: LayoutRenderer) {\n if (this.layouts.has(type)) {\n console.warn(`[dynamic-field-kit] Layout \"${type}\" already exists`);\n }\n this.layouts.set(type, renderer);\n }\n\n get(type: string): LayoutRenderer | undefined {\n return this.layouts.get(type);\n }\n}\n\nexport const layoutRegistry = new LayoutRegistry();\n","import { layoutRegistry } from './layoutRegistry';\n\ninterface GridConfig {\n gap?: number;\n columns?: number;\n}\n\nlayoutRegistry.register('column', ({ children, config }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: (config as { gap?: number })?.gap ?? 12,\n }}\n >\n {children}\n </div>\n));\n\nlayoutRegistry.register('row', ({ children, config }) => (\n <div\n style={{\n display: 'flex',\n flexDirection: 'row',\n gap: (config as { gap?: number })?.gap ?? 12,\n }}\n >\n {children}\n </div>\n));\n\nlayoutRegistry.register('grid', ({ children, config }) => (\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: `repeat(${\n (config as GridConfig)?.columns ?? 2\n }, 1fr)`,\n gap: (config as GridConfig)?.gap ?? 12,\n }}\n >\n {children}\n </div>\n));\n","import React, { useEffect, useState } from 'react';\nimport {\n LayoutConfig,\n ResponsiveLayout,\n layoutRegistry,\n} from './layoutRegistry';\n\nfunction resolve(layout: LayoutConfig) {\n if (typeof layout === 'string') {\n return { type: layout, config: {} };\n }\n return { type: layout.type, config: layout };\n}\n\nfunction checkIsMobile(breakpoint: number) {\n if (typeof window === 'undefined') {\n return false;\n }\n if (typeof window.matchMedia === 'function') {\n return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;\n }\n return window.innerWidth < breakpoint;\n}\n\nlayoutRegistry.register('responsive', ({ children, config }) => {\n const responsiveConfig = config as ResponsiveLayout;\n const breakpoint = responsiveConfig.breakpoint ?? 768;\n\n // Registered as a real component (invoked via JSX in MultiFieldInput), so\n // hooks are safe here and let the layout react to viewport resizes instead\n // of freezing whatever the width happened to be on first render.\n const [isMobile, setIsMobile] = useState(() => checkIsMobile(breakpoint));\n\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n if (typeof window.matchMedia !== 'function') {\n const handleResize = () => setIsMobile(checkIsMobile(breakpoint));\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }\n const mediaQuery = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);\n const handleChange = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n setIsMobile(mediaQuery.matches);\n\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }\n mediaQuery.addListener(handleChange);\n return () => mediaQuery.removeListener(handleChange);\n }, [breakpoint]);\n\n const current = isMobile ? responsiveConfig.mobile : responsiveConfig.desktop;\n if (!current) {\n return <>{children} </>;\n }\n\n const { type, config: childConfig } = resolve(current);\n const Renderer = layoutRegistry.get(type);\n\n if (!Renderer) {\n return <>{children} </>;\n }\n\n return <Renderer config={childConfig}>{children}</Renderer>;\n});\n","import {\n FieldRendererProps,\n FieldTypeKey,\n Properties,\n} from '@dynamic-field-kit/core';\nimport React, { ReactNode, useMemo } from 'react';\nimport { useFieldRegistry } from '../FieldRegistryContext';\n\ninterface Props<T extends FieldTypeKey> {\n type: T;\n value?: unknown;\n onChange?: (value: unknown) => void;\n onBlur?: () => void;\n label?: string;\n options?: Properties[];\n className?: string;\n description?: ReactNode;\n disabled?: boolean;\n readOnly?: boolean;\n required?: boolean;\n touched?: boolean;\n dirty?: boolean;\n error?: string | string[];\n id?: string;\n ariaInvalid?: boolean;\n ariaDescribedBy?: string;\n ariaRequired?: boolean;\n /** Extra, framework-agnostic props forwarded verbatim to the renderer. */\n extraProps?: Properties;\n}\n\nconst DynamicInputInner = <T extends FieldTypeKey>({\n type,\n value,\n onChange,\n onBlur,\n label,\n options,\n className,\n description,\n disabled,\n readOnly,\n required,\n touched,\n dirty,\n error,\n id,\n ariaInvalid,\n ariaDescribedBy,\n ariaRequired,\n extraProps,\n}: Props<T>) => {\n const registry = useFieldRegistry();\n\n // Memoize renderer lookup to avoid unnecessary work on re-renders\n const Renderer = useMemo(\n () => registry.get(type) as React.ComponentType<FieldRendererProps>,\n [registry, type]\n );\n\n if (!Renderer) {\n return <div>Unknown field type: {type}</div>;\n }\n\n return React.createElement(Renderer, {\n ...extraProps,\n value,\n onValueChange: onChange,\n onBlur,\n label,\n options,\n className,\n description,\n disabled,\n readOnly,\n required,\n touched,\n dirty,\n error,\n id,\n ariaInvalid,\n ariaDescribedBy,\n ariaRequired,\n });\n};\n\n// Skip re-render when none of the rendered props actually changed, so\n// unaffected fields don't re-render every time a sibling field's value changes.\n// React.memo erases the generic signature, so restore it via an `unknown`\n// round-trip (plain `as typeof DynamicInputInner` fails dts generation).\nconst DynamicInput = React.memo(\n DynamicInputInner\n) as unknown as typeof DynamicInputInner;\n\nexport default DynamicInput;\n","import React, { createContext, useContext } from 'react';\nimport { fieldRegistry, type ReactFieldRegistry } from './fieldRegistry';\n\n// Defaults to the process-wide singleton so existing code that never wraps a\n// provider keeps working. Wrap a subtree in <FieldRegistryProvider> to give it\n// an isolated set of renderers (e.g. two design systems in one app).\nconst FieldRegistryContext = createContext<ReactFieldRegistry>(fieldRegistry);\n\nexport interface FieldRegistryProviderProps {\n registry: ReactFieldRegistry;\n children: React.ReactNode;\n}\n\nexport const FieldRegistryProvider = ({\n registry,\n children,\n}: FieldRegistryProviderProps): React.ReactElement => (\n <FieldRegistryContext.Provider value={registry}>\n {children}\n </FieldRegistryContext.Provider>\n);\n\n/** The registry for the nearest provider, or the global singleton. */\nexport function useFieldRegistry(): ReactFieldRegistry {\n return useContext(FieldRegistryContext);\n}\n","import {\n fieldRegistry as coreFieldRegistry,\n type FieldRendererProps,\n type FieldTypeMap,\n} from '@dynamic-field-kit/core';\nimport type { ComponentType } from 'react';\n\nexport type ReactFieldRenderer<T = unknown> = ComponentType<\n FieldRendererProps<T>\n>;\n\nexport interface ReactFieldRegistry {\n register<K extends keyof FieldTypeMap>(\n type: K,\n renderer: ReactFieldRenderer<FieldTypeMap[K]>\n ): void;\n get<K extends keyof FieldTypeMap>(\n type: K\n ): ReactFieldRenderer<FieldTypeMap[K]> | undefined;\n}\n\nexport const fieldRegistry = coreFieldRegistry as ReactFieldRegistry;\n","import {\n resolveDisabled,\n resolveOptions,\n resolveReadOnly,\n validateField,\n FieldDescription,\n Properties,\n} from '@dynamic-field-kit/core';\nimport React, { useCallback } from 'react';\nimport DynamicInput from './DynamicInput';\nimport FieldGroupInput from './FieldGroupInput';\n\ninterface Props {\n fieldDescription: FieldDescription;\n renderInfos: Properties;\n rootData?: Properties;\n touched?: boolean;\n dirty?: boolean;\n onBlurField?: (key: string) => void;\n onValueChangeField: (value: unknown, key: string) => void;\n}\n\nconst FieldInputInner = ({\n fieldDescription,\n renderInfos,\n rootData,\n touched,\n dirty,\n onBlurField,\n onValueChangeField,\n}: Props) => {\n const { name, type, label, className, description, props, fields, required } =\n fieldDescription;\n\n // Stable per-field handler so DynamicInput's memoization isn't defeated\n // by a freshly-allocated closure on every parent render.\n const handleChange = useCallback(\n (v: unknown) => onValueChangeField(v, name),\n [onValueChangeField, name]\n );\n\n const handleBlur = useCallback(\n () => onBlurField?.(name),\n [onBlurField, name]\n );\n\n if (fields) {\n const items = Array.isArray(renderInfos[name])\n ? (renderInfos[name] as Properties[])\n : [];\n\n return (\n <FieldGroupInput\n fieldDescription={fieldDescription}\n items={items}\n rootData={rootData}\n onChange={handleChange}\n />\n );\n }\n\n const effectiveDisabled = resolveDisabled(\n fieldDescription,\n renderInfos,\n rootData\n );\n const readOnly = resolveReadOnly(fieldDescription, renderInfos, rootData);\n const resolvedOptionsList = resolveOptions(\n fieldDescription,\n renderInfos,\n rootData\n );\n const errors = effectiveDisabled\n ? []\n : validateField(fieldDescription, renderInfos[name], renderInfos, rootData);\n const error = errors.length > 0 ? errors : undefined;\n const fieldId = `dfk-field-${name}`;\n\n return (\n <DynamicInput\n id={fieldId}\n type={type}\n label={label}\n value={renderInfos[name]}\n options={resolvedOptionsList}\n className={className}\n description={description as React.ReactNode}\n disabled={effectiveDisabled}\n readOnly={readOnly}\n required={required}\n touched={touched}\n dirty={dirty}\n error={error}\n ariaInvalid={Boolean(error)}\n ariaRequired={Boolean(required)}\n extraProps={props}\n onChange={handleChange}\n onBlur={handleBlur}\n />\n );\n};\n\n// `renderInfos` covers every field, so the default shallow-prop compare would\n// re-render all fields whenever any one of them changes. Compare only the\n// slice this field actually reads instead.\nconst FieldInput = React.memo(FieldInputInner, (prev, next) => {\n const name = prev.fieldDescription.name;\n return (\n prev.fieldDescription === next.fieldDescription &&\n prev.onValueChangeField === next.onValueChangeField &&\n prev.onBlurField === next.onBlurField &&\n prev.rootData === next.rootData &&\n prev.touched === next.touched &&\n prev.dirty === next.dirty &&\n prev.renderInfos[name] === next.renderInfos[name]\n );\n});\n\nexport default FieldInput;\n","import {\n canAddGroupItem,\n canRemoveGroupItem,\n createGroupItem,\n FieldDescription,\n Properties,\n} from '@dynamic-field-kit/core';\nimport React, { useCallback } from 'react';\nimport MultiFieldInput from './MultiFieldInput';\n\ninterface Props {\n fieldDescription: FieldDescription;\n items: Properties[];\n rootData?: Properties;\n onChange: (items: Properties[]) => void;\n}\n\nconst FieldGroupInput = ({\n fieldDescription,\n items,\n rootData,\n onChange,\n}: Props) => {\n const {\n fields = [],\n label,\n addLabel,\n removeLabel,\n keyField,\n } = fieldDescription;\n\n const itemKey = (item: Properties, index: number): string | number =>\n keyField ? (item[keyField] as string | number) ?? index : index;\n\n const addText = addLabel ?? 'Add';\n const removeText = removeLabel ?? 'Remove';\n const groupName = label ?? fieldDescription.name;\n\n const handleItemChange = useCallback(\n (index: number, next: Properties) => {\n const nextItems = items.slice();\n nextItems[index] = next;\n onChange(nextItems);\n },\n [items, onChange]\n );\n\n const handleAdd = useCallback(() => {\n if (!canAddGroupItem(fieldDescription, items)) {\n return;\n }\n onChange([...items, createGroupItem(fieldDescription)]);\n }, [fieldDescription, items, onChange]);\n\n const handleRemove = useCallback(\n (index: number) => {\n if (!canRemoveGroupItem(fieldDescription, items)) {\n return;\n }\n onChange(items.filter((_, i) => i !== index));\n },\n [fieldDescription, items, onChange]\n );\n\n return (\n <div className={fieldDescription.className}>\n {label && <div>{label}</div>}\n {items.map((item, index) => (\n <div\n key={itemKey(item, index)}\n style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}\n >\n <div style={{ flex: 1 }}>\n <MultiFieldInput\n fieldDescriptions={fields}\n properties={item}\n rootData={rootData}\n onChange={(next) => handleItemChange(index, next)}\n />\n </div>\n <button\n type=\"button\"\n aria-label={`${removeText} ${groupName} ${index + 1}`}\n onClick={() => handleRemove(index)}\n disabled={!canRemoveGroupItem(fieldDescription, items)}\n >\n {removeText}\n </button>\n </div>\n ))}\n <button\n type=\"button\"\n aria-label={`${addText} ${groupName}`}\n onClick={handleAdd}\n disabled={!canAddGroupItem(fieldDescription, items)}\n >\n {addText}\n </button>\n </div>\n );\n};\n\nexport default FieldGroupInput;\n","import {\r\n applyComputedValues,\r\n validateFields,\r\n FieldDescription,\r\n Properties,\r\n type ValidationResult,\r\n} from '@dynamic-field-kit/core';\r\nimport React, {\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useRef,\r\n useState,\r\n} from 'react';\r\n\r\nimport { layoutRegistry, LayoutConfig } from '../layout';\r\nimport FieldInput from './FieldInput';\r\n\r\ninterface Props {\r\n fieldDescriptions: FieldDescription[];\r\n properties?: Properties;\r\n onChange?: (data: Properties) => void;\r\n layout?: LayoutConfig;\r\n /**\r\n * Top-level form data, threaded down through repeatable groups so a nested\r\n * field's `appearCondition`/`computeValue` can read the root form. Omitted at\r\n * the top level, where the form's own data is the root.\r\n */\r\n rootData?: Properties;\r\n /**\r\n * Called with the recursive validation result ({ valid, errors }) on every\r\n * change. On the top-level component this covers the whole form (groups\r\n * included).\r\n */\r\n onValidityChange?: (result: ValidationResult) => void;\r\n}\r\n\r\nfunction resolveLayout(layout?: LayoutConfig) {\r\n if (!layout) {\r\n return { type: 'column', config: {} };\r\n }\r\n if (typeof layout === 'string') {\r\n return { type: layout, config: {} };\r\n }\r\n return { type: layout.type, config: layout };\r\n}\r\n\r\nconst MultiFieldInput = ({\r\n fieldDescriptions,\r\n properties,\r\n onChange,\r\n layout,\r\n rootData,\r\n onValidityChange,\r\n}: Props) => {\r\n const [data, setData] = useState<Properties>({});\r\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>(\r\n {}\r\n );\r\n const initialPropertiesRef = useRef<Properties>(properties ?? {});\r\n\r\n useEffect(() => {\r\n if (properties) {\r\n setData(applyComputedValues(fieldDescriptions, properties, rootData));\r\n }\r\n // Only re-run when `properties` itself changes; recomputing on every\r\n // fieldDescriptions identity change would fight user edits mid-session.\r\n }, [properties]);\r\n\r\n // The root data seen by this level: the prop when nested in a group, else\r\n // this form's own data at the top level.\r\n const effectiveRoot = rootData ?? data;\r\n\r\n const visibleFields = useMemo(\r\n () =>\r\n fieldDescriptions.filter(\r\n (f) => !f.appearCondition || f.appearCondition(data, effectiveRoot)\r\n ),\r\n [fieldDescriptions, data, effectiveRoot]\r\n );\r\n\r\n // Keep the latest data/onChange in refs so handleValueChangeField can stay\r\n // referentially stable (empty deps) without defeating FieldInput's memoization,\r\n // and without calling onChange from inside a setState updater (must stay pure).\r\n const dataRef = useRef(data);\r\n dataRef.current = data;\r\n const onChangeRef = useRef(onChange);\r\n onChangeRef.current = onChange;\r\n const fieldDescriptionsRef = useRef(fieldDescriptions);\r\n fieldDescriptionsRef.current = fieldDescriptions;\r\n const rootDataRef = useRef(rootData);\r\n rootDataRef.current = rootData;\r\n const onValidityChangeRef = useRef(onValidityChange);\r\n onValidityChangeRef.current = onValidityChange;\r\n\r\n useEffect(() => {\r\n onValidityChangeRef.current?.(\r\n validateFields(fieldDescriptions, data, rootData)\r\n );\r\n }, [data, fieldDescriptions, rootData]);\r\n\r\n const handleValueChangeField = useCallback((value: unknown, key: string) => {\r\n const merged = { ...dataRef.current, [key]: value };\r\n const next = applyComputedValues(\r\n fieldDescriptionsRef.current,\r\n merged,\r\n rootDataRef.current\r\n );\r\n dataRef.current = next;\r\n setData(next);\r\n onChangeRef.current?.(next);\r\n }, []);\r\n\r\n const handleBlurField = useCallback((key: string) => {\r\n setTouchedFields((prev) => (prev[key] ? prev : { ...prev, [key]: true }));\r\n }, []);\r\n\r\n const { type, config } = resolveLayout(layout);\r\n\r\n const Layout = layoutRegistry.get(type);\r\n\r\n if (!Layout) {\r\n throw new Error(`Unknown layout: ${type}`);\r\n }\r\n\r\n return (\r\n <Layout config={config}>\r\n {visibleFields.map((f) => (\r\n <FieldInput\r\n key={f.name}\r\n fieldDescription={f}\r\n renderInfos={data}\r\n rootData={effectiveRoot}\r\n touched={Boolean(touchedFields[f.name])}\r\n dirty={data[f.name] !== initialPropertiesRef.current[f.name]}\r\n onBlurField={handleBlurField}\r\n onValueChangeField={handleValueChangeField}\r\n />\r\n ))}\r\n </Layout>\r\n );\r\n};\r\n\r\nexport default MultiFieldInput;\r\n","import './layout/defaultLayouts';\nimport './layout/responsiveLayout';\n\nexport { layoutRegistry } from './layout';\n\nexport { default as DynamicInput } from './components/DynamicInput';\nexport { default as FieldInput } from './components/FieldInput';\nexport { default as MultiFieldInput } from './components/MultiFieldInput';\nexport {\n fieldRegistry,\n type ReactFieldRenderer,\n type ReactFieldRegistry,\n} from './fieldRegistry';\nexport {\n FieldRegistryProvider,\n useFieldRegistry,\n type FieldRegistryProviderProps,\n} from './FieldRegistryContext';\nexport { FieldRegistry } from '@dynamic-field-kit/core';\n\nexport type { LayoutConfig } from './types/layout';\n// Re-export selected core APIs\nexport {\n type FieldTypeKey,\n type FieldDescription,\n type FieldRendererProps,\n} from '@dynamic-field-kit/core';\nexport {\n validateField,\n validateFieldAsync,\n validateFields,\n validateFieldsAsync,\n resolveDisabled,\n resolveReadOnly,\n resolveOptions,\n validators,\n type ValidationResult,\n} from '@dynamic-field-kit/core';\n"],"mappings":"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","names":["jsx","React","jsx","jsxs","React","React","useCallback","useCallback","useEffect","useMemo","useState","jsx","useState","useEffect","useMemo","jsx","jsxs","useCallback","jsx","useCallback","React","validateField","validateFields","resolveDisabled","resolveReadOnly","resolveOptions"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-field-kit/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "React renderer for dynamic-field-kit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
8
|
"sideEffects": [
|
|
10
9
|
"./dist/index.js",
|
|
11
10
|
"./dist/index.mjs",
|
|
@@ -13,20 +12,19 @@
|
|
|
13
12
|
"./src/layout/defaultLayouts.tsx",
|
|
14
13
|
"./src/layout/responsiveLayout.tsx"
|
|
15
14
|
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
16
18
|
"files": [
|
|
17
19
|
"dist"
|
|
18
20
|
],
|
|
19
21
|
"peerDependencies": {
|
|
20
|
-
"@dynamic-field-kit/core": "^1.
|
|
22
|
+
"@dynamic-field-kit/core": "^1.3.0",
|
|
21
23
|
"react": "^18.0.0 || ^19.0.0",
|
|
22
24
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
23
25
|
},
|
|
24
|
-
"dependencies": {
|
|
25
|
-
"@dynamic-field-kit/core": "^1.2.0",
|
|
26
|
-
"react": "^19.2.4",
|
|
27
|
-
"react-dom": "^19.2.4"
|
|
28
|
-
},
|
|
29
26
|
"devDependencies": {
|
|
27
|
+
"@dynamic-field-kit/core": "^1.3.0",
|
|
30
28
|
"@testing-library/dom": "^10.0.0",
|
|
31
29
|
"@testing-library/jest-dom": "^6.4.0",
|
|
32
30
|
"@testing-library/react": "^16.0.0",
|
|
@@ -34,6 +32,8 @@
|
|
|
34
32
|
"@vitest/coverage-v8": "^1.6.0",
|
|
35
33
|
"@vitejs/plugin-react": "^4.2.0",
|
|
36
34
|
"jsdom": "^24.0.0",
|
|
35
|
+
"react": "^19.2.4",
|
|
36
|
+
"react-dom": "^19.2.4",
|
|
37
37
|
"tsup": "^8.0.1",
|
|
38
38
|
"vite": "^5.4.0",
|
|
39
39
|
"vitest": "^1.6.0"
|
|
@@ -50,8 +50,9 @@
|
|
|
50
50
|
"clean": "rimraf dist",
|
|
51
51
|
"test": "vitest run",
|
|
52
52
|
"test:watch": "vitest",
|
|
53
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
53
54
|
"test:coverage": "vitest run --coverage",
|
|
54
|
-
"prepublishOnly": "npm run
|
|
55
|
+
"prepublishOnly": "npm run build",
|
|
55
56
|
"release:patch": "npm version patch && npm publish",
|
|
56
57
|
"release:minor": "npm version minor && npm publish",
|
|
57
58
|
"release:major": "npm version major && npm publish"
|