import React, { useEffect, useState, useContext } from "react"; import { Box, Flex, Text, IconButton, Textarea } from "theme-ui"; import Slider from "../Slider"; import MapMenu from "../map/MapMenu"; import colors, { colorOptions } from "../../helpers/colors"; import usePrevious from "../../hooks/usePrevious"; import LockIcon from "../../icons/TokenLockIcon"; import UnlockIcon from "../../icons/TokenUnlockIcon"; import ShowIcon from "../../icons/TokenShowIcon"; import HideIcon from "../../icons/TokenHideIcon"; import NoteIcon from "../../icons/NoteToolIcon"; import TextIcon from "../../icons/NoteTextIcon"; import AuthContext from "../../contexts/AuthContext"; const defaultNoteMaxSize = 6; function NoteMenu({ isOpen, onRequestClose, note, noteNode, onNoteChange, map, }) { const { userId } = useContext(AuthContext); const wasOpen = usePrevious(isOpen); const [noteMaxSize, setNoteMaxSize] = useState(defaultNoteMaxSize); const [menuLeft, setMenuLeft] = useState(0); const [menuTop, setMenuTop] = useState(0); useEffect(() => { if (isOpen && !wasOpen && note) { setNoteMaxSize(Math.max(note.size, defaultNoteMaxSize)); // Update menu position if (noteNode) { const nodeRect = noteNode.getClientRect(); const mapElement = document.querySelector(".map"); const mapRect = mapElement.getBoundingClientRect(); // Center X for the menu which is 156px wide setMenuLeft(mapRect.left + nodeRect.x + nodeRect.width / 2 - 156 / 2); // Y 12px from the bottom setMenuTop(mapRect.top + nodeRect.y + nodeRect.height + 12); } } }, [isOpen, note, wasOpen, noteNode]); function handleTextChange(event) { const text = event.target.value.substring(0, 144); note && onNoteChange({ ...note, text: text }); } function handleColorChange(color) { if (!note) { return; } onNoteChange({ ...note, color: color }); } function handleSizeChange(event) { const newSize = parseFloat(event.target.value); note && onNoteChange({ ...note, size: newSize }); } function handleVisibleChange() { note && onNoteChange({ ...note, visible: !note.visible }); } function handleLockChange() { note && onNoteChange({ ...note, locked: !note.locked }); } function handleModeChange() { note && onNoteChange({ ...note, textOnly: !note.textOnly }); } function handleModalContent(node) { if (node) { // Focus input const tokenLabelInput = node.querySelector("#changeNoteText"); tokenLabelInput.focus(); tokenLabelInput.select(); // Ensure menu is in bounds const nodeRect = node.getBoundingClientRect(); const mapElement = document.querySelector(".map"); const mapRect = mapElement.getBoundingClientRect(); setMenuLeft((prevLeft) => Math.min( mapRect.right - nodeRect.width, Math.max(mapRect.left, prevLeft) ) ); setMenuTop((prevTop) => Math.min(mapRect.bottom - nodeRect.height, prevTop) ); } } function handleTextKeyPress(e) { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); onRequestClose(); } } return ( { e.preventDefault(); onRequestClose(); }} sx={{ alignItems: "center" }} >