diff options
Diffstat (limited to 'packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx')
-rw-r--r-- | packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx b/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx new file mode 100644 index 000000000..fdee35447 --- /dev/null +++ b/packages/aml-backoffice-ui/src/handlers/InputChoiceHorizontal.tsx @@ -0,0 +1,86 @@ +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> + ); +} |