@uniform-ts/core 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -5
- package/dist/index.d.mts +47 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +65 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ UniForm takes a Zod schema and automatically renders a fully customizable form.
|
|
|
14
14
|
- **Per-field `onChange` in `fields` prop** — react to individual field changes inline, with typed values and full form control methods
|
|
15
15
|
- **Per-field custom components** — pass any `React.ComponentType<FieldProps>` directly as `meta.component` (inline, no registry) or register under a custom string key; direct components bypass the registry _and_ the default `ArrayField`/`ObjectField` routing, allowing fully custom multi-value widgets for `array`-typed fields
|
|
16
16
|
- **Layout hooks** — `classNames`, `fieldWrapper`, `layout.formWrapper`, `layout.sectionWrapper`, `layout.submitButton`
|
|
17
|
-
- **Section grouping** — group fields into named sections via `meta.section`
|
|
17
|
+
- **Section grouping** — group fields into named sections via `meta.section`; style or swap individual section wrappers via `layout.sections`
|
|
18
18
|
- **Conditional fields** — show/hide fields based on form values with `meta.condition`; hidden fields automatically reset to their default value
|
|
19
19
|
- **Field ordering** — control render order with `meta.order`
|
|
20
20
|
- **`createAutoForm()` factory** — bake in your design system defaults once, use everywhere
|
|
@@ -178,7 +178,7 @@ const MyAutoForm = createAutoForm({
|
|
|
178
178
|
| -------------- | ---------------------------------------- | ------------------------------------------------ |
|
|
179
179
|
| `components` | `ComponentRegistry` | Deep merge (instance overrides specific keys) |
|
|
180
180
|
| `fieldWrapper` | `React.ComponentType<FieldWrapperProps>` | Instance replaces factory |
|
|
181
|
-
| `layout` | `LayoutSlots` | Shallow merge
|
|
181
|
+
| `layout` | `LayoutSlots` | Shallow merge (except `sections` — deep-merged) |
|
|
182
182
|
| `classNames` | `FormClassNames` | Shallow merge |
|
|
183
183
|
| `disabled` | `boolean` | OR logic (either `true` → disabled) |
|
|
184
184
|
| `coercions` | `CoercionMap` | Shallow merge |
|
|
@@ -307,11 +307,29 @@ type LayoutSlots = {
|
|
|
307
307
|
sectionWrapper?: React.ComponentType<{
|
|
308
308
|
children: React.ReactNode
|
|
309
309
|
title: string
|
|
310
|
+
className?: string
|
|
310
311
|
}>
|
|
311
312
|
submitButton?: React.ComponentType<{ isSubmitting: boolean }>
|
|
312
313
|
arrayRowLayout?: React.ComponentType<ArrayRowLayoutProps>
|
|
313
314
|
/** Shown while async `defaultValues` are resolving. Default: `<p>Loading…</p>` */
|
|
314
315
|
loadingFallback?: React.ReactNode
|
|
316
|
+
/** Per-section styling / component overrides keyed by section title. */
|
|
317
|
+
sections?: Record<string, SectionConfig>
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### `SectionConfig`
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
type SectionConfig = {
|
|
325
|
+
/** CSS class name forwarded to the section wrapper. */
|
|
326
|
+
className?: string
|
|
327
|
+
/** Replace the section wrapper component for this section only. */
|
|
328
|
+
component?: React.ComponentType<{
|
|
329
|
+
children: React.ReactNode
|
|
330
|
+
title: string
|
|
331
|
+
className?: string
|
|
332
|
+
}>
|
|
315
333
|
}
|
|
316
334
|
```
|
|
317
335
|
|
|
@@ -468,7 +486,26 @@ const schema = z.object({
|
|
|
468
486
|
|
|
469
487
|
Zod still validates the array (`.min(1)` etc.) — only the _render_ is taken over by your component.
|
|
470
488
|
|
|
471
|
-
#### Option 2 —
|
|
489
|
+
#### Option 2 — String field as select
|
|
490
|
+
|
|
491
|
+
A `z.string()` field can be rendered as a select by setting `meta.component: 'select'` together with `meta.options`. UniForm treats it as type `"select"` during introspection:
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
const schema = z.object({
|
|
495
|
+
role: z.string().meta({
|
|
496
|
+
component: 'select',
|
|
497
|
+
options: [
|
|
498
|
+
{ label: 'User', value: 'user' },
|
|
499
|
+
{ label: 'Admin', value: 'admin' },
|
|
500
|
+
{ label: 'Editor', value: 'editor' },
|
|
501
|
+
],
|
|
502
|
+
}),
|
|
503
|
+
})
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
This is an alternative to `z.enum(...)` — useful when the option list is dynamic or when you need a plain `string` output type rather than a union literal.
|
|
507
|
+
|
|
508
|
+
#### Option 3 — Named key in the registry
|
|
472
509
|
|
|
473
510
|
Register a component under a custom string key — either in `createAutoForm` or the `components` prop — then reference it with `meta.component: 'yourKey'`:
|
|
474
511
|
|
|
@@ -614,8 +651,8 @@ The `span` value is set as `--field-span` CSS custom property on each field wrap
|
|
|
614
651
|
city: { section: 'Address', order: 4 },
|
|
615
652
|
}}
|
|
616
653
|
layout={{
|
|
617
|
-
sectionWrapper: ({ children, title }) => (
|
|
618
|
-
<fieldset>
|
|
654
|
+
sectionWrapper: ({ children, title, className }) => (
|
|
655
|
+
<fieldset className={className}>
|
|
619
656
|
<legend>{title}</legend>
|
|
620
657
|
{children}
|
|
621
658
|
</fieldset>
|
|
@@ -624,6 +661,23 @@ The `span` value is set as `--field-span` CSS custom property on each field wrap
|
|
|
624
661
|
/>
|
|
625
662
|
```
|
|
626
663
|
|
|
664
|
+
Use `layout.sections` to style or swap the wrapper for individual sections:
|
|
665
|
+
|
|
666
|
+
```tsx
|
|
667
|
+
<AutoForm
|
|
668
|
+
form={myForm}
|
|
669
|
+
onSubmit={handleSubmit}
|
|
670
|
+
layout={{
|
|
671
|
+
sections: {
|
|
672
|
+
Personal: { className: 'bg-blue-50 p-4 rounded' },
|
|
673
|
+
Address: { component: AddressCard }, // completely different component
|
|
674
|
+
},
|
|
675
|
+
}}
|
|
676
|
+
/>
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
`className` is forwarded as a prop to the active wrapper (global `sectionWrapper` or the per-section `component`). Factory-level and instance-level `sections` are merged — instance wins on conflicts.
|
|
680
|
+
|
|
627
681
|
### Conditional Fields
|
|
628
682
|
|
|
629
683
|
Show a field only when another field has a specific value. Conditional fields are fully lifecycle-managed:
|
package/dist/index.d.mts
CHANGED
|
@@ -181,6 +181,26 @@ type FieldConfigBase = {
|
|
|
181
181
|
required: boolean;
|
|
182
182
|
/** Merged UI metadata for the field. */
|
|
183
183
|
meta: FieldMeta;
|
|
184
|
+
/**
|
|
185
|
+
* The original Zod schema for this field, after transparent wrappers
|
|
186
|
+
* (`optional`, `nullable`, `default`, `pipe`) have been stripped.
|
|
187
|
+
*
|
|
188
|
+
* This is a general escape hatch for custom components that need to inspect
|
|
189
|
+
* the raw schema — for example, to read union variants, access custom Zod
|
|
190
|
+
* metadata not captured by introspection, or build schema-aware validation UI.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* function MyUnionInput({ field }: FieldProps) {
|
|
194
|
+
* // Inspect the original schema for any edge case
|
|
195
|
+
* const schema = field.schema
|
|
196
|
+
* if (schema._zod.def.type === 'union') {
|
|
197
|
+
* const variants = (schema._zod.def as z.$ZodUnionDef).options
|
|
198
|
+
* // render a type-switcher using the raw Zod variants
|
|
199
|
+
* }
|
|
200
|
+
* return <input ... />
|
|
201
|
+
* }
|
|
202
|
+
*/
|
|
203
|
+
schema: z.$ZodType;
|
|
184
204
|
};
|
|
185
205
|
/**
|
|
186
206
|
* The fully resolved configuration for a single form field, produced by
|
|
@@ -256,6 +276,12 @@ type FieldProps = {
|
|
|
256
276
|
options?: SelectOption[];
|
|
257
277
|
/** Full field metadata, including any custom keys. */
|
|
258
278
|
meta: FieldMeta;
|
|
279
|
+
/**
|
|
280
|
+
* The original Zod schema for this field (after transparent wrappers are stripped).
|
|
281
|
+
* Use this as an escape hatch when you need capabilities beyond what `FieldConfig`
|
|
282
|
+
* exposes — e.g. inspecting union variants, accessing custom Zod refinements, etc.
|
|
283
|
+
*/
|
|
284
|
+
schema: z.$ZodType;
|
|
259
285
|
};
|
|
260
286
|
/**
|
|
261
287
|
* A map of field type keys to React components used to render them.
|
|
@@ -321,6 +347,20 @@ type ArrayRowLayoutProps = {
|
|
|
321
347
|
/** Total number of rows currently in the array. */
|
|
322
348
|
rowCount: number;
|
|
323
349
|
};
|
|
350
|
+
/**
|
|
351
|
+
* Per-section styling overrides forwarded to the `sectionWrapper` component.
|
|
352
|
+
* Keys are section titles; values control how that section wrapper is styled.
|
|
353
|
+
*/
|
|
354
|
+
type SectionConfig = {
|
|
355
|
+
/** CSS class name(s) applied to the section wrapper. */
|
|
356
|
+
className?: string;
|
|
357
|
+
/** Replaces the section wrapper component entirely for this section. */
|
|
358
|
+
component?: React.ComponentType<{
|
|
359
|
+
children: React.ReactNode;
|
|
360
|
+
title: string;
|
|
361
|
+
className?: string;
|
|
362
|
+
}>;
|
|
363
|
+
};
|
|
324
364
|
/**
|
|
325
365
|
* Optional layout slot overrides for top-level structural components of the
|
|
326
366
|
* form. Provide only the slots you want to replace; omitted slots fall back
|
|
@@ -335,6 +375,7 @@ type LayoutSlots = {
|
|
|
335
375
|
sectionWrapper?: React.ComponentType<{
|
|
336
376
|
children: React.ReactNode;
|
|
337
377
|
title: string;
|
|
378
|
+
className?: string;
|
|
338
379
|
}>;
|
|
339
380
|
/** Custom submit button component. */
|
|
340
381
|
submitButton?: React.ComponentType<{
|
|
@@ -348,6 +389,11 @@ type LayoutSlots = {
|
|
|
348
389
|
* Defaults to a simple `<p>Loading…</p>` when not provided.
|
|
349
390
|
*/
|
|
350
391
|
loadingFallback?: React.ReactNode;
|
|
392
|
+
/**
|
|
393
|
+
* Per-section config keyed by section title.
|
|
394
|
+
* Forwarded to the `sectionWrapper` component as a `className` prop.
|
|
395
|
+
*/
|
|
396
|
+
sections?: Record<string, SectionConfig>;
|
|
351
397
|
};
|
|
352
398
|
/**
|
|
353
399
|
* The resolved version of `LayoutSlots` used internally, where all slots are
|
|
@@ -360,6 +406,7 @@ type ResolvedLayoutSlots = {
|
|
|
360
406
|
sectionWrapper: React.ComponentType<{
|
|
361
407
|
children: React.ReactNode;
|
|
362
408
|
title: string;
|
|
409
|
+
className?: string;
|
|
363
410
|
}>;
|
|
364
411
|
submitButton: React.ComponentType<{
|
|
365
412
|
isSubmitting: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -181,6 +181,26 @@ type FieldConfigBase = {
|
|
|
181
181
|
required: boolean;
|
|
182
182
|
/** Merged UI metadata for the field. */
|
|
183
183
|
meta: FieldMeta;
|
|
184
|
+
/**
|
|
185
|
+
* The original Zod schema for this field, after transparent wrappers
|
|
186
|
+
* (`optional`, `nullable`, `default`, `pipe`) have been stripped.
|
|
187
|
+
*
|
|
188
|
+
* This is a general escape hatch for custom components that need to inspect
|
|
189
|
+
* the raw schema — for example, to read union variants, access custom Zod
|
|
190
|
+
* metadata not captured by introspection, or build schema-aware validation UI.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* function MyUnionInput({ field }: FieldProps) {
|
|
194
|
+
* // Inspect the original schema for any edge case
|
|
195
|
+
* const schema = field.schema
|
|
196
|
+
* if (schema._zod.def.type === 'union') {
|
|
197
|
+
* const variants = (schema._zod.def as z.$ZodUnionDef).options
|
|
198
|
+
* // render a type-switcher using the raw Zod variants
|
|
199
|
+
* }
|
|
200
|
+
* return <input ... />
|
|
201
|
+
* }
|
|
202
|
+
*/
|
|
203
|
+
schema: z.$ZodType;
|
|
184
204
|
};
|
|
185
205
|
/**
|
|
186
206
|
* The fully resolved configuration for a single form field, produced by
|
|
@@ -256,6 +276,12 @@ type FieldProps = {
|
|
|
256
276
|
options?: SelectOption[];
|
|
257
277
|
/** Full field metadata, including any custom keys. */
|
|
258
278
|
meta: FieldMeta;
|
|
279
|
+
/**
|
|
280
|
+
* The original Zod schema for this field (after transparent wrappers are stripped).
|
|
281
|
+
* Use this as an escape hatch when you need capabilities beyond what `FieldConfig`
|
|
282
|
+
* exposes — e.g. inspecting union variants, accessing custom Zod refinements, etc.
|
|
283
|
+
*/
|
|
284
|
+
schema: z.$ZodType;
|
|
259
285
|
};
|
|
260
286
|
/**
|
|
261
287
|
* A map of field type keys to React components used to render them.
|
|
@@ -321,6 +347,20 @@ type ArrayRowLayoutProps = {
|
|
|
321
347
|
/** Total number of rows currently in the array. */
|
|
322
348
|
rowCount: number;
|
|
323
349
|
};
|
|
350
|
+
/**
|
|
351
|
+
* Per-section styling overrides forwarded to the `sectionWrapper` component.
|
|
352
|
+
* Keys are section titles; values control how that section wrapper is styled.
|
|
353
|
+
*/
|
|
354
|
+
type SectionConfig = {
|
|
355
|
+
/** CSS class name(s) applied to the section wrapper. */
|
|
356
|
+
className?: string;
|
|
357
|
+
/** Replaces the section wrapper component entirely for this section. */
|
|
358
|
+
component?: React.ComponentType<{
|
|
359
|
+
children: React.ReactNode;
|
|
360
|
+
title: string;
|
|
361
|
+
className?: string;
|
|
362
|
+
}>;
|
|
363
|
+
};
|
|
324
364
|
/**
|
|
325
365
|
* Optional layout slot overrides for top-level structural components of the
|
|
326
366
|
* form. Provide only the slots you want to replace; omitted slots fall back
|
|
@@ -335,6 +375,7 @@ type LayoutSlots = {
|
|
|
335
375
|
sectionWrapper?: React.ComponentType<{
|
|
336
376
|
children: React.ReactNode;
|
|
337
377
|
title: string;
|
|
378
|
+
className?: string;
|
|
338
379
|
}>;
|
|
339
380
|
/** Custom submit button component. */
|
|
340
381
|
submitButton?: React.ComponentType<{
|
|
@@ -348,6 +389,11 @@ type LayoutSlots = {
|
|
|
348
389
|
* Defaults to a simple `<p>Loading…</p>` when not provided.
|
|
349
390
|
*/
|
|
350
391
|
loadingFallback?: React.ReactNode;
|
|
392
|
+
/**
|
|
393
|
+
* Per-section config keyed by section title.
|
|
394
|
+
* Forwarded to the `sectionWrapper` component as a `className` prop.
|
|
395
|
+
*/
|
|
396
|
+
sections?: Record<string, SectionConfig>;
|
|
351
397
|
};
|
|
352
398
|
/**
|
|
353
399
|
* The resolved version of `LayoutSlots` used internally, where all slots are
|
|
@@ -360,6 +406,7 @@ type ResolvedLayoutSlots = {
|
|
|
360
406
|
sectionWrapper: React.ComponentType<{
|
|
361
407
|
children: React.ReactNode;
|
|
362
408
|
title: string;
|
|
409
|
+
className?: string;
|
|
363
410
|
}>;
|
|
364
411
|
submitButton: React.ComponentType<{
|
|
365
412
|
isSubmitting: boolean;
|
package/dist/index.js
CHANGED
|
@@ -83,25 +83,30 @@ function introspectSchema(schema, name = "", parentPath = "") {
|
|
|
83
83
|
let maxItems;
|
|
84
84
|
try {
|
|
85
85
|
if (kind === "string") {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
mergedMeta["inputType"] = "email";
|
|
90
|
-
} else if (defFormat === "url") {
|
|
91
|
-
mergedMeta["inputType"] = "url";
|
|
92
|
-
} else if (defFormat === "uuid") {
|
|
93
|
-
mergedMeta["inputType"] = "uuid";
|
|
86
|
+
if (mergedMeta.component === "select" && Array.isArray(mergedMeta.options) && mergedMeta.options.length > 0) {
|
|
87
|
+
type = "select";
|
|
88
|
+
options = mergedMeta.options;
|
|
94
89
|
} else {
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
);
|
|
99
|
-
if (hasFormat("email")) {
|
|
90
|
+
type = "string";
|
|
91
|
+
const defFormat = def.format;
|
|
92
|
+
if (defFormat === "email") {
|
|
100
93
|
mergedMeta["inputType"] = "email";
|
|
101
|
-
} else if (
|
|
94
|
+
} else if (defFormat === "url") {
|
|
102
95
|
mergedMeta["inputType"] = "url";
|
|
103
|
-
} else if (
|
|
96
|
+
} else if (defFormat === "uuid") {
|
|
104
97
|
mergedMeta["inputType"] = "uuid";
|
|
98
|
+
} else {
|
|
99
|
+
const checks = def.checks ?? [];
|
|
100
|
+
const hasFormat = (fmt) => checks.some(
|
|
101
|
+
(c) => c._zod.def.check === "string_format" && c._zod.def.format === fmt
|
|
102
|
+
);
|
|
103
|
+
if (hasFormat("email")) {
|
|
104
|
+
mergedMeta["inputType"] = "email";
|
|
105
|
+
} else if (hasFormat("url")) {
|
|
106
|
+
mergedMeta["inputType"] = "url";
|
|
107
|
+
} else if (hasFormat("uuid")) {
|
|
108
|
+
mergedMeta["inputType"] = "uuid";
|
|
109
|
+
}
|
|
105
110
|
}
|
|
106
111
|
}
|
|
107
112
|
} else if (kind === "number") {
|
|
@@ -138,15 +143,24 @@ function introspectSchema(schema, name = "", parentPath = "") {
|
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
} else if (def.type === "union") {
|
|
141
|
-
type = "union";
|
|
142
146
|
const unionDef = def;
|
|
147
|
+
const variants = unionDef.options;
|
|
143
148
|
if ("discriminator" in unionDef) {
|
|
149
|
+
type = "union";
|
|
144
150
|
discriminatorKey = unionDef.discriminator;
|
|
151
|
+
unionVariants = variants.map(
|
|
152
|
+
(variant, i) => introspectSchema(variant, String(i), path)
|
|
153
|
+
);
|
|
154
|
+
} else {
|
|
155
|
+
const collapsed = introspectSchema(variants[0], name, parentPath);
|
|
156
|
+
return {
|
|
157
|
+
...collapsed,
|
|
158
|
+
name: path,
|
|
159
|
+
label,
|
|
160
|
+
meta: { ...collapsed.meta, ...mergedMeta },
|
|
161
|
+
schema: inner
|
|
162
|
+
};
|
|
145
163
|
}
|
|
146
|
-
const variants = unionDef.options;
|
|
147
|
-
unionVariants = variants.map(
|
|
148
|
-
(variant, i) => introspectSchema(variant, String(i), path)
|
|
149
|
-
);
|
|
150
164
|
}
|
|
151
165
|
} catch {
|
|
152
166
|
type = "unknown";
|
|
@@ -157,6 +171,7 @@ function introspectSchema(schema, name = "", parentPath = "") {
|
|
|
157
171
|
label,
|
|
158
172
|
required,
|
|
159
173
|
meta: mergedMeta,
|
|
174
|
+
schema: inner,
|
|
160
175
|
...options !== void 0 && { options },
|
|
161
176
|
...children !== void 0 && { children },
|
|
162
177
|
...itemConfig !== void 0 && { itemConfig },
|
|
@@ -195,6 +210,7 @@ function parseDiscriminatedUnionMeta(schema) {
|
|
|
195
210
|
label: deriveLabel(discriminatorKey),
|
|
196
211
|
required: true,
|
|
197
212
|
meta: {},
|
|
213
|
+
schema,
|
|
198
214
|
options: discriminatorOptions
|
|
199
215
|
};
|
|
200
216
|
return {
|
|
@@ -382,9 +398,10 @@ function DefaultFormWrapper({ children }) {
|
|
|
382
398
|
}
|
|
383
399
|
function DefaultSectionWrapper({
|
|
384
400
|
children,
|
|
385
|
-
title
|
|
401
|
+
title,
|
|
402
|
+
className
|
|
386
403
|
}) {
|
|
387
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { children: [
|
|
404
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className, children: [
|
|
388
405
|
/* @__PURE__ */ jsxRuntime.jsx("legend", { children: title }),
|
|
389
406
|
children
|
|
390
407
|
] });
|
|
@@ -495,7 +512,7 @@ function ScalarField({
|
|
|
495
512
|
onChange: (value) => {
|
|
496
513
|
const coerced = coerceValue(field.type, value, coercions);
|
|
497
514
|
rhfField.onChange(coerced);
|
|
498
|
-
field.meta.onChange?.(coerced, formMethods);
|
|
515
|
+
void field.meta.onChange?.(coerced, formMethods);
|
|
499
516
|
},
|
|
500
517
|
onBlur: rhfField.onBlur,
|
|
501
518
|
ref: rhfField.ref,
|
|
@@ -505,7 +522,9 @@ function ScalarField({
|
|
|
505
522
|
error: fieldState.error?.message,
|
|
506
523
|
required: field.required,
|
|
507
524
|
disabled: field.meta.disabled || contextDisabled,
|
|
508
|
-
|
|
525
|
+
options: field.meta.options,
|
|
526
|
+
meta: field.meta,
|
|
527
|
+
schema: field.schema
|
|
509
528
|
}
|
|
510
529
|
)
|
|
511
530
|
}
|
|
@@ -537,7 +556,7 @@ function BooleanField({
|
|
|
537
556
|
value: rhfField.value ?? false,
|
|
538
557
|
onChange: (value) => {
|
|
539
558
|
rhfField.onChange(value);
|
|
540
|
-
field.meta.onChange?.(value, formMethods);
|
|
559
|
+
void field.meta.onChange?.(value, formMethods);
|
|
541
560
|
},
|
|
542
561
|
onBlur: rhfField.onBlur,
|
|
543
562
|
ref: rhfField.ref,
|
|
@@ -547,7 +566,8 @@ function BooleanField({
|
|
|
547
566
|
error: fieldState.error?.message,
|
|
548
567
|
required: field.required,
|
|
549
568
|
disabled: field.meta.disabled || rhfField.disabled || contextDisabled,
|
|
550
|
-
meta: field.meta
|
|
569
|
+
meta: field.meta,
|
|
570
|
+
schema: field.schema
|
|
551
571
|
}
|
|
552
572
|
)
|
|
553
573
|
}
|
|
@@ -579,7 +599,7 @@ function SelectField({
|
|
|
579
599
|
value: rhfField.value ?? "",
|
|
580
600
|
onChange: (value) => {
|
|
581
601
|
rhfField.onChange(value);
|
|
582
|
-
field.meta.onChange?.(value, formMethods);
|
|
602
|
+
void field.meta.onChange?.(value, formMethods);
|
|
583
603
|
},
|
|
584
604
|
onBlur: rhfField.onBlur,
|
|
585
605
|
ref: rhfField.ref,
|
|
@@ -590,7 +610,8 @@ function SelectField({
|
|
|
590
610
|
required: field.required,
|
|
591
611
|
disabled: field.meta.disabled || contextDisabled,
|
|
592
612
|
options: field.options,
|
|
593
|
-
meta: field.meta
|
|
613
|
+
meta: field.meta,
|
|
614
|
+
schema: field.schema
|
|
594
615
|
}
|
|
595
616
|
)
|
|
596
617
|
}
|
|
@@ -1505,7 +1526,17 @@ function AutoForm(props) {
|
|
|
1505
1526
|
if (section.title === null) {
|
|
1506
1527
|
return /* @__PURE__ */ jsxRuntime.jsx(React3__namespace.Fragment, { children: renderedFields }, "__ungrouped");
|
|
1507
1528
|
}
|
|
1508
|
-
|
|
1529
|
+
const sectionConfig = layout?.sections?.[section.title];
|
|
1530
|
+
const PerSectionWrapper = sectionConfig?.component ?? SectionWrapper;
|
|
1531
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1532
|
+
PerSectionWrapper,
|
|
1533
|
+
{
|
|
1534
|
+
title: section.title,
|
|
1535
|
+
className: sectionConfig?.className,
|
|
1536
|
+
children: renderedFields
|
|
1537
|
+
},
|
|
1538
|
+
section.title
|
|
1539
|
+
);
|
|
1509
1540
|
}),
|
|
1510
1541
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1511
1542
|
SubmitButton,
|
|
@@ -1525,7 +1556,11 @@ function createAutoForm(config) {
|
|
|
1525
1556
|
[props.components]
|
|
1526
1557
|
);
|
|
1527
1558
|
const mergedLayout = React3__namespace.useMemo(
|
|
1528
|
-
() => ({
|
|
1559
|
+
() => ({
|
|
1560
|
+
...config.layout,
|
|
1561
|
+
...props.layout,
|
|
1562
|
+
sections: config.layout?.sections || props.layout?.sections ? { ...config.layout?.sections, ...props.layout?.sections } : void 0
|
|
1563
|
+
}),
|
|
1529
1564
|
[props.layout]
|
|
1530
1565
|
);
|
|
1531
1566
|
const mergedClassNames = React3__namespace.useMemo(
|