aboutsummaryrefslogtreecommitdiff
path: root/packages/web-util/src
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-05-03 08:43:53 -0300
committerSebastian <sebasjm@gmail.com>2024-05-03 08:44:07 -0300
commit20353eda268efa962959bead466b59823bfb9b29 (patch)
tree868d016693f09b40e2c55893d3aed72eca505ecb /packages/web-util/src
parentfa4c7039f4ebeb6ad3cf19237ad7b138519ac142 (diff)
downloadwallet-core-20353eda268efa962959bead466b59823bfb9b29.tar.xz
form hook now takes the shape of the form (do not rely on initial value)
Diffstat (limited to 'packages/web-util/src')
-rw-r--r--packages/web-util/src/forms/Caption.tsx17
-rw-r--r--packages/web-util/src/forms/Group.tsx38
-rw-r--r--packages/web-util/src/forms/InputAmount.tsx6
-rw-r--r--packages/web-util/src/forms/InputChoiceHorizontal.tsx8
-rw-r--r--packages/web-util/src/forms/InputLine.tsx83
5 files changed, 70 insertions, 82 deletions
diff --git a/packages/web-util/src/forms/Caption.tsx b/packages/web-util/src/forms/Caption.tsx
index 8facddec3..be4725ffa 100644
--- a/packages/web-util/src/forms/Caption.tsx
+++ b/packages/web-util/src/forms/Caption.tsx
@@ -1,27 +1,22 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import { VNode, h } from "preact";
-import {
- LabelWithTooltipMaybeRequired
-} from "./InputLine.js";
+import { LabelWithTooltipMaybeRequired, RenderAddon } from "./InputLine.js";
+import { Addon } from "./FormProvider.js";
interface Props {
label: TranslatedString;
tooltip?: TranslatedString;
help?: TranslatedString;
- before?: VNode;
- after?: VNode;
+ before?: Addon;
+ after?: Addon;
}
export function Caption({ before, after, label, tooltip, help }: Props): VNode {
return (
<div class="sm:col-span-6 flex">
- {before !== undefined && (
- <span class="pointer-events-none flex items-center pr-2">{before}</span>
- )}
+ {before !== undefined && <RenderAddon addon={before} />}
<LabelWithTooltipMaybeRequired label={label} tooltip={tooltip} />
- {after !== undefined && (
- <span class="pointer-events-none flex items-center pl-2">{after}</span>
- )}
+ {after !== undefined && <RenderAddon addon={after} />}
{help && (
<p class="mt-2 text-sm text-gray-500" id="email-description">
{help}
diff --git a/packages/web-util/src/forms/Group.tsx b/packages/web-util/src/forms/Group.tsx
index 0645f6d97..d5626be1d 100644
--- a/packages/web-util/src/forms/Group.tsx
+++ b/packages/web-util/src/forms/Group.tsx
@@ -1,41 +1,39 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import { VNode, h } from "preact";
-import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
+import { LabelWithTooltipMaybeRequired, RenderAddon } from "./InputLine.js";
import { RenderAllFieldsByUiConfig, UIFormField } from "./forms.js";
+import { Addon } from "./FormProvider.js";
interface Props {
- before?: TranslatedString;
- after?: TranslatedString;
- tooltipBefore?: TranslatedString;
- tooltipAfter?: TranslatedString;
+ label: TranslatedString;
+ tooltip?: TranslatedString;
+ help?: TranslatedString;
+ before?: Addon;
+ after?: Addon;
fields: UIFormField[];
}
export function Group({
before,
after,
- tooltipAfter,
- tooltipBefore,
+ label,
+ tooltip,
+ help,
fields,
}: Props): VNode {
return (
<div class="sm:col-span-6 p-4 rounded-lg border-r-2 border-2 bg-gray-50">
- <div class="pb-4">
- {before && (
- <LabelWithTooltipMaybeRequired
- label={before}
- tooltip={tooltipBefore}
- />
- )}
- </div>
+ {before !== undefined && <RenderAddon addon={before} />}
+ <LabelWithTooltipMaybeRequired label={label} tooltip={tooltip} />
+ {after !== undefined && <RenderAddon addon={after} />}
+ {help && (
+ <p class="mt-2 text-sm text-gray-500" id="email-description">
+ {help}
+ </p>
+ )}
<div class="grid max-w-2xl grid-cols-1 gap-x-6 gap-y-2 sm:grid-cols-6">
<RenderAllFieldsByUiConfig fields={fields} />
</div>
- <div class="pt-4">
- {after && (
- <LabelWithTooltipMaybeRequired label={after} tooltip={tooltipAfter} />
- )}
- </div>
</div>
);
}
diff --git a/packages/web-util/src/forms/InputAmount.tsx b/packages/web-util/src/forms/InputAmount.tsx
index 31e83350e..e8683468e 100644
--- a/packages/web-util/src/forms/InputAmount.tsx
+++ b/packages/web-util/src/forms/InputAmount.tsx
@@ -23,15 +23,15 @@ export function InputAmount<T extends object, K extends keyof T>(
type: "text",
text: currency as TranslatedString,
}}
- converter={{
- //@ts-ignore
+ //@ts-ignore
+ converter={ props.converter ?? {
+
fromStringUI: (v): AmountJson => {
return (
Amounts.parse(`${currency}:${v}`) ??
Amounts.zeroOfCurrency(currency)
);
},
- //@ts-ignore
toStringUI: (v: AmountJson) => {
return v === undefined ? "" : Amounts.stringifyValue(v);
},
diff --git a/packages/web-util/src/forms/InputChoiceHorizontal.tsx b/packages/web-util/src/forms/InputChoiceHorizontal.tsx
index 82a7c3115..d8361718d 100644
--- a/packages/web-util/src/forms/InputChoiceHorizontal.tsx
+++ b/packages/web-util/src/forms/InputChoiceHorizontal.tsx
@@ -12,10 +12,10 @@ export interface ChoiceH<V> {
export function InputChoiceHorizontal<T extends object, K extends keyof T>(
props: {
- choices: ChoiceH<T[K]>[];
+ choices: ChoiceH<string>[];
} & UIFormProps<T, K>,
): VNode {
- const { choices, label, tooltip, help, required } = props;
+ const { choices, label, tooltip, help, required, converter } = props;
//FIXME: remove deprecated
const fieldCtx = useField<T, K>(props.name);
const { value, onChange, state } =
@@ -38,7 +38,7 @@ export function InputChoiceHorizontal<T extends object, K extends keyof T>(
const isLast = idx === choices.length - 1;
let clazz =
"relative inline-flex items-center px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 focus:z-10";
- if (choice.value === value) {
+ if (converter?.fromStringUI(choice.value as any) === value) {
clazz +=
" text-white bg-indigo-600 hover:bg-indigo-500 ring-2 ring-indigo-600 hover:ring-indigo-500";
} else {
@@ -61,7 +61,7 @@ export function InputChoiceHorizontal<T extends object, K extends keyof T>(
class={clazz}
onClick={(e) => {
onChange(
- (value === choice.value ? undefined : choice.value) as any,
+ (value === choice.value ? undefined : converter?.fromStringUI(choice.value as any)) as any,
);
}}
>
diff --git a/packages/web-util/src/forms/InputLine.tsx b/packages/web-util/src/forms/InputLine.tsx
index ee9150492..eb3238ef9 100644
--- a/packages/web-util/src/forms/InputLine.tsx
+++ b/packages/web-util/src/forms/InputLine.tsx
@@ -1,6 +1,6 @@
import { TranslatedString } from "@gnu-taler/taler-util";
import { ComponentChildren, Fragment, VNode, h } from "preact";
-import { UIFormProps } from "./FormProvider.js";
+import { Addon, UIFormProps } from "./FormProvider.js";
import { noHandlerPropsAndNoContextForField } from "./InputArray.js";
import { useField } from "./useField.js";
@@ -68,6 +68,37 @@ export function LabelWithTooltipMaybeRequired({
return WithTooltip;
}
+export function RenderAddon({ disabled, addon }: { disabled?: boolean, addon: Addon }): VNode {
+ switch (addon.type) {
+ case "text": {
+ return (
+ <span class="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 px-3 text-gray-500 sm:text-sm">
+ {addon.text}
+ </span>
+ );
+ }
+ case "icon": {
+ return (
+ <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
+ {addon.icon}
+ </div>
+ );
+ }
+ case "button": {
+ return (
+ <button
+ type="button"
+ disabled={disabled}
+ onClick={addon.onClick}
+ class="relative -ml-px inline-flex items-center gap-x-1.5 rounded-l-md px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
+ >
+ {addon.children}
+ </button>
+ );
+ }
+ }
+}
+
function InputWrapper<T extends object, K extends keyof T>({
children,
label,
@@ -91,47 +122,11 @@ function InputWrapper<T extends object, K extends keyof T>({
tooltip={tooltip}
/>
<div class="relative mt-2 flex rounded-md shadow-sm">
- {before &&
- (before.type === "text" ? (
- <span class="inline-flex items-center rounded-l-md border border-r-0 border-gray-300 px-3 text-gray-500 sm:text-sm">
- {before.text}
- </span>
- ) : before.type === "icon" ? (
- <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
- {before.icon}
- </div>
- ) : before.type === "button" ? (
- <button
- type="button"
- disabled={disabled}
- onClick={before.onClick}
- class="relative -ml-px inline-flex items-center gap-x-1.5 rounded-l-md px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
- >
- {before.children}
- </button>
- ) : undefined)}
+ {before && <RenderAddon disabled={disabled} addon={before} />}
{children}
- {after &&
- (after.type === "text" ? (
- <span class="inline-flex items-center rounded-r-md border border-l-0 border-gray-300 px-3 text-gray-500 sm:text-sm">
- {after.text}
- </span>
- ) : after.type === "icon" ? (
- <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
- {after.icon}
- </div>
- ) : after.type === "button" ? (
- <button
- type="button"
- disabled={disabled}
- onClick={after.onClick}
- class="relative -ml-px inline-flex items-center gap-x-1.5 rounded-r-md px-3 py-2 text-sm font-semibold text-gray-900 ring-1 ring-inset ring-gray-300 hover:bg-gray-50"
- >
- {after.children}
- </button>
- ) : undefined)}
+ {after && <RenderAddon disabled={disabled} addon={after} />}
</div>
{error && (
<p class="mt-2 text-sm text-red-600" id="email-error">
@@ -259,13 +254,13 @@ export function InputLine<T extends object, K extends keyof T>(
name={String(name)}
type={type}
onChange={(e) => {
- onChange(e.currentTarget.value as any);
+ onChange(fromString(e.currentTarget.value));
}}
placeholder={placeholder ? placeholder : undefined}
- value={value as string}
- onBlur={() => {
- onChange(fromString(value as any));
- }}
+ value={toString(value) ?? ""}
+ // onBlur={() => {
+ // onChange(fromString(value as any));
+ // }}
// defaultValue={toString(value)}
disabled={state.disabled}
aria-invalid={showError}