From cdf8c5c8377c2878cd2118a957913c35f8a10b75 Mon Sep 17 00:00:00 2001
From: rizrmd
Date: Fri, 22 Mar 2024 19:08:51 -0700
Subject: [PATCH] wip fix
---
comps/custom/NavMenu.tsx | 1 +
comps/custom/Popover.tsx | 26 ++--
comps/form/Dropdown/index.tsx | 61 +++++++++
comps/form/Field.tsx | 31 +----
comps/form/PopUpDropdown/index.tsx | 68 ----------
comps/form/Radio/index.tsx | 16 ++-
comps/ui/dropdown-menu.tsx | 198 +++++++++++++++++++++++++++++
comps/ui/form.tsx | 93 +++++++-------
utils/use-local.ts | 9 +-
9 files changed, 333 insertions(+), 170 deletions(-)
create mode 100755 comps/form/Dropdown/index.tsx
delete mode 100755 comps/form/PopUpDropdown/index.tsx
create mode 100755 comps/ui/dropdown-menu.tsx
diff --git a/comps/custom/NavMenu.tsx b/comps/custom/NavMenu.tsx
index 0c67bff..9c308fb 100755
--- a/comps/custom/NavMenu.tsx
+++ b/comps/custom/NavMenu.tsx
@@ -7,6 +7,7 @@ import {
NavigationMenuTrigger,
navigationMenuTriggerStyle,
} from "@/comps/ui/navigation-menu";
+import { useLocal } from "@/utils/use-local";
import get from "lodash.get";
import { FC, forwardRef } from "react";
diff --git a/comps/custom/Popover.tsx b/comps/custom/Popover.tsx
index f6faaac..dfc6b59 100755
--- a/comps/custom/Popover.tsx
+++ b/comps/custom/Popover.tsx
@@ -175,15 +175,13 @@ export const usePopoverContext = () => {
export function Popover({
children,
content,
- className,
modal = false,
- popoverClassName,
+ className,
arrow,
...restOptions
}: {
- className?: string;
root?: HTMLElement;
- popoverClassName?: string;
+ className?: string;
children: React.ReactNode;
content?: React.ReactNode;
arrow?: boolean;
@@ -196,7 +194,7 @@ export function Popover({
return (
{
@@ -209,13 +207,12 @@ export function Popover({
{_content}
@@ -297,10 +294,7 @@ export const PopoverContent = React.forwardRef<
return (
{context.backdrop ? (
-
+
{content}
) : (
diff --git a/comps/form/Dropdown/index.tsx b/comps/form/Dropdown/index.tsx
new file mode 100755
index 0000000..b36f2cc
--- /dev/null
+++ b/comps/form/Dropdown/index.tsx
@@ -0,0 +1,61 @@
+import { Popover } from "@/comps/custom/Popover";
+import { Input } from "@/comps/ui/input";
+import { useLocal } from "@/utils/use-local";
+import { ChevronDown } from "lucide-react";
+import { FC } from "react";
+import type { ControllerRenderProps, FieldValues } from "react-hook-form";
+
+export const Dropdown: FC> = ({
+ value,
+}) => {
+ const local = useLocal({
+ open: false,
+ ref: { input: null as null | HTMLInputElement },
+ });
+ return (
+ {
+ local.open = false;
+ local.render();
+ }}
+ arrow={false}
+ className={cx("c-rounded-sm c-bg-white")}
+ content={
+
+ }
+ >
+
+
+
+
+
{
+ local.open = true;
+ local.render();
+ }}
+ className="cursor-pointer"
+ ref={(el) => {
+ local.ref.input = el;
+ }}
+ type="text"
+ />
+
+
+ );
+};
diff --git a/comps/form/Field.tsx b/comps/form/Field.tsx
index f2e13e3..c9c197d 100755
--- a/comps/form/Field.tsx
+++ b/comps/form/Field.tsx
@@ -9,16 +9,15 @@ import {
import { useLocal } from "@/utils/use-local";
import autosize from "autosize";
import { FC, ReactNode, useEffect, useRef } from "react";
-import { Button } from "../ui/button";
import { Input } from "../ui/input";
import { Textarea } from "../ui/textarea";
import { Date } from "./Date";
import { Datetime } from "./Datetime";
import { InputMoney } from "./InputMoney";
-import { PopUpDropdown } from "./PopUpDropdown";
import { Radio } from "./Radio";
import { SliderOptions } from "./Slider/types";
import { FormHook, modify } from "./utils/utils";
+import { Dropdown } from "./Dropdown";
export const Field: FC<{
name: string;
@@ -70,9 +69,6 @@ export const Field: FC<{
}) => {
const value = form?.hook.getValues()[name];
const local = useLocal({
- dropdown: {
- popup: false,
- },
date: {
// label: "",
popup: false,
@@ -120,19 +116,6 @@ export const Field: FC<{
return (
<>
- {local.dropdown.popup && (
- {
- local.dropdown.popup = false;
- local.render();
- }}
- on_select={(value: any) => {
- form?.hook.setValue(name, value);
- }}
- title={label}
- options={options}
- />
- )}
)}
- {type === "dropdown" && (
-
- )}
+ {type === "dropdown" && }
{type === "date" && (
void;
- on_close: () => void;
- title: string;
- options: () => Promise<{ value: string; label: string }[]>;
-}> = ({ on_close, title, options, on_select }) => {
- const local = useLocal({
- list: [] as { value: string; label: string }[],
- status: "init" as "init" | "loading" | "ready",
- });
-
- useEffect(() => {
- if (local.status === "init") {
- local.status = "loading";
- local.render();
- options().then((result) => {
- local.list = result;
-
- local.status = "ready";
- local.render();
- });
- }
- }, [options]);
-
- return (
-
-
-
-
- {title}
-
-
-
-
-
- {!!local.list &&
- local.list.map((item, index) => (
-
- ))}
-
-
-
- );
-};
diff --git a/comps/form/Radio/index.tsx b/comps/form/Radio/index.tsx
index ff9b738..bba198b 100755
--- a/comps/form/Radio/index.tsx
+++ b/comps/form/Radio/index.tsx
@@ -10,7 +10,7 @@ export const Radio: FC<{
data: any;
current_name: string;
}) => Promise<(string | { value: string; label: string })[]>;
- value: string;
+ value: string | string[];
PassProp: any;
custom: "y" | "n";
child: any;
@@ -99,14 +99,16 @@ export const Radio: FC<{
option_item={item}
current_name={name}
item_click={() => {
- console.log(selection);
+ console.log(value, "====single", name);
if (selection === "single") {
- console.log(form.hook.get);
-
- form.hook.setValue(name, [...value]);
+ local.mod(name, { value: item.value });
+ local.render();
} else if (selection === "multi") {
-
- form.hook
+ const val = []
+ val.push()
+ local.mod(name, { value: item.value });
+ local.render();
+ console.log(value, "====multi", name);
} else {
null;
}
diff --git a/comps/ui/dropdown-menu.tsx b/comps/ui/dropdown-menu.tsx
new file mode 100755
index 0000000..5022c1d
--- /dev/null
+++ b/comps/ui/dropdown-menu.tsx
@@ -0,0 +1,198 @@
+import * as React from "react"
+import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
+import { Check, ChevronRight, Circle } from "lucide-react"
+
+import { cn } from "@/utils"
+
+const DropdownMenu = DropdownMenuPrimitive.Root
+
+const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
+
+const DropdownMenuGroup = DropdownMenuPrimitive.Group
+
+const DropdownMenuPortal = DropdownMenuPrimitive.Portal
+
+const DropdownMenuSub = DropdownMenuPrimitive.Sub
+
+const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
+
+const DropdownMenuSubTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean
+ }
+>(({ className, inset, children, ...props }, ref) => (
+
+ {children}
+
+
+))
+DropdownMenuSubTrigger.displayName =
+ DropdownMenuPrimitive.SubTrigger.displayName
+
+const DropdownMenuSubContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+DropdownMenuSubContent.displayName =
+ DropdownMenuPrimitive.SubContent.displayName
+
+const DropdownMenuContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, sideOffset = 4, ...props }, ref) => (
+
+
+
+))
+DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
+
+const DropdownMenuItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean
+ }
+>(({ className, inset, ...props }, ref) => (
+
+))
+DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
+
+const DropdownMenuCheckboxItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, checked, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+))
+DropdownMenuCheckboxItem.displayName =
+ DropdownMenuPrimitive.CheckboxItem.displayName
+
+const DropdownMenuRadioItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+))
+DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
+
+const DropdownMenuLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef & {
+ inset?: boolean
+ }
+>(({ className, inset, ...props }, ref) => (
+
+))
+DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
+
+const DropdownMenuSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+))
+DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
+
+const DropdownMenuShortcut = ({
+ className,
+ ...props
+}: React.HTMLAttributes) => {
+ return (
+
+ )
+}
+DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
+
+export {
+ DropdownMenu,
+ DropdownMenuTrigger,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuCheckboxItem,
+ DropdownMenuRadioItem,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+ DropdownMenuShortcut,
+ DropdownMenuGroup,
+ DropdownMenuPortal,
+ DropdownMenuSub,
+ DropdownMenuSubContent,
+ DropdownMenuSubTrigger,
+ DropdownMenuRadioGroup,
+}
diff --git a/comps/ui/form.tsx b/comps/ui/form.tsx
index 7980b6c..2ad12e2 100755
--- a/comps/ui/form.tsx
+++ b/comps/ui/form.tsx
@@ -1,6 +1,6 @@
-import * as React from "react"
-import * as LabelPrimitive from "@radix-ui/react-label"
-import { Slot } from "@radix-ui/react-slot"
+import * as React from "react";
+import * as LabelPrimitive from "@radix-ui/react-label";
+import { Slot } from "@radix-ui/react-slot";
import {
Controller,
ControllerProps,
@@ -8,23 +8,23 @@ import {
FieldValues,
FormProvider,
useFormContext,
-} from "react-hook-form"
+} from "react-hook-form";
-import { cn } from "@/utils"
-import { Label } from "@/comps/ui/label"
+import { cn } from "@/utils";
+import { Label } from "@/comps/ui/label";
-const Form = FormProvider
+const Form = FormProvider;
type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath = FieldPath
> = {
- name: TName
-}
+ name: TName;
+};
const FormFieldContext = React.createContext(
{} as FormFieldContextValue
-)
+);
const FormField = <
TFieldValues extends FieldValues = FieldValues,
@@ -36,21 +36,21 @@ const FormField = <
- )
-}
+ );
+};
const useFormField = () => {
- const fieldContext = React.useContext(FormFieldContext)
- const itemContext = React.useContext(FormItemContext)
- const { getFieldState, formState } = useFormContext()
+ const fieldContext = React.useContext(FormFieldContext);
+ const itemContext = React.useContext(FormItemContext);
+ const { getFieldState, formState } = useFormContext();
- const fieldState = getFieldState(fieldContext.name, formState)
+ const fieldState = getFieldState(fieldContext.name, formState);
if (!fieldContext) {
- throw new Error("useFormField should be used within ")
+ throw new Error("useFormField should be used within ");
}
- const { id } = itemContext
+ const { id } = itemContext;
return {
id,
@@ -59,36 +59,36 @@ const useFormField = () => {
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
...fieldState,
- }
-}
+ };
+};
type FormItemContextValue = {
- id: string
-}
+ id: string;
+};
const FormItemContext = React.createContext(
{} as FormItemContextValue
-)
+);
const FormItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes
>(({ className, ...props }, ref) => {
- const id = React.useId()
+ const id = React.useId();
return (
- )
-})
-FormItem.displayName = "FormItem"
+ );
+});
+FormItem.displayName = "FormItem";
const FormLabel = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ className, ...props }, ref) => {
- const { error, formItemId } = useFormField()
+ const { error, formItemId } = useFormField();
return (
- )
-})
-FormLabel.displayName = "FormLabel"
+ );
+});
+FormLabel.displayName = "FormLabel";
const FormControl = React.forwardRef<
React.ElementRef,
React.ComponentPropsWithoutRef
>(({ ...props }, ref) => {
- const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
+ const { error, formItemId, formDescriptionId, formMessageId } =
+ useFormField();
return (
- )
-})
-FormControl.displayName = "FormControl"
+ );
+});
+FormControl.displayName = "FormControl";
const FormDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes
>(({ className, ...props }, ref) => {
- const { formDescriptionId } = useFormField()
+ const { formDescriptionId } = useFormField();
return (
- )
-})
-FormDescription.displayName = "FormDescription"
+ );
+});
+FormDescription.displayName = "FormDescription";
const FormMessage = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes
>(({ className, children, ...props }, ref) => {
- const { error, formMessageId } = useFormField()
- const body = error ? String(error?.message) : children
+ const { error, formMessageId } = useFormField();
+ const body = error ? String(error?.message) : children;
if (!body) {
- return null
+ return null;
}
return (
@@ -160,9 +161,9 @@ const FormMessage = React.forwardRef<
>
{body}
- )
-})
-FormMessage.displayName = "FormMessage"
+ );
+});
+FormMessage.displayName = "FormMessage";
export {
useFormField,
@@ -173,4 +174,4 @@ export {
FormDescription,
FormMessage,
FormField,
-}
+};
diff --git a/utils/use-local.ts b/utils/use-local.ts
index 55988f8..120c87f 100755
--- a/utils/use-local.ts
+++ b/utils/use-local.ts
@@ -8,11 +8,11 @@ export const useLocal = (
deps?: any[]
): {
[K in keyof T]: T[K] extends Promise ? null | Awaited : T[K];
-} & { render: () => void } => {
+} & { render: (force?: boolean) => void } => {
const [, _render] = useState({});
const _ = useRef({
data: data as unknown as T & {
- render: () => void;
+ render: (force?: boolean) => void;
},
deps: (deps || []) as any[],
promisedKeys: new Set(),
@@ -45,8 +45,9 @@ export const useLocal = (
}
}
- local.data.render = () => {
- if (local.ready) _render({});
+ local.data.render = (force) => {
+ if (force) _render({})
+ else if (local.ready) _render({});
};
} else {
if (local.deps.length > 0 && deps) {