@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.js
CHANGED
|
@@ -32,9 +32,20 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
DynamicInput: () => DynamicInput_default,
|
|
34
34
|
FieldInput: () => FieldInput_default,
|
|
35
|
+
FieldRegistry: () => import_core5.FieldRegistry,
|
|
36
|
+
FieldRegistryProvider: () => FieldRegistryProvider,
|
|
35
37
|
MultiFieldInput: () => MultiFieldInput_default,
|
|
36
38
|
fieldRegistry: () => fieldRegistry,
|
|
37
|
-
layoutRegistry: () => layoutRegistry
|
|
39
|
+
layoutRegistry: () => layoutRegistry,
|
|
40
|
+
resolveDisabled: () => import_core6.resolveDisabled,
|
|
41
|
+
resolveOptions: () => import_core6.resolveOptions,
|
|
42
|
+
resolveReadOnly: () => import_core6.resolveReadOnly,
|
|
43
|
+
useFieldRegistry: () => useFieldRegistry,
|
|
44
|
+
validateField: () => import_core6.validateField,
|
|
45
|
+
validateFieldAsync: () => import_core6.validateFieldAsync,
|
|
46
|
+
validateFields: () => import_core6.validateFields,
|
|
47
|
+
validateFieldsAsync: () => import_core6.validateFieldsAsync,
|
|
48
|
+
validators: () => import_core6.validators
|
|
38
49
|
});
|
|
39
50
|
module.exports = __toCommonJS(index_exports);
|
|
40
51
|
|
|
@@ -101,17 +112,36 @@ function resolve(layout) {
|
|
|
101
112
|
return { type: layout.type, config: layout };
|
|
102
113
|
}
|
|
103
114
|
function checkIsMobile(breakpoint) {
|
|
104
|
-
|
|
115
|
+
if (typeof window === "undefined") {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
if (typeof window.matchMedia === "function") {
|
|
119
|
+
return window.matchMedia(`(max-width: ${breakpoint - 1}px)`).matches;
|
|
120
|
+
}
|
|
121
|
+
return window.innerWidth < breakpoint;
|
|
105
122
|
}
|
|
106
123
|
layoutRegistry.register("responsive", ({ children, config }) => {
|
|
107
124
|
const responsiveConfig = config;
|
|
108
125
|
const breakpoint = responsiveConfig.breakpoint ?? 768;
|
|
109
126
|
const [isMobile, setIsMobile] = (0, import_react.useState)(() => checkIsMobile(breakpoint));
|
|
110
127
|
(0, import_react.useEffect)(() => {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
128
|
+
if (typeof window === "undefined") {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (typeof window.matchMedia !== "function") {
|
|
132
|
+
const handleResize = () => setIsMobile(checkIsMobile(breakpoint));
|
|
133
|
+
window.addEventListener("resize", handleResize);
|
|
134
|
+
return () => window.removeEventListener("resize", handleResize);
|
|
135
|
+
}
|
|
136
|
+
const mediaQuery = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
137
|
+
const handleChange = (e) => setIsMobile(e.matches);
|
|
138
|
+
setIsMobile(mediaQuery.matches);
|
|
139
|
+
if (mediaQuery.addEventListener) {
|
|
140
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
141
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
142
|
+
}
|
|
143
|
+
mediaQuery.addListener(handleChange);
|
|
144
|
+
return () => mediaQuery.removeListener(handleChange);
|
|
115
145
|
}, [breakpoint]);
|
|
116
146
|
const current = isMobile ? responsiveConfig.mobile : responsiveConfig.desktop;
|
|
117
147
|
if (!current) {
|
|
@@ -132,58 +162,98 @@ layoutRegistry.register("responsive", ({ children, config }) => {
|
|
|
132
162
|
});
|
|
133
163
|
|
|
134
164
|
// src/components/DynamicInput.tsx
|
|
135
|
-
var
|
|
165
|
+
var import_react3 = __toESM(require("react"));
|
|
166
|
+
|
|
167
|
+
// src/FieldRegistryContext.tsx
|
|
168
|
+
var import_react2 = require("react");
|
|
136
169
|
|
|
137
170
|
// src/fieldRegistry.ts
|
|
138
171
|
var import_core = require("@dynamic-field-kit/core");
|
|
139
172
|
var fieldRegistry = import_core.fieldRegistry;
|
|
140
173
|
|
|
141
|
-
// src/
|
|
174
|
+
// src/FieldRegistryContext.tsx
|
|
142
175
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
176
|
+
var FieldRegistryContext = (0, import_react2.createContext)(fieldRegistry);
|
|
177
|
+
var FieldRegistryProvider = ({
|
|
178
|
+
registry,
|
|
179
|
+
children
|
|
180
|
+
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FieldRegistryContext.Provider, { value: registry, children });
|
|
181
|
+
function useFieldRegistry() {
|
|
182
|
+
return (0, import_react2.useContext)(FieldRegistryContext);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/components/DynamicInput.tsx
|
|
186
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
143
187
|
var DynamicInputInner = ({
|
|
144
188
|
type,
|
|
145
189
|
value,
|
|
146
190
|
onChange,
|
|
191
|
+
onBlur,
|
|
147
192
|
label,
|
|
148
193
|
options,
|
|
149
194
|
className,
|
|
150
|
-
description
|
|
195
|
+
description,
|
|
196
|
+
disabled,
|
|
197
|
+
readOnly,
|
|
198
|
+
required,
|
|
199
|
+
touched,
|
|
200
|
+
dirty,
|
|
201
|
+
error,
|
|
202
|
+
id,
|
|
203
|
+
ariaInvalid,
|
|
204
|
+
ariaDescribedBy,
|
|
205
|
+
ariaRequired,
|
|
206
|
+
extraProps
|
|
151
207
|
}) => {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
208
|
+
const registry = useFieldRegistry();
|
|
209
|
+
const Renderer = (0, import_react3.useMemo)(
|
|
210
|
+
() => registry.get(type),
|
|
211
|
+
[registry, type]
|
|
155
212
|
);
|
|
156
213
|
if (!Renderer) {
|
|
157
|
-
return /* @__PURE__ */ (0,
|
|
214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
|
|
158
215
|
"Unknown field type: ",
|
|
159
216
|
type
|
|
160
217
|
] });
|
|
161
218
|
}
|
|
162
|
-
return
|
|
219
|
+
return import_react3.default.createElement(Renderer, {
|
|
220
|
+
...extraProps,
|
|
163
221
|
value,
|
|
164
222
|
onValueChange: onChange,
|
|
223
|
+
onBlur,
|
|
165
224
|
label,
|
|
166
225
|
options,
|
|
167
226
|
className,
|
|
168
|
-
description
|
|
227
|
+
description,
|
|
228
|
+
disabled,
|
|
229
|
+
readOnly,
|
|
230
|
+
required,
|
|
231
|
+
touched,
|
|
232
|
+
dirty,
|
|
233
|
+
error,
|
|
234
|
+
id,
|
|
235
|
+
ariaInvalid,
|
|
236
|
+
ariaDescribedBy,
|
|
237
|
+
ariaRequired
|
|
169
238
|
});
|
|
170
239
|
};
|
|
171
|
-
var DynamicInput =
|
|
240
|
+
var DynamicInput = import_react3.default.memo(
|
|
172
241
|
DynamicInputInner
|
|
173
242
|
);
|
|
174
243
|
var DynamicInput_default = DynamicInput;
|
|
175
244
|
|
|
176
245
|
// src/components/FieldInput.tsx
|
|
177
|
-
var
|
|
246
|
+
var import_core4 = require("@dynamic-field-kit/core");
|
|
247
|
+
var import_react6 = __toESM(require("react"));
|
|
178
248
|
|
|
179
249
|
// src/components/FieldGroupInput.tsx
|
|
180
250
|
var import_core3 = require("@dynamic-field-kit/core");
|
|
181
|
-
var
|
|
251
|
+
var import_react5 = require("react");
|
|
182
252
|
|
|
183
253
|
// src/components/MultiFieldInput.tsx
|
|
184
254
|
var import_core2 = require("@dynamic-field-kit/core");
|
|
185
|
-
var
|
|
186
|
-
var
|
|
255
|
+
var import_react4 = require("react");
|
|
256
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
187
257
|
function resolveLayout(layout) {
|
|
188
258
|
if (!layout) {
|
|
189
259
|
return { type: "column", config: {} };
|
|
@@ -197,45 +267,70 @@ var MultiFieldInput = ({
|
|
|
197
267
|
fieldDescriptions,
|
|
198
268
|
properties,
|
|
199
269
|
onChange,
|
|
200
|
-
layout
|
|
270
|
+
layout,
|
|
271
|
+
rootData,
|
|
272
|
+
onValidityChange
|
|
201
273
|
}) => {
|
|
202
|
-
const [data, setData] = (0,
|
|
203
|
-
(0,
|
|
274
|
+
const [data, setData] = (0, import_react4.useState)({});
|
|
275
|
+
const [touchedFields, setTouchedFields] = (0, import_react4.useState)(
|
|
276
|
+
{}
|
|
277
|
+
);
|
|
278
|
+
const initialPropertiesRef = (0, import_react4.useRef)(properties ?? {});
|
|
279
|
+
(0, import_react4.useEffect)(() => {
|
|
204
280
|
if (properties) {
|
|
205
|
-
setData((0, import_core2.applyComputedValues)(fieldDescriptions, properties));
|
|
281
|
+
setData((0, import_core2.applyComputedValues)(fieldDescriptions, properties, rootData));
|
|
206
282
|
}
|
|
207
283
|
}, [properties]);
|
|
208
|
-
const
|
|
284
|
+
const effectiveRoot = rootData ?? data;
|
|
285
|
+
const visibleFields = (0, import_react4.useMemo)(
|
|
209
286
|
() => fieldDescriptions.filter(
|
|
210
|
-
(f) => !f.appearCondition || f.appearCondition(data)
|
|
287
|
+
(f) => !f.appearCondition || f.appearCondition(data, effectiveRoot)
|
|
211
288
|
),
|
|
212
|
-
[fieldDescriptions, data]
|
|
289
|
+
[fieldDescriptions, data, effectiveRoot]
|
|
213
290
|
);
|
|
214
|
-
const dataRef = (0,
|
|
291
|
+
const dataRef = (0, import_react4.useRef)(data);
|
|
215
292
|
dataRef.current = data;
|
|
216
|
-
const onChangeRef = (0,
|
|
293
|
+
const onChangeRef = (0, import_react4.useRef)(onChange);
|
|
217
294
|
onChangeRef.current = onChange;
|
|
218
|
-
const fieldDescriptionsRef = (0,
|
|
295
|
+
const fieldDescriptionsRef = (0, import_react4.useRef)(fieldDescriptions);
|
|
219
296
|
fieldDescriptionsRef.current = fieldDescriptions;
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
297
|
+
const rootDataRef = (0, import_react4.useRef)(rootData);
|
|
298
|
+
rootDataRef.current = rootData;
|
|
299
|
+
const onValidityChangeRef = (0, import_react4.useRef)(onValidityChange);
|
|
300
|
+
onValidityChangeRef.current = onValidityChange;
|
|
301
|
+
(0, import_react4.useEffect)(() => {
|
|
302
|
+
onValidityChangeRef.current?.(
|
|
303
|
+
(0, import_core2.validateFields)(fieldDescriptions, data, rootData)
|
|
304
|
+
);
|
|
305
|
+
}, [data, fieldDescriptions, rootData]);
|
|
306
|
+
const handleValueChangeField = (0, import_react4.useCallback)((value, key) => {
|
|
307
|
+
const merged = { ...dataRef.current, [key]: value };
|
|
308
|
+
const next = (0, import_core2.applyComputedValues)(
|
|
309
|
+
fieldDescriptionsRef.current,
|
|
310
|
+
merged,
|
|
311
|
+
rootDataRef.current
|
|
312
|
+
);
|
|
225
313
|
dataRef.current = next;
|
|
226
314
|
setData(next);
|
|
227
315
|
onChangeRef.current?.(next);
|
|
228
316
|
}, []);
|
|
317
|
+
const handleBlurField = (0, import_react4.useCallback)((key) => {
|
|
318
|
+
setTouchedFields((prev) => prev[key] ? prev : { ...prev, [key]: true });
|
|
319
|
+
}, []);
|
|
229
320
|
const { type, config } = resolveLayout(layout);
|
|
230
321
|
const Layout = layoutRegistry.get(type);
|
|
231
322
|
if (!Layout) {
|
|
232
323
|
throw new Error(`Unknown layout: ${type}`);
|
|
233
324
|
}
|
|
234
|
-
return /* @__PURE__ */ (0,
|
|
325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Layout, { config, children: visibleFields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
235
326
|
FieldInput_default,
|
|
236
327
|
{
|
|
237
328
|
fieldDescription: f,
|
|
238
329
|
renderInfos: data,
|
|
330
|
+
rootData: effectiveRoot,
|
|
331
|
+
touched: Boolean(touchedFields[f.name]),
|
|
332
|
+
dirty: data[f.name] !== initialPropertiesRef.current[f.name],
|
|
333
|
+
onBlurField: handleBlurField,
|
|
239
334
|
onValueChangeField: handleValueChangeField
|
|
240
335
|
},
|
|
241
336
|
f.name
|
|
@@ -244,10 +339,25 @@ var MultiFieldInput = ({
|
|
|
244
339
|
var MultiFieldInput_default = MultiFieldInput;
|
|
245
340
|
|
|
246
341
|
// src/components/FieldGroupInput.tsx
|
|
247
|
-
var
|
|
248
|
-
var FieldGroupInput = ({
|
|
249
|
-
|
|
250
|
-
|
|
342
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
343
|
+
var FieldGroupInput = ({
|
|
344
|
+
fieldDescription,
|
|
345
|
+
items,
|
|
346
|
+
rootData,
|
|
347
|
+
onChange
|
|
348
|
+
}) => {
|
|
349
|
+
const {
|
|
350
|
+
fields = [],
|
|
351
|
+
label,
|
|
352
|
+
addLabel,
|
|
353
|
+
removeLabel,
|
|
354
|
+
keyField
|
|
355
|
+
} = fieldDescription;
|
|
356
|
+
const itemKey = (item, index) => keyField ? item[keyField] ?? index : index;
|
|
357
|
+
const addText = addLabel ?? "Add";
|
|
358
|
+
const removeText = removeLabel ?? "Remove";
|
|
359
|
+
const groupName = label ?? fieldDescription.name;
|
|
360
|
+
const handleItemChange = (0, import_react5.useCallback)(
|
|
251
361
|
(index, next) => {
|
|
252
362
|
const nextItems = items.slice();
|
|
253
363
|
nextItems[index] = next;
|
|
@@ -255,13 +365,13 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
255
365
|
},
|
|
256
366
|
[items, onChange]
|
|
257
367
|
);
|
|
258
|
-
const handleAdd = (0,
|
|
368
|
+
const handleAdd = (0, import_react5.useCallback)(() => {
|
|
259
369
|
if (!(0, import_core3.canAddGroupItem)(fieldDescription, items)) {
|
|
260
370
|
return;
|
|
261
371
|
}
|
|
262
372
|
onChange([...items, (0, import_core3.createGroupItem)(fieldDescription)]);
|
|
263
373
|
}, [fieldDescription, items, onChange]);
|
|
264
|
-
const handleRemove = (0,
|
|
374
|
+
const handleRemove = (0, import_react5.useCallback)(
|
|
265
375
|
(index) => {
|
|
266
376
|
if (!(0, import_core3.canRemoveGroupItem)(fieldDescription, items)) {
|
|
267
377
|
return;
|
|
@@ -270,41 +380,44 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
270
380
|
},
|
|
271
381
|
[fieldDescription, items, onChange]
|
|
272
382
|
);
|
|
273
|
-
return /* @__PURE__ */ (0,
|
|
274
|
-
label && /* @__PURE__ */ (0,
|
|
275
|
-
items.map((item, index) => /* @__PURE__ */ (0,
|
|
383
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: fieldDescription.className, children: [
|
|
384
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: label }),
|
|
385
|
+
items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
276
386
|
"div",
|
|
277
387
|
{
|
|
278
388
|
style: { display: "flex", alignItems: "flex-start", gap: 8 },
|
|
279
389
|
children: [
|
|
280
|
-
/* @__PURE__ */ (0,
|
|
390
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { flex: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
281
391
|
MultiFieldInput_default,
|
|
282
392
|
{
|
|
283
393
|
fieldDescriptions: fields,
|
|
284
394
|
properties: item,
|
|
395
|
+
rootData,
|
|
285
396
|
onChange: (next) => handleItemChange(index, next)
|
|
286
397
|
}
|
|
287
398
|
) }),
|
|
288
|
-
/* @__PURE__ */ (0,
|
|
399
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
289
400
|
"button",
|
|
290
401
|
{
|
|
291
402
|
type: "button",
|
|
403
|
+
"aria-label": `${removeText} ${groupName} ${index + 1}`,
|
|
292
404
|
onClick: () => handleRemove(index),
|
|
293
405
|
disabled: !(0, import_core3.canRemoveGroupItem)(fieldDescription, items),
|
|
294
|
-
children:
|
|
406
|
+
children: removeText
|
|
295
407
|
}
|
|
296
408
|
)
|
|
297
409
|
]
|
|
298
410
|
},
|
|
299
|
-
index
|
|
411
|
+
itemKey(item, index)
|
|
300
412
|
)),
|
|
301
|
-
/* @__PURE__ */ (0,
|
|
413
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
302
414
|
"button",
|
|
303
415
|
{
|
|
304
416
|
type: "button",
|
|
417
|
+
"aria-label": `${addText} ${groupName}`,
|
|
305
418
|
onClick: handleAdd,
|
|
306
419
|
disabled: !(0, import_core3.canAddGroupItem)(fieldDescription, items),
|
|
307
|
-
children:
|
|
420
|
+
children: addText
|
|
308
421
|
}
|
|
309
422
|
)
|
|
310
423
|
] });
|
|
@@ -312,52 +425,101 @@ var FieldGroupInput = ({ fieldDescription, items, onChange }) => {
|
|
|
312
425
|
var FieldGroupInput_default = FieldGroupInput;
|
|
313
426
|
|
|
314
427
|
// src/components/FieldInput.tsx
|
|
315
|
-
var
|
|
428
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
316
429
|
var FieldInputInner = ({
|
|
317
430
|
fieldDescription,
|
|
318
431
|
renderInfos,
|
|
432
|
+
rootData,
|
|
433
|
+
touched,
|
|
434
|
+
dirty,
|
|
435
|
+
onBlurField,
|
|
319
436
|
onValueChangeField
|
|
320
437
|
}) => {
|
|
321
|
-
const { name, type, label,
|
|
322
|
-
const handleChange = (0,
|
|
438
|
+
const { name, type, label, className, description, props, fields, required } = fieldDescription;
|
|
439
|
+
const handleChange = (0, import_react6.useCallback)(
|
|
323
440
|
(v) => onValueChangeField(v, name),
|
|
324
441
|
[onValueChangeField, name]
|
|
325
442
|
);
|
|
443
|
+
const handleBlur = (0, import_react6.useCallback)(
|
|
444
|
+
() => onBlurField?.(name),
|
|
445
|
+
[onBlurField, name]
|
|
446
|
+
);
|
|
326
447
|
if (fields) {
|
|
327
448
|
const items = Array.isArray(renderInfos[name]) ? renderInfos[name] : [];
|
|
328
|
-
return /* @__PURE__ */ (0,
|
|
449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
329
450
|
FieldGroupInput_default,
|
|
330
451
|
{
|
|
331
452
|
fieldDescription,
|
|
332
453
|
items,
|
|
454
|
+
rootData,
|
|
333
455
|
onChange: handleChange
|
|
334
456
|
}
|
|
335
457
|
);
|
|
336
458
|
}
|
|
337
|
-
|
|
459
|
+
const effectiveDisabled = (0, import_core4.resolveDisabled)(
|
|
460
|
+
fieldDescription,
|
|
461
|
+
renderInfos,
|
|
462
|
+
rootData
|
|
463
|
+
);
|
|
464
|
+
const readOnly = (0, import_core4.resolveReadOnly)(fieldDescription, renderInfos, rootData);
|
|
465
|
+
const resolvedOptionsList = (0, import_core4.resolveOptions)(
|
|
466
|
+
fieldDescription,
|
|
467
|
+
renderInfos,
|
|
468
|
+
rootData
|
|
469
|
+
);
|
|
470
|
+
const errors = effectiveDisabled ? [] : (0, import_core4.validateField)(fieldDescription, renderInfos[name], renderInfos, rootData);
|
|
471
|
+
const error = errors.length > 0 ? errors : void 0;
|
|
472
|
+
const fieldId = `dfk-field-${name}`;
|
|
473
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
338
474
|
DynamicInput_default,
|
|
339
475
|
{
|
|
476
|
+
id: fieldId,
|
|
340
477
|
type,
|
|
341
478
|
label,
|
|
342
479
|
value: renderInfos[name],
|
|
343
|
-
options,
|
|
480
|
+
options: resolvedOptionsList,
|
|
344
481
|
className,
|
|
345
482
|
description,
|
|
346
|
-
|
|
483
|
+
disabled: effectiveDisabled,
|
|
484
|
+
readOnly,
|
|
485
|
+
required,
|
|
486
|
+
touched,
|
|
487
|
+
dirty,
|
|
488
|
+
error,
|
|
489
|
+
ariaInvalid: Boolean(error),
|
|
490
|
+
ariaRequired: Boolean(required),
|
|
491
|
+
extraProps: props,
|
|
492
|
+
onChange: handleChange,
|
|
493
|
+
onBlur: handleBlur
|
|
347
494
|
}
|
|
348
495
|
);
|
|
349
496
|
};
|
|
350
|
-
var FieldInput =
|
|
497
|
+
var FieldInput = import_react6.default.memo(FieldInputInner, (prev, next) => {
|
|
351
498
|
const name = prev.fieldDescription.name;
|
|
352
|
-
return prev.fieldDescription === next.fieldDescription && prev.onValueChangeField === next.onValueChangeField && prev.renderInfos[name] === next.renderInfos[name];
|
|
499
|
+
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
500
|
});
|
|
354
501
|
var FieldInput_default = FieldInput;
|
|
502
|
+
|
|
503
|
+
// src/index.ts
|
|
504
|
+
var import_core5 = require("@dynamic-field-kit/core");
|
|
505
|
+
var import_core6 = require("@dynamic-field-kit/core");
|
|
355
506
|
// Annotate the CommonJS export names for ESM import in node:
|
|
356
507
|
0 && (module.exports = {
|
|
357
508
|
DynamicInput,
|
|
358
509
|
FieldInput,
|
|
510
|
+
FieldRegistry,
|
|
511
|
+
FieldRegistryProvider,
|
|
359
512
|
MultiFieldInput,
|
|
360
513
|
fieldRegistry,
|
|
361
|
-
layoutRegistry
|
|
514
|
+
layoutRegistry,
|
|
515
|
+
resolveDisabled,
|
|
516
|
+
resolveOptions,
|
|
517
|
+
resolveReadOnly,
|
|
518
|
+
useFieldRegistry,
|
|
519
|
+
validateField,
|
|
520
|
+
validateFieldAsync,
|
|
521
|
+
validateFields,
|
|
522
|
+
validateFieldsAsync,
|
|
523
|
+
validators
|
|
362
524
|
});
|
|
363
525
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../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 './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';\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';\n","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":["import_jsx_runtime","import_react","coreFieldRegistry","import_jsx_runtime","React","import_react","import_core","import_react","import_core","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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"],"sourcesContent":["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","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"],"mappings":"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","names":["import_jsx_runtime","import_react","import_react","coreFieldRegistry","import_jsx_runtime","import_jsx_runtime","React","import_core","import_react","import_core","import_react","import_core","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_core"]}
|