From fdbe623e1060efc4b074d213a96e8f5a2ab7498b Mon Sep 17 00:00:00 2001
From: Sebastian <sebasjm@gmail.com>
Date: Wed, 20 Sep 2023 15:16:28 -0300
Subject: more ui stuff, moved forms to util

---
 packages/web-util/src/forms/InputChoiceStacked.tsx | 111 +++++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100644 packages/web-util/src/forms/InputChoiceStacked.tsx

(limited to 'packages/web-util/src/forms/InputChoiceStacked.tsx')

diff --git a/packages/web-util/src/forms/InputChoiceStacked.tsx b/packages/web-util/src/forms/InputChoiceStacked.tsx
new file mode 100644
index 000000000..c37984368
--- /dev/null
+++ b/packages/web-util/src/forms/InputChoiceStacked.tsx
@@ -0,0 +1,111 @@
+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;
+  description?: TranslatedString;
+  value: V;
+}
+
+export function InputChoiceStacked<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="space-y-4">
+          {choices.map((choice) => {
+            // const currentValue = !converter
+            //   ? choice.value
+            //   : converter.fromStringUI(choice.value) ?? "";
+
+            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}
+                  value={
+                    (!converter
+                      ? (choice.value as string)
+                      : converter?.toStringUI(choice.value)) ?? ""
+                  }
+                  onClick={(e) => {
+                    onChange(
+                      (value === choice.value
+                        ? undefined
+                        : choice.value) as T[K],
+                    );
+                  }}
+                  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>
+      {help && (
+        <p class="mt-2 text-sm text-gray-500" id="email-description">
+          {help}
+        </p>
+      )}
+    </div>
+  );
+}
-- 
cgit v1.2.3

