UNPKG

tldraw

Version:

A tiny little drawing editor.

111 lines (110 loc) 3.94 kB
import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { openWindow, preventDefault, useEditor } from "@tldraw/editor"; import { useCallback, useEffect, useRef, useState } from "react"; import { useUiEvents } from "../../context/events.mjs"; import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs"; import { TldrawUiButton } from "../primitives/Button/TldrawUiButton.mjs"; import { TldrawUiButtonIcon } from "../primitives/Button/TldrawUiButtonIcon.mjs"; import { TldrawUiInput } from "../primitives/TldrawUiInput.mjs"; function LinkEditor({ textEditor, value: initialValue, onClose }) { const editor = useEditor(); const [value, setValue] = useState(initialValue); const msg = useTranslation(); const ref = useRef(null); const trackEvent = useUiEvents(); const source = "rich-text-menu"; const linkifiedValue = value.startsWith("http") ? value : `https://${value}`; const handleValueChange = (value2) => setValue(value2); const handleLinkComplete = useCallback( (link) => { trackEvent("rich-text", { operation: "link-edit", source }); if (!link.startsWith("http://") && !link.startsWith("https://")) { link = `https://${link}`; } textEditor.chain().setLink({ href: link }).run(); if (editor.getInstanceState().isCoarsePointer) { textEditor.commands.blur(); } else { textEditor.commands.focus(); } onClose(); }, [trackEvent, source, textEditor, editor, onClose] ); const handleVisitLink = () => { trackEvent("rich-text", { operation: "link-visit", source }); openWindow(linkifiedValue, "_blank"); onClose(); }; const handleRemoveLink = useCallback(() => { trackEvent("rich-text", { operation: "link-remove", source }); textEditor.chain().unsetLink().focus().run(); onClose(); }, [trackEvent, source, textEditor, onClose]); const handleLinkCancel = () => onClose(); useEffect(() => { const handlePointerDown = (e) => { const toolbar = document.querySelector(".tlui-rich-text__toolbar"); if (toolbar?.contains(e.target)) return; if (value) { handleLinkComplete(value); } else { handleRemoveLink(); } }; document.addEventListener("pointerdown", handlePointerDown, { capture: true }); return () => { document.removeEventListener("pointerdown", handlePointerDown, { capture: true }); }; }, [handleLinkComplete, handleRemoveLink, value]); useEffect(() => { ref.current?.focus(); }, [value]); useEffect(() => { setValue(initialValue); }, [initialValue]); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( TldrawUiInput, { ref, "data-testid": "rich-text.link-input", className: "tlui-rich-text__toolbar-link-input", value, onValueChange: handleValueChange, onComplete: handleLinkComplete, onCancel: handleLinkCancel, placeholder: "example.com", "aria-label": "example.com" } ), /* @__PURE__ */ jsx( TldrawUiButton, { className: "tlui-rich-text__toolbar-link-visit", title: msg("tool.rich-text-link-visit"), type: "icon", onPointerDown: preventDefault, onClick: handleVisitLink, disabled: !value, children: /* @__PURE__ */ jsx(TldrawUiButtonIcon, { small: true, icon: "external-link" }) } ), /* @__PURE__ */ jsx( TldrawUiButton, { className: "tlui-rich-text__toolbar-link-remove", title: msg("tool.rich-text-link-remove"), "data-testid": "rich-text.link-remove", type: "icon", onPointerDown: preventDefault, onClick: handleRemoveLink, children: /* @__PURE__ */ jsx(TldrawUiButtonIcon, { small: true, icon: "trash" }) } ) ] }); } export { LinkEditor }; //# sourceMappingURL=LinkEditor.mjs.map