This commit is contained in:
rizky 2024-03-21 06:57:28 +00:00
parent a72e479932
commit 7fe2663c39
3 changed files with 109 additions and 22 deletions

View File

@ -19,12 +19,13 @@ import { Datetime } from "./Datetime";
import { InputMoney } from "./InputMoney"; import { InputMoney } from "./InputMoney";
import { PopUpDropdown } from "./PopUpDropdown"; import { PopUpDropdown } from "./PopUpDropdown";
import { SliderOptions } from "./Slider/types"; import { SliderOptions } from "./Slider/types";
import { FormHook, modify } from "./utils/utils";
export const Field: FC<{ export const Field: FC<{
name: string; name: string;
label: string; label: string;
desc?: string; desc?: string;
form?: { hook: UseFormReturn<any, any, undefined>; render: () => void }; form?: FormHook;
type: type:
| "text" | "text"
| "textarea" | "textarea"
@ -43,7 +44,7 @@ export const Field: FC<{
PassProp: any; PassProp: any;
custom: "y" | "n"; custom: "y" | "n";
child: any; child: any;
label_alt: ReactNode | (() => ReactNode); label_alt: ReactNode | FC<{ modify: typeof modify; data: any }>;
}> = ({ }> = ({
name, name,
form, form,
@ -77,6 +78,7 @@ export const Field: FC<{
} as SliderOptions, } as SliderOptions,
status: "init" as "init" | "loading" | "ready", status: "init" as "init" | "loading" | "ready",
}, },
modify: null as any,
}); });
const textAreaRef = useRef<any>(); const textAreaRef = useRef<any>();
@ -136,7 +138,17 @@ export const Field: FC<{
)} )}
</div> </div>
<div> <div>
{typeof label_alt === "function" ? label_alt() : label_alt} {typeof label_alt === "function" &&
form &&
label_alt({
modify: local.modify
? local.modify
: modify.bind({
form,
}),
data: form.hook.getValues(),
})}
{typeof label_alt !== "function" && label_alt}
</div> </div>
</FormLabel> </FormLabel>
<FormControl> <FormControl>
@ -230,9 +242,14 @@ export const Field: FC<{
child={child} child={child}
value={field.value} value={field.value}
custom={custom} custom={custom}
form={form}
on_select={(value: any) => { on_select={(value: any) => {
form?.hook.setValue(name, value); form?.hook.setValue(name, value);
}} }}
init_modify={(mod) => {
local.modify = mod;
local.render();
}}
/> />
)} )}

View File

@ -1,6 +1,7 @@
import { useLocal } from "@/utils/use-local"; import { useLocal } from "@/utils/use-local";
import { FC, useEffect } from "react"; import { FC, useEffect } from "react";
import { Button } from "../../ui/button"; import { Button } from "../../ui/button";
import { FormHook, modify } from "../utils/utils";
export const Radio: FC<{ export const Radio: FC<{
on_select: (val: any) => void; on_select: (val: any) => void;
@ -9,38 +10,81 @@ export const Radio: FC<{
PassProp: any; PassProp: any;
custom: "y" | "n"; custom: "y" | "n";
child: any; child: any;
}> = ({ options, on_select, value, custom, child, PassProp }) => { form?: FormHook;
init_modify: (modify: any) => void;
}> = ({
options,
on_select,
form,
value,
custom,
child,
PassProp,
init_modify,
}) => {
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,
}); });
useEffect(() => { useEffect(() => {
if (local.status === "init") { local.status = "loading";
local.status = "loading"; local.render();
local.render(); options().then((result) => {
options().then((result) => { local.list = result.map((e) => {
local.list = result.map((e) => { if (typeof e === "string") {
if (typeof e === "string") { return {
return { value: e,
value: e, label: e,
label: e, };
}; }
} return e;
return e;
});
local.status = "ready";
local.render();
}); });
}
local.status = "ready";
local.render();
});
}, [options]); }, [options]);
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) => {
if (typeof e === "string") {
return {
value: e,
label: e,
};
}
return e;
});
local.render();
}
},
});
init_modify(mod);
}
return ( return (
<div className="c-flex c-flex-1"> <div className="c-flex c-flex-1">
{!!local.list && {!!local.list &&
local.list.map((item, index) => { local.list.map((item, index) => {
if (custom === "y") return <PassProp>{child}</PassProp>; if (custom === "y" && form)
return (
<PassProp
data={form.hook.getValues()}
modify={mod}
is_active={item.value === value}
>
{child}
</PassProp>
);
return ( return (
<Button <Button
key={index} key={index}

26
comps/form/utils/utils.ts Executable file
View File

@ -0,0 +1,26 @@
import { UseFormReturn } from "react-hook-form";
type ModifyOpt = {
value?: any;
options?: (string | { value: any; label: string })[];
};
export const modify = function (
this: { form: FormHook; change_hook?: (opt: ModifyOpt) => void },
field_name: string,
opt: ModifyOpt
) {
const f = this.form;
const keys = Object.keys(opt);
if (keys.includes("value")) {
f.hook.setValue(field_name, opt.value);
}
if (this.change_hook)
this.change_hook(opt);
};
export type FormHook = {
hook: UseFormReturn<any, any, undefined>;
render: () => void;
};