diff options
Diffstat (limited to 'packages/exchange-backoffice-ui/src/forms/FormProvider.tsx')
-rw-r--r-- | packages/exchange-backoffice-ui/src/forms/FormProvider.tsx | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/packages/exchange-backoffice-ui/src/forms/FormProvider.tsx b/packages/exchange-backoffice-ui/src/forms/FormProvider.tsx new file mode 100644 index 000000000..c9b6783e6 --- /dev/null +++ b/packages/exchange-backoffice-ui/src/forms/FormProvider.tsx @@ -0,0 +1,54 @@ +import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util"; +import { ComponentChildren, VNode, createContext, h } from "preact"; +import { StateUpdater, useMemo } from "preact/hooks"; + +export interface FormType<T> { + initialValue: Partial<T>; + value: Partial<T>; + onUpdate: StateUpdater<T>; + computeFormState?: (v: T) => FormState<T>; +} + +//@ts-ignore +export const FormContext = createContext<FormType<any>>({}); + +type FormState<T> = { + [field in keyof T]?: T[field] extends AbsoluteTime + ? Partial<InputFieldState> + : T[field] extends object + ? 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 function FormProvider<T>({ + children, + state, + computeFormState, +}: { + state: [Partial<T>, StateUpdater<T>]; + computeFormState?: (v: T) => FormState<T>; + children: ComponentChildren; +}): VNode { + const [value, onUpdate] = state; + const initialValue = useMemo(() => value, []); + const contextValue = useMemo( + () => ({ initialValue, value, onUpdate, computeFormState }), + [value, onUpdate, computeFormState], + ); + return ( + <FormContext.Provider value={contextValue}> + <form>{children}</form> + </FormContext.Provider> + ); +} |