gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-typescript-core] branch master updated: better array form


From: gnunet
Subject: [taler-typescript-core] branch master updated: better array form
Date: Wed, 29 Jan 2025 15:58:40 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository taler-typescript-core.

The following commit(s) were added to refs/heads/master by this push:
     new 5c1747681 better array form
5c1747681 is described below

commit 5c17476815c55585c3176de23d33294b8aea7a59
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Jan 29 11:58:33 2025 -0300

    better array form
---
 .../src/forms/fields/InputArray.stories.tsx        |   2 +-
 packages/web-util/src/forms/fields/InputArray.tsx  | 229 ++++++++++++---------
 packages/web-util/src/hooks/useForm.ts             |   4 +-
 3 files changed, 132 insertions(+), 103 deletions(-)

diff --git a/packages/web-util/src/forms/fields/InputArray.stories.tsx 
b/packages/web-util/src/forms/fields/InputArray.stories.tsx
index a4dfaf417..9f88ac392 100644
--- a/packages/web-util/src/forms/fields/InputArray.stories.tsx
+++ b/packages/web-util/src/forms/fields/InputArray.stories.tsx
@@ -96,7 +96,7 @@ const design2: FormDesign = {
       fields: [
         {
           type: "text",
-          id: "PERSON_FULL_NAME" as UIHandlerId,
+          id: "AGE" as UIHandlerId,
           label: "Full name",
           required: true,
         },
diff --git a/packages/web-util/src/forms/fields/InputArray.tsx 
b/packages/web-util/src/forms/fields/InputArray.tsx
index dc5186e10..77e07c559 100644
--- a/packages/web-util/src/forms/fields/InputArray.tsx
+++ b/packages/web-util/src/forms/fields/InputArray.tsx
@@ -14,71 +14,6 @@ import { UIFormProps } from "../FormProvider.js";
 import { LabelWithTooltipMaybeRequired } from "./InputLine.js";
 import { UIFormElementConfig, UIHandlerId } from "../forms-types.js";
 
-function Option({
-  label,
-  disabled,
-  isFirst,
-  isLast,
-  isSelected,
-  onClick,
-}: {
-  label: TranslatedString;
-  isFirst?: boolean;
-  isLast?: boolean;
-  isSelected?: boolean;
-  disabled?: boolean;
-  onClick: () => void;
-}): VNode {
-  let clazz = "relative flex border p-4 focus:outline-none disabled:text-grey";
-  if (isFirst) {
-    clazz += " rounded-tl-md rounded-tr-md ";
-  }
-  if (isLast) {
-    clazz += " rounded-bl-md rounded-br-md ";
-  }
-  if (isSelected) {
-    clazz += " z-10 border-indigo-200 bg-indigo-50 ";
-  } else {
-    clazz += " border-gray-200";
-  }
-  if (disabled) {
-    clazz +=
-      " cursor-not-allowed bg-gray-50 text-gray-500 ring-gray-200  text-gray";
-  } else {
-    clazz += " cursor-pointer";
-  }
-  return (
-    <label class={clazz}>
-      <input
-        type="radio"
-        name="privacy-setting"
-        checked={isSelected}
-        disabled={disabled}
-        onClick={onClick}
-        class="mt-0.5 h-4 w-4 shrink-0 text-indigo-600 
disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 
disabled:ring-gray-200  focus:ring-indigo-600"
-        aria-labelledby="privacy-setting-0-label"
-        aria-describedby="privacy-setting-0-description"
-      />
-      <span class="ml-3 flex flex-col">
-        <span
-          id="privacy-setting-0-label"
-          disabled
-          class="block text-sm font-medium"
-        >
-          {label}
-        </span>
-        {/* <!-- Checked: "text-indigo-700", Not Checked: "text-gray-500" --> 
*/}
-        {/* <span
-        id="privacy-setting-0-description"
-        class="block text-sm"
-      >
-        This project would be available to anyone who has the link
-      </span> */}
-      </span>
-    </label>
-  );
-}
-
 export function noHandlerPropsAndNoContextForField(
   field: string | number | symbol,
 ): never {
@@ -92,12 +27,17 @@ type FormType = {};
 function ArrayForm({
   fields,
   selected,
-  onChange,
+  onClose,
+  onRemove,
+  onConfirm,
 }: {
   fields: UIFormElementConfig[];
   selected: Record<string, string | undefined> | undefined;
-  onChange: (r: RecursivePartial<FormType>) => void;
+  onClose: () => void;
+  onRemove: () => void;
+  onConfirm: (r: RecursivePartial<FormType>) => void;
 }): VNode {
+  const { i18n } = useTranslationContext();
   const form = useForm<FormType>(
     {
       type: "single-column",
@@ -106,15 +46,54 @@ function ArrayForm({
     selected ?? {},
   );
 
-  useEffect(() => {
-    onChange(form.status.result);
-  }, [form.status.result]);
+  // useEffect(() => {
+  //   onChange(form.status.result);
+  // }, [form.status.result]);
 
   return (
     <div class="px-4 py-6">
       <div class="grid grid-cols-1 gap-y-8 ">
         <SingleColumnFormSectionUI fields={fields} handler={form.handler} />
       </div>
+      {/* <pre>{JSON.stringify(form.status, undefined, 2)}</pre> */}
+
+      <div class="flex items-center justify-end gap-x-6 mt-4">
+        <button
+          type="button"
+          onClick={onClose}
+          class="block px-3 py-2 text-sm font-semibold leading-6 text-gray-900"
+        >
+          <i18n.Translate>Cancel</i18n.Translate>
+        </button>
+
+        <button
+          type="button"
+          disabled={selected === undefined}
+          onClick={() => {
+            onRemove();
+          }}
+          // onClick={() => {
+          //   const newValue = [...list];
+          //   newValue.splice(selectedIndex, 1);
+          //   onChange(newValue as any);
+          //   // setSelectedIndex(undefined);
+          // }}
+          class="block rounded-md bg-red-600 px-3 py-2 text-center text-sm  
text-white shadow-sm hover:bg-red-500 disabled:cursor-not-allowed 
disabled:bg-gray-50 disabled:text-gray-500 disabled:ring-gray-200"
+        >
+          <i18n.Translate>Remove</i18n.Translate>
+        </button>
+
+        <button
+          type="button"
+          disabled={form.status.status !== "ok"}
+          onClick={() => {
+            onConfirm(form.status.result);
+          }}
+          class="block rounded-md bg-indigo-600 px-3 py-2 text-center text-sm  
text-white shadow-sm hover:bg-indigo-500 disabled:cursor-not-allowed 
disabled:bg-gray-50 disabled:text-gray-500 disabled:ring-gray-200"
+        >
+          <i18n.Translate>Confirm</i18n.Translate>
+        </button>
+      </div>
     </div>
   );
 }
@@ -132,7 +111,8 @@ export function InputArray<T extends object, K extends 
keyof T>(
 
   const list = (value ?? []) as Array<Record<string, string | undefined>>;
   const [selectedIndex, setSelectedIndex] = useState<number | undefined>(
-    undefined,
+    // undefined,
+    0,
   );
   const selected =
     selectedIndex === undefined ? undefined : list[selectedIndex];
@@ -172,7 +152,7 @@ export function InputArray<T extends object, K extends 
keyof T>(
           {!state.disabled && (
             <div class="pt-2">
               <Option
-                label={"Add new..." as TranslatedString}
+                label={i18n.str`Add new...`}
                 isSelected={selectedIndex === list.length}
                 isLast
                 isFirst
@@ -191,41 +171,90 @@ export function InputArray<T extends object, K extends 
keyof T>(
         {selectedIndex !== undefined && (
           <ArrayForm
             fields={fields}
-            onChange={(result) => {
+            onRemove={() => {
               const newValue = [...list];
-              newValue.splice(selectedIndex, 1, result);
+              newValue.splice(selectedIndex, 1);
               onChange(newValue as any);
+              setSelectedIndex(undefined);
+            }}
+            onClose={() => {
+              setSelectedIndex(undefined);
+            }}
+            onConfirm={(value) => {
+              const newValue = [...list];
+              newValue.splice(selectedIndex, 1, value);
+              onChange(newValue as any);
+              setSelectedIndex(undefined);
             }}
             selected={selected}
           />
         )}
-        {selectedIndex !== undefined && (
-          <div class="flex items-center justify-end gap-x-6">
-            <button
-              type="button"
-              onClick={() => {
-                setSelectedIndex(undefined);
-              }}
-              class="block px-3 py-2 text-sm font-semibold leading-6 
text-gray-900"
-            >
-              <i18n.Translate>Close</i18n.Translate>
-            </button>
-
-            <button
-              type="button"
-              onClick={() => {
-                const newValue = [...list];
-                newValue.splice(selectedIndex, 1);
-                onChange(newValue as any);
-                setSelectedIndex(undefined);
-              }}
-              class="block rounded-md bg-red-600 px-3 py-2 text-center text-sm 
 text-white shadow-sm hover:bg-red-500 "
-            >
-              <i18n.Translate>Remove</i18n.Translate>
-            </button>
-          </div>
-        )}
       </div>
     </div>
   );
 }
+
+function Option({
+  label,
+  disabled,
+  isFirst,
+  isLast,
+  isSelected,
+  onClick,
+}: {
+  label: TranslatedString;
+  isFirst?: boolean;
+  isLast?: boolean;
+  isSelected?: boolean;
+  disabled?: boolean;
+  onClick: () => void;
+}): VNode {
+  let clazz = "relative flex border p-4 focus:outline-none disabled:text-grey";
+  if (isFirst) {
+    clazz += " rounded-tl-md rounded-tr-md ";
+  }
+  if (isLast) {
+    clazz += " rounded-bl-md rounded-br-md ";
+  }
+  if (isSelected) {
+    clazz += " z-10 border-indigo-200 bg-indigo-50 ";
+  } else {
+    clazz += " border-gray-200";
+  }
+  if (disabled) {
+    clazz +=
+      " cursor-not-allowed bg-gray-50 text-gray-500 ring-gray-200  text-gray";
+  } else {
+    clazz += " cursor-pointer";
+  }
+  return (
+    <label class={clazz}>
+      <input
+        type="radio"
+        name="privacy-setting"
+        checked={isSelected}
+        disabled={disabled}
+        onClick={onClick}
+        class="mt-0.5 h-4 w-4 shrink-0 text-indigo-600 
disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500 
disabled:ring-gray-200  focus:ring-indigo-600"
+        aria-labelledby="privacy-setting-0-label"
+        aria-describedby="privacy-setting-0-description"
+      />
+      <span class="ml-3 flex flex-col">
+        <span
+          id="privacy-setting-0-label"
+          disabled
+          class="block text-sm font-medium"
+        >
+          {label}
+        </span>
+        {/* <!-- Checked: "text-indigo-700", Not Checked: "text-gray-500" --> 
*/}
+        {/* <span
+        id="privacy-setting-0-description"
+        class="block text-sm"
+      >
+        This project would be available to anyone who has the link
+      </span> */}
+      </span>
+    </label>
+  );
+}
diff --git a/packages/web-util/src/hooks/useForm.ts 
b/packages/web-util/src/hooks/useForm.ts
index ca12defbf..6c95f89f9 100644
--- a/packages/web-util/src/hooks/useForm.ts
+++ b/packages/web-util/src/hooks/useForm.ts
@@ -205,7 +205,7 @@ export function validateRequiredFields<FormType>(
 
   function checkIfRequiredFieldHasValue(formElement: UIFormElementConfig) {
     if ("fields" in formElement) {
-      formElement.fields.forEach(checkIfRequiredFieldHasValue);
+      // formElement.fields.forEach(checkIfRequiredFieldHasValue);
     }
     if (!("id" in formElement)) {
       return;
@@ -249,7 +249,7 @@ function constructFormHandler<T>(
 
   function notifyUpdateOnFieldChange(formElement: UIFormElementConfig): void {
     if ("fields" in formElement) {
-      formElement.fields.forEach(notifyUpdateOnFieldChange);
+      // formElement.fields.forEach(notifyUpdateOnFieldChange);
     }
     if (!("id" in formElement)) {
       return;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]