@tldraw/editor 3.13.0-canary.b133066477f2 → 3.13.0-canary.b29c8448ae7b

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 (141) hide show
  1. package/dist-cjs/index.d.ts +96 -99
  2. package/dist-cjs/index.js +7 -22
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/Shape.js +12 -8
  5. package/dist-cjs/lib/components/Shape.js.map +2 -2
  6. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +30 -7
  7. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +17 -11
  9. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  10. package/dist-cjs/lib/editor/Editor.js +40 -15
  11. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  12. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +2 -2
  13. package/dist-cjs/lib/editor/managers/TextManager.js +10 -0
  14. package/dist-cjs/lib/editor/managers/TextManager.js.map +2 -2
  15. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +1 -1
  16. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  17. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  18. package/dist-cjs/lib/exports/getSvgJsx.js +12 -3
  19. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  20. package/dist-cjs/lib/hooks/useEditorComponents.js +1 -2
  21. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  22. package/dist-cjs/lib/primitives/Box.js +16 -0
  23. package/dist-cjs/lib/primitives/Box.js.map +2 -2
  24. package/dist-cjs/lib/primitives/Mat.js +1 -1
  25. package/dist-cjs/lib/primitives/Mat.js.map +2 -2
  26. package/dist-cjs/lib/primitives/Vec.js +20 -0
  27. package/dist-cjs/lib/primitives/Vec.js.map +2 -2
  28. package/dist-cjs/lib/primitives/geometry/Arc2d.js +2 -2
  29. package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
  30. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
  31. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
  32. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -1
  33. package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
  34. package/dist-cjs/lib/primitives/geometry/CubicSpline2d.js.map +2 -2
  35. package/dist-cjs/lib/primitives/geometry/Edge2d.js +1 -1
  36. package/dist-cjs/lib/primitives/geometry/Edge2d.js.map +2 -2
  37. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
  38. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +91 -20
  39. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +2 -2
  40. package/dist-cjs/lib/primitives/geometry/Group2d.js +55 -2
  41. package/dist-cjs/lib/primitives/geometry/Group2d.js.map +2 -2
  42. package/dist-cjs/lib/primitives/geometry/Point2d.js.map +2 -2
  43. package/dist-cjs/lib/primitives/geometry/Polyline2d.js.map +2 -2
  44. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +2 -2
  45. package/dist-cjs/lib/utils/areShapesContentEqual.js +25 -0
  46. package/dist-cjs/lib/utils/areShapesContentEqual.js.map +7 -0
  47. package/dist-cjs/lib/utils/debug-flags.js +5 -2
  48. package/dist-cjs/lib/utils/debug-flags.js.map +2 -2
  49. package/dist-cjs/lib/utils/nearestMultiple.js +34 -0
  50. package/dist-cjs/lib/utils/nearestMultiple.js.map +7 -0
  51. package/dist-cjs/version.js +3 -3
  52. package/dist-cjs/version.js.map +1 -1
  53. package/dist-esm/index.d.mts +96 -99
  54. package/dist-esm/index.mjs +9 -41
  55. package/dist-esm/index.mjs.map +2 -2
  56. package/dist-esm/lib/components/Shape.mjs +12 -8
  57. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  58. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +30 -7
  59. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  60. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +17 -11
  61. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  62. package/dist-esm/lib/editor/Editor.mjs +40 -15
  63. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  64. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +2 -2
  65. package/dist-esm/lib/editor/managers/TextManager.mjs +10 -0
  66. package/dist-esm/lib/editor/managers/TextManager.mjs.map +2 -2
  67. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +1 -1
  68. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  69. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  70. package/dist-esm/lib/exports/getSvgJsx.mjs +12 -3
  71. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  72. package/dist-esm/lib/hooks/useEditorComponents.mjs +1 -4
  73. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  74. package/dist-esm/lib/primitives/Box.mjs +16 -0
  75. package/dist-esm/lib/primitives/Box.mjs.map +2 -2
  76. package/dist-esm/lib/primitives/Mat.mjs +1 -1
  77. package/dist-esm/lib/primitives/Mat.mjs.map +2 -2
  78. package/dist-esm/lib/primitives/Vec.mjs +20 -0
  79. package/dist-esm/lib/primitives/Vec.mjs.map +2 -2
  80. package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
  81. package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
  82. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -1
  83. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
  84. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -1
  85. package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
  86. package/dist-esm/lib/primitives/geometry/CubicSpline2d.mjs.map +2 -2
  87. package/dist-esm/lib/primitives/geometry/Edge2d.mjs +1 -1
  88. package/dist-esm/lib/primitives/geometry/Edge2d.mjs.map +2 -2
  89. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
  90. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +92 -21
  91. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +2 -2
  92. package/dist-esm/lib/primitives/geometry/Group2d.mjs +55 -2
  93. package/dist-esm/lib/primitives/geometry/Group2d.mjs.map +2 -2
  94. package/dist-esm/lib/primitives/geometry/Point2d.mjs.map +2 -2
  95. package/dist-esm/lib/primitives/geometry/Polyline2d.mjs.map +2 -2
  96. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +2 -2
  97. package/dist-esm/lib/utils/areShapesContentEqual.mjs +5 -0
  98. package/dist-esm/lib/utils/areShapesContentEqual.mjs.map +7 -0
  99. package/dist-esm/lib/utils/debug-flags.mjs +5 -2
  100. package/dist-esm/lib/utils/debug-flags.mjs.map +2 -2
  101. package/dist-esm/lib/utils/nearestMultiple.mjs +14 -0
  102. package/dist-esm/lib/utils/nearestMultiple.mjs.map +7 -0
  103. package/dist-esm/version.mjs +3 -3
  104. package/dist-esm/version.mjs.map +1 -1
  105. package/editor.css +31 -4
  106. package/package.json +7 -7
  107. package/src/index.ts +16 -31
  108. package/src/lib/components/Shape.tsx +14 -10
  109. package/src/lib/components/default-components/DefaultCanvas.tsx +30 -7
  110. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +17 -8
  111. package/src/lib/editor/Editor.test.ts +1 -1
  112. package/src/lib/editor/Editor.ts +40 -15
  113. package/src/lib/editor/managers/SnapManager/HandleSnaps.ts +0 -1
  114. package/src/lib/editor/managers/TextManager.ts +12 -0
  115. package/src/lib/editor/shapes/ShapeUtil.ts +23 -3
  116. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +9 -9
  117. package/src/lib/exports/getSvgJsx.tsx +16 -7
  118. package/src/lib/hooks/useEditorComponents.tsx +2 -5
  119. package/src/lib/primitives/Box.ts +20 -0
  120. package/src/lib/primitives/Mat.ts +5 -4
  121. package/src/lib/primitives/Vec.ts +23 -0
  122. package/src/lib/primitives/geometry/Arc2d.ts +5 -5
  123. package/src/lib/primitives/geometry/Circle2d.ts +4 -4
  124. package/src/lib/primitives/geometry/CubicBezier2d.ts +4 -4
  125. package/src/lib/primitives/geometry/CubicSpline2d.ts +3 -3
  126. package/src/lib/primitives/geometry/Edge2d.ts +3 -3
  127. package/src/lib/primitives/geometry/Ellipse2d.ts +3 -3
  128. package/src/lib/primitives/geometry/Geometry2d.test.ts +42 -0
  129. package/src/lib/primitives/geometry/Geometry2d.ts +123 -35
  130. package/src/lib/primitives/geometry/Group2d.ts +70 -7
  131. package/src/lib/primitives/geometry/Point2d.ts +2 -2
  132. package/src/lib/primitives/geometry/Polyline2d.ts +3 -3
  133. package/src/lib/primitives/geometry/Stadium2d.ts +3 -3
  134. package/src/lib/test/currentToolIdMask.test.ts +1 -1
  135. package/src/lib/test/user.test.ts +1 -1
  136. package/src/lib/utils/areShapesContentEqual.ts +4 -0
  137. package/src/lib/utils/debug-flags.ts +7 -2
  138. package/src/lib/utils/nearestMultiple.ts +13 -0
  139. package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -1
  140. package/src/lib/utils/sync/TLLocalSyncClient.test.ts +1 -1
  141. package/src/version.ts +3 -3
@@ -5,16 +5,21 @@ import { memo, useLayoutEffect, useRef } from "react";
5
5
  import { useEditor } from "../../hooks/useEditor.mjs";
6
6
  import { useEditorComponents } from "../../hooks/useEditorComponents.mjs";
7
7
  import { OptionalErrorBoundary } from "../ErrorBoundary.mjs";
8
- const EvenInnererIndicator = memo(({ shape, util }) => {
9
- return useStateTracking(
10
- "Indicator: " + shape.type,
11
- () => (
12
- // always fetch the latest shape from the store even if the props/meta have not changed, to avoid
13
- // calling the render method with stale data.
14
- (util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id)))
15
- )
16
- );
17
- });
8
+ const EvenInnererIndicator = memo(
9
+ ({ shape, util }) => {
10
+ return useStateTracking(
11
+ "Indicator: " + shape.type,
12
+ () => (
13
+ // always fetch the latest shape from the store even if the props/meta have not changed, to avoid
14
+ // calling the render method with stale data.
15
+ (util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id)))
16
+ )
17
+ );
18
+ },
19
+ (prevProps, nextProps) => {
20
+ return prevProps.shape.props === nextProps.shape.props && prevProps.shape.meta === nextProps.shape.meta;
21
+ }
22
+ );
18
23
  const InnerIndicator = memo(({ editor, id }) => {
19
24
  const shape = useValue("shape for indicator", () => editor.store.get(id), [editor, id]);
20
25
  const { ShapeIndicatorErrorFallback } = useEditorComponents();
@@ -40,13 +45,14 @@ const DefaultShapeIndicator = memo(function DefaultShapeIndicator2({
40
45
  useQuickReactor(
41
46
  "indicator transform",
42
47
  () => {
48
+ if (hidden) return;
43
49
  const elm = rIndicator.current;
44
50
  if (!elm) return;
45
51
  const pageTransform = editor.getShapePageTransform(shapeId);
46
52
  if (!pageTransform) return;
47
53
  elm.style.setProperty("transform", pageTransform.toCssString());
48
54
  },
49
- [editor, shapeId]
55
+ [editor, shapeId, hidden]
50
56
  );
51
57
  useLayoutEffect(() => {
52
58
  const elm = rIndicator.current;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultShapeIndicator.tsx"],
4
- "sourcesContent": ["import { useQuickReactor, useStateTracking, useValue } from '@tldraw/state-react'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { memo, useLayoutEffect, useRef } from 'react'\nimport type { Editor } from '../../editor/Editor'\nimport { ShapeUtil } from '../../editor/shapes/ShapeUtil'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { OptionalErrorBoundary } from '../ErrorBoundary'\n\n// need an extra layer of indirection here to allow hooks to be used inside the indicator render\nconst EvenInnererIndicator = memo(({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {\n\treturn useStateTracking('Indicator: ' + shape.type, () =>\n\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t// calling the render method with stale data.\n\t\tutil.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)\n\t)\n})\n\nconst InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId }) => {\n\tconst shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])\n\n\tconst { ShapeIndicatorErrorFallback } = useEditorComponents()\n\n\tif (!shape || shape.isLocked) return null\n\n\treturn (\n\t\t<OptionalErrorBoundary\n\t\t\tfallback={ShapeIndicatorErrorFallback}\n\t\t\tonError={(error) =>\n\t\t\t\teditor.annotateError(error, { origin: 'react.shapeIndicator', willCrashApp: false })\n\t\t\t}\n\t\t>\n\t\t\t<EvenInnererIndicator key={shape.id} shape={shape} util={editor.getShapeUtil(shape)} />\n\t\t</OptionalErrorBoundary>\n\t)\n})\n\n/** @public */\nexport interface TLShapeIndicatorProps {\n\tuserId?: string\n\tshapeId: TLShapeId\n\tcolor?: string | undefined\n\topacity?: number\n\tclassName?: string\n\thidden?: boolean\n}\n\n/** @public @react */\nexport const DefaultShapeIndicator = memo(function DefaultShapeIndicator({\n\tshapeId,\n\tclassName,\n\tcolor,\n\thidden,\n\topacity,\n}: TLShapeIndicatorProps) {\n\tconst editor = useEditor()\n\n\tconst rIndicator = useRef<SVGSVGElement>(null)\n\n\tuseQuickReactor(\n\t\t'indicator transform',\n\t\t() => {\n\t\t\tconst elm = rIndicator.current\n\t\t\tif (!elm) return\n\t\t\tconst pageTransform = editor.getShapePageTransform(shapeId)\n\t\t\tif (!pageTransform) return\n\t\t\telm.style.setProperty('transform', pageTransform.toCssString())\n\t\t},\n\t\t[editor, shapeId]\n\t)\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = rIndicator.current\n\t\tif (!elm) return\n\t\telm.style.setProperty('display', hidden ? 'none' : 'block')\n\t}, [hidden])\n\n\treturn (\n\t\t<svg ref={rIndicator} className={classNames('tl-overlays__item', className)}>\n\t\t\t<g className=\"tl-shape-indicator\" stroke={color ?? 'var(--color-selected)'} opacity={opacity}>\n\t\t\t\t<InnerIndicator editor={editor} id={shapeId} />\n\t\t\t</g>\n\t\t</svg>\n\t)\n})\n"],
5
- "mappings": "AAiCG;AAjCH,SAAS,iBAAiB,kBAAkB,gBAAgB;AAE5D,OAAO,gBAAgB;AACvB,SAAS,MAAM,iBAAiB,cAAc;AAG9C,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAGtC,MAAM,uBAAuB,KAAK,CAAC,EAAE,OAAO,KAAK,MAAgD;AAChG,SAAO;AAAA,IAAiB,gBAAgB,MAAM;AAAA,IAAM;AAAA;AAAA;AAAA,MAGnD,KAAK,UAAU,KAAK,OAAO,MAAM,wBAAwB,MAAM,EAAE,CAAY;AAAA;AAAA,EAC9E;AACD,CAAC;AAED,MAAM,iBAAiB,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAyC;AAClF,QAAM,QAAQ,SAAS,uBAAuB,MAAM,OAAO,MAAM,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AAEtF,QAAM,EAAE,4BAA4B,IAAI,oBAAoB;AAE5D,MAAI,CAAC,SAAS,MAAM,SAAU,QAAO;AAErC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,UAAU;AAAA,MACV,SAAS,CAAC,UACT,OAAO,cAAc,OAAO,EAAE,QAAQ,wBAAwB,cAAc,MAAM,CAAC;AAAA,MAGpF,8BAAC,wBAAoC,OAAc,MAAM,OAAO,aAAa,KAAK,KAAvD,MAAM,EAAoD;AAAA;AAAA,EACtF;AAEF,CAAC;AAaM,MAAM,wBAAwB,KAAK,SAASA,uBAAsB;AAAA,EACxE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA0B;AACzB,QAAM,SAAS,UAAU;AAEzB,QAAM,aAAa,OAAsB,IAAI;AAE7C;AAAA,IACC;AAAA,IACA,MAAM;AACL,YAAM,MAAM,WAAW;AACvB,UAAI,CAAC,IAAK;AACV,YAAM,gBAAgB,OAAO,sBAAsB,OAAO;AAC1D,UAAI,CAAC,cAAe;AACpB,UAAI,MAAM,YAAY,aAAa,cAAc,YAAY,CAAC;AAAA,IAC/D;AAAA,IACA,CAAC,QAAQ,OAAO;AAAA,EACjB;AAEA,kBAAgB,MAAM;AACrB,UAAM,MAAM,WAAW;AACvB,QAAI,CAAC,IAAK;AACV,QAAI,MAAM,YAAY,WAAW,SAAS,SAAS,OAAO;AAAA,EAC3D,GAAG,CAAC,MAAM,CAAC;AAEX,SACC,oBAAC,SAAI,KAAK,YAAY,WAAW,WAAW,qBAAqB,SAAS,GACzE,8BAAC,OAAE,WAAU,sBAAqB,QAAQ,SAAS,yBAAyB,SAC3E,8BAAC,kBAAe,QAAgB,IAAI,SAAS,GAC9C,GACD;AAEF,CAAC;",
4
+ "sourcesContent": ["import { useQuickReactor, useStateTracking, useValue } from '@tldraw/state-react'\nimport { TLShape, TLShapeId } from '@tldraw/tlschema'\nimport classNames from 'classnames'\nimport { memo, useLayoutEffect, useRef } from 'react'\nimport type { Editor } from '../../editor/Editor'\nimport { ShapeUtil } from '../../editor/shapes/ShapeUtil'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\nimport { OptionalErrorBoundary } from '../ErrorBoundary'\n\n// need an extra layer of indirection here to allow hooks to be used inside the indicator render\nconst EvenInnererIndicator = memo(\n\t({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {\n\t\treturn useStateTracking('Indicator: ' + shape.type, () =>\n\t\t\t// always fetch the latest shape from the store even if the props/meta have not changed, to avoid\n\t\t\t// calling the render method with stale data.\n\t\t\tutil.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)\n\t\t)\n\t},\n\t(prevProps, nextProps) => {\n\t\treturn (\n\t\t\tprevProps.shape.props === nextProps.shape.props &&\n\t\t\tprevProps.shape.meta === nextProps.shape.meta\n\t\t)\n\t}\n)\n\nconst InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId }) => {\n\tconst shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])\n\n\tconst { ShapeIndicatorErrorFallback } = useEditorComponents()\n\n\tif (!shape || shape.isLocked) return null\n\n\treturn (\n\t\t<OptionalErrorBoundary\n\t\t\tfallback={ShapeIndicatorErrorFallback}\n\t\t\tonError={(error) =>\n\t\t\t\teditor.annotateError(error, { origin: 'react.shapeIndicator', willCrashApp: false })\n\t\t\t}\n\t\t>\n\t\t\t<EvenInnererIndicator key={shape.id} shape={shape} util={editor.getShapeUtil(shape)} />\n\t\t</OptionalErrorBoundary>\n\t)\n})\n\n/** @public */\nexport interface TLShapeIndicatorProps {\n\tuserId?: string\n\tshapeId: TLShapeId\n\tcolor?: string | undefined\n\topacity?: number\n\tclassName?: string\n\thidden?: boolean\n}\n\n/** @public @react */\nexport const DefaultShapeIndicator = memo(function DefaultShapeIndicator({\n\tshapeId,\n\tclassName,\n\tcolor,\n\thidden,\n\topacity,\n}: TLShapeIndicatorProps) {\n\tconst editor = useEditor()\n\n\tconst rIndicator = useRef<SVGSVGElement>(null)\n\n\tuseQuickReactor(\n\t\t'indicator transform',\n\t\t() => {\n\t\t\tif (hidden) return\n\t\t\tconst elm = rIndicator.current\n\t\t\tif (!elm) return\n\t\t\tconst pageTransform = editor.getShapePageTransform(shapeId)\n\t\t\tif (!pageTransform) return\n\t\t\telm.style.setProperty('transform', pageTransform.toCssString())\n\t\t},\n\t\t[editor, shapeId, hidden]\n\t)\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = rIndicator.current\n\t\tif (!elm) return\n\t\telm.style.setProperty('display', hidden ? 'none' : 'block')\n\t}, [hidden])\n\n\treturn (\n\t\t<svg ref={rIndicator} className={classNames('tl-overlays__item', className)}>\n\t\t\t<g className=\"tl-shape-indicator\" stroke={color ?? 'var(--color-selected)'} opacity={opacity}>\n\t\t\t\t<InnerIndicator editor={editor} id={shapeId} />\n\t\t\t</g>\n\t\t</svg>\n\t)\n})\n"],
5
+ "mappings": "AAyCG;AAzCH,SAAS,iBAAiB,kBAAkB,gBAAgB;AAE5D,OAAO,gBAAgB;AACvB,SAAS,MAAM,iBAAiB,cAAc;AAG9C,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAGtC,MAAM,uBAAuB;AAAA,EAC5B,CAAC,EAAE,OAAO,KAAK,MAAgD;AAC9D,WAAO;AAAA,MAAiB,gBAAgB,MAAM;AAAA,MAAM;AAAA;AAAA;AAAA,QAGnD,KAAK,UAAU,KAAK,OAAO,MAAM,wBAAwB,MAAM,EAAE,CAAY;AAAA;AAAA,IAC9E;AAAA,EACD;AAAA,EACA,CAAC,WAAW,cAAc;AACzB,WACC,UAAU,MAAM,UAAU,UAAU,MAAM,SAC1C,UAAU,MAAM,SAAS,UAAU,MAAM;AAAA,EAE3C;AACD;AAEA,MAAM,iBAAiB,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAyC;AAClF,QAAM,QAAQ,SAAS,uBAAuB,MAAM,OAAO,MAAM,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AAEtF,QAAM,EAAE,4BAA4B,IAAI,oBAAoB;AAE5D,MAAI,CAAC,SAAS,MAAM,SAAU,QAAO;AAErC,SACC;AAAA,IAAC;AAAA;AAAA,MACA,UAAU;AAAA,MACV,SAAS,CAAC,UACT,OAAO,cAAc,OAAO,EAAE,QAAQ,wBAAwB,cAAc,MAAM,CAAC;AAAA,MAGpF,8BAAC,wBAAoC,OAAc,MAAM,OAAO,aAAa,KAAK,KAAvD,MAAM,EAAoD;AAAA;AAAA,EACtF;AAEF,CAAC;AAaM,MAAM,wBAAwB,KAAK,SAASA,uBAAsB;AAAA,EACxE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAA0B;AACzB,QAAM,SAAS,UAAU;AAEzB,QAAM,aAAa,OAAsB,IAAI;AAE7C;AAAA,IACC;AAAA,IACA,MAAM;AACL,UAAI,OAAQ;AACZ,YAAM,MAAM,WAAW;AACvB,UAAI,CAAC,IAAK;AACV,YAAM,gBAAgB,OAAO,sBAAsB,OAAO;AAC1D,UAAI,CAAC,cAAe;AACpB,UAAI,MAAM,YAAY,aAAa,cAAc,YAAY,CAAC;AAAA,IAC/D;AAAA,IACA,CAAC,QAAQ,SAAS,MAAM;AAAA,EACzB;AAEA,kBAAgB,MAAM;AACrB,UAAM,MAAM,WAAW;AACvB,QAAI,CAAC,IAAK;AACV,QAAI,MAAM,YAAY,WAAW,SAAS,SAAS,OAAO;AAAA,EAC3D,GAAG,CAAC,MAAM,CAAC;AAEX,SACC,oBAAC,SAAI,KAAK,YAAY,WAAW,WAAW,qBAAqB,SAAS,GACzE,8BAAC,OAAE,WAAU,sBAAqB,QAAQ,SAAS,yBAAyB,SAC3E,8BAAC,kBAAe,QAAgB,IAAI,SAAS,GAC9C,GACD;AAEF,CAAC;",
6
6
  "names": ["DefaultShapeIndicator"]
7
7
  }
@@ -132,6 +132,7 @@ import { Group2d } from "../primitives/geometry/Group2d.mjs";
132
132
  import { intersectPolygonPolygon } from "../primitives/intersect.mjs";
133
133
  import { PI, approximately, areAnglesCompatible, clamp, pointInPolygon } from "../primitives/utils.mjs";
134
134
  import { SharedStyleMap } from "../utils/SharedStylesMap.mjs";
135
+ import { areShapesContentEqual } from "../utils/areShapesContentEqual.mjs";
135
136
  import { dataUrlToFile } from "../utils/assets.mjs";
136
137
  import { debugFlags } from "../utils/debug-flags.mjs";
137
138
  import {
@@ -457,7 +458,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
457
458
  ) : getShapeVisibility;
458
459
  this.options = { ...defaultTldrawOptions, ...options };
459
460
  this.store = store;
460
- this.disposables.add(this.store.dispose.bind(this.store));
461
461
  this.history = new HistoryManager({
462
462
  store,
463
463
  annotateError: (error) => {
@@ -869,6 +869,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
869
869
  dispose() {
870
870
  this.disposables.forEach((dispose) => dispose());
871
871
  this.disposables.clear();
872
+ this.store.dispose();
872
873
  this.isDisposed = true;
873
874
  }
874
875
  getShapeUtil(arg) {
@@ -1771,13 +1772,21 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1771
1772
  setEditingShape(shape) {
1772
1773
  const id = typeof shape === "string" ? shape : shape?.id ?? null;
1773
1774
  this.setRichTextEditor(null);
1774
- if (id !== this.getEditingShapeId()) {
1775
+ const prevEditingShapeId = this.getEditingShapeId();
1776
+ if (id !== prevEditingShapeId) {
1775
1777
  if (id) {
1776
1778
  const shape2 = this.getShape(id);
1777
1779
  if (shape2 && this.getShapeUtil(shape2).canEdit(shape2)) {
1778
1780
  this.run(
1779
1781
  () => {
1780
1782
  this._updateCurrentPageState({ editingShapeId: id });
1783
+ if (prevEditingShapeId) {
1784
+ const prevEditingShape = this.getShape(prevEditingShapeId);
1785
+ if (prevEditingShape) {
1786
+ this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1787
+ }
1788
+ }
1789
+ this.getShapeUtil(shape2).onEditStart?.(shape2);
1781
1790
  },
1782
1791
  { history: "ignore" }
1783
1792
  );
@@ -1788,6 +1797,12 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
1788
1797
  () => {
1789
1798
  this._updateCurrentPageState({ editingShapeId: null });
1790
1799
  this._currentRichTextEditor.set(null);
1800
+ if (prevEditingShapeId) {
1801
+ const prevEditingShape = this.getShape(prevEditingShapeId);
1802
+ if (prevEditingShape) {
1803
+ this.getShapeUtil(prevEditingShape).onEditEnd?.(prevEditingShape);
1804
+ }
1805
+ }
1791
1806
  },
1792
1807
  { history: "ignore" }
1793
1808
  );
@@ -3473,7 +3488,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3473
3488
  this.fonts.trackFontsForShape(shape2);
3474
3489
  return this.getShapeUtil(shape2).getGeometry(shape2, opts);
3475
3490
  },
3476
- { areRecordsEqual: (a, b) => a.props === b.props }
3491
+ { areRecordsEqual: areShapesContentEqual }
3477
3492
  );
3478
3493
  }
3479
3494
  return this._shapeGeometryCaches[context].get(
@@ -3516,9 +3531,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3516
3531
  );
3517
3532
  }
3518
3533
  _getShapeHandlesCache() {
3519
- return this.store.createComputedCache("handles", (shape) => {
3520
- return this.getShapeUtil(shape).getHandles?.(shape);
3521
- });
3534
+ return this.store.createComputedCache(
3535
+ "handles",
3536
+ (shape) => {
3537
+ return this.getShapeUtil(shape).getHandles?.(shape);
3538
+ },
3539
+ {
3540
+ areRecordsEqual: areShapesContentEqual
3541
+ }
3542
+ );
3522
3543
  }
3523
3544
  /**
3524
3545
  * Get the handles (if any) for a shape.
@@ -4402,9 +4423,15 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
4402
4423
  }
4403
4424
  _getBindingsIndexCache() {
4404
4425
  const index = bindingsIndex(this);
4405
- return this.store.createComputedCache("bindingsIndex", (shape) => {
4406
- return index.get().get(shape.id);
4407
- });
4426
+ return this.store.createComputedCache(
4427
+ "bindingsIndex",
4428
+ (shape) => {
4429
+ return index.get().get(shape.id);
4430
+ },
4431
+ // we can ignore the shape equality check here because the index is
4432
+ // computed incrementally based on what bindings are in the store
4433
+ { areRecordsEqual: () => true }
4434
+ );
4408
4435
  }
4409
4436
  /**
4410
4437
  * Get a binding from the store by its ID if it exists.
@@ -7479,7 +7506,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7479
7506
  const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
7480
7507
  const { x: dx, y: dy, z: dz = 0 } = info.delta;
7481
7508
  let behavior = wheelBehavior;
7482
- if (inputs.ctrlKey) behavior = wheelBehavior === "pan" ? "zoom" : "pan";
7509
+ if (info.ctrlKey) behavior = wheelBehavior === "pan" ? "zoom" : "pan";
7483
7510
  switch (behavior) {
7484
7511
  case "zoom": {
7485
7512
  const { x, y } = this.inputs.currentScreenPoint;
@@ -7560,12 +7587,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7560
7587
  const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
7561
7588
  if (this.inputs.isPanning && this.inputs.isPointing) {
7562
7589
  const { currentScreenPoint, previousScreenPoint } = this.inputs;
7563
- const { panSpeed } = cameraOptions;
7564
7590
  const offset = Vec.Sub(currentScreenPoint, previousScreenPoint);
7565
- this.setCamera(
7566
- new Vec(cx + offset.x * panSpeed / cz, cy + offset.y * panSpeed / cz, cz),
7567
- { immediate: true }
7568
- );
7591
+ this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
7592
+ immediate: true
7593
+ });
7569
7594
  this.maybeTrackPerformance("Panning");
7570
7595
  return;
7571
7596
  }