diff options
Diffstat (limited to 'packages/web-util/src/forms/FormProvider.tsx')
-rw-r--r-- | packages/web-util/src/forms/FormProvider.tsx | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/packages/web-util/src/forms/FormProvider.tsx b/packages/web-util/src/forms/FormProvider.tsx index f4616525b..5e08efb32 100644 --- a/packages/web-util/src/forms/FormProvider.tsx +++ b/packages/web-util/src/forms/FormProvider.tsx @@ -4,10 +4,7 @@ import { TranslatedString, } from "@gnu-taler/taler-util"; import { ComponentChildren, VNode, createContext, h } from "preact"; -import { - MutableRef, - useState -} from "preact/hooks"; +import { MutableRef, useState } from "preact/hooks"; export interface FormType<T extends object> { value: MutableRef<Partial<T>>; @@ -17,8 +14,7 @@ export interface FormType<T extends object> { computeFormState?: (v: Partial<T>) => FormState<T>; } -//@ts-ignore -export const FormContext = createContext<FormType<any>>({}); +export const FormContext = createContext<FormType<any>| undefined>(undefined); /** * Map of {[field]:FieldUIOptions} @@ -26,29 +22,27 @@ export const FormContext = createContext<FormType<any>>({}); * - any native (string, number, etc...) * - absoluteTime * - amountJson - * - * except for: + * + * 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 - ? FieldUIOptions - : T[field] extends AmountJson - ? FieldUIOptions - : T[field] extends Array<infer P extends object> - ? InputArrayFieldState<P> - : T[field] extends (object | undefined) - ? FormState<T[field]> - : FieldUIOptions; + ? FieldUIOptions + : T[field] extends AmountJson + ? FieldUIOptions + : T[field] extends Array<infer P extends object> + ? InputArrayFieldState<P> + : T[field] extends object | undefined + ? FormState<T[field]> + : FieldUIOptions; }; /** * Properties that can be defined by design or by computing state */ export type FieldUIOptions = { - /* text to be shown next to the field */ - error?: TranslatedString; /* instruction to be shown in the field */ placeholder?: TranslatedString; /* long text help to be shown on demand */ @@ -63,13 +57,13 @@ export type FieldUIOptions = { /* show a mark as required*/ required?: boolean; -} +}; /** * properties only to be defined on design time */ -export interface UIFormProps<T extends object, K extends keyof T> extends FieldUIOptions { - +export interface UIFormProps<T extends object, K extends keyof T> + extends FieldUIOptions { // property name of the object name: K; @@ -80,8 +74,17 @@ export interface UIFormProps<T extends object, K extends keyof T> extends FieldU // converter to string and back converter?: StringConverter<T[K]>; + + handler?: UIFieldHandler; } +export type UIFieldHandler = { + value: string | undefined; + onChange: (s: string) => void; + state: FieldUIOptions; + error?: TranslatedString; +}; + export interface IconAddon { type: "icon"; icon: VNode; @@ -109,7 +112,7 @@ export interface InputArrayFieldState<P extends object> extends FieldUIOptions { export type FormProviderProps<T extends object> = Omit<FormType<T>, "value"> & { onSubmit?: (v: Partial<T>, s: FormState<T> | undefined) => void; children?: ComponentChildren; -} +}; export function FormProvider<T extends object>({ children, @@ -119,7 +122,6 @@ export function FormProvider<T extends object>({ computeFormState, readOnly, }: FormProviderProps<T>): VNode { - const [state, setState] = useState<Partial<T>>(initial ?? {}); const value = { current: state }; const onUpdate = (v: typeof state) => { |