@tldraw/editor 3.16.0-canary.c349490eaef0 → 3.16.0-canary.c360426d8b7a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +28 -27
- package/dist-cjs/index.js +4 -2
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +2 -0
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +4 -4
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +0 -29
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +17 -17
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useDocumentEvents.js +4 -4
- package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js +1 -1
- package/dist-cjs/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useHandleEvents.js +6 -6
- package/dist-cjs/lib/hooks/useHandleEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useSelectionEvents.js +8 -8
- package/dist-cjs/lib/hooks/useSelectionEvents.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +2 -3
- package/dist-cjs/lib/license/Watermark.js.map +2 -2
- package/dist-cjs/lib/utils/dom.js +12 -1
- package/dist-cjs/lib/utils/dom.js.map +2 -2
- package/dist-cjs/lib/utils/getPointerInfo.js +3 -2
- package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +28 -27
- package/dist-esm/index.mjs +7 -3
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +2 -0
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -5
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +0 -29
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +24 -18
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDocumentEvents.mjs +10 -5
- package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs +2 -2
- package/dist-esm/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useHandleEvents.mjs +12 -7
- package/dist-esm/lib/hooks/useHandleEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useSelectionEvents.mjs +15 -9
- package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +3 -4
- package/dist-esm/lib/license/Watermark.mjs.map +2 -2
- package/dist-esm/lib/utils/dom.mjs +12 -1
- package/dist-esm/lib/utils/dom.mjs.map +2 -2
- package/dist-esm/lib/utils/getPointerInfo.mjs +3 -2
- package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +2 -0
- package/src/lib/TldrawEditor.tsx +2 -0
- package/src/lib/components/default-components/DefaultCanvas.tsx +5 -5
- package/src/lib/editor/Editor.ts +0 -33
- package/src/lib/hooks/useCanvasEvents.ts +24 -18
- package/src/lib/hooks/useDocumentEvents.ts +10 -5
- package/src/lib/hooks/useFixSafariDoubleTapZoomPencilEvents.ts +2 -2
- package/src/lib/hooks/useHandleEvents.ts +12 -7
- package/src/lib/hooks/useSelectionEvents.ts +15 -9
- package/src/lib/license/Watermark.tsx +3 -4
- package/src/lib/utils/dom.test.ts +24 -33
- package/src/lib/utils/dom.ts +31 -1
- package/src/lib/utils/getPointerInfo.ts +3 -3
- package/src/version.ts +3 -3
|
@@ -36,6 +36,15 @@ function releasePointerCapture(element, event) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
const stopEventPropagation = (e) => e.stopPropagation();
|
|
39
|
+
const handledEvents = /* @__PURE__ */ new WeakSet();
|
|
40
|
+
function markEventAsHandled(e) {
|
|
41
|
+
const nativeEvent = "nativeEvent" in e ? e.nativeEvent : e;
|
|
42
|
+
handledEvents.add(nativeEvent);
|
|
43
|
+
}
|
|
44
|
+
function wasEventAlreadyHandled(e) {
|
|
45
|
+
const nativeEvent = "nativeEvent" in e ? e.nativeEvent : e;
|
|
46
|
+
return handledEvents.has(nativeEvent);
|
|
47
|
+
}
|
|
39
48
|
const setStyleProperty = (elm, property, value) => {
|
|
40
49
|
if (!elm) return;
|
|
41
50
|
elm.style.setProperty(property, value);
|
|
@@ -48,10 +57,12 @@ function activeElementShouldCaptureKeys(allowButtons = false) {
|
|
|
48
57
|
export {
|
|
49
58
|
activeElementShouldCaptureKeys,
|
|
50
59
|
loopToHtmlElement,
|
|
60
|
+
markEventAsHandled,
|
|
51
61
|
preventDefault,
|
|
52
62
|
releasePointerCapture,
|
|
53
63
|
setPointerCapture,
|
|
54
64
|
setStyleProperty,
|
|
55
|
-
stopEventPropagation
|
|
65
|
+
stopEventPropagation,
|
|
66
|
+
wasEventAlreadyHandled
|
|
56
67
|
};
|
|
57
68
|
//# sourceMappingURL=dom.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/dom.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm.nodeType === Node.ELEMENT_NODE) return elm as HTMLElement\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent<Element> | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent<Element> | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/**\n * Calls `event.stopPropagation()`.\n *\n * @deprecated Use {@link
|
|
5
|
-
"mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,IAAI,aAAa,KAAK,aAAc,QAAO;AAC/C,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAUO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;
|
|
4
|
+
"sourcesContent": ["/*\nThis is used to facilitate double clicking and pointer capture on elements.\n\nThe events in this file are possibly set on individual SVG elements, \nsuch as handles or corner handles, rather than on HTML elements or \nSVGSVGElements. Raw SVG elemnets do not support pointerCapture in \nmost cases, meaning that in order for pointer capture to work, we \nneed to crawl up the DOM tree to find the nearest HTML element. Then,\nin order for that element to also call the `onPointerUp` event from\nthis file, we need to manually set that event on that element and\nlater remove it when the pointerup occurs. This is a potential leak\nif the user clicks on a handle but the pointerup does not fire for\nwhatever reason.\n*/\n\nimport React from 'react'\nimport { debugFlags, pointerCaptureTrackingObject } from './debug-flags'\n\n/** @public */\nexport function loopToHtmlElement(elm: Element): HTMLElement {\n\tif (elm.nodeType === Node.ELEMENT_NODE) return elm as HTMLElement\n\tif (elm.parentElement) return loopToHtmlElement(elm.parentElement)\n\telse throw Error('Could not find a parent element of an HTML type!')\n}\n\n/**\n * This function calls `event.preventDefault()` for you. Why is that useful?\n *\n * Beacuase if you enable `window.preventDefaultLogging = true` it'll log out a message when it\n * happens. Because we use console.warn rather than (log) you'll get a stack trace in the inspector\n * telling you exactly where it happened. This is important because `e.preventDefault()` is the\n * source of many bugs, but unfortuantly it can't be avoided because it also stops a lot of default\n * behaviour which doesn't make sense in our UI\n *\n * @param event - To prevent default on\n * @public\n */\nexport function preventDefault(event: React.BaseSyntheticEvent | Event) {\n\tevent.preventDefault()\n\tif (debugFlags.logPreventDefaults.get()) {\n\t\tconsole.warn('preventDefault called on event:', event)\n\t}\n}\n\n/** @public */\nexport function setPointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent<Element> | PointerEvent\n) {\n\telement.setPointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\ttrackingObj.set(element, (trackingObj.get(element) ?? 0) + 1)\n\t\tconsole.warn('setPointerCapture called on element:', element, event)\n\t}\n}\n\n/** @public */\nexport function releasePointerCapture(\n\telement: Element,\n\tevent: React.PointerEvent<Element> | PointerEvent\n) {\n\tif (!element.hasPointerCapture(event.pointerId)) {\n\t\treturn\n\t}\n\n\telement.releasePointerCapture(event.pointerId)\n\tif (debugFlags.logPointerCaptures.get()) {\n\t\tconst trackingObj = pointerCaptureTrackingObject.get()\n\t\tif (trackingObj.get(element) === 1) {\n\t\t\ttrackingObj.delete(element)\n\t\t} else if (trackingObj.has(element)) {\n\t\t\ttrackingObj.set(element, trackingObj.get(element)! - 1)\n\t\t} else {\n\t\t\tconsole.warn('Release without capture')\n\t\t}\n\t\tconsole.warn('releasePointerCapture called on element:', element, event)\n\t}\n}\n\n/**\n * Calls `event.stopPropagation()`.\n *\n * @deprecated Use {@link markEventAsHandled} instead, or manually call `event.stopPropagation()` if\n * that's what you really want.\n *\n * @public\n */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\n\nconst handledEvents = new WeakSet<Event>()\n\n/**\n * In tldraw, events are sometimes handled by multiple components. For example, the shapes might\n * have events, but the canvas handles events too. The way that the canvas handles events can\n * interfere with the with the shapes event handlers - for example, it calls `.preventDefault()` on\n * `pointerDown`, which also prevents `click` events from firing on the shapes.\n *\n * You can use `.stopPropagation()` to prevent the event from propagating to the rest of the DOM,\n * but that can impact non-tldraw event handlers set up elsewhere. By using `markEventAsHandled`,\n * you'll stop other parts of tldraw from handling the event without impacting other, non-tldraw\n * event handlers. See also {@link wasEventAlreadyHandled}.\n *\n * @public\n */\nexport function markEventAsHandled(e: Event | { nativeEvent: Event }) {\n\tconst nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e\n\thandledEvents.add(nativeEvent)\n}\n\n/**\n * Checks if an event has already been handled. See {@link markEventAsHandled}.\n *\n * @public\n */\nexport function wasEventAlreadyHandled(e: Event | { nativeEvent: Event }) {\n\tconst nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e\n\treturn handledEvents.has(nativeEvent)\n}\n\n/** @internal */\nexport const setStyleProperty = (\n\telm: HTMLElement | null,\n\tproperty: string,\n\tvalue: string | number\n) => {\n\tif (!elm) return\n\telm.style.setProperty(property, value as string)\n}\n\n/** @internal */\nexport function activeElementShouldCaptureKeys(allowButtons = false) {\n\tconst { activeElement } = document\n\tconst elements = allowButtons ? ['input', 'textarea'] : ['input', 'select', 'button', 'textarea']\n\treturn !!(\n\t\tactiveElement &&\n\t\t((activeElement as HTMLElement).isContentEditable ||\n\t\t\telements.indexOf(activeElement.tagName.toLowerCase()) > -1 ||\n\t\t\tactiveElement.classList.contains('tlui-slider__thumb'))\n\t)\n}\n"],
|
|
5
|
+
"mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,IAAI,aAAa,KAAK,aAAc,QAAO;AAC/C,MAAI,IAAI,cAAe,QAAO,kBAAkB,IAAI,aAAa;AAAA,MAC5D,OAAM,MAAM,kDAAkD;AACpE;AAcO,SAAS,eAAe,OAAyC;AACvE,QAAM,eAAe;AACrB,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,YAAQ,KAAK,mCAAmC,KAAK;AAAA,EACtD;AACD;AAGO,SAAS,kBACf,SACA,OACC;AACD,UAAQ,kBAAkB,MAAM,SAAS;AACzC,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,gBAAY,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,KAAK,CAAC;AAC5D,YAAQ,KAAK,wCAAwC,SAAS,KAAK;AAAA,EACpE;AACD;AAGO,SAAS,sBACf,SACA,OACC;AACD,MAAI,CAAC,QAAQ,kBAAkB,MAAM,SAAS,GAAG;AAChD;AAAA,EACD;AAEA,UAAQ,sBAAsB,MAAM,SAAS;AAC7C,MAAI,WAAW,mBAAmB,IAAI,GAAG;AACxC,UAAM,cAAc,6BAA6B,IAAI;AACrD,QAAI,YAAY,IAAI,OAAO,MAAM,GAAG;AACnC,kBAAY,OAAO,OAAO;AAAA,IAC3B,WAAW,YAAY,IAAI,OAAO,GAAG;AACpC,kBAAY,IAAI,SAAS,YAAY,IAAI,OAAO,IAAK,CAAC;AAAA,IACvD,OAAO;AACN,cAAQ,KAAK,yBAAyB;AAAA,IACvC;AACA,YAAQ,KAAK,4CAA4C,SAAS,KAAK;AAAA,EACxE;AACD;AAUO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAElE,MAAM,gBAAgB,oBAAI,QAAe;AAelC,SAAS,mBAAmB,GAAmC;AACrE,QAAM,cAAc,iBAAiB,IAAI,EAAE,cAAc;AACzD,gBAAc,IAAI,WAAW;AAC9B;AAOO,SAAS,uBAAuB,GAAmC;AACzE,QAAM,cAAc,iBAAiB,IAAI,EAAE,cAAc;AACzD,SAAO,cAAc,IAAI,WAAW;AACrC;AAGO,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;AAGO,SAAS,+BAA+B,eAAe,OAAO;AACpE,QAAM,EAAE,cAAc,IAAI;AAC1B,QAAM,WAAW,eAAe,CAAC,SAAS,UAAU,IAAI,CAAC,SAAS,UAAU,UAAU,UAAU;AAChG,SAAO,CAAC,EACP,kBACE,cAA8B,qBAC/B,SAAS,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI,MACxD,cAAc,UAAU,SAAS,oBAAoB;AAExD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/utils/getPointerInfo.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { markEventAsHandled } from './dom'\nimport { isAccelKey } from './keyboard'\n\n/** @public */\nexport function getPointerInfo(e: React.PointerEvent | PointerEvent) {\n\tmarkEventAsHandled(e)\n\n\treturn {\n\t\tpoint: {\n\t\t\tx: e.clientX,\n\t\t\ty: e.clientY,\n\t\t\tz: e.pressure,\n\t\t},\n\t\tshiftKey: e.shiftKey,\n\t\taltKey: e.altKey,\n\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\tmetaKey: e.metaKey,\n\t\taccelKey: isAccelKey(e),\n\t\tpointerId: e.pointerId,\n\t\tbutton: e.button,\n\t\tisPen: e.pointerType === 'pen',\n\t}\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAA0B;AACnC,SAAS,kBAAkB;AAGpB,SAAS,eAAe,GAAsC;AACpE,qBAAmB,CAAC;AAEpB,SAAO;AAAA,IACN,OAAO;AAAA,MACN,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,IACN;AAAA,IACA,UAAU,EAAE;AAAA,IACZ,QAAQ,EAAE;AAAA,IACV,SAAS,EAAE,WAAW,EAAE;AAAA,IACxB,SAAS,EAAE;AAAA,IACX,UAAU,WAAW,CAAC;AAAA,IACtB,WAAW,EAAE;AAAA,IACb,QAAQ,EAAE;AAAA,IACV,OAAO,EAAE,gBAAgB;AAAA,EAC1B;AACD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist-esm/version.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const version = "3.16.0-canary.
|
|
1
|
+
const version = "3.16.0-canary.c360426d8b7a";
|
|
2
2
|
const publishDates = {
|
|
3
3
|
major: "2024-09-13T14:36:29.063Z",
|
|
4
|
-
minor: "2025-09-
|
|
5
|
-
patch: "2025-09-
|
|
4
|
+
minor: "2025-09-17T15:16:03.696Z",
|
|
5
|
+
patch: "2025-09-17T15:16:03.696Z"
|
|
6
6
|
};
|
|
7
7
|
export {
|
|
8
8
|
publishDates,
|
package/dist-esm/version.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/version.ts"],
|
|
4
|
-
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.16.0-canary.
|
|
4
|
+
"sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.16.0-canary.c360426d8b7a'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-09-17T15:16:03.696Z',\n\tpatch: '2025-09-17T15:16:03.696Z',\n}\n"],
|
|
5
5
|
"mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (editor).",
|
|
4
|
-
"version": "3.16.0-canary.
|
|
4
|
+
"version": "3.16.0-canary.c360426d8b7a",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -50,12 +50,12 @@
|
|
|
50
50
|
"@tiptap/core": "^2.9.1",
|
|
51
51
|
"@tiptap/pm": "^2.9.1",
|
|
52
52
|
"@tiptap/react": "^2.9.1",
|
|
53
|
-
"@tldraw/state": "3.16.0-canary.
|
|
54
|
-
"@tldraw/state-react": "3.16.0-canary.
|
|
55
|
-
"@tldraw/store": "3.16.0-canary.
|
|
56
|
-
"@tldraw/tlschema": "3.16.0-canary.
|
|
57
|
-
"@tldraw/utils": "3.16.0-canary.
|
|
58
|
-
"@tldraw/validate": "3.16.0-canary.
|
|
53
|
+
"@tldraw/state": "3.16.0-canary.c360426d8b7a",
|
|
54
|
+
"@tldraw/state-react": "3.16.0-canary.c360426d8b7a",
|
|
55
|
+
"@tldraw/store": "3.16.0-canary.c360426d8b7a",
|
|
56
|
+
"@tldraw/tlschema": "3.16.0-canary.c360426d8b7a",
|
|
57
|
+
"@tldraw/utils": "3.16.0-canary.c360426d8b7a",
|
|
58
|
+
"@tldraw/validate": "3.16.0-canary.c360426d8b7a",
|
|
59
59
|
"@types/core-js": "^2.5.8",
|
|
60
60
|
"@use-gesture/react": "^10.3.1",
|
|
61
61
|
"classnames": "^2.5.1",
|
package/src/index.ts
CHANGED
|
@@ -447,10 +447,12 @@ export {
|
|
|
447
447
|
export {
|
|
448
448
|
activeElementShouldCaptureKeys,
|
|
449
449
|
loopToHtmlElement,
|
|
450
|
+
markEventAsHandled,
|
|
450
451
|
preventDefault,
|
|
451
452
|
releasePointerCapture,
|
|
452
453
|
setPointerCapture,
|
|
453
454
|
stopEventPropagation,
|
|
455
|
+
wasEventAlreadyHandled,
|
|
454
456
|
} from './lib/utils/dom'
|
|
455
457
|
export { EditorAtom } from './lib/utils/EditorAtom'
|
|
456
458
|
export { getIncrementedName } from './lib/utils/getIncrementedName'
|
package/src/lib/TldrawEditor.tsx
CHANGED
|
@@ -44,6 +44,7 @@ import { LicenseProvider } from './license/LicenseProvider'
|
|
|
44
44
|
import { Watermark } from './license/Watermark'
|
|
45
45
|
import { TldrawOptions } from './options'
|
|
46
46
|
import { TLDeepLinkOptions } from './utils/deepLinks'
|
|
47
|
+
import { markEventAsHandled } from './utils/dom'
|
|
47
48
|
import { TLTextOptions } from './utils/richText'
|
|
48
49
|
import { TLStoreWithStatus } from './utils/sync/StoreWithStatus'
|
|
49
50
|
|
|
@@ -274,6 +275,7 @@ export const TldrawEditor = memo(function TldrawEditor({
|
|
|
274
275
|
data-tldraw={version}
|
|
275
276
|
draggable={false}
|
|
276
277
|
className={classNames(`${TL_CONTAINER_CLASS} tl-theme__light`, className)}
|
|
278
|
+
onPointerDown={markEventAsHandled}
|
|
277
279
|
tabIndex={-1}
|
|
278
280
|
role="application"
|
|
279
281
|
aria-label={_options?.branding ?? 'tldraw'}
|
|
@@ -21,7 +21,7 @@ import { Mat } from '../../primitives/Mat'
|
|
|
21
21
|
import { Vec } from '../../primitives/Vec'
|
|
22
22
|
import { toDomPrecision } from '../../primitives/utils'
|
|
23
23
|
import { debugFlags } from '../../utils/debug-flags'
|
|
24
|
-
import { setStyleProperty } from '../../utils/dom'
|
|
24
|
+
import { markEventAsHandled, setStyleProperty } from '../../utils/dom'
|
|
25
25
|
import { GeometryDebuggingView } from '../GeometryDebuggingView'
|
|
26
26
|
import { LiveCollaborators } from '../LiveCollaborators'
|
|
27
27
|
import { MenuClickCapture } from '../MenuClickCapture'
|
|
@@ -174,10 +174,10 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
|
|
|
174
174
|
</div>
|
|
175
175
|
<div
|
|
176
176
|
className="tl-canvas__in-front"
|
|
177
|
-
onPointerDown={
|
|
178
|
-
onPointerUp={
|
|
179
|
-
onTouchStart={
|
|
180
|
-
onTouchEnd={
|
|
177
|
+
onPointerDown={markEventAsHandled}
|
|
178
|
+
onPointerUp={markEventAsHandled}
|
|
179
|
+
onTouchStart={markEventAsHandled}
|
|
180
|
+
onTouchEnd={markEventAsHandled}
|
|
181
181
|
>
|
|
182
182
|
<InFrontOfTheCanvasWrapper />
|
|
183
183
|
</div>
|
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -343,8 +343,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
343
343
|
this.root = new NewRoot(this)
|
|
344
344
|
this.root.children = {}
|
|
345
345
|
|
|
346
|
-
this.markEventAsHandled = this.markEventAsHandled.bind(this)
|
|
347
|
-
|
|
348
346
|
const allShapeUtils = checkShapesAndAddCore(shapeUtils)
|
|
349
347
|
|
|
350
348
|
const _shapeUtils = {} as Record<string, ShapeUtil<any>>
|
|
@@ -10099,37 +10097,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10099
10097
|
/** @internal */
|
|
10100
10098
|
private performanceTrackerTimeout = -1 as any
|
|
10101
10099
|
|
|
10102
|
-
/** @internal */
|
|
10103
|
-
private handledEvents = new WeakSet<Event>()
|
|
10104
|
-
|
|
10105
|
-
/**
|
|
10106
|
-
* In tldraw, events are sometimes handled by multiple components. For example, the shapes might
|
|
10107
|
-
* have events, but the canvas handles events too. The way that the canvas handles events can
|
|
10108
|
-
* interfere with the with the shapes event handlers - for example, it calls `.preventDefault()`
|
|
10109
|
-
* on `pointerDown`, which also prevents `click` events from firing on the shapes.
|
|
10110
|
-
*
|
|
10111
|
-
* You can use `.stopPropagation()` to prevent the event from propagating to the rest of the
|
|
10112
|
-
* DOM, but that can impact non-tldraw event handlers set up elsewhere. By using
|
|
10113
|
-
* `markEventAsHandled`, you'll stop other parts of tldraw from handling the event without
|
|
10114
|
-
* impacting other, non-tldraw event handlers. See also {@link Editor.wasEventAlreadyHandled}.
|
|
10115
|
-
*
|
|
10116
|
-
* @public
|
|
10117
|
-
*/
|
|
10118
|
-
markEventAsHandled(e: Event | { nativeEvent: Event }) {
|
|
10119
|
-
const nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e
|
|
10120
|
-
this.handledEvents.add(nativeEvent)
|
|
10121
|
-
}
|
|
10122
|
-
|
|
10123
|
-
/**
|
|
10124
|
-
* Checks if an event has already been handled. See {@link Editor.markEventAsHandled}.
|
|
10125
|
-
*
|
|
10126
|
-
* @public
|
|
10127
|
-
*/
|
|
10128
|
-
wasEventAlreadyHandled(e: Event | { nativeEvent: Event }) {
|
|
10129
|
-
const nativeEvent = 'nativeEvent' in e ? e.nativeEvent : e
|
|
10130
|
-
return this.handledEvents.has(nativeEvent)
|
|
10131
|
-
}
|
|
10132
|
-
|
|
10133
10100
|
/**
|
|
10134
10101
|
* Dispatch an event to the editor.
|
|
10135
10102
|
*
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { useValue } from '@tldraw/state-react'
|
|
2
2
|
import React, { useEffect, useMemo } from 'react'
|
|
3
3
|
import { RIGHT_MOUSE_BUTTON } from '../constants'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
markEventAsHandled,
|
|
6
|
+
preventDefault,
|
|
7
|
+
releasePointerCapture,
|
|
8
|
+
setPointerCapture,
|
|
9
|
+
wasEventAlreadyHandled,
|
|
10
|
+
} from '../utils/dom'
|
|
5
11
|
import { getPointerInfo } from '../utils/getPointerInfo'
|
|
6
12
|
import { useEditor } from './useEditor'
|
|
7
13
|
|
|
@@ -12,14 +18,14 @@ export function useCanvasEvents() {
|
|
|
12
18
|
const events = useMemo(
|
|
13
19
|
function canvasEvents() {
|
|
14
20
|
function onPointerDown(e: React.PointerEvent) {
|
|
15
|
-
if (
|
|
21
|
+
if (wasEventAlreadyHandled(e)) return
|
|
16
22
|
|
|
17
23
|
if (e.button === RIGHT_MOUSE_BUTTON) {
|
|
18
24
|
editor.dispatch({
|
|
19
25
|
type: 'pointer',
|
|
20
26
|
target: 'canvas',
|
|
21
27
|
name: 'right_click',
|
|
22
|
-
...getPointerInfo(
|
|
28
|
+
...getPointerInfo(e),
|
|
23
29
|
})
|
|
24
30
|
return
|
|
25
31
|
}
|
|
@@ -32,12 +38,12 @@ export function useCanvasEvents() {
|
|
|
32
38
|
type: 'pointer',
|
|
33
39
|
target: 'canvas',
|
|
34
40
|
name: 'pointer_down',
|
|
35
|
-
...getPointerInfo(
|
|
41
|
+
...getPointerInfo(e),
|
|
36
42
|
})
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
function onPointerUp(e: React.PointerEvent) {
|
|
40
|
-
if (
|
|
46
|
+
if (wasEventAlreadyHandled(e)) return
|
|
41
47
|
if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return
|
|
42
48
|
|
|
43
49
|
releasePointerCapture(e.currentTarget, e)
|
|
@@ -46,33 +52,33 @@ export function useCanvasEvents() {
|
|
|
46
52
|
type: 'pointer',
|
|
47
53
|
target: 'canvas',
|
|
48
54
|
name: 'pointer_up',
|
|
49
|
-
...getPointerInfo(
|
|
55
|
+
...getPointerInfo(e),
|
|
50
56
|
})
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
function onPointerEnter(e: React.PointerEvent) {
|
|
54
|
-
if (
|
|
60
|
+
if (wasEventAlreadyHandled(e)) return
|
|
55
61
|
if (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return
|
|
56
62
|
const canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'
|
|
57
63
|
editor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
function onPointerLeave(e: React.PointerEvent) {
|
|
61
|
-
if (
|
|
67
|
+
if (wasEventAlreadyHandled(e)) return
|
|
62
68
|
if (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return
|
|
63
69
|
const canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'
|
|
64
70
|
editor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
function onTouchStart(e: React.TouchEvent) {
|
|
68
|
-
if (
|
|
69
|
-
|
|
74
|
+
if (wasEventAlreadyHandled(e)) return
|
|
75
|
+
markEventAsHandled(e)
|
|
70
76
|
preventDefault(e)
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
function onTouchEnd(e: React.TouchEvent) {
|
|
74
|
-
if (
|
|
75
|
-
|
|
80
|
+
if (wasEventAlreadyHandled(e)) return
|
|
81
|
+
markEventAsHandled(e)
|
|
76
82
|
// check that e.target is an HTMLElement
|
|
77
83
|
if (!(e.target instanceof HTMLElement)) return
|
|
78
84
|
|
|
@@ -91,12 +97,12 @@ export function useCanvasEvents() {
|
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
function onDragOver(e: React.DragEvent<Element>) {
|
|
94
|
-
if (
|
|
100
|
+
if (wasEventAlreadyHandled(e)) return
|
|
95
101
|
preventDefault(e)
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
async function onDrop(e: React.DragEvent<Element>) {
|
|
99
|
-
if (
|
|
105
|
+
if (wasEventAlreadyHandled(e)) return
|
|
100
106
|
preventDefault(e)
|
|
101
107
|
e.stopPropagation()
|
|
102
108
|
|
|
@@ -123,7 +129,7 @@ export function useCanvasEvents() {
|
|
|
123
129
|
}
|
|
124
130
|
|
|
125
131
|
function onClick(e: React.MouseEvent) {
|
|
126
|
-
if (
|
|
132
|
+
if (wasEventAlreadyHandled(e)) return
|
|
127
133
|
e.stopPropagation()
|
|
128
134
|
}
|
|
129
135
|
|
|
@@ -151,8 +157,8 @@ export function useCanvasEvents() {
|
|
|
151
157
|
let lastX: number, lastY: number
|
|
152
158
|
|
|
153
159
|
function onPointerMove(e: PointerEvent) {
|
|
154
|
-
if (
|
|
155
|
-
|
|
160
|
+
if (wasEventAlreadyHandled(e)) return
|
|
161
|
+
markEventAsHandled(e)
|
|
156
162
|
|
|
157
163
|
if (e.clientX === lastX && e.clientY === lastY) return
|
|
158
164
|
lastX = e.clientX
|
|
@@ -168,7 +174,7 @@ export function useCanvasEvents() {
|
|
|
168
174
|
type: 'pointer',
|
|
169
175
|
target: 'canvas',
|
|
170
176
|
name: 'pointer_move',
|
|
171
|
-
...getPointerInfo(
|
|
177
|
+
...getPointerInfo(singleEvent),
|
|
172
178
|
})
|
|
173
179
|
}
|
|
174
180
|
}
|
|
@@ -2,7 +2,12 @@ import { useValue } from '@tldraw/state-react'
|
|
|
2
2
|
import { useEffect } from 'react'
|
|
3
3
|
import { Editor } from '../editor/Editor'
|
|
4
4
|
import { TLKeyboardEventInfo } from '../editor/types/event-types'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
activeElementShouldCaptureKeys,
|
|
7
|
+
markEventAsHandled,
|
|
8
|
+
preventDefault,
|
|
9
|
+
wasEventAlreadyHandled,
|
|
10
|
+
} from '../utils/dom'
|
|
6
11
|
import { isAccelKey } from '../utils/keyboard'
|
|
7
12
|
import { useContainer } from './useContainer'
|
|
8
13
|
import { useEditor } from './useEditor'
|
|
@@ -103,8 +108,8 @@ export function useDocumentEvents() {
|
|
|
103
108
|
preventDefault(e)
|
|
104
109
|
}
|
|
105
110
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
111
|
+
if (wasEventAlreadyHandled(e)) return
|
|
112
|
+
markEventAsHandled(e)
|
|
108
113
|
const hasSelectedShapes = !!editor.getSelectedShapeIds().length
|
|
109
114
|
|
|
110
115
|
switch (e.key) {
|
|
@@ -211,8 +216,8 @@ export function useDocumentEvents() {
|
|
|
211
216
|
}
|
|
212
217
|
|
|
213
218
|
const handleKeyUp = (e: KeyboardEvent) => {
|
|
214
|
-
if (
|
|
215
|
-
|
|
219
|
+
if (wasEventAlreadyHandled(e)) return
|
|
220
|
+
markEventAsHandled(e)
|
|
216
221
|
|
|
217
222
|
if (areShortcutsDisabled(editor)) {
|
|
218
223
|
return
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect } from 'react'
|
|
2
|
-
import { preventDefault } from '../utils/dom'
|
|
2
|
+
import { markEventAsHandled, preventDefault } from '../utils/dom'
|
|
3
3
|
import { useEditor } from './useEditor'
|
|
4
4
|
|
|
5
5
|
const IGNORED_TAGS = ['textarea', 'input']
|
|
@@ -19,7 +19,7 @@ export function useFixSafariDoubleTapZoomPencilEvents(ref: React.RefObject<HTMLE
|
|
|
19
19
|
|
|
20
20
|
const handleEvent = (e: PointerEvent | TouchEvent) => {
|
|
21
21
|
if (e instanceof PointerEvent && e.pointerType === 'pen') {
|
|
22
|
-
|
|
22
|
+
markEventAsHandled(e)
|
|
23
23
|
const { target } = e
|
|
24
24
|
|
|
25
25
|
// Allow events to propagate if the app is editing a shape, or if the event is occurring in a text area or input
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { TLArrowShape, TLLineShape, TLShapeId } from '@tldraw/tlschema'
|
|
2
2
|
import * as React from 'react'
|
|
3
3
|
import { Editor } from '../editor/Editor'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
loopToHtmlElement,
|
|
6
|
+
releasePointerCapture,
|
|
7
|
+
setPointerCapture,
|
|
8
|
+
wasEventAlreadyHandled,
|
|
9
|
+
} from '../utils/dom'
|
|
5
10
|
import { getPointerInfo } from '../utils/getPointerInfo'
|
|
6
11
|
import { useEditor } from './useEditor'
|
|
7
12
|
|
|
@@ -16,7 +21,7 @@ export function useHandleEvents(id: TLShapeId, handleId: string) {
|
|
|
16
21
|
|
|
17
22
|
return React.useMemo(() => {
|
|
18
23
|
const onPointerDown = (e: React.PointerEvent) => {
|
|
19
|
-
if (
|
|
24
|
+
if (wasEventAlreadyHandled(e)) return
|
|
20
25
|
|
|
21
26
|
// Must set pointer capture on an HTML element!
|
|
22
27
|
const target = loopToHtmlElement(e.currentTarget)
|
|
@@ -32,7 +37,7 @@ export function useHandleEvents(id: TLShapeId, handleId: string) {
|
|
|
32
37
|
handle,
|
|
33
38
|
shape,
|
|
34
39
|
name: 'pointer_down',
|
|
35
|
-
...getPointerInfo(
|
|
40
|
+
...getPointerInfo(e),
|
|
36
41
|
})
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -40,7 +45,7 @@ export function useHandleEvents(id: TLShapeId, handleId: string) {
|
|
|
40
45
|
let lastX: number, lastY: number
|
|
41
46
|
|
|
42
47
|
const onPointerMove = (e: React.PointerEvent) => {
|
|
43
|
-
if (
|
|
48
|
+
if (wasEventAlreadyHandled(e)) return
|
|
44
49
|
if (e.clientX === lastX && e.clientY === lastY) return
|
|
45
50
|
lastX = e.clientX
|
|
46
51
|
lastY = e.clientY
|
|
@@ -55,12 +60,12 @@ export function useHandleEvents(id: TLShapeId, handleId: string) {
|
|
|
55
60
|
handle,
|
|
56
61
|
shape,
|
|
57
62
|
name: 'pointer_move',
|
|
58
|
-
...getPointerInfo(
|
|
63
|
+
...getPointerInfo(e),
|
|
59
64
|
})
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
const onPointerUp = (e: React.PointerEvent) => {
|
|
63
|
-
if (
|
|
68
|
+
if (wasEventAlreadyHandled(e)) return
|
|
64
69
|
|
|
65
70
|
const target = loopToHtmlElement(e.currentTarget)
|
|
66
71
|
releasePointerCapture(target, e)
|
|
@@ -75,7 +80,7 @@ export function useHandleEvents(id: TLShapeId, handleId: string) {
|
|
|
75
80
|
handle,
|
|
76
81
|
shape,
|
|
77
82
|
name: 'pointer_up',
|
|
78
|
-
...getPointerInfo(
|
|
83
|
+
...getPointerInfo(e),
|
|
79
84
|
})
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { useMemo } from 'react'
|
|
2
2
|
import { RIGHT_MOUSE_BUTTON } from '../constants'
|
|
3
3
|
import { TLSelectionHandle } from '../editor/types/selection-types'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
loopToHtmlElement,
|
|
6
|
+
markEventAsHandled,
|
|
7
|
+
releasePointerCapture,
|
|
8
|
+
setPointerCapture,
|
|
9
|
+
wasEventAlreadyHandled,
|
|
10
|
+
} from '../utils/dom'
|
|
5
11
|
import { getPointerInfo } from '../utils/getPointerInfo'
|
|
6
12
|
import { useEditor } from './useEditor'
|
|
7
13
|
|
|
@@ -12,7 +18,7 @@ export function useSelectionEvents(handle: TLSelectionHandle) {
|
|
|
12
18
|
const events = useMemo(
|
|
13
19
|
function selectionEvents() {
|
|
14
20
|
const onPointerDown: React.PointerEventHandler = (e) => {
|
|
15
|
-
if (
|
|
21
|
+
if (wasEventAlreadyHandled(e)) return
|
|
16
22
|
|
|
17
23
|
if (e.button === RIGHT_MOUSE_BUTTON) {
|
|
18
24
|
editor.dispatch({
|
|
@@ -20,7 +26,7 @@ export function useSelectionEvents(handle: TLSelectionHandle) {
|
|
|
20
26
|
target: 'selection',
|
|
21
27
|
handle,
|
|
22
28
|
name: 'right_click',
|
|
23
|
-
...getPointerInfo(
|
|
29
|
+
...getPointerInfo(e),
|
|
24
30
|
})
|
|
25
31
|
return
|
|
26
32
|
}
|
|
@@ -47,16 +53,16 @@ export function useSelectionEvents(handle: TLSelectionHandle) {
|
|
|
47
53
|
type: 'pointer',
|
|
48
54
|
target: 'selection',
|
|
49
55
|
handle,
|
|
50
|
-
...getPointerInfo(
|
|
56
|
+
...getPointerInfo(e),
|
|
51
57
|
})
|
|
52
|
-
|
|
58
|
+
markEventAsHandled(e)
|
|
53
59
|
}
|
|
54
60
|
|
|
55
61
|
// Track the last screen point
|
|
56
62
|
let lastX: number, lastY: number
|
|
57
63
|
|
|
58
64
|
function onPointerMove(e: React.PointerEvent) {
|
|
59
|
-
if (
|
|
65
|
+
if (wasEventAlreadyHandled(e)) return
|
|
60
66
|
if (e.button !== 0) return
|
|
61
67
|
if (e.clientX === lastX && e.clientY === lastY) return
|
|
62
68
|
lastX = e.clientX
|
|
@@ -67,12 +73,12 @@ export function useSelectionEvents(handle: TLSelectionHandle) {
|
|
|
67
73
|
type: 'pointer',
|
|
68
74
|
target: 'selection',
|
|
69
75
|
handle,
|
|
70
|
-
...getPointerInfo(
|
|
76
|
+
...getPointerInfo(e),
|
|
71
77
|
})
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
const onPointerUp: React.PointerEventHandler = (e) => {
|
|
75
|
-
if (
|
|
81
|
+
if (wasEventAlreadyHandled(e)) return
|
|
76
82
|
if (e.button !== 0) return
|
|
77
83
|
|
|
78
84
|
editor.dispatch({
|
|
@@ -80,7 +86,7 @@ export function useSelectionEvents(handle: TLSelectionHandle) {
|
|
|
80
86
|
type: 'pointer',
|
|
81
87
|
target: 'selection',
|
|
82
88
|
handle,
|
|
83
|
-
...getPointerInfo(
|
|
89
|
+
...getPointerInfo(e),
|
|
84
90
|
})
|
|
85
91
|
}
|
|
86
92
|
|
|
@@ -3,7 +3,7 @@ import { memo, useRef } from 'react'
|
|
|
3
3
|
import { useCanvasEvents } from '../hooks/useCanvasEvents'
|
|
4
4
|
import { useEditor } from '../hooks/useEditor'
|
|
5
5
|
import { usePassThroughWheelEvents } from '../hooks/usePassThroughWheelEvents'
|
|
6
|
-
import { preventDefault } from '../utils/dom'
|
|
6
|
+
import { markEventAsHandled, preventDefault } from '../utils/dom'
|
|
7
7
|
import { runtime } from '../utils/runtime'
|
|
8
8
|
import { watermarkDesktopSvg, watermarkMobileSvg } from '../watermarks'
|
|
9
9
|
import { LicenseManager } from './LicenseManager'
|
|
@@ -43,7 +43,6 @@ const UnlicensedWatermark = memo(function UnlicensedWatermark({
|
|
|
43
43
|
isDebugMode: boolean
|
|
44
44
|
isMobile: boolean
|
|
45
45
|
}) {
|
|
46
|
-
const editor = useEditor()
|
|
47
46
|
const events = useCanvasEvents()
|
|
48
47
|
const ref = useRef<HTMLDivElement>(null)
|
|
49
48
|
usePassThroughWheelEvents(ref)
|
|
@@ -66,7 +65,7 @@ const UnlicensedWatermark = memo(function UnlicensedWatermark({
|
|
|
66
65
|
draggable={false}
|
|
67
66
|
role="button"
|
|
68
67
|
onPointerDown={(e) => {
|
|
69
|
-
|
|
68
|
+
markEventAsHandled(e)
|
|
70
69
|
preventDefault(e)
|
|
71
70
|
}}
|
|
72
71
|
title="The tldraw SDK requires a license key to work in production. You can get a free 100-day trial license at tldraw.dev/pricing."
|
|
@@ -116,7 +115,7 @@ const WatermarkInner = memo(function WatermarkInner({
|
|
|
116
115
|
draggable={false}
|
|
117
116
|
role="button"
|
|
118
117
|
onPointerDown={(e) => {
|
|
119
|
-
|
|
118
|
+
markEventAsHandled(e)
|
|
120
119
|
preventDefault(e)
|
|
121
120
|
}}
|
|
122
121
|
title="Build infinite canvas applications with the tldraw SDK. Learn more at https://tldraw.dev."
|