summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-01-02 17:56:42 -0300
committerSebastian <sebasjm@gmail.com>2024-01-02 17:56:42 -0300
commit609ad091e332e4150b4d472284e5a9518cbe7571 (patch)
treed5b8af748a1d6efa1e26c0ff6ea1f9ee89172a6e
parentf0046ec557bf8d52aaf5cb13cf03ab98450adc0a (diff)
downloadwallet-core-609ad091e332e4150b4d472284e5a9518cbe7571.tar.gz
wallet-core-609ad091e332e4150b4d472284e5a9518cbe7571.tar.bz2
wallet-core-609ad091e332e4150b4d472284e5a9518cbe7571.zip
sort for documentation
-rw-r--r--packages/aml-backoffice-ui/src/pages/Cases.tsx2
-rw-r--r--packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx1
-rw-r--r--packages/demobank-ui/src/forms/simplest.ts2
-rw-r--r--packages/web-util/src/forms/DefaultForm.tsx47
-rw-r--r--packages/web-util/src/forms/FormProvider.tsx94
-rw-r--r--packages/web-util/src/forms/InputAbsoluteTime.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputAbsoluteTime.tsx10
-rw-r--r--packages/web-util/src/forms/InputAmount.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputAmount.tsx2
-rw-r--r--packages/web-util/src/forms/InputArray.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputArray.tsx2
-rw-r--r--packages/web-util/src/forms/InputChoiceHorizontal.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputChoiceHorizontal.tsx2
-rw-r--r--packages/web-util/src/forms/InputChoiceStacked.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputChoiceStacked.tsx2
-rw-r--r--packages/web-util/src/forms/InputFile.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputFile.tsx2
-rw-r--r--packages/web-util/src/forms/InputInteger.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputLine.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputLine.tsx2
-rw-r--r--packages/web-util/src/forms/InputSelectMultiple.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputSelectMultiple.tsx4
-rw-r--r--packages/web-util/src/forms/InputSelectOne.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputText.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputText.tsx2
-rw-r--r--packages/web-util/src/forms/InputTextArea.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputToggle.stories.tsx2
-rw-r--r--packages/web-util/src/forms/InputToggle.tsx2
-rw-r--r--packages/web-util/src/forms/forms.ts41
-rw-r--r--packages/web-util/src/forms/useField.ts8
30 files changed, 136 insertions, 115 deletions
diff --git a/packages/aml-backoffice-ui/src/pages/Cases.tsx b/packages/aml-backoffice-ui/src/pages/Cases.tsx
index 3d3d7b49b..7161e4086 100644
--- a/packages/aml-backoffice-ui/src/pages/Cases.tsx
+++ b/packages/aml-backoffice-ui/src/pages/Cases.tsx
@@ -30,7 +30,7 @@ export function CasesUI({ records, filter, onChangeFilter, onFirstPage, onNext }
</div>
<div class="px-2">
<form.Provider
- initialValue={{ state: filter }}
+ initial={{ state: filter }}
onUpdate={(v) => {
onChangeFilter(v.state ?? filter);
}}
diff --git a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
index 46563f702..cd801256a 100644
--- a/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
+++ b/packages/aml-backoffice-ui/src/pages/UnlockAccount.tsx
@@ -29,7 +29,6 @@ export function UnlockAccount({
<div class="mt-10 sm:mx-auto sm:w-full sm:max-w-[480px] ">
<div class="bg-gray-100 px-6 py-6 shadow sm:rounded-lg sm:px-12">
<Form.Provider
- initialValue={{}}
onSubmit={async (v) => {
try {
await onAccountUnlocked(v.password!);
diff --git a/packages/demobank-ui/src/forms/simplest.ts b/packages/demobank-ui/src/forms/simplest.ts
index 54b6b1c65..38211b681 100644
--- a/packages/demobank-ui/src/forms/simplest.ts
+++ b/packages/demobank-ui/src/forms/simplest.ts
@@ -34,7 +34,7 @@ const design: DoubleColumnForm = [
description: `Current state is and threshold at ` as TranslatedString,
fields: [
{
- type: "date",
+ type: "absoluteTime",
props: {
name: "when",
label: "Decision Time" as TranslatedString,
diff --git a/packages/web-util/src/forms/DefaultForm.tsx b/packages/web-util/src/forms/DefaultForm.tsx
index ffd2812da..1155401f5 100644
--- a/packages/web-util/src/forms/DefaultForm.tsx
+++ b/packages/web-util/src/forms/DefaultForm.tsx
@@ -1,7 +1,37 @@
-import { ComponentChildren, Fragment, h } from "preact";
-import { FormProvider } from "./FormProvider.js";
-import { FlexibleForm, RenderAllFieldsByUiConfig } from "./forms.js";
+import { Fragment, h } from "preact";
+import { FormProvider, FormProviderProps, FormState } from "./FormProvider.js";
+import { RenderAllFieldsByUiConfig, UIFormField } from "./forms.js";
+import { TranslatedString } from "@gnu-taler/taler-util";
+/**
+ * Flexible form uses a DoubleColumForm for design
+ * and may have a dynamic properties defined by
+ * behavior function.
+ */
+export interface FlexibleForm<T extends object> {
+ design: DoubleColumnForm;
+ behavior?: (form: Partial<T>) => FormState<T>;
+}
+
+/**
+ * Double column form
+ *
+ * Form with sections, every sections have a title and may
+ * have a description.
+ * Every sections contain a set of fields.
+ */
+export type DoubleColumnForm = Array<DoubleColumnFormSection | undefined>;
+
+export type DoubleColumnFormSection = {
+ title: TranslatedString;
+ description?: TranslatedString;
+ fields: UIFormField[];
+};
+
+/**
+ * Form Provider implementation that use FlexibleForm
+ * to defined behavior and fields.
+ */
export function DefaultForm<T extends object>({
initial,
onUpdate,
@@ -9,17 +39,10 @@ export function DefaultForm<T extends object>({
onSubmit,
children,
readOnly,
-}: {
- children?: ComponentChildren;
- initial: Partial<T>;
- onSubmit?: (v: Partial<T>) => void;
- form: FlexibleForm<T>;
- readOnly?: boolean;
- onUpdate?: (d: Partial<T>) => void;
-}) {
+}: Omit<FormProviderProps<T>, "computeFormState"> & { form: FlexibleForm<T> }) {
return (
<FormProvider
- initialValue={initial}
+ initial={initial}
onUpdate={onUpdate}
onSubmit={onSubmit}
readOnly={readOnly}
diff --git a/packages/web-util/src/forms/FormProvider.tsx b/packages/web-util/src/forms/FormProvider.tsx
index b9f9f7832..f4616525b 100644
--- a/packages/web-util/src/forms/FormProvider.tsx
+++ b/packages/web-util/src/forms/FormProvider.tsx
@@ -6,23 +6,22 @@ import {
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>;
+ initial?: Partial<T>;
readOnly?: boolean;
- onUpdate?: StateUpdater<T>;
- computeFormState?: (v: T) => FormState<T>;
+ onUpdate?: (v: Partial<T>) => void;
+ computeFormState?: (v: Partial<T>) => FormState<T>;
}
//@ts-ignore
export const FormContext = createContext<FormType<any>>({});
/**
- * Map of {[field]:BehaviorResult}
+ * Map of {[field]:FieldUIOptions}
* for every field of type
* - any native (string, number, etc...)
* - absoluteTime
@@ -34,27 +33,53 @@ export const FormContext = createContext<FormType<any>>({});
*/
export type FormState<T extends object | undefined> = {
[field in keyof T]?: T[field] extends AbsoluteTime
- ? BehaviorResult
+ ? FieldUIOptions
: T[field] extends AmountJson
- ? BehaviorResult
+ ? FieldUIOptions
: T[field] extends Array<infer P extends object>
? InputArrayFieldState<P>
: T[field] extends (object | undefined)
? FormState<T[field]>
- : BehaviorResult;
+ : FieldUIOptions;
};
-export type BehaviorResult = Partial<InputFieldState> & FieldUIOptions
-
-export interface InputFieldState {
- /* should show the error */
+/**
+ * Properties that can be defined by design or by computing state
+ */
+export type FieldUIOptions = {
+ /* text to be shown next to the field */
error?: TranslatedString;
- /* should not allow to edit */
- readonly: boolean;
- /* should show as disable */
- disabled: boolean;
+ /* instruction to be shown in the field */
+ placeholder?: TranslatedString;
+ /* long text help to be shown on demand */
+ tooltip?: TranslatedString;
+ /* short text to be shown next to the field*/
+
+ help?: TranslatedString;
+ /* should show as disabled and readonly */
+ disabled?: boolean;
/* should not show */
- hidden: boolean;
+ hidden?: boolean;
+
+ /* 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 {
+
+ // property name of the object
+ name: K;
+
+ // label if the field
+ label: TranslatedString;
+ before?: Addon;
+ after?: Addon;
+
+ // converter to string and back
+ converter?: StringConverter<T[K]>;
}
export interface IconAddon {
@@ -77,42 +102,25 @@ export interface StringConverter<T> {
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 FieldUIOptions {
+ elements?: FormState<P>[];
}
-export interface InputArrayFieldState<P extends object> extends BehaviorResult {
- elements?: FormState<P>[];
+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,
- initialValue,
+ initial,
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 {
+}: FormProviderProps<T>): VNode {
- const [state, setState] = useState<Partial<T>>(initialValue ?? {});
+ const [state, setState] = useState<Partial<T>>(initial ?? {});
const value = { current: state };
const onUpdate = (v: typeof state) => {
setState(v);
@@ -120,7 +128,7 @@ export function FormProvider<T extends object>({
};
return (
<FormContext.Provider
- value={{ initialValue, value, onUpdate, computeFormState, readOnly }}
+ value={{ initial, value, onUpdate, computeFormState, readOnly }}
>
<form
onSubmit={(e) => {
diff --git a/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx b/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx
index d146d20bf..6245cf27c 100644
--- a/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx
+++ b/packages/web-util/src/forms/InputAbsoluteTime.stories.tsx
@@ -22,9 +22,9 @@
import { AbsoluteTime, TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Absolute Time",
diff --git a/packages/web-util/src/forms/InputAbsoluteTime.tsx b/packages/web-util/src/forms/InputAbsoluteTime.tsx
index 0e03c5595..ee18e5592 100644
--- a/packages/web-util/src/forms/InputAbsoluteTime.tsx
+++ b/packages/web-util/src/forms/InputAbsoluteTime.tsx
@@ -13,7 +13,7 @@ export function InputAbsoluteTime<T extends object, K extends keyof T>(
props: { pattern?: string } & UIFormProps<T, K>,
): VNode {
const pattern = props.pattern ?? "dd/MM/yyyy";
- const [open, setOpen] = useState(true)
+ const [open, setOpen] = useState(false)
const { value, onChange } = useField<T, K>(props.name);
return (
<Fragment>
@@ -53,7 +53,7 @@ export function InputAbsoluteTime<T extends object, K extends keyof T>(
}}
{...props}
/>
- {/* {open &&
+ {open &&
<Dialog onClose={() => setOpen(false)}>
<Calendar value={value as AbsoluteTime ?? AbsoluteTime.now()}
onChange={(v) => {
@@ -61,8 +61,8 @@ export function InputAbsoluteTime<T extends object, K extends keyof T>(
setOpen(false)
}} />
</Dialog>
- } */}
- {open &&
+ }
+ {/* {open &&
<Dialog onClose={() => setOpen(false)} >
<TimePicker value={value as AbsoluteTime ?? AbsoluteTime.now()}
onChange={(v) => {
@@ -71,7 +71,7 @@ export function InputAbsoluteTime<T extends object, K extends keyof T>(
onConfirm={() => {
setOpen(false)
}} />
- </Dialog>}
+ </Dialog>} */}
</Fragment>
);
}
diff --git a/packages/web-util/src/forms/InputAmount.stories.tsx b/packages/web-util/src/forms/InputAmount.stories.tsx
index d6dd9387a..c9f12a437 100644
--- a/packages/web-util/src/forms/InputAmount.stories.tsx
+++ b/packages/web-util/src/forms/InputAmount.stories.tsx
@@ -22,9 +22,9 @@
import { AmountJson, Amounts, TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Amount",
diff --git a/packages/web-util/src/forms/InputAmount.tsx b/packages/web-util/src/forms/InputAmount.tsx
index 29ec43525..7a8c08f76 100644
--- a/packages/web-util/src/forms/InputAmount.tsx
+++ b/packages/web-util/src/forms/InputAmount.tsx
@@ -1,8 +1,8 @@
import { AmountJson, Amounts, TranslatedString } from "@gnu-taler/taler-util";
import { VNode, h } from "preact";
+import { UIFormProps } from "./FormProvider.js";
import { InputLine } from "./InputLine.js";
import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
export function InputAmount<T extends object, K extends keyof T>(
props: { currency?: string } & UIFormProps<T, K>,
diff --git a/packages/web-util/src/forms/InputArray.stories.tsx b/packages/web-util/src/forms/InputArray.stories.tsx
index c44789c37..8dbd3ff07 100644
--- a/packages/web-util/src/forms/InputArray.stories.tsx
+++ b/packages/web-util/src/forms/InputArray.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Array",
diff --git a/packages/web-util/src/forms/InputArray.tsx b/packages/web-util/src/forms/InputArray.tsx
index 38c399e66..7d9a1b378 100644
--- a/packages/web-util/src/forms/InputArray.tsx
+++ b/packages/web-util/src/forms/InputArray.tsx
@@ -132,7 +132,7 @@ export function InputArray<T extends object, K extends keyof T>(
* Consider creating an InnerFormProvider since not every feature is expected
*/
<FormProvider
- initialValue={selected}
+ initial={selected}
readOnly={state.disabled}
computeFormState={(v) => {
// current state is ignored
diff --git a/packages/web-util/src/forms/InputChoiceHorizontal.stories.tsx b/packages/web-util/src/forms/InputChoiceHorizontal.stories.tsx
index a1c60e44a..2907a4dab 100644
--- a/packages/web-util/src/forms/InputChoiceHorizontal.stories.tsx
+++ b/packages/web-util/src/forms/InputChoiceHorizontal.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Choice Horizontal",
diff --git a/packages/web-util/src/forms/InputChoiceHorizontal.tsx b/packages/web-util/src/forms/InputChoiceHorizontal.tsx
index b490a2c25..778b73c75 100644
--- a/packages/web-util/src/forms/InputChoiceHorizontal.tsx
+++ b/packages/web-util/src/forms/InputChoiceHorizontal.tsx
@@ -1,8 +1,8 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, VNode, h } from "preact";
+import { UIFormProps } from "./FormProvider.js";
import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
export interface ChoiceH<V> {
label: TranslatedString;
diff --git a/packages/web-util/src/forms/InputChoiceStacked.stories.tsx b/packages/web-util/src/forms/InputChoiceStacked.stories.tsx
index 11816ed98..54228934e 100644
--- a/packages/web-util/src/forms/InputChoiceStacked.stories.tsx
+++ b/packages/web-util/src/forms/InputChoiceStacked.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Choice Stacked",
diff --git a/packages/web-util/src/forms/InputChoiceStacked.tsx b/packages/web-util/src/forms/InputChoiceStacked.tsx
index e49b87800..234bb2255 100644
--- a/packages/web-util/src/forms/InputChoiceStacked.tsx
+++ b/packages/web-util/src/forms/InputChoiceStacked.tsx
@@ -1,8 +1,8 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, VNode, h } from "preact";
+import { UIFormProps } from "./FormProvider.js";
import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
import { useField } from "./useField.js";
-import { UIFormProps } from "./FormProvider.js";
export interface ChoiceS<V> {
label: TranslatedString;
diff --git a/packages/web-util/src/forms/InputFile.stories.tsx b/packages/web-util/src/forms/InputFile.stories.tsx
index 6779977b6..ba06debf9 100644
--- a/packages/web-util/src/forms/InputFile.stories.tsx
+++ b/packages/web-util/src/forms/InputFile.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input File",
diff --git a/packages/web-util/src/forms/InputFile.tsx b/packages/web-util/src/forms/InputFile.tsx
index bc460f370..6337d0902 100644
--- a/packages/web-util/src/forms/InputFile.tsx
+++ b/packages/web-util/src/forms/InputFile.tsx
@@ -1,7 +1,7 @@
import { Fragment, VNode, h } from "preact";
+import { UIFormProps } from "./FormProvider.js";
import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
import { useField } from "./useField.js";
-import { UIFormProps, BehaviorResult } from "./FormProvider.js";
export function InputFile<T extends object, K extends keyof T>(
props: { maxBites: number; accept?: string } & UIFormProps<T, K>,
diff --git a/packages/web-util/src/forms/InputInteger.stories.tsx b/packages/web-util/src/forms/InputInteger.stories.tsx
index f3bdfc500..bd1a467ab 100644
--- a/packages/web-util/src/forms/InputInteger.stories.tsx
+++ b/packages/web-util/src/forms/InputInteger.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Integer",
diff --git a/packages/web-util/src/forms/InputLine.stories.tsx b/packages/web-util/src/forms/InputLine.stories.tsx
index d048aa05a..da41a221e 100644
--- a/packages/web-util/src/forms/InputLine.stories.tsx
+++ b/packages/web-util/src/forms/InputLine.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Line",
diff --git a/packages/web-util/src/forms/InputLine.tsx b/packages/web-util/src/forms/InputLine.tsx
index 8c44b1ca5..b8879f9ec 100644
--- a/packages/web-util/src/forms/InputLine.tsx
+++ b/packages/web-util/src/forms/InputLine.tsx
@@ -1,8 +1,8 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import { ComponentChildren, Fragment, VNode, h } from "preact";
-import { useField } from "./useField.js";
import { useEffect, useState } from "preact/hooks";
import { UIFormProps } from "./FormProvider.js";
+import { useField } from "./useField.js";
//@ts-ignore
const TooltipIcon = (
diff --git a/packages/web-util/src/forms/InputSelectMultiple.stories.tsx b/packages/web-util/src/forms/InputSelectMultiple.stories.tsx
index 7fdc7fca5..6ce5445c0 100644
--- a/packages/web-util/src/forms/InputSelectMultiple.stories.tsx
+++ b/packages/web-util/src/forms/InputSelectMultiple.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Select Multiple",
diff --git a/packages/web-util/src/forms/InputSelectMultiple.tsx b/packages/web-util/src/forms/InputSelectMultiple.tsx
index a721eadce..a67eb23b7 100644
--- a/packages/web-util/src/forms/InputSelectMultiple.tsx
+++ b/packages/web-util/src/forms/InputSelectMultiple.tsx
@@ -1,9 +1,9 @@
import { Fragment, VNode, h } from "preact";
+import { useState } from "preact/hooks";
+import { UIFormProps } from "./FormProvider.js";
import { ChoiceS } from "./InputChoiceStacked.js";
import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
import { useField } from "./useField.js";
-import { useState } from "preact/hooks";
-import { UIFormProps } from "./FormProvider.js";
export function InputSelectMultiple<T extends object, K extends keyof T>(
props: {
diff --git a/packages/web-util/src/forms/InputSelectOne.stories.tsx b/packages/web-util/src/forms/InputSelectOne.stories.tsx
index acf2d0c8f..9e9029a77 100644
--- a/packages/web-util/src/forms/InputSelectOne.stories.tsx
+++ b/packages/web-util/src/forms/InputSelectOne.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Select One",
diff --git a/packages/web-util/src/forms/InputText.stories.tsx b/packages/web-util/src/forms/InputText.stories.tsx
index 0137b7488..04ab8a1c6 100644
--- a/packages/web-util/src/forms/InputText.stories.tsx
+++ b/packages/web-util/src/forms/InputText.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Text",
diff --git a/packages/web-util/src/forms/InputText.tsx b/packages/web-util/src/forms/InputText.tsx
index 7ad36b737..1c0c04225 100644
--- a/packages/web-util/src/forms/InputText.tsx
+++ b/packages/web-util/src/forms/InputText.tsx
@@ -1,6 +1,6 @@
import { VNode, h } from "preact";
-import { InputLine } from "./InputLine.js";
import { UIFormProps } from "./FormProvider.js";
+import { InputLine } from "./InputLine.js";
export function InputText<T extends object, K extends keyof T>(
props: UIFormProps<T, K>,
diff --git a/packages/web-util/src/forms/InputTextArea.stories.tsx b/packages/web-util/src/forms/InputTextArea.stories.tsx
index 50d659a74..c8c3eb088 100644
--- a/packages/web-util/src/forms/InputTextArea.stories.tsx
+++ b/packages/web-util/src/forms/InputTextArea.stories.tsx
@@ -23,8 +23,8 @@ import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
DefaultForm as TestedComponent,
+ FlexibleForm,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Text Area",
diff --git a/packages/web-util/src/forms/InputToggle.stories.tsx b/packages/web-util/src/forms/InputToggle.stories.tsx
index 005a1d448..ca6857618 100644
--- a/packages/web-util/src/forms/InputToggle.stories.tsx
+++ b/packages/web-util/src/forms/InputToggle.stories.tsx
@@ -22,9 +22,9 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import * as tests from "@gnu-taler/web-util/testing";
import {
+ FlexibleForm,
DefaultForm as TestedComponent,
} from "./DefaultForm.js";
-import { FlexibleForm } from "./forms.js";
export default {
title: "Input Toggle",
diff --git a/packages/web-util/src/forms/InputToggle.tsx b/packages/web-util/src/forms/InputToggle.tsx
index 1ea8699b2..56b29c502 100644
--- a/packages/web-util/src/forms/InputToggle.tsx
+++ b/packages/web-util/src/forms/InputToggle.tsx
@@ -1,6 +1,6 @@
import { VNode, h } from "preact";
-import { InputLine, LabelWithTooltipMaybeRequired } from "./InputLine.js";
import { UIFormProps } from "./FormProvider.js";
+import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
import { useField } from "./useField.js";
export function InputToggle<T extends object, K extends keyof T>(
diff --git a/packages/web-util/src/forms/forms.ts b/packages/web-util/src/forms/forms.ts
index 1c212fafa..3b8620bfb 100644
--- a/packages/web-util/src/forms/forms.ts
+++ b/packages/web-util/src/forms/forms.ts
@@ -1,34 +1,21 @@
-import { TranslatedString } from "@gnu-taler/taler-util";
-import { InputText } from "./InputText.js";
-import { InputAbsoluteTime } from "./InputAbsoluteTime.js";
-import { InputInteger } from "./InputInteger.js";
import { h as create, Fragment, VNode } from "preact";
-import { InputChoiceStacked } from "./InputChoiceStacked.js";
-import { InputArray } from "./InputArray.js";
-import { InputSelectMultiple } from "./InputSelectMultiple.js";
-import { InputTextArea } from "./InputTextArea.js";
-import { InputFile } from "./InputFile.js";
import { Caption } from "./Caption.js";
+import { FormProvider } from "./FormProvider.js";
import { Group } from "./Group.js";
-import { InputSelectOne } from "./InputSelectOne.js";
-import { FormProvider, FormState } from "./FormProvider.js";
-import { InputLine } from "./InputLine.js";
+import { InputAbsoluteTime } from "./InputAbsoluteTime.js";
import { InputAmount } from "./InputAmount.js";
+import { InputArray } from "./InputArray.js";
import { InputChoiceHorizontal } from "./InputChoiceHorizontal.js";
+import { InputChoiceStacked } from "./InputChoiceStacked.js";
+import { InputFile } from "./InputFile.js";
+import { InputInteger } from "./InputInteger.js";
+import { InputLine } from "./InputLine.js";
+import { InputSelectMultiple } from "./InputSelectMultiple.js";
+import { InputSelectOne } from "./InputSelectOne.js";
+import { InputText } from "./InputText.js";
+import { InputTextArea } from "./InputTextArea.js";
import { InputToggle } from "./InputToggle.js";
-export type DoubleColumnForm = Array<DoubleColumnFormSection | undefined>;
-
-export type DoubleColumnFormSection = {
- title: TranslatedString;
- description?: TranslatedString;
- fields: UIFormField[];
-};
-export interface FlexibleForm<T extends object> {
- design: DoubleColumnForm;
- behavior?: (form: Partial<T>) => FormState<T>;
-}
-
/**
* Constrain the type with the ui props
*/
@@ -127,6 +114,12 @@ type FormSet<T extends object> = {
InputLine: <K extends keyof T>() => typeof InputLine<T, K>;
InputChoiceHorizontal: <K extends keyof T>() => typeof InputChoiceHorizontal<T, K>;
};
+
+/**
+ * Helper function that created a typed object.
+ *
+ * @returns
+ */
export function createNewForm<T extends object>() {
const res: FormSet<T> = {
Provider: FormProvider,
diff --git a/packages/web-util/src/forms/useField.ts b/packages/web-util/src/forms/useField.ts
index 651778628..eed8cebea 100644
--- a/packages/web-util/src/forms/useField.ts
+++ b/packages/web-util/src/forms/useField.ts
@@ -1,10 +1,10 @@
import { useContext, useState } from "preact/compat";
-import { BehaviorResult, FormContext, InputFieldState } from "./FormProvider.js";
+import { FieldUIOptions, FormContext } from "./FormProvider.js";
export interface InputFieldHandler<Type> {
value: Type;
onChange: (s: Type) => void;
- state: BehaviorResult;
+ state: FieldUIOptions;
isDirty: boolean;
}
@@ -12,7 +12,6 @@ export function useField<T extends object, K extends keyof T>(
name: K,
): InputFieldHandler<T[K]> {
const {
- initialValue,
value: formValue,
computeFormState,
onUpdate: notifyUpdate,
@@ -27,12 +26,11 @@ export function useField<T extends object, K extends keyof T>(
// console.log("USE FIELD", String(name), formValue.current, fieldValue);
const [currentValue, setCurrentValue] = useState<any | undefined>(fieldValue);
const fieldState =
- readField<Partial<BehaviorResult>>(formState, String(name)) ?? {};
+ readField<Partial<FieldUIOptions>>(formState, String(name)) ?? {};
//compute default state
const state = {
disabled: readOnlyForm ? true : (fieldState.disabled ?? false),
- readonly: readOnlyForm ? true : (fieldState.readonly ?? false),
hidden: fieldState.hidden ?? false,
error: fieldState.error,
help: fieldState.help,