diff options
Diffstat (limited to 'packages/aml-backoffice-ui/src/handlers/FormProvider.tsx')
-rw-r--r-- | packages/aml-backoffice-ui/src/handlers/FormProvider.tsx | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/packages/aml-backoffice-ui/src/handlers/FormProvider.tsx b/packages/aml-backoffice-ui/src/handlers/FormProvider.tsx deleted file mode 100644 index b9f9f7832..000000000 --- a/packages/aml-backoffice-ui/src/handlers/FormProvider.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import { - AbsoluteTime, - AmountJson, - TranslatedString, -} from "@gnu-taler/taler-util"; -import { ComponentChildren, VNode, createContext, h } from "preact"; -import { - MutableRef, - StateUpdater, - useState -} from "preact/hooks"; - -export interface FormType<T extends object> { - value: MutableRef<Partial<T>>; - initialValue?: Partial<T>; - readOnly?: boolean; - onUpdate?: StateUpdater<T>; - computeFormState?: (v: T) => FormState<T>; -} - -//@ts-ignore -export const FormContext = createContext<FormType<any>>({}); - -/** - * Map of {[field]:BehaviorResult} - * for every field of type - * - any native (string, number, etc...) - * - absoluteTime - * - amountJson - * - * except for: - * - object => recurse into - * - array => behavior result and element field - */ -export type FormState<T extends object | undefined> = { - [field in keyof T]?: T[field] extends AbsoluteTime - ? BehaviorResult - : T[field] extends AmountJson - ? BehaviorResult - : T[field] extends Array<infer P extends object> - ? InputArrayFieldState<P> - : T[field] extends (object | undefined) - ? FormState<T[field]> - : BehaviorResult; -}; - -export type BehaviorResult = Partial<InputFieldState> & FieldUIOptions - -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 IconAddon { - type: "icon"; - icon: VNode; -} -export interface ButtonAddon { - type: "button"; - onClick: () => void; - children: ComponentChildren; -} -export interface TextAddon { - type: "text"; - text: TranslatedString; -} -export type Addon = IconAddon | ButtonAddon | TextAddon; - -export interface StringConverter<T> { - toStringUI: (v?: T) => string; - fromStringUI: (v?: string) => T; -} - -type FieldUIOptions = { - placeholder?: TranslatedString; - tooltip?: TranslatedString; - help?: TranslatedString; - required?: boolean; -} - -export interface UIFormProps<T extends object, K extends keyof T> extends FieldUIOptions { - name: K; - label: TranslatedString; - before?: Addon; - after?: Addon; - converter?: StringConverter<T[K]>; -} - -export interface InputArrayFieldState<P extends object> extends BehaviorResult { - elements?: FormState<P>[]; -} - -export function FormProvider<T extends object>({ - children, - initialValue, - onUpdate: notify, - onSubmit, - computeFormState, - readOnly, -}: { - initialValue?: Partial<T>; - onUpdate?: (v: Partial<T>) => void; - onSubmit?: (v: Partial<T>, s: FormState<T> | undefined) => void; - computeFormState?: (v: Partial<T>) => FormState<T>; - readOnly?: boolean; - children: ComponentChildren; -}): VNode { - - const [state, setState] = useState<Partial<T>>(initialValue ?? {}); - const value = { current: state }; - const onUpdate = (v: typeof state) => { - setState(v); - if (notify) notify(v); - }; - return ( - <FormContext.Provider - value={{ initialValue, value, onUpdate, computeFormState, readOnly }} - > - <form - onSubmit={(e) => { - e.preventDefault(); - //@ts-ignore - if (onSubmit) - onSubmit( - value.current, - !computeFormState ? undefined : computeFormState(value.current), - ); - }} - > - {children} - </form> - </FormContext.Provider> - ); -} |