diff options
author | Sebastian <sebasjm@gmail.com> | 2023-09-20 15:16:28 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-09-25 14:50:39 -0300 |
commit | fdbe623e1060efc4b074d213a96e8f5a2ab7498b (patch) | |
tree | 6bbe00f6f36f1910ea99180a6e0d5c53aeb9f34f /packages/web-util/src/forms/InputChoiceHorizontal.tsx | |
parent | a5406c5a5dc437e036168eb068db11d88e05bb0f (diff) | |
download | wallet-core-fdbe623e1060efc4b074d213a96e8f5a2ab7498b.tar.xz |
more ui stuff, moved forms to util
Diffstat (limited to 'packages/web-util/src/forms/InputChoiceHorizontal.tsx')
-rw-r--r-- | packages/web-util/src/forms/InputChoiceHorizontal.tsx | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/packages/web-util/src/forms/InputChoiceHorizontal.tsx b/packages/web-util/src/forms/InputChoiceHorizontal.tsx new file mode 100644 index 000000000..5c909b5d7 --- /dev/null +++ b/packages/web-util/src/forms/InputChoiceHorizontal.tsx @@ -0,0 +1,82 @@ +import { TranslatedString } from "@gnu-taler/taler-util"; +import { Fragment, VNode, h } from "preact"; +import { LabelWithTooltipMaybeRequired, UIFormProps } from "./InputLine.js"; +import { useField } from "./useField.js"; +import { Choice } from "./InputChoiceStacked.js"; + +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> + ); +} |