aboutsummaryrefslogtreecommitdiff
path: root/packages/aml-backoffice-ui/src/handlers/InputLine.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/aml-backoffice-ui/src/handlers/InputLine.tsx')
-rw-r--r--packages/aml-backoffice-ui/src/handlers/InputLine.tsx268
1 files changed, 0 insertions, 268 deletions
diff --git a/packages/aml-backoffice-ui/src/handlers/InputLine.tsx b/packages/aml-backoffice-ui/src/handlers/InputLine.tsx
deleted file mode 100644
index 8c44b1ca5..000000000
--- a/packages/aml-backoffice-ui/src/handlers/InputLine.tsx
+++ /dev/null
@@ -1,268 +0,0 @@
-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";
-
-//@ts-ignore
-const TooltipIcon = (
- <svg
- class="w-5 h-5"
- xmlns="http://www.w3.org/2000/svg"
- viewBox="0 0 20 20"
- fill="currentColor"
- >
- <path
- fill-rule="evenodd"
- d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z"
- clip-rule="evenodd"
- />
- </svg>
-);
-
-export function LabelWithTooltipMaybeRequired({
- label,
- required,
- tooltip,
-}: {
- label: TranslatedString;
- required?: boolean;
- tooltip?: TranslatedString;
-}): VNode {
- const Label = (
- <Fragment>
- <div class="flex justify-between">
- <label
- htmlFor="email"
- class="block text-sm font-medium leading-6 text-gray-900"
- >
- {label}
- </label>
- </div>
- </Fragment>
- );
- const WithTooltip = tooltip ? (
- <div class="relative flex flex-grow items-stretch focus-within:z-10">
- {Label}
- <span class="relative flex items-center group pl-2">
- {TooltipIcon}
- <div class="absolute bottom-0 -ml-10 hidden flex-col items-center mb-6 group-hover:flex w-28">
- <div class="relative z-10 p-2 text-xs leading-none text-white whitespace-no-wrap bg-black shadow-lg">
- {tooltip}
- </div>
- <div class="w-3 h-3 -mt-2 rotate-45 bg-black"></div>
- </div>
- </span>
- </div>
- ) : (
- Label
- );
- if (required) {
- return (
- <div class="flex justify-between">
- {WithTooltip}
- <span class="text-sm leading-6 text-red-600">*</span>
- </div>
- );
- }
- return WithTooltip;
-}
-
-function InputWrapper<T extends object, K extends keyof T>({
- children,
- label,
- tooltip,
- before,
- after,
- help,
- error,
- disabled,
- required,
-}: { error?: string; disabled: boolean, children: ComponentChildren } & UIFormProps<T, K>): VNode {
- return (
- <div class="sm:col-span-6">
- <LabelWithTooltipMaybeRequired
- label={label}
- required={required}
- 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)}
-
- {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)}
- </div>
- {error && (
- <p class="mt-2 text-sm text-red-600" id="email-error">
- {error}
- </p>
- )}
- {help && (
- <p class="mt-2 text-sm text-gray-500" id="email-description">
- {help}
- </p>
- )}
- </div>
- );
-}
-
-function defaultToString(v: unknown) {
- return v === undefined ? "" : typeof v !== "object" ? String(v) : "";
-}
-function defaultFromString(v: string) {
- return v;
-}
-
-type InputType = "text" | "text-area" | "password" | "email" | "number";
-
-export function InputLine<T extends object, K extends keyof T>(
- props: { type: InputType } & UIFormProps<T, K>,
-): VNode {
- const { name, placeholder, before, after, converter, type } = props;
- const { value, onChange, state, isDirty } = useField<T, K>(name);
-
- const [text, setText] = useState("")
- const fromString: (s: string) => any =
- converter?.fromStringUI ?? defaultFromString;
- const toString: (s: any) => string = converter?.toStringUI ?? defaultToString;
-
- useEffect(() => {
- const newValue = toString(value)
- if (newValue) {
- setText(newValue)
- }
- }, [value])
-
- if (state.hidden) return <div />;
-
- let clazz =
- "block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 disabled:ring-gray-200";
- if (before) {
- switch (before.type) {
- case "icon": {
- clazz += " pl-10";
- break;
- }
- case "button": {
- clazz += " rounded-none rounded-r-md ";
- break;
- }
- case "text": {
- clazz += " min-w-0 flex-1 rounded-r-md rounded-none ";
- break;
- }
- }
- }
- if (after) {
- switch (after.type) {
- case "icon": {
- clazz += " pr-10";
- break;
- }
- case "button": {
- clazz += " rounded-none rounded-l-md";
- break;
- }
- case "text": {
- clazz += " min-w-0 flex-1 rounded-l-md rounded-none ";
- break;
- }
- }
- }
- const showError = isDirty && state.error;
- if (showError) {
- clazz +=
- " text-red-900 ring-red-300 placeholder:text-red-300 focus:ring-red-500";
- } else {
- clazz +=
- " text-gray-900 ring-gray-300 placeholder:text-gray-400 focus:ring-indigo-600";
- }
-
- if (type === "text-area") {
- return (
- <InputWrapper<T, K>
- {...props}
- help={props.help ?? state.help}
- disabled={state.disabled ?? false}
- error={showError ? state.error : undefined}
- >
- <textarea
- rows={4}
- name={String(name)}
- onChange={(e) => {
- onChange(fromString(e.currentTarget.value));
- }}
- placeholder={placeholder ? placeholder : undefined}
- value={toString(value) ?? ""}
- // defaultValue={toString(value)}
- disabled={state.disabled}
- aria-invalid={showError}
- // aria-describedby="email-error"
- class={clazz}
- />
- </InputWrapper>
- );
- }
-
- return (
- <InputWrapper<T, K> {...props}
- help={props.help ?? state.help}
- disabled={state.disabled ?? false} error={showError ? state.error : undefined}
- >
- <input
- name={String(name)}
- type={type}
- onChange={(e) => {
- setText(e.currentTarget.value)
- }}
- placeholder={placeholder ? placeholder : undefined}
- value={text}
- onBlur={() => {
- onChange(fromString(text));
- }}
- // defaultValue={toString(value)}
- disabled={state.disabled}
- aria-invalid={showError}
- // aria-describedby="email-error"
- class={clazz}
- />
- </InputWrapper>
- );
-}