[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-typescript-core] branch master updated: better array form,
gnunet <=