diff --git a/bun.lockb b/bun.lockb index 6b3f159..c422350 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 81d9907..667f1ba 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "sonner": "^1.5.0", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", + "usehooks-ts": "^3.1.0", "zod": "^3.23.8", "zustand": "^4.5.4" }, diff --git a/src/components/editor/action.ts b/src/components/editor/action.ts index b788bfa..6646653 100644 --- a/src/components/editor/action.ts +++ b/src/components/editor/action.ts @@ -24,6 +24,7 @@ type EditorActionMap = { elementDetails: EditorElement; }; CHANGE_CLICKED_ELEMENT: { + elementRef?: React.RefObject; elementDetails?: EditorElement; }; CHANGE_CURRENT_TAB_VALUE: { @@ -178,6 +179,7 @@ const actionHandlers: { return updateEditorHistory(editor, { ...editor.state, selectedElement: payload.elementDetails ?? emptyElement, + selectedElementRef: payload.elementRef, currentTabValue: newTabValue, }); }, diff --git a/src/components/editor/elements/element-helper.tsx b/src/components/editor/elements/element-helper.tsx new file mode 100644 index 0000000..6d967f1 --- /dev/null +++ b/src/components/editor/elements/element-helper.tsx @@ -0,0 +1,90 @@ +"use client"; + +import { + ArrowDownIcon, + ArrowUpIcon, + CopyPlusIcon, + GripVerticalIcon, + Trash2Icon, +} from "lucide-react"; +import { createPortal } from "react-dom"; +import { useEditor } from "~/components/editor/provider"; +import { Badge } from "~/components/ui/badge"; +import { Button } from "~/components/ui/button"; +import { cn } from "~/lib/utils"; + +import { useRef } from "react"; +import { useResizeObserver } from "usehooks-ts"; + +export default function ElementHelper() { + const { editor, dispatch } = useEditor(); + const element = editor.state.selectedElement; + const elementRef = editor.state.selectedElementRef; + + const emptyRef = useRef(null); + const { width, height } = useResizeObserver({ + ref: elementRef ?? emptyRef, + box: "border-box", + }); + + const handleDeleteElement = () => { + dispatch({ + type: "DELETE_ELEMENT", + payload: { + elementDetails: element, + }, + }); + }; + + return ( + document.body && + createPortal( + !editor.state.isPreviewMode && elementRef?.current && ( +
+ + {element.name} + +
+
+ + + + + + + + + +
+
+
+
+ + + + + + +
+
+
+ ), + document.body, + ) + ); +} + +function IconButton(props: React.ComponentProps<"button">) { + return