tldraw
Version:
A tiny little drawing editor.
110 lines (109 loc) • 3.34 kB
JavaScript
import { jsx } from "react/jsx-runtime";
import { isAccelKey, preventDefault } from "@tldraw/editor";
import { useEffect, useMemo, useState } from "react";
import { useUiEvents } from "../../context/events.mjs";
import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs";
import { TldrawUiButtonIcon } from "../primitives/Button/TldrawUiButtonIcon.mjs";
import { TldrawUiToolbarButton } from "../primitives/TldrawUiToolbar.mjs";
function DefaultRichTextToolbarContent({
textEditor,
onEditLinkStart
}) {
const trackEvent = useUiEvents();
const msg = useTranslation();
const source = "rich-text-menu";
const [_, set] = useState(0);
useEffect(
function forceUpdateWhenContentChanges() {
function forceUpdate() {
set((t) => t + 1);
}
textEditor.on("update", forceUpdate);
textEditor.on("selectionUpdate", forceUpdate);
},
[textEditor]
);
useEffect(() => {
function handleKeyDown(event) {
if (onEditLinkStart && isAccelKey(event) && event.shiftKey && event.key === "k") {
event.preventDefault();
onEditLinkStart();
}
}
document.addEventListener("keydown", handleKeyDown);
return () => {
document.removeEventListener("keydown", handleKeyDown);
};
}, [onEditLinkStart]);
const actions = useMemo(() => {
function handleOp(name, op) {
if (!textEditor.view) return;
trackEvent("rich-text", { operation: name, source });
textEditor.chain().focus()[op]().run();
}
return [
// { name: 'heading', attrs: { level: 3 }, onSelect() { textEditor.chain().focus().toggleHeading({ level: 3}).run() }},
{
name: "bold",
onSelect() {
handleOp("bold", "toggleBold");
}
},
{
name: "italic",
onSelect() {
handleOp("bold", "toggleItalic");
}
},
// { name: 'underline', onSelect() { handleOp('underline', 'toggleUnderline') }},
// { name: 'strike', onSelect() { handleOp('strike', 'toggleStrike') }},
{
name: "code",
onSelect() {
handleOp("bold", "toggleCode");
}
},
onEditLinkStart ? {
name: "link",
onSelect() {
onEditLinkStart();
}
} : void 0,
// ? is this really optional?
{
name: "bulletList",
onSelect() {
handleOp("bulletList", "toggleBulletList");
}
},
{
name: "highlight",
onSelect() {
handleOp("bulletList", "toggleHighlight");
}
}
].filter(Boolean);
}, [textEditor, trackEvent, onEditLinkStart]);
return actions.map(({ name, attrs, onSelect }) => {
const isActive = textEditor.view ? textEditor.isActive(name, attrs) : false;
return /* @__PURE__ */ jsx(
TldrawUiToolbarButton,
{
title: msg(`tool.rich-text-${name}`),
"data-testid": `rich-text.${name}`,
type: "icon",
isActive,
onPointerDown: preventDefault,
onClick: onSelect,
role: "option",
"aria-pressed": isActive,
children: /* @__PURE__ */ jsx(TldrawUiButtonIcon, { small: true, icon: name })
},
name
);
});
}
export {
DefaultRichTextToolbarContent
};
//# sourceMappingURL=DefaultRichTextToolbarContent.mjs.map