@tldraw/editor 3.16.0-canary.f293c3bb58f5 → 3.16.0-canary.f55016ece635

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.
@@ -1,11 +1,14 @@
1
1
  import { useEffect } from "react";
2
2
  import { preventDefault } from "../utils/dom.mjs";
3
3
  import { useContainer } from "./useContainer.mjs";
4
+ import { useMaybeEditor } from "./useEditor.mjs";
4
5
  function usePassThroughWheelEvents(ref) {
5
6
  if (!ref) throw Error("usePassThroughWheelEvents must be passed a ref");
6
7
  const container = useContainer();
8
+ const editor = useMaybeEditor();
7
9
  useEffect(() => {
8
10
  function onWheel(e) {
11
+ if (!editor?.getInstanceState().isFocused) return;
9
12
  if (e.isSpecialRedispatchedEvent) return;
10
13
  const elm2 = ref.current;
11
14
  if (elm2 && elm2.scrollHeight > elm2.clientHeight) {
@@ -24,7 +27,7 @@ function usePassThroughWheelEvents(ref) {
24
27
  return () => {
25
28
  elm.removeEventListener("wheel", onWheel);
26
29
  };
27
- }, [container, ref]);
30
+ }, [container, editor, ref]);
28
31
  }
29
32
  export {
30
33
  usePassThroughWheelEvents
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/hooks/usePassThroughWheelEvents.ts"],
4
- "sourcesContent": ["import { RefObject, useEffect } from 'react'\nimport { preventDefault } from '../utils/dom'\nimport { useContainer } from './useContainer'\n\n/** @public */\nexport function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {\n\tif (!ref) throw Error('usePassThroughWheelEvents must be passed a ref')\n\tconst container = useContainer()\n\n\tuseEffect(() => {\n\t\tfunction onWheel(e: WheelEvent) {\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\n\t\t\t// if the element is scrollable, don't redispatch the event\n\t\t\tconst elm = ref.current\n\t\t\tif (elm && elm.scrollHeight > elm.clientHeight) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tconst cvs = container.querySelector('.tl-canvas')\n\t\t\tif (!cvs) return\n\t\t\tconst newEvent = new WheelEvent('wheel', e as any)\n\t\t\t;(newEvent as any).isSpecialRedispatchedEvent = true\n\t\t\tcvs.dispatchEvent(newEvent)\n\t\t}\n\n\t\tconst elm = ref.current\n\t\tif (!elm) return\n\n\t\telm.addEventListener('wheel', onWheel, { passive: false })\n\t\treturn () => {\n\t\t\telm.removeEventListener('wheel', onWheel)\n\t\t}\n\t}, [container, ref])\n}\n"],
5
- "mappings": "AAAA,SAAoB,iBAAiB;AACrC,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAGtB,SAAS,0BAA0B,KAA6B;AACtE,MAAI,CAAC,IAAK,OAAM,MAAM,gDAAgD;AACtE,QAAM,YAAY,aAAa;AAE/B,YAAU,MAAM;AACf,aAAS,QAAQ,GAAe;AAC/B,UAAK,EAAU,2BAA4B;AAG3C,YAAMA,OAAM,IAAI;AAChB,UAAIA,QAAOA,KAAI,eAAeA,KAAI,cAAc;AAC/C;AAAA,MACD;AAEA,qBAAe,CAAC;AAChB,YAAM,MAAM,UAAU,cAAc,YAAY;AAChD,UAAI,CAAC,IAAK;AACV,YAAM,WAAW,IAAI,WAAW,SAAS,CAAQ;AAChD,MAAC,SAAiB,6BAA6B;AAChD,UAAI,cAAc,QAAQ;AAAA,IAC3B;AAEA,UAAM,MAAM,IAAI;AAChB,QAAI,CAAC,IAAK;AAEV,QAAI,iBAAiB,SAAS,SAAS,EAAE,SAAS,MAAM,CAAC;AACzD,WAAO,MAAM;AACZ,UAAI,oBAAoB,SAAS,OAAO;AAAA,IACzC;AAAA,EACD,GAAG,CAAC,WAAW,GAAG,CAAC;AACpB;",
4
+ "sourcesContent": ["import { RefObject, useEffect } from 'react'\nimport { preventDefault } from '../utils/dom'\nimport { useContainer } from './useContainer'\nimport { useMaybeEditor } from './useEditor'\n\n/** @public */\nexport function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {\n\tif (!ref) throw Error('usePassThroughWheelEvents must be passed a ref')\n\tconst container = useContainer()\n\tconst editor = useMaybeEditor()\n\n\tuseEffect(() => {\n\t\tfunction onWheel(e: WheelEvent) {\n\t\t\t// Only pass through wheel events if the editor is focused\n\t\t\tif (!editor?.getInstanceState().isFocused) return\n\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\n\n\t\t\t// if the element is scrollable, don't redispatch the event\n\t\t\tconst elm = ref.current\n\t\t\tif (elm && elm.scrollHeight > elm.clientHeight) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpreventDefault(e)\n\t\t\tconst cvs = container.querySelector('.tl-canvas')\n\t\t\tif (!cvs) return\n\t\t\tconst newEvent = new WheelEvent('wheel', e as any)\n\t\t\t;(newEvent as any).isSpecialRedispatchedEvent = true\n\t\t\tcvs.dispatchEvent(newEvent)\n\t\t}\n\n\t\tconst elm = ref.current\n\t\tif (!elm) return\n\n\t\telm.addEventListener('wheel', onWheel, { passive: false })\n\t\treturn () => {\n\t\t\telm.removeEventListener('wheel', onWheel)\n\t\t}\n\t}, [container, editor, ref])\n}\n"],
5
+ "mappings": "AAAA,SAAoB,iBAAiB;AACrC,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAGxB,SAAS,0BAA0B,KAA6B;AACtE,MAAI,CAAC,IAAK,OAAM,MAAM,gDAAgD;AACtE,QAAM,YAAY,aAAa;AAC/B,QAAM,SAAS,eAAe;AAE9B,YAAU,MAAM;AACf,aAAS,QAAQ,GAAe;AAE/B,UAAI,CAAC,QAAQ,iBAAiB,EAAE,UAAW;AAE3C,UAAK,EAAU,2BAA4B;AAG3C,YAAMA,OAAM,IAAI;AAChB,UAAIA,QAAOA,KAAI,eAAeA,KAAI,cAAc;AAC/C;AAAA,MACD;AAEA,qBAAe,CAAC;AAChB,YAAM,MAAM,UAAU,cAAc,YAAY;AAChD,UAAI,CAAC,IAAK;AACV,YAAM,WAAW,IAAI,WAAW,SAAS,CAAQ;AAChD,MAAC,SAAiB,6BAA6B;AAChD,UAAI,cAAc,QAAQ;AAAA,IAC3B;AAEA,UAAM,MAAM,IAAI;AAChB,QAAI,CAAC,IAAK;AAEV,QAAI,iBAAiB,SAAS,SAAS,EAAE,SAAS,MAAM,CAAC;AACzD,WAAO,MAAM;AACZ,UAAI,oBAAoB,SAAS,OAAO;AAAA,IACzC;AAAA,EACD,GAAG,CAAC,WAAW,QAAQ,GAAG,CAAC;AAC5B;",
6
6
  "names": ["elm"]
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.16.0-canary.f293c3bb58f5";
1
+ const version = "3.16.0-canary.f55016ece635";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-08-21T12:41:23.735Z",
5
- patch: "2025-08-21T12:41:23.735Z"
4
+ minor: "2025-08-26T12:45:19.828Z",
5
+ patch: "2025-08-26T12:45:19.828Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -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.f293c3bb58f5'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-08-21T12:41:23.735Z',\n\tpatch: '2025-08-21T12:41:23.735Z',\n}\n"],
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.f55016ece635'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-08-26T12:45:19.828Z',\n\tpatch: '2025-08-26T12:45:19.828Z',\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/editor.css CHANGED
@@ -29,6 +29,7 @@
29
29
  --tl-layer-watermark: 200;
30
30
  --tl-layer-canvas-shapes: 300;
31
31
  --tl-layer-canvas-overlays: 500;
32
+ --tl-layer-canvas-in-front: 600;
32
33
  --tl-layer-canvas-blocker: 10000;
33
34
 
34
35
  /* Canvas overlays z-index */
@@ -297,6 +298,13 @@ input,
297
298
  contain: strict;
298
299
  }
299
300
 
301
+ .tl-canvas__in-front {
302
+ position: absolute;
303
+ inset: 0;
304
+ pointer-events: none;
305
+ z-index: var(--tl-layer-canvas-in-front);
306
+ }
307
+
300
308
  .tl-shapes {
301
309
  position: relative;
302
310
  z-index: var(--tl-layer-canvas-shapes);
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.f293c3bb58f5",
4
+ "version": "3.16.0-canary.f55016ece635",
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.f293c3bb58f5",
54
- "@tldraw/state-react": "3.16.0-canary.f293c3bb58f5",
55
- "@tldraw/store": "3.16.0-canary.f293c3bb58f5",
56
- "@tldraw/tlschema": "3.16.0-canary.f293c3bb58f5",
57
- "@tldraw/utils": "3.16.0-canary.f293c3bb58f5",
58
- "@tldraw/validate": "3.16.0-canary.f293c3bb58f5",
53
+ "@tldraw/state": "3.16.0-canary.f55016ece635",
54
+ "@tldraw/state-react": "3.16.0-canary.f55016ece635",
55
+ "@tldraw/store": "3.16.0-canary.f55016ece635",
56
+ "@tldraw/tlschema": "3.16.0-canary.f55016ece635",
57
+ "@tldraw/utils": "3.16.0-canary.f55016ece635",
58
+ "@tldraw/validate": "3.16.0-canary.f55016ece635",
59
59
  "@types/core-js": "^2.5.8",
60
60
  "@use-gesture/react": "^10.3.1",
61
61
  "classnames": "^2.5.1",
@@ -172,10 +172,12 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
172
172
  <LiveCollaborators />
173
173
  </div>
174
174
  </div>
175
+ <div className="tl-canvas__in-front">
176
+ <InFrontOfTheCanvasWrapper />
177
+ </div>
175
178
  <MovingCameraHitTestBlocker />
176
179
  </div>
177
180
  <MenuClickCapture />
178
- <InFrontOfTheCanvasWrapper />
179
181
  </>
180
182
  )
181
183
  }
@@ -9519,6 +9519,24 @@ export class Editor extends EventEmitter<TLEventMap> {
9519
9519
  }
9520
9520
  }
9521
9521
 
9522
+ /**
9523
+ * Get an exported image of the given shapes as a data URL.
9524
+ *
9525
+ * @param shapes - The shapes (or shape ids) to export.
9526
+ * @param opts - Options for the export.
9527
+ *
9528
+ * @returns A data URL of the image.
9529
+ * @public
9530
+ */
9531
+ async toImageDataUrl(shapes: TLShapeId[] | TLShape[], opts: TLImageExportOptions = {}) {
9532
+ const { blob, width, height } = await this.toImage(shapes, opts)
9533
+ return {
9534
+ url: await FileHelpers.blobToDataUrl(blob),
9535
+ width,
9536
+ height,
9537
+ }
9538
+ }
9539
+
9522
9540
  /* --------------------- Events --------------------- */
9523
9541
 
9524
9542
  /**
@@ -1,14 +1,19 @@
1
1
  import { RefObject, useEffect } from 'react'
2
2
  import { preventDefault } from '../utils/dom'
3
3
  import { useContainer } from './useContainer'
4
+ import { useMaybeEditor } from './useEditor'
4
5
 
5
6
  /** @public */
6
7
  export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
7
8
  if (!ref) throw Error('usePassThroughWheelEvents must be passed a ref')
8
9
  const container = useContainer()
10
+ const editor = useMaybeEditor()
9
11
 
10
12
  useEffect(() => {
11
13
  function onWheel(e: WheelEvent) {
14
+ // Only pass through wheel events if the editor is focused
15
+ if (!editor?.getInstanceState().isFocused) return
16
+
12
17
  if ((e as any).isSpecialRedispatchedEvent) return
13
18
 
14
19
  // if the element is scrollable, don't redispatch the event
@@ -32,5 +37,5 @@ export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
32
37
  return () => {
33
38
  elm.removeEventListener('wheel', onWheel)
34
39
  }
35
- }, [container, ref])
40
+ }, [container, editor, ref])
36
41
  }
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.16.0-canary.f293c3bb58f5'
4
+ export const version = '3.16.0-canary.f55016ece635'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-08-21T12:41:23.735Z',
8
- patch: '2025-08-21T12:41:23.735Z',
7
+ minor: '2025-08-26T12:45:19.828Z',
8
+ patch: '2025-08-26T12:45:19.828Z',
9
9
  }