basic UI for selecting and editing

This commit is contained in:
Abi Raja 2024-05-29 14:40:46 -04:00
parent 939539611f
commit 97cdb093a5
2 changed files with 126 additions and 3 deletions

View File

@ -1,6 +1,7 @@
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import classNames from "classnames";
import useThrottle from "../hooks/useThrottle";
import EditPopup from "./select-and-edit/EditPopup";
interface Props {
code: string;
@ -13,9 +14,70 @@ function Preview({ code, device }: Props) {
// Don't update code more often than every 200ms.
const throttledCode = useThrottle(code, 200);
const [selectedElement, setSelectedElement] = useState<HTMLElement | null>(
null
);
const [popupVisible, setPopupVisible] = useState(false);
const [popupPosition, setPopupPosition] = useState({ x: 0, y: 0 });
const [editText, setEditText] = useState("");
console.log(selectedElement);
function updateHighlight(targetElement: HTMLElement) {
setSelectedElement((prev) => {
// Remove style from previous element
if (prev) {
prev.style.outline = "";
prev.style.backgroundColor = "";
}
// Add style to new element
targetElement.style.outline = "2px dashed #1846db";
targetElement.style.backgroundColor = "#bfcbf5";
return targetElement;
});
}
function handleClick(event: MouseEvent) {
const { clientX, clientY } = event;
// Prevent default to avoid issues like label clicks triggering textareas, etc.
event.preventDefault();
const targetElement = event.target as HTMLElement;
// Return if no target element
if (!targetElement) {
return;
}
// Highlight the selected element
updateHighlight(targetElement);
// Show popup at click position
setPopupVisible(false);
setPopupPosition({ x: clientX, y: clientY });
setPopupVisible(true);
}
function handleEditSubmit() {
if (selectedElement) {
selectedElement.innerText = editText;
}
setPopupVisible(false);
}
useEffect(() => {
if (iframeRef.current) {
iframeRef.current.srcdoc = throttledCode;
const iframe = iframeRef.current;
if (iframe) {
iframe.srcdoc = throttledCode;
// Related to
iframe.addEventListener("load", function () {
iframe.contentWindow?.document.body.addEventListener(
"click",
handleClick
);
});
}
}, [throttledCode]);
@ -34,6 +96,15 @@ function Preview({ code, device }: Props) {
}
)}
></iframe>
<EditPopup
{...{
popupVisible,
popupPosition,
editText,
setEditText,
handleEditSubmit,
}}
/>
</div>
);
}

View File

@ -0,0 +1,52 @@
import React, { useEffect, useRef } from "react";
import { Textarea } from "../ui/textarea";
import { Button } from "../ui/button";
interface EditPopupProps {
popupVisible: boolean;
popupPosition: { x: number; y: number };
editText: string;
setEditText: (text: string) => void;
handleEditSubmit: () => void;
}
const EditPopup: React.FC<EditPopupProps> = ({
popupVisible,
popupPosition,
editText,
setEditText,
handleEditSubmit,
}) => {
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
useEffect(() => {
if (popupVisible && textareaRef.current) {
textareaRef.current.focus();
}
}, [popupVisible]);
// useEffect(() => {
// if (!popupVisible) {
// setEditText("");
// }
// }, [popupVisible, setEditText]);
return (
<div
className="absolute bg-white p-4 border border-gray-300 rounded shadow-lg"
style={{ top: popupPosition.y, left: popupPosition.x }}
>
<Textarea
ref={textareaRef}
value={editText}
onChange={(e) => setEditText(e.target.value)}
placeholder="Edit text"
/>
<Button onClick={handleEditSubmit} className="mt-2">
Submit
</Button>
</div>
);
};
export default EditPopup;