import type { Token } from '@furystack/inject';
import type { ChildrenList, PartialElement } from '@furystack/shades';
import { ObservableValue } from '@furystack/utils';
import type { InputValidationResult } from './inputs/input.js';
type UnknownFormValidationResult = {
    isValid: null;
};
type ValidFormValidationResult = {
    isValid: true;
};
type InvalidFormValidationResult = {
    isValid: false;
    reason: 'validation-failed' | 'input-validation-failed' | 'unknown';
};
type FormValidationResult = ValidFormValidationResult | InvalidFormValidationResult | UnknownFormValidationResult;
/**
 * Per-form state shared between the `<Form>` host and its child inputs.
 */
export interface FormService<T = unknown> extends Disposable {
    readonly validatedFormData: ObservableValue<T | null>;
    readonly rawFormData: ObservableValue<{
        [k: string]: FormDataEntryValue;
    } | null>;
    readonly validationResult: ObservableValue<FormValidationResult>;
    readonly fieldErrors: ObservableValue<{
        [K in string]?: {
            validationResult: InputValidationResult;
            validity: ValidityState;
        };
    }>;
    readonly inputs: Set<HTMLInputElement>;
    readonly isSubmitting: ObservableValue<boolean>;
    readonly submitError: ObservableValue<unknown>;
    setFieldState(key: keyof T, validationResult: InputValidationResult, validity: ValidityState): void;
}
/**
 * Creates a fresh {@link FormService} instance. Called by `<Form>` to populate
 * the `FormContextToken` on the form's child scope so descendant inputs can
 * discover it.
 */
export declare const createFormService: <T>() => FormService<T>;
/**
 * Scoped token used by `<Form>` to publish a {@link FormService} instance to
 * descendant inputs. Defaults to `null` so inputs rendered outside a `<Form>`
 * can gracefully skip form integration.
 */
export declare const FormContextToken: Token<FormService | null, 'scoped'>;
type FormProps<T> = {
    onSubmit: (formData: T) => void | Promise<void>;
    onReset?: () => void;
    validate: (formData: unknown) => formData is T;
    disableOnSubmit?: boolean;
} & PartialElement<Omit<HTMLFormElement, 'onsubmit' | 'onchange' | 'onreset'>>;
export declare const Form: <T>(props: FormProps<T>, children: ChildrenList) => JSX.Element;
export {};
//# sourceMappingURL=form.d.ts.map