UNPKG

@conform-to/dom

Version:

A set of opinionated helpers built on top of the Constraint Validation API

204 lines 7.71 kB
/** * Construct a form data with the submitter value. * It utilizes the submitter argument on the FormData constructor from modern browsers * with fallback to append the submitter value in case it is not unsupported. * * @see https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#parameters */ export declare function getFormData(form: HTMLFormElement, submitter?: HTMLInputElement | HTMLButtonElement | null): FormData; /** * Returns the paths from a name based on the JS syntax convention * @example * ```js * const paths = getPaths('todos[0].content'); // ['todos', 0, 'content'] * ``` */ export declare function getPaths(name: string | undefined): Array<string | number>; /** * Returns a formatted name from the paths based on the JS syntax convention * @example * ```js * const name = formatPaths(['todos', 0, 'content']); // "todos[0].content" * ``` */ export declare function formatPaths(paths: Array<string | number>): string; /** * Format based on a prefix and a path */ export declare function formatName(prefix: string | undefined, path?: string | number): string; /** * Check if a name match the prefix paths */ export declare function isPrefix(name: string, prefix: string): boolean; /** * Compare the parent and child paths to get the relative paths * Returns null if the child paths do not start with the parent paths */ export declare function getChildPaths(parentNameOrPaths: string | Array<string | number>, childName: string): (string | number)[] | null; /** * Assign a value to a target object by following the paths */ export declare function setValue(target: Record<string, any>, name: string, valueFn: (currentValue?: unknown) => unknown): void; /** * Retrive the value from a target object by following the paths */ export declare function getValue(target: unknown, name: string): unknown; /** * Check if the value is a plain object */ export declare function isPlainObject(obj: unknown): obj is Record<string | number | symbol, unknown>; type GlobalConstructors = { [K in keyof typeof globalThis]: (typeof globalThis)[K] extends new (...args: any) => any ? K : never; }[keyof typeof globalThis]; export declare function isGlobalInstance<ClassName extends GlobalConstructors>(obj: unknown, className: ClassName): obj is InstanceType<(typeof globalThis)[ClassName]>; /** * Normalize value by removing empty object or array, empty string and null values */ export declare function normalize<Type extends Record<string, unknown>>(value: Type, acceptFile?: boolean): Type | undefined; export declare function normalize<Type extends Array<unknown>>(value: Type, acceptFile?: boolean): Type | undefined; export declare function normalize(value: unknown, acceptFile?: boolean): unknown | undefined; /** * Flatten a tree into a dictionary */ export declare function flatten(data: unknown, options?: { resolve?: (data: unknown) => unknown; prefix?: string; }): Record<string, unknown>; export declare function deepEqual(left: unknown, right: unknown): boolean; export type JsonPrimitive = string | number | boolean | null; /** * The form value of a submission. This is usually constructed from a FormData or URLSearchParams. * It may contains JSON primitives if the value is updated based on a form intent. */ export type FormValue<Type extends JsonPrimitive | FormDataEntryValue = JsonPrimitive | FormDataEntryValue> = Type | FormValue<Type | null>[] | { [key: string]: FormValue<Type>; }; /** * The data of a form submission. */ export type Submission<ValueType extends FormDataEntryValue = FormDataEntryValue> = { /** * The form value structured following the naming convention. */ value: Record<string, FormValue<ValueType>>; /** * The field names that are included in the FormData or URLSearchParams. */ fields: string[]; /** * The intent of the submission. This is usally included by specifying a name and value on a submit button. */ intent: string | null; }; /** * Parse `FormData` or `URLSearchParams` into a submission object. * This function structures the form values based on the naming convention. * It also includes all the field names and the intent if the `intentName` option is provided. * * @example * ```ts * const formData = new FormData(); * * formData.append('email', 'test@example.com'); * formData.append('password', 'secret'); * * parseSubmission(formData) * // { * // value: { email: 'test@example.com', password: 'secret' }, * // fields: ['email', 'password'], * // intent: null, * // } * * // If you have an intent field * formData.append('intent', 'login'); * parseSubmission(formData, { intentName: 'intent' }) * // { * // value: { email: 'test@example.com', password: 'secret' }, * // fields: ['email', 'password'], * // intent: 'login', * // } * ``` */ export declare function parseSubmission(formData: FormData | URLSearchParams, options?: { /** * The name of the submit button that triggered the form submission. * Used to extract the submission's intent. */ intentName?: string; /** * A filter function that excludes specific entries from being parsed. * Return `true` to skip the entry. */ skipEntry?: (name: string) => boolean; }): Submission; export type ParseSubmissionOptions = Required<Parameters<typeof parseSubmission>>[1]; export declare function defaultSerialize(value: unknown): FormDataEntryValue | undefined; /** * A utility function that checks whether the current form data differs from the default values. * * @see https://conform.guide/api/react/future/isDirty * @example Enable a submit button only if the form is dirty * * ```tsx * const dirty = useFormData( * formRef, * (formData) => isDirty(formData, { defaultValue }) ?? false, * ); * * return ( * <button type="submit" disabled={!dirty}> * Save changes * </button> * ); * ``` */ export declare function isDirty( /** * The current form data to compare. It can be: * * - A `FormData` object * - A `URLSearchParams` object * - A plain object that was parsed from form data (i.e. `submission.payload`) */ formData: FormData | URLSearchParams | FormValue<FormDataEntryValue> | null, options?: { /** * An object representing the default values of the form to compare against. * Defaults to an empty object if not provided. */ defaultValue?: unknown; /** * The name of the submit button that triggered the submission. * It will be excluded from the dirty comparison. */ intentName?: string; /** * A function to serialize values in defaultValue before comparing them to the form data. * If not provided, a default serializer is used that behaves as follows: * * - string / File: * - Returned as-is * - boolean: * - true → 'on' * - false → undefined * - number / bigint: * - Converted to string using `.toString()` * - Date: * - Converted to ISO string using `.toISOString()` */ serialize?: (value: unknown, defaultSerialize: (value: unknown) => FormDataEntryValue | undefined) => FormDataEntryValue | undefined; /** * A function to exclude specific fields from the comparison. * Useful for ignoring hidden inputs like CSRF tokens or internal fields added by frameworks * (e.g. Next.js uses hidden inputs to support server actions). * * @example * ```ts * isDirty(formData, { * skipEntry: (name) => name === 'csrf-token', * }); * ``` */ skipEntry?: (name: string) => boolean; }): boolean | undefined; export {}; //# sourceMappingURL=formdata.d.ts.map