@tldraw/editor
Version:
tldraw infinite canvas SDK (editor).
225 lines (224 loc) • 8.08 kB
JavaScript
;
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