import type * as React from 'react'; import type { FieldCharacterCountOptions, FieldMode, FieldSnapshot, FieldValidator } from '../utils/field-core.js'; import type { PolymorphicTag, PrimitivePropsWithRef } from '../utils/primitive.js'; export type { FieldCharacterCountOptions, FieldMode, FieldValidationResult, FieldValidator, } from '../utils/field-core.js'; /** The state a `Field` reports through {@link FieldOwnProps.onValidityChange}. */ export type FieldValidityDetail = Omit; /** Imperative Field contract for programmatic validation and reset. */ export interface FieldValidateHandle { /** Runs validation now, covering server errors, custom validation, native constraints, and character count. */ checkValidity(): Promise; /** Clears messages and touched/dirty state, and re-derives filled/count from the control. */ reset(): void; } /** What {@link Field}'s forwarded ref carries: the root `
` plus the validate handle's methods. */ export type FieldHandle = HTMLDivElement & FieldValidateHandle; /** What {@link Fieldset}'s forwarded ref carries: the `
` plus the validate handle's methods. */ export type FieldsetHandle = FieldValidateHandle & HTMLFieldSetElement; /** The validation-model props shared by {@link FieldProps} and {@link FieldsetProps}. */ export interface FieldOwnProps { /** * Validator for this field; may be async, returning a message (or none) for the current value. * @default undefined — only the `errors` prop and native constraint validation produce messages. */ validate?: FieldValidator | undefined; /** * When validation first runs; a field that has already failed re-validates on every input. * @default 'blur' */ mode?: FieldMode | undefined; /** * Server-injected errors, always shown and listed before anything `validate` produces. * @default undefined */ errors?: string | string[] | undefined; /** * Value handed to `validate`; omitted, the Field reads the wrapped control's `checked`/`value` instead. * @default undefined — read from the control. */ value?: unknown; /** * Field name, used as the `FormErrorSummary` link text when no `FieldError` is rendered. * @default undefined */ name?: string | undefined; /** * Whether an answer is mandatory, reflected as native `required` or `aria-required="true"` on the control. * @default false */ required?: boolean | undefined; /** * Whether the field is unavailable, applied as native `disabled` or `aria-disabled="true"` and mirrored as `data-disabled`. * @default false */ disabled?: boolean | undefined; /** * Fires whenever the field's validity or interaction state changes. * @default undefined */ onValidityChange?: ((detail: FieldValidityDetail) => void) | undefined; /** * Words all character-count copy: rendered text, announced message, and over-limit error. * @default undefined */ getCharacterCountMessage?: ((remaining: number) => string) | undefined; /** * Message shown when the control fails native constraint validation with no message of its own. * @default undefined — 'This field is invalid.' */ invalidMessage?: string | undefined; /** * Milliseconds `mode="change"` waits after the last keystroke before validating; a blur runs it immediately. * @default 0 — no debounce. */ validationDebounceTime?: number | undefined; /** * Spacing rung the skin packs the field by, mirrored to `data-density`. * @default undefined — the skin's own default spacing. */ density?: 'compact' | (string & {}) | undefined; } /** Props for {@link FieldRoot}: {@link FieldProps} minus the derived-anatomy-only props. */ export type FieldRootProps = Omit & Pick, 'asChild'>; /** Props for {@link Field}, which wires one control to its label, description and error text. */ export interface FieldProps extends Omit, 'value' | 'asChild'>, FieldOwnProps { /** * The control's label, rendered into a derived `FieldLabel` whose `htmlFor` points at the found control. * @default undefined — no label is rendered, and the control is unnamed. */ label?: React.ReactNode | undefined; /** * Help text, rendered into a derived `FieldDescription` joined to the control's `aria-describedby`. * @default undefined — no description is rendered. */ description?: React.ReactNode | undefined; } /** Props for {@link Fieldset}, a {@link FieldRoot} that groups several controls under a ``. */ export interface FieldsetProps extends Omit, 'value' | 'name'>, FieldOwnProps { /** * Derives the first legend; omit when composing FieldLabel manually. * @default undefined */ legend?: React.ReactNode | undefined; } /** Props for {@link FieldLabel}, which renders a `