diff options
author | Sebastian <sebasjm@gmail.com> | 2023-09-20 15:16:28 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-09-25 14:50:39 -0300 |
commit | fdbe623e1060efc4b074d213a96e8f5a2ab7498b (patch) | |
tree | 6bbe00f6f36f1910ea99180a6e0d5c53aeb9f34f /packages/web-util/src/forms/FormProvider.tsx | |
parent | a5406c5a5dc437e036168eb068db11d88e05bb0f (diff) | |
download | wallet-core-fdbe623e1060efc4b074d213a96e8f5a2ab7498b.tar.xz |
more ui stuff, moved forms to util
Diffstat (limited to 'packages/web-util/src/forms/FormProvider.tsx')
-rw-r--r-- | packages/web-util/src/forms/FormProvider.tsx | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/packages/web-util/src/forms/FormProvider.tsx b/packages/web-util/src/forms/FormProvider.tsx new file mode 100644 index 000000000..3da2a4f07 --- /dev/null +++ b/packages/web-util/src/forms/FormProvider.tsx @@ -0,0 +1,99 @@ +import { + AbsoluteTime, + AmountJson, + TranslatedString, +} from "@gnu-taler/taler-util"; +import { ComponentChildren, VNode, createContext, h } from "preact"; +import { + MutableRef, + StateUpdater, + useEffect, + useRef, + useState, +} from "preact/hooks"; + +export interface FormType<T> { + value: MutableRef<Partial<T>>; + initialValue?: Partial<T>; + onUpdate?: StateUpdater<T>; + computeFormState?: (v: T) => FormState<T>; +} + +//@ts-ignore +export const FormContext = createContext<FormType<any>>({}); + +export type FormState<T> = { + [field in keyof T]?: T[field] extends AbsoluteTime + ? Partial<InputFieldState> + : T[field] extends AmountJson + ? Partial<InputFieldState> + : T[field] extends Array<infer P> + ? Partial<InputArrayFieldState<P>> + : T[field] extends (object | undefined) + ? FormState<T[field]> + : Partial<InputFieldState>; +}; + +export interface InputFieldState { + /* should show the error */ + error?: TranslatedString; + /* should not allow to edit */ + readonly: boolean; + /* should show as disable */ + disabled: boolean; + /* should not show */ + hidden: boolean; +} + +export interface InputArrayFieldState<T> extends InputFieldState { + elements: FormState<T>[]; +} + +export function FormProvider<T>({ + children, + initialValue, + onUpdate: notify, + onSubmit, + computeFormState, +}: { + initialValue?: Partial<T>; + onUpdate?: (v: Partial<T>) => void; + onSubmit?: (v: Partial<T>, s: FormState<T> | undefined) => void; + computeFormState?: (v: Partial<T>) => FormState<T>; + children: ComponentChildren; +}): VNode { + // const value = useRef(initialValue ?? {}); + // useEffect(() => { + // return function onUnload() { + // value.current = initialValue ?? {}; + // }; + // }); + // const onUpdate = notify + const [state, setState] = useState<Partial<T>>(initialValue ?? {}); + const value = { current: state }; + // console.log("RENDER", initialValue, value); + const onUpdate = (v: typeof state) => { + // console.log("updated"); + setState(v); + if (notify) notify(v); + }; + return ( + <FormContext.Provider + value={{ initialValue, value, onUpdate, computeFormState }} + > + <form + onSubmit={(e) => { + e.preventDefault(); + //@ts-ignore + if (onSubmit) + onSubmit( + value.current, + !computeFormState ? undefined : computeFormState(value.current), + ); + }} + > + {children} + </form> + </FormContext.Provider> + ); +} |