This commit is contained in:
rizrmd 2024-03-21 11:39:51 -07:00
parent 7fe2663c39
commit 5af47da93a
4 changed files with 112 additions and 70 deletions

View File

@ -44,7 +44,10 @@ export const Field: FC<{
PassProp: any; PassProp: any;
custom: "y" | "n"; custom: "y" | "n";
child: any; child: any;
label_alt: ReactNode | FC<{ modify: typeof modify; data: any }>; selection: "single" | "multi";
label_alt:
| ReactNode
| FC<{ modify: typeof modify; data: any; current_name: string }>;
}> = ({ }> = ({
name, name,
form, form,
@ -57,6 +60,7 @@ export const Field: FC<{
on_change, on_change,
PassProp, PassProp,
custom, custom,
selection,
child, child,
label_alt, label_alt,
}) => { }) => {
@ -146,6 +150,7 @@ export const Field: FC<{
: modify.bind({ : modify.bind({
form, form,
}), }),
current_name: name,
data: form.hook.getValues(), data: form.hook.getValues(),
})} })}
{typeof label_alt !== "function" && label_alt} {typeof label_alt !== "function" && label_alt}
@ -237,12 +242,14 @@ export const Field: FC<{
{type === "radio" && ( {type === "radio" && (
<Radio <Radio
name={name}
options={options} options={options}
PassProp={PassProp} PassProp={PassProp}
child={child} child={child}
value={field.value} value={field.value}
custom={custom} custom={custom}
form={form} form={form}
selection={selection}
on_select={(value: any) => { on_select={(value: any) => {
form?.hook.setValue(name, value); form?.hook.setValue(name, value);
}} }}

View File

@ -4,13 +4,22 @@ import { FC } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
export const Form: FC<{ export const Form: FC<{
on_init: (arg: { submit: any }) => any;
on_load: () => any; on_load: () => any;
on_submit: (arg: { form: any; error: any }) => any; on_submit: (arg: { form: any; error: any }) => any;
body: any; body: any;
form: { hook: any; render: () => void }; form: { hook: any; render: () => void };
PassProp: any; PassProp: any;
layout: "auto" | "1-col" | "2-col"; layout: "auto" | "1-col" | "2-col";
}> = ({ on_load, body, form, PassProp, on_submit, layout: _layout }) => { }> = ({
on_init,
on_load,
body,
form,
PassProp,
on_submit,
layout: _layout,
}) => {
const form_hook = useForm<any>({ const form_hook = useForm<any>({
defaultValues: on_load, defaultValues: on_load,
}); });
@ -19,6 +28,7 @@ export const Form: FC<{
el: null as any, el: null as any,
submit_timeout: null as any, submit_timeout: null as any,
layout: "unknown" as "unknown" | "2-col" | "1-col", layout: "unknown" as "unknown" | "2-col" | "1-col",
init: false,
}); });
form.hook = form_hook; form.hook = form_hook;
@ -26,6 +36,21 @@ export const Form: FC<{
let layout = _layout || "auto"; let layout = _layout || "auto";
if (layout !== "auto") local.layout = layout; if (layout !== "auto") local.layout = layout;
const submit = () => {
clearTimeout(local.submit_timeout);
local.submit_timeout = setTimeout(() => {
on_submit({
form: form.hook.getValues(),
error: {},
});
}, 300);
};
if (!local.init) {
local.init = true;
on_init({ submit });
}
return ( return (
<FForm {...form_hook}> <FForm {...form_hook}>
<form <form
@ -35,11 +60,7 @@ export const Form: FC<{
onSubmit={(e) => { onSubmit={(e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
submit();
clearTimeout(local.submit_timeout);
local.submit_timeout = setTimeout(() => {
on_submit({ form: form.hook.getValues(), error: {} });
}, 300);
}} }}
> >
<div <div
@ -80,14 +101,7 @@ export const Form: FC<{
` `
)} )}
> >
<PassProp <PassProp submit={submit} data={form_hook.getValues()}>
submit={() => {
clearTimeout(local.submit_timeout);
local.submit_timeout = setTimeout(() => {
on_submit({ form: form.hook.getValues(), error: {} });
}, 300);
}}
>
{body} {body}
</PassProp> </PassProp>
</div> </div>

View File

@ -4,13 +4,18 @@ import { Button } from "../../ui/button";
import { FormHook, modify } from "../utils/utils"; import { FormHook, modify } from "../utils/utils";
export const Radio: FC<{ export const Radio: FC<{
name: string;
on_select: (val: any) => void; on_select: (val: any) => void;
options: () => Promise<(string | { value: string; label: string })[]>; options: (opt: {
data: any;
current_name: string;
}) => Promise<(string | { value: string; label: string })[]>;
value: string; value: string;
PassProp: any; PassProp: any;
custom: "y" | "n"; custom: "y" | "n";
child: any; child: any;
form?: FormHook; form?: FormHook;
selection: "single" | "multi";
init_modify: (modify: any) => void; init_modify: (modify: any) => void;
}> = ({ }> = ({
options, options,
@ -21,40 +26,22 @@ export const Radio: FC<{
child, child,
PassProp, PassProp,
init_modify, init_modify,
selection,
name,
}) => { }) => {
const local = useLocal({ const local = useLocal({
list: [] as { value: string; label: string }[], list: [] as { value: string; label: string }[],
status: "init" as "init" | "loading" | "ready", status: "init" as "init" | "loading" | "ready",
mod: false, mod: null as any,
option_modified: false,
}); });
useEffect(() => { useEffect(() => {
local.status = "loading"; if (!local.option_modified && form) {
local.render(); local.status = "loading";
options().then((result) => {
local.list = result.map((e) => {
if (typeof e === "string") {
return {
value: e,
label: e,
};
}
return e;
});
local.status = "ready";
local.render(); local.render();
}); options({ data: form.hook.getValues(), current_name: name }).then(
}, [options]); (result) => {
let mod = null as any;
if (form && !local.mod) {
local.mod = true;
mod = modify.bind({
form,
change_hook(opt) {
const result = opt.options;
if (result) {
local.list = result.map((e) => { local.list = result.map((e) => {
if (typeof e === "string") { if (typeof e === "string") {
return { return {
@ -64,41 +51,76 @@ export const Radio: FC<{
} }
return e; return e;
}); });
local.status = "ready";
local.render(); local.render();
} }
}, );
}); }
init_modify(mod); }, [options]);
if (form) {
if (!local.mod) {
local.mod = modify.bind({
form,
change_hook(opt) {
const result = opt.options;
if (result) {
local.option_modified = true;
local.list = result.map((e) => {
if (typeof e === "string") {
return {
value: e,
label: e,
};
}
return e;
});
}
form.render();
},
});
init_modify(local.mod);
}
} }
return ( return (
<div className="c-flex c-flex-1"> <div className="c-flex c-flex-1 c-flex-wrap">
{!!local.list && {!!local.list &&
local.list.map((item, index) => { local.list
if (custom === "y" && form) .filter((e) => e)
.map((item, index) => {
if (custom === "y" && form)
return (
<PassProp
data={form.hook.getValues()}
modify={local.mod}
is_active={item.value === value}
option_item={item}
current_name={name}
item_click={() => {
console.log(selection);
form.hook.setValue(name, [...value])
}}
>
{child}
</PassProp>
);
return ( return (
<PassProp <Button
data={form.hook.getValues()} key={index}
modify={mod} onClick={() => {
is_active={item.value === value} on_select(item.value);
local.render();
}}
className={cx("c-mr-2")}
variant={item.value === value ? "default" : "outline"}
> >
{child} <span>{item.label}</span>
</PassProp> </Button>
); );
return ( })}
<Button
key={index}
onClick={() => {
on_select(item.value);
local.render();
}}
className={cx("c-mr-2")}
variant={item.value === value ? "default" : "outline"}
>
<span>{item.label}</span>
</Button>
);
})}
</div> </div>
); );
}; };

View File

@ -16,8 +16,7 @@ export const modify = function (
if (keys.includes("value")) { if (keys.includes("value")) {
f.hook.setValue(field_name, opt.value); f.hook.setValue(field_name, opt.value);
} }
if (this.change_hook) if (this.change_hook) this.change_hook(opt);
this.change_hook(opt);
}; };
export type FormHook = { export type FormHook = {