@tldraw/editor 4.4.0-next.84d68f44c848 → 4.4.0-next.bde73a32273d

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 (126) hide show
  1. package/dist-cjs/index.d.ts +277 -30
  2. package/dist-cjs/index.js +1 -6
  3. package/dist-cjs/index.js.map +3 -3
  4. package/dist-cjs/lib/TldrawEditor.js +20 -8
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/LiveCollaborators.js +14 -24
  7. package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
  8. package/dist-cjs/lib/components/Shape.js +12 -17
  9. package/dist-cjs/lib/components/Shape.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +226 -0
  11. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +7 -0
  12. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +45 -15
  13. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +3 -1
  15. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +13 -1
  17. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
  18. package/dist-cjs/lib/config/TLUserPreferences.js +9 -3
  19. package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
  20. package/dist-cjs/lib/config/createTLStore.js.map +1 -1
  21. package/dist-cjs/lib/editor/Editor.js +39 -18
  22. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  23. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js +32 -13
  24. package/dist-cjs/lib/editor/derivations/notVisibleShapes.js.map +2 -2
  25. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +2 -3
  26. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +2 -2
  27. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +13 -38
  28. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +3 -3
  29. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +378 -89
  30. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +2 -2
  31. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +8 -3
  32. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  33. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +29 -0
  34. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  35. package/dist-cjs/lib/editor/tools/RootState.js +0 -13
  36. package/dist-cjs/lib/editor/tools/RootState.js.map +2 -2
  37. package/dist-cjs/lib/hooks/usePeerIds.js +35 -0
  38. package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
  39. package/dist-cjs/lib/hooks/useShapeCulling.js +75 -0
  40. package/dist-cjs/lib/hooks/useShapeCulling.js.map +7 -0
  41. package/dist-cjs/lib/license/LicenseManager.js +6 -6
  42. package/dist-cjs/lib/license/LicenseManager.js.map +2 -2
  43. package/dist-cjs/lib/options.js +7 -1
  44. package/dist-cjs/lib/options.js.map +2 -2
  45. package/dist-cjs/lib/utils/collaboratorState.js +42 -0
  46. package/dist-cjs/lib/utils/collaboratorState.js.map +7 -0
  47. package/dist-cjs/version.js +3 -3
  48. package/dist-cjs/version.js.map +1 -1
  49. package/dist-esm/index.d.mts +277 -30
  50. package/dist-esm/index.mjs +1 -6
  51. package/dist-esm/index.mjs.map +2 -2
  52. package/dist-esm/lib/TldrawEditor.mjs +20 -8
  53. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  54. package/dist-esm/lib/components/LiveCollaborators.mjs +17 -24
  55. package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
  56. package/dist-esm/lib/components/Shape.mjs +12 -17
  57. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  58. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +206 -0
  59. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +7 -0
  60. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +45 -15
  61. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  62. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +3 -1
  63. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  64. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +13 -1
  65. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
  66. package/dist-esm/lib/config/TLUserPreferences.mjs +9 -3
  67. package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
  68. package/dist-esm/lib/config/createTLStore.mjs.map +1 -1
  69. package/dist-esm/lib/editor/Editor.mjs +39 -18
  70. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  71. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs +32 -13
  72. package/dist-esm/lib/editor/derivations/notVisibleShapes.mjs.map +2 -2
  73. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +2 -3
  74. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +2 -2
  75. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +14 -39
  76. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +2 -2
  77. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +378 -89
  78. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +2 -2
  79. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +8 -3
  80. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  81. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +29 -0
  82. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  83. package/dist-esm/lib/editor/tools/RootState.mjs +0 -13
  84. package/dist-esm/lib/editor/tools/RootState.mjs.map +2 -2
  85. package/dist-esm/lib/hooks/usePeerIds.mjs +39 -1
  86. package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
  87. package/dist-esm/lib/hooks/useShapeCulling.mjs +55 -0
  88. package/dist-esm/lib/hooks/useShapeCulling.mjs.map +7 -0
  89. package/dist-esm/lib/license/LicenseManager.mjs +6 -6
  90. package/dist-esm/lib/license/LicenseManager.mjs.map +2 -2
  91. package/dist-esm/lib/options.mjs +7 -1
  92. package/dist-esm/lib/options.mjs.map +2 -2
  93. package/dist-esm/lib/utils/collaboratorState.mjs +22 -0
  94. package/dist-esm/lib/utils/collaboratorState.mjs.map +7 -0
  95. package/dist-esm/version.mjs +3 -3
  96. package/dist-esm/version.mjs.map +1 -1
  97. package/editor.css +28 -11
  98. package/package.json +8 -11
  99. package/src/index.ts +2 -5
  100. package/src/lib/TldrawEditor.tsx +35 -13
  101. package/src/lib/components/LiveCollaborators.tsx +26 -37
  102. package/src/lib/components/Shape.tsx +15 -16
  103. package/src/lib/components/default-components/CanvasShapeIndicators.tsx +288 -0
  104. package/src/lib/components/default-components/DefaultCanvas.tsx +39 -3
  105. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +6 -1
  106. package/src/lib/components/default-components/DefaultShapeIndicators.tsx +16 -1
  107. package/src/lib/config/TLUserPreferences.test.ts +1 -0
  108. package/src/lib/config/TLUserPreferences.ts +8 -0
  109. package/src/lib/config/createTLStore.ts +1 -1
  110. package/src/lib/editor/Editor.ts +72 -20
  111. package/src/lib/editor/derivations/notVisibleShapes.ts +39 -17
  112. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +0 -35
  113. package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts +4 -8
  114. package/src/lib/editor/managers/HistoryManager/HistoryManager.ts +19 -47
  115. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.ts +491 -106
  116. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +24 -0
  117. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +8 -0
  118. package/src/lib/editor/shapes/ShapeUtil.ts +63 -5
  119. package/src/lib/editor/tools/RootState.ts +0 -16
  120. package/src/lib/hooks/usePeerIds.ts +53 -1
  121. package/src/lib/hooks/useShapeCulling.tsx +98 -0
  122. package/src/lib/license/LicenseManager.ts +6 -6
  123. package/src/lib/options.ts +48 -2
  124. package/src/lib/utils/collaboratorState.ts +54 -0
  125. package/src/version.ts +3 -3
  126. package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +0 -621
@@ -53,8 +53,20 @@ const DefaultShapeIndicators = memo(function DefaultShapeIndicators2({
53
53
  );
54
54
  const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]);
55
55
  const { ShapeIndicator } = useEditorComponents();
56
+ const shapesToRender = useValue(
57
+ "shapes to render for svg indicators",
58
+ () => {
59
+ return renderingShapes.filter(({ id }) => {
60
+ const shape = editor.getShape(id);
61
+ if (!shape) return false;
62
+ const util = editor.getShapeUtil(shape);
63
+ return util.useLegacyIndicator();
64
+ });
65
+ },
66
+ [editor, renderingShapes]
67
+ );
56
68
  if (!ShapeIndicator) return null;
57
- return renderingShapes.map(({ id }) => /* @__PURE__ */ jsx(
69
+ return shapesToRender.map(({ id }) => /* @__PURE__ */ jsx(
58
70
  ShapeIndicator,
59
71
  {
60
72
  shapeId: id,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/components/default-components/DefaultShapeIndicators.tsx"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { TLShapeId } from '@tldraw/tlschema'\nimport { memo, useRef } from 'react'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\n\n/** @public */\nexport interface TLShapeIndicatorsProps {\n\t/** Whether to hide all of the indicators */\n\thideAll?: boolean\n\t/** Whether to show all of the indicators */\n\tshowAll?: boolean\n}\n\n/** @public @react */\nexport const DefaultShapeIndicators = memo(function DefaultShapeIndicators({\n\thideAll,\n\tshowAll,\n}: TLShapeIndicatorsProps) {\n\tconst editor = useEditor()\n\n\tif (hideAll && showAll)\n\t\tthrow Error('You cannot set both hideAll and showAll props to true, cmon now')\n\n\tconst rPreviousSelectedShapeIds = useRef<Set<TLShapeId>>(new Set())\n\n\tconst idsToDisplay = useValue(\n\t\t'should display selected ids',\n\t\t() => {\n\t\t\tconst prev = rPreviousSelectedShapeIds.current\n\t\t\tconst next = new Set<TLShapeId>()\n\n\t\t\tconst instanceState = editor.getInstanceState()\n\n\t\t\tconst isChangingStyle = instanceState.isChangingStyle\n\n\t\t\t// todo: this is tldraw specific and is duplicated at the tldraw layer. What should we do here instead?\n\n\t\t\tconst isIdleOrEditing = editor.isInAny('select.idle', 'select.editing_shape')\n\n\t\t\tconst isInSelectState = editor.isInAny(\n\t\t\t\t'select.brushing',\n\t\t\t\t'select.scribble_brushing',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_handle'\n\t\t\t)\n\n\t\t\t// We hide all indicators if we're changing style or in certain interactions\n\t\t\t// todo: move this to some kind of Tool.hideIndicators property\n\t\t\tif (isChangingStyle || !(isIdleOrEditing || isInSelectState)) {\n\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\treturn next\n\t\t\t}\n\n\t\t\t// We always want to show indicators for the selected shapes, if any\n\t\t\tfor (const id of editor.getSelectedShapeIds()) {\n\t\t\t\tnext.add(id)\n\t\t\t}\n\n\t\t\t// If we're idle or editing a shape, we want to also show an indicator for the hovered shape, if any\n\t\t\tif (isIdleOrEditing && instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) {\n\t\t\t\tconst hovered = editor.getHoveredShapeId()\n\t\t\t\tif (hovered) next.add(hovered)\n\t\t\t}\n\n\t\t\t// Ok, has anything changed?\n\n\t\t\t// If the number of items in the set is different, then the selection has changed. This catches most changes.\n\t\t\tif (prev.size !== next.size) {\n\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\treturn next\n\t\t\t}\n\n\t\t\t// Set difference check\n\t\t\tfor (const id of next) {\n\t\t\t\tif (!prev.has(id)) {\n\t\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\t\treturn next\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn prev\n\t\t},\n\t\t[editor]\n\t)\n\n\t// Show indicators only for the shapes that are currently being rendered (ie that are on screen)\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\tconst { ShapeIndicator } = useEditorComponents()\n\tif (!ShapeIndicator) return null\n\n\treturn renderingShapes.map(({ id }) => (\n\t\t<ShapeIndicator\n\t\t\tkey={id + '_indicator'}\n\t\t\tshapeId={id}\n\t\t\thidden={!showAll && (hideAll || !idsToDisplay.has(id))}\n\t\t/>\n\t))\n})\n"],
5
- "mappings": "AA8FE;AA9FF,SAAS,gBAAgB;AAEzB,SAAS,MAAM,cAAc;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AAW7B,MAAM,yBAAyB,KAAK,SAASA,wBAAuB;AAAA,EAC1E;AAAA,EACA;AACD,GAA2B;AAC1B,QAAM,SAAS,UAAU;AAEzB,MAAI,WAAW;AACd,UAAM,MAAM,iEAAiE;AAE9E,QAAM,4BAA4B,OAAuB,oBAAI,IAAI,CAAC;AAElE,QAAM,eAAe;AAAA,IACpB;AAAA,IACA,MAAM;AACL,YAAM,OAAO,0BAA0B;AACvC,YAAM,OAAO,oBAAI,IAAe;AAEhC,YAAM,gBAAgB,OAAO,iBAAiB;AAE9C,YAAM,kBAAkB,cAAc;AAItC,YAAM,kBAAkB,OAAO,QAAQ,eAAe,sBAAsB;AAE5E,YAAM,kBAAkB,OAAO;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAIA,UAAI,mBAAmB,EAAE,mBAAmB,kBAAkB;AAC7D,kCAA0B,UAAU;AACpC,eAAO;AAAA,MACR;AAGA,iBAAW,MAAM,OAAO,oBAAoB,GAAG;AAC9C,aAAK,IAAI,EAAE;AAAA,MACZ;AAGA,UAAI,mBAAmB,cAAc,oBAAoB,CAAC,cAAc,iBAAiB;AACxF,cAAM,UAAU,OAAO,kBAAkB;AACzC,YAAI,QAAS,MAAK,IAAI,OAAO;AAAA,MAC9B;AAKA,UAAI,KAAK,SAAS,KAAK,MAAM;AAC5B,kCAA0B,UAAU;AACpC,eAAO;AAAA,MACR;AAGA,iBAAW,MAAM,MAAM;AACtB,YAAI,CAAC,KAAK,IAAI,EAAE,GAAG;AAClB,oCAA0B,UAAU;AACpC,iBAAO;AAAA,QACR;AAAA,MACD;AAEA,aAAO;AAAA,IACR;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAGA,QAAM,kBAAkB,SAAS,oBAAoB,MAAM,OAAO,mBAAmB,GAAG,CAAC,MAAM,CAAC;AAEhG,QAAM,EAAE,eAAe,IAAI,oBAAoB;AAC/C,MAAI,CAAC,eAAgB,QAAO;AAE5B,SAAO,gBAAgB,IAAI,CAAC,EAAE,GAAG,MAChC;AAAA,IAAC;AAAA;AAAA,MAEA,SAAS;AAAA,MACT,QAAQ,CAAC,YAAY,WAAW,CAAC,aAAa,IAAI,EAAE;AAAA;AAAA,IAF/C,KAAK;AAAA,EAGX,CACA;AACF,CAAC;",
4
+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { TLShapeId } from '@tldraw/tlschema'\nimport { memo, useRef } from 'react'\nimport { useEditor } from '../../hooks/useEditor'\nimport { useEditorComponents } from '../../hooks/useEditorComponents'\n\n/** @public */\nexport interface TLShapeIndicatorsProps {\n\t/** Whether to hide all of the indicators */\n\thideAll?: boolean\n\t/** Whether to show all of the indicators */\n\tshowAll?: boolean\n}\n\n/** @public @react */\nexport const DefaultShapeIndicators = memo(function DefaultShapeIndicators({\n\thideAll,\n\tshowAll,\n}: TLShapeIndicatorsProps) {\n\tconst editor = useEditor()\n\n\tif (hideAll && showAll)\n\t\tthrow Error('You cannot set both hideAll and showAll props to true, cmon now')\n\n\tconst rPreviousSelectedShapeIds = useRef<Set<TLShapeId>>(new Set())\n\n\tconst idsToDisplay = useValue(\n\t\t'should display selected ids',\n\t\t() => {\n\t\t\tconst prev = rPreviousSelectedShapeIds.current\n\t\t\tconst next = new Set<TLShapeId>()\n\n\t\t\tconst instanceState = editor.getInstanceState()\n\n\t\t\tconst isChangingStyle = instanceState.isChangingStyle\n\n\t\t\t// todo: this is tldraw specific and is duplicated at the tldraw layer. What should we do here instead?\n\n\t\t\tconst isIdleOrEditing = editor.isInAny('select.idle', 'select.editing_shape')\n\n\t\t\tconst isInSelectState = editor.isInAny(\n\t\t\t\t'select.brushing',\n\t\t\t\t'select.scribble_brushing',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_handle'\n\t\t\t)\n\n\t\t\t// We hide all indicators if we're changing style or in certain interactions\n\t\t\t// todo: move this to some kind of Tool.hideIndicators property\n\t\t\tif (isChangingStyle || !(isIdleOrEditing || isInSelectState)) {\n\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\treturn next\n\t\t\t}\n\n\t\t\t// We always want to show indicators for the selected shapes, if any\n\t\t\tfor (const id of editor.getSelectedShapeIds()) {\n\t\t\t\tnext.add(id)\n\t\t\t}\n\n\t\t\t// If we're idle or editing a shape, we want to also show an indicator for the hovered shape, if any\n\t\t\tif (isIdleOrEditing && instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) {\n\t\t\t\tconst hovered = editor.getHoveredShapeId()\n\t\t\t\tif (hovered) next.add(hovered)\n\t\t\t}\n\n\t\t\t// Ok, has anything changed?\n\n\t\t\t// If the number of items in the set is different, then the selection has changed. This catches most changes.\n\t\t\tif (prev.size !== next.size) {\n\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\treturn next\n\t\t\t}\n\n\t\t\t// Set difference check\n\t\t\tfor (const id of next) {\n\t\t\t\tif (!prev.has(id)) {\n\t\t\t\t\trPreviousSelectedShapeIds.current = next\n\t\t\t\t\treturn next\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn prev\n\t\t},\n\t\t[editor]\n\t)\n\n\t// Show indicators only for the shapes that are currently being rendered (ie that are on screen)\n\tconst renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])\n\n\tconst { ShapeIndicator } = useEditorComponents()\n\n\t// Filter out shapes that have canvas indicator support - only render shapes that use legacy SVG indicators\n\tconst shapesToRender = useValue(\n\t\t'shapes to render for svg indicators',\n\t\t() => {\n\t\t\treturn renderingShapes.filter(({ id }) => {\n\t\t\t\tconst shape = editor.getShape(id)\n\t\t\t\tif (!shape) return false\n\t\t\t\tconst util = editor.getShapeUtil(shape)\n\t\t\t\treturn util.useLegacyIndicator()\n\t\t\t})\n\t\t},\n\t\t[editor, renderingShapes]\n\t)\n\n\tif (!ShapeIndicator) return null\n\n\treturn shapesToRender.map(({ id }) => (\n\t\t<ShapeIndicator\n\t\t\tkey={id + '_indicator'}\n\t\t\tshapeId={id}\n\t\t\thidden={!showAll && (hideAll || !idsToDisplay.has(id))}\n\t\t/>\n\t))\n})\n"],
5
+ "mappings": "AA6GE;AA7GF,SAAS,gBAAgB;AAEzB,SAAS,MAAM,cAAc;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,2BAA2B;AAW7B,MAAM,yBAAyB,KAAK,SAASA,wBAAuB;AAAA,EAC1E;AAAA,EACA;AACD,GAA2B;AAC1B,QAAM,SAAS,UAAU;AAEzB,MAAI,WAAW;AACd,UAAM,MAAM,iEAAiE;AAE9E,QAAM,4BAA4B,OAAuB,oBAAI,IAAI,CAAC;AAElE,QAAM,eAAe;AAAA,IACpB;AAAA,IACA,MAAM;AACL,YAAM,OAAO,0BAA0B;AACvC,YAAM,OAAO,oBAAI,IAAe;AAEhC,YAAM,gBAAgB,OAAO,iBAAiB;AAE9C,YAAM,kBAAkB,cAAc;AAItC,YAAM,kBAAkB,OAAO,QAAQ,eAAe,sBAAsB;AAE5E,YAAM,kBAAkB,OAAO;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAIA,UAAI,mBAAmB,EAAE,mBAAmB,kBAAkB;AAC7D,kCAA0B,UAAU;AACpC,eAAO;AAAA,MACR;AAGA,iBAAW,MAAM,OAAO,oBAAoB,GAAG;AAC9C,aAAK,IAAI,EAAE;AAAA,MACZ;AAGA,UAAI,mBAAmB,cAAc,oBAAoB,CAAC,cAAc,iBAAiB;AACxF,cAAM,UAAU,OAAO,kBAAkB;AACzC,YAAI,QAAS,MAAK,IAAI,OAAO;AAAA,MAC9B;AAKA,UAAI,KAAK,SAAS,KAAK,MAAM;AAC5B,kCAA0B,UAAU;AACpC,eAAO;AAAA,MACR;AAGA,iBAAW,MAAM,MAAM;AACtB,YAAI,CAAC,KAAK,IAAI,EAAE,GAAG;AAClB,oCAA0B,UAAU;AACpC,iBAAO;AAAA,QACR;AAAA,MACD;AAEA,aAAO;AAAA,IACR;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAGA,QAAM,kBAAkB,SAAS,oBAAoB,MAAM,OAAO,mBAAmB,GAAG,CAAC,MAAM,CAAC;AAEhG,QAAM,EAAE,eAAe,IAAI,oBAAoB;AAG/C,QAAM,iBAAiB;AAAA,IACtB;AAAA,IACA,MAAM;AACL,aAAO,gBAAgB,OAAO,CAAC,EAAE,GAAG,MAAM;AACzC,cAAM,QAAQ,OAAO,SAAS,EAAE;AAChC,YAAI,CAAC,MAAO,QAAO;AACnB,cAAM,OAAO,OAAO,aAAa,KAAK;AACtC,eAAO,KAAK,mBAAmB;AAAA,MAChC,CAAC;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,eAAe;AAAA,EACzB;AAEA,MAAI,CAAC,eAAgB,QAAO;AAE5B,SAAO,eAAe,IAAI,CAAC,EAAE,GAAG,MAC/B;AAAA,IAAC;AAAA;AAAA,MAEA,SAAS;AAAA,MACT,QAAQ,CAAC,YAAY,WAAW,CAAC,aAAa,IAAI,EAAE;AAAA;AAAA,IAF/C,KAAK;AAAA,EAGX,CACA;AACF,CAAC;",
6
6
  "names": ["DefaultShapeIndicators"]
7
7
  }
@@ -18,7 +18,8 @@ const userTypeValidator = T.object({
18
18
  isDynamicSizeMode: T.boolean.nullable().optional(),
19
19
  isPasteAtCursorMode: T.boolean.nullable().optional(),
20
20
  enhancedA11yMode: T.boolean.nullable().optional(),
21
- inputMode: T.literalEnum("trackpad", "mouse").nullable().optional()
21
+ inputMode: T.literalEnum("trackpad", "mouse").nullable().optional(),
22
+ isZoomDirectionInverted: T.boolean.nullable().optional()
22
23
  });
23
24
  const Versions = {
24
25
  AddAnimationSpeed: 1,
@@ -32,7 +33,8 @@ const Versions = {
32
33
  AddKeyboardShortcuts: 9,
33
34
  AddShowUiLabels: 10,
34
35
  AddPointerPeripheral: 11,
35
- RenameShowUiLabelsToEnhancedA11yMode: 12
36
+ RenameShowUiLabelsToEnhancedA11yMode: 12,
37
+ AddZoomDirectionInverted: 13
36
38
  };
37
39
  const CURRENT_VERSION = Math.max(...Object.values(Versions));
38
40
  function migrateSnapshot(data) {
@@ -77,6 +79,9 @@ function migrateSnapshot(data) {
77
79
  if (data.version < Versions.AddPointerPeripheral) {
78
80
  data.user.inputMode = null;
79
81
  }
82
+ if (data.version < Versions.AddZoomDirectionInverted) {
83
+ data.user.isZoomDirectionInverted = false;
84
+ }
80
85
  data.version = CURRENT_VERSION;
81
86
  }
82
87
  const USER_COLORS = [
@@ -116,7 +121,8 @@ const defaultUserPreferences = Object.freeze({
116
121
  isPasteAtCursorMode: false,
117
122
  enhancedA11yMode: false,
118
123
  colorScheme: "light",
119
- inputMode: null
124
+ inputMode: null,
125
+ isZoomDirectionInverted: false
120
126
  });
121
127
  function getFreshUserPreferences() {
122
128
  return {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/TLUserPreferences.ts"],
4
- "sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tenhancedA11yMode?: boolean | null\n\tinputMode?: 'trackpad' | 'mouse' | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tenhancedA11yMode: T.boolean.nullable().optional(),\n\tinputMode: T.literalEnum('trackpad', 'mouse').nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n\tAddPointerPeripheral: 11,\n\tRenameShowUiLabelsToEnhancedA11yMode: 12,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\tif (data.version < Versions.RenameShowUiLabelsToEnhancedA11yMode) {\n\t\tdata.user.enhancedA11yMode = data.user.showUiLabels\n\t\tdelete data.user.showUiLabels\n\t}\n\n\tif (data.version < Versions.AddPointerPeripheral) {\n\t\tdata.user.inputMode = null\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\treturn window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false\n\t}\n\n\treturn false\n}\n\n/** @public */\nexport const defaultUserPreferences = Object.freeze({\n\tname: '',\n\tlocale: getDefaultTranslationLocale(),\n\tcolor: getRandomColor(),\n\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tedgeScrollSpeed: 1,\n\tanimationSpeed: userPrefersReducedMotion() ? 0 : 1,\n\tareKeyboardShortcutsEnabled: true,\n\tisSnapMode: false,\n\tisWrapMode: false,\n\tisDynamicSizeMode: false,\n\tisPasteAtCursorMode: false,\n\tenhancedA11yMode: false,\n\tcolorScheme: 'light',\n\tinputMode: null,\n}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>\n\n/** @public */\nexport function getFreshUserPreferences(): TLUserPreferences {\n\treturn {\n\t\tid: uniqueId(),\n\t\tcolor: getRandomColor(),\n\t}\n}\n\nfunction migrateUserPreferences(userData: unknown): TLUserPreferences {\n\tif (userData === null || typeof userData !== 'object') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tif (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tconst snapshot = structuredClone(userData) as any\n\n\tmigrateSnapshot(snapshot)\n\n\ttry {\n\t\treturn userTypeValidator.validate(snapshot.user)\n\t} catch {\n\t\treturn getFreshUserPreferences()\n\t}\n}\n\nfunction loadUserPreferences(): TLUserPreferences {\n\tconst userData = (JSON.parse(getFromLocalStorage(USER_DATA_KEY) || 'null') ??\n\t\tnull) as null | UserDataSnapshot\n\n\treturn migrateUserPreferences(userData)\n}\n\nconst globalUserPreferences = atom<TLUserPreferences | null>('globalUserData', null)\n\nfunction storeUserPreferences() {\n\tsetInLocalStorage(\n\t\tUSER_DATA_KEY,\n\t\tJSON.stringify({\n\t\t\tversion: CURRENT_VERSION,\n\t\t\tuser: globalUserPreferences.get(),\n\t\t})\n\t)\n}\n\n/** @public */\nexport function setUserPreferences(user: TLUserPreferences) {\n\tuserTypeValidator.validate(user)\n\tglobalUserPreferences.set(user)\n\tstoreUserPreferences()\n\tbroadcastUserPreferencesChange()\n}\n\nconst isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\nconst channel =\n\ttypeof BroadcastChannel !== 'undefined' && !isTest\n\t\t? new BroadcastChannel('tldraw-user-sync')\n\t\t: null\n\nchannel?.addEventListener('message', (e) => {\n\tconst data = e.data as undefined | UserChangeBroadcastMessage\n\tif (data?.type === broadcastEventKey && data?.origin !== getBroadcastOrigin()) {\n\t\tglobalUserPreferences.set(migrateUserPreferences(data.data))\n\t}\n})\n\nlet _broadcastOrigin = null as null | string\nfunction getBroadcastOrigin() {\n\tif (_broadcastOrigin === null) {\n\t\t_broadcastOrigin = uniqueId()\n\t}\n\treturn _broadcastOrigin\n}\nconst broadcastEventKey = 'tldraw-user-preferences-change' as const\n\nfunction broadcastUserPreferencesChange() {\n\tchannel?.postMessage({\n\t\ttype: broadcastEventKey,\n\t\torigin: getBroadcastOrigin(),\n\t\tdata: {\n\t\t\tuser: getUserPreferences(),\n\t\t\tversion: CURRENT_VERSION,\n\t\t},\n\t} satisfies UserChangeBroadcastMessage)\n}\n\n/** @public */\nexport function getUserPreferences(): TLUserPreferences {\n\tlet prefs = globalUserPreferences.get()\n\tif (!prefs) {\n\t\tprefs = loadUserPreferences()\n\t\tsetUserPreferences(prefs)\n\t}\n\treturn prefs\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { atom } from '@tldraw/state'\nimport { getDefaultTranslationLocale } from '@tldraw/tlschema'\nimport { getFromLocalStorage, setInLocalStorage, structuredClone, uniqueId } from '@tldraw/utils'\nimport { T } from '@tldraw/validate'\n\nconst USER_DATA_KEY = 'TLDRAW_USER_DATA_v3'\n\n/**\n * A user of tldraw\n *\n * @public\n */\nexport interface TLUserPreferences {\n\tid: string\n\tname?: string | null\n\tcolor?: string | null\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale?: string | null\n\tanimationSpeed?: number | null\n\tareKeyboardShortcutsEnabled?: boolean | null\n\tedgeScrollSpeed?: number | null\n\tcolorScheme?: 'light' | 'dark' | 'system'\n\tisSnapMode?: boolean | null\n\tisWrapMode?: boolean | null\n\tisDynamicSizeMode?: boolean | null\n\tisPasteAtCursorMode?: boolean | null\n\tenhancedA11yMode?: boolean | null\n\tinputMode?: 'trackpad' | 'mouse' | null\n\tisZoomDirectionInverted?: boolean | null\n}\n\ninterface UserDataSnapshot {\n\tversion: number\n\tuser: TLUserPreferences\n}\n\ninterface UserChangeBroadcastMessage {\n\ttype: typeof broadcastEventKey\n\torigin: string\n\tdata: UserDataSnapshot\n}\n\n/** @public */\nexport const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUserPreferences>({\n\tid: T.string,\n\tname: T.string.nullable().optional(),\n\tcolor: T.string.nullable().optional(),\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tlocale: T.string.nullable().optional(),\n\tanimationSpeed: T.number.nullable().optional(),\n\tareKeyboardShortcutsEnabled: T.boolean.nullable().optional(),\n\tedgeScrollSpeed: T.number.nullable().optional(),\n\tcolorScheme: T.literalEnum('light', 'dark', 'system').optional(),\n\tisSnapMode: T.boolean.nullable().optional(),\n\tisWrapMode: T.boolean.nullable().optional(),\n\tisDynamicSizeMode: T.boolean.nullable().optional(),\n\tisPasteAtCursorMode: T.boolean.nullable().optional(),\n\tenhancedA11yMode: T.boolean.nullable().optional(),\n\tinputMode: T.literalEnum('trackpad', 'mouse').nullable().optional(),\n\tisZoomDirectionInverted: T.boolean.nullable().optional(),\n})\n\nconst Versions = {\n\tAddAnimationSpeed: 1,\n\tAddIsSnapMode: 2,\n\tMakeFieldsNullable: 3,\n\tAddEdgeScrollSpeed: 4,\n\tAddExcalidrawSelectMode: 5,\n\tAddDynamicSizeMode: 6,\n\tAllowSystemColorScheme: 7,\n\tAddPasteAtCursor: 8,\n\tAddKeyboardShortcuts: 9,\n\tAddShowUiLabels: 10,\n\tAddPointerPeripheral: 11,\n\tRenameShowUiLabelsToEnhancedA11yMode: 12,\n\tAddZoomDirectionInverted: 13,\n} as const\n\nconst CURRENT_VERSION = Math.max(...Object.values(Versions))\n\nfunction migrateSnapshot(data: { version: number; user: any }) {\n\tif (data.version < Versions.AddAnimationSpeed) {\n\t\tdata.user.animationSpeed = 1\n\t}\n\tif (data.version < Versions.AddIsSnapMode) {\n\t\tdata.user.isSnapMode = false\n\t}\n\tif (data.version < Versions.MakeFieldsNullable) {\n\t\t// noop\n\t}\n\tif (data.version < Versions.AddEdgeScrollSpeed) {\n\t\tdata.user.edgeScrollSpeed = 1\n\t}\n\tif (data.version < Versions.AddExcalidrawSelectMode) {\n\t\tdata.user.isWrapMode = false\n\t}\n\tif (data.version < Versions.AllowSystemColorScheme) {\n\t\tif (data.user.isDarkMode === true) {\n\t\t\tdata.user.colorScheme = 'dark'\n\t\t} else if (data.user.isDarkMode === false) {\n\t\t\tdata.user.colorScheme = 'light'\n\t\t}\n\t\tdelete data.user.isDarkMode\n\t}\n\n\tif (data.version < Versions.AddDynamicSizeMode) {\n\t\tdata.user.isDynamicSizeMode = false\n\t}\n\tif (data.version < Versions.AddPasteAtCursor) {\n\t\tdata.user.isPasteAtCursorMode = false\n\t}\n\tif (data.version < Versions.AddKeyboardShortcuts) {\n\t\tdata.user.areKeyboardShortcutsEnabled = true\n\t}\n\tif (data.version < Versions.AddShowUiLabels) {\n\t\tdata.user.showUiLabels = false\n\t}\n\tif (data.version < Versions.RenameShowUiLabelsToEnhancedA11yMode) {\n\t\tdata.user.enhancedA11yMode = data.user.showUiLabels\n\t\tdelete data.user.showUiLabels\n\t}\n\n\tif (data.version < Versions.AddPointerPeripheral) {\n\t\tdata.user.inputMode = null\n\t}\n\n\tif (data.version < Versions.AddZoomDirectionInverted) {\n\t\tdata.user.isZoomDirectionInverted = false\n\t}\n\n\t// finally\n\tdata.version = CURRENT_VERSION\n}\n\n/** @internal */\nexport const USER_COLORS = [\n\t'#FF802B',\n\t'#EC5E41',\n\t'#F2555A',\n\t'#F04F88',\n\t'#E34BA9',\n\t'#BD54C6',\n\t'#9D5BD2',\n\t'#7B66DC',\n\t'#02B1CC',\n\t'#11B3A3',\n\t'#39B178',\n\t'#55B467',\n] as const\n\nfunction getRandomColor() {\n\treturn USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]\n}\n\n/** @internal */\nexport function userPrefersReducedMotion() {\n\tif (typeof window !== 'undefined' && window.matchMedia) {\n\t\treturn window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false\n\t}\n\n\treturn false\n}\n\n/** @public */\nexport const defaultUserPreferences = Object.freeze({\n\tname: '',\n\tlocale: getDefaultTranslationLocale(),\n\tcolor: getRandomColor(),\n\n\t// N.B. These are duplicated in TLdrawAppUser.\n\tedgeScrollSpeed: 1,\n\tanimationSpeed: userPrefersReducedMotion() ? 0 : 1,\n\tareKeyboardShortcutsEnabled: true,\n\tisSnapMode: false,\n\tisWrapMode: false,\n\tisDynamicSizeMode: false,\n\tisPasteAtCursorMode: false,\n\tenhancedA11yMode: false,\n\tcolorScheme: 'light',\n\tinputMode: null,\n\tisZoomDirectionInverted: false,\n}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>\n\n/** @public */\nexport function getFreshUserPreferences(): TLUserPreferences {\n\treturn {\n\t\tid: uniqueId(),\n\t\tcolor: getRandomColor(),\n\t}\n}\n\nfunction migrateUserPreferences(userData: unknown): TLUserPreferences {\n\tif (userData === null || typeof userData !== 'object') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tif (!('version' in userData) || !('user' in userData) || typeof userData.version !== 'number') {\n\t\treturn getFreshUserPreferences()\n\t}\n\n\tconst snapshot = structuredClone(userData) as any\n\n\tmigrateSnapshot(snapshot)\n\n\ttry {\n\t\treturn userTypeValidator.validate(snapshot.user)\n\t} catch {\n\t\treturn getFreshUserPreferences()\n\t}\n}\n\nfunction loadUserPreferences(): TLUserPreferences {\n\tconst userData = (JSON.parse(getFromLocalStorage(USER_DATA_KEY) || 'null') ??\n\t\tnull) as null | UserDataSnapshot\n\n\treturn migrateUserPreferences(userData)\n}\n\nconst globalUserPreferences = atom<TLUserPreferences | null>('globalUserData', null)\n\nfunction storeUserPreferences() {\n\tsetInLocalStorage(\n\t\tUSER_DATA_KEY,\n\t\tJSON.stringify({\n\t\t\tversion: CURRENT_VERSION,\n\t\t\tuser: globalUserPreferences.get(),\n\t\t})\n\t)\n}\n\n/** @public */\nexport function setUserPreferences(user: TLUserPreferences) {\n\tuserTypeValidator.validate(user)\n\tglobalUserPreferences.set(user)\n\tstoreUserPreferences()\n\tbroadcastUserPreferencesChange()\n}\n\nconst isTest = typeof process !== 'undefined' && process.env.NODE_ENV === 'test'\n\nconst channel =\n\ttypeof BroadcastChannel !== 'undefined' && !isTest\n\t\t? new BroadcastChannel('tldraw-user-sync')\n\t\t: null\n\nchannel?.addEventListener('message', (e) => {\n\tconst data = e.data as undefined | UserChangeBroadcastMessage\n\tif (data?.type === broadcastEventKey && data?.origin !== getBroadcastOrigin()) {\n\t\tglobalUserPreferences.set(migrateUserPreferences(data.data))\n\t}\n})\n\nlet _broadcastOrigin = null as null | string\nfunction getBroadcastOrigin() {\n\tif (_broadcastOrigin === null) {\n\t\t_broadcastOrigin = uniqueId()\n\t}\n\treturn _broadcastOrigin\n}\nconst broadcastEventKey = 'tldraw-user-preferences-change' as const\n\nfunction broadcastUserPreferencesChange() {\n\tchannel?.postMessage({\n\t\ttype: broadcastEventKey,\n\t\torigin: getBroadcastOrigin(),\n\t\tdata: {\n\t\t\tuser: getUserPreferences(),\n\t\t\tversion: CURRENT_VERSION,\n\t\t},\n\t} satisfies UserChangeBroadcastMessage)\n}\n\n/** @public */\nexport function getUserPreferences(): TLUserPreferences {\n\tlet prefs = globalUserPreferences.get()\n\tif (!prefs) {\n\t\tprefs = loadUserPreferences()\n\t\tsetUserPreferences(prefs)\n\t}\n\treturn prefs\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/config/createTLStore.ts"],
4
- "sourcesContent": ["import { Signal } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tcreateTLSchema,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** Called when the store is connected to an {@link Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tonMount,\n\tcollaboration,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
4
+ "sourcesContent": ["import { Signal } from '@tldraw/state'\nimport { HistoryEntry, MigrationSequence, SerializedStore, Store, StoreSchema } from '@tldraw/store'\nimport {\n\tSchemaPropsInfo,\n\tTLAssetStore,\n\tTLRecord,\n\tTLStore,\n\tTLStoreProps,\n\tTLStoreSnapshot,\n\tcreateTLSchema,\n} from '@tldraw/tlschema'\nimport { FileHelpers, assert } from '@tldraw/utils'\nimport { Editor } from '../editor/Editor'\nimport { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'\nimport { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'\nimport { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'\n\n/** @public */\nexport interface TLStoreBaseOptions {\n\t/** The initial data for the store. */\n\tinitialData?: SerializedStore<TLRecord>\n\n\t/** A snapshot of initial data to migrate and load into the store. */\n\tsnapshot?: Partial<TLEditorSnapshot> | TLStoreSnapshot\n\n\t/** The default name for the store. */\n\tdefaultName?: string\n\n\t/** How should this store upload & resolve assets? */\n\tassets?: TLAssetStore\n\n\t/** Called when the store is connected to an {@link @tldraw/editor#Editor}. */\n\tonMount?(editor: Editor): void | (() => void)\n}\n\n/** @public */\nexport type TLStoreSchemaOptions =\n\t| {\n\t\t\tschema?: StoreSchema<TLRecord, TLStoreProps>\n\t }\n\t| {\n\t\t\tshapeUtils?: readonly TLAnyShapeUtilConstructor[]\n\t\t\tmigrations?: readonly MigrationSequence[]\n\t\t\tbindingUtils?: readonly TLAnyBindingUtilConstructor[]\n\t }\n\n/** @public */\nexport type TLStoreOptions = TLStoreBaseOptions & {\n\tid?: string\n\t/** Collaboration options for the store. */\n\tcollaboration?: {\n\t\tstatus: Signal<'online' | 'offline'> | null\n\t\tmode?: Signal<'readonly' | 'readwrite'> | null\n\t}\n} & TLStoreSchemaOptions\n\n/** @public */\nexport type TLStoreEventInfo = HistoryEntry<TLRecord>\n\nconst defaultAssetResolve: NonNullable<TLAssetStore['resolve']> = (asset) => asset.props.src\n\n/** @public */\nexport const inlineBase64AssetStore: TLAssetStore = {\n\tupload: async (_, file) => {\n\t\treturn { src: await FileHelpers.blobToDataUrl(file) }\n\t},\n}\n\n/**\n * A helper for creating a TLStore schema from either an object with shapeUtils, bindingUtils, and\n * migrations, or a schema.\n *\n * @param opts - Options for creating the schema.\n *\n * @public\n */\nexport function createTLSchemaFromUtils(\n\topts: TLStoreSchemaOptions\n): StoreSchema<TLRecord, TLStoreProps> {\n\tif ('schema' in opts && opts.schema) return opts.schema\n\n\treturn createTLSchema({\n\t\tshapes:\n\t\t\t'shapeUtils' in opts && opts.shapeUtils\n\t\t\t\t? utilsToMap(checkShapesAndAddCore(opts.shapeUtils))\n\t\t\t\t: undefined,\n\t\tbindings:\n\t\t\t'bindingUtils' in opts && opts.bindingUtils\n\t\t\t\t? utilsToMap(checkBindings(opts.bindingUtils))\n\t\t\t\t: undefined,\n\t\tmigrations: 'migrations' in opts ? opts.migrations : undefined,\n\t})\n}\n\n/**\n * A helper for creating a TLStore.\n *\n * @param opts - Options for creating the store.\n *\n * @public\n */\nexport function createTLStore({\n\tinitialData,\n\tdefaultName = '',\n\tid,\n\tassets = inlineBase64AssetStore,\n\tonMount,\n\tcollaboration,\n\t...rest\n}: TLStoreOptions = {}): TLStore {\n\tconst schema = createTLSchemaFromUtils(rest)\n\n\tconst store = new Store({\n\t\tid,\n\t\tschema,\n\t\tinitialData,\n\t\tprops: {\n\t\t\tdefaultName,\n\t\t\tassets: {\n\t\t\t\tupload: assets.upload,\n\t\t\t\tresolve: assets.resolve ?? defaultAssetResolve,\n\t\t\t\tremove: assets.remove ?? (() => Promise.resolve()),\n\t\t\t},\n\t\t\tonMount: (editor) => {\n\t\t\t\tassert(editor instanceof Editor)\n\t\t\t\tonMount?.(editor)\n\t\t\t},\n\t\t\tcollaboration,\n\t\t},\n\t})\n\n\tif (rest.snapshot) {\n\t\tif (initialData) throw new Error('Cannot provide both initialData and snapshot')\n\t\tloadSnapshot(store, rest.snapshot, { forceOverwriteSessionState: true })\n\t}\n\n\treturn store\n}\n\nfunction utilsToMap<T extends SchemaPropsInfo & { type: string }>(utils: T[]) {\n\treturn Object.fromEntries(\n\t\tutils.map((s): [string, SchemaPropsInfo] => [\n\t\t\ts.type,\n\t\t\t{\n\t\t\t\tprops: s.props,\n\t\t\t\tmigrations: s.migrations,\n\t\t\t},\n\t\t])\n\t)\n}\n"],
5
5
  "mappings": "AACA,SAA2D,aAA0B;AACrF;AAAA,EAOC;AAAA,OACM;AACP,SAAS,aAAa,cAAc;AACpC,SAAS,cAAc;AACvB,SAA2B,oBAAoB;AAC/C,SAAsC,qBAAqB;AAC3D,SAAoC,6BAA6B;AA4CjE,MAAM,sBAA4D,CAAC,UAAU,MAAM,MAAM;AAGlF,MAAM,yBAAuC;AAAA,EACnD,QAAQ,OAAO,GAAG,SAAS;AAC1B,WAAO,EAAE,KAAK,MAAM,YAAY,cAAc,IAAI,EAAE;AAAA,EACrD;AACD;AAUO,SAAS,wBACf,MACsC;AACtC,MAAI,YAAY,QAAQ,KAAK,OAAQ,QAAO,KAAK;AAEjD,SAAO,eAAe;AAAA,IACrB,QACC,gBAAgB,QAAQ,KAAK,aAC1B,WAAW,sBAAsB,KAAK,UAAU,CAAC,IACjD;AAAA,IACJ,UACC,kBAAkB,QAAQ,KAAK,eAC5B,WAAW,cAAc,KAAK,YAAY,CAAC,IAC3C;AAAA,IACJ,YAAY,gBAAgB,OAAO,KAAK,aAAa;AAAA,EACtD,CAAC;AACF;AASO,SAAS,cAAc;AAAA,EAC7B;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA,GAAG;AACJ,IAAoB,CAAC,GAAY;AAChC,QAAM,SAAS,wBAAwB,IAAI;AAE3C,QAAM,QAAQ,IAAI,MAAM;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACP,QAAQ,OAAO;AAAA,QACf,SAAS,OAAO,WAAW;AAAA,QAC3B,QAAQ,OAAO,WAAW,MAAM,QAAQ,QAAQ;AAAA,MACjD;AAAA,MACA,SAAS,CAAC,WAAW;AACpB,eAAO,kBAAkB,MAAM;AAC/B,kBAAU,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACD;AAAA,EACD,CAAC;AAED,MAAI,KAAK,UAAU;AAClB,QAAI,YAAa,OAAM,IAAI,MAAM,8CAA8C;AAC/E,iBAAa,OAAO,KAAK,UAAU,EAAE,4BAA4B,KAAK,CAAC;AAAA,EACxE;AAEA,SAAO;AACR;AAEA,SAAS,WAAyD,OAAY;AAC7E,SAAO,OAAO;AAAA,IACb,MAAM,IAAI,CAAC,MAAiC;AAAA,MAC3C,EAAE;AAAA,MACF;AAAA,QACC,OAAO,EAAE;AAAA,QACT,YAAY,EAAE;AAAA,MACf;AAAA,IACD,CAAC;AAAA,EACF;AACD;",
6
6
  "names": []
7
7
  }
@@ -165,12 +165,16 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
165
165
  bindingUtils,
166
166
  tools,
167
167
  getContainer,
168
+ // needs to be here for backwards compatibility with TldrawEditor
169
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
168
170
  cameraOptions,
169
- textOptions,
170
171
  initialState,
171
172
  autoFocus,
172
173
  inferDarkMode,
173
- options,
174
+ options: _options,
175
+ // needs to be here for backwards compatibility with TldrawEditor
176
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
177
+ textOptions: _textOptions,
174
178
  getShapeVisibility,
175
179
  fontAssetUrls
176
180
  }) {
@@ -331,7 +335,6 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
331
335
  // unmount / remount in the DOM, which is expensive; and computing visibility is
332
336
  // also expensive in large projects. For this reason, we use a second bounding
333
337
  // box just for rendering, and we only update after the camera stops moving.
334
- __publicField(this, "_cameraState", atom("camera state", "idle"));
335
338
  __publicField(this, "_cameraStateTimeoutRemaining", 0);
336
339
  /* @internal */
337
340
  __publicField(this, "_currentPageShapeIds");
@@ -404,6 +407,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
404
407
  __publicField(this, "handledEvents", /* @__PURE__ */ new WeakSet());
405
408
  __publicField(this, "_pendingEventsForNextTick", []);
406
409
  this._getShapeVisibility = getShapeVisibility;
410
+ const options = _textOptions ? { ..._options, text: _options?.text ?? _textOptions } : _options;
407
411
  this.options = { ...defaultTldrawOptions, ...options };
408
412
  this.store = store;
409
413
  this.history = new HistoryManager({
@@ -417,8 +421,12 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
417
421
  this._spatialIndex = new SpatialIndexManager(this);
418
422
  this.disposables.add(() => this._spatialIndex.dispose());
419
423
  this.disposables.add(this.timers.dispose);
420
- this._cameraOptions.set({ ...DEFAULT_CAMERA_OPTIONS, ...cameraOptions });
421
- this._textOptions = atom("text options", textOptions ?? null);
424
+ this._cameraOptions.set({
425
+ ...DEFAULT_CAMERA_OPTIONS,
426
+ ...cameraOptions,
427
+ ...options?.camera
428
+ });
429
+ this._textOptions = atom("text options", options?.text ?? null);
422
430
  this.user = new UserPreferencesManager(user ?? createTLUser(), inferDarkMode ?? false);
423
431
  this.disposables.add(() => this.user.dispose());
424
432
  this.getContainer = getContainer;
@@ -2422,7 +2430,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
2422
2430
  * @public
2423
2431
  */
2424
2432
  zoomToFit(opts) {
2425
- const ids = [...this.getCurrentPageShapeIds()];
2433
+ const ids = [...this.getCurrentPageShapeIds()].filter((id) => !this.isShapeHidden(id));
2426
2434
  if (ids.length <= 0) return this;
2427
2435
  const pageBounds = Box.Common(compact(ids.map((id) => this.getShapePageBounds(id))));
2428
2436
  this.zoomToBounds(pageBounds, opts);
@@ -3121,15 +3129,18 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3121
3129
  this._cameraStateTimeoutRemaining -= elapsed;
3122
3130
  if (this._cameraStateTimeoutRemaining > 0) return;
3123
3131
  this.off("tick", this._decayCameraStateTimeout);
3124
- this._cameraState.set("idle");
3132
+ this._setCameraState("idle");
3125
3133
  }
3126
3134
  _tickCameraState() {
3127
3135
  this._cameraStateTimeoutRemaining = this.options.cameraMovingTimeoutMs;
3128
- if (this._cameraState.__unsafe__getWithoutCapture() !== "idle") return;
3129
- this._cameraState.set("moving");
3136
+ if (this.getInstanceState().cameraState !== "idle") return;
3137
+ this._setCameraState("moving");
3130
3138
  this._debouncedZoomLevel.set(unsafe__withoutCapture(() => this.getCamera().z));
3131
3139
  this.on("tick", this._decayCameraStateTimeout);
3132
3140
  }
3141
+ _setCameraState(cameraState) {
3142
+ this.updateInstanceState({ cameraState }, { history: "ignore" });
3143
+ }
3133
3144
  /**
3134
3145
  * Whether the camera is moving or idle.
3135
3146
  *
@@ -3141,7 +3152,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3141
3152
  * @public
3142
3153
  */
3143
3154
  getCameraState() {
3144
- return this._cameraState.get();
3155
+ return this.getInstanceState().cameraState;
3145
3156
  }
3146
3157
  getRenderingShapes() {
3147
3158
  const renderingShapes = this.getUnorderedRenderingShapes(true);
@@ -3907,6 +3918,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
3907
3918
  getCurrentPageBounds() {
3908
3919
  let commonBounds;
3909
3920
  this.getCurrentPageShapeIdsSorted().forEach((shapeId) => {
3921
+ if (this.isShapeHidden(shapeId)) return;
3910
3922
  const bounds = this.getShapeMaskedPageBounds(shapeId);
3911
3923
  if (!bounds) return;
3912
3924
  if (!commonBounds) {
@@ -4085,7 +4097,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
4085
4097
  * @param bounds - The bounds to search within.
4086
4098
  * @returns Unordered set of shape IDs within the given bounds.
4087
4099
  *
4088
- * @internal
4100
+ * @public
4089
4101
  */
4090
4102
  getShapeIdsInsideBounds(bounds) {
4091
4103
  return this._spatialIndex.getShapeIdsInsideBounds(bounds);
@@ -4628,7 +4640,13 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
4628
4640
  const fromShapeType = typeof fromShape === "string" ? fromShape : fromShape.type;
4629
4641
  const toShapeType = typeof toShape === "string" ? toShape : toShape.type;
4630
4642
  const bindingType = typeof binding === "string" ? binding : binding.type;
4631
- const canBindOpts = { fromShapeType, toShapeType, bindingType };
4643
+ const canBindOpts = {
4644
+ fromShape: typeof fromShape === "string" ? { type: fromShape } : fromShape,
4645
+ toShape: typeof toShape === "string" ? { type: toShape } : toShape,
4646
+ bindingType,
4647
+ fromShapeType,
4648
+ toShapeType
4649
+ };
4632
4650
  if (fromShapeType === toShapeType) {
4633
4651
  return this.getShapeUtil(fromShapeType).canBind(canBindOpts);
4634
4652
  }
@@ -5768,7 +5786,8 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
5768
5786
  this.resizeShape(id, shapeScale, {
5769
5787
  initialShape: options.initialShape,
5770
5788
  initialBounds: options.initialBounds,
5771
- isAspectRatioLocked: options.isAspectRatioLocked
5789
+ isAspectRatioLocked: options.isAspectRatioLocked,
5790
+ initialPageTransform: options.initialPageTransform
5772
5791
  });
5773
5792
  if (Math.sign(scale.x) * Math.sign(scale.y) < 0) {
5774
5793
  const parentRotation = this.getShapeParentTransform(id).rotation();
@@ -7248,7 +7267,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7248
7267
  /**
7249
7268
  * Handles navigating to the content specified by the query param in the given URL.
7250
7269
  *
7251
- * Use {@link Editor#createDeepLink} to create a URL with a deep link query param.
7270
+ * Use {@link Editor.createDeepLink} to create a URL with a deep link query param.
7252
7271
  *
7253
7272
  * If no URL is provided, it will look for the param in the current `window.location.href`.
7254
7273
  *
@@ -7599,9 +7618,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7599
7618
  case "pinch_start": {
7600
7619
  if (inputs.getIsPinching()) return;
7601
7620
  if (!inputs.getIsEditing()) {
7602
- if (!this._selectedShapeIdsAtPointerDown.length) {
7603
- this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
7604
- }
7621
+ this._selectedShapeIdsAtPointerDown = [...pageState.selectedShapeIds];
7605
7622
  this._didPinch = true;
7606
7623
  inputs.setIsPinching(true);
7607
7624
  this.interrupt();
@@ -7687,7 +7704,10 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7687
7704
  delta = dy / 100;
7688
7705
  }
7689
7706
  }
7690
- const zoom = cz + (delta ?? 0) * zoomSpeed * cz;
7707
+ const isZoomDirectionInverted = (this.user.getUserPreferences().isZoomDirectionInverted && inputMode === "mouse") ?? false;
7708
+ const deltaValue = delta ?? 0;
7709
+ const finalDelta = isZoomDirectionInverted ? -deltaValue : deltaValue;
7710
+ const zoom = cz + finalDelta * zoomSpeed * cz;
7691
7711
  this._setCamera(new Vec(cx + x / zoom - x / cz, cy + y / zoom - y / cz, zoom), {
7692
7712
  immediate: true
7693
7713
  });
@@ -7813,6 +7833,7 @@ class Editor extends (_a = EventEmitter, _getIsShapeHiddenCache_dec = [computed]
7813
7833
  this.setCurrentTool(this._restoreToolId);
7814
7834
  }
7815
7835
  }
7836
+ this._selectedShapeIdsAtPointerDown = [];
7816
7837
  break;
7817
7838
  }
7818
7839
  }