orynn 0.1.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/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/index.cjs +823 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +400 -0
- package/dist/index.d.ts +400 -0
- package/dist/index.js +809 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +201 -0
- package/package.json +82 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ComponentType, SyntheticEvent, SelectHTMLAttributes, ReactNode, ChangeEvent, InputHTMLAttributes, FormEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Per-field validation config. V1 ships `required` / `minLength` / `maxLength`.
|
|
6
|
+
* Future rule keys (regex, email, min, max, validate, ...) are added here without
|
|
7
|
+
* a breaking change.
|
|
8
|
+
*/
|
|
9
|
+
interface FieldValidation {
|
|
10
|
+
required?: boolean;
|
|
11
|
+
minLength?: number;
|
|
12
|
+
maxLength?: number;
|
|
13
|
+
/** Per-rule message overrides, e.g. `{ required: "Name is required" }`. */
|
|
14
|
+
messages?: Partial<Record<string, string>>;
|
|
15
|
+
}
|
|
16
|
+
/** A single validation failure. Shape is frozen — new fields must stay optional. */
|
|
17
|
+
interface FieldError {
|
|
18
|
+
/** Rule that failed: `"required"`, `"minLength"`, `"custom"`, `"async"`, ... */
|
|
19
|
+
rule: string;
|
|
20
|
+
message: string;
|
|
21
|
+
/** Reserved for cross-field / nested errors. Unused in V1. */
|
|
22
|
+
path?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validation output. Key = field name. The reserved key `"$form"` holds
|
|
26
|
+
* form-level / cross-field errors.
|
|
27
|
+
*/
|
|
28
|
+
type ValidationResult = Record<string, FieldError[]>;
|
|
29
|
+
/** Reserved key in {@link ValidationResult} for form-level errors. */
|
|
30
|
+
declare const FORM_ERROR_KEY: "$form";
|
|
31
|
+
/** What triggered a validation run. */
|
|
32
|
+
type ValidationTrigger = "change" | "blur" | "submit";
|
|
33
|
+
interface ValidationContext {
|
|
34
|
+
/** Field whose change/blur triggered this run, if any. */
|
|
35
|
+
changedField?: string;
|
|
36
|
+
trigger: ValidationTrigger;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The single seam through which all validation flows. V1's default resolver is
|
|
40
|
+
* rule-based and synchronous; the `Promise` return type keeps async, schema, and
|
|
41
|
+
* cross-field validation additive.
|
|
42
|
+
*/
|
|
43
|
+
type ValidationResolver = (values: Record<string, unknown>, config: FieldsetConfig, context: ValidationContext) => ValidationResult | Promise<ValidationResult>;
|
|
44
|
+
/**
|
|
45
|
+
* A single rule implementation. Returns an error message string on failure, or
|
|
46
|
+
* `null` on success. `allValues` is passed so cross-field rules need no
|
|
47
|
+
* signature change later.
|
|
48
|
+
*/
|
|
49
|
+
type RuleFn = (value: unknown, param: unknown, allValues: Record<string, unknown>) => string | null;
|
|
50
|
+
|
|
51
|
+
/** A single selectable option in a {@link DropdownFieldConfig}. */
|
|
52
|
+
interface DropdownOption {
|
|
53
|
+
label: string;
|
|
54
|
+
value: string;
|
|
55
|
+
disabled?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/** Number of columns at each responsive breakpoint. */
|
|
58
|
+
interface ColumnSpec {
|
|
59
|
+
desktop: number;
|
|
60
|
+
tablet: number;
|
|
61
|
+
mobile: number;
|
|
62
|
+
}
|
|
63
|
+
/** Fields common to every field type. */
|
|
64
|
+
interface BaseFieldConfig {
|
|
65
|
+
/** Unique key within the fieldset; also the key in the values object. */
|
|
66
|
+
name: string;
|
|
67
|
+
label?: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
placeholder?: string;
|
|
70
|
+
disabled?: boolean;
|
|
71
|
+
readOnly?: boolean;
|
|
72
|
+
defaultValue?: unknown;
|
|
73
|
+
validation?: FieldValidation;
|
|
74
|
+
/** Field-level column span, overriding the fieldset's `columns`. */
|
|
75
|
+
layout?: Partial<ColumnSpec>;
|
|
76
|
+
/** Escape hatch: spread verbatim onto the underlying control. */
|
|
77
|
+
props?: Record<string, unknown>;
|
|
78
|
+
}
|
|
79
|
+
/** Native `<input>` field. `inputType` maps to the DOM `type` attribute. */
|
|
80
|
+
interface InputFieldConfig extends BaseFieldConfig {
|
|
81
|
+
type: "input";
|
|
82
|
+
inputType?: "text" | "email" | "password" | "number" | "tel" | "url";
|
|
83
|
+
}
|
|
84
|
+
/** Native `<select>` field. */
|
|
85
|
+
interface DropdownFieldConfig extends BaseFieldConfig {
|
|
86
|
+
type: "dropdown";
|
|
87
|
+
options: DropdownOption[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Maps a field `type` string to its config shape. Consumers register custom
|
|
91
|
+
* field types by augmenting this interface:
|
|
92
|
+
*
|
|
93
|
+
* ```ts
|
|
94
|
+
* declare module "orynn" {
|
|
95
|
+
* interface FieldConfigRegistry {
|
|
96
|
+
* rating: RatingFieldConfig;
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
interface FieldConfigRegistry {
|
|
102
|
+
input: InputFieldConfig;
|
|
103
|
+
dropdown: DropdownFieldConfig;
|
|
104
|
+
}
|
|
105
|
+
/** Discriminated union of every registered field config. */
|
|
106
|
+
type FieldConfig = FieldConfigRegistry[keyof FieldConfigRegistry];
|
|
107
|
+
/** The `type` discriminant of any registered field. */
|
|
108
|
+
type FieldType = keyof FieldConfigRegistry;
|
|
109
|
+
/** Top-level configuration passed to `<Fieldset config={...} />`. */
|
|
110
|
+
interface FieldsetConfig {
|
|
111
|
+
fields: FieldConfig[];
|
|
112
|
+
/** Rendered in a `<legend>` when present. */
|
|
113
|
+
legend?: string;
|
|
114
|
+
/** Columns per breakpoint. Defaults to `{ desktop: 3, tablet: 2, mobile: 1 }`. */
|
|
115
|
+
columns?: Partial<ColumnSpec>;
|
|
116
|
+
/** Grid gap; a number is treated as pixels. */
|
|
117
|
+
gap?: string | number;
|
|
118
|
+
id?: string;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The contract every control receives from `Fieldset`. This is the stability
|
|
123
|
+
* boundary between the orchestrator and the controls: as long as this holds,
|
|
124
|
+
* either side can change freely.
|
|
125
|
+
*/
|
|
126
|
+
interface ControlProps<TValue = unknown> {
|
|
127
|
+
id: string;
|
|
128
|
+
name: string;
|
|
129
|
+
value: TValue;
|
|
130
|
+
/** Value-first; the DOM event is the optional second argument. */
|
|
131
|
+
onChange: (value: TValue, event?: SyntheticEvent) => void;
|
|
132
|
+
onBlur: () => void;
|
|
133
|
+
onFocus: () => void;
|
|
134
|
+
disabled?: boolean;
|
|
135
|
+
readOnly?: boolean;
|
|
136
|
+
required?: boolean;
|
|
137
|
+
invalid?: boolean;
|
|
138
|
+
/** Space-separated id list to place on the control's `aria-describedby`. */
|
|
139
|
+
describedById?: string;
|
|
140
|
+
/** The full field config, for type-specific data (e.g. dropdown `options`). */
|
|
141
|
+
config: FieldConfig;
|
|
142
|
+
}
|
|
143
|
+
/** A React component that satisfies {@link ControlProps}. */
|
|
144
|
+
type ControlComponent<TValue = any> = ComponentType<ControlProps<TValue>>;
|
|
145
|
+
/** A registry entry for one field `type`. */
|
|
146
|
+
interface FieldRegistration<TValue = any> {
|
|
147
|
+
component: ControlComponent<TValue>;
|
|
148
|
+
/** Value used when neither the config nor the form supplies one. */
|
|
149
|
+
defaultValue?: TValue;
|
|
150
|
+
/** Normalize an incoming value before it reaches the control. */
|
|
151
|
+
parseValue?: (raw: unknown) => TValue;
|
|
152
|
+
/** Normalize an outgoing value before it reaches `onChange`. */
|
|
153
|
+
formatValue?: (value: TValue) => unknown;
|
|
154
|
+
/**
|
|
155
|
+
* Type-specific config validation. Return an error string to reject a field
|
|
156
|
+
* config (thrown in development), or `null` when it is valid. Keeps per-type
|
|
157
|
+
* knowledge out of the core normalizer.
|
|
158
|
+
*/
|
|
159
|
+
validateConfig?: (config: BaseFieldConfig & {
|
|
160
|
+
type: string;
|
|
161
|
+
}) => string | null;
|
|
162
|
+
}
|
|
163
|
+
/** Read-only view of a field registry. */
|
|
164
|
+
interface FieldRegistry {
|
|
165
|
+
register(type: string, registration: FieldRegistration): void;
|
|
166
|
+
get(type: string): FieldRegistration | undefined;
|
|
167
|
+
has(type: string): boolean;
|
|
168
|
+
/** All registered type strings, for error messages. */
|
|
169
|
+
types(): string[];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Error prop accepted by controls: one message or many. */
|
|
173
|
+
type ErrorProp = string | string[] | undefined;
|
|
174
|
+
/** Context handed to `<Field>`'s render function. */
|
|
175
|
+
interface FieldRenderContext {
|
|
176
|
+
/** Resolved control id (generated when not supplied). */
|
|
177
|
+
id: string;
|
|
178
|
+
/** Value for the control's `aria-describedby`, or `undefined`. */
|
|
179
|
+
describedById: string | undefined;
|
|
180
|
+
invalid: boolean;
|
|
181
|
+
required: boolean | undefined;
|
|
182
|
+
disabled: boolean | undefined;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Low-level layout + a11y wrapper. Renders label, description and error region
|
|
186
|
+
* and wires the ARIA relationships. `Input` and `Dropdown` are built on it, and
|
|
187
|
+
* it is exported for custom control authors.
|
|
188
|
+
*/
|
|
189
|
+
interface FieldProps {
|
|
190
|
+
label?: ReactNode;
|
|
191
|
+
description?: ReactNode;
|
|
192
|
+
error?: ErrorProp;
|
|
193
|
+
required?: boolean;
|
|
194
|
+
disabled?: boolean;
|
|
195
|
+
/** Control id; generated with `useId` when omitted. */
|
|
196
|
+
id?: string;
|
|
197
|
+
className?: string;
|
|
198
|
+
children: ReactNode | ((ctx: FieldRenderContext) => ReactNode);
|
|
199
|
+
}
|
|
200
|
+
/** Props shared by the standalone controls. */
|
|
201
|
+
interface SharedControlProps {
|
|
202
|
+
label?: ReactNode;
|
|
203
|
+
description?: ReactNode;
|
|
204
|
+
error?: ErrorProp;
|
|
205
|
+
}
|
|
206
|
+
interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "value" | "type">, SharedControlProps {
|
|
207
|
+
value?: string;
|
|
208
|
+
onChange?: (value: string, event?: ChangeEvent<HTMLInputElement>) => void;
|
|
209
|
+
type?: "text" | "email" | "password" | "number" | "tel" | "url";
|
|
210
|
+
}
|
|
211
|
+
interface DropdownProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, "onChange" | "value">, SharedControlProps {
|
|
212
|
+
options: DropdownOption[];
|
|
213
|
+
value?: string;
|
|
214
|
+
onChange?: (value: string, event?: ChangeEvent<HTMLSelectElement>) => void;
|
|
215
|
+
/** Renders a non-selectable prompt option when the value is empty. */
|
|
216
|
+
placeholder?: string;
|
|
217
|
+
}
|
|
218
|
+
interface FieldsetProps<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
219
|
+
config: FieldsetConfig;
|
|
220
|
+
/** Controlled values. Omit and use `defaultValue` for uncontrolled. */
|
|
221
|
+
value?: TValues;
|
|
222
|
+
defaultValue?: Partial<TValues>;
|
|
223
|
+
onChange?: (values: TValues) => void;
|
|
224
|
+
onValidationChange?: (result: ValidationResult) => void;
|
|
225
|
+
/** Replace validation wholesale. Defaults to the built-in rule resolver. */
|
|
226
|
+
resolver?: ValidationResolver;
|
|
227
|
+
/** Override the field registry for this instance. */
|
|
228
|
+
registry?: FieldRegistry;
|
|
229
|
+
/** When to validate. `"blur"` (default) also always validates on submit. */
|
|
230
|
+
validateOn?: ValidationTrigger;
|
|
231
|
+
/** Disable every field (rendered as a native `<fieldset disabled>`). */
|
|
232
|
+
disabled?: boolean;
|
|
233
|
+
className?: string;
|
|
234
|
+
id?: string;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* A labelled single-select built on the native `<select>` element (accessible
|
|
239
|
+
* and keyboard-navigable out of the box). Works with or without `<Fieldset>`.
|
|
240
|
+
*/
|
|
241
|
+
declare const Dropdown: react.ForwardRefExoticComponent<DropdownProps & react.RefAttributes<HTMLSelectElement>>;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Layout + accessibility wrapper for a single control. Renders the label,
|
|
245
|
+
* optional description, and an error region, and wires the ARIA relationships
|
|
246
|
+
* (`htmlFor`, `aria-describedby`, `aria-invalid`, `aria-required`).
|
|
247
|
+
*
|
|
248
|
+
* Pass a render function as `children` to receive the resolved ids:
|
|
249
|
+
*
|
|
250
|
+
* ```tsx
|
|
251
|
+
* <Field label="Name" error={error}>
|
|
252
|
+
* {({ id, describedById, invalid }) => (
|
|
253
|
+
* <input id={id} aria-describedby={describedById} aria-invalid={invalid} />
|
|
254
|
+
* )}
|
|
255
|
+
* </Field>
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
declare function Field(props: FieldProps): react.JSX.Element;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* A labelled text input. Controlled when `value` is passed, uncontrolled
|
|
262
|
+
* otherwise (`defaultValue` flows through to the native element). Works with or
|
|
263
|
+
* without `<Fieldset>`.
|
|
264
|
+
*/
|
|
265
|
+
declare const Input: react.ForwardRefExoticComponent<InputProps & react.RefAttributes<HTMLInputElement>>;
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Renders a form (or a form section) from a `FieldsetConfig`. Controlled when
|
|
269
|
+
* `value` is passed, uncontrolled otherwise. Renders a native `<fieldset>` — so
|
|
270
|
+
* `disabled` cascades to every control — and does not render its own `<form>`;
|
|
271
|
+
* wrap it in one and use `useFieldsetState().handleSubmit` for submission.
|
|
272
|
+
*/
|
|
273
|
+
declare function Fieldset<TValues extends Record<string, unknown> = Record<string, unknown>>(props: FieldsetProps<TValues>): react.JSX.Element;
|
|
274
|
+
|
|
275
|
+
/** Form-level validation roll-up. */
|
|
276
|
+
type FieldStatus = "idle" | "validating" | "valid" | "invalid";
|
|
277
|
+
/** The complete state a fieldset tracks. New keys must be additive. */
|
|
278
|
+
interface FieldsetState {
|
|
279
|
+
values: Record<string, unknown>;
|
|
280
|
+
/** Field has been blurred at least once. */
|
|
281
|
+
touched: Record<string, boolean>;
|
|
282
|
+
/** Field value differs from its initial value. */
|
|
283
|
+
dirty: Record<string, boolean>;
|
|
284
|
+
errors: ValidationResult;
|
|
285
|
+
status: FieldStatus;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** A validated `FieldsetConfig` with every default resolved. */
|
|
289
|
+
interface NormalizedFieldsetConfig {
|
|
290
|
+
fields: FieldConfig[];
|
|
291
|
+
columns: ColumnSpec;
|
|
292
|
+
/** CSS length for the grid gap, or `undefined` to use the token default. */
|
|
293
|
+
gap: string | undefined;
|
|
294
|
+
legend: string | undefined;
|
|
295
|
+
id: string | undefined;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Validate a `FieldsetConfig` and resolve its defaults. Structural problems
|
|
299
|
+
* throw in development with an actionable message; in production the checks are
|
|
300
|
+
* stripped and normalization is defensive.
|
|
301
|
+
*
|
|
302
|
+
* Pass `registry` (as `<Fieldset>` does) to also validate each field's `type`
|
|
303
|
+
* and run type-specific config checks.
|
|
304
|
+
*/
|
|
305
|
+
declare function normalizeConfig(config: FieldsetConfig, registry?: FieldRegistry): NormalizedFieldsetConfig;
|
|
306
|
+
|
|
307
|
+
type Values = Record<string, unknown>;
|
|
308
|
+
interface UseFieldsetStateOptions<TValues extends Values = Values> {
|
|
309
|
+
/** Controlled values. Omit and pass `defaultValue` for uncontrolled. */
|
|
310
|
+
value?: TValues;
|
|
311
|
+
defaultValue?: Partial<TValues>;
|
|
312
|
+
onChange?: (values: TValues) => void;
|
|
313
|
+
/** Called after a full validation pass (`validate()` / submit), not per blur. */
|
|
314
|
+
onValidationChange?: (result: ValidationResult) => void;
|
|
315
|
+
resolver?: ValidationResolver;
|
|
316
|
+
registry?: FieldRegistry;
|
|
317
|
+
/** `"blur"` (default) also always validates on submit. */
|
|
318
|
+
validateOn?: ValidationTrigger;
|
|
319
|
+
}
|
|
320
|
+
/** Everything a renderer needs for one field. Handlers are referentially stable. */
|
|
321
|
+
interface FieldSlice {
|
|
322
|
+
name: string;
|
|
323
|
+
value: unknown;
|
|
324
|
+
errors: FieldError[];
|
|
325
|
+
touched: boolean;
|
|
326
|
+
dirty: boolean;
|
|
327
|
+
setValue: (value: unknown) => void;
|
|
328
|
+
markTouched: () => void;
|
|
329
|
+
}
|
|
330
|
+
interface UseFieldsetStateReturn<TValues extends Values = Values> {
|
|
331
|
+
config: NormalizedFieldsetConfig;
|
|
332
|
+
state: FieldsetState;
|
|
333
|
+
values: TValues;
|
|
334
|
+
errors: ValidationResult;
|
|
335
|
+
touched: Record<string, boolean>;
|
|
336
|
+
dirty: Record<string, boolean>;
|
|
337
|
+
status: FieldStatus;
|
|
338
|
+
isValid: boolean;
|
|
339
|
+
setFieldValue: (name: string, value: unknown) => void;
|
|
340
|
+
setValues: (values: TValues) => void;
|
|
341
|
+
reset: (next?: Partial<TValues>) => void;
|
|
342
|
+
validate: () => Promise<ValidationResult>;
|
|
343
|
+
handleSubmit: (onValid: (values: TValues) => void, onInvalid?: (result: ValidationResult) => void) => (event?: FormEvent) => void;
|
|
344
|
+
getFieldProps: (name: string) => FieldSlice;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* The form engine behind `<Fieldset>`, usable directly when you want to own the
|
|
348
|
+
* markup. Manages values (controlled or uncontrolled), touched/dirty tracking,
|
|
349
|
+
* and validation through a pluggable resolver.
|
|
350
|
+
*/
|
|
351
|
+
declare function useFieldsetState<TValues extends Values = Values>(config: FieldsetConfig, options?: UseFieldsetStateOptions<TValues>): UseFieldsetStateReturn<TValues>;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Create an isolated field registry. Use this to give a `<Fieldset>` its own set
|
|
355
|
+
* of field types without touching the module-global {@link defaultRegistry}
|
|
356
|
+
* (recommended on the server, where mutating a shared registry per request would
|
|
357
|
+
* leak between requests).
|
|
358
|
+
*
|
|
359
|
+
* @experimental The registry API may change before 1.0.
|
|
360
|
+
*/
|
|
361
|
+
declare function createRegistry(): FieldRegistry;
|
|
362
|
+
/**
|
|
363
|
+
* The module-global registry used by `<Fieldset>` when no `registry` prop is
|
|
364
|
+
* passed. Seeded with the built-in `input` and `dropdown` fields.
|
|
365
|
+
*
|
|
366
|
+
* @experimental
|
|
367
|
+
*/
|
|
368
|
+
declare const defaultRegistry: FieldRegistry;
|
|
369
|
+
/**
|
|
370
|
+
* Register a field type on the {@link defaultRegistry}. Call this once at
|
|
371
|
+
* application start-up, not per render or per request.
|
|
372
|
+
*
|
|
373
|
+
* @experimental
|
|
374
|
+
*/
|
|
375
|
+
declare function registerField(type: string, registration: FieldRegistration): void;
|
|
376
|
+
|
|
377
|
+
/** A synchronous resolver — the built-in resolver's precise return type. */
|
|
378
|
+
type SyncResolver = (values: Record<string, unknown>, config: FieldsetConfig, context: ValidationContext) => ValidationResult;
|
|
379
|
+
/**
|
|
380
|
+
* The default, rule-based {@link ValidationResolver}. For every field with a
|
|
381
|
+
* `validation` block, each key (other than `messages`) is looked up in the rule
|
|
382
|
+
* registry and run against the field's current value. All fields are validated
|
|
383
|
+
* on every call; callers decide which errors to surface.
|
|
384
|
+
*
|
|
385
|
+
* Synchronous today. Async, schema-based, and cross-field resolvers plug in at
|
|
386
|
+
* the same seam without an API change.
|
|
387
|
+
*/
|
|
388
|
+
declare function createRuleResolver(): SyncResolver;
|
|
389
|
+
/** Shared default instance. */
|
|
390
|
+
declare const defaultResolver: ValidationResolver;
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Register a validation rule for the built-in resolver. A field opts in by
|
|
394
|
+
* adding a key of the same name to its `validation` config.
|
|
395
|
+
*
|
|
396
|
+
* @experimental The rule API may change before 1.0.
|
|
397
|
+
*/
|
|
398
|
+
declare function registerRule(name: string, fn: RuleFn): void;
|
|
399
|
+
|
|
400
|
+
export { type BaseFieldConfig, type ColumnSpec, type ControlComponent, type ControlProps, Dropdown, type DropdownFieldConfig, type DropdownOption, type DropdownProps, type ErrorProp, FORM_ERROR_KEY, Field, type FieldConfig, type FieldConfigRegistry, type FieldError, type FieldProps, type FieldRegistration, type FieldRegistry, type FieldRenderContext, type FieldSlice, type FieldStatus, type FieldType, type FieldValidation, Fieldset, type FieldsetConfig, type FieldsetProps, type FieldsetState, Input, type InputFieldConfig, type InputProps, type NormalizedFieldsetConfig, type RuleFn, type SyncResolver, type UseFieldsetStateOptions, type UseFieldsetStateReturn, type ValidationContext, type ValidationResolver, type ValidationResult, type ValidationTrigger, createRegistry, createRuleResolver, defaultRegistry, defaultResolver, normalizeConfig, registerField, registerRule, useFieldsetState };
|