@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
56 lines • 2.34 kB
TypeScript
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