import Ajv from 'ajv'; import { JSONSchema7Definition } from 'json-schema'; import React$1 from 'react'; /** * Accessibility helpers shared by `` and ``. * * Lives in its own module (not `Form/helpers`) because it carries no form * logic — it only wires the two components together. */ /** * Deterministic default id of a `` for field `name` inside the * `
` instance identified by `formId`. * * The `formId` prefix guarantees that two ``s rendered on the same * page with a field of the same `name` produce distinct error ids — without * it, an `aria-describedby` IDREF could resolve to the error of the OTHER * form. `name` may contain dots or brackets (e.g. `user.emails[0]`): both * are valid inside an HTML id attribute, so the name is used as-is. * * ``'s `aria-describedby` does NOT call this function: it reads the * ids actually registered by the mounted ``s from the form * context (see `getFieldErrorDescribedBy`), so a custom `id` prop on * `` stays referenced automatically. * * Caveats: * - Rendering several `` with the same `name` in one form * produces duplicate default ids (invalid HTML). Override `id` on all but * one of them in that case. * - A `name` containing spaces cannot be referenced this way: * `aria-describedby` is a space-separated IDREF list, so the generated id * would be read as several ids. Override `id` for such names. * * @param {string} formId * @param {string} name * @returns {string} */ export declare function getFieldErrorId(formId: string, name: string): string; /** * An AJV `ErrorObject` enriched with a `field` property — a normalized, * dot-separated path to the offending field (e.g. `'user.email'` or * `'items.0.label'`). Used everywhere internally to locate the input * associated with an error. * * `instancePath` is declared here because the bundled AJV 6 typings only * know `dataPath`; AJV 8 errors carry `instancePath` instead, and * {@link formatErrors} accepts both shapes. * * Because {@link createAjv} enables AJV's `verbose` option (issue #6), * errors also carry `data` (the current value of the offending field — * for `required` errors it is the parent object missing the property), * `schema` (the failing keyword's value) and `parentSchema` (the * enclosing subschema). Those three properties are already declared as * optional on AJV 6's `ErrorObject` (`data?: any`, `schema?: any`, * `parentSchema?: object`), so they are inherited here — no re-declaration * needed. They stay `undefined` when a custom `ajv` prop is passed to * `` without `verbose: true`. */ export type FormattedError = Ajv.ErrorObject & { instancePath?: string; field: string; }; /** * Minimal shape required by the library on an input target. Structurally * compatible with `HTMLInputElement`, `HTMLTextAreaElement`, `HTMLSelectElement` * and any custom object that mimics them (e.g. when an integration like * `react-select` synthesizes its own events). Only the properties actually * read by the library appear here. */ export type FormInputTarget = { name: string; value: string; type?: string; checked?: boolean; files?: FileList | null; multiple?: boolean; }; /** * Lightweight change event accepted by the form. Any DOM `ChangeEvent` * or `InputEvent` is structurally compatible with this shape, so users can * forward native React events without casting. */ export type FormChangeEvent = { target: FormInputTarget; }; /** * Internal `Omit` variant that keeps typed keys strict even when `T` has an * index signature (like `[key: string]: any` — reactstrap and a few other * libraries expose these). Standard `Omit` on such a type collapses * the typed keys back into `any` through the index, which effectively kills * the polymorphic type-checking on `` etc. * * This variant: * 1. Strips the index signature so `Omit` can operate on named keys only, * keeping their precise types. * 2. Only re-attaches the original index signature (with its original * value type) *if T actually had one to begin with*. The `string * extends keyof T` guard prevents accidentally re-injecting an index * signature on plain "record-like" types whose values happen to share * a common supertype (e.g. `{ label: string; flavor: 'a' | 'b' }` * structurally extends `{ [k: string]: string }` but does not really * accept arbitrary keys). */ export type SafePropsOmit = (Omit<{ [P in keyof T as string extends P ? never : P]: T[P]; }, K> & (string extends keyof T ? (T extends { [k: string]: infer V; } ? { [k: string]: V; } : {}) : {})); /** * Built-in AJV validation keywords. Listed here so consumers writing * `errorMessages` get IDE autocomplete on the well-known keys while still * being free to add custom keywords (any other string is accepted via the * `(string & {})` intersection in `ErrorMessagesMap`). */ export type AjvKeyword = ("type" | "required" | "enum" | "const" | "minimum" | "maximum" | "exclusiveMinimum" | "exclusiveMaximum" | "multipleOf" | "minLength" | "maxLength" | "pattern" | "format" | "minItems" | "maxItems" | "uniqueItems" | "minProperties" | "maxProperties" | "additionalProperties" | "dependencies" | "patternProperties" | "properties" | "oneOf" | "anyOf" | "allOf" | "not" | "if" | "then" | "else"); /** * Builds a single error message string from an AJV error. */ export type ErrorMessageFn = (error: FormattedError) => string; /** * Map of error messages. `defaultMessage` is the catch-all used by * `` when no entry matches the error's keyword. The known * keywords (see {@link AjvKeyword}) are typed for autocomplete; any other * string key (e.g. a custom AJV keyword) is still allowed. * * The `(string & {})` in the key union is the standard TypeScript trick to * accept arbitrary strings *without* collapsing the literal union — plain * `string` would erase the autocomplete on the known keywords. */ export type ErrorMessagesMap = Partial>; /** * The complete value of the form context, supplied by `` to all its * descendants. The actual context type is `FormContextValue | undefined` * (it is `undefined` for any consumer rendered outside a ``), but * `useFormContext()` and `withFormContext()` perform the runtime check * so downstream code receives a guaranteed non-`undefined` value. */ export type FormContextValue = { errors: FormattedError[]; isSubmitted: boolean; touchedFields: string[]; valid: boolean; errorMessages?: ErrorMessagesMap; formId: string; getFieldErrorDescribedBy: (name: string) => string | undefined; getFieldErrors: (names: string | string[]) => FormattedError[]; handleFieldChange: (event: FormChangeEvent | string, value?: unknown) => void; isFieldTouched: (names: string | string[]) => boolean; isFieldInvalid: (names: string | string[]) => boolean; isTouched: () => boolean; registerFieldError: (key: string, name: string, id: string) => void; reset: () => void; touch: (names: string | string[]) => void; unregisterFieldError: (key: string) => void; }; declare const _default: (props: FieldProps & { ref?: React$1.ComponentPropsWithRef["ref"]; }) => JSX.Element | null; /** * `onChange` handler for a default `` (intrinsic ``). * For ``, prefer `PolymorphicFieldChangeHandler` * or let TypeScript infer the handler type from context. */ export type FieldChangeHandler = (event: FormChangeEvent, formHandleFieldChange: FormContextValue["handleFieldChange"]) => void; /** * First argument type of component `C`'s handler `K` (`'onChange'` or * `'onBlur'`). Falls back to `FormChangeEvent` / `FocusEvent` when `C` * doesn't declare the handler. * * Only the FIRST argument is captured. Handlers with additional * parameters (e.g. `(option, action) => void`) type the first one only. */ export type ChildEmit = K extends "onChange" ? (React$1.ComponentProps extends { onChange?: (arg: infer A, ...rest: any) => any; } ? A : FormChangeEvent) : (React$1.ComponentProps extends { onBlur?: (arg: infer A, ...rest: any) => any; } ? A : React$1.FocusEvent); /** * `onChange` handler whose first parameter follows what `C` emits: * a DOM event for intrinsic elements, a raw value for custom components. */ export type PolymorphicFieldChangeHandler = (eventOrValue: ChildEmit, formHandleFieldChange: FormContextValue["handleFieldChange"]) => void; /** * Base props of `` — the validation-specific props handled by the * component itself. The public, polymorphic `FieldProps` extends this * with the props of the underlying component `C`. * * `forwardedRef` is an implementation detail (injected by the outer * `React.forwardRef` wrapper) and is omitted from the public polymorphic * type below. */ export type FieldBaseProps = { name: string; "aria-describedby"?: string | null; children?: React$1.ReactNode; className?: string; component?: React$1.ElementType; forwardedRef?: React$1.Ref | null; onBlur?: ((event: React$1.FocusEvent) => void) | null; onChange?: FieldChangeHandler | null; }; /** * Polymorphic props of ``. When `component={X}` is supplied, every * prop accepted by `X` is also accepted here (with autocomplete and typo * detection). The default `C = 'input'` matches the runtime default. * * - `name` — path within the form data this field reads/writes. * - `component` — host element or component (default `'input'`). * - `onChange` — user override. First parameter follows what `C` emits * (a DOM event for intrinsic elements, a raw value for * custom components). The form's internal handler is * passed as the second parameter so the user can still * apply the change from inside their handler. * - `onBlur` — user override; always fires *after* `form.touch(name)`. * First parameter polymorphic on `C.onBlur`. */ export type FieldProps = (Omit & { component?: C; onChange?: PolymorphicFieldChangeHandler | null; onBlur?: ((arg: ChildEmit) => void) | null; } & SafePropsOmit, keyof FieldBaseProps | "ref" | "onChange" | "onBlur">); declare const _default$1: (props: FieldErrorProps) => JSX.Element | null; /** * Base props of `` — the validation-specific props handled by * the component itself. The public, polymorphic `FieldErrorProps` extends * this with the props of the underlying component `C`. */ export type FieldErrorBaseProps = { children?: React$1.ReactNode; className?: string; component?: React$1.ElementType; errorMessages?: ErrorMessagesMap | null; id?: string | null; name: string; }; /** * Polymorphic props of ``. When `component={X}` is supplied, * every prop accepted by `X` is also accepted here (with autocomplete and * typo detection). The default `C = 'div'` matches the runtime default. * * - `name` — path of the form field whose first error should be shown. * - `errorMessages` — optional per-field overrides; they take priority over the * map declared at the `` level (see `ErrorMessagesMap`). * - `component` — element rendered when an error is present (default `'div'`). * - `children` — replaces the auto-generated message when provided. * - `id` — overrides the default deterministic id; the effective id is * registered in the form, so ``'s `aria-describedby` * follows it automatically. */ export type FieldErrorProps = (Omit & { component?: C; } & SafePropsOmit, keyof FieldErrorBaseProps | "ref">); declare const _default$2: , C extends React$1.ElementType = "form">(props: FormProps) => JSX.Element | null; /** * Options controlling how the form scrolls to the first invalid field on * a failed submit. Forwarded to the native `element.scrollIntoView()`. * * Native `scrollIntoView` options (`behavior`, `block`, `inline`) are passed * through as-is. The legacy `align` option ('top' | 'middle' | 'bottom'), * inherited from the former `scroll-to-element` dependency, is mapped to * `block` ('start' | 'center' | 'end'); an explicit `block` wins over `align`. * * The legacy `offset`, `duration` and `ease` options are still accepted for * backward compatibility but are IGNORED: the native scrolling API has no * equivalent — animation is delegated to the browser via `behavior: 'smooth'` * (the default). */ export type JfvScrollOptions = { behavior?: ScrollBehavior; block?: ScrollLogicalPosition; inline?: ScrollLogicalPosition; align?: "top" | "middle" | "bottom" | (string & {}); offset?: number; duration?: number; ease?: string; }; /** * Base props of `` — the validation-specific props the component * handles itself. The public, polymorphic `FormProps` extends this * with the props of the underlying component `C` and typed data `T`. */ export type FormBaseProps = { ajv?: Ajv.Ajv; children?: React$1.ReactNode; className?: string; component?: React$1.ElementType; data?: Record; throttleDuration?: number; errorMessages?: ErrorMessagesMap; onChange?: ((data: Record, event?: FormChangeEvent) => void) | null; onSubmit: (event: React$1.FormEvent) => void; resetOnSubmit?: boolean; schema: JSONSchema7Definition; scrollToError?: boolean; scrollOptions?: JfvScrollOptions; }; /** * Polymorphic props of ``. Two type parameters: * - `T` — shape of the form data. Inferred from `data` / `onChange`, or * you can pass it explicitly via ` …>`. Default * `Record`. Note that `T` is a *promise* by the * caller: nothing at compile time ensures the JSON Schema actually * validates `T`. * - `C` — element type used for the form wrapper (the `component` prop). * Default `'form'`. When supplied, every prop accepted by `C` is * also accepted on `` (autocomplete + typo detection). * * Field reference: * - `schema` — JSON-Schema used to validate `data`. * - `data` — current form values, fully controlled by the parent. * - `onChange` — called with the updated data on every field change. * - `onSubmit` — called only when validation passes at submit time. * - `resetOnSubmit` — when `false`, the touched/submitted state is kept after * a successful submit (default `true`: the form state is * reset before `onSubmit` runs). Companion of the * context's `reset()`: set `resetOnSubmit={false}` and * call `reset()` from the context when appropriate * (e.g. once the server confirms the submission). * - `errorMessages` — map of error messages shared by every `` * descendant (see `ErrorMessagesMap`). * - `ajv` — optional pre-configured AJV instance, useful to plug * in custom keywords/formats. * - `component` — element rendered for the form wrapper (default ``). */ export type FormProps, C extends React$1.ElementType = "form"> = (Omit & { component?: C; data?: T; onChange?: ((data: T, event?: FormChangeEvent) => void) | null; } & SafePropsOmit, keyof FormBaseProps | "ref">); export function useFormContext(): FormContextValue; export function withFormContext(cb: (ctx: FormContextValue) => T): React$1.ReactElement; /** * @import { ReactElement } from 'react' * @import { FormContextValue } from './Context.types' */ /** * React context that carries the `` state down to descendant * `` and `` components. Not intended for direct use — * consume it through `useFormContext()` (or the legacy `withFormContext()` * render-prop helper), which handles the "outside a Form" case with a * descriptive error instead of returning `undefined`. */ export declare const FormContext: React$1.Context; export { _default as Field, _default$1 as FieldError, _default$2 as Form, _default$2 as default, }; export {};