tldraw
Version:
A tiny little drawing editor.
90 lines (89 loc) • 3.69 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { preventDefault, useContainer, useEditor, useEditorComponents } from "@tldraw/editor";
import { ContextMenu as _ContextMenu } from "radix-ui";
import { memo, useCallback, useEffect } from "react";
import { useMenuIsOpen } from "../../hooks/useMenuIsOpen.mjs";
import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs";
import { TldrawUiMenuContextProvider } from "../primitives/menus/TldrawUiMenuContext.mjs";
import { DefaultContextMenuContent } from "./DefaultContextMenuContent.mjs";
const DefaultContextMenu = memo(function DefaultContextMenu2({
children,
disabled = false
}) {
const editor = useEditor();
const msg = useTranslation();
const { Canvas } = useEditorComponents();
const preventEscapeFromLosingShapeFocus = useCallback(
(e) => {
if (e.key === "Escape") {
e.stopPropagation();
editor.getContainer().focus();
}
},
[editor]
);
useEffect(() => {
return () => {
document.body.removeEventListener("keydown", preventEscapeFromLosingShapeFocus, {
capture: true
});
};
}, [preventEscapeFromLosingShapeFocus]);
const cb = useCallback(
(isOpen2) => {
if (!isOpen2) {
const onlySelectedShape = editor.getOnlySelectedShape();
if (onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)) {
editor.setSelectedShapes([]);
}
editor.timers.requestAnimationFrame(() => {
document.body.removeEventListener("keydown", preventEscapeFromLosingShapeFocus, {
capture: true
});
});
} else {
document.body.addEventListener("keydown", preventEscapeFromLosingShapeFocus, {
capture: true
});
if (editor.getInstanceState().isCoarsePointer) {
const selectedShapes = editor.getSelectedShapes();
const currentPagePoint = editor.inputs.getCurrentPagePoint();
const shapesAtPoint = editor.getShapesAtPoint(currentPagePoint);
if (
// if there are no selected shapes
!editor.getSelectedShapes().length || // OR if none of the shapes at the point include the selected shape
!shapesAtPoint.some((s) => selectedShapes.includes(s))
) {
const lockedShapes = shapesAtPoint.filter((s) => editor.isShapeOrAncestorLocked(s));
if (lockedShapes.length) {
editor.select(...lockedShapes.map((s) => s.id));
}
}
}
}
},
[editor, preventEscapeFromLosingShapeFocus]
);
const container = useContainer();
const [isOpen, handleOpenChange] = useMenuIsOpen("context menu", cb);
const content = children ?? /* @__PURE__ */ jsx(DefaultContextMenuContent, {});
return /* @__PURE__ */ jsxs(_ContextMenu.Root, { dir: "ltr", onOpenChange: handleOpenChange, modal: false, children: [
/* @__PURE__ */ jsx(_ContextMenu.Trigger, { onContextMenu: void 0, dir: "ltr", disabled, children: Canvas ? /* @__PURE__ */ jsx(Canvas, {}) : null }),
isOpen && /* @__PURE__ */ jsx(_ContextMenu.Portal, { container, children: /* @__PURE__ */ jsx(
_ContextMenu.Content,
{
className: "tlui-menu tlui-scrollable",
"data-testid": "context-menu",
"aria-label": msg("context-menu.title"),
alignOffset: -4,
collisionPadding: 4,
onContextMenu: preventDefault,
children: /* @__PURE__ */ jsx(TldrawUiMenuContextProvider, { type: "context-menu", sourceId: "context-menu", children: content })
}
) })
] });
});
export {
DefaultContextMenu
};
//# sourceMappingURL=DefaultContextMenu.mjs.map