@tldraw/editor 3.12.0-canary.e08eba00c6c8 → 3.12.0-canary.e45d65cbc328

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.
@@ -5545,14 +5545,12 @@ export declare abstract class StateNode implements Partial<TLEventHandlers> {
5545
5545
  static initial?: string;
5546
5546
  static children?: () => TLStateNodeConstructor[];
5547
5547
  static isLockable: boolean;
5548
- static useCoalescedEvents: boolean;
5549
5548
  id: string;
5550
5549
  type: 'branch' | 'leaf' | 'root';
5551
5550
  shapeType?: string;
5552
5551
  initial?: string;
5553
5552
  children?: Record<string, StateNode>;
5554
5553
  isLockable: boolean;
5555
- useCoalescedEvents: boolean;
5556
5554
  parent: StateNode;
5557
5555
  /**
5558
5556
  * This node's path of active state nodes
@@ -7166,7 +7164,6 @@ export declare interface TLStateNodeConstructor {
7166
7164
  initial?: string;
7167
7165
  children?(): TLStateNodeConstructor[];
7168
7166
  isLockable: boolean;
7169
- useCoalescedEvents: boolean;
7170
7167
  }
7171
7168
 
7172
7169
  /** @public */
package/dist-cjs/index.js CHANGED
@@ -376,7 +376,7 @@ function debugEnableLicensing() {
376
376
  }
377
377
  (0, import_utils.registerTldrawLibraryVersion)(
378
378
  "@tldraw/editor",
379
- "3.12.0-canary.e08eba00c6c8",
379
+ "3.12.0-canary.e45d65cbc328",
380
380
  "cjs"
381
381
  );
382
382
  //# sourceMappingURL=index.js.map
@@ -41,7 +41,7 @@ const STATE_NODES_TO_MEASURE = [
41
41
  class StateNode {
42
42
  constructor(editor, parent) {
43
43
  this.editor = editor;
44
- const { id, children, initial, isLockable, useCoalescedEvents } = this.constructor;
44
+ const { id, children, initial, isLockable } = this.constructor;
45
45
  this.id = id;
46
46
  this._isActive = (0, import_state.atom)("toolIsActive" + this.id, false);
47
47
  this._current = (0, import_state.atom)("toolState" + this.id, void 0);
@@ -72,7 +72,6 @@ class StateNode {
72
72
  }
73
73
  }
74
74
  this.isLockable = isLockable;
75
- this.useCoalescedEvents = useCoalescedEvents;
76
75
  this.performanceTracker = new import_utils.PerformanceTracker();
77
76
  }
78
77
  performanceTracker;
@@ -80,14 +79,12 @@ class StateNode {
80
79
  static initial;
81
80
  static children;
82
81
  static isLockable = true;
83
- static useCoalescedEvents = false;
84
82
  id;
85
83
  type;
86
84
  shapeType;
87
85
  initial;
88
86
  children;
89
87
  isLockable;
90
- useCoalescedEvents;
91
88
  parent;
92
89
  /**
93
90
  * This node's path of active state nodes
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/tools/StateNode.ts"],
4
- "sourcesContent": ["import { Atom, Computed, atom, computed } from '@tldraw/state'\nimport { PerformanceTracker } from '@tldraw/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport type { Editor } from '../Editor'\nimport {\n\tEVENT_NAME_MAP,\n\tTLCancelEventInfo,\n\tTLClickEventInfo,\n\tTLCompleteEventInfo,\n\tTLEventHandlers,\n\tTLEventInfo,\n\tTLInterruptEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLTickEventInfo,\n\tTLWheelEventInfo,\n} from '../types/event-types'\n\nconst STATE_NODES_TO_MEASURE = [\n\t'brushing',\n\t'cropping',\n\t'dragging',\n\t'dragging_handle',\n\t'drawing',\n\t'erasing',\n\t'lasering',\n\t'resizing',\n\t'rotating',\n\t'scribble_brushing',\n\t'translating',\n]\n\n/** @public */\nexport interface TLStateNodeConstructor {\n\tnew (editor: Editor, parent?: StateNode): StateNode\n\tid: string\n\tinitial?: string\n\tchildren?(): TLStateNodeConstructor[]\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n}\n\n/** @public */\nexport abstract class StateNode implements Partial<TLEventHandlers> {\n\tperformanceTracker: PerformanceTracker\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tparent?: StateNode\n\t) {\n\t\tconst { id, children, initial, isLockable, useCoalescedEvents } = this\n\t\t\t.constructor as TLStateNodeConstructor\n\n\t\tthis.id = id\n\t\tthis._isActive = atom<boolean>('toolIsActive' + this.id, false)\n\t\tthis._current = atom<StateNode | undefined>('toolState' + this.id, undefined)\n\n\t\tthis._path = computed('toolPath' + this.id, () => {\n\t\t\tconst current = this.getCurrent()\n\t\t\treturn this.id + (current ? `.${current.getPath()}` : '')\n\t\t})\n\n\t\tthis.parent = parent ?? ({} as any)\n\n\t\tif (this.parent) {\n\t\t\tif (children && initial) {\n\t\t\t\tthis.type = 'branch'\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t} else {\n\t\t\t\tthis.type = 'leaf'\n\t\t\t}\n\t\t} else {\n\t\t\tthis.type = 'root'\n\n\t\t\tif (children && initial) {\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t}\n\t\t}\n\t\tthis.isLockable = isLockable\n\t\tthis.useCoalescedEvents = useCoalescedEvents\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tstatic id: string\n\tstatic initial?: string\n\tstatic children?: () => TLStateNodeConstructor[]\n\tstatic isLockable = true\n\tstatic useCoalescedEvents = false\n\n\tid: string\n\ttype: 'branch' | 'leaf' | 'root'\n\tshapeType?: string\n\tinitial?: string\n\tchildren?: Record<string, StateNode>\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n\tparent: StateNode\n\n\t/**\n\t * This node's path of active state nodes\n\t *\n\t * @public\n\t */\n\tgetPath() {\n\t\treturn this._path.get()\n\t}\n\t_path: Computed<string>\n\n\t/**\n\t * This node's current active child node, if any.\n\t *\n\t * @public\n\t */\n\tgetCurrent() {\n\t\treturn this._current.get()\n\t}\n\tprivate _current: Atom<StateNode | undefined>\n\n\t/**\n\t * Whether this node is active.\n\t *\n\t * @public\n\t */\n\tgetIsActive() {\n\t\treturn this._isActive.get()\n\t}\n\tprivate _isActive: Atom<boolean>\n\n\t/**\n\t * Transition to a new active child state node.\n\t *\n\t * @example\n\t * ```ts\n\t * parentState.transition('childStateA')\n\t * parentState.transition('childStateB', { myData: 4 })\n\t *```\n\t *\n\t * @param id - The id of the child state node to transition to.\n\t * @param info - Any data to pass to the `onEnter` and `onExit` handlers.\n\t *\n\t * @public\n\t */\n\ttransition(id: string, info: any = {}) {\n\t\tconst path = id.split('.')\n\n\t\tlet currState = this as StateNode\n\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tconst id = path[i]\n\t\t\tconst prevChildState = currState.getCurrent()\n\t\t\tconst nextChildState = currState.children?.[id]\n\n\t\t\tif (!nextChildState) {\n\t\t\t\tthrow Error(`${currState.id} - no child state exists with the id ${id}.`)\n\t\t\t}\n\n\t\t\tif (prevChildState?.id !== nextChildState.id) {\n\t\t\t\tprevChildState?.exit(info, id)\n\t\t\t\tcurrState._current.set(nextChildState)\n\t\t\t\tnextChildState.enter(info, prevChildState?.id || 'initial')\n\t\t\t\tif (!nextChildState.getIsActive()) break\n\t\t\t}\n\n\t\t\tcurrState = nextChildState\n\t\t}\n\n\t\treturn this\n\t}\n\n\thandleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>) {\n\t\tconst cbName = EVENT_NAME_MAP[info.name]\n\t\tconst currentActiveChild = this._current.__unsafe__getWithoutCapture()\n\n\t\tthis[cbName]?.(info as any)\n\t\tif (\n\t\t\tthis._isActive.__unsafe__getWithoutCapture() &&\n\t\t\tcurrentActiveChild &&\n\t\t\tcurrentActiveChild === this._current.__unsafe__getWithoutCapture()\n\t\t) {\n\t\t\tcurrentActiveChild.handleEvent(info)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\tenter(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && STATE_NODES_TO_MEASURE.includes(this.id)) {\n\t\t\tthis.performanceTracker.start(this.id)\n\t\t}\n\n\t\tthis._isActive.set(true)\n\t\tthis.onEnter?.(info, from)\n\n\t\tif (this.children && this.initial && this.getIsActive()) {\n\t\t\tconst initial = this.children[this.initial]\n\t\t\tthis._current.set(initial)\n\t\t\tinitial.enter(info, from)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\texit(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {\n\t\t\tthis.performanceTracker.stop()\n\t\t}\n\t\tthis._isActive.set(false)\n\t\tthis.onExit?.(info, from)\n\n\t\tif (!this.getIsActive()) {\n\t\t\tthis.getCurrent()?.exit(info, from)\n\t\t}\n\t}\n\n\t/**\n\t * This is a hack / escape hatch that will tell the editor to\n\t * report a different state as active (in `getCurrentToolId()`) when\n\t * this state is active. This is usually used when a tool transitions\n\t * to a child of a different state for a certain interaction and then\n\t * returns to the original tool when that interaction completes; and\n\t * where we would want to show the original tool as active in the UI.\n\t *\n\t * @public\n\t */\n\t_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)\n\n\tgetCurrentToolIdMask() {\n\t\treturn this._currentToolIdMask.get()\n\t}\n\n\tsetCurrentToolIdMask(id: string | undefined) {\n\t\tthis._currentToolIdMask.set(id)\n\t}\n\n\tonWheel?(info: TLWheelEventInfo): void\n\tonPointerDown?(info: TLPointerEventInfo): void\n\tonPointerMove?(info: TLPointerEventInfo): void\n\tonLongPress?(info: TLPointerEventInfo): void\n\tonPointerUp?(info: TLPointerEventInfo): void\n\tonDoubleClick?(info: TLClickEventInfo): void\n\tonTripleClick?(info: TLClickEventInfo): void\n\tonQuadrupleClick?(info: TLClickEventInfo): void\n\tonRightClick?(info: TLPointerEventInfo): void\n\tonMiddleClick?(info: TLPointerEventInfo): void\n\tonKeyDown?(info: TLKeyboardEventInfo): void\n\tonKeyUp?(info: TLKeyboardEventInfo): void\n\tonKeyRepeat?(info: TLKeyboardEventInfo): void\n\tonCancel?(info: TLCancelEventInfo): void\n\tonComplete?(info: TLCompleteEventInfo): void\n\tonInterrupt?(info: TLInterruptEventInfo): void\n\tonTick?(info: TLTickEventInfo): void\n\n\tonEnter?(info: any, from: string): void\n\tonExit?(info: any, to: string): void\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Atom, Computed, atom, computed } from '@tldraw/state'\nimport { PerformanceTracker } from '@tldraw/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport type { Editor } from '../Editor'\nimport {\n\tEVENT_NAME_MAP,\n\tTLCancelEventInfo,\n\tTLClickEventInfo,\n\tTLCompleteEventInfo,\n\tTLEventHandlers,\n\tTLEventInfo,\n\tTLInterruptEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLTickEventInfo,\n\tTLWheelEventInfo,\n} from '../types/event-types'\n\nconst STATE_NODES_TO_MEASURE = [\n\t'brushing',\n\t'cropping',\n\t'dragging',\n\t'dragging_handle',\n\t'drawing',\n\t'erasing',\n\t'lasering',\n\t'resizing',\n\t'rotating',\n\t'scribble_brushing',\n\t'translating',\n]\n\n/** @public */\nexport interface TLStateNodeConstructor {\n\tnew (editor: Editor, parent?: StateNode): StateNode\n\tid: string\n\tinitial?: string\n\tchildren?(): TLStateNodeConstructor[]\n\tisLockable: boolean\n}\n\n/** @public */\nexport abstract class StateNode implements Partial<TLEventHandlers> {\n\tperformanceTracker: PerformanceTracker\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tparent?: StateNode\n\t) {\n\t\tconst { id, children, initial, isLockable } = this.constructor as TLStateNodeConstructor\n\n\t\tthis.id = id\n\t\tthis._isActive = atom<boolean>('toolIsActive' + this.id, false)\n\t\tthis._current = atom<StateNode | undefined>('toolState' + this.id, undefined)\n\n\t\tthis._path = computed('toolPath' + this.id, () => {\n\t\t\tconst current = this.getCurrent()\n\t\t\treturn this.id + (current ? `.${current.getPath()}` : '')\n\t\t})\n\n\t\tthis.parent = parent ?? ({} as any)\n\n\t\tif (this.parent) {\n\t\t\tif (children && initial) {\n\t\t\t\tthis.type = 'branch'\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t} else {\n\t\t\t\tthis.type = 'leaf'\n\t\t\t}\n\t\t} else {\n\t\t\tthis.type = 'root'\n\n\t\t\tif (children && initial) {\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t}\n\t\t}\n\t\tthis.isLockable = isLockable\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tstatic id: string\n\tstatic initial?: string\n\tstatic children?: () => TLStateNodeConstructor[]\n\tstatic isLockable = true\n\n\tid: string\n\ttype: 'branch' | 'leaf' | 'root'\n\tshapeType?: string\n\tinitial?: string\n\tchildren?: Record<string, StateNode>\n\tisLockable: boolean\n\tparent: StateNode\n\n\t/**\n\t * This node's path of active state nodes\n\t *\n\t * @public\n\t */\n\tgetPath() {\n\t\treturn this._path.get()\n\t}\n\t_path: Computed<string>\n\n\t/**\n\t * This node's current active child node, if any.\n\t *\n\t * @public\n\t */\n\tgetCurrent() {\n\t\treturn this._current.get()\n\t}\n\tprivate _current: Atom<StateNode | undefined>\n\n\t/**\n\t * Whether this node is active.\n\t *\n\t * @public\n\t */\n\tgetIsActive() {\n\t\treturn this._isActive.get()\n\t}\n\tprivate _isActive: Atom<boolean>\n\n\t/**\n\t * Transition to a new active child state node.\n\t *\n\t * @example\n\t * ```ts\n\t * parentState.transition('childStateA')\n\t * parentState.transition('childStateB', { myData: 4 })\n\t *```\n\t *\n\t * @param id - The id of the child state node to transition to.\n\t * @param info - Any data to pass to the `onEnter` and `onExit` handlers.\n\t *\n\t * @public\n\t */\n\ttransition(id: string, info: any = {}) {\n\t\tconst path = id.split('.')\n\n\t\tlet currState = this as StateNode\n\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tconst id = path[i]\n\t\t\tconst prevChildState = currState.getCurrent()\n\t\t\tconst nextChildState = currState.children?.[id]\n\n\t\t\tif (!nextChildState) {\n\t\t\t\tthrow Error(`${currState.id} - no child state exists with the id ${id}.`)\n\t\t\t}\n\n\t\t\tif (prevChildState?.id !== nextChildState.id) {\n\t\t\t\tprevChildState?.exit(info, id)\n\t\t\t\tcurrState._current.set(nextChildState)\n\t\t\t\tnextChildState.enter(info, prevChildState?.id || 'initial')\n\t\t\t\tif (!nextChildState.getIsActive()) break\n\t\t\t}\n\n\t\t\tcurrState = nextChildState\n\t\t}\n\n\t\treturn this\n\t}\n\n\thandleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>) {\n\t\tconst cbName = EVENT_NAME_MAP[info.name]\n\t\tconst currentActiveChild = this._current.__unsafe__getWithoutCapture()\n\n\t\tthis[cbName]?.(info as any)\n\t\tif (\n\t\t\tthis._isActive.__unsafe__getWithoutCapture() &&\n\t\t\tcurrentActiveChild &&\n\t\t\tcurrentActiveChild === this._current.__unsafe__getWithoutCapture()\n\t\t) {\n\t\t\tcurrentActiveChild.handleEvent(info)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\tenter(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && STATE_NODES_TO_MEASURE.includes(this.id)) {\n\t\t\tthis.performanceTracker.start(this.id)\n\t\t}\n\n\t\tthis._isActive.set(true)\n\t\tthis.onEnter?.(info, from)\n\n\t\tif (this.children && this.initial && this.getIsActive()) {\n\t\t\tconst initial = this.children[this.initial]\n\t\t\tthis._current.set(initial)\n\t\t\tinitial.enter(info, from)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\texit(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {\n\t\t\tthis.performanceTracker.stop()\n\t\t}\n\t\tthis._isActive.set(false)\n\t\tthis.onExit?.(info, from)\n\n\t\tif (!this.getIsActive()) {\n\t\t\tthis.getCurrent()?.exit(info, from)\n\t\t}\n\t}\n\n\t/**\n\t * This is a hack / escape hatch that will tell the editor to\n\t * report a different state as active (in `getCurrentToolId()`) when\n\t * this state is active. This is usually used when a tool transitions\n\t * to a child of a different state for a certain interaction and then\n\t * returns to the original tool when that interaction completes; and\n\t * where we would want to show the original tool as active in the UI.\n\t *\n\t * @public\n\t */\n\t_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)\n\n\tgetCurrentToolIdMask() {\n\t\treturn this._currentToolIdMask.get()\n\t}\n\n\tsetCurrentToolIdMask(id: string | undefined) {\n\t\tthis._currentToolIdMask.set(id)\n\t}\n\n\tonWheel?(info: TLWheelEventInfo): void\n\tonPointerDown?(info: TLPointerEventInfo): void\n\tonPointerMove?(info: TLPointerEventInfo): void\n\tonLongPress?(info: TLPointerEventInfo): void\n\tonPointerUp?(info: TLPointerEventInfo): void\n\tonDoubleClick?(info: TLClickEventInfo): void\n\tonTripleClick?(info: TLClickEventInfo): void\n\tonQuadrupleClick?(info: TLClickEventInfo): void\n\tonRightClick?(info: TLPointerEventInfo): void\n\tonMiddleClick?(info: TLPointerEventInfo): void\n\tonKeyDown?(info: TLKeyboardEventInfo): void\n\tonKeyUp?(info: TLKeyboardEventInfo): void\n\tonKeyRepeat?(info: TLKeyboardEventInfo): void\n\tonCancel?(info: TLCancelEventInfo): void\n\tonComplete?(info: TLCompleteEventInfo): void\n\tonInterrupt?(info: TLInterruptEventInfo): void\n\tonTick?(info: TLTickEventInfo): void\n\n\tonEnter?(info: any, from: string): void\n\tonExit?(info: any, to: string): void\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA+C;AAC/C,mBAAmC;AACnC,yBAA2B;AAE3B,yBAaO;AAEP,MAAM,yBAAyB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAYO,MAAe,UAA8C;AAAA,EAEnE,YACQ,QACP,QACC;AAFM;AAGP,UAAM,EAAE,IAAI,UAAU,SAAS,WAAW,IAAI,KAAK;AAEnD,SAAK,KAAK;AACV,SAAK,gBAAY,mBAAc,iBAAiB,KAAK,IAAI,KAAK;AAC9D,SAAK,eAAW,mBAA4B,cAAc,KAAK,IAAI,MAAS;AAE5E,SAAK,YAAQ,uBAAS,aAAa,KAAK,IAAI,MAAM;AACjD,YAAM,UAAU,KAAK,WAAW;AAChC,aAAO,KAAK,MAAM,UAAU,IAAI,QAAQ,QAAQ,CAAC,KAAK;AAAA,IACvD,CAAC;AAED,SAAK,SAAS,UAAW,CAAC;AAE1B,QAAI,KAAK,QAAQ;AAChB,UAAI,YAAY,SAAS;AACxB,aAAK,OAAO;AACZ,aAAK,UAAU;AACf,aAAK,WAAW,OAAO;AAAA,UACtB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC;AAAA,QAChE;AACA,aAAK,SAAS,IAAI,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA,MAC9C,OAAO;AACN,aAAK,OAAO;AAAA,MACb;AAAA,IACD,OAAO;AACN,WAAK,OAAO;AAEZ,UAAI,YAAY,SAAS;AACxB,aAAK,UAAU;AACf,aAAK,WAAW,OAAO;AAAA,UACtB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC;AAAA,QAChE;AACA,aAAK,SAAS,IAAI,KAAK,SAAS,KAAK,OAAO,CAAC;AAAA,MAC9C;AAAA,IACD;AACA,SAAK,aAAa;AAClB,SAAK,qBAAqB,IAAI,gCAAmB;AAAA,EAClD;AAAA,EA1CA;AAAA,EA4CA,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO,aAAa;AAAA,EAEpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU;AACT,WAAO,KAAK,MAAM,IAAI;AAAA,EACvB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AACZ,WAAO,KAAK,SAAS,IAAI;AAAA,EAC1B;AAAA,EACQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOR,cAAc;AACb,WAAO,KAAK,UAAU,IAAI;AAAA,EAC3B;AAAA,EACQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBR,WAAW,IAAY,OAAY,CAAC,GAAG;AACtC,UAAM,OAAO,GAAG,MAAM,GAAG;AAEzB,QAAI,YAAY;AAEhB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACrC,YAAMA,MAAK,KAAK,CAAC;AACjB,YAAM,iBAAiB,UAAU,WAAW;AAC5C,YAAM,iBAAiB,UAAU,WAAWA,GAAE;AAE9C,UAAI,CAAC,gBAAgB;AACpB,cAAM,MAAM,GAAG,UAAU,EAAE,wCAAwCA,GAAE,GAAG;AAAA,MACzE;AAEA,UAAI,gBAAgB,OAAO,eAAe,IAAI;AAC7C,wBAAgB,KAAK,MAAMA,GAAE;AAC7B,kBAAU,SAAS,IAAI,cAAc;AACrC,uBAAe,MAAM,MAAM,gBAAgB,MAAM,SAAS;AAC1D,YAAI,CAAC,eAAe,YAAY,EAAG;AAAA,MACpC;AAEA,kBAAY;AAAA,IACb;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,YAAY,MAA8C;AACzD,UAAM,SAAS,kCAAe,KAAK,IAAI;AACvC,UAAM,qBAAqB,KAAK,SAAS,4BAA4B;AAErE,SAAK,MAAM,IAAI,IAAW;AAC1B,QACC,KAAK,UAAU,4BAA4B,KAC3C,sBACA,uBAAuB,KAAK,SAAS,4BAA4B,GAChE;AACD,yBAAmB,YAAY,IAAI;AAAA,IACpC;AAAA,EACD;AAAA;AAAA,EAGA,MAAM,MAAW,MAAc;AAC9B,QAAI,8BAAW,mBAAmB,IAAI,KAAK,uBAAuB,SAAS,KAAK,EAAE,GAAG;AACpF,WAAK,mBAAmB,MAAM,KAAK,EAAE;AAAA,IACtC;AAEA,SAAK,UAAU,IAAI,IAAI;AACvB,SAAK,UAAU,MAAM,IAAI;AAEzB,QAAI,KAAK,YAAY,KAAK,WAAW,KAAK,YAAY,GAAG;AACxD,YAAM,UAAU,KAAK,SAAS,KAAK,OAAO;AAC1C,WAAK,SAAS,IAAI,OAAO;AACzB,cAAQ,MAAM,MAAM,IAAI;AAAA,IACzB;AAAA,EACD;AAAA;AAAA,EAGA,KAAK,MAAW,MAAc;AAC7B,QAAI,8BAAW,mBAAmB,IAAI,KAAK,KAAK,mBAAmB,UAAU,GAAG;AAC/E,WAAK,mBAAmB,KAAK;AAAA,IAC9B;AACA,SAAK,UAAU,IAAI,KAAK;AACxB,SAAK,SAAS,MAAM,IAAI;AAExB,QAAI,CAAC,KAAK,YAAY,GAAG;AACxB,WAAK,WAAW,GAAG,KAAK,MAAM,IAAI;AAAA,IACnC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,yBAAqB,mBAAK,uBAAuB,MAA+B;AAAA,EAEhF,uBAAuB;AACtB,WAAO,KAAK,mBAAmB,IAAI;AAAA,EACpC;AAAA,EAEA,qBAAqB,IAAwB;AAC5C,SAAK,mBAAmB,IAAI,EAAE;AAAA,EAC/B;AAsBD;",
6
6
  "names": ["id"]
7
7
  }
@@ -21,7 +21,6 @@ __export(useCanvasEvents_exports, {
21
21
  useCanvasEvents: () => useCanvasEvents
22
22
  });
23
23
  module.exports = __toCommonJS(useCanvasEvents_exports);
24
- var import_state_react = require("@tldraw/state-react");
25
24
  var import_react = require("react");
26
25
  var import_constants = require("../constants");
27
26
  var import_dom = require("../utils/dom");
@@ -29,7 +28,6 @@ var import_getPointerInfo = require("../utils/getPointerInfo");
29
28
  var import_useEditor = require("./useEditor");
30
29
  function useCanvasEvents() {
31
30
  const editor = (0, import_useEditor.useEditor)();
32
- const currentTool = (0, import_state_react.useValue)("current tool", () => editor.getCurrentTool(), [editor]);
33
31
  const events = (0, import_react.useMemo)(
34
32
  function canvasEvents() {
35
33
  let lastX, lastY;
@@ -58,15 +56,12 @@ function useCanvasEvents() {
58
56
  if (e.clientX === lastX && e.clientY === lastY) return;
59
57
  lastX = e.clientX;
60
58
  lastY = e.clientY;
61
- const events2 = currentTool.useCoalescedEvents ? e.nativeEvent.getCoalescedEvents() : [e];
62
- for (const singleEvent of events2) {
63
- editor.dispatch({
64
- type: "pointer",
65
- target: "canvas",
66
- name: "pointer_move",
67
- ...(0, import_getPointerInfo.getPointerInfo)(singleEvent)
68
- });
69
- }
59
+ editor.dispatch({
60
+ type: "pointer",
61
+ target: "canvas",
62
+ name: "pointer_move",
63
+ ...(0, import_getPointerInfo.getPointerInfo)(e)
64
+ });
70
65
  }
71
66
  function onPointerUp(e) {
72
67
  if (e.isKilled) return;
@@ -102,7 +97,7 @@ function useCanvasEvents() {
102
97
  ;
103
98
  e.isKilled = true;
104
99
  if (!(e.target instanceof HTMLElement)) return;
105
- if (e.target.tagName !== "A" && e.target.tagName !== "TEXTAREA" && e.target.isContentEditable && // When in EditingShape state, we are actually clicking on a 'DIV'
100
+ if (e.target.tagName !== "A" && e.target.tagName !== "TEXTAREA" && !e.target.isContentEditable && // When in EditingShape state, we are actually clicking on a 'DIV'
106
101
  // not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position
107
102
  // for edit mode on mobile we need to not preventDefault.
108
103
  // TODO: Find out if we still need this preventDefault in general though.
@@ -152,7 +147,7 @@ function useCanvasEvents() {
152
147
  onClick
153
148
  };
154
149
  },
155
- [editor, currentTool]
150
+ [editor]
156
151
  );
157
152
  return events;
158
153
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/hooks/useCanvasEvents.ts"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\t// Track the last screen point\n\t\t\tlet lastX: number, lastY: number\n\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerMove(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t\t// we dispatch the coalesced events.\n\t\t\t\tconst events = currentTool.useCoalescedEvents ? e.nativeEvent.getCoalescedEvents() : [e]\n\t\t\t\tfor (const singleEvent of events) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t\t...getPointerInfo(singleEvent),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\te.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t\tignoreParent: false,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerMove,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor, currentTool]\n\t)\n\n\treturn events\n}\n"],
5
- "mappings": "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",
6
- "names": ["events"]
4
+ "sourcesContent": ["import React, { useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\t// Track the last screen point\n\t\t\tlet lastX: number, lastY: number\n\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerMove(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\t!e.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t\tignoreParent: false,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerMove,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn events\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
7
  }
@@ -22,10 +22,10 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- const version = "3.12.0-canary.e08eba00c6c8";
25
+ const version = "3.12.0-canary.e45d65cbc328";
26
26
  const publishDates = {
27
27
  major: "2024-09-13T14:36:29.063Z",
28
- minor: "2025-04-10T11:17:26.910Z",
29
- patch: "2025-04-10T11:17:26.910Z"
28
+ minor: "2025-04-15T09:02:55.799Z",
29
+ patch: "2025-04-15T09:02:55.799Z"
30
30
  };
31
31
  //# sourceMappingURL=version.js.map
@@ -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.12.0-canary.e08eba00c6c8'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-04-10T11:17:26.910Z',\n\tpatch: '2025-04-10T11:17:26.910Z',\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.12.0-canary.e45d65cbc328'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-04-15T09:02:55.799Z',\n\tpatch: '2025-04-15T09:02:55.799Z',\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -5545,14 +5545,12 @@ export declare abstract class StateNode implements Partial<TLEventHandlers> {
5545
5545
  static initial?: string;
5546
5546
  static children?: () => TLStateNodeConstructor[];
5547
5547
  static isLockable: boolean;
5548
- static useCoalescedEvents: boolean;
5549
5548
  id: string;
5550
5549
  type: 'branch' | 'leaf' | 'root';
5551
5550
  shapeType?: string;
5552
5551
  initial?: string;
5553
5552
  children?: Record<string, StateNode>;
5554
5553
  isLockable: boolean;
5555
- useCoalescedEvents: boolean;
5556
5554
  parent: StateNode;
5557
5555
  /**
5558
5556
  * This node's path of active state nodes
@@ -7166,7 +7164,6 @@ export declare interface TLStateNodeConstructor {
7166
7164
  initial?: string;
7167
7165
  children?(): TLStateNodeConstructor[];
7168
7166
  isLockable: boolean;
7169
- useCoalescedEvents: boolean;
7170
7167
  }
7171
7168
 
7172
7169
  /** @public */
@@ -303,7 +303,7 @@ function debugEnableLicensing() {
303
303
  }
304
304
  registerTldrawLibraryVersion(
305
305
  "@tldraw/editor",
306
- "3.12.0-canary.e08eba00c6c8",
306
+ "3.12.0-canary.e45d65cbc328",
307
307
  "esm"
308
308
  );
309
309
  export {
@@ -20,7 +20,7 @@ const STATE_NODES_TO_MEASURE = [
20
20
  class StateNode {
21
21
  constructor(editor, parent) {
22
22
  this.editor = editor;
23
- const { id, children, initial, isLockable, useCoalescedEvents } = this.constructor;
23
+ const { id, children, initial, isLockable } = this.constructor;
24
24
  this.id = id;
25
25
  this._isActive = atom("toolIsActive" + this.id, false);
26
26
  this._current = atom("toolState" + this.id, void 0);
@@ -51,7 +51,6 @@ class StateNode {
51
51
  }
52
52
  }
53
53
  this.isLockable = isLockable;
54
- this.useCoalescedEvents = useCoalescedEvents;
55
54
  this.performanceTracker = new PerformanceTracker();
56
55
  }
57
56
  performanceTracker;
@@ -59,14 +58,12 @@ class StateNode {
59
58
  static initial;
60
59
  static children;
61
60
  static isLockable = true;
62
- static useCoalescedEvents = false;
63
61
  id;
64
62
  type;
65
63
  shapeType;
66
64
  initial;
67
65
  children;
68
66
  isLockable;
69
- useCoalescedEvents;
70
67
  parent;
71
68
  /**
72
69
  * This node's path of active state nodes
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/editor/tools/StateNode.ts"],
4
- "sourcesContent": ["import { Atom, Computed, atom, computed } from '@tldraw/state'\nimport { PerformanceTracker } from '@tldraw/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport type { Editor } from '../Editor'\nimport {\n\tEVENT_NAME_MAP,\n\tTLCancelEventInfo,\n\tTLClickEventInfo,\n\tTLCompleteEventInfo,\n\tTLEventHandlers,\n\tTLEventInfo,\n\tTLInterruptEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLTickEventInfo,\n\tTLWheelEventInfo,\n} from '../types/event-types'\n\nconst STATE_NODES_TO_MEASURE = [\n\t'brushing',\n\t'cropping',\n\t'dragging',\n\t'dragging_handle',\n\t'drawing',\n\t'erasing',\n\t'lasering',\n\t'resizing',\n\t'rotating',\n\t'scribble_brushing',\n\t'translating',\n]\n\n/** @public */\nexport interface TLStateNodeConstructor {\n\tnew (editor: Editor, parent?: StateNode): StateNode\n\tid: string\n\tinitial?: string\n\tchildren?(): TLStateNodeConstructor[]\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n}\n\n/** @public */\nexport abstract class StateNode implements Partial<TLEventHandlers> {\n\tperformanceTracker: PerformanceTracker\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tparent?: StateNode\n\t) {\n\t\tconst { id, children, initial, isLockable, useCoalescedEvents } = this\n\t\t\t.constructor as TLStateNodeConstructor\n\n\t\tthis.id = id\n\t\tthis._isActive = atom<boolean>('toolIsActive' + this.id, false)\n\t\tthis._current = atom<StateNode | undefined>('toolState' + this.id, undefined)\n\n\t\tthis._path = computed('toolPath' + this.id, () => {\n\t\t\tconst current = this.getCurrent()\n\t\t\treturn this.id + (current ? `.${current.getPath()}` : '')\n\t\t})\n\n\t\tthis.parent = parent ?? ({} as any)\n\n\t\tif (this.parent) {\n\t\t\tif (children && initial) {\n\t\t\t\tthis.type = 'branch'\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t} else {\n\t\t\t\tthis.type = 'leaf'\n\t\t\t}\n\t\t} else {\n\t\t\tthis.type = 'root'\n\n\t\t\tif (children && initial) {\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t}\n\t\t}\n\t\tthis.isLockable = isLockable\n\t\tthis.useCoalescedEvents = useCoalescedEvents\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tstatic id: string\n\tstatic initial?: string\n\tstatic children?: () => TLStateNodeConstructor[]\n\tstatic isLockable = true\n\tstatic useCoalescedEvents = false\n\n\tid: string\n\ttype: 'branch' | 'leaf' | 'root'\n\tshapeType?: string\n\tinitial?: string\n\tchildren?: Record<string, StateNode>\n\tisLockable: boolean\n\tuseCoalescedEvents: boolean\n\tparent: StateNode\n\n\t/**\n\t * This node's path of active state nodes\n\t *\n\t * @public\n\t */\n\tgetPath() {\n\t\treturn this._path.get()\n\t}\n\t_path: Computed<string>\n\n\t/**\n\t * This node's current active child node, if any.\n\t *\n\t * @public\n\t */\n\tgetCurrent() {\n\t\treturn this._current.get()\n\t}\n\tprivate _current: Atom<StateNode | undefined>\n\n\t/**\n\t * Whether this node is active.\n\t *\n\t * @public\n\t */\n\tgetIsActive() {\n\t\treturn this._isActive.get()\n\t}\n\tprivate _isActive: Atom<boolean>\n\n\t/**\n\t * Transition to a new active child state node.\n\t *\n\t * @example\n\t * ```ts\n\t * parentState.transition('childStateA')\n\t * parentState.transition('childStateB', { myData: 4 })\n\t *```\n\t *\n\t * @param id - The id of the child state node to transition to.\n\t * @param info - Any data to pass to the `onEnter` and `onExit` handlers.\n\t *\n\t * @public\n\t */\n\ttransition(id: string, info: any = {}) {\n\t\tconst path = id.split('.')\n\n\t\tlet currState = this as StateNode\n\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tconst id = path[i]\n\t\t\tconst prevChildState = currState.getCurrent()\n\t\t\tconst nextChildState = currState.children?.[id]\n\n\t\t\tif (!nextChildState) {\n\t\t\t\tthrow Error(`${currState.id} - no child state exists with the id ${id}.`)\n\t\t\t}\n\n\t\t\tif (prevChildState?.id !== nextChildState.id) {\n\t\t\t\tprevChildState?.exit(info, id)\n\t\t\t\tcurrState._current.set(nextChildState)\n\t\t\t\tnextChildState.enter(info, prevChildState?.id || 'initial')\n\t\t\t\tif (!nextChildState.getIsActive()) break\n\t\t\t}\n\n\t\t\tcurrState = nextChildState\n\t\t}\n\n\t\treturn this\n\t}\n\n\thandleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>) {\n\t\tconst cbName = EVENT_NAME_MAP[info.name]\n\t\tconst currentActiveChild = this._current.__unsafe__getWithoutCapture()\n\n\t\tthis[cbName]?.(info as any)\n\t\tif (\n\t\t\tthis._isActive.__unsafe__getWithoutCapture() &&\n\t\t\tcurrentActiveChild &&\n\t\t\tcurrentActiveChild === this._current.__unsafe__getWithoutCapture()\n\t\t) {\n\t\t\tcurrentActiveChild.handleEvent(info)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\tenter(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && STATE_NODES_TO_MEASURE.includes(this.id)) {\n\t\t\tthis.performanceTracker.start(this.id)\n\t\t}\n\n\t\tthis._isActive.set(true)\n\t\tthis.onEnter?.(info, from)\n\n\t\tif (this.children && this.initial && this.getIsActive()) {\n\t\t\tconst initial = this.children[this.initial]\n\t\t\tthis._current.set(initial)\n\t\t\tinitial.enter(info, from)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\texit(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {\n\t\t\tthis.performanceTracker.stop()\n\t\t}\n\t\tthis._isActive.set(false)\n\t\tthis.onExit?.(info, from)\n\n\t\tif (!this.getIsActive()) {\n\t\t\tthis.getCurrent()?.exit(info, from)\n\t\t}\n\t}\n\n\t/**\n\t * This is a hack / escape hatch that will tell the editor to\n\t * report a different state as active (in `getCurrentToolId()`) when\n\t * this state is active. This is usually used when a tool transitions\n\t * to a child of a different state for a certain interaction and then\n\t * returns to the original tool when that interaction completes; and\n\t * where we would want to show the original tool as active in the UI.\n\t *\n\t * @public\n\t */\n\t_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)\n\n\tgetCurrentToolIdMask() {\n\t\treturn this._currentToolIdMask.get()\n\t}\n\n\tsetCurrentToolIdMask(id: string | undefined) {\n\t\tthis._currentToolIdMask.set(id)\n\t}\n\n\tonWheel?(info: TLWheelEventInfo): void\n\tonPointerDown?(info: TLPointerEventInfo): void\n\tonPointerMove?(info: TLPointerEventInfo): void\n\tonLongPress?(info: TLPointerEventInfo): void\n\tonPointerUp?(info: TLPointerEventInfo): void\n\tonDoubleClick?(info: TLClickEventInfo): void\n\tonTripleClick?(info: TLClickEventInfo): void\n\tonQuadrupleClick?(info: TLClickEventInfo): void\n\tonRightClick?(info: TLPointerEventInfo): void\n\tonMiddleClick?(info: TLPointerEventInfo): void\n\tonKeyDown?(info: TLKeyboardEventInfo): void\n\tonKeyUp?(info: TLKeyboardEventInfo): void\n\tonKeyRepeat?(info: TLKeyboardEventInfo): void\n\tonCancel?(info: TLCancelEventInfo): void\n\tonComplete?(info: TLCompleteEventInfo): void\n\tonInterrupt?(info: TLInterruptEventInfo): void\n\tonTick?(info: TLTickEventInfo): void\n\n\tonEnter?(info: any, from: string): void\n\tonExit?(info: any, to: string): void\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Atom, Computed, atom, computed } from '@tldraw/state'\nimport { PerformanceTracker } from '@tldraw/utils'\nimport { debugFlags } from '../../utils/debug-flags'\nimport type { Editor } from '../Editor'\nimport {\n\tEVENT_NAME_MAP,\n\tTLCancelEventInfo,\n\tTLClickEventInfo,\n\tTLCompleteEventInfo,\n\tTLEventHandlers,\n\tTLEventInfo,\n\tTLInterruptEventInfo,\n\tTLKeyboardEventInfo,\n\tTLPinchEventInfo,\n\tTLPointerEventInfo,\n\tTLTickEventInfo,\n\tTLWheelEventInfo,\n} from '../types/event-types'\n\nconst STATE_NODES_TO_MEASURE = [\n\t'brushing',\n\t'cropping',\n\t'dragging',\n\t'dragging_handle',\n\t'drawing',\n\t'erasing',\n\t'lasering',\n\t'resizing',\n\t'rotating',\n\t'scribble_brushing',\n\t'translating',\n]\n\n/** @public */\nexport interface TLStateNodeConstructor {\n\tnew (editor: Editor, parent?: StateNode): StateNode\n\tid: string\n\tinitial?: string\n\tchildren?(): TLStateNodeConstructor[]\n\tisLockable: boolean\n}\n\n/** @public */\nexport abstract class StateNode implements Partial<TLEventHandlers> {\n\tperformanceTracker: PerformanceTracker\n\tconstructor(\n\t\tpublic editor: Editor,\n\t\tparent?: StateNode\n\t) {\n\t\tconst { id, children, initial, isLockable } = this.constructor as TLStateNodeConstructor\n\n\t\tthis.id = id\n\t\tthis._isActive = atom<boolean>('toolIsActive' + this.id, false)\n\t\tthis._current = atom<StateNode | undefined>('toolState' + this.id, undefined)\n\n\t\tthis._path = computed('toolPath' + this.id, () => {\n\t\t\tconst current = this.getCurrent()\n\t\t\treturn this.id + (current ? `.${current.getPath()}` : '')\n\t\t})\n\n\t\tthis.parent = parent ?? ({} as any)\n\n\t\tif (this.parent) {\n\t\t\tif (children && initial) {\n\t\t\t\tthis.type = 'branch'\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t} else {\n\t\t\t\tthis.type = 'leaf'\n\t\t\t}\n\t\t} else {\n\t\t\tthis.type = 'root'\n\n\t\t\tif (children && initial) {\n\t\t\t\tthis.initial = initial\n\t\t\t\tthis.children = Object.fromEntries(\n\t\t\t\t\tchildren().map((Ctor) => [Ctor.id, new Ctor(this.editor, this)])\n\t\t\t\t)\n\t\t\t\tthis._current.set(this.children[this.initial])\n\t\t\t}\n\t\t}\n\t\tthis.isLockable = isLockable\n\t\tthis.performanceTracker = new PerformanceTracker()\n\t}\n\n\tstatic id: string\n\tstatic initial?: string\n\tstatic children?: () => TLStateNodeConstructor[]\n\tstatic isLockable = true\n\n\tid: string\n\ttype: 'branch' | 'leaf' | 'root'\n\tshapeType?: string\n\tinitial?: string\n\tchildren?: Record<string, StateNode>\n\tisLockable: boolean\n\tparent: StateNode\n\n\t/**\n\t * This node's path of active state nodes\n\t *\n\t * @public\n\t */\n\tgetPath() {\n\t\treturn this._path.get()\n\t}\n\t_path: Computed<string>\n\n\t/**\n\t * This node's current active child node, if any.\n\t *\n\t * @public\n\t */\n\tgetCurrent() {\n\t\treturn this._current.get()\n\t}\n\tprivate _current: Atom<StateNode | undefined>\n\n\t/**\n\t * Whether this node is active.\n\t *\n\t * @public\n\t */\n\tgetIsActive() {\n\t\treturn this._isActive.get()\n\t}\n\tprivate _isActive: Atom<boolean>\n\n\t/**\n\t * Transition to a new active child state node.\n\t *\n\t * @example\n\t * ```ts\n\t * parentState.transition('childStateA')\n\t * parentState.transition('childStateB', { myData: 4 })\n\t *```\n\t *\n\t * @param id - The id of the child state node to transition to.\n\t * @param info - Any data to pass to the `onEnter` and `onExit` handlers.\n\t *\n\t * @public\n\t */\n\ttransition(id: string, info: any = {}) {\n\t\tconst path = id.split('.')\n\n\t\tlet currState = this as StateNode\n\n\t\tfor (let i = 0; i < path.length; i++) {\n\t\t\tconst id = path[i]\n\t\t\tconst prevChildState = currState.getCurrent()\n\t\t\tconst nextChildState = currState.children?.[id]\n\n\t\t\tif (!nextChildState) {\n\t\t\t\tthrow Error(`${currState.id} - no child state exists with the id ${id}.`)\n\t\t\t}\n\n\t\t\tif (prevChildState?.id !== nextChildState.id) {\n\t\t\t\tprevChildState?.exit(info, id)\n\t\t\t\tcurrState._current.set(nextChildState)\n\t\t\t\tnextChildState.enter(info, prevChildState?.id || 'initial')\n\t\t\t\tif (!nextChildState.getIsActive()) break\n\t\t\t}\n\n\t\t\tcurrState = nextChildState\n\t\t}\n\n\t\treturn this\n\t}\n\n\thandleEvent(info: Exclude<TLEventInfo, TLPinchEventInfo>) {\n\t\tconst cbName = EVENT_NAME_MAP[info.name]\n\t\tconst currentActiveChild = this._current.__unsafe__getWithoutCapture()\n\n\t\tthis[cbName]?.(info as any)\n\t\tif (\n\t\t\tthis._isActive.__unsafe__getWithoutCapture() &&\n\t\t\tcurrentActiveChild &&\n\t\t\tcurrentActiveChild === this._current.__unsafe__getWithoutCapture()\n\t\t) {\n\t\t\tcurrentActiveChild.handleEvent(info)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\tenter(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && STATE_NODES_TO_MEASURE.includes(this.id)) {\n\t\t\tthis.performanceTracker.start(this.id)\n\t\t}\n\n\t\tthis._isActive.set(true)\n\t\tthis.onEnter?.(info, from)\n\n\t\tif (this.children && this.initial && this.getIsActive()) {\n\t\t\tconst initial = this.children[this.initial]\n\t\t\tthis._current.set(initial)\n\t\t\tinitial.enter(info, from)\n\t\t}\n\t}\n\n\t// todo: move this logic into transition\n\texit(info: any, from: string) {\n\t\tif (debugFlags.measurePerformance.get() && this.performanceTracker.isStarted()) {\n\t\t\tthis.performanceTracker.stop()\n\t\t}\n\t\tthis._isActive.set(false)\n\t\tthis.onExit?.(info, from)\n\n\t\tif (!this.getIsActive()) {\n\t\t\tthis.getCurrent()?.exit(info, from)\n\t\t}\n\t}\n\n\t/**\n\t * This is a hack / escape hatch that will tell the editor to\n\t * report a different state as active (in `getCurrentToolId()`) when\n\t * this state is active. This is usually used when a tool transitions\n\t * to a child of a different state for a certain interaction and then\n\t * returns to the original tool when that interaction completes; and\n\t * where we would want to show the original tool as active in the UI.\n\t *\n\t * @public\n\t */\n\t_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)\n\n\tgetCurrentToolIdMask() {\n\t\treturn this._currentToolIdMask.get()\n\t}\n\n\tsetCurrentToolIdMask(id: string | undefined) {\n\t\tthis._currentToolIdMask.set(id)\n\t}\n\n\tonWheel?(info: TLWheelEventInfo): void\n\tonPointerDown?(info: TLPointerEventInfo): void\n\tonPointerMove?(info: TLPointerEventInfo): void\n\tonLongPress?(info: TLPointerEventInfo): void\n\tonPointerUp?(info: TLPointerEventInfo): void\n\tonDoubleClick?(info: TLClickEventInfo): void\n\tonTripleClick?(info: TLClickEventInfo): void\n\tonQuadrupleClick?(info: TLClickEventInfo): void\n\tonRightClick?(info: TLPointerEventInfo): void\n\tonMiddleClick?(info: TLPointerEventInfo): void\n\tonKeyDown?(info: TLKeyboardEventInfo): void\n\tonKeyUp?(info: TLKeyboardEventInfo): void\n\tonKeyRepeat?(info: TLKeyboardEventInfo): void\n\tonCancel?(info: TLCancelEventInfo): void\n\tonComplete?(info: TLCompleteEventInfo): void\n\tonInterrupt?(info: TLInterruptEventInfo): void\n\tonTick?(info: TLTickEventInfo): void\n\n\tonEnter?(info: any, from: string): void\n\tonExit?(info: any, to: string): void\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["id"]
7
7
  }
@@ -1,4 +1,3 @@
1
- import { useValue } from "@tldraw/state-react";
2
1
  import { useMemo } from "react";
3
2
  import { RIGHT_MOUSE_BUTTON } from "../constants.mjs";
4
3
  import {
@@ -11,7 +10,6 @@ import { getPointerInfo } from "../utils/getPointerInfo.mjs";
11
10
  import { useEditor } from "./useEditor.mjs";
12
11
  function useCanvasEvents() {
13
12
  const editor = useEditor();
14
- const currentTool = useValue("current tool", () => editor.getCurrentTool(), [editor]);
15
13
  const events = useMemo(
16
14
  function canvasEvents() {
17
15
  let lastX, lastY;
@@ -40,15 +38,12 @@ function useCanvasEvents() {
40
38
  if (e.clientX === lastX && e.clientY === lastY) return;
41
39
  lastX = e.clientX;
42
40
  lastY = e.clientY;
43
- const events2 = currentTool.useCoalescedEvents ? e.nativeEvent.getCoalescedEvents() : [e];
44
- for (const singleEvent of events2) {
45
- editor.dispatch({
46
- type: "pointer",
47
- target: "canvas",
48
- name: "pointer_move",
49
- ...getPointerInfo(singleEvent)
50
- });
51
- }
41
+ editor.dispatch({
42
+ type: "pointer",
43
+ target: "canvas",
44
+ name: "pointer_move",
45
+ ...getPointerInfo(e)
46
+ });
52
47
  }
53
48
  function onPointerUp(e) {
54
49
  if (e.isKilled) return;
@@ -84,7 +79,7 @@ function useCanvasEvents() {
84
79
  ;
85
80
  e.isKilled = true;
86
81
  if (!(e.target instanceof HTMLElement)) return;
87
- if (e.target.tagName !== "A" && e.target.tagName !== "TEXTAREA" && e.target.isContentEditable && // When in EditingShape state, we are actually clicking on a 'DIV'
82
+ if (e.target.tagName !== "A" && e.target.tagName !== "TEXTAREA" && !e.target.isContentEditable && // When in EditingShape state, we are actually clicking on a 'DIV'
88
83
  // not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position
89
84
  // for edit mode on mobile we need to not preventDefault.
90
85
  // TODO: Find out if we still need this preventDefault in general though.
@@ -134,7 +129,7 @@ function useCanvasEvents() {
134
129
  onClick
135
130
  };
136
131
  },
137
- [editor, currentTool]
132
+ [editor]
138
133
  );
139
134
  return events;
140
135
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/hooks/useCanvasEvents.ts"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport React, { useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\tconst currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\t// Track the last screen point\n\t\t\tlet lastX: number, lastY: number\n\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerMove(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\t// For tools that benefit from a higher fidelity of events,\n\t\t\t\t// we dispatch the coalesced events.\n\t\t\t\tconst events = currentTool.useCoalescedEvents ? e.nativeEvent.getCoalescedEvents() : [e]\n\t\t\t\tfor (const singleEvent of events) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t\t...getPointerInfo(singleEvent),\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\te.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t\tignoreParent: false,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerMove,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor, currentTool]\n\t)\n\n\treturn events\n}\n"],
5
- "mappings": "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",
6
- "names": ["events"]
4
+ "sourcesContent": ["import React, { useMemo } from 'react'\nimport { RIGHT_MOUSE_BUTTON } from '../constants'\nimport {\n\tpreventDefault,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tstopEventPropagation,\n} from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\nimport { useEditor } from './useEditor'\n\nexport function useCanvasEvents() {\n\tconst editor = useEditor()\n\n\tconst events = useMemo(\n\t\tfunction canvasEvents() {\n\t\t\t// Track the last screen point\n\t\t\tlet lastX: number, lastY: number\n\n\t\t\tfunction onPointerDown(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.button === RIGHT_MOUSE_BUTTON) {\n\t\t\t\t\teditor.dispatch({\n\t\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\t\tname: 'right_click',\n\t\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 5) return\n\n\t\t\t\tsetPointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerMove(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\n\t\t\t\tif (e.clientX === lastX && e.clientY === lastY) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerUp(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return\n\t\t\t\tlastX = e.clientX\n\t\t\t\tlastY = e.clientY\n\n\t\t\t\treleasePointerCapture(e.currentTarget, e)\n\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_up',\n\t\t\t\t\t...getPointerInfo(e),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tfunction onPointerEnter(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? true : null })\n\t\t\t}\n\n\t\t\tfunction onPointerLeave(e: React.PointerEvent) {\n\t\t\t\tif ((e as any).isKilled) return\n\t\t\t\tif (editor.getInstanceState().isPenMode && e.pointerType !== 'pen') return\n\t\t\t\tconst canHover = e.pointerType === 'mouse' || e.pointerType === 'pen'\n\t\t\t\teditor.updateInstanceState({ isHoveringCanvas: canHover ? false : null })\n\t\t\t}\n\n\t\t\tfunction onTouchStart(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tfunction onTouchEnd(e: React.TouchEvent) {\n\t\t\t\t;(e as any).isKilled = true\n\t\t\t\t// check that e.target is an HTMLElement\n\t\t\t\tif (!(e.target instanceof HTMLElement)) return\n\n\t\t\t\tif (\n\t\t\t\t\te.target.tagName !== 'A' &&\n\t\t\t\t\te.target.tagName !== 'TEXTAREA' &&\n\t\t\t\t\t!e.target.isContentEditable &&\n\t\t\t\t\t// When in EditingShape state, we are actually clicking on a 'DIV'\n\t\t\t\t\t// not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position\n\t\t\t\t\t// for edit mode on mobile we need to not preventDefault.\n\t\t\t\t\t// TODO: Find out if we still need this preventDefault in general though.\n\t\t\t\t\t!(editor.getEditingShape() && e.target.className.includes('tl-text-content'))\n\t\t\t\t) {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onDragOver(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t}\n\n\t\t\tasync function onDrop(e: React.DragEvent<Element>) {\n\t\t\t\tpreventDefault(e)\n\t\t\t\tstopEventPropagation(e)\n\n\t\t\t\tif (e.dataTransfer?.files?.length) {\n\t\t\t\t\tconst files = Array.from(e.dataTransfer.files)\n\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'files',\n\t\t\t\t\t\tfiles,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t\tignoreParent: false,\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst url = e.dataTransfer.getData('url')\n\t\t\t\tif (url) {\n\t\t\t\t\tawait editor.putExternalContent({\n\t\t\t\t\t\ttype: 'url',\n\t\t\t\t\t\turl,\n\t\t\t\t\t\tpoint: editor.screenToPage({ x: e.clientX, y: e.clientY }),\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction onClick(e: React.MouseEvent) {\n\t\t\t\tstopEventPropagation(e)\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonPointerDown,\n\t\t\t\tonPointerMove,\n\t\t\t\tonPointerUp,\n\t\t\t\tonPointerEnter,\n\t\t\t\tonPointerLeave,\n\t\t\t\tonDragOver,\n\t\t\t\tonDrop,\n\t\t\t\tonTouchStart,\n\t\t\t\tonTouchEnd,\n\t\t\t\tonClick,\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn events\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.12.0-canary.e08eba00c6c8";
1
+ const version = "3.12.0-canary.e45d65cbc328";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-04-10T11:17:26.910Z",
5
- patch: "2025-04-10T11:17:26.910Z"
4
+ minor: "2025-04-15T09:02:55.799Z",
5
+ patch: "2025-04-15T09:02:55.799Z"
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.12.0-canary.e08eba00c6c8'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-04-10T11:17:26.910Z',\n\tpatch: '2025-04-10T11:17:26.910Z',\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.12.0-canary.e45d65cbc328'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-04-15T09:02:55.799Z',\n\tpatch: '2025-04-15T09:02:55.799Z',\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
@@ -63,31 +63,40 @@
63
63
 
64
64
  /* Cursor SVGs */
65
65
  --tl-cursor-none: none;
66
- --tl-cursor-default: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z' fill='white'/><path d='m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z' fill='white'/><path d='m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z' fill='black'/><path d='m13 10.814v11.188l2.969-2.866.428-.139h4.768z' fill='black'/></g></svg>")
66
+ --tl-cursor-default:
67
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z' fill='white'/><path d='m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z' fill='white'/><path d='m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z' fill='black'/><path d='m13 10.814v11.188l2.969-2.866.428-.139h4.768z' fill='black'/></g></svg>")
67
68
  12 8,
68
69
  default;
69
- --tl-cursor-pointer: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' stroke-linejoin='round'/><path d='m21.5664 21.7344v-3.459'/><path d='m19.5508 21.7461-.016-3.473'/><path d='m17.5547 18.3047.021 3.426'/></g></g></svg>")
70
+ --tl-cursor-pointer:
71
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.3315 21.3799c-.284-.359-.629-1.093-1.243-1.984-.348-.504-1.211-1.453-1.468-1.935-.223-.426-.199-.617-.146-.97.094-.628.738-1.117 1.425-1.051.519.049.959.392 1.355.716.239.195.533.574.71.788.163.196.203.277.377.509.23.307.302.459.214.121-.071-.496-.187-1.343-.355-2.092-.128-.568-.159-.657-.281-1.093-.129-.464-.195-.789-.316-1.281-.084-.348-.235-1.059-.276-1.459-.057-.547-.087-1.439.264-1.849.275-.321.906-.418 1.297-.22.512.259.803 1.003.936 1.3.239.534.387 1.151.516 1.961.164 1.031.466 2.462.476 2.763.024-.369-.068-1.146-.004-1.5.058-.321.328-.694.666-.795.286-.085.621-.116.916-.055.313.064.643.288.766.499.362.624.369 1.899.384 1.831.086-.376.071-1.229.284-1.584.14-.234.497-.445.687-.479.294-.052.655-.068.964-.008.249.049.586.345.677.487.218.344.342 1.317.379 1.658.015.141.074-.392.293-.736.406-.639 1.843-.763 1.898.639.025.654.02.624.02 1.064 0 .517-.012.828-.04 1.202-.031.4-.117 1.304-.242 1.742-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.191 1.813-.118.562-.079.566-.102.965-.023.398.121.922.121.922s-.802.104-1.234.035c-.391-.063-.875-.841-1-1.079-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.031-3.139.02 0 0 .185-1.011-.227-1.358-.305-.259-.83-.784-1.144-1.06z' stroke-linejoin='round'/><path d='m21.5664 21.7344v-3.459'/><path d='m19.5508 21.7461-.016-3.473'/><path d='m17.5547 18.3047.021 3.426'/></g></g></svg>")
70
72
  14 10,
71
73
  pointer;
72
- --tl-cursor-cross: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m25 16h-6.01v-6h-2.98v6h-6.01v3h6.01v6h2.98v-6h6.01z' fill='white'/><path d='m23.9902 17.0103h-6v-6.01h-.98v6.01h-6v.98h6v6.01h.98v-6.01h6z' fill='%23231f1f'/></g></svg>")
74
+ --tl-cursor-cross:
75
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m25 16h-6.01v-6h-2.98v6h-6.01v3h6.01v6h2.98v-6h6.01z' fill='white'/><path d='m23.9902 17.0103h-6v-6.01h-.98v6.01h-6v.98h6v6.01h.98v-6.01h6z' fill='%23231f1f'/></g></svg>")
73
76
  16 16,
74
77
  crosshair;
75
- --tl-cursor-move: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m19 14h1v1h-1zm1 6h-1v-1h1zm-5-5h-1v-1h1zm0 5h-1v-1h1zm2-10.987-7.985 7.988 5.222 5.221 2.763 2.763 7.984-7.985z' fill='white'/><g fill='black'><path d='m23.5664 16.9971-2.557-2.809v1.829h-4.009-4.001v-1.829l-2.571 2.809 2.572 2.808-.001-1.808h4.001 4.009l-.001 1.808z'/><path d='m17.9873 17h.013v-4.001l1.807.001-2.807-2.571-2.809 2.57h1.809v4.001h.008v4.002l-1.828-.001 2.807 2.577 2.805-2.576h-1.805z'/></g></g></svg>")
78
+ --tl-cursor-move:
79
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m19 14h1v1h-1zm1 6h-1v-1h1zm-5-5h-1v-1h1zm0 5h-1v-1h1zm2-10.987-7.985 7.988 5.222 5.221 2.763 2.763 7.984-7.985z' fill='white'/><g fill='black'><path d='m23.5664 16.9971-2.557-2.809v1.829h-4.009-4.001v-1.829l-2.571 2.809 2.572 2.808-.001-1.808h4.001 4.009l-.001 1.808z'/><path d='m17.9873 17h.013v-4.001l1.807.001-2.807-2.571-2.809 2.57h1.809v4.001h.008v4.002l-1.828-.001 2.807 2.577 2.805-2.576h-1.805z'/></g></g></svg>")
76
80
  16 16,
77
81
  move;
78
- --tl-cursor-grab: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' stroke-linejoin='round'/><path d='m20.5664 21.7344v-3.459'/><path d='m18.5508 21.7461-.016-3.473'/><path d='m16.5547 18.3047.021 3.426'/></g></g></svg>")
82
+ --tl-cursor-grab:
83
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' fill='white'/><g stroke='black' stroke-linecap='round' stroke-width='.75'><path d='m13.5557 17.5742c-.098-.375-.196-.847-.406-1.552-.167-.557-.342-.859-.47-1.233-.155-.455-.303-.721-.496-1.181-.139-.329-.364-1.048-.457-1.44-.119-.509.033-.924.244-1.206.253-.339.962-.49 1.357-.351.371.13.744.512.916.788.288.46.357.632.717 1.542.393.992.564 1.918.611 2.231l.085.452c-.001-.04-.043-1.122-.044-1.162-.035-1.029-.06-1.823-.038-2.939.002-.126.064-.587.084-.715.078-.5.305-.8.673-.979.412-.201.926-.215 1.401-.017.423.173.626.55.687 1.022.014.109.094.987.093 1.107-.013 1.025.006 1.641.015 2.174.004.231.003 1.625.017 1.469.061-.656.094-3.189.344-3.942.144-.433.405-.746.794-.929.431-.203 1.113-.07 1.404.243.285.305.446.692.482 1.153.032.405-.019.897-.02 1.245 0 .867-.021 1.324-.037 2.121-.001.038-.015.298.023.182.094-.28.188-.542.266-.745.049-.125.241-.614.359-.859.114-.234.211-.369.415-.688.2-.313.415-.448.668-.561.54-.235 1.109.112 1.301.591.086.215.009.713-.028 1.105-.061.647-.254 1.306-.352 1.648-.128.447-.274 1.235-.34 1.601-.072.394-.234 1.382-.359 1.82-.086.301-.371.978-.652 1.384 0 0-1.074 1.25-1.192 1.812-.117.563-.078.567-.101.965-.024.399.121.923.121.923s-.802.104-1.234.034c-.391-.062-.875-.841-1-1.078-.172-.328-.539-.265-.682-.023-.225.383-.709 1.07-1.051 1.113-.668.084-2.054.03-3.139.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.284-.36-.629-1.093-1.243-1.985-.348-.504-1.027-1.085-1.284-1.579-.223-.425-.331-.954-.19-1.325.225-.594.675-.897 1.362-.832.519.05.848.206 1.238.537.225.19.573.534.75.748.163.195.203.276.377.509.23.307.302.459.214.121' stroke-linejoin='round'/><path d='m20.5664 21.7344v-3.459'/><path d='m18.5508 21.7461-.016-3.473'/><path d='m16.5547 18.3047.021 3.426'/></g></g></svg>")
79
84
  16 16,
80
85
  grab;
81
- --tl-cursor-grabbing: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042' fill='white'/><g stroke='black' stroke-width='.75'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042z' stroke-linejoin='round'/><path d='m20.5664 19.7344v-3.459' stroke-linecap='round'/><path d='m18.5508 19.7461-.016-3.473' stroke-linecap='round'/><path d='m16.5547 16.3047.021 3.426' stroke-linecap='round'/></g></g></svg>")
86
+ --tl-cursor-grabbing:
87
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042' fill='white'/><g stroke='black' stroke-width='.75'><path d='m13.5732 12.0361c.48-.178 1.427-.069 1.677.473.213.462.396 1.241.406 1.075.024-.369-.024-1.167.137-1.584.117-.304.347-.59.686-.691.285-.086.62-.116.916-.055.313.064.642.287.765.499.362.623.368 1.899.385 1.831.064-.272.07-1.229.283-1.584.141-.235.497-.445.687-.479.294-.052.656-.068.964-.008.249.049.586.344.677.487.219.344.342 1.316.379 1.658.016.141.074-.393.293-.736.406-.639 1.844-.763 1.898.639.026.654.02.624.02 1.064 0 .516-.012.828-.04 1.202-.03.399-.116 1.304-.241 1.742-.086.301-.371.978-.653 1.384 0 0-1.074 1.25-1.191 1.812-.117.563-.078.567-.102.965-.023.399.121.923.121.923s-.801.104-1.234.034c-.391-.062-.875-.84-1-1.078-.172-.328-.539-.265-.682-.023-.224.383-.709 1.07-1.05 1.113-.669.084-2.055.03-3.14.02 0 0 .185-1.011-.227-1.358-.305-.26-.83-.784-1.144-1.06l-.832-.921c-.283-.36-1.002-.929-1.243-1.985-.213-.936-.192-1.395.037-1.77.232-.381.67-.589.854-.625.208-.042.692-.039.875.062.223.123.313.159.488.391.23.307.312.456.213.121-.076-.262-.322-.595-.434-.97-.109-.361-.401-.943-.38-1.526.008-.221.103-.771.832-1.042z' stroke-linejoin='round'/><path d='m20.5664 19.7344v-3.459' stroke-linecap='round'/><path d='m18.5508 19.7461-.016-3.473' stroke-linecap='round'/><path d='m16.5547 16.3047.021 3.426' stroke-linecap='round'/></g></g></svg>")
82
88
  16 16,
83
89
  grabbing;
84
- --tl-cursor-text: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path fill='white' d='M7.94 0a5.25 5.25 0 0 0-3.47 1.17A5.27 5.27 0 0 0 1 0H0v3h1c1.41 0 1.85.7 2 1v3.94H2v3h1v3c-.13.3-.57 1-2 1H0v3h1a5.27 5.27 0 0 0 3.47-1.17c.98.8 2.21 1.21 3.47 1.17h1v-3h-1c-1.41 0-1.85-.7-2-1v-3H7v-3H6V4c.13-.3.57-1 2-1h1V0H7.94z'/><path fill='black' d='M7.94 2V1a4 4 0 0 0-3.47 1.64A4 4 0 0 0 1 1v1c1.3-.17 2.56.6 3 1.84v5.1H3v1h1v4.16c-.45 1.24-1.7 2-3 1.84v1a4.05 4.05 0 0 0 3.47-1.63 4.05 4.05 0 0 0 3.47 1.63v-1A2.82 2.82 0 0 1 5 14.1V9.93h1v-1H5V3.85A2.81 2.81 0 0 1 7.94 2z'/></g></svg>")
90
+ --tl-cursor-text:
91
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path fill='white' d='M7.94 0a5.25 5.25 0 0 0-3.47 1.17A5.27 5.27 0 0 0 1 0H0v3h1c1.41 0 1.85.7 2 1v3.94H2v3h1v3c-.13.3-.57 1-2 1H0v3h1a5.27 5.27 0 0 0 3.47-1.17c.98.8 2.21 1.21 3.47 1.17h1v-3h-1c-1.41 0-1.85-.7-2-1v-3H7v-3H6V4c.13-.3.57-1 2-1h1V0H7.94z'/><path fill='black' d='M7.94 2V1a4 4 0 0 0-3.47 1.64A4 4 0 0 0 1 1v1c1.3-.17 2.56.6 3 1.84v5.1H3v1h1v4.16c-.45 1.24-1.7 2-3 1.84v1a4.05 4.05 0 0 0 3.47-1.63 4.05 4.05 0 0 0 3.47 1.63v-1A2.82 2.82 0 0 1 5 14.1V9.93h1v-1H5V3.85A2.81 2.81 0 0 1 7.94 2z'/></g></svg>")
85
92
  4 10,
86
93
  text;
87
- --tl-cursor-zoom-in: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 14h-2v-2h-2v2h-2v1.98h2v2.02h2v-2.02h2z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
94
+ --tl-cursor-zoom-in:
95
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 14h-2v-2h-2v2h-2v1.98h2v2.02h2v-2.02h2z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
88
96
  16 16,
89
97
  zoom-in;
90
- --tl-cursor-zoom-out: url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 16h-5.98v-1.98h5.98z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
98
+ --tl-cursor-zoom-out:
99
+ url("data:image/svg+xml,<svg height='32' width='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg' style='color: black;'><defs><filter id='shadow' y='-40%' x='-40%' width='180px' height='180%' color-interpolation-filters='sRGB'><feDropShadow dx='1' dy='1' stdDeviation='1.2' flood-opacity='.5'/></filter></defs><g fill='none' transform='rotate(0 16 16)' filter='url(%23shadow)'><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5' fill='white'/><path d='m20.5 15c0 3.038-2.462 5.5-5.5 5.5s-5.5-2.462-5.5-5.5 2.462-5.5 5.5-5.5 5.5 2.462 5.5 5.5z' stroke='black'/><g fill='black'><path d='m18 16h-5.98v-1.98h5.98z'/><path d='m23.5859 25 1.414-1.414-5.449-5.449-1.414 1.414z'/></g></g></svg>")
91
100
  16 16,
92
101
  zoom-out;
93
102
 
@@ -114,10 +123,10 @@
114
123
  /* text outline */
115
124
  --a: calc(min(0.5, 1 / var(--tl-zoom)) * 2px);
116
125
  --b: calc(min(0.5, 1 / var(--tl-zoom)) * -2px);
117
- --tl-text-outline-reference: 0 var(--b) 0 var(--color-background),
118
- 0 var(--a) 0 var(--color-background), var(--b) var(--b) 0 var(--color-background),
119
- var(--a) var(--b) 0 var(--color-background), var(--a) var(--a) 0 var(--color-background),
120
- var(--b) var(--a) 0 var(--color-background);
126
+ --tl-text-outline-reference:
127
+ 0 var(--b) 0 var(--color-background), 0 var(--a) 0 var(--color-background),
128
+ var(--b) var(--b) 0 var(--color-background), var(--a) var(--b) 0 var(--color-background),
129
+ var(--a) var(--a) 0 var(--color-background), var(--b) var(--a) 0 var(--color-background);
121
130
  --tl-text-outline: var(--tl-text-outline-reference);
122
131
  /* own properties */
123
132
  position: relative;
@@ -168,11 +177,14 @@
168
177
  --color-laser: hsl(0, 100%, 50%);
169
178
  /* Shadows */
170
179
  --shadow-1: 0px 1px 2px hsl(0, 0%, 0%, 25%), 0px 1px 3px hsl(0, 0%, 0%, 9%);
171
- --shadow-2: 0px 0px 2px hsl(0, 0%, 0%, 16%), 0px 2px 3px hsl(0, 0%, 0%, 24%),
180
+ --shadow-2:
181
+ 0px 0px 2px hsl(0, 0%, 0%, 16%), 0px 2px 3px hsl(0, 0%, 0%, 24%),
172
182
  0px 2px 6px hsl(0, 0%, 0%, 0.1), inset 0px 0px 0px 1px var(--color-panel-contrast);
173
- --shadow-3: 0px 1px 2px hsl(0, 0%, 0%, 28%), 0px 2px 6px hsl(0, 0%, 0%, 14%),
183
+ --shadow-3:
184
+ 0px 1px 2px hsl(0, 0%, 0%, 28%), 0px 2px 6px hsl(0, 0%, 0%, 14%),
174
185
  inset 0px 0px 0px 1px var(--color-panel-contrast);
175
- --shadow-4: 0px 0px 3px hsl(0, 0%, 0%, 19%), 0px 5px 4px hsl(0, 0%, 0%, 16%),
186
+ --shadow-4:
187
+ 0px 0px 3px hsl(0, 0%, 0%, 19%), 0px 5px 4px hsl(0, 0%, 0%, 16%),
176
188
  0px 2px 16px hsl(0, 0%, 0%, 6%), inset 0px 0px 0px 1px var(--color-panel-contrast);
177
189
  }
178
190
 
@@ -215,11 +227,14 @@
215
227
  --color-text: hsl(210, 17%, 98%);
216
228
  --color-laser: hsl(0, 100%, 50%);
217
229
  /* Shadows */
218
- --shadow-1: 0px 1px 2px hsl(0, 0%, 0%, 16.1%), 0px 1px 3px hsl(0, 0%, 0%, 22%),
230
+ --shadow-1:
231
+ 0px 1px 2px hsl(0, 0%, 0%, 16.1%), 0px 1px 3px hsl(0, 0%, 0%, 22%),
219
232
  inset 0px 0px 0px 1px var(--color-panel-contrast);
220
- --shadow-2: 0px 1px 3px hsl(0, 0%, 0%, 66.6%), 0px 2px 6px hsl(0, 0%, 0%, 33%),
233
+ --shadow-2:
234
+ 0px 1px 3px hsl(0, 0%, 0%, 66.6%), 0px 2px 6px hsl(0, 0%, 0%, 33%),
221
235
  inset 0px 0px 0px 1px var(--color-panel-contrast);
222
- --shadow-3: 0px 1px 3px hsl(0, 0%, 0%, 50%), 0px 2px 12px hsl(0, 0%, 0%, 50%),
236
+ --shadow-3:
237
+ 0px 1px 3px hsl(0, 0%, 0%, 50%), 0px 2px 12px hsl(0, 0%, 0%, 50%),
223
238
  inset 0px 0px 0px 1px var(--color-panel-contrast);
224
239
  }
225
240
 
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.12.0-canary.e08eba00c6c8",
4
+ "version": "3.12.0-canary.e45d65cbc328",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -48,12 +48,12 @@
48
48
  "@tiptap/core": "^2.9.1",
49
49
  "@tiptap/pm": "^2.9.1",
50
50
  "@tiptap/react": "^2.9.1",
51
- "@tldraw/state": "3.12.0-canary.e08eba00c6c8",
52
- "@tldraw/state-react": "3.12.0-canary.e08eba00c6c8",
53
- "@tldraw/store": "3.12.0-canary.e08eba00c6c8",
54
- "@tldraw/tlschema": "3.12.0-canary.e08eba00c6c8",
55
- "@tldraw/utils": "3.12.0-canary.e08eba00c6c8",
56
- "@tldraw/validate": "3.12.0-canary.e08eba00c6c8",
51
+ "@tldraw/state": "3.12.0-canary.e45d65cbc328",
52
+ "@tldraw/state-react": "3.12.0-canary.e45d65cbc328",
53
+ "@tldraw/store": "3.12.0-canary.e45d65cbc328",
54
+ "@tldraw/tlschema": "3.12.0-canary.e45d65cbc328",
55
+ "@tldraw/utils": "3.12.0-canary.e45d65cbc328",
56
+ "@tldraw/validate": "3.12.0-canary.e45d65cbc328",
57
57
  "@types/core-js": "^2.5.8",
58
58
  "@use-gesture/react": "^10.3.1",
59
59
  "classnames": "^2.5.1",
@@ -38,7 +38,6 @@ export interface TLStateNodeConstructor {
38
38
  initial?: string
39
39
  children?(): TLStateNodeConstructor[]
40
40
  isLockable: boolean
41
- useCoalescedEvents: boolean
42
41
  }
43
42
 
44
43
  /** @public */
@@ -48,8 +47,7 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
48
47
  public editor: Editor,
49
48
  parent?: StateNode
50
49
  ) {
51
- const { id, children, initial, isLockable, useCoalescedEvents } = this
52
- .constructor as TLStateNodeConstructor
50
+ const { id, children, initial, isLockable } = this.constructor as TLStateNodeConstructor
53
51
 
54
52
  this.id = id
55
53
  this._isActive = atom<boolean>('toolIsActive' + this.id, false)
@@ -85,7 +83,6 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
85
83
  }
86
84
  }
87
85
  this.isLockable = isLockable
88
- this.useCoalescedEvents = useCoalescedEvents
89
86
  this.performanceTracker = new PerformanceTracker()
90
87
  }
91
88
 
@@ -93,7 +90,6 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
93
90
  static initial?: string
94
91
  static children?: () => TLStateNodeConstructor[]
95
92
  static isLockable = true
96
- static useCoalescedEvents = false
97
93
 
98
94
  id: string
99
95
  type: 'branch' | 'leaf' | 'root'
@@ -101,7 +97,6 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
101
97
  initial?: string
102
98
  children?: Record<string, StateNode>
103
99
  isLockable: boolean
104
- useCoalescedEvents: boolean
105
100
  parent: StateNode
106
101
 
107
102
  /**
@@ -1,4 +1,3 @@
1
- import { useValue } from '@tldraw/state-react'
2
1
  import React, { useMemo } from 'react'
3
2
  import { RIGHT_MOUSE_BUTTON } from '../constants'
4
3
  import {
@@ -12,7 +11,6 @@ import { useEditor } from './useEditor'
12
11
 
13
12
  export function useCanvasEvents() {
14
13
  const editor = useEditor()
15
- const currentTool = useValue('current tool', () => editor.getCurrentTool(), [editor])
16
14
 
17
15
  const events = useMemo(
18
16
  function canvasEvents() {
@@ -51,17 +49,12 @@ export function useCanvasEvents() {
51
49
  lastX = e.clientX
52
50
  lastY = e.clientY
53
51
 
54
- // For tools that benefit from a higher fidelity of events,
55
- // we dispatch the coalesced events.
56
- const events = currentTool.useCoalescedEvents ? e.nativeEvent.getCoalescedEvents() : [e]
57
- for (const singleEvent of events) {
58
- editor.dispatch({
59
- type: 'pointer',
60
- target: 'canvas',
61
- name: 'pointer_move',
62
- ...getPointerInfo(singleEvent),
63
- })
64
- }
52
+ editor.dispatch({
53
+ type: 'pointer',
54
+ target: 'canvas',
55
+ name: 'pointer_move',
56
+ ...getPointerInfo(e),
57
+ })
65
58
  }
66
59
 
67
60
  function onPointerUp(e: React.PointerEvent) {
@@ -107,7 +100,7 @@ export function useCanvasEvents() {
107
100
  if (
108
101
  e.target.tagName !== 'A' &&
109
102
  e.target.tagName !== 'TEXTAREA' &&
110
- e.target.isContentEditable &&
103
+ !e.target.isContentEditable &&
111
104
  // When in EditingShape state, we are actually clicking on a 'DIV'
112
105
  // not A/TEXTAREA/contenteditable element yet. So, to preserve cursor position
113
106
  // for edit mode on mobile we need to not preventDefault.
@@ -166,7 +159,7 @@ export function useCanvasEvents() {
166
159
  onClick,
167
160
  }
168
161
  },
169
- [editor, currentTool]
162
+ [editor]
170
163
  )
171
164
 
172
165
  return events
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.12.0-canary.e08eba00c6c8'
4
+ export const version = '3.12.0-canary.e45d65cbc328'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-04-10T11:17:26.910Z',
8
- patch: '2025-04-10T11:17:26.910Z',
7
+ minor: '2025-04-15T09:02:55.799Z',
8
+ patch: '2025-04-15T09:02:55.799Z',
9
9
  }