wallet-core/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx
2023-06-05 10:04:09 -03:00

87 lines
2.4 KiB
TypeScript

import { TranslatedString } from "@gnu-taler/taler-util";
import { Fragment, VNode, h } from "preact";
import { LabelWithTooltipMaybeRequired, UIFormProps } from "./InputLine.js";
import { useField } from "./useField.js";
export interface Choice<V> {
label: TranslatedString;
value: V;
}
export function InputChoiceHorizontal<T extends object, K extends keyof T>(
props: {
choices: Choice<T[K]>[];
} & UIFormProps<T, K>,
): VNode {
const {
choices,
name,
label,
tooltip,
help,
placeholder,
required,
before,
after,
converter,
} = props;
const { value, onChange, state, isDirty } = useField<T, K>(name);
if (state.hidden) {
return <Fragment />;
}
return (
<div class="sm:col-span-6">
<LabelWithTooltipMaybeRequired
label={label}
required={required}
tooltip={tooltip}
/>
<fieldset class="mt-2">
<div class="isolate inline-flex rounded-md shadow-sm">
{choices.map((choice, idx) => {
const isFirst = idx === 0;
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) {
clazz +=
" text-white bg-indigo-600 hover:bg-indigo-500 ring-2 ring-indigo-600 hover:ring-indigo-500";
} else {
clazz += " hover:bg-gray-100 border-gray-300";
}
if (isFirst) {
clazz += " rounded-l-md";
} else {
clazz += " -ml-px";
}
if (isLast) {
clazz += " rounded-r-md";
}
return (
<button
type="button"
class={clazz}
onClick={(e) => {
onChange(
(value === choice.value ? undefined : choice.value) as T[K],
);
}}
>
{(!converter
? (choice.value as string)
: converter?.toStringUI(choice.value)) ?? ""}
</button>
);
})}
</div>
</fieldset>
{help && (
<p class="mt-2 text-sm text-gray-500" id="email-description">
{help}
</p>
)}
</div>
);
}