@tldraw/editor 5.1.1 → 5.2.0-canary.019da1aa690a

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 (171) hide show
  1. package/README.md +7 -1
  2. package/dist-cjs/index.d.ts +52 -50
  3. package/dist-cjs/index.js +4 -4
  4. package/dist-cjs/index.js.map +2 -2
  5. package/dist-cjs/lib/components/MenuClickCapture.js +8 -5
  6. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  7. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +4 -1
  8. package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +3 -3
  9. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultLoadingScreen.js.map +2 -2
  11. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js +1 -1
  12. package/dist-cjs/lib/components/default-components/DefaultShapeErrorFallback.js.map +3 -3
  13. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultSvgDefs.js.map +2 -2
  15. package/dist-cjs/lib/editor/Editor.js +121 -55
  16. package/dist-cjs/lib/editor/Editor.js.map +3 -3
  17. package/dist-cjs/lib/editor/derivations/bindingsIndex.js +2 -2
  18. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  19. package/dist-cjs/lib/editor/derivations/parentsToChildren.js +2 -2
  20. package/dist-cjs/lib/editor/derivations/parentsToChildren.js.map +2 -2
  21. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js +2 -2
  22. package/dist-cjs/lib/editor/derivations/shapeIdsInCurrentPage.js.map +2 -2
  23. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +8 -58
  24. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +3 -3
  26. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -2
  28. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +2 -2
  29. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +24 -2
  30. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +2 -2
  31. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +14 -3
  32. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  33. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +4 -2
  34. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +2 -2
  35. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +7 -3
  36. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +2 -2
  37. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +0 -1
  38. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +2 -2
  39. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +15 -2
  40. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  41. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js +79 -0
  42. package/dist-cjs/lib/editor/overlays/strokeShapeIndicators.js.map +7 -0
  43. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js +3 -0
  44. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  45. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  46. package/dist-cjs/lib/editor/types/event-types.js +0 -2
  47. package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
  48. package/dist-cjs/lib/hooks/useCanvasEvents.js +14 -7
  49. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  50. package/dist-cjs/lib/hooks/usePresence.js.map +2 -2
  51. package/dist-cjs/lib/license/LicenseProvider.js +3 -1
  52. package/dist-cjs/lib/license/LicenseProvider.js.map +2 -2
  53. package/dist-cjs/lib/primitives/utils.js +2 -2
  54. package/dist-cjs/lib/primitives/utils.js.map +2 -2
  55. package/dist-cjs/lib/utils/dom.js +5 -3
  56. package/dist-cjs/lib/utils/dom.js.map +2 -2
  57. package/dist-cjs/lib/utils/getPointerInfo.js +2 -1
  58. package/dist-cjs/lib/utils/getPointerInfo.js.map +2 -2
  59. package/dist-cjs/lib/utils/pointer.js +32 -0
  60. package/dist-cjs/lib/utils/pointer.js.map +7 -0
  61. package/dist-cjs/version.js +3 -3
  62. package/dist-cjs/version.js.map +1 -1
  63. package/dist-esm/index.d.mts +52 -50
  64. package/dist-esm/index.mjs +5 -7
  65. package/dist-esm/index.mjs.map +2 -2
  66. package/dist-esm/lib/components/MenuClickCapture.mjs +8 -5
  67. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  68. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +4 -1
  69. package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +3 -3
  70. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs +2 -2
  71. package/dist-esm/lib/components/default-components/DefaultLoadingScreen.mjs.map +2 -2
  72. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs +1 -1
  73. package/dist-esm/lib/components/default-components/DefaultShapeErrorFallback.mjs.map +3 -3
  74. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs +2 -2
  75. package/dist-esm/lib/components/default-components/DefaultSvgDefs.mjs.map +2 -2
  76. package/dist-esm/lib/editor/Editor.mjs +121 -55
  77. package/dist-esm/lib/editor/Editor.mjs.map +3 -3
  78. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs +2 -2
  79. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  80. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs +2 -2
  81. package/dist-esm/lib/editor/derivations/parentsToChildren.mjs.map +2 -2
  82. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs +2 -2
  83. package/dist-esm/lib/editor/derivations/shapeIdsInCurrentPage.mjs.map +2 -2
  84. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +8 -58
  85. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +2 -2
  86. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +3 -3
  87. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +2 -2
  88. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -2
  89. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +2 -2
  90. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +24 -2
  91. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
  92. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +14 -3
  93. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  94. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +4 -2
  95. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +2 -2
  96. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +7 -3
  97. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +2 -2
  98. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +0 -1
  99. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +2 -2
  100. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +15 -2
  101. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  102. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs +59 -0
  103. package/dist-esm/lib/editor/overlays/strokeShapeIndicators.mjs.map +7 -0
  104. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs +3 -0
  105. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  106. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  107. package/dist-esm/lib/editor/types/event-types.mjs +0 -2
  108. package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
  109. package/dist-esm/lib/hooks/useCanvasEvents.mjs +14 -7
  110. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  111. package/dist-esm/lib/hooks/usePresence.mjs.map +2 -2
  112. package/dist-esm/lib/license/LicenseProvider.mjs +3 -1
  113. package/dist-esm/lib/license/LicenseProvider.mjs.map +2 -2
  114. package/dist-esm/lib/primitives/utils.mjs +2 -2
  115. package/dist-esm/lib/primitives/utils.mjs.map +2 -2
  116. package/dist-esm/lib/utils/dom.mjs +5 -3
  117. package/dist-esm/lib/utils/dom.mjs.map +2 -2
  118. package/dist-esm/lib/utils/getPointerInfo.mjs +2 -1
  119. package/dist-esm/lib/utils/getPointerInfo.mjs.map +2 -2
  120. package/dist-esm/lib/utils/pointer.mjs +12 -0
  121. package/dist-esm/lib/utils/pointer.mjs.map +7 -0
  122. package/dist-esm/version.mjs +3 -3
  123. package/dist-esm/version.mjs.map +1 -1
  124. package/editor.css +5 -3
  125. package/package.json +11 -8
  126. package/src/index.ts +2 -5
  127. package/src/lib/components/MenuClickCapture.tsx +8 -4
  128. package/src/lib/components/default-components/DefaultErrorFallback.tsx +4 -1
  129. package/src/lib/components/default-components/DefaultLoadingScreen.tsx +1 -1
  130. package/src/lib/components/default-components/DefaultShapeErrorFallback.tsx +4 -3
  131. package/src/lib/components/default-components/DefaultSvgDefs.tsx +1 -1
  132. package/src/lib/editor/Editor.ts +168 -72
  133. package/src/lib/editor/derivations/bindingsIndex.ts +1 -1
  134. package/src/lib/editor/derivations/parentsToChildren.ts +1 -1
  135. package/src/lib/editor/derivations/shapeIdsInCurrentPage.ts +1 -1
  136. package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +54 -74
  137. package/src/lib/editor/managers/ClickManager/ClickManager.ts +15 -65
  138. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.test.ts +43 -16
  139. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +8 -5
  140. package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +4 -4
  141. package/src/lib/editor/managers/FocusManager/FocusManager.ts +1 -2
  142. package/src/lib/editor/managers/FontManager/FontManager.test.ts +13 -9
  143. package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +32 -0
  144. package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +34 -4
  145. package/src/lib/editor/managers/InputsManager/InputsManager.test.ts +61 -0
  146. package/src/lib/editor/managers/InputsManager/InputsManager.ts +16 -4
  147. package/src/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.ts +9 -2
  148. package/src/lib/editor/managers/TextManager/TextManager.test.ts +16 -14
  149. package/src/lib/editor/managers/TextManager/TextManager.ts +17 -2
  150. package/src/lib/editor/managers/TickManager/TickManager.test.ts +0 -40
  151. package/src/lib/editor/managers/TickManager/TickManager.ts +0 -1
  152. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +12 -2
  153. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +27 -2
  154. package/src/lib/editor/overlays/strokeShapeIndicators.ts +86 -0
  155. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +4 -0
  156. package/src/lib/editor/tools/StateNode.ts +0 -2
  157. package/src/lib/editor/types/event-types.ts +2 -6
  158. package/src/lib/hooks/useCanvasEvents.ts +19 -12
  159. package/src/lib/hooks/usePresence.ts +2 -2
  160. package/src/lib/license/LicenseProvider.tsx +3 -1
  161. package/src/lib/primitives/utils.ts +1 -1
  162. package/src/lib/utils/dom.ts +5 -3
  163. package/src/lib/utils/getPointerInfo.ts +2 -1
  164. package/src/lib/utils/pointer.test.ts +48 -0
  165. package/src/lib/utils/pointer.ts +18 -0
  166. package/src/version.ts +3 -3
  167. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +0 -161
  168. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +0 -7
  169. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +0 -141
  170. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +0 -7
  171. package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +0 -216
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultErrorFallback.tsx"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { getOwnerDocument } from '../../exports/domUtils'\nimport { useEditorComponents } from '../../hooks/EditorComponentsContext'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { getGlobalWindow } from '../../utils/dom'\nimport { hardResetEditor, refreshPage } from '../../utils/runtime'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }) => {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState<null | boolean>(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' && getGlobalWindow().matchMedia) {\n\t\t\tsetIsDarkMode(getGlobalWindow().matchMedia('(prefers-color-scheme: dark)').matches)\n\t\t}\n\t}, [isDarkModeFromApp])\n\n\tuseEffect(() => {\n\t\tif (didCopy) {\n\t\t\tconst timeout = editor?.timers.setTimeout(() => {\n\t\t\t\tsetDidCopy(false)\n\t\t\t}, 2000)\n\t\t\treturn () => clearTimeout(timeout)\n\t\t}\n\t}, [didCopy, editor])\n\n\tconst copyError = () => {\n\t\tconst doc = getOwnerDocument(containerRef.current)\n\t\tconst textarea = doc.createElement('textarea')\n\t\ttextarea.value = errorStack ?? errorMessage\n\t\tdoc.body.appendChild(textarea)\n\t\ttextarea.select()\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tdoc.execCommand('copy')\n\t\ttextarea.remove()\n\t\tsetDidCopy(true)\n\t}\n\n\tconst refresh = () => {\n\t\trefreshPage()\n\t}\n\n\tconst resetLocalState = async () => {\n\t\thardResetEditor()\n\t}\n\n\tconst url = new URL(BASE_ERROR_URL)\n\turl.searchParams.set('title', errorMessage)\n\turl.searchParams.set('labels', `bug`)\n\turl.searchParams.set(\n\t\t'body',\n\t\t`Hey, I ran into an error while using tldraw:\n\n\\`\\`\\`js\n${errorStack ?? errorMessage}\n\\`\\`\\`\n\nMy browser: ${navigator.userAgent}`\n\t)\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName={classNames(\n\t\t\t\t'tl-container tl-error-boundary',\n\t\t\t\t// error-boundary is sometimes used outside of the theme\n\t\t\t\t// container, so we need to provide it with a theme for our\n\t\t\t\t// styles to work correctly\n\t\t\t\tisDarkMode === null ? '' : isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'\n\t\t\t)}\n\t\t>\n\t\t\t<div className=\"tl-error-boundary__overlay\" />\n\t\t\t{editor && (\n\t\t\t\t// opportunistically attempt to render the canvas to reassure\n\t\t\t\t// the user that their document is still there. there's a good\n\t\t\t\t// chance this won't work (ie the error that we're currently\n\t\t\t\t// notifying the user about originates in the canvas) so it's\n\t\t\t\t// not a big deal if it doesn't work - in that case we just have\n\t\t\t\t// a plain grey background.\n\t\t\t\t<ErrorBoundary onError={noop} fallback={() => null}>\n\t\t\t\t\t<EditorProvider editor={editor}>\n\t\t\t\t\t\t<div className=\"tl-overlay tl-error-boundary__canvas\">{Canvas ? <Canvas /> : null}</div>\n\t\t\t\t\t</EditorProvider>\n\t\t\t\t</ErrorBoundary>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={classNames('tl-modal', 'tl-error-boundary__content', {\n\t\t\t\t\t'tl-error-boundary__content__expanded': shouldShowError && !shouldShowResetConfirmation,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{shouldShowResetConfirmation ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Are you sure?</h2>\n\t\t\t\t\t\t<p>Resetting your data will delete your drawing and cannot be undone.</p>\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowResetConfirmation(false)}>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__reset\" onClick={resetLocalState}>\n\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Something went wrong</h2>\n\t\t\t\t\t\t<p>Please refresh your browser.</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tIf the issue continues after refreshing, you may need to reset the tldraw data stored\n\t\t\t\t\t\t\ton your device.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<strong>Note:</strong> Resetting will erase your current project and any unsaved work.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{process.env.NODE_ENV !== 'production' && (\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\tIf you&apos;re developing with the SDK and need help, join us on{' '}\n\t\t\t\t\t\t\t\t<a href=\"https://discord.tldraw.com/?utm_source=sdk&utm_medium=organic&utm_campaign=error-screen\">\n\t\t\t\t\t\t\t\t\tDiscord\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{shouldShowError && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tMessage:\n\t\t\t\t\t\t\t\t<h4>\n\t\t\t\t\t\t\t\t\t<code>{errorMessage}</code>\n\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\tStack trace:\n\t\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__error\">\n\t\t\t\t\t\t\t\t\t<pre>\n\t\t\t\t\t\t\t\t\t\t<code>{errorStack ?? errorMessage}</code>\n\t\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={copyError}>\n\t\t\t\t\t\t\t\t\t\t{didCopy ? 'Copied!' : 'Copy'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowError(!shouldShowError)}>\n\t\t\t\t\t\t\t\t{shouldShowError ? 'Hide details' : 'Show details'}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions__group\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-button tl-error-boundary__reset\"\n\t\t\t\t\t\t\t\t\tonClick={() => setShouldShowResetConfirmation(true)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__refresh\" onClick={refresh}>\n\t\t\t\t\t\t\t\t\tRefresh Page\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],
5
- "mappings": "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",
6
- "names": ["classNames"]
4
+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { noop } from '@tldraw/utils'\nimport classNames from 'classnames'\nimport { ComponentType, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { Editor } from '../../editor/Editor'\nimport { getOwnerDocument } from '../../exports/domUtils'\nimport { useEditorComponents } from '../../hooks/EditorComponentsContext'\nimport { EditorProvider } from '../../hooks/useEditor'\nimport { getGlobalWindow } from '../../utils/dom'\nimport { hardResetEditor, refreshPage } from '../../utils/runtime'\nimport { ErrorBoundary } from '../ErrorBoundary'\n\nconst BASE_ERROR_URL = 'https://github.com/tldraw/tldraw/issues/new'\n\n/** @public */\nexport type TLErrorFallbackComponent = ComponentType<{ error: unknown; editor?: Editor }>\n\n/** @public @react */\nexport const DefaultErrorFallback: TLErrorFallbackComponent = function DefaultErrorFallback({\n\terror,\n\teditor,\n}) {\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst [shouldShowError, setShouldShowError] = useState(process.env.NODE_ENV === 'development')\n\tconst [didCopy, setDidCopy] = useState(false)\n\tconst [shouldShowResetConfirmation, setShouldShowResetConfirmation] = useState(false)\n\n\tlet Canvas: React.ComponentType | null = null\n\ttry {\n\t\t// eslint-disable-next-line react-hooks/rules-of-hooks\n\t\tconst components = useEditorComponents()\n\t\tCanvas = components.Canvas ?? null\n\t} catch {\n\t\t// allow this to fail silently\n\t}\n\n\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\tconst errorStack = error instanceof Error ? error.stack : null\n\n\tconst isDarkModeFromApp = useValue(\n\t\t'isDarkMode',\n\t\t() => {\n\t\t\ttry {\n\t\t\t\tif (editor) {\n\t\t\t\t\treturn editor.user.getIsDarkMode()\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// we're in a funky error state so this might not work for spooky\n\t\t\t\t// reasons. if not, we'll have another attempt later:\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\t\t[editor]\n\t)\n\tconst [isDarkMode, setIsDarkMode] = useState<null | boolean>(null)\n\tuseLayoutEffect(() => {\n\t\t// if we found a theme class from the app, we can just use that\n\t\tif (isDarkModeFromApp !== null) {\n\t\t\tsetIsDarkMode(isDarkModeFromApp)\n\t\t}\n\n\t\t// do any of our parents have a theme class? if yes then we can just\n\t\t// rely on that and don't need to set our own class\n\t\tlet parent = containerRef.current?.parentElement\n\t\tlet foundParentThemeClass = false\n\t\twhile (parent) {\n\t\t\tif (\n\t\t\t\tparent.classList.contains('tl-theme__dark') ||\n\t\t\t\tparent.classList.contains('tl-theme__light')\n\t\t\t) {\n\t\t\t\tfoundParentThemeClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tparent = parent.parentElement\n\t\t}\n\t\tif (foundParentThemeClass) {\n\t\t\tsetIsDarkMode(null)\n\t\t\treturn\n\t\t}\n\n\t\t// if we can't find a theme class from the app or from a parent, we have\n\t\t// to fall back on using a media query:\n\t\tif (typeof window !== 'undefined' && getGlobalWindow().matchMedia) {\n\t\t\tsetIsDarkMode(getGlobalWindow().matchMedia('(prefers-color-scheme: dark)').matches)\n\t\t}\n\t}, [isDarkModeFromApp])\n\n\tuseEffect(() => {\n\t\tif (didCopy) {\n\t\t\tconst timeout = editor?.timers.setTimeout(() => {\n\t\t\t\tsetDidCopy(false)\n\t\t\t}, 2000)\n\t\t\treturn () => clearTimeout(timeout)\n\t\t}\n\t}, [didCopy, editor])\n\n\tconst copyError = () => {\n\t\tconst doc = getOwnerDocument(containerRef.current)\n\t\tconst textarea = doc.createElement('textarea')\n\t\ttextarea.value = errorStack ?? errorMessage\n\t\tdoc.body.appendChild(textarea)\n\t\ttextarea.select()\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated\n\t\tdoc.execCommand('copy')\n\t\ttextarea.remove()\n\t\tsetDidCopy(true)\n\t}\n\n\tconst refresh = () => {\n\t\trefreshPage()\n\t}\n\n\tconst resetLocalState = async () => {\n\t\thardResetEditor()\n\t}\n\n\tconst url = new URL(BASE_ERROR_URL)\n\turl.searchParams.set('title', errorMessage)\n\turl.searchParams.set('labels', `bug`)\n\turl.searchParams.set(\n\t\t'body',\n\t\t`Hey, I ran into an error while using tldraw:\n\n\\`\\`\\`js\n${errorStack ?? errorMessage}\n\\`\\`\\`\n\nMy browser: ${navigator.userAgent}`\n\t)\n\n\treturn (\n\t\t<div\n\t\t\tref={containerRef}\n\t\t\tclassName={classNames(\n\t\t\t\t'tl-container tl-error-boundary',\n\t\t\t\t// error-boundary is sometimes used outside of the theme\n\t\t\t\t// container, so we need to provide it with a theme for our\n\t\t\t\t// styles to work correctly\n\t\t\t\tisDarkMode === null ? '' : isDarkMode ? 'tl-theme__dark' : 'tl-theme__light'\n\t\t\t)}\n\t\t>\n\t\t\t<div className=\"tl-error-boundary__overlay\" />\n\t\t\t{editor && (\n\t\t\t\t// opportunistically attempt to render the canvas to reassure\n\t\t\t\t// the user that their document is still there. there's a good\n\t\t\t\t// chance this won't work (ie the error that we're currently\n\t\t\t\t// notifying the user about originates in the canvas) so it's\n\t\t\t\t// not a big deal if it doesn't work - in that case we just have\n\t\t\t\t// a plain grey background.\n\t\t\t\t<ErrorBoundary onError={noop} fallback={() => null}>\n\t\t\t\t\t<EditorProvider editor={editor}>\n\t\t\t\t\t\t<div className=\"tl-overlay tl-error-boundary__canvas\">{Canvas ? <Canvas /> : null}</div>\n\t\t\t\t\t</EditorProvider>\n\t\t\t\t</ErrorBoundary>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\tclassName={classNames('tl-modal', 'tl-error-boundary__content', {\n\t\t\t\t\t'tl-error-boundary__content__expanded': shouldShowError && !shouldShowResetConfirmation,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{shouldShowResetConfirmation ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Are you sure?</h2>\n\t\t\t\t\t\t<p>Resetting your data will delete your drawing and cannot be undone.</p>\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowResetConfirmation(false)}>\n\t\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__reset\" onClick={resetLocalState}>\n\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t) : (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<h2>Something went wrong</h2>\n\t\t\t\t\t\t<p>Please refresh your browser.</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tIf the issue continues after refreshing, you may need to reset the tldraw data stored\n\t\t\t\t\t\t\ton your device.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t<strong>Note:</strong> Resetting will erase your current project and any unsaved work.\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{process.env.NODE_ENV !== 'production' && (\n\t\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\t\tIf you&apos;re developing with the SDK and need help, join us on{' '}\n\t\t\t\t\t\t\t\t<a href=\"https://discord.tldraw.com/?utm_source=sdk&utm_medium=organic&utm_campaign=error-screen\">\n\t\t\t\t\t\t\t\t\tDiscord\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t\t.\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{shouldShowError && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\tMessage:\n\t\t\t\t\t\t\t\t<h4>\n\t\t\t\t\t\t\t\t\t<code>{errorMessage}</code>\n\t\t\t\t\t\t\t\t</h4>\n\t\t\t\t\t\t\t\tStack trace:\n\t\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__error\">\n\t\t\t\t\t\t\t\t\t<pre>\n\t\t\t\t\t\t\t\t\t\t<code>{errorStack ?? errorMessage}</code>\n\t\t\t\t\t\t\t\t\t</pre>\n\t\t\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={copyError}>\n\t\t\t\t\t\t\t\t\t\t{didCopy ? 'Copied!' : 'Copy'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions\">\n\t\t\t\t\t\t\t<button className=\"tlui-button\" onClick={() => setShouldShowError(!shouldShowError)}>\n\t\t\t\t\t\t\t\t{shouldShowError ? 'Hide details' : 'Show details'}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<div className=\"tl-error-boundary__content__actions__group\">\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-button tl-error-boundary__reset\"\n\t\t\t\t\t\t\t\t\tonClick={() => setShouldShowResetConfirmation(true)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tReset data\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button className=\"tlui-button tl-error-boundary__refresh\" onClick={refresh}>\n\t\t\t\t\t\t\t\t\tRefresh Page\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["DefaultErrorFallback", "classNames"]
7
7
  }
@@ -23,8 +23,8 @@ __export(DefaultLoadingScreen_exports, {
23
23
  module.exports = __toCommonJS(DefaultLoadingScreen_exports);
24
24
  var import_jsx_runtime = require("react/jsx-runtime");
25
25
  var import_EditorComponentsContext = require("../../hooks/EditorComponentsContext");
26
- const DefaultLoadingScreen = () => {
26
+ function DefaultLoadingScreen() {
27
27
  const { Spinner } = (0, import_EditorComponentsContext.useEditorComponents)();
28
28
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tl-loading", "aria-busy": "true", tabIndex: 0, children: Spinner ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}) : null });
29
- };
29
+ }
30
30
  //# sourceMappingURL=DefaultLoadingScreen.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultLoadingScreen.tsx"],
4
- "sourcesContent": ["import { useEditorComponents } from '../../hooks/EditorComponentsContext'\n\n/** @public @react */\nexport const DefaultLoadingScreen = () => {\n\tconst { Spinner } = useEditorComponents()\n\treturn (\n\t\t<div className=\"tl-loading\" aria-busy=\"true\" tabIndex={0}>\n\t\t\t{Spinner ? <Spinner /> : null}\n\t\t</div>\n\t)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOc;AAPd,qCAAoC;AAG7B,MAAM,uBAAuB,MAAM;AACzC,QAAM,EAAE,QAAQ,QAAI,oDAAoB;AACxC,SACC,4CAAC,SAAI,WAAU,cAAa,aAAU,QAAO,UAAU,GACrD,oBAAU,4CAAC,WAAQ,IAAK,MAC1B;AAEF;",
4
+ "sourcesContent": ["import { useEditorComponents } from '../../hooks/EditorComponentsContext'\n\n/** @public @react */\nexport function DefaultLoadingScreen() {\n\tconst { Spinner } = useEditorComponents()\n\treturn (\n\t\t<div className=\"tl-loading\" aria-busy=\"true\" tabIndex={0}>\n\t\t\t{Spinner ? <Spinner /> : null}\n\t\t</div>\n\t)\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOc;AAPd,qCAAoC;AAG7B,SAAS,uBAAuB;AACtC,QAAM,EAAE,QAAQ,QAAI,oDAAoB;AACxC,SACC,4CAAC,SAAI,WAAU,cAAa,aAAU,QAAO,UAAU,GACrD,oBAAU,4CAAC,WAAQ,IAAK,MAC1B;AAEF;",
6
6
  "names": []
7
7
  }
@@ -22,7 +22,7 @@ __export(DefaultShapeErrorFallback_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(DefaultShapeErrorFallback_exports);
24
24
  var import_jsx_runtime = require("react/jsx-runtime");
25
- const DefaultShapeErrorFallback = () => {
25
+ const DefaultShapeErrorFallback = function DefaultShapeErrorFallback2() {
26
26
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tl-shape-error-boundary" });
27
27
  };
28
28
  //# sourceMappingURL=DefaultShapeErrorFallback.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultShapeErrorFallback.tsx"],
4
- "sourcesContent": ["import { ComponentType } from 'react'\n\n/** @public */\nexport type TLShapeErrorFallbackComponent = ComponentType<{ error: any }>\n\n/** @internal */\nexport const DefaultShapeErrorFallback: TLShapeErrorFallbackComponent = () => {\n\treturn <div className=\"tl-shape-error-boundary\" />\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOQ;AADD,MAAM,4BAA2D,MAAM;AAC7E,SAAO,4CAAC,SAAI,WAAU,2BAA0B;AACjD;",
6
- "names": []
4
+ "sourcesContent": ["import { ComponentType } from 'react'\n\n/** @public */\nexport type TLShapeErrorFallbackComponent = ComponentType<{ error: any }>\n\n/** @internal */\nexport const DefaultShapeErrorFallback: TLShapeErrorFallbackComponent =\n\tfunction DefaultShapeErrorFallback() {\n\t\treturn <div className=\"tl-shape-error-boundary\" />\n\t}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQS;AAFF,MAAM,4BACZ,SAASA,6BAA4B;AACpC,SAAO,4CAAC,SAAI,WAAU,2BAA0B;AACjD;",
6
+ "names": ["DefaultShapeErrorFallback"]
7
7
  }
@@ -21,7 +21,7 @@ __export(DefaultSvgDefs_exports, {
21
21
  DefaultSvgDefs: () => DefaultSvgDefs
22
22
  });
23
23
  module.exports = __toCommonJS(DefaultSvgDefs_exports);
24
- const DefaultSvgDefs = () => {
24
+ function DefaultSvgDefs() {
25
25
  return null;
26
- };
26
+ }
27
27
  //# sourceMappingURL=DefaultSvgDefs.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultSvgDefs.tsx"],
4
- "sourcesContent": ["/** @public @react */\nexport const DefaultSvgDefs = () => {\n\treturn null\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACO,MAAM,iBAAiB,MAAM;AACnC,SAAO;AACR;",
4
+ "sourcesContent": ["/** @public @react */\nexport function DefaultSvgDefs() {\n\treturn null\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACO,SAAS,iBAAiB;AAChC,SAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -155,12 +155,12 @@ class Editor extends import_eventemitter3.default {
155
155
  this._tickManager = new import_TickManager.TickManager(this);
156
156
  this.disposables.add(() => this._tickManager.dispose());
157
157
  this.disposables.add(() => {
158
- this.off("tick", this._decayCameraStateTimeout);
159
158
  this._setCameraState("idle");
160
159
  });
161
160
  this.fonts = new import_FontManager.FontManager(this, fontAssetUrls);
162
161
  this.disposables.add(() => this.fonts.dispose());
163
162
  this.inputs = new import_InputsManager.InputsManager(this);
163
+ this.disposables.add(() => this.inputs.dispose());
164
164
  this.performance = new import_PerformanceManager.PerformanceManager(this);
165
165
  this.disposables.add(() => this.performance.dispose());
166
166
  this.collaborators = new import_CollaboratorsManager.CollaboratorsManager(this);
@@ -789,6 +789,7 @@ class Editor extends import_eventemitter3.default {
789
789
  this.store.dispose();
790
790
  this.isDisposed = true;
791
791
  this.emit("dispose");
792
+ this.removeAllListeners();
792
793
  }
793
794
  /* ------------------ Themes (shadowing the theme manager) ------------------ */
794
795
  /**
@@ -1058,6 +1059,14 @@ class Editor extends import_eventemitter3.default {
1058
1059
  getMarkIdMatching(idSubstring) {
1059
1060
  return this.history.getMarkIdMatching(idSubstring);
1060
1061
  }
1062
+ /**
1063
+ * Whether the editor is currently replaying history (i.e. an undo or redo is being applied).
1064
+ *
1065
+ * @internal
1066
+ */
1067
+ isReplayingHistory() {
1068
+ return this.history.isReplaying();
1069
+ }
1061
1070
  /**
1062
1071
  * Coalesces all changes since the given mark into a single change, removing any intermediate marks.
1063
1072
  *
@@ -2152,7 +2161,7 @@ class Editor extends import_eventemitter3.default {
2152
2161
  return baseCamera;
2153
2162
  }
2154
2163
  _getFollowingPresence(targetUserId) {
2155
- const visited = [this.user.getId()];
2164
+ const visited = [this.user.getRecordId()];
2156
2165
  const collaborators = this.getCollaborators();
2157
2166
  let leaderPresence = null;
2158
2167
  while (targetUserId && !visited.includes(targetUserId)) {
@@ -2340,6 +2349,11 @@ class Editor extends import_eventemitter3.default {
2340
2349
  getConstrainedCamera(point, opts) {
2341
2350
  const currentCamera = this.getCamera();
2342
2351
  let { x, y, z = currentCamera.z } = point;
2352
+ const preserveFocalPoint = (current, requested, rz, z2) => {
2353
+ const cz = currentCamera.z;
2354
+ if (rz === cz) return current;
2355
+ return current + (requested - current) * (1 / z2 - 1 / cz) / (1 / rz - 1 / cz);
2356
+ };
2343
2357
  if (!opts?.force) {
2344
2358
  const cameraOptions = this.getCameraOptions();
2345
2359
  const zoomMin = cameraOptions.zoomSteps[0];
@@ -2359,14 +2373,10 @@ class Editor extends import_eventemitter3.default {
2359
2373
  z = this.getInitialZoom();
2360
2374
  }
2361
2375
  if (z < minZ || z > maxZ) {
2362
- const { x: cx, y: cy, z: cz } = currentCamera;
2363
- const cxA = -cx + vsb.w / cz / 2;
2364
- const cyA = -cy + vsb.h / cz / 2;
2376
+ const rz = z;
2365
2377
  z = (0, import_utils2.clamp)(z, minZ, maxZ);
2366
- const cxB = -cx + vsb.w / z / 2;
2367
- const cyB = -cy + vsb.h / z / 2;
2368
- x = cx + cxB - cxA;
2369
- y = cy + cyB - cyA;
2378
+ x = preserveFocalPoint(currentCamera.x, x, rz, z);
2379
+ y = preserveFocalPoint(currentCamera.y, y, rz, z);
2370
2380
  }
2371
2381
  const minX = px / z - bounds.x;
2372
2382
  const minY = py / z - bounds.y;
@@ -2435,10 +2445,10 @@ class Editor extends import_eventemitter3.default {
2435
2445
  }
2436
2446
  } else {
2437
2447
  if (z > zoomMax || z < zoomMin) {
2438
- const { x: cx, y: cy, z: cz } = currentCamera;
2448
+ const rz = z;
2439
2449
  z = (0, import_utils2.clamp)(z, zoomMin, zoomMax);
2440
- x = cx + (-cx + vsb.w / z / 2) - (-cx + vsb.w / cz / 2);
2441
- y = cy + (-cy + vsb.h / z / 2) - (-cy + vsb.h / cz / 2);
2450
+ x = preserveFocalPoint(currentCamera.x, x, rz, z);
2451
+ y = preserveFocalPoint(currentCamera.y, y, rz, z);
2442
2452
  }
2443
2453
  }
2444
2454
  }
@@ -2861,14 +2871,25 @@ class Editor extends import_eventemitter3.default {
2861
2871
  this.off("stop-camera-animation", cancel);
2862
2872
  };
2863
2873
  this.once("stop-camera-animation", cancel);
2874
+ const dirZ = direction.z ?? 0;
2864
2875
  const moveCamera = (elapsed) => {
2865
2876
  const { x: cx, y: cy, z: cz } = this.getCamera();
2866
- const movementVec = import_Vec.Vec.Mul(direction, currentSpeed * elapsed / cz);
2877
+ const dx = direction.x * (currentSpeed * elapsed) / cz;
2878
+ const dy = direction.y * (currentSpeed * elapsed) / cz;
2879
+ let newCx = cx + dx;
2880
+ let newCy = cy + dy;
2881
+ let newCz = cz;
2882
+ if (dirZ !== 0) {
2883
+ newCz = cz * (1 + dirZ * currentSpeed * elapsed);
2884
+ const center = this.getViewportScreenCenter();
2885
+ newCx += center.x / newCz - center.x / cz;
2886
+ newCy += center.y / newCz - center.y / cz;
2887
+ }
2867
2888
  currentSpeed *= 1 - friction;
2868
2889
  if (currentSpeed < speedThreshold) {
2869
2890
  cancel();
2870
2891
  } else {
2871
- this._setCamera(new import_Vec.Vec(cx + movementVec.x, cy + movementVec.y, cz));
2892
+ this._setCamera(new import_Vec.Vec(newCx, newCy, newCz));
2872
2893
  }
2873
2894
  };
2874
2895
  this.on("tick", moveCamera);
@@ -3188,7 +3209,7 @@ class Editor extends import_eventemitter3.default {
3188
3209
  */
3189
3210
  startFollowingUser(userId) {
3190
3211
  this.stopFollowingUser();
3191
- const thisUserId = this.user.getId();
3212
+ const thisUserId = this.user.getExternalId();
3192
3213
  if (!thisUserId) {
3193
3214
  console.warn("You should set the userId for the current instance before following a user");
3194
3215
  }
@@ -5892,24 +5913,40 @@ class Editor extends import_eventemitter3.default {
5892
5913
  * @public
5893
5914
  */
5894
5915
  resizeShape(shape, scale, opts = {}) {
5916
+ const partial = this.getResizeShapePartial(shape, scale, opts);
5917
+ if (partial) this.updateShapes([partial]);
5918
+ return this;
5919
+ }
5920
+ /**
5921
+ * Get the update for a resized shape without committing it to the store. Interactions that
5922
+ * resize many shapes at once use this to collect all of the updates and commit them in a
5923
+ * single batch. Returns null when there is nothing to update.
5924
+ *
5925
+ * Shapes that are rotated out of alignment with the scale axis cannot be resized with a
5926
+ * single update; those shapes are resized immediately (as `resizeShape` would do) and null
5927
+ * is returned.
5928
+ *
5929
+ * @internal
5930
+ */
5931
+ getResizeShapePartial(shape, scale, opts = {}) {
5895
5932
  const id = typeof shape === "string" ? shape : shape.id;
5896
- if (this.getIsReadonly()) return this;
5933
+ if (this.getIsReadonly()) return null;
5897
5934
  if (!Number.isFinite(scale.x)) scale = new import_Vec.Vec(1, scale.y);
5898
5935
  if (!Number.isFinite(scale.y)) scale = new import_Vec.Vec(scale.x, 1);
5899
5936
  const initialShape = opts.initialShape ?? this.getShape(id);
5900
- if (!initialShape) return this;
5937
+ if (!initialShape) return null;
5901
5938
  const scaleOrigin = opts.scaleOrigin ?? this.getShapePageBounds(id)?.center;
5902
- if (!scaleOrigin) return this;
5939
+ if (!scaleOrigin) return null;
5903
5940
  const pageTransform = opts.initialPageTransform ? import_Mat.Mat.Cast(opts.initialPageTransform) : this.getShapePageTransform(id);
5904
- if (!pageTransform) return this;
5941
+ if (!pageTransform) return null;
5905
5942
  const pageRotation = pageTransform.rotation();
5906
- if (pageRotation == null) return this;
5943
+ if (pageRotation == null) return null;
5907
5944
  const scaleAxisRotation = opts.scaleAxisRotation ?? pageRotation;
5908
5945
  const initialBounds = opts.initialBounds ?? this.getShapeGeometry(id).bounds;
5909
- if (!initialBounds) return this;
5946
+ if (!initialBounds) return null;
5910
5947
  const isAspectRatioLocked = opts.isAspectRatioLocked ?? this.getShapeUtil(initialShape).isAspectRatioLocked(initialShape);
5911
5948
  if (!(0, import_utils2.areAnglesCompatible)(pageRotation, scaleAxisRotation)) {
5912
- return this._resizeUnalignedShape(id, scale, {
5949
+ this._resizeUnalignedShape(id, scale, {
5913
5950
  ...opts,
5914
5951
  initialBounds,
5915
5952
  scaleOrigin,
@@ -5918,6 +5955,7 @@ class Editor extends import_eventemitter3.default {
5918
5955
  isAspectRatioLocked,
5919
5956
  initialShape
5920
5957
  });
5958
+ return null;
5921
5959
  }
5922
5960
  const util = this.getShapeUtil(initialShape);
5923
5961
  if (isAspectRatioLocked) {
@@ -5927,7 +5965,7 @@ class Editor extends import_eventemitter3.default {
5927
5965
  scale = new import_Vec.Vec(Math.sign(scale.x) * Math.abs(scale.y), scale.y);
5928
5966
  }
5929
5967
  }
5930
- let didResize = false;
5968
+ let workingShape = null;
5931
5969
  if (util.onResize && util.canResize(initialShape)) {
5932
5970
  const newPagePoint = this._scalePagePoint(
5933
5971
  import_Mat.Mat.applyToPoint(pageTransform, new import_Vec.Vec(0, 0)),
@@ -5945,7 +5983,7 @@ class Editor extends import_eventemitter3.default {
5945
5983
  myScale.y = areWidthAndHeightAlignedWithCorrectAxis ? scale.y : scale.x;
5946
5984
  const initialPagePoint = import_Mat.Mat.applyToPoint(pageTransform, new import_Vec.Vec());
5947
5985
  const { x, y } = this.getPointInParentSpace(initialShape.id, initialPagePoint);
5948
- let workingShape = initialShape;
5986
+ workingShape = initialShape;
5949
5987
  if (!opts.skipStartAndEndCallbacks) {
5950
5988
  workingShape = applyPartialToRecordWithProps(
5951
5989
  initialShape,
@@ -5965,9 +6003,6 @@ class Editor extends import_eventemitter3.default {
5965
6003
  initialShape
5966
6004
  }
5967
6005
  );
5968
- if (resizedShape) {
5969
- didResize = true;
5970
- }
5971
6006
  workingShape = applyPartialToRecordWithProps(workingShape, {
5972
6007
  id,
5973
6008
  type: initialShape.type,
@@ -5981,32 +6016,36 @@ class Editor extends import_eventemitter3.default {
5981
6016
  util.onResizeEnd?.(initialShape, workingShape) ?? void 0
5982
6017
  );
5983
6018
  }
5984
- this.updateShapes([workingShape]);
6019
+ if (resizedShape) {
6020
+ return workingShape;
6021
+ }
5985
6022
  }
5986
- if (!didResize) {
5987
- const initialPageCenter = import_Mat.Mat.applyToPoint(pageTransform, initialBounds.center);
5988
- const newPageCenter = this._scalePagePoint(
5989
- initialPageCenter,
5990
- scaleOrigin,
5991
- scale,
5992
- scaleAxisRotation
5993
- );
5994
- const initialPageCenterInParentSpace = this.getPointInParentSpace(
5995
- initialShape.id,
5996
- initialPageCenter
5997
- );
5998
- const newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter);
5999
- const delta = import_Vec.Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace);
6000
- this.updateShapes([
6001
- {
6002
- id,
6003
- type: initialShape.type,
6004
- x: initialShape.x + delta.x,
6005
- y: initialShape.y + delta.y
6006
- }
6007
- ]);
6023
+ const initialPageCenter = import_Mat.Mat.applyToPoint(pageTransform, initialBounds.center);
6024
+ const newPageCenter = this._scalePagePoint(
6025
+ initialPageCenter,
6026
+ scaleOrigin,
6027
+ scale,
6028
+ scaleAxisRotation
6029
+ );
6030
+ const initialPageCenterInParentSpace = this.getPointInParentSpace(
6031
+ initialShape.id,
6032
+ initialPageCenter
6033
+ );
6034
+ const newPageCenterInParentSpace = this.getPointInParentSpace(initialShape.id, newPageCenter);
6035
+ const delta = import_Vec.Vec.Sub(newPageCenterInParentSpace, initialPageCenterInParentSpace);
6036
+ if (workingShape) {
6037
+ return {
6038
+ ...workingShape,
6039
+ x: initialShape.x + delta.x,
6040
+ y: initialShape.y + delta.y
6041
+ };
6008
6042
  }
6009
- return this;
6043
+ return {
6044
+ id,
6045
+ type: initialShape.type,
6046
+ x: initialShape.x + delta.x,
6047
+ y: initialShape.y + delta.y
6048
+ };
6010
6049
  }
6011
6050
  /** @internal */
6012
6051
  _scalePagePoint(point, scaleOrigin, scale, scaleAxisRotation) {
@@ -7834,6 +7873,15 @@ class Editor extends import_eventemitter3.default {
7834
7873
  _didPinch = false;
7835
7874
  /** @internal */
7836
7875
  _selectedShapeIdsAtPointerDown = [];
7876
+ /**
7877
+ * Whether `_selectedShapeIdsAtPointerDown` holds a pre-gesture selection
7878
+ * captured by a `pointer_down` (the touch path) that a following pinch
7879
+ * should restore. False when no pointer_down preceded the pinch (the
7880
+ * Safari trackpad path uses gesture events), in which case `pinch_start`
7881
+ * captures the live selection instead.
7882
+ * @internal
7883
+ */
7884
+ _didCaptureSelectionAtPointerDown = false;
7837
7885
  /** @internal */
7838
7886
  _longPressTimeout = -1;
7839
7887
  /** @internal */
@@ -7966,10 +8014,15 @@ class Editor extends import_eventemitter3.default {
7966
8014
  case "pinch_start": {
7967
8015
  if (inputs.getIsPinching()) return;
7968
8016
  if (!inputs.getIsEditing()) {
7969
- this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
8017
+ if (!this._didCaptureSelectionAtPointerDown) {
8018
+ this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
8019
+ }
7970
8020
  this._didPinch = true;
7971
8021
  inputs.setIsPinching(true);
7972
8022
  this.interrupt();
8023
+ if (this._didCaptureSelectionAtPointerDown) {
8024
+ this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
8025
+ }
7973
8026
  }
7974
8027
  this.emit("event", info);
7975
8028
  return;
@@ -8009,6 +8062,7 @@ class Editor extends import_eventemitter3.default {
8009
8062
  const { _selectedShapeIdsAtPointerDown: shapesToReselect } = this;
8010
8063
  this.setSelectedShapes(this._selectedShapeIdsAtPointerDown);
8011
8064
  this._selectedShapeIdsAtPointerDown = [];
8065
+ this._didCaptureSelectionAtPointerDown = false;
8012
8066
  if (this._didPinch) {
8013
8067
  this._didPinch = false;
8014
8068
  if (shapesToReselect.length > 0) {
@@ -8102,7 +8156,10 @@ class Editor extends import_eventemitter3.default {
8102
8156
  });
8103
8157
  }, this.options.longPressDurationMs);
8104
8158
  }
8105
- this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
8159
+ if (!this._didCaptureSelectionAtPointerDown) {
8160
+ this._selectedShapeIdsAtPointerDown = this.getSelectedShapeIds();
8161
+ this._didCaptureSelectionAtPointerDown = true;
8162
+ }
8106
8163
  if (info.button === import_constants.LEFT_MOUSE_BUTTON) this.capturedPointerId = info.pointerId;
8107
8164
  inputs.buttons.add(info.button);
8108
8165
  inputs.setIsPointing(true);
@@ -8178,6 +8235,7 @@ class Editor extends import_eventemitter3.default {
8178
8235
  if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
8179
8236
  this.inputs.setIsRightPointing(false);
8180
8237
  this._selectedShapeIdsAtPointerDown = [];
8238
+ this._didCaptureSelectionAtPointerDown = false;
8181
8239
  break;
8182
8240
  }
8183
8241
  this.inputs.setIsRightPointing(false);
@@ -8212,14 +8270,21 @@ class Editor extends import_eventemitter3.default {
8212
8270
  this.setCursor({ type: this._prevCursor, rotation: 0 });
8213
8271
  }
8214
8272
  if (slideSpeed > 0) {
8215
- this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8273
+ this.slideCamera({
8274
+ speed: slideSpeed,
8275
+ direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
8276
+ });
8216
8277
  }
8217
8278
  this._selectedShapeIdsAtPointerDown = [];
8279
+ this._didCaptureSelectionAtPointerDown = false;
8218
8280
  return this;
8219
8281
  }
8220
8282
  }
8221
8283
  if (slideSpeed > 0) {
8222
- this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8284
+ this.slideCamera({
8285
+ speed: slideSpeed,
8286
+ direction: { x: slideDirection.x, y: slideDirection.y, z: 0 }
8287
+ });
8223
8288
  }
8224
8289
  } else {
8225
8290
  if (info.button === import_constants.STYLUS_ERASER_BUTTON) {
@@ -8228,6 +8293,7 @@ class Editor extends import_eventemitter3.default {
8228
8293
  }
8229
8294
  }
8230
8295
  this._selectedShapeIdsAtPointerDown = [];
8296
+ this._didCaptureSelectionAtPointerDown = false;
8231
8297
  break;
8232
8298
  }
8233
8299
  }