summaryrefslogtreecommitdiff
path: root/packages/web-util/src/forms/FormProvider.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/web-util/src/forms/FormProvider.tsx')
-rw-r--r--packages/web-util/src/forms/FormProvider.tsx48
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) => {