aboutsummaryrefslogtreecommitdiff
path: root/packages/exchange-backoffice-ui/src/handlers/InputChoice.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/exchange-backoffice-ui/src/handlers/InputChoice.tsx')
-rw-r--r--packages/exchange-backoffice-ui/src/handlers/InputChoice.tsx93
1 files changed, 93 insertions, 0 deletions
diff --git a/packages/exchange-backoffice-ui/src/handlers/InputChoice.tsx b/packages/exchange-backoffice-ui/src/handlers/InputChoice.tsx
new file mode 100644
index 000000000..b19a0d82e
--- /dev/null
+++ b/packages/exchange-backoffice-ui/src/handlers/InputChoice.tsx
@@ -0,0 +1,93 @@
+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 {
+ label: TranslatedString;
+ description?: TranslatedString;
+ value: string;
+}
+
+export function InputChoiceStacked(
+ props: {
+ choices: Choice[];
+ } & UIFormProps<string>,
+): VNode {
+ const {
+ choices,
+ name,
+ label,
+ tooltip,
+ placeholder,
+ required,
+ before,
+ after,
+ converter,
+ } = props;
+ const { value, onChange, state, isDirty } = useField<{
+ [s: string]: undefined | string;
+ }>(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="space-y-4">
+ {choices.map((choice) => {
+ let clazz =
+ "border relative block cursor-pointer rounded-lg bg-white px-6 py-4 shadow-sm focus:outline-none sm:flex sm:justify-between";
+ if (choice.value === value) {
+ clazz +=
+ " border-transparent border-indigo-600 ring-2 ring-indigo-600";
+ } else {
+ clazz += " border-gray-300";
+ }
+ return (
+ <label class={clazz}>
+ <input
+ type="radio"
+ name="server-size"
+ defaultValue={choice.value}
+ onClick={(e) => {
+ onChange(value === choice.value ? undefined : choice.value);
+ }}
+ class="sr-only"
+ aria-labelledby="server-size-0-label"
+ aria-describedby="server-size-0-description-0 server-size-0-description-1"
+ />
+ <span class="flex items-center">
+ <span class="flex flex-col text-sm">
+ <span
+ id="server-size-0-label"
+ class="font-medium text-gray-900"
+ >
+ {choice.label}
+ </span>
+ {choice.description !== undefined && (
+ <span
+ id="server-size-0-description-0"
+ class="text-gray-500"
+ >
+ <span class="block sm:inline">
+ {choice.description}
+ </span>
+ </span>
+ )}
+ </span>
+ </span>
+ </label>
+ );
+ })}
+ </div>
+ </fieldset>
+ </div>
+ );
+}