@tldraw/editor 3.13.0-canary.77b2db3d8725 → 3.13.0-canary.87a0019c391d

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 (114) hide show
  1. package/dist-cjs/index.d.ts +97 -84
  2. package/dist-cjs/index.js +22 -7
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +5 -9
  5. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  6. package/dist-cjs/lib/editor/Editor.js +7 -19
  7. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  8. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
  9. package/dist-cjs/lib/editor/managers/TextManager.js +0 -10
  10. package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
  11. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  13. package/dist-cjs/lib/hooks/useEditorComponents.js +2 -1
  14. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  15. package/dist-cjs/lib/primitives/Box.js +0 -16
  16. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  17. package/dist-cjs/lib/primitives/Mat.js +1 -1
  18. package/dist-cjs/lib/primitives/Mat.js.map +2 -2
  19. package/dist-cjs/lib/primitives/Vec.js +0 -20
  20. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  21. package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
  22. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  23. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
  24. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  25. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
  26. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  27. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
  28. package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
  29. package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
  30. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  31. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +20 -91
  32. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  33. package/dist-cjs/lib/primitives/geometry/Group2d.js +2 -55
  34. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  35. package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
  36. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  37. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  38. package/dist-cjs/lib/utils/debug-flags.js +2 -5
  39. package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
  40. package/dist-cjs/version.js +3 -3
  41. package/dist-cjs/version.js.map +1 -1
  42. package/dist-esm/index.d.mts +97 -84
  43. package/dist-esm/index.mjs +41 -9
  44. package/dist-esm/index.mjs.map +2 -2
  45. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -9
  46. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  47. package/dist-esm/lib/editor/Editor.mjs +7 -19
  48. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  49. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
  50. package/dist-esm/lib/editor/managers/TextManager.mjs +0 -10
  51. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  52. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  53. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  54. package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -1
  55. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  56. package/dist-esm/lib/primitives/Box.mjs +0 -16
  57. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  58. package/dist-esm/lib/primitives/Mat.mjs +1 -1
  59. package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
  60. package/dist-esm/lib/primitives/Vec.mjs +0 -20
  61. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  62. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  63. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  64. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
  65. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  66. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
  67. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  68. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
  69. package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
  70. package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
  71. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  72. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +21 -92
  73. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  74. package/dist-esm/lib/primitives/geometry/Group2d.mjs +2 -55
  75. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  76. package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
  77. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  78. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  79. package/dist-esm/lib/utils/debug-flags.mjs +2 -5
  80. package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
  81. package/dist-esm/version.mjs +3 -3
  82. package/dist-esm/version.mjs.map +1 -1
  83. package/editor.css +4 -31
  84. package/package.json +7 -7
  85. package/src/index.ts +31 -16
  86. package/src/lib/components/default-components/DefaultCanvas.tsx +5 -9
  87. package/src/lib/editor/Editor.test.ts +1 -1
  88. package/src/lib/editor/Editor.ts +7 -19
  89. package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +1 -0
  90. package/src/lib/editor/managers/TextManager.ts +0 -12
  91. package/src/lib/editor/shapes/ShapeUtil.ts +1 -9
  92. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
  93. package/src/lib/hooks/useEditorComponents.tsx +5 -2
  94. package/src/lib/primitives/Box.ts +0 -20
  95. package/src/lib/primitives/Mat.ts +4 -5
  96. package/src/lib/primitives/Vec.ts +0 -23
  97. package/src/lib/primitives/geometry/Arc2d.ts +5 -5
  98. package/src/lib/primitives/geometry/Circle2d.ts +4 -4
  99. package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
  100. package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
  101. package/src/lib/primitives/geometry/Edge2d.ts +3 -3
  102. package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
  103. package/src/lib/primitives/geometry/Geometry2d.ts +35 -123
  104. package/src/lib/primitives/geometry/Group2d.ts +7 -70
  105. package/src/lib/primitives/geometry/Point2d.ts +2 -2
  106. package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
  107. package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
  108. package/src/lib/test/currentToolIdMask.test.ts +1 -1
  109. package/src/lib/test/user.test.ts +1 -1
  110. package/src/lib/utils/debug-flags.ts +2 -7
  111. package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
  112. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
  113. package/src/version.ts +3 -3
  114. package/src/lib/primitives/geometry/Geometry2d.test.ts +0 -42
package/editor.css CHANGED
@@ -157,7 +157,6 @@
157
157
  --color-panel-contrast: hsl(0, 0%, 100%);
158
158
  --color-panel-overlay: hsl(0, 0%, 100%, 82%);
159
159
  --color-panel: hsl(0, 0%, 99%);
160
- --color-panel-transparent: hsla(0, 0%, 99%, 0%);
161
160
  --color-focus: hsl(219, 65%, 50%);
162
161
  --color-selected: hsl(214, 84%, 56%);
163
162
  --color-selected-contrast: hsl(0, 0%, 100%);
@@ -209,7 +208,6 @@
209
208
  --color-panel-contrast: hsl(245, 12%, 23%);
210
209
  --color-panel: hsl(235, 6.8%, 13.5%);
211
210
  --color-panel-overlay: hsl(210, 10%, 24%, 82%);
212
- --color-panel-transparent: hsla(235, 6.8%, 13.5%, 0%);
213
211
  --color-focus: hsl(217, 76%, 80%);
214
212
  --color-selected: hsl(217, 89%, 61%);
215
213
  --color-selected-contrast: hsl(0, 0%, 100%);
@@ -602,31 +600,6 @@ input,
602
600
  }
603
601
  }
604
602
 
605
- /* --------------------- Arrow Hints -------------------- */
606
-
607
- .tl-arrow-hint-handle {
608
- fill: var(--color-selected-contrast);
609
- stroke: var(--color-selection-stroke);
610
- stroke-width: calc(1.5px * var(--tl-scale));
611
- r: calc(4px * var(--tl-scale));
612
- }
613
-
614
- .tl-arrow-hint-snap {
615
- stroke: transparent;
616
- fill: var(--color-selection-fill);
617
- r: calc(12px * var(--tl-scale));
618
- }
619
-
620
- .tl-arrow-hint-snap__none,
621
- .tl-arrow-hint-snap__center,
622
- .tl-arrow-hint-snap__axis {
623
- display: none;
624
- }
625
-
626
- .tl-arrow-hint-snap__edge {
627
- r: calc(8px * var(--tl-scale));
628
- }
629
-
630
603
  /* ------------------ Bounds Detail ----------------- */
631
604
 
632
605
  .tl-image,
@@ -996,8 +969,6 @@ input,
996
969
 
997
970
  .tl-rich-text p {
998
971
  margin: 0;
999
- /* Depending on the extensions, <p> tags can be empty, without a <br />. */
1000
- min-height: 1lh;
1001
972
  }
1002
973
 
1003
974
  .tl-rich-text ul,
@@ -1005,8 +976,6 @@ input,
1005
976
  text-align: left;
1006
977
  margin: 0;
1007
978
  padding-left: 3.25ch;
1008
- /* Some resets, like Tailwind, nix the list styling. */
1009
- list-style: revert;
1010
979
  }
1011
980
 
1012
981
  .tl-rich-text ol:has(> li:nth-child(10)) {
@@ -1384,6 +1353,10 @@ input,
1384
1353
  opacity: 0;
1385
1354
  }
1386
1355
 
1356
+ .tl-arrow-label[data-isediting='true'] > .tl-arrow-label__inner {
1357
+ background-color: var(--color-background);
1358
+ }
1359
+
1387
1360
  .tl-arrow-label__inner {
1388
1361
  border-radius: var(--radius-1);
1389
1362
  box-sizing: content-box;
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.13.0-canary.77b2db3d8725",
4
+ "version": "3.13.0-canary.87a0019c391d",
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.13.0-canary.77b2db3d8725",
52
- "@tldraw/state-react": "3.13.0-canary.77b2db3d8725",
53
- "@tldraw/store": "3.13.0-canary.77b2db3d8725",
54
- "@tldraw/tlschema": "3.13.0-canary.77b2db3d8725",
55
- "@tldraw/utils": "3.13.0-canary.77b2db3d8725",
56
- "@tldraw/validate": "3.13.0-canary.77b2db3d8725",
51
+ "@tldraw/state": "3.13.0-canary.87a0019c391d",
52
+ "@tldraw/state-react": "3.13.0-canary.87a0019c391d",
53
+ "@tldraw/store": "3.13.0-canary.87a0019c391d",
54
+ "@tldraw/tlschema": "3.13.0-canary.87a0019c391d",
55
+ "@tldraw/utils": "3.13.0-canary.87a0019c391d",
56
+ "@tldraw/validate": "3.13.0-canary.87a0019c391d",
57
57
  "@types/core-js": "^2.5.8",
58
58
  "@use-gesture/react": "^10.3.1",
59
59
  "classnames": "^2.5.1",
package/src/index.ts CHANGED
@@ -4,11 +4,37 @@ import 'core-js/stable/array/flat-map.js'
4
4
  import 'core-js/stable/array/flat.js'
5
5
  import 'core-js/stable/string/at.js'
6
6
  import 'core-js/stable/string/replace-all.js'
7
-
8
- // eslint-disable-next-line local/no-export-star
9
- export * from '@tldraw/state'
10
- // eslint-disable-next-line local/no-export-star
11
- export * from '@tldraw/state-react'
7
+ export {
8
+ EMPTY_ARRAY,
9
+ EffectScheduler,
10
+ atom,
11
+ computed,
12
+ react,
13
+ transact,
14
+ transaction,
15
+ whyAmIRunning,
16
+ type Atom,
17
+ type Signal,
18
+ } from '@tldraw/state'
19
+ export {
20
+ track,
21
+ useAtom,
22
+ useComputed,
23
+ useQuickReactor,
24
+ useReactor,
25
+ useStateTracking,
26
+ useValue,
27
+ } from '@tldraw/state-react'
28
+ export { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'
29
+ export {
30
+ getFontsFromRichText,
31
+ type RichTextFontVisitor,
32
+ type RichTextFontVisitorState,
33
+ type TLTextOptions,
34
+ type TiptapEditor,
35
+ type TiptapNode,
36
+ } from './lib/utils/richText'
37
+ export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
12
38
  // eslint-disable-next-line local/no-export-star
13
39
  export * from '@tldraw/store'
14
40
  // eslint-disable-next-line local/no-export-star
@@ -17,7 +43,6 @@ export * from '@tldraw/tlschema'
17
43
  export * from '@tldraw/utils'
18
44
  // eslint-disable-next-line local/no-export-star
19
45
  export * from '@tldraw/validate'
20
-
21
46
  export {
22
47
  ErrorScreen,
23
48
  LoadingScreen,
@@ -187,7 +212,6 @@ export {
187
212
  export { GroupShapeUtil } from './lib/editor/shapes/group/GroupShapeUtil'
188
213
  export { getPerfectDashProps } from './lib/editor/shapes/shared/getPerfectDashProps'
189
214
  export { resizeBox, type ResizeBoxOptions } from './lib/editor/shapes/shared/resizeBox'
190
- export { resizeScaled } from './lib/editor/shapes/shared/resizeScaled'
191
215
  export { BaseBoxShapeTool } from './lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool'
192
216
  export { maybeSnapToGrid } from './lib/editor/tools/BaseBoxShapeTool/children/Pointing'
193
217
  export { StateNode, type TLStateNodeConstructor } from './lib/editor/tools/StateNode'
@@ -435,21 +459,12 @@ export { hardResetEditor } from './lib/utils/hardResetEditor'
435
459
  export { isAccelKey } from './lib/utils/keyboard'
436
460
  export { normalizeWheel } from './lib/utils/normalizeWheel'
437
461
  export { refreshPage } from './lib/utils/refreshPage'
438
- export {
439
- getFontsFromRichText,
440
- type RichTextFontVisitor,
441
- type RichTextFontVisitorState,
442
- type TLTextOptions,
443
- type TiptapEditor,
444
- type TiptapNode,
445
- } from './lib/utils/richText'
446
462
  export {
447
463
  applyRotationToSnapshotShapes,
448
464
  getRotationSnapshot,
449
465
  type TLRotationSnapshot,
450
466
  } from './lib/utils/rotation'
451
467
  export { runtime, setRuntimeOverrides } from './lib/utils/runtime'
452
- export { LocalIndexedDb, Table, type StoreName } from './lib/utils/sync/LocalIndexedDb'
453
468
  export { type TLStoreWithStatus } from './lib/utils/sync/StoreWithStatus'
454
469
  export { hardReset } from './lib/utils/sync/hardReset'
455
470
  export { uniq } from './lib/utils/uniq'
@@ -37,7 +37,7 @@ export interface TLCanvasComponentProps {
37
37
  export function DefaultCanvas({ className }: TLCanvasComponentProps) {
38
38
  const editor = useEditor()
39
39
 
40
- const { SelectionBackground, Background, SvgDefs, ShapeIndicators } = useEditorComponents()
40
+ const { Background, SvgDefs, ShapeIndicators } = useEditorComponents()
41
41
 
42
42
  const rCanvas = useRef<HTMLDivElement>(null)
43
43
  const rHtmlLayer = useRef<HTMLDivElement>(null)
@@ -155,7 +155,7 @@ export function DefaultCanvas({ className }: TLCanvasComponentProps) {
155
155
  <GridWrapper />
156
156
  <div ref={rHtmlLayer} className="tl-html-layer tl-shapes" draggable={false}>
157
157
  <OnTheCanvasWrapper />
158
- {SelectionBackground && <SelectionBackgroundWrapper />}
158
+ <SelectionBackgroundWrapper />
159
159
  {hideShapes ? null : debugSvg ? <ShapesWithSVGs /> : <ShapesToDisplay />}
160
160
  </div>
161
161
  <div className="tl-overlays">
@@ -575,13 +575,9 @@ function DebugSvgCopy({ id, mode }: { id: TLShapeId; mode: 'img' | 'iframe' }) {
575
575
 
576
576
  function SelectionForegroundWrapper() {
577
577
  const editor = useEditor()
578
- const selectionRotation = useValue(
579
- 'selection rotation',
580
- function getSelectionRotation() {
581
- return editor.getSelectionRotation()
582
- },
583
- [editor]
584
- )
578
+ const selectionRotation = useValue('selection rotation', () => editor.getSelectionRotation(), [
579
+ editor,
580
+ ])
585
581
  const selectionBounds = useValue(
586
582
  'selection bounds',
587
583
  () => editor.getSelectionRotatedPageBounds(),
@@ -52,7 +52,7 @@ beforeEach(() => {
52
52
  shapeUtils: [CustomShape],
53
53
  bindingUtils: [],
54
54
  tools: [],
55
- store: createTLStore({ shapeUtils: [CustomShape], bindingUtils: [] }),
55
+ store: createTLStore({ shapeUtils: [CustomShape] }),
56
56
  getContainer: () => document.body,
57
57
  })
58
58
  editor.setCameraOptions({ isLocked: true })
@@ -326,6 +326,7 @@ export class Editor extends EventEmitter<TLEventMap> {
326
326
  this.options = { ...defaultTldrawOptions, ...options }
327
327
 
328
328
  this.store = store
329
+ this.disposables.add(this.store.dispose.bind(this.store))
329
330
  this.history = new HistoryManager<TLRecord>({
330
331
  store,
331
332
  annotateError: (error) => {
@@ -955,7 +956,6 @@ export class Editor extends EventEmitter<TLEventMap> {
955
956
  dispose() {
956
957
  this.disposables.forEach((dispose) => dispose())
957
958
  this.disposables.clear()
958
- this.store.dispose()
959
959
  this.isDisposed = true
960
960
  }
961
961
 
@@ -2276,21 +2276,13 @@ export class Editor extends EventEmitter<TLEventMap> {
2276
2276
  setEditingShape(shape: TLShapeId | TLShape | null): this {
2277
2277
  const id = typeof shape === 'string' ? shape : (shape?.id ?? null)
2278
2278
  this.setRichTextEditor(null)
2279
- const prevEditingShapeId = this.getEditingShapeId()
2280
- if (id !== prevEditingShapeId) {
2279
+ if (id !== this.getEditingShapeId()) {
2281
2280
  if (id) {
2282
2281
  const shape = this.getShape(id)
2283
2282
  if (shape && this.getShapeUtil(shape).canEdit(shape)) {
2284
2283
  this.run(
2285
2284
  () => {
2286
2285
  this._updateCurrentPageState({ editingShapeId: id })
2287
- if (prevEditingShapeId) {
2288
- const prevEditingShape = this.getShape(prevEditingShapeId)
2289
- if (prevEditingShape) {
2290
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)
2291
- }
2292
- }
2293
- this.getShapeUtil(shape).onEditStart?.(shape)
2294
2286
  },
2295
2287
  { history: 'ignore' }
2296
2288
  )
@@ -2303,12 +2295,6 @@ export class Editor extends EventEmitter<TLEventMap> {
2303
2295
  () => {
2304
2296
  this._updateCurrentPageState({ editingShapeId: null })
2305
2297
  this._currentRichTextEditor.set(null)
2306
- if (prevEditingShapeId) {
2307
- const prevEditingShape = this.getShape(prevEditingShapeId)
2308
- if (prevEditingShape) {
2309
- this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape)
2310
- }
2311
- }
2312
2298
  },
2313
2299
  { history: 'ignore' }
2314
2300
  )
@@ -10357,10 +10343,12 @@ export class Editor extends EventEmitter<TLEventMap> {
10357
10343
  if (this.inputs.isPanning && this.inputs.isPointing) {
10358
10344
  // Handle spacebar / middle mouse button panning
10359
10345
  const { currentScreenPoint, previousScreenPoint } = this.inputs
10346
+ const { panSpeed } = cameraOptions
10360
10347
  const offset = Vec.Sub(currentScreenPoint, previousScreenPoint)
10361
- this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
10362
- immediate: true,
10363
- })
10348
+ this.setCamera(
10349
+ new Vec(cx + (offset.x * panSpeed) / cz, cy + (offset.y * panSpeed) / cz, cz),
10350
+ { immediate: true }
10351
+ )
10364
10352
  this.maybeTrackPerformance('Panning')
10365
10353
  return
10366
10354
  }
@@ -45,6 +45,7 @@ export interface HandleSnapGeometry {
45
45
 
46
46
  const defaultGetSelfSnapOutline = () => null
47
47
  const defaultGetSelfSnapPoints = () => []
48
+
48
49
  /** @public */
49
50
  export class HandleSnaps {
50
51
  readonly editor: Editor
@@ -32,7 +32,6 @@ export interface TLMeasureTextSpanOpts {
32
32
  fontStyle: string
33
33
  lineHeight: number
34
34
  textAlign: TLDefaultHorizontalAlignStyle
35
- otherStyles?: Record<string, string>
36
35
  }
37
36
 
38
37
  const spaceCharacterRegex = /\s/
@@ -87,7 +86,6 @@ export class TextManager {
87
86
  */
88
87
  maxWidth: null | number
89
88
  minWidth?: null | number
90
- otherStyles?: Record<string, string>
91
89
  padding: string
92
90
  disableOverflowWrapBreaking?: boolean
93
91
  }
@@ -114,11 +112,6 @@ export class TextManager {
114
112
  'overflow-wrap',
115
113
  opts.disableOverflowWrapBreaking ? 'normal' : 'break-word'
116
114
  )
117
- if (opts.otherStyles) {
118
- for (const [key, value] of Object.entries(opts.otherStyles)) {
119
- wrapperElm.style.setProperty(key, value)
120
- }
121
- }
122
115
 
123
116
  const scrollWidth = wrapperElm.scrollWidth
124
117
  const rect = wrapperElm.getBoundingClientRect()
@@ -263,11 +256,6 @@ export class TextManager {
263
256
  elm.style.setProperty('line-height', `${opts.lineHeight * opts.fontSize}px`)
264
257
  elm.style.setProperty('text-align', textAlignmentsForLtr[opts.textAlign])
265
258
  elm.style.setProperty('font-style', opts.fontStyle)
266
- if (opts.otherStyles) {
267
- for (const [key, value] of Object.entries(opts.otherStyles)) {
268
- elm.style.setProperty(key, value)
269
- }
270
- }
271
259
 
272
260
  const shouldTruncateToFirstLine =
273
261
  opts.overflow === 'truncate-ellipsis' || opts.overflow === 'truncate-clip'
@@ -707,15 +707,7 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
707
707
  onClick?(shape: Shape): TLShapePartial<Shape> | void
708
708
 
709
709
  /**
710
- * A callback called when a shape starts being edited.
711
- *
712
- * @param shape - The shape.
713
- * @public
714
- */
715
- onEditStart?(shape: Shape): void
716
-
717
- /**
718
- * A callback called when a shape finishes being edited.
710
+ * A callback called when a shape finishes being editing.
719
711
  *
720
712
  * @param shape - The shape.
721
713
  * @public
@@ -4,15 +4,15 @@ import { TLDefaultDashStyle } from '@tldraw/tlschema'
4
4
  export function getPerfectDashProps(
5
5
  totalLength: number,
6
6
  strokeWidth: number,
7
- opts: {
8
- style?: TLDefaultDashStyle
9
- snap?: number
10
- end?: 'skip' | 'outset' | 'none'
11
- start?: 'skip' | 'outset' | 'none'
12
- lengthRatio?: number
13
- closed?: boolean
14
- forceSolid?: boolean
15
- } = {}
7
+ opts = {} as Partial<{
8
+ style: TLDefaultDashStyle
9
+ snap: number
10
+ end: 'skip' | 'outset' | 'none'
11
+ start: 'skip' | 'outset' | 'none'
12
+ lengthRatio: number
13
+ closed: boolean
14
+ forceSolid: boolean
15
+ }>
16
16
  ): {
17
17
  strokeDasharray: string
18
18
  strokeDashoffset: string
@@ -19,7 +19,10 @@ import { DefaultHandle, TLHandleProps } from '../components/default-components/D
19
19
  import { DefaultHandles, TLHandlesProps } from '../components/default-components/DefaultHandles'
20
20
  import { DefaultLoadingScreen } from '../components/default-components/DefaultLoadingScreen'
21
21
  import { DefaultScribble, TLScribbleProps } from '../components/default-components/DefaultScribble'
22
- import { TLSelectionBackgroundProps } from '../components/default-components/DefaultSelectionBackground'
22
+ import {
23
+ DefaultSelectionBackground,
24
+ TLSelectionBackgroundProps,
25
+ } from '../components/default-components/DefaultSelectionBackground'
23
26
  import {
24
27
  DefaultSelectionForeground,
25
28
  TLSelectionForegroundProps,
@@ -110,7 +113,7 @@ export function EditorComponentsProvider({
110
113
  OnTheCanvas: null,
111
114
  Overlays: null,
112
115
  Scribble: DefaultScribble,
113
- SelectionBackground: null,
116
+ SelectionBackground: DefaultSelectionBackground,
114
117
  SelectionForeground: DefaultSelectionForeground,
115
118
  ShapeIndicator: DefaultShapeIndicator,
116
119
  ShapeIndicators: DefaultShapeIndicators,
@@ -57,11 +57,6 @@ export class Box {
57
57
  this.x = n
58
58
  }
59
59
 
60
- // eslint-disable-next-line no-restricted-syntax
61
- get left() {
62
- return this.x
63
- }
64
-
65
60
  // eslint-disable-next-line no-restricted-syntax
66
61
  get midX() {
67
62
  return this.x + this.w / 2
@@ -72,11 +67,6 @@ export class Box {
72
67
  return this.x + this.w
73
68
  }
74
69
 
75
- // eslint-disable-next-line no-restricted-syntax
76
- get right() {
77
- return this.x + this.w
78
- }
79
-
80
70
  // eslint-disable-next-line no-restricted-syntax
81
71
  get minY() {
82
72
  return this.y
@@ -87,11 +77,6 @@ export class Box {
87
77
  this.y = n
88
78
  }
89
79
 
90
- // eslint-disable-next-line no-restricted-syntax
91
- get top() {
92
- return this.y
93
- }
94
-
95
80
  // eslint-disable-next-line no-restricted-syntax
96
81
  get midY() {
97
82
  return this.y + this.h / 2
@@ -102,11 +87,6 @@ export class Box {
102
87
  return this.y + this.h
103
88
  }
104
89
 
105
- // eslint-disable-next-line no-restricted-syntax
106
- get bottom() {
107
- return this.y + this.h
108
- }
109
-
110
90
  // eslint-disable-next-line no-restricted-syntax
111
91
  get width() {
112
92
  return this.w
@@ -157,13 +157,12 @@ export class Mat {
157
157
  return Mat.Compose(Mat.Translate(cx, cy!), rotationMatrix, Mat.Translate(-cx, -cy!))
158
158
  }
159
159
 
160
- static Scale(x: number, y: number): Mat
161
- static Scale(x: number, y: number, cx: number, cy: number): Mat
162
- static Scale(x: number, y: number, cx?: number, cy?: number): Mat {
160
+ static Scale(x: number, y: number): MatModel
161
+ static Scale(x: number, y: number, cx: number, cy: number): MatModel
162
+ static Scale(x: number, y: number, cx?: number, cy?: number): MatModel {
163
163
  const scaleMatrix = new Mat(x, 0, 0, y, 0, 0)
164
164
  if (cx === undefined) return scaleMatrix
165
-
166
- return Mat.Translate(cx, cy!).multiply(scaleMatrix).translate(-cx, -cy!)
165
+ return Mat.Compose(Mat.Translate(cx, cy!), scaleMatrix, Mat.Translate(-cx, -cy!))
167
166
  }
168
167
  static Multiply(m1: MatModel, m2: MatModel): MatModel {
169
168
  return {
@@ -319,11 +319,6 @@ export class Vec {
319
319
  return ((A.y - B.y) ** 2 + (A.x - B.x) ** 2) ** 0.5
320
320
  }
321
321
 
322
- // Get the Manhattan distance between two points.
323
- static ManhattanDist(A: VecLike, B: VecLike): number {
324
- return Math.abs(A.x - B.x) + Math.abs(A.y - B.y)
325
- }
326
-
327
322
  // Get whether a distance between two points is less than a number. This is faster to calulate than using `Vec.Dist(a, b) < n`.
328
323
  static DistMin(A: VecLike, B: VecLike, n: number): boolean {
329
324
  return (A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) < n ** 2
@@ -470,28 +465,10 @@ export class Vec {
470
465
  return isNaN(A.x) || isNaN(A.y)
471
466
  }
472
467
 
473
- /**
474
- * Get the angle from position A to position B.
475
- */
476
468
  static Angle(A: VecLike, B: VecLike): number {
477
469
  return Math.atan2(B.y - A.y, B.x - A.x)
478
470
  }
479
471
 
480
- /**
481
- * Get the angle between vector A and vector B. This will return the smallest angle between the
482
- * two vectors, between -π and π. The sign indicates direction of angle.
483
- */
484
- static AngleBetween(A: VecLike, B: VecLike): number {
485
- const p = A.x * B.x + A.y * B.y
486
- const n = Math.sqrt(
487
- (Math.pow(A.x, 2) + Math.pow(A.y, 2)) * (Math.pow(B.x, 2) + Math.pow(B.y, 2))
488
- )
489
- const sign = A.x * B.y - A.y * B.x < 0 ? -1 : 1
490
- const angle = sign * Math.acos(p / n)
491
-
492
- return angle
493
- }
494
-
495
472
  /**
496
473
  * Linearly interpolate between two points.
497
474
  * @param A - The first point.
@@ -1,4 +1,4 @@
1
- import { Vec, VecLike } from '../Vec'
1
+ import { Vec } from '../Vec'
2
2
  import { intersectLineSegmentCircle } from '../intersect'
3
3
  import { getArcMeasure, getPointInArcT, getPointOnCircle } from '../utils'
4
4
  import { Geometry2d, Geometry2dOptions } from './Geometry2d'
@@ -44,14 +44,14 @@ export class Arc2d extends Geometry2d {
44
44
  this._center = center
45
45
  }
46
46
 
47
- nearestPoint(point: VecLike): Vec {
47
+ nearestPoint(point: Vec): Vec {
48
48
  const { _center, measure, radius, angleEnd, angleStart, start: A, end: B } = this
49
49
  const t = getPointInArcT(measure, angleStart, angleEnd, _center.angle(point))
50
50
  if (t <= 0) return A
51
51
  if (t >= 1) return B
52
52
 
53
53
  // Get the point (P) on the arc, then pick the nearest of A, B, and P
54
- const P = Vec.Sub(point, _center).uni().mul(radius).add(_center)
54
+ const P = _center.clone().add(point.clone().sub(_center).uni().mul(radius))
55
55
 
56
56
  let nearest: Vec | undefined
57
57
  let dist = Infinity
@@ -67,7 +67,7 @@ export class Arc2d extends Geometry2d {
67
67
  return nearest
68
68
  }
69
69
 
70
- hitTestLineSegment(A: VecLike, B: VecLike): boolean {
70
+ hitTestLineSegment(A: Vec, B: Vec): boolean {
71
71
  const { _center, radius, measure, angleStart, angleEnd } = this
72
72
  const intersection = intersectLineSegmentCircle(A, B, _center, radius)
73
73
  if (intersection === null) return false
@@ -95,6 +95,6 @@ export class Arc2d extends Geometry2d {
95
95
  }
96
96
 
97
97
  override getLength() {
98
- return Math.abs(this.measure * this.radius)
98
+ return this.measure * this.radius
99
99
  }
100
100
  }
@@ -1,5 +1,5 @@
1
1
  import { Box } from '../Box'
2
- import { Vec, VecLike } from '../Vec'
2
+ import { Vec } from '../Vec'
3
3
  import { intersectLineSegmentCircle } from '../intersect'
4
4
  import { PI2, getPointOnCircle } from '../utils'
5
5
  import { Geometry2d, Geometry2dOptions } from './Geometry2d'
@@ -43,13 +43,13 @@ export class Circle2d extends Geometry2d {
43
43
  return vertices
44
44
  }
45
45
 
46
- nearestPoint(point: VecLike): Vec {
46
+ nearestPoint(point: Vec): Vec {
47
47
  const { _center, radius } = this
48
48
  if (_center.equals(point)) return Vec.AddXY(_center, radius, 0)
49
- return Vec.Sub(point, _center).uni().mul(radius).add(_center)
49
+ return _center.clone().add(point.clone().sub(_center).uni().mul(radius))
50
50
  }
51
51
 
52
- hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {
52
+ hitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {
53
53
  const { _center, radius } = this
54
54
  return intersectLineSegmentCircle(A, B, _center, radius + distance) !== null
55
55
  }
@@ -1,5 +1,5 @@
1
- import { Vec, VecLike } from '../Vec'
2
- import { Geometry2dFilters, Geometry2dOptions } from './Geometry2d'
1
+ import { Vec } from '../Vec'
2
+ import { Geometry2dOptions } from './Geometry2d'
3
3
  import { Polyline2d } from './Polyline2d'
4
4
 
5
5
  /** @public */
@@ -52,7 +52,7 @@ export class CubicBezier2d extends Polyline2d {
52
52
  return CubicBezier2d.GetAtT(this, 0.5)
53
53
  }
54
54
 
55
- nearestPoint(A: VecLike): Vec {
55
+ nearestPoint(A: Vec): Vec {
56
56
  let nearest: Vec | undefined
57
57
  let dist = Infinity
58
58
  let d: number
@@ -89,7 +89,7 @@ export class CubicBezier2d extends Polyline2d {
89
89
  )
90
90
  }
91
91
 
92
- override getLength(filters?: Geometry2dFilters, precision = 32) {
92
+ override getLength(precision = 32) {
93
93
  let n1: Vec,
94
94
  p1 = this.a,
95
95
  length = 0
@@ -1,4 +1,4 @@
1
- import { Vec, VecLike } from '../Vec'
1
+ import { Vec } from '../Vec'
2
2
  import { CubicBezier2d } from './CubicBezier2d'
3
3
  import { Geometry2d, Geometry2dOptions } from './Geometry2d'
4
4
 
@@ -58,7 +58,7 @@ export class CubicSpline2d extends Geometry2d {
58
58
  return vertices
59
59
  }
60
60
 
61
- nearestPoint(A: VecLike): Vec {
61
+ nearestPoint(A: Vec): Vec {
62
62
  let nearest: Vec | undefined
63
63
  let dist = Infinity
64
64
  let d: number
@@ -75,7 +75,7 @@ export class CubicSpline2d extends Geometry2d {
75
75
  return nearest
76
76
  }
77
77
 
78
- hitTestLineSegment(A: VecLike, B: VecLike): boolean {
78
+ hitTestLineSegment(A: Vec, B: Vec): boolean {
79
79
  return this.segments.some((segment) => segment.hitTestLineSegment(A, B))
80
80
  }
81
81
 
@@ -1,5 +1,5 @@
1
+ import { Vec } from '../Vec'
1
2
  import { linesIntersect } from '../intersect'
2
- import { Vec, VecLike } from '../Vec'
3
3
  import { Geometry2d } from './Geometry2d'
4
4
 
5
5
  /** @public */
@@ -34,7 +34,7 @@ export class Edge2d extends Geometry2d {
34
34
  return [this.start, this.end]
35
35
  }
36
36
 
37
- override nearestPoint(point: VecLike): Vec {
37
+ override nearestPoint(point: Vec): Vec {
38
38
  const { start, end, d, u, ul: l } = this
39
39
  if (d.len() === 0) return start // start and end are the same
40
40
  if (l === 0) return start // no length in the unit vector
@@ -48,7 +48,7 @@ export class Edge2d extends Geometry2d {
48
48
  return new Vec(cx, cy)
49
49
  }
50
50
 
51
- override hitTestLineSegment(A: VecLike, B: VecLike, distance = 0): boolean {
51
+ override hitTestLineSegment(A: Vec, B: Vec, distance = 0): boolean {
52
52
  return (
53
53
  linesIntersect(A, B, this.start, this.end) || this.distanceToLineSegment(A, B) <= distance
54
54
  )