@tldraw/editor 5.2.3 → 5.3.0-canary.0114f715ad01

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist-cjs/index.d.ts +76 -10
  2. package/dist-cjs/index.js +3 -3
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +6 -1
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/editor/Editor.js +67 -15
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/managers/EditorManager.js +52 -0
  9. package/dist-cjs/lib/editor/managers/EditorManager.js.map +7 -0
  10. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +9 -11
  11. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  12. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +5 -9
  13. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  14. package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js +18 -29
  15. package/dist-cjs/lib/editor/managers/SpatialIndexManager/RBushIndex.js.map +2 -2
  16. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +96 -54
  17. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
  18. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +24 -19
  19. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  20. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +4 -7
  21. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
  22. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +3 -0
  23. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +1 -1
  25. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +1 -2
  26. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  27. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  28. package/dist-cjs/lib/options.js +2 -1
  29. package/dist-cjs/lib/options.js.map +2 -2
  30. package/dist-cjs/version.js +3 -3
  31. package/dist-cjs/version.js.map +1 -1
  32. package/dist-esm/index.d.mts +76 -10
  33. package/dist-esm/index.mjs +3 -3
  34. package/dist-esm/index.mjs.map +2 -2
  35. package/dist-esm/lib/TldrawEditor.mjs +6 -1
  36. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  37. package/dist-esm/lib/editor/Editor.mjs +67 -15
  38. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  39. package/dist-esm/lib/editor/managers/EditorManager.mjs +32 -0
  40. package/dist-esm/lib/editor/managers/EditorManager.mjs.map +7 -0
  41. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +9 -11
  42. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  43. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +5 -9
  44. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  45. package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs +18 -29
  46. package/dist-esm/lib/editor/managers/SpatialIndexManager/RBushIndex.mjs.map +2 -2
  47. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +103 -56
  48. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
  49. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +24 -19
  50. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  51. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +4 -7
  52. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
  53. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +3 -0
  54. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +2 -2
  55. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +1 -1
  56. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +1 -2
  57. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  58. package/dist-esm/lib/options.mjs +2 -1
  59. package/dist-esm/lib/options.mjs.map +2 -2
  60. package/dist-esm/version.mjs +3 -3
  61. package/dist-esm/version.mjs.map +1 -1
  62. package/package.json +7 -7
  63. package/src/index.ts +1 -1
  64. package/src/lib/TldrawEditor.tsx +10 -1
  65. package/src/lib/editor/Editor.ts +101 -20
  66. package/src/lib/editor/managers/EditorManager.test.ts +51 -0
  67. package/src/lib/editor/managers/EditorManager.ts +60 -0
  68. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +2 -1
  69. package/src/lib/editor/managers/FocusManager/FocusManager.ts +10 -14
  70. package/src/lib/editor/managers/InputsManager/InputsManager.ts +6 -9
  71. package/src/lib/editor/managers/SpatialIndexManager/RBushIndex.ts +19 -33
  72. package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +173 -86
  73. package/src/lib/editor/managers/TextManager/TextManager.test.ts +61 -1
  74. package/src/lib/editor/managers/TextManager/TextManager.ts +33 -19
  75. package/src/lib/editor/managers/TickManager/TickManager.test.ts +0 -10
  76. package/src/lib/editor/managers/TickManager/TickManager.ts +5 -6
  77. package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +6 -1
  78. package/src/lib/editor/shapes/ShapeUtil.ts +1 -0
  79. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +2 -2
  80. package/src/lib/editor/types/emit-types.ts +1 -0
  81. package/src/lib/options.ts +3 -1
  82. package/src/version.ts +3 -3
  83. package/dist-cjs/lib/editor/tools/cancelShapeCreationOnLongPress.js +0 -28
  84. package/dist-cjs/lib/editor/tools/cancelShapeCreationOnLongPress.js.map +0 -7
  85. package/dist-esm/lib/editor/tools/cancelShapeCreationOnLongPress.mjs +0 -8
  86. package/dist-esm/lib/editor/tools/cancelShapeCreationOnLongPress.mjs.map +0 -7
  87. package/src/lib/editor/tools/cancelShapeCreationOnLongPress.ts +0 -31
@@ -1,5 +1,6 @@
1
1
  import { throttleToNextFrame as _throttleToNextFrame, bind } from '@tldraw/utils'
2
2
  import type { Editor } from '../../Editor'
3
+ import { EditorManager } from '../EditorManager'
3
4
 
4
5
  const throttleToNextFrame =
5
6
  typeof process !== 'undefined' && process.env.NODE_ENV === 'test'
@@ -13,9 +14,9 @@ const throttleToNextFrame =
13
14
  : _throttleToNextFrame
14
15
 
15
16
  /** @internal */
16
- export class TickManager {
17
- constructor(public editor: Editor) {
18
- this.editor.disposables.add(this.dispose)
17
+ export class TickManager extends EditorManager {
18
+ constructor(editor: Editor) {
19
+ super(editor)
19
20
  this.start()
20
21
  }
21
22
 
@@ -45,11 +46,9 @@ export class TickManager {
45
46
  this.cancelRaf = throttleToNextFrame(this.tick)
46
47
  }
47
48
 
48
- // Clear the listener
49
- @bind
50
49
  dispose() {
51
50
  this.isPaused = true
52
-
53
51
  this.cancelRaf?.()
52
+ super.dispose()
54
53
  }
55
54
  }
@@ -5,7 +5,7 @@ import { BaseBoxShapeUtil, TLBaseBoxShape } from './BaseBoxShapeUtil'
5
5
  import { TLDragShapesInInfo, TLDragShapesOutInfo } from './ShapeUtil'
6
6
 
7
7
  /**
8
- * A base class for frame-like shapes — containers that clip their children,
8
+ * A base class for frame-like shapes — containers that clip their children except arrows,
9
9
  * require full-brush selection, block erasure from inside, and support
10
10
  * drag-and-drop reparenting.
11
11
  *
@@ -17,6 +17,7 @@ import { TLDragShapesInInfo, TLDragShapesOutInfo } from './ShapeUtil'
17
17
  * - `canReceiveNewChildrenOfType()` returns `true` unless the container is locked
18
18
  * - `canRemoveChildrenOfType()` returns `true` unless the container is locked
19
19
  * - `getClipPath()` returns the shape geometry's vertices
20
+ * - `shouldClipChild()` clips all children except arrows
20
21
  * - `onDragShapesIn()` reparents shapes into the frame (with index restoration)
21
22
  * - `onDragShapesOut()` reparents shapes back to the page
22
23
  *
@@ -69,6 +70,10 @@ export abstract class BaseFrameLikeShapeUtil<
69
70
  return this.editor.getShapeGeometry(shape.id).vertices
70
71
  }
71
72
 
73
+ override shouldClipChild(child: TLShape): boolean {
74
+ return child.type !== 'arrow'
75
+ }
76
+
72
77
  override onDragShapesIn(
73
78
  shape: Shape,
74
79
  draggingShapes: TLShape[],
@@ -1039,6 +1039,7 @@ export interface TLCropInfo<T extends TLShape> {
1039
1039
  uncroppedSize: { w: number; h: number }
1040
1040
  initialShape: T
1041
1041
  aspectRatioLocked?: boolean
1042
+ isResizingFromCenter?: boolean
1042
1043
  }
1043
1044
 
1044
1045
  /** @public */
@@ -4,7 +4,6 @@ import { Vec } from '../../../../primitives/Vec'
4
4
  import type { Editor } from '../../../Editor'
5
5
  import { TLBaseBoxShape } from '../../../shapes/BaseBoxShapeUtil'
6
6
  import { TLPointerEventInfo } from '../../../types/event-types'
7
- import { cancelShapeCreationOnLongPress } from '../../cancelShapeCreationOnLongPress'
8
7
  import { StateNode } from '../../StateNode'
9
8
  import type { BaseBoxShapeTool } from '../BaseBoxShapeTool'
10
9
 
@@ -67,7 +66,8 @@ export class Pointing extends StateNode {
67
66
  }
68
67
 
69
68
  override onLongPress() {
70
- cancelShapeCreationOnLongPress(this.editor, () => this.cancel())
69
+ // On a touch (coarse pointer) long-press, cancel the pending shape so it leaves nothing behind.
70
+ if (this.editor.getInstanceState().isCoarsePointer) this.cancel()
71
71
  }
72
72
 
73
73
  override onCancel() {
@@ -6,6 +6,7 @@ import { TLEventInfo } from './event-types'
6
6
  export interface TLEventMap {
7
7
  // Lifecycle / Internal
8
8
  mount: []
9
+ unmount: []
9
10
  'max-shapes': [{ name: string; pageId: TLPageId; count: number }]
10
11
  change: [HistoryEntry<TLRecord>]
11
12
  update: []
@@ -86,6 +86,7 @@ export interface TldrawOptions {
86
86
  readonly collaboratorCheckIntervalMs: number
87
87
  readonly cameraMovingTimeoutMs: number
88
88
  readonly hitTestMargin: number
89
+ readonly coarseHitTestMargin: number
89
90
  readonly edgeScrollDelay: number
90
91
  readonly edgeScrollEaseDuration: number
91
92
  readonly edgeScrollSpeed: number
@@ -312,7 +313,8 @@ export const defaultTldrawOptions = {
312
313
  collaboratorIdleTimeoutMs: 3000,
313
314
  collaboratorCheckIntervalMs: 1200,
314
315
  cameraMovingTimeoutMs: 64,
315
- hitTestMargin: 8,
316
+ hitTestMargin: 3,
317
+ coarseHitTestMargin: 4,
316
318
  edgeScrollDelay: 200,
317
319
  edgeScrollEaseDuration: 200,
318
320
  edgeScrollSpeed: 25,
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 = '5.2.3'
4
+ export const version = '5.3.0-canary.0114f715ad01'
5
5
  export const publishDates = {
6
6
  major: '2026-05-06T16:28:18.473Z',
7
- minor: '2026-07-01T09:20:01.735Z',
8
- patch: '2026-07-06T16:50:48.696Z',
7
+ minor: '2026-07-06T22:25:54.730Z',
8
+ patch: '2026-07-06T22:25:54.730Z',
9
9
  }
@@ -1,28 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var cancelShapeCreationOnLongPress_exports = {};
20
- __export(cancelShapeCreationOnLongPress_exports, {
21
- cancelShapeCreationOnLongPress: () => cancelShapeCreationOnLongPress
22
- });
23
- module.exports = __toCommonJS(cancelShapeCreationOnLongPress_exports);
24
- function cancelShapeCreationOnLongPress(editor, cancelPendingCreation) {
25
- if (!editor.getInstanceState().isCoarsePointer) return;
26
- cancelPendingCreation();
27
- }
28
- //# sourceMappingURL=cancelShapeCreationOnLongPress.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/lib/editor/tools/cancelShapeCreationOnLongPress.ts"],
4
- "sourcesContent": ["import type { Editor } from '../Editor'\n\n/**\n * Shared handler for a long-press in a discrete shape-creation tool's pointing\n * state (geo, note, line, text, arrow, frame). On a coarse pointer this cancels\n * any pending creation so the long-press leaves no shape behind (issue #8277).\n * It does not open a context menu \u2014 that is a select-tool surface, reached on\n * touch only from the select tool, and on desktop from a right-click (which the\n * editor routes through the select tool).\n *\n * Gated on `isCoarsePointer`: on a fine pointer (mouse) the long-press timer\n * powers the deliberate \"pause before drag to start a precise arrow\" gesture,\n * which we must not disturb. The bug only manifests on coarse pointers, because\n * that is also where the browser fires `contextmenu` at the long-press mark.\n *\n * The `cancelPendingCreation` callback is the tool's own cleanup \u2014 it knows\n * whether it needs to `bailToMark` a shape it created early or simply transition\n * back to idle. Continuous-gesture tools (draw, highlight, eraser, laser) are\n * excluded: their press is their own action, so they handle (or ignore) the\n * long-press themselves.\n *\n * @internal\n */\nexport function cancelShapeCreationOnLongPress(\n\teditor: Editor,\n\tcancelPendingCreation: () => void\n): void {\n\tif (!editor.getInstanceState().isCoarsePointer) return\n\n\tcancelPendingCreation()\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBO,SAAS,+BACf,QACA,uBACO;AACP,MAAI,CAAC,OAAO,iBAAiB,EAAE,gBAAiB;AAEhD,wBAAsB;AACvB;",
6
- "names": []
7
- }
@@ -1,8 +0,0 @@
1
- function cancelShapeCreationOnLongPress(editor, cancelPendingCreation) {
2
- if (!editor.getInstanceState().isCoarsePointer) return;
3
- cancelPendingCreation();
4
- }
5
- export {
6
- cancelShapeCreationOnLongPress
7
- };
8
- //# sourceMappingURL=cancelShapeCreationOnLongPress.mjs.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../../src/lib/editor/tools/cancelShapeCreationOnLongPress.ts"],
4
- "sourcesContent": ["import type { Editor } from '../Editor'\n\n/**\n * Shared handler for a long-press in a discrete shape-creation tool's pointing\n * state (geo, note, line, text, arrow, frame). On a coarse pointer this cancels\n * any pending creation so the long-press leaves no shape behind (issue #8277).\n * It does not open a context menu \u2014 that is a select-tool surface, reached on\n * touch only from the select tool, and on desktop from a right-click (which the\n * editor routes through the select tool).\n *\n * Gated on `isCoarsePointer`: on a fine pointer (mouse) the long-press timer\n * powers the deliberate \"pause before drag to start a precise arrow\" gesture,\n * which we must not disturb. The bug only manifests on coarse pointers, because\n * that is also where the browser fires `contextmenu` at the long-press mark.\n *\n * The `cancelPendingCreation` callback is the tool's own cleanup \u2014 it knows\n * whether it needs to `bailToMark` a shape it created early or simply transition\n * back to idle. Continuous-gesture tools (draw, highlight, eraser, laser) are\n * excluded: their press is their own action, so they handle (or ignore) the\n * long-press themselves.\n *\n * @internal\n */\nexport function cancelShapeCreationOnLongPress(\n\teditor: Editor,\n\tcancelPendingCreation: () => void\n): void {\n\tif (!editor.getInstanceState().isCoarsePointer) return\n\n\tcancelPendingCreation()\n}\n"],
5
- "mappings": "AAuBO,SAAS,+BACf,QACA,uBACO;AACP,MAAI,CAAC,OAAO,iBAAiB,EAAE,gBAAiB;AAEhD,wBAAsB;AACvB;",
6
- "names": []
7
- }
@@ -1,31 +0,0 @@
1
- import type { Editor } from '../Editor'
2
-
3
- /**
4
- * Shared handler for a long-press in a discrete shape-creation tool's pointing
5
- * state (geo, note, line, text, arrow, frame). On a coarse pointer this cancels
6
- * any pending creation so the long-press leaves no shape behind (issue #8277).
7
- * It does not open a context menu — that is a select-tool surface, reached on
8
- * touch only from the select tool, and on desktop from a right-click (which the
9
- * editor routes through the select tool).
10
- *
11
- * Gated on `isCoarsePointer`: on a fine pointer (mouse) the long-press timer
12
- * powers the deliberate "pause before drag to start a precise arrow" gesture,
13
- * which we must not disturb. The bug only manifests on coarse pointers, because
14
- * that is also where the browser fires `contextmenu` at the long-press mark.
15
- *
16
- * The `cancelPendingCreation` callback is the tool's own cleanup — it knows
17
- * whether it needs to `bailToMark` a shape it created early or simply transition
18
- * back to idle. Continuous-gesture tools (draw, highlight, eraser, laser) are
19
- * excluded: their press is their own action, so they handle (or ignore) the
20
- * long-press themselves.
21
- *
22
- * @internal
23
- */
24
- export function cancelShapeCreationOnLongPress(
25
- editor: Editor,
26
- cancelPendingCreation: () => void
27
- ): void {
28
- if (!editor.getInstanceState().isCoarsePointer) return
29
-
30
- cancelPendingCreation()
31
- }