summaryrefslogtreecommitdiff
path: root/packages/exchange-backoffice-ui/src/forms/FormProvider.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/exchange-backoffice-ui/src/forms/FormProvider.tsx')
-rw-r--r--packages/exchange-backoffice-ui/src/forms/FormProvider.tsx54
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>
+ );
+}