UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

225 lines (224 loc) • 8.08 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var useDocumentEvents_exports = {}; __export(useDocumentEvents_exports, { useDocumentEvents: () => useDocumentEvents }); module.exports = __toCommonJS(useDocumentEvents_exports); var import_state_react = require("@tldraw/state-react"); var import_react = require("react"); var import_dom = require("../utils/dom"); var import_keyboard = require("../utils/keyboard"); var import_useContainer = require("./useContainer"); var import_useEditor = require("./useEditor"); function useDocumentEvents() { const editor = (0, import_useEditor.useEditor)(); const container = (0, import_useContainer.useContainer)(); const isEditing = (0, import_state_react.useValue)("isEditing", () => editor.getEditingShapeId(), [editor]); const isAppFocused = (0, import_state_react.useValue)("isFocused", () => editor.getIsFocused(), [editor]); (0, import_react.useEffect)(() => { if (!container) return; function onDrop(e) { if (e.isSpecialRedispatchedEvent) return; (0, import_dom.preventDefault)(e); (0, import_dom.stopEventPropagation)(e); const cvs = container.querySelector(".tl-canvas"); if (!cvs) return; const newEvent = new DragEvent(e.type, e); newEvent.isSpecialRedispatchedEvent = true; cvs.dispatchEvent(newEvent); } container.addEventListener("dragover", onDrop); container.addEventListener("drop", onDrop); return () => { container.removeEventListener("dragover", onDrop); container.removeEventListener("drop", onDrop); }; }, [container]); (0, import_react.useEffect)(() => { if (typeof window === "undefined" || !("matchMedia" in window)) return; let remove = null; const updatePixelRatio = () => { if (remove != null) { remove(); } const mqString = `(resolution: ${window.devicePixelRatio}dppx)`; const media = matchMedia(mqString); const safariCb = (ev) => { if (ev.type === "change") { updatePixelRatio(); } }; if (media.addEventListener) { media.addEventListener("change", updatePixelRatio); } else if (media.addListener) { media.addListener(safariCb); } remove = () => { if (media.removeEventListener) { media.removeEventListener("change", updatePixelRatio); } else if (media.removeListener) { media.removeListener(safariCb); } }; editor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio }); }; updatePixelRatio(); return () => { remove?.(); }; }, [editor]); (0, import_react.useEffect)(() => { if (!isAppFocused) return; const handleKeyDown = (e) => { if (e.altKey && // todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them? (editor.isIn("zoom") || !editor.getPath().endsWith(".idle")) && !areShortcutsDisabled(editor)) { (0, import_dom.preventDefault)(e); } if (e.isKilled) return; e.isKilled = true; const hasSelectedShapes = !!editor.getSelectedShapeIds().length; switch (e.key) { case "=": case "-": case "0": { if (e.metaKey || e.ctrlKey) { (0, import_dom.preventDefault)(e); return; } break; } case "Tab": { if (areShortcutsDisabled(editor)) { return; } if (hasSelectedShapes && !isEditing) { (0, import_dom.preventDefault)(e); } break; } case "ArrowLeft": case "ArrowRight": case "ArrowUp": case "ArrowDown": { if (areShortcutsDisabled(editor)) { return; } if (hasSelectedShapes && (e.metaKey || e.ctrlKey)) { (0, import_dom.preventDefault)(e); } break; } case ",": { return; } case "Escape": { if (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) { (0, import_dom.preventDefault)(e); } if (editor.menus.getOpenMenus().length > 0) return; if (editor.inputs.keys.has("Escape")) { } else { editor.inputs.keys.add("Escape"); editor.cancel(); container.focus(); } return; } default: { if (areShortcutsDisabled(editor)) { return; } } } const info = { type: "keyboard", name: e.repeat ? "key_repeat" : "key_down", key: e.key, code: e.code, shiftKey: e.shiftKey, altKey: e.altKey, ctrlKey: e.metaKey || e.ctrlKey, metaKey: e.metaKey, accelKey: (0, import_keyboard.isAccelKey)(e) }; editor.dispatch(info); }; const handleKeyUp = (e) => { if (e.isKilled) return; e.isKilled = true; if (areShortcutsDisabled(editor)) { return; } if (e.key === ",") { return; } const info = { type: "keyboard", name: "key_up", key: e.key, code: e.code, shiftKey: e.shiftKey, altKey: e.altKey, ctrlKey: e.metaKey || e.ctrlKey, metaKey: e.metaKey, accelKey: (0, import_keyboard.isAccelKey)(e) }; editor.dispatch(info); }; function handleTouchStart(e) { if (container.contains(e.target)) { const touchXPosition = e.touches[0].pageX; const touchXRadius = e.touches[0].radiusX || 0; if (touchXPosition - touchXRadius < 10 || touchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10) { if (e.target?.tagName === "BUTTON") { ; e.target?.click(); } (0, import_dom.preventDefault)(e); } } } const handleWheel = (e) => { if (container.contains(e.target) && (e.ctrlKey || e.metaKey)) { (0, import_dom.preventDefault)(e); } }; container.addEventListener("touchstart", handleTouchStart, { passive: false }); container.addEventListener("wheel", handleWheel, { passive: false }); document.addEventListener("gesturestart", import_dom.preventDefault); document.addEventListener("gesturechange", import_dom.preventDefault); document.addEventListener("gestureend", import_dom.preventDefault); container.addEventListener("keydown", handleKeyDown); container.addEventListener("keyup", handleKeyUp); return () => { container.removeEventListener("touchstart", handleTouchStart); container.removeEventListener("wheel", handleWheel); document.removeEventListener("gesturestart", import_dom.preventDefault); document.removeEventListener("gesturechange", import_dom.preventDefault); document.removeEventListener("gestureend", import_dom.preventDefault); container.removeEventListener("keydown", handleKeyDown); container.removeEventListener("keyup", handleKeyUp); }; }, [editor, container, isAppFocused, isEditing]); } function areShortcutsDisabled(editor) { return editor.menus.hasOpenMenus() || (0, import_dom.activeElementShouldCaptureKeys)(); } //# sourceMappingURL=useDocumentEvents.js.map