taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 759b941d2431c23ca53792c8af791fe0b0717141
parent 112b0dc323371d11360c7ee3cf6655b0bd66c8d3
Author: Sebastian <sebasjm@taler-systems.com>
Date:   Fri, 27 Feb 2026 10:02:56 -0300

fix #11165

Diffstat:
Mpackages/merchant-backoffice-ui/src/components/SolveMFA.tsx | 1+
Mpackages/merchant-backoffice-ui/src/components/form/Input.tsx | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Mpackages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx | 2+-
Mpackages/merchant-backoffice-ui/src/components/form/InputNumber.tsx | 2+-
Mpackages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx | 17++++++++++++-----
Mpackages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx | 2+-
Mpackages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx | 2+-
7 files changed, 74 insertions(+), 22 deletions(-)

diff --git a/packages/merchant-backoffice-ui/src/components/SolveMFA.tsx b/packages/merchant-backoffice-ui/src/components/SolveMFA.tsx @@ -161,6 +161,7 @@ function SolveChallenge({ focus={focus} readonly={showExpired} dontRemember + inputType="numeric" /> {expiration.t_ms === "never" ? undefined : ( <p> diff --git a/packages/merchant-backoffice-ui/src/components/form/Input.tsx b/packages/merchant-backoffice-ui/src/components/form/Input.tsx @@ -22,8 +22,18 @@ import { ComponentChildren, h, VNode } from "preact"; import { InputProps, useField } from "./useField.js"; import { Tooltip } from "../Tooltip.js"; +export type SupportedTextInputType = + | "text" + | "numeric" + | "decimal" + | "tel" + | "email" + | "url" + | "search" + | "multiline" + | "password"; interface Props<T> extends InputProps<T> { - inputType?: "text" | "number" | "multiline" | "password"; + inputType?: SupportedTextInputType; expand?: boolean; toStr?: (v?: any) => string; fromStr?: (s: string) => any; @@ -47,22 +57,56 @@ export function doAutoFocus<T extends HTMLElement>( const defaultToString = (f?: any): string => f || ""; const defaultFromString = (v: string): any => v as any; -const TextInput = ({ inputType, focus, error, ...rest }: any) => - inputType === "multiline" ? ( - <textarea - {...rest} +export function InternalTextInputSwitch({ + inputType, + focus, + hasError, + ...rest +}: Props<any> & { hasError?: boolean }): VNode { + if (inputType === "multiline") { + return ( + <textarea + {...(rest as any)} + ref={focus ? doAutoFocus : undefined} + class={hasError ? "textarea is-danger" : "textarea"} + rows={3} + /> + ); + } + if (inputType === "numeric" || inputType === "decimal") { + return ( + <input + {...(rest as any)} + ref={focus ? doAutoFocus : undefined} + class={hasError ? "input is-danger" : "input"} + type={"number"} + inputMode={inputType} + /> + ); + } + if ( + inputType === "email" || + inputType === "tel" || + inputType === "search" || + inputType === "url" + ) { + <input + {...(rest as any)} ref={focus ? doAutoFocus : undefined} - class={error ? "textarea is-danger" : "textarea"} - rows="3" - /> - ) : ( + class={hasError ? "input is-danger" : "input"} + type={inputType} + inputMode={inputType} + />; + } + return ( <input - {...rest} + {...(rest as any)} ref={focus ? doAutoFocus : undefined} - class={error ? "input is-danger" : "input"} + class={hasError ? "input is-danger" : "input"} type={inputType} /> ); +} export function Input<T>({ name, @@ -108,8 +152,8 @@ export function Input<T>({ : "control has-icons-right" } > - <TextInput - error={error} + <InternalTextInputSwitch + hasError={error} {...inputExtra} inputType={inputType} placeholder={placeholder} diff --git a/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx b/packages/merchant-backoffice-ui/src/components/form/InputCurrency.tsx @@ -56,7 +56,7 @@ export function InputCurrency<T>({ help={help} tooltip={tooltip} addonAfter={addonAfter} - inputType="number" + inputType="decimal" expand={expand} toStr={(v?: AmountString) => v?.split(":")[1] || ""} fromStr={(v: string) => (!v ? undefined : `${config.currency}:${v}`)} diff --git a/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx b/packages/merchant-backoffice-ui/src/components/form/InputNumber.tsx @@ -46,7 +46,7 @@ export function InputNumber<T>({ readonly={readonly} fromStr={(v) => (!v ? undefined : parseInt(v, 10))} toStr={(v) => `${v}`} - inputType="number" + inputType="numeric" expand={expand} label={label} placeholder={placeholder} diff --git a/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx b/packages/merchant-backoffice-ui/src/components/form/InputWithAddon.tsx @@ -21,10 +21,11 @@ import { ComponentChildren, h, VNode } from "preact"; import { InputProps, useField } from "./useField.js"; import { Tooltip } from "../Tooltip.js"; +import { InternalTextInputSwitch, SupportedTextInputType } from "./Input.js"; export interface Props<T> extends InputProps<T> { expand?: boolean; - inputType?: "text" | "number" | "password"; + inputType?: SupportedTextInputType; addonBefore?: ComponentChildren; addonBeforeLarge?: boolean; addonAfter?: ComponentChildren; @@ -70,7 +71,11 @@ export function InputWithAddon<T>({ * </span> )} - {tooltip && <Tooltip text={tooltip} ><i class="icon mdi mdi-information" /></Tooltip>} + {tooltip && ( + <Tooltip text={tooltip}> + <i class="icon mdi mdi-information" /> + </Tooltip> + )} </label> </div> @@ -92,16 +97,18 @@ export function InputWithAddon<T>({ required ? " has-icons-right" : "" }`} > - <input + <InternalTextInputSwitch {...(inputExtra || {})} class={error ? "input is-danger" : "input"} - type={inputType} + inputType={inputType} placeholder={placeholder} readonly={readonly} disabled={readonly} name={String(name)} value={toStr(value)} - onChange={(e): void => onChange(fromStr(e.currentTarget.value))} + onChange={(e: h.JSX.TargetedEvent<HTMLInputElement>): void => + onChange(fromStr(e.currentTarget.value)) + } /> {children} </p> diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx @@ -315,7 +315,7 @@ export function UpdatePage({ template, onUpdated, onBack }: Props): VNode { name="amount" label={i18n.str`Amount`} addonBefore={state.currency} - inputType="number" + inputType="decimal" toStr={(v?: AmountString) => v?.split(":")[1] || ""} fromStr={(v: string) => !v ? undefined : `${state.currency}:${v}` diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/UsePage.tsx @@ -148,7 +148,7 @@ export function UsePage({ name="amount" label={i18n.str`Amount`} addonBefore={state.currency} - inputType="number" + inputType="decimal" toStr={(v?: AmountString) => v?.split(":")[1] || ""} fromStr={(v: string) => !v ? undefined : `${state.currency}:${v}`