import Ajv from 'ajv';
import { JSONSchema7Definition } from 'json-schema';
import React$1 from 'react';

/**
 * 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.
 */
export type FormattedError = Ajv.ErrorObject & {
	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<T, K>` on such a type collapses
 * the typed keys back into `any` through the index, which effectively kills
 * the polymorphic type-checking on `<Field component={X} .../>` 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<T, K extends PropertyKey> = (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
 * `<FieldError>` 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<Record<AjvKeyword | "defaultMessage" | (string & {}), ErrorMessageFn>>;
/**
 * The complete value of the form context, supplied by `<Form>` to all its
 * descendants. The actual context type is `FormContextValue | undefined`
 * (it is `undefined` for any consumer rendered outside a `<Form>`), 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;
	getFieldErrors: (names: string | string[]) => FormattedError[];
	handleFieldChange: (event: FormChangeEvent | string, value?: unknown) => void;
	isFieldTouched: (names: string | string[]) => boolean;
	isFieldInvalid: (names: string | string[]) => boolean;
	isTouched: () => boolean;
	touch: (names: string | string[]) => void;
};
declare const _default: <C extends React$1.ElementType = "input">(props: FieldProps<C> & {
	ref?: React$1.ComponentPropsWithRef<C>["ref"];
}) => JSX.Element | null;
/**
 * Signature of the user-supplied `onChange` handler. It receives the event
 * and the form's internal handler so the user can decide whether to apply,
 * transform or skip the update.
 */
export type FieldChangeHandler = (event: FormChangeEvent, formHandleFieldChange: FormContextValue["handleFieldChange"]) => void;
/**
 * Base props of `<Field>` — the validation-specific props handled by the
 * component itself. The public, polymorphic `FieldProps<C>` 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;
	children?: React$1.ReactNode;
	className?: string;
	component?: React$1.ElementType;
	forwardedRef?: React$1.Ref<unknown> | null;
	onBlur?: ((event: React$1.FocusEvent) => void) | null;
	onChange?: FieldChangeHandler | null;
};
/**
 * Polymorphic props of `<Field>`. 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; receives the raw event plus the form's
 *                   internal change handler so the user can decide whether
 *                   to apply, transform or skip the update.
 * - `onBlur`      — user override; always fires *after* `form.touch(name)`.
 */
export type FieldProps<C extends React$1.ElementType = "input"> = (Omit<FieldBaseProps, "component" | "forwardedRef"> & {
	component?: C;
} & SafePropsOmit<React$1.ComponentProps<C>, keyof FieldBaseProps | "ref">);
declare const _default$1: <C extends React$1.ElementType = "div">(props: FieldErrorProps<C>) => JSX.Element | null;
/**
 * Base props of `<FieldError>` — the validation-specific props handled by
 * the component itself. The public, polymorphic `FieldErrorProps<C>` 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;
	name: string;
};
/**
 * Polymorphic props of `<FieldError>`. 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 `<Form>` level (see `ErrorMessagesMap`).
 * - `component`       — element rendered when an error is present (default `'div'`).
 * - `children`        — replaces the auto-generated message when provided.
 */
export type FieldErrorProps<C extends React$1.ElementType = "div"> = (Omit<FieldErrorBaseProps, "component"> & {
	component?: C;
} & SafePropsOmit<React$1.ComponentProps<C>, keyof FieldErrorBaseProps | "ref">);
declare const _default$2: <T = Record<string, unknown>, C extends React$1.ElementType = "form">(props: FormProps<T, C>) => JSX.Element | null;
/**
 * Options controlling how the form scrolls to the first invalid field on
 * a failed submit.
 */
export type JfvScrollOptions = {
	offset?: number;
	align?: "top" | "middle" | "bottom" | (string & {});
	duration?: number;
	ease?: string;
};
/**
 * Base props of `<Form>` — the validation-specific props the component
 * handles itself. The public, polymorphic `FormProps<T, C>` 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<string, unknown>;
	throttleDuration?: number;
	errorMessages?: ErrorMessagesMap;
	onChange?: ((data: Record<string, unknown>, event?: FormChangeEvent) => void) | null;
	onSubmit: (event: React$1.FormEvent) => void;
	schema: JSONSchema7Definition;
	scrollToError?: boolean;
	scrollOptions?: JfvScrollOptions;
};
/**
 * Polymorphic props of `<Form>`. Two type parameters:
 * - `T` — shape of the form data. Inferred from `data` / `onChange`, or
 *         you can pass it explicitly via `<Form<UserData> …>`. Default
 *         `Record<string, unknown>`. 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 `<Form>` (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.
 * - `errorMessages` — map of error messages shared by every `<FieldError>`
 *                     descendant (see `ErrorMessagesMap`).
 * - `ajv`           — optional pre-configured AJV instance, useful to plug
 *                     in custom keywords/formats.
 * - `component`     — element rendered for the form wrapper (default `<form noValidate>`).
 */
export type FormProps<T = Record<string, unknown>, C extends React$1.ElementType = "form"> = (Omit<FormBaseProps, "component" | "data" | "onChange"> & {
	component?: C;
	data?: T;
	onChange?: ((data: T, event?: FormChangeEvent) => void) | null;
} & SafePropsOmit<React$1.ComponentProps<C>, keyof FormBaseProps | "ref">);
export function useFormContext(): FormContextValue;
export function withFormContext<T>(cb: (ctx: FormContextValue) => T): React$1.ReactElement;
/**
 * @import { ReactElement } from 'react'
 * @import { FormContextValue } from './Context.types'
 */
/**
 * React context that carries the `<Form>` state down to descendant
 * `<Field>` and `<FieldError>` 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<FormContextValue | undefined>;

export {
	_default as Field,
	_default$1 as FieldError,
	_default$2 as Form,
	_default$2 as default,
};

export {};
