commit e2a7155e272d9e9284dee4415efb43094fd6940a
parent ef19fee60819f26f50056d495c352354523c4281
Author: Florian Dold <florian@dold.me>
Date: Fri, 21 Mar 2025 16:58:03 +0100
forms: use computed hiden state
Diffstat:
4 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/packages/web-util/src/forms/FormProvider.tsx b/packages/web-util/src/forms/FormProvider.tsx
@@ -1,10 +1,6 @@
-import {
- AbsoluteTime,
- AmountJson,
- TranslatedString,
-} from "@gnu-taler/taler-util";
-import { ComponentChildren, VNode, createContext, h } from "preact";
-import { MutableRef, useState } from "preact/hooks";
+import { TranslatedString } from "@gnu-taler/taler-util";
+import { ComponentChildren, VNode, createContext } from "preact";
+import { MutableRef } from "preact/hooks";
export interface FormType<T extends object> {
value: MutableRef<Partial<T>>;
@@ -59,7 +55,10 @@ export interface UIFormProps<T extends object, K extends keyof T> {
hidden?: boolean;
/* should start with focus */
focus?: boolean;
- /* show a mark as required*/
+
+ /**
+ * show a mark as required
+ */
required?: boolean;
// label if the field
@@ -78,7 +77,14 @@ export type UIFieldHandler<T = any> = {
onChange: (s: T) => void;
// state: FieldUIOptions;
error?: TranslatedString;
+
+ /**
+ * Root result of the form.
+ */
parentRef?: any;
+ computedProperties: {
+ hidden?: boolean;
+ };
};
export interface IconAddon {
diff --git a/packages/web-util/src/forms/forms-ui.tsx b/packages/web-util/src/forms/forms-ui.tsx
@@ -103,7 +103,11 @@ export function DoubleColumnFormSectionUI<T>({
const { i18n } = useTranslationContext();
const fs = convertFormConfigToUiField(i18n, section.fields, handler);
const allHidden = fs.every((v) => {
- return "hidden" in v.properties && !!v.properties.hidden;
+ // FIXME: Handler should probably be present for all Form UI fields, not just some.
+ if ("handler" in v.properties) {
+ return v.properties.handler?.computedProperties.hidden;
+ }
+ return false;
});
if (allHidden) {
return <RenderAllFieldsByUiConfig key="fields" fields={fs} focus={focus} />;
@@ -133,6 +137,7 @@ export function DoubleColumnFormSectionUI<T>({
</form>
);
}
+
export function SingleColumnFormSectionUI<T>({
fields,
name,
@@ -176,7 +181,16 @@ export function RenderAllFieldsByUiConfig({
const Component = UIFormConfiguration[
field.type
] as FieldComponentFunction<any>;
- const p = { ...field.properties, focus: !!focus && i === 0 };
+ let computedHidden = false;
+ if ("handler" in field.properties) {
+ computedHidden =
+ field.properties.handler?.computedProperties.hidden ?? false;
+ }
+ const p = {
+ ...field.properties,
+ focus: !!focus && i === 0,
+ hidden: computedHidden,
+ };
return <Component key={i} {...p} />;
}),
diff --git a/packages/web-util/src/forms/forms-utils.ts b/packages/web-util/src/forms/forms-utils.ts
@@ -26,6 +26,7 @@ import { format, parse } from "date-fns";
export function convertFormConfigToUiField(
i18n_: InternationalizationAPI,
fieldConfig: UIFormElementConfig[],
+ // FIXME: Clarify types, this is a FormHandler
form: object,
): UIFormField[] {
const result = fieldConfig.map((config) => {
diff --git a/packages/web-util/src/hooks/useForm.ts b/packages/web-util/src/hooks/useForm.ts
@@ -29,8 +29,11 @@ import {
UIFormElementConfig,
useTranslationContext,
} from "../index.browser.js";
-import e from "express";
+/**
+ * T is the type of the form's result content.
+ * Every primitive type is converted to a form handler.
+ */
export type FormHandler<T> = {
[k in keyof T]?: T[k] extends string
? UIFieldHandler
@@ -217,6 +220,9 @@ function checkFormFieldIsValid(
return undefined;
}
+/**
+ * @param formValue Plain, unprocessed form contents.
+ */
function constructFormHandler<T>(
design: FormDesign,
formValue: RecursivePartial<FormValues<T>>,
@@ -270,6 +276,9 @@ function constructFormHandler<T>(
value: currentValue,
onChange: updater,
parentRef: result,
+ computedProperties: {
+ hidden,
+ }
};
// FIXME: handler should not be set but we also need to refactor