import { useEffect, useState } from "react"; /* Icons the main app does not already provide, drawn to match its stroke style. */ const strokeProps = { width: 15, height: 15, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", }; const TableIcon = () => ( ); const LinkIcon = () => ( ); const QuoteIcon = () => ( ); const CodeIcon = () => ( ); const AtIcon = () => ( ); /** * Formatting controls for the note body. * * Reads its active states straight off the editor, so the buttons reflect the * cursor even when formatting changed by keyboard shortcut. */ export function EditorToolbar({ editor, T, icons, compact }) { const [, force] = useState(0); const [showTable, setShowTable] = useState(false); // ProseMirror state changes do not go through React; subscribe so the active // states stay in sync with the cursor. useEffect(() => { if (!editor) return; const rerender = () => force((n) => n + 1); editor.on("transaction", rerender); editor.on("selectionUpdate", rerender); return () => { editor.off("transaction", rerender); editor.off("selectionUpdate", rerender); }; }, [editor]); useEffect(() => { if (!showTable) return; const close = (e) => { if (!e.target.closest?.("[data-table-menu]")) setShowTable(false); }; document.addEventListener("pointerdown", close); return () => document.removeEventListener("pointerdown", close); }, [showTable]); if (!editor) return null; const btn = (active) => ({ display: "flex", alignItems: "center", justifyContent: "center", width: 30, height: 30, borderRadius: 6, border: "none", cursor: "pointer", background: active ? T.active + "22" : "transparent", color: active ? T.active : T.text, transition: "all .12s", flexShrink: 0, }); const divider = (
); const inTable = editor.isActive("table"); const menuItem = { display: "block", width: "100%", padding: "6px 10px", border: "none", borderRadius: 6, background: "transparent", color: T.text, fontSize: 12, textAlign: "left", cursor: "pointer", }; const promptLink = () => { const previous = editor.getAttributes("link").href || ""; const url = window.prompt("Link URL (leave empty to remove)", previous); if (url === null) return; if (url === "") { editor.chain().focus().extendMarkRange("link").unsetLink().run(); return; } if (!/^(https?|mailto):/i.test(url)) { window.alert("Only http(s) and mailto links are allowed."); return; } editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run(); }; return ( <> {divider} {divider} {/* Tables */}
{showTable && (
{inTable && ( <>
)}
)}
{!compact && ( <> {divider} )} {divider} {divider} ); } export default EditorToolbar;