@tldraw/editor 3.8.0-canary.fcad75fe42f9 → 3.8.0-canary.ff19d0d907b9

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.
Files changed (56) hide show
  1. package/dist-cjs/index.d.ts +48 -92
  2. package/dist-cjs/index.js +8 -9
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/config/TLSessionStateSnapshot.js.map +2 -2
  5. package/dist-cjs/lib/editor/Editor.js +2 -3
  6. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  7. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +2 -2
  8. package/dist-cjs/lib/editor/managers/TextManager.js +0 -1
  9. package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
  10. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  11. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  12. package/dist-cjs/lib/exports/StyleEmbedder.js.map +2 -2
  13. package/dist-cjs/lib/hooks/useDocumentEvents.js +3 -1
  14. package/dist-cjs/lib/hooks/useDocumentEvents.js.map +2 -2
  15. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +0 -4
  16. package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +3 -3
  17. package/dist-cjs/lib/options.js +1 -2
  18. package/dist-cjs/lib/options.js.map +2 -2
  19. package/dist-cjs/lib/utils/dom.js +0 -6
  20. package/dist-cjs/lib/utils/dom.js.map +2 -2
  21. package/dist-cjs/version.js +3 -3
  22. package/dist-cjs/version.js.map +1 -1
  23. package/dist-esm/index.d.mts +48 -92
  24. package/dist-esm/index.mjs +1 -3
  25. package/dist-esm/index.mjs.map +2 -2
  26. package/dist-esm/lib/config/TLSessionStateSnapshot.mjs.map +2 -2
  27. package/dist-esm/lib/editor/Editor.mjs +2 -3
  28. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  29. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +2 -2
  30. package/dist-esm/lib/editor/managers/TextManager.mjs +0 -1
  31. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  32. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +2 -2
  33. package/dist-esm/lib/hooks/useDocumentEvents.mjs +4 -2
  34. package/dist-esm/lib/hooks/useDocumentEvents.mjs.map +2 -2
  35. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +0 -4
  36. package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +3 -3
  37. package/dist-esm/lib/options.mjs +1 -2
  38. package/dist-esm/lib/options.mjs.map +2 -2
  39. package/dist-esm/lib/utils/dom.mjs +0 -6
  40. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  41. package/dist-esm/version.mjs +3 -3
  42. package/dist-esm/version.mjs.map +1 -1
  43. package/package.json +20 -20
  44. package/src/index.ts +1 -14
  45. package/src/lib/config/TLSessionStateSnapshot.ts +1 -3
  46. package/src/lib/editor/Editor.ts +18 -18
  47. package/src/lib/editor/managers/SnapManager/BoundsSnaps.ts +4 -4
  48. package/src/lib/editor/managers/TextManager.ts +0 -1
  49. package/src/lib/editor/types/emit-types.ts +0 -1
  50. package/src/lib/editor/types/external-content.ts +50 -90
  51. package/src/lib/exports/StyleEmbedder.ts +1 -1
  52. package/src/lib/hooks/useDocumentEvents.ts +11 -2
  53. package/src/lib/hooks/usePassThroughWheelEvents.ts +0 -7
  54. package/src/lib/options.ts +0 -5
  55. package/src/lib/utils/dom.ts +0 -12
  56. package/src/version.ts +3 -3
@@ -7,10 +7,6 @@ function usePassThroughWheelEvents(ref) {
7
7
  useEffect(() => {
8
8
  function onWheel(e) {
9
9
  if (e.isSpecialRedispatchedEvent) return;
10
- const elm2 = ref.current;
11
- if (elm2 && elm2.scrollHeight > elm2.clientHeight) {
12
- return;
13
- }
14
10
  preventDefault(e);
15
11
  const cvs = container.querySelector(".tl-canvas");
16
12
  if (!cvs) return;
@@ -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\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;AAEtE,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;",
6
- "names": ["elm"]
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\n\tconst container = useContainer()\n\n\tuseEffect(() => {\n\t\tfunction onWheel(e: WheelEvent) {\n\t\t\tif ((e as any).isSpecialRedispatchedEvent) return\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;AAEtE,QAAM,YAAY,aAAa;AAE/B,YAAU,MAAM;AACf,aAAS,QAAQ,GAAe;AAC/B,UAAK,EAAU,2BAA4B;AAC3C,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;",
6
+ "names": []
7
7
  }
@@ -43,8 +43,7 @@ const defaultTldrawOptions = {
43
43
  actionShortcutsLocation: "swap",
44
44
  createTextOnCanvasDoubleClick: true,
45
45
  exportProvider: Fragment,
46
- noteShapeResizeMode: "none",
47
- enableToolbarKeyboardShortcuts: true
46
+ noteShapeResizeMode: "none"
48
47
  };
49
48
  export {
50
49
  defaultTldrawOptions
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/options.ts"],
4
- "sourcesContent": ["import { ComponentType, Fragment } from 'react'\n\n/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial<TldrawOptions> = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return <Tldraw options={options} />\n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly maxPointsPerDrawShape: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\treadonly maxExportDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n\treadonly actionShortcutsLocation: 'menu' | 'toolbar' | 'swap'\n\treadonly createTextOnCanvasDoubleClick: boolean\n\t/**\n\t * The react provider to use when exporting an image. This is useful if your shapes depend on\n\t * external context providers. By default, this is `React.Fragment`.\n\t */\n\treadonly exportProvider: ComponentType<{ children: React.ReactNode }>\n\t/**\n\t * How should the note shape resize? By default it does not resize (except automatically based on its text content),\n\t * but you can set it to be user-resizable using scale.\n\t */\n\treadonly noteShapeResizeMode: 'none' | 'scale'\n\t/**\n\t * By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.\n\t */\n\treadonly enableToolbarKeyboardShortcuts: boolean\n}\n\n/** @public */\nexport const defaultTldrawOptions = {\n\tmaxShapesPerPage: 4000,\n\tmaxFilesAtOnce: 100,\n\tmaxPages: 40,\n\tanimationMediumMs: 320,\n\tfollowChaseViewportSnap: 2,\n\tdoubleClickDurationMs: 450,\n\tmultiClickDurationMs: 200,\n\tcoarseDragDistanceSquared: 36, // 6 squared\n\tdragDistanceSquared: 16, // 4 squared\n\tdefaultSvgPadding: 32,\n\tcameraSlideFriction: 0.09,\n\tmaxPointsPerDrawShape: 500,\n\tgridSteps: [\n\t\t{ min: -1, mid: 0.15, step: 64 },\n\t\t{ min: 0.05, mid: 0.375, step: 16 },\n\t\t{ min: 0.15, mid: 1, step: 4 },\n\t\t{ min: 0.7, mid: 2.5, step: 1 },\n\t],\n\tcollaboratorInactiveTimeoutMs: 60000,\n\tcollaboratorIdleTimeoutMs: 3000,\n\tcollaboratorCheckIntervalMs: 1200,\n\tcameraMovingTimeoutMs: 64,\n\thitTestMargin: 8,\n\tedgeScrollDelay: 200,\n\tedgeScrollEaseDuration: 200,\n\tedgeScrollSpeed: 25,\n\tedgeScrollDistance: 8,\n\tcoarsePointerWidth: 12,\n\tcoarseHandleRadius: 20,\n\thandleRadius: 12,\n\tlongPressDurationMs: 500,\n\ttextShadowLod: 0.35,\n\tadjacentShapeMargin: 10,\n\tflattenImageBoundsExpand: 64,\n\tflattenImageBoundsPadding: 16,\n\tlaserDelayMs: 1200,\n\tmaxExportDelayMs: 5000,\n\ttemporaryAssetPreviewLifetimeMs: 180000,\n\tactionShortcutsLocation: 'swap',\n\tcreateTextOnCanvasDoubleClick: true,\n\texportProvider: Fragment,\n\tnoteShapeResizeMode: 'none',\n\tenableToolbarKeyboardShortcuts: true,\n} as const satisfies TldrawOptions\n"],
5
- "mappings": "AAAA,SAAwB,gBAAgB;AAgFjC,MAAM,uBAAuB;AAAA,EACnC,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA;AAAA,EAC3B,qBAAqB;AAAA;AAAA,EACrB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,WAAW;AAAA,IACV,EAAE,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG;AAAA,IAC/B,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,GAAG;AAAA,IAClC,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,EAAE;AAAA,IAC7B,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,EAC/B;AAAA,EACA,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,gCAAgC;AACjC;",
4
+ "sourcesContent": ["import { ComponentType, Fragment } from 'react'\n\n/**\n * Options for configuring tldraw. For defaults, see {@link defaultTldrawOptions}.\n *\n * @example\n * ```tsx\n * const options: Partial<TldrawOptions> = {\n * maxPages: 3,\n * maxShapesPerPage: 1000,\n * }\n *\n * function MyTldrawComponent() {\n * return <Tldraw options={options} />\n * }\n * ```\n *\n * @public\n */\nexport interface TldrawOptions {\n\treadonly maxShapesPerPage: number\n\treadonly maxFilesAtOnce: number\n\treadonly maxPages: number\n\treadonly animationMediumMs: number\n\treadonly followChaseViewportSnap: number\n\treadonly doubleClickDurationMs: number\n\treadonly multiClickDurationMs: number\n\treadonly coarseDragDistanceSquared: number\n\treadonly dragDistanceSquared: number\n\treadonly defaultSvgPadding: number\n\treadonly cameraSlideFriction: number\n\treadonly maxPointsPerDrawShape: number\n\treadonly gridSteps: readonly {\n\t\treadonly min: number\n\t\treadonly mid: number\n\t\treadonly step: number\n\t}[]\n\treadonly collaboratorInactiveTimeoutMs: number\n\treadonly collaboratorIdleTimeoutMs: number\n\treadonly collaboratorCheckIntervalMs: number\n\treadonly cameraMovingTimeoutMs: number\n\treadonly hitTestMargin: number\n\treadonly edgeScrollDelay: number\n\treadonly edgeScrollEaseDuration: number\n\treadonly edgeScrollSpeed: number\n\treadonly edgeScrollDistance: number\n\treadonly coarsePointerWidth: number\n\treadonly coarseHandleRadius: number\n\treadonly handleRadius: number\n\treadonly longPressDurationMs: number\n\treadonly textShadowLod: number\n\treadonly adjacentShapeMargin: number\n\treadonly flattenImageBoundsExpand: number\n\treadonly flattenImageBoundsPadding: number\n\treadonly laserDelayMs: number\n\treadonly maxExportDelayMs: number\n\t/**\n\t * How long should previews created by {@link Editor.createTemporaryAssetPreview} last before\n\t * they expire? Defaults to 3 minutes.\n\t */\n\treadonly temporaryAssetPreviewLifetimeMs: number\n\treadonly actionShortcutsLocation: 'menu' | 'toolbar' | 'swap'\n\treadonly createTextOnCanvasDoubleClick: boolean\n\t/**\n\t * The react provider to use when exporting an image. This is useful if your shapes depend on\n\t * external context providers. By default, this is `React.Fragment`.\n\t */\n\treadonly exportProvider: ComponentType<{ children: React.ReactNode }>\n\t/**\n\t * How should the note shape resize? By default it does not resize (except automatically based on its text content),\n\t * but you can set it to be user-resizable using scale.\n\t */\n\treadonly noteShapeResizeMode: 'none' | 'scale'\n}\n\n/** @public */\nexport const defaultTldrawOptions = {\n\tmaxShapesPerPage: 4000,\n\tmaxFilesAtOnce: 100,\n\tmaxPages: 40,\n\tanimationMediumMs: 320,\n\tfollowChaseViewportSnap: 2,\n\tdoubleClickDurationMs: 450,\n\tmultiClickDurationMs: 200,\n\tcoarseDragDistanceSquared: 36, // 6 squared\n\tdragDistanceSquared: 16, // 4 squared\n\tdefaultSvgPadding: 32,\n\tcameraSlideFriction: 0.09,\n\tmaxPointsPerDrawShape: 500,\n\tgridSteps: [\n\t\t{ min: -1, mid: 0.15, step: 64 },\n\t\t{ min: 0.05, mid: 0.375, step: 16 },\n\t\t{ min: 0.15, mid: 1, step: 4 },\n\t\t{ min: 0.7, mid: 2.5, step: 1 },\n\t],\n\tcollaboratorInactiveTimeoutMs: 60000,\n\tcollaboratorIdleTimeoutMs: 3000,\n\tcollaboratorCheckIntervalMs: 1200,\n\tcameraMovingTimeoutMs: 64,\n\thitTestMargin: 8,\n\tedgeScrollDelay: 200,\n\tedgeScrollEaseDuration: 200,\n\tedgeScrollSpeed: 25,\n\tedgeScrollDistance: 8,\n\tcoarsePointerWidth: 12,\n\tcoarseHandleRadius: 20,\n\thandleRadius: 12,\n\tlongPressDurationMs: 500,\n\ttextShadowLod: 0.35,\n\tadjacentShapeMargin: 10,\n\tflattenImageBoundsExpand: 64,\n\tflattenImageBoundsPadding: 16,\n\tlaserDelayMs: 1200,\n\tmaxExportDelayMs: 5000,\n\ttemporaryAssetPreviewLifetimeMs: 180000,\n\tactionShortcutsLocation: 'swap',\n\tcreateTextOnCanvasDoubleClick: true,\n\texportProvider: Fragment,\n\tnoteShapeResizeMode: 'none',\n} as const satisfies TldrawOptions\n"],
5
+ "mappings": "AAAA,SAAwB,gBAAgB;AA4EjC,MAAM,uBAAuB;AAAA,EACnC,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,sBAAsB;AAAA,EACtB,2BAA2B;AAAA;AAAA,EAC3B,qBAAqB;AAAA;AAAA,EACrB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,WAAW;AAAA,IACV,EAAE,KAAK,IAAI,KAAK,MAAM,MAAM,GAAG;AAAA,IAC/B,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,GAAG;AAAA,IAClC,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,EAAE;AAAA,IAC7B,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,EAC/B;AAAA,EACA,+BAA+B;AAAA,EAC/B,2BAA2B;AAAA,EAC3B,6BAA6B;AAAA,EAC7B,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,qBAAqB;AAAA,EACrB,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA,EAC3B,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,iCAAiC;AAAA,EACjC,yBAAyB;AAAA,EACzB,+BAA+B;AAAA,EAC/B,gBAAgB;AAAA,EAChB,qBAAqB;AACtB;",
6
6
  "names": []
7
7
  }
@@ -40,13 +40,7 @@ const setStyleProperty = (elm, property, value) => {
40
40
  if (!elm) return;
41
41
  elm.style.setProperty(property, value);
42
42
  };
43
- const INPUTS = ["input", "select", "button", "textarea"];
44
- function activeElementShouldCaptureKeys() {
45
- const { activeElement } = document;
46
- return !!(activeElement && (activeElement.getAttribute("contenteditable") || INPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1));
47
- }
48
43
  export {
49
- activeElementShouldCaptureKeys,
50
44
  loopToHtmlElement,
51
45
  preventDefault,
52
46
  releasePointerCapture,
@@ -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 instanceof HTMLElement) return elm\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/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\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\nconst INPUTS = ['input', 'select', 'button', 'textarea']\n\n/** @internal */\nexport function activeElementShouldCaptureKeys() {\n\tconst { activeElement } = document\n\treturn !!(\n\t\tactiveElement &&\n\t\t(activeElement.getAttribute('contenteditable') ||\n\t\t\tINPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)\n\t)\n}\n"],
5
- "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,eAAe,YAAa,QAAO;AACvC,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;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;AAEA,MAAM,SAAS,CAAC,SAAS,UAAU,UAAU,UAAU;AAGhD,SAAS,iCAAiC;AAChD,QAAM,EAAE,cAAc,IAAI;AAC1B,SAAO,CAAC,EACP,kBACC,cAAc,aAAa,iBAAiB,KAC5C,OAAO,QAAQ,cAAc,QAAQ,YAAY,CAAC,IAAI;AAEzD;",
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 instanceof HTMLElement) return elm\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/** @public */\nexport const stopEventPropagation = (e: any) => e.stopPropagation()\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"],
5
+ "mappings": "AAgBA,SAAS,YAAY,oCAAoC;AAGlD,SAAS,kBAAkB,KAA2B;AAC5D,MAAI,eAAe,YAAa,QAAO;AACvC,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;AAGO,MAAM,uBAAuB,CAAC,MAAW,EAAE,gBAAgB;AAG3D,MAAM,mBAAmB,CAC/B,KACA,UACA,UACI;AACJ,MAAI,CAAC,IAAK;AACV,MAAI,MAAM,YAAY,UAAU,KAAe;AAChD;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.8.0-canary.fcad75fe42f9";
1
+ const version = "3.8.0-canary.ff19d0d907b9";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-02-07T10:08:19.720Z",
5
- patch: "2025-02-07T10:08:19.720Z"
4
+ minor: "2025-01-29T10:42:55.894Z",
5
+ patch: "2025-01-29T10:42:55.894Z"
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.8.0-canary.fcad75fe42f9'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-02-07T10:08:19.720Z',\n\tpatch: '2025-02-07T10:08:19.720Z',\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.8.0-canary.ff19d0d907b9'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-01-29T10:42:55.894Z',\n\tpatch: '2025-01-29T10:42:55.894Z',\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": "A tiny little drawing app (editor).",
4
- "version": "3.8.0-canary.fcad75fe42f9",
4
+ "version": "3.8.0-canary.ff19d0d907b9",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -45,37 +45,37 @@
45
45
  "lint": "yarn run -T tsx ../../internal/scripts/lint.ts"
46
46
  },
47
47
  "dependencies": {
48
- "@tldraw/state": "3.8.0-canary.fcad75fe42f9",
49
- "@tldraw/state-react": "3.8.0-canary.fcad75fe42f9",
50
- "@tldraw/store": "3.8.0-canary.fcad75fe42f9",
51
- "@tldraw/tlschema": "3.8.0-canary.fcad75fe42f9",
52
- "@tldraw/utils": "3.8.0-canary.fcad75fe42f9",
53
- "@tldraw/validate": "3.8.0-canary.fcad75fe42f9",
54
- "@types/core-js": "^2.5.8",
55
- "@use-gesture/react": "^10.3.1",
48
+ "@tldraw/state": "3.8.0-canary.ff19d0d907b9",
49
+ "@tldraw/state-react": "3.8.0-canary.ff19d0d907b9",
50
+ "@tldraw/store": "3.8.0-canary.ff19d0d907b9",
51
+ "@tldraw/tlschema": "3.8.0-canary.ff19d0d907b9",
52
+ "@tldraw/utils": "3.8.0-canary.ff19d0d907b9",
53
+ "@tldraw/validate": "3.8.0-canary.ff19d0d907b9",
54
+ "@types/core-js": "^2.5.5",
55
+ "@use-gesture/react": "^10.2.27",
56
56
  "canvas-size": "~2.0.0",
57
- "classnames": "^2.5.1",
58
- "core-js": "^3.40.0",
57
+ "classnames": "^2.3.2",
58
+ "core-js": "^3.31.1",
59
59
  "eventemitter3": "^4.0.7",
60
60
  "idb": "^7.1.1",
61
61
  "is-plain-object": "^5.0.0",
62
62
  "lodash.isequal": "^4.5.0"
63
63
  },
64
64
  "peerDependencies": {
65
- "react": "^18.2.0 || ^19.0.0",
66
- "react-dom": "^18.2.0 || ^19.0.0"
65
+ "react": "^18.2.0",
66
+ "react-dom": "^18.2.0"
67
67
  },
68
68
  "devDependencies": {
69
- "@peculiar/webcrypto": "^1.5.0",
70
- "@testing-library/jest-dom": "^5.17.0",
71
- "@testing-library/react": "^15.0.7",
72
- "@types/benchmark": "^2.1.5",
69
+ "@peculiar/webcrypto": "^1.4.0",
70
+ "@testing-library/jest-dom": "^5.16.5",
71
+ "@testing-library/react": "^15.0.6",
72
+ "@types/benchmark": "^2.1.2",
73
73
  "@types/canvas-size": "^1.2.2",
74
- "@types/wicg-file-system-access": "^2020.9.8",
74
+ "@types/wicg-file-system-access": "^2020.9.5",
75
75
  "benchmark": "^2.1.4",
76
- "fake-indexeddb": "^4.0.2",
76
+ "fake-indexeddb": "^4.0.0",
77
77
  "jest-canvas-mock": "^2.5.2",
78
- "jest-environment-jsdom": "^29.7.0",
78
+ "jest-environment-jsdom": "^29.4.3",
79
79
  "lazyrepo": "0.0.0-alpha.27",
80
80
  "resize-observer-polyfill": "^1.5.1"
81
81
  },
package/src/index.ts CHANGED
@@ -240,21 +240,9 @@ export {
240
240
  type UiEventType,
241
241
  } from './lib/editor/types/event-types'
242
242
  export {
243
- type TLBaseExternalContent,
244
- type TLEmbedExternalContent,
245
- type TLErrorExternalContentSource,
246
- type TLExcalidrawExternalContentSource,
247
- type TLExternalAsset,
243
+ type TLExternalAssetContent,
248
244
  type TLExternalContent,
249
245
  type TLExternalContentSource,
250
- type TLFileExternalAsset,
251
- type TLFilesExternalContent,
252
- type TLSvgTextExternalContent,
253
- type TLTextExternalContent,
254
- type TLTextExternalContentSource,
255
- type TLTldrawExternalContentSource,
256
- type TLUrlExternalAsset,
257
- type TLUrlExternalContent,
258
246
  } from './lib/editor/types/external-content'
259
247
  export {
260
248
  type TLHistoryBatchOptions,
@@ -413,7 +401,6 @@ export {
413
401
  type TLDeepLinkOptions,
414
402
  } from './lib/utils/deepLinks'
415
403
  export {
416
- activeElementShouldCaptureKeys,
417
404
  loopToHtmlElement,
418
405
  preventDefault,
419
406
  releasePointerCapture,
@@ -50,9 +50,7 @@ function iOS() {
50
50
  * @public
51
51
  */
52
52
  export const TAB_ID: string = window
53
- ? (window[tabIdKey] ??
54
- getFromSessionStorage(tabIdKey) ??
55
- `TLDRAW_INSTANCE_STATE_V1_` + uniqueId())
53
+ ? window[tabIdKey] ?? getFromSessionStorage(tabIdKey) ?? `TLDRAW_INSTANCE_STATE_V1_` + uniqueId()
56
54
  : '<error>'
57
55
  if (window) {
58
56
  window[tabIdKey] = TAB_ID
@@ -155,7 +155,7 @@ import {
155
155
  TLPointerEventInfo,
156
156
  TLWheelEventInfo,
157
157
  } from './types/event-types'
158
- import { TLExternalAsset, TLExternalContent } from './types/external-content'
158
+ import { TLExternalAssetContent, TLExternalContent } from './types/external-content'
159
159
  import { TLHistoryBatchOptions } from './types/history-types'
160
160
  import {
161
161
  OptionalKeys,
@@ -1400,8 +1400,8 @@ export class Editor extends EventEmitter<TLEventMap> {
1400
1400
  *
1401
1401
  * @example
1402
1402
  * ```ts
1403
- * editor.getStateDescendant('select')
1404
- * editor.getStateDescendant('select.brushing')
1403
+ * state.getStateDescendant('select')
1404
+ * state.getStateDescendant('select.brushing')
1405
1405
  * ```
1406
1406
  *
1407
1407
  * @param path - The descendant's path of state ids, separated by periods.
@@ -1681,7 +1681,7 @@ export class Editor extends EventEmitter<TLEventMap> {
1681
1681
  * @public
1682
1682
  */
1683
1683
  isAncestorSelected(shape: TLShape | TLShapeId): boolean {
1684
- const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
1684
+ const id = typeof shape === 'string' ? shape : shape?.id ?? null
1685
1685
  const _shape = this.getShape(id)
1686
1686
  if (!_shape) return false
1687
1687
  const selectedShapeIds = this.getSelectedShapeIds()
@@ -1938,7 +1938,7 @@ export class Editor extends EventEmitter<TLEventMap> {
1938
1938
  * @public
1939
1939
  */
1940
1940
  setFocusedGroup(shape: TLShapeId | TLGroupShape | null): this {
1941
- const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
1941
+ const id = typeof shape === 'string' ? shape : shape?.id ?? null
1942
1942
 
1943
1943
  if (id !== null) {
1944
1944
  const shape = this.getShape(id)
@@ -2021,7 +2021,7 @@ export class Editor extends EventEmitter<TLEventMap> {
2021
2021
  * @public
2022
2022
  */
2023
2023
  setEditingShape(shape: TLShapeId | TLShape | null): this {
2024
- const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
2024
+ const id = typeof shape === 'string' ? shape : shape?.id ?? null
2025
2025
  if (id !== this.getEditingShapeId()) {
2026
2026
  if (id) {
2027
2027
  const shape = this.getShape(id)
@@ -2082,7 +2082,7 @@ export class Editor extends EventEmitter<TLEventMap> {
2082
2082
  * @public
2083
2083
  */
2084
2084
  setHoveredShape(shape: TLShapeId | TLShape | null): this {
2085
- const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
2085
+ const id = typeof shape === 'string' ? shape : shape?.id ?? null
2086
2086
  if (id === this.getHoveredShapeId()) return this
2087
2087
  this.run(
2088
2088
  () => {
@@ -2231,7 +2231,7 @@ export class Editor extends EventEmitter<TLEventMap> {
2231
2231
  * @public
2232
2232
  */
2233
2233
  setCroppingShape(shape: TLShapeId | TLShape | null): this {
2234
- const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
2234
+ const id = typeof shape === 'string' ? shape : shape?.id ?? null
2235
2235
  if (id !== this.getCroppingShapeId()) {
2236
2236
  this.run(
2237
2237
  () => {
@@ -7975,8 +7975,10 @@ export class Editor extends EventEmitter<TLEventMap> {
7975
7975
 
7976
7976
  /** @internal */
7977
7977
  externalAssetContentHandlers: {
7978
- [K in TLExternalAsset['type']]: {
7979
- [Key in K]: null | ((info: TLExternalAsset & { type: Key }) => Promise<TLAsset | undefined>)
7978
+ [K in TLExternalAssetContent['type']]: {
7979
+ [Key in K]:
7980
+ | null
7981
+ | ((info: TLExternalAssetContent & { type: Key }) => Promise<TLAsset | undefined>)
7980
7982
  }[K]
7981
7983
  } = {
7982
7984
  file: null,
@@ -8005,9 +8007,9 @@ export class Editor extends EventEmitter<TLEventMap> {
8005
8007
  *
8006
8008
  * @public
8007
8009
  */
8008
- registerExternalAssetHandler<T extends TLExternalAsset['type']>(
8010
+ registerExternalAssetHandler<T extends TLExternalAssetContent['type']>(
8009
8011
  type: T,
8010
- handler: null | ((info: TLExternalAsset & { type: T }) => Promise<TLAsset>)
8012
+ handler: null | ((info: TLExternalAssetContent & { type: T }) => Promise<TLAsset>)
8011
8013
  ): this {
8012
8014
  this.externalAssetContentHandlers[type] = handler as any
8013
8015
  return this
@@ -8075,11 +8077,11 @@ export class Editor extends EventEmitter<TLEventMap> {
8075
8077
  * @param info - Info about the external content.
8076
8078
  * @returns The asset.
8077
8079
  */
8078
- async getAssetForExternalContent(info: TLExternalAsset): Promise<TLAsset | undefined> {
8080
+ async getAssetForExternalContent(info: TLExternalAssetContent): Promise<TLAsset | undefined> {
8079
8081
  return await this.externalAssetContentHandlers[info.type]?.(info as any)
8080
8082
  }
8081
8083
 
8082
- hasExternalAssetHandler(type: TLExternalAsset['type']): boolean {
8084
+ hasExternalAssetHandler(type: TLExternalAssetContent['type']): boolean {
8083
8085
  return !!this.externalAssetContentHandlers[type]
8084
8086
  }
8085
8087
 
@@ -8801,8 +8803,8 @@ export class Editor extends EventEmitter<TLEventMap> {
8801
8803
  // If our pointer moved only because we're following some other user, then don't
8802
8804
  // update our last activity timestamp; otherwise, update it to the current timestamp.
8803
8805
  info.type === 'pointer' && info.pointerId === INTERNAL_POINTER_IDS.CAMERA_MOVE
8804
- ? (this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??
8805
- this._tickManager.now)
8806
+ ? this.store.unsafeGetWithoutCapture(TLPOINTER_ID)?.lastActivityTimestamp ??
8807
+ this._tickManager.now
8806
8808
  : this._tickManager.now,
8807
8809
  meta: {},
8808
8810
  },
@@ -9367,8 +9369,6 @@ export class Editor extends EventEmitter<TLEventMap> {
9367
9369
  // todo: replace with new readonly mode?
9368
9370
  if (this.getCrashingError()) return this
9369
9371
 
9370
- this.emit('before-event', info)
9371
-
9372
9372
  const { inputs } = this
9373
9373
  const { type } = info
9374
9374
 
@@ -390,8 +390,8 @@ export class BoundsSnaps {
390
390
 
391
391
  // at the same time, calculate how far we need to nudge the shape to 'snap' to the target point(s)
392
392
  const nudge = new Vec(
393
- lockedAxis === 'x' ? 0 : (nearestSnapsX[0]?.nudge ?? 0),
394
- lockedAxis === 'y' ? 0 : (nearestSnapsY[0]?.nudge ?? 0)
393
+ lockedAxis === 'x' ? 0 : nearestSnapsX[0]?.nudge ?? 0,
394
+ lockedAxis === 'y' ? 0 : nearestSnapsY[0]?.nudge ?? 0
395
395
  )
396
396
 
397
397
  // ok we've figured out how much the box should be nudged, now let's find all the snap points
@@ -504,8 +504,8 @@ export class BoundsSnaps {
504
504
 
505
505
  // at the same time, calculate how far we need to nudge the shape to 'snap' to the target point(s)
506
506
  const nudge = new Vec(
507
- isXLocked ? 0 : (nearestSnapsX[0]?.nudge ?? 0),
508
- isYLocked ? 0 : (nearestSnapsY[0]?.nudge ?? 0)
507
+ isXLocked ? 0 : nearestSnapsX[0]?.nudge ?? 0,
508
+ isYLocked ? 0 : nearestSnapsY[0]?.nudge ?? 0
509
509
  )
510
510
 
511
511
  if (isAspectRatioLocked && isSelectionCorner(handle) && nudge.len() !== 0) {
@@ -230,7 +230,6 @@ export class TextManager {
230
230
  elm.style.setProperty('font-weight', opts.fontWeight)
231
231
  elm.style.setProperty('line-height', `${opts.lineHeight * opts.fontSize}px`)
232
232
  elm.style.setProperty('text-align', textAlignmentsForLtr[opts.textAlign])
233
- elm.style.setProperty('font-style', opts.fontStyle)
234
233
 
235
234
  const shouldTruncateToFirstLine =
236
235
  opts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'
@@ -12,7 +12,6 @@ export interface TLEventMap {
12
12
  crash: [{ error: unknown }]
13
13
  'stop-camera-animation': []
14
14
  'stop-following': []
15
- 'before-event': [TLEventInfo]
16
15
  event: [TLEventInfo]
17
16
  tick: [number]
18
17
  frame: [number]
@@ -2,97 +2,57 @@ import { TLAssetId } from '@tldraw/tlschema'
2
2
  import { VecLike } from '../../primitives/Vec'
3
3
  import { TLContent } from './clipboard-types'
4
4
 
5
- /** @public */
6
- export interface TLTldrawExternalContentSource {
7
- type: 'tldraw'
8
- data: TLContent
9
- }
10
-
11
- /** @public */
12
- export interface TLExcalidrawExternalContentSource {
13
- type: 'excalidraw'
14
- data: any
15
- }
16
-
17
- /** @public */
18
- export interface TLTextExternalContentSource {
19
- type: 'text'
20
- data: string
21
- subtype: 'json' | 'html' | 'text' | 'url'
22
- }
23
-
24
- /** @public */
25
- export interface TLErrorExternalContentSource {
26
- type: 'error'
27
- data: string | null
28
- reason: string
29
- }
30
-
31
5
  /** @public */
32
6
  export type TLExternalContentSource =
33
- | TLTldrawExternalContentSource
34
- | TLExcalidrawExternalContentSource
35
- | TLTextExternalContentSource
36
- | TLErrorExternalContentSource
37
-
38
- /** @public */
39
- export interface TLBaseExternalContent {
7
+ | {
8
+ type: 'tldraw'
9
+ data: TLContent
10
+ }
11
+ | {
12
+ type: 'excalidraw'
13
+ data: any
14
+ }
15
+ | {
16
+ type: 'text'
17
+ data: string
18
+ subtype: 'json' | 'html' | 'text' | 'url'
19
+ }
20
+ | {
21
+ type: 'error'
22
+ data: string | null
23
+ reason: string
24
+ }
25
+
26
+ /** @public */
27
+ export type TLExternalContent<EmbedDefinition> = {
40
28
  sources?: TLExternalContentSource[]
41
29
  point?: VecLike
42
- }
43
-
44
- /** @public */
45
- export interface TLTextExternalContent extends TLBaseExternalContent {
46
- type: 'text'
47
- text: string
48
- }
49
-
50
- /** @public */
51
- export interface TLFilesExternalContent extends TLBaseExternalContent {
52
- type: 'files'
53
- files: File[]
54
- ignoreParent: boolean
55
- }
56
-
57
- /** @public */
58
- export interface TLUrlExternalContent extends TLBaseExternalContent {
59
- type: 'url'
60
- url: string
61
- }
62
-
63
- /** @public */
64
- export interface TLSvgTextExternalContent extends TLBaseExternalContent {
65
- type: 'svg-text'
66
- text: string
67
- }
68
-
69
- /** @public */
70
- export interface TLEmbedExternalContent<EmbedDefinition> extends TLBaseExternalContent {
71
- type: 'embed'
72
- url: string
73
- embed: EmbedDefinition
74
- }
75
-
76
- /** @public */
77
- export type TLExternalContent<EmbedDefinition> =
78
- | TLTextExternalContent
79
- | TLFilesExternalContent
80
- | TLUrlExternalContent
81
- | TLSvgTextExternalContent
82
- | TLEmbedExternalContent<EmbedDefinition>
83
-
84
- /** @public */
85
- export interface TLFileExternalAsset {
86
- type: 'file'
87
- file: File
88
- assetId?: TLAssetId
89
- }
90
-
91
- /** @public */
92
- export interface TLUrlExternalAsset {
93
- type: 'url'
94
- url: string
95
- }
96
-
97
- /** @public */
98
- export type TLExternalAsset = TLFileExternalAsset | TLUrlExternalAsset
30
+ } & (
31
+ | {
32
+ type: 'text'
33
+ text: string
34
+ }
35
+ | {
36
+ type: 'files'
37
+ files: File[]
38
+ ignoreParent: boolean
39
+ }
40
+ | {
41
+ type: 'url'
42
+ url: string
43
+ }
44
+ | {
45
+ type: 'svg-text'
46
+ text: string
47
+ }
48
+ | {
49
+ type: 'embed'
50
+ url: string
51
+ embed: EmbedDefinition
52
+ }
53
+ )
54
+
55
+ /** @public */
56
+ export type TLExternalAssetContent =
57
+ | { type: 'file'; file: File; assetId?: TLAssetId }
58
+ | { type: 'url'; url: string }
@@ -54,7 +54,7 @@ export class StyleEmbedder {
54
54
  : NO_STYLES
55
55
 
56
56
  const parentStyles = shouldSkipInheritedParentStyles
57
- ? (this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES)
57
+ ? this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES
58
58
  : NO_STYLES
59
59
 
60
60
  const info: ElementStyleInfo = {
@@ -2,7 +2,7 @@ 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 { activeElementShouldCaptureKeys, preventDefault, stopEventPropagation } from '../utils/dom'
5
+ import { preventDefault, stopEventPropagation } from '../utils/dom'
6
6
  import { isAccelKey } from '../utils/keyboard'
7
7
  import { useContainer } from './useContainer'
8
8
  import { useEditor } from './useEditor'
@@ -274,6 +274,15 @@ export function useDocumentEvents() {
274
274
  }, [editor, container, isAppFocused])
275
275
  }
276
276
 
277
+ const INPUTS = ['input', 'select', 'button', 'textarea']
278
+
277
279
  function areShortcutsDisabled(editor: Editor) {
278
- return editor.menus.hasOpenMenus() || activeElementShouldCaptureKeys()
280
+ const { activeElement } = document
281
+
282
+ return (
283
+ editor.menus.hasOpenMenus() ||
284
+ (activeElement &&
285
+ (activeElement.getAttribute('contenteditable') ||
286
+ INPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1))
287
+ )
279
288
  }
@@ -11,13 +11,6 @@ export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
11
11
  useEffect(() => {
12
12
  function onWheel(e: WheelEvent) {
13
13
  if ((e as any).isSpecialRedispatchedEvent) return
14
-
15
- // if the element is scrollable, don't redispatch the event
16
- const elm = ref.current
17
- if (elm && elm.scrollHeight > elm.clientHeight) {
18
- return
19
- }
20
-
21
14
  preventDefault(e)
22
15
  const cvs = container.querySelector('.tl-canvas')
23
16
  if (!cvs) return
@@ -71,10 +71,6 @@ export interface TldrawOptions {
71
71
  * but you can set it to be user-resizable using scale.
72
72
  */
73
73
  readonly noteShapeResizeMode: 'none' | 'scale'
74
- /**
75
- * By default, the toolbar items are accessible via number shortcuts according to their order. To disable this, set this option to false.
76
- */
77
- readonly enableToolbarKeyboardShortcuts: boolean
78
74
  }
79
75
 
80
76
  /** @public */
@@ -121,5 +117,4 @@ export const defaultTldrawOptions = {
121
117
  createTextOnCanvasDoubleClick: true,
122
118
  exportProvider: Fragment,
123
119
  noteShapeResizeMode: 'none',
124
- enableToolbarKeyboardShortcuts: true,
125
120
  } as const satisfies TldrawOptions
@@ -90,15 +90,3 @@ export const setStyleProperty = (
90
90
  if (!elm) return
91
91
  elm.style.setProperty(property, value as string)
92
92
  }
93
-
94
- const INPUTS = ['input', 'select', 'button', 'textarea']
95
-
96
- /** @internal */
97
- export function activeElementShouldCaptureKeys() {
98
- const { activeElement } = document
99
- return !!(
100
- activeElement &&
101
- (activeElement.getAttribute('contenteditable') ||
102
- INPUTS.indexOf(activeElement.tagName.toLowerCase()) > -1)
103
- )
104
- }