fix label
This commit is contained in:
parent
cdf8c5c837
commit
1dc4da9a68
|
|
@ -2,16 +2,71 @@ import { Popover } from "@/comps/custom/Popover";
|
||||||
import { Input } from "@/comps/ui/input";
|
import { Input } from "@/comps/ui/input";
|
||||||
import { useLocal } from "@/utils/use-local";
|
import { useLocal } from "@/utils/use-local";
|
||||||
import { ChevronDown } from "lucide-react";
|
import { ChevronDown } from "lucide-react";
|
||||||
import { FC } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import type { ControllerRenderProps, FieldValues } from "react-hook-form";
|
import type { ControllerRenderProps, FieldValues } from "react-hook-form";
|
||||||
|
import { FieldListItem, FieldOptions } from "../type";
|
||||||
|
import { FormHook } from "../utils/utils";
|
||||||
|
import { Skeleton } from "@/comps/ui/skeleton";
|
||||||
|
|
||||||
export const Dropdown: FC<ControllerRenderProps<FieldValues, string>> = ({
|
export const Dropdown: FC<
|
||||||
value,
|
ControllerRenderProps<FieldValues, string> & {
|
||||||
}) => {
|
options: FieldOptions;
|
||||||
|
form?: FormHook;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
> = ({ value, options, form, name }) => {
|
||||||
const local = useLocal({
|
const local = useLocal({
|
||||||
|
status: "loading" as "loading" | "ready",
|
||||||
open: false,
|
open: false,
|
||||||
ref: { input: null as null | HTMLInputElement },
|
ref: { input: null as null | HTMLInputElement },
|
||||||
|
list: [] as FieldListItem[],
|
||||||
|
input: "",
|
||||||
|
label: "",
|
||||||
|
filter: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (form) {
|
||||||
|
local.status = "loading";
|
||||||
|
local.render();
|
||||||
|
const callback = (result: any[]) => {
|
||||||
|
local.list = result.map((e) => {
|
||||||
|
if (typeof e === "string") {
|
||||||
|
return {
|
||||||
|
value: e,
|
||||||
|
label: e,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
});
|
||||||
|
|
||||||
|
const found = local.list.find((e) => e.value === value);
|
||||||
|
if (found) {
|
||||||
|
local.label = found.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
local.status = "ready";
|
||||||
|
local.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = options({ data: form.hook.getValues(), current_name: name });
|
||||||
|
if (res instanceof Promise) {
|
||||||
|
res.then(callback);
|
||||||
|
} else {
|
||||||
|
callback(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [options]);
|
||||||
|
|
||||||
|
let filtered = local.list;
|
||||||
|
|
||||||
|
if (local.filter) {
|
||||||
|
filtered = local.list.filter((e) => {
|
||||||
|
if (e.value.toLowerCase().includes(local.filter)) return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
open={local.open}
|
open={local.open}
|
||||||
|
|
@ -24,12 +79,51 @@ export const Dropdown: FC<ControllerRenderProps<FieldValues, string>> = ({
|
||||||
content={
|
content={
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"c-px-3 c-py-2",
|
"c-text-sm",
|
||||||
css`
|
css`
|
||||||
width: ${local.ref.input?.clientWidth || 100}px;
|
width: ${local.ref.input?.clientWidth || 100}px;
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
></div>
|
>
|
||||||
|
{local.status === "loading" && (
|
||||||
|
<>
|
||||||
|
<div className="c-flex c-flex-col c-space-y-1 c-px-3 c-py-2">
|
||||||
|
<Skeleton className="c-h-[10px] c-w-[90px]" />
|
||||||
|
<Skeleton className="c-h-[10px] c-w-[60px]" />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
{local.status === "ready" && (
|
||||||
|
<>
|
||||||
|
{filtered.map((item, idx) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
tabIndex={0}
|
||||||
|
key={item.value + "_" + idx}
|
||||||
|
className={cx(
|
||||||
|
"c-px-3 c-py-1 cursor-pointer option-item",
|
||||||
|
item.value === value
|
||||||
|
? "c-bg-blue-600 c-text-white"
|
||||||
|
: "hover:c-bg-blue-50",
|
||||||
|
idx > 0 && "c-border-t",
|
||||||
|
idx === 0 && "c-rounded-t-sm",
|
||||||
|
idx === local.list.length - 1 && "c-rounded-b-sm"
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
if (form) {
|
||||||
|
local.open = false;
|
||||||
|
form.hook.setValue(name, item.value);
|
||||||
|
form.render();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.label}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|
@ -39,22 +133,41 @@ export const Dropdown: FC<ControllerRenderProps<FieldValues, string>> = ({
|
||||||
cursor: pointer !important;
|
cursor: pointer !important;
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
|
tabIndex={0}
|
||||||
|
onFocus={() => {
|
||||||
|
local.open = true;
|
||||||
|
local.input = local.label;
|
||||||
|
local.filter = "";
|
||||||
|
local.render();
|
||||||
|
setTimeout(() => {
|
||||||
|
local.ref.input?.focus();
|
||||||
|
});
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="c-absolute c-pointer-events-none c-inset-0 c-left-auto c-flex c-items-center c-pr-4">
|
<div className="c-absolute c-pointer-events-none c-inset-0 c-left-auto c-flex c-items-center c-pr-4">
|
||||||
<ChevronDown size={14} />
|
<ChevronDown size={14} />
|
||||||
</div>
|
</div>
|
||||||
<Input
|
<Input
|
||||||
spellCheck={false}
|
spellCheck={false}
|
||||||
onFocus={() => {
|
value={local.open ? local.input : ""}
|
||||||
local.open = true;
|
className={cx(
|
||||||
|
local.open ? "c-cursor-pointer" : "c-pointer-events-none"
|
||||||
|
)}
|
||||||
|
onChange={(e) => {
|
||||||
|
local.input = e.currentTarget.value;
|
||||||
|
local.filter = local.input.toLowerCase();
|
||||||
local.render();
|
local.render();
|
||||||
}}
|
}}
|
||||||
className="cursor-pointer"
|
|
||||||
ref={(el) => {
|
ref={(el) => {
|
||||||
local.ref.input = el;
|
local.ref.input = el;
|
||||||
}}
|
}}
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
|
{!local.open && (
|
||||||
|
<div className="c-absolute c-text-sm c-inset-0 c-px-3 c-flex c-items-center">
|
||||||
|
{local.label}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import { Radio } from "./Radio";
|
||||||
import { SliderOptions } from "./Slider/types";
|
import { SliderOptions } from "./Slider/types";
|
||||||
import { FormHook, modify } from "./utils/utils";
|
import { FormHook, modify } from "./utils/utils";
|
||||||
import { Dropdown } from "./Dropdown";
|
import { Dropdown } from "./Dropdown";
|
||||||
|
import { FieldOptions } from "./type";
|
||||||
|
|
||||||
export const Field: FC<{
|
export const Field: FC<{
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -37,7 +38,7 @@ export const Field: FC<{
|
||||||
| "slider"
|
| "slider"
|
||||||
| "master-link";
|
| "master-link";
|
||||||
required: "y" | "n";
|
required: "y" | "n";
|
||||||
options: () => Promise<{ value: string; label: string }[]>;
|
options: FieldOptions;
|
||||||
slider: () => Promise<SliderOptions>;
|
slider: () => Promise<SliderOptions>;
|
||||||
on_change: (arg: { value: any }) => void | Promise<void>;
|
on_change: (arg: { value: any }) => void | Promise<void>;
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
|
|
@ -218,7 +219,14 @@ export const Field: FC<{
|
||||||
<Textarea {...field} ref={textAreaRef} />
|
<Textarea {...field} ref={textAreaRef} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{type === "dropdown" && <Dropdown {...field} />}
|
{type === "dropdown" && (
|
||||||
|
<Dropdown
|
||||||
|
{...field}
|
||||||
|
options={options}
|
||||||
|
form={form}
|
||||||
|
name={name}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{type === "date" && (
|
{type === "date" && (
|
||||||
<Date
|
<Date
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,12 @@ 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";
|
import { FormHook, modify } from "../utils/utils";
|
||||||
|
import { FieldOptions } from "../type";
|
||||||
|
|
||||||
export const Radio: FC<{
|
export const Radio: FC<{
|
||||||
name: string;
|
name: string;
|
||||||
on_select: (val: any) => void;
|
on_select: (val: any) => void;
|
||||||
options: (opt: {
|
options: FieldOptions;
|
||||||
data: any;
|
|
||||||
current_name: string;
|
|
||||||
}) => Promise<(string | { value: string; label: string })[]>;
|
|
||||||
value: string | string[];
|
value: string | string[];
|
||||||
PassProp: any;
|
PassProp: any;
|
||||||
custom: "y" | "n";
|
custom: "y" | "n";
|
||||||
|
|
@ -40,22 +38,27 @@ export const Radio: FC<{
|
||||||
if (!local.option_modified && form) {
|
if (!local.option_modified && form) {
|
||||||
local.status = "loading";
|
local.status = "loading";
|
||||||
local.render();
|
local.render();
|
||||||
options({ data: form.hook.getValues(), current_name: name }).then(
|
const callback = (result: any[]) => {
|
||||||
(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.status = "ready";
|
||||||
local.render();
|
local.render();
|
||||||
}
|
};
|
||||||
);
|
|
||||||
|
const res = options({ data: form.hook.getValues(), current_name: name });
|
||||||
|
if (res instanceof Promise) {
|
||||||
|
res.then(callback);
|
||||||
|
} else {
|
||||||
|
callback(res);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [options]);
|
}, [options]);
|
||||||
|
|
||||||
|
|
@ -104,8 +107,8 @@ export const Radio: FC<{
|
||||||
local.mod(name, { value: item.value });
|
local.mod(name, { value: item.value });
|
||||||
local.render();
|
local.render();
|
||||||
} else if (selection === "multi") {
|
} else if (selection === "multi") {
|
||||||
const val = []
|
const val = [];
|
||||||
val.push()
|
val.push();
|
||||||
local.mod(name, { value: item.value });
|
local.mod(name, { value: item.value });
|
||||||
local.render();
|
local.render();
|
||||||
console.log(value, "====multi", name);
|
console.log(value, "====multi", name);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
export type FieldOptions = (opt: {
|
||||||
|
data: any;
|
||||||
|
current_name: string;
|
||||||
|
where?: { values: string[] }
|
||||||
|
}) => Promise<(string | FieldListItem)[]>
|
||||||
|
|
||||||
|
export type FieldListItem = { value: string; label: string }
|
||||||
Loading…
Reference in New Issue