pocket-hook-form
Version:
pocket-store base hook form
60 lines (50 loc) • 1.43 kB
text/typescript
// createHookForm.ts
import {useEffect, useMemo} from 'react';
import type {
CreateOptions,
FormState,
FormStoreControl,
FormValue,
} from '../models/type';
import { Store } from 'pocket-state';
type WithController<T extends FormValue> = {
controller: FormStoreControl<T>;
};
type HookOptions<T extends FormValue> = Omit<
Partial<CreateOptions<T>>,
'defaultValues'
> & {defaultValues?: Partial<T>};
type MaybeUpdateOptions<T extends FormValue> = {
updateOptions?: (
next: Partial<CreateOptions<T>>,
behavior?: {resetValues?: boolean},
) => void;
getStoreOptions?: () => CreateOptions<T>;
};
export function createHookForm<T extends FormValue>(
control: FormStoreControl<T> & MaybeUpdateOptions<T>,
) {
const $store = (control as any)._store as Store<FormState<T>>;
function useHookForm(
options?: HookOptions<T>,
): FormStoreControl<T> & WithController<T> {
useEffect(() => {
if (!options) return;
const {defaultValues: nextValue, ...rest} = options;
if (nextValue) {
control.reset(nextValue);
}
control.updateOptions({...rest});
return () => control.reset();
}, []);
return useMemo(
() =>
({
...(control as FormStoreControl<T>),
controller: control as FormStoreControl<T>,
} as FormStoreControl<T> & WithController<T>),
[control, $store],
);
}
return useHookForm;
}