@tldraw/editor 4.6.0-next.0eb36d65eec3 → 4.6.0-next.1a05e8ec7833

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 (300) hide show
  1. package/dist-cjs/index.d.ts +816 -112
  2. package/dist-cjs/index.js +22 -6
  3. package/dist-cjs/index.js.map +3 -3
  4. package/dist-cjs/lib/TldrawEditor.js +59 -14
  5. package/dist-cjs/lib/TldrawEditor.js.map +3 -3
  6. package/dist-cjs/lib/components/LiveCollaborators.js +1 -0
  7. package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
  8. package/dist-cjs/lib/components/MenuClickCapture.js +99 -38
  9. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +10 -3
  11. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +3 -3
  12. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +5 -2
  13. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  14. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -1
  15. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
  16. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +1 -0
  17. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
  18. package/dist-cjs/lib/config/{createTLUser.js → createTLCurrentUser.js} +9 -9
  19. package/dist-cjs/lib/config/createTLCurrentUser.js.map +7 -0
  20. package/dist-cjs/lib/config/createTLStore.js +30 -0
  21. package/dist-cjs/lib/config/createTLStore.js.map +2 -2
  22. package/dist-cjs/lib/config/defaultAssets.js +36 -0
  23. package/dist-cjs/lib/config/defaultAssets.js.map +7 -0
  24. package/dist-cjs/lib/editor/Editor.js +389 -13
  25. package/dist-cjs/lib/editor/Editor.js.map +3 -3
  26. package/dist-cjs/lib/editor/assets/AssetUtil.js +67 -0
  27. package/dist-cjs/lib/editor/assets/AssetUtil.js.map +7 -0
  28. package/dist-cjs/lib/editor/bindings/BindingUtil.js +1 -0
  29. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +1 -1
  30. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -0
  31. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +1 -1
  32. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +1 -0
  33. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +1 -1
  34. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -0
  35. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +1 -1
  36. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +2 -0
  37. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
  38. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +2 -0
  39. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +1 -1
  40. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +12 -0
  41. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  42. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js +80 -0
  43. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js.map +7 -0
  44. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +466 -0
  45. package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +7 -0
  46. package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js +17 -0
  47. package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js.map +7 -0
  48. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +1 -0
  49. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +1 -1
  50. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +1 -0
  51. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
  52. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +1 -0
  53. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
  54. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +2 -1
  55. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  56. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +1 -0
  57. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +1 -1
  58. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +1 -0
  59. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +1 -1
  60. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +107 -0
  61. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +7 -0
  62. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +586 -0
  63. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +7 -0
  64. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -0
  65. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
  66. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +8 -4
  67. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
  68. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +76 -0
  69. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +7 -0
  70. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +32 -2
  71. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  72. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
  73. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  74. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +6 -0
  75. package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
  76. package/dist-cjs/lib/editor/tools/StateNode.js +15 -17
  77. package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
  78. package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
  79. package/dist-cjs/lib/editor/types/clipboard-types.js.map +1 -1
  80. package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
  81. package/dist-cjs/lib/exports/ExportDelay.js +1 -0
  82. package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
  83. package/dist-cjs/lib/exports/StyleEmbedder.js +1 -0
  84. package/dist-cjs/lib/exports/StyleEmbedder.js.map +1 -1
  85. package/dist-cjs/lib/exports/getSvgJsx.js +14 -8
  86. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  87. package/dist-cjs/lib/globals/environment.js +18 -1
  88. package/dist-cjs/lib/globals/environment.js.map +2 -2
  89. package/dist-cjs/lib/hooks/useCanvasEvents.js +25 -4
  90. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  91. package/dist-cjs/lib/hooks/{useIsDarkMode.js → useColorMode.js} +14 -10
  92. package/dist-cjs/lib/hooks/useColorMode.js.map +7 -0
  93. package/dist-cjs/lib/hooks/useCursor.js +3 -7
  94. package/dist-cjs/lib/hooks/useCursor.js.map +2 -2
  95. package/dist-cjs/lib/hooks/useDarkMode.js +4 -4
  96. package/dist-cjs/lib/hooks/useDarkMode.js.map +2 -2
  97. package/dist-cjs/lib/hooks/useGestureEvents.js +171 -127
  98. package/dist-cjs/lib/hooks/useGestureEvents.js.map +3 -3
  99. package/dist-cjs/lib/options.js +2 -0
  100. package/dist-cjs/lib/options.js.map +2 -2
  101. package/dist-cjs/lib/primitives/Vec.js +3 -0
  102. package/dist-cjs/lib/primitives/Vec.js.map +1 -1
  103. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -0
  104. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +1 -1
  105. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -0
  106. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +1 -1
  107. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +2 -0
  108. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +1 -1
  109. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +1 -0
  110. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +1 -1
  111. package/dist-cjs/lib/utils/EditorAtom.js +2 -0
  112. package/dist-cjs/lib/utils/EditorAtom.js.map +1 -1
  113. package/dist-cjs/lib/utils/reparenting.js +2 -1
  114. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  115. package/dist-cjs/lib/utils/richText.js.map +2 -2
  116. package/dist-cjs/lib/utils/runtime.js +2 -1
  117. package/dist-cjs/lib/utils/runtime.js.map +2 -2
  118. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +2 -0
  119. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +1 -1
  120. package/dist-cjs/lib/utils/sync/hardReset.js +0 -8
  121. package/dist-cjs/lib/utils/sync/hardReset.js.map +2 -2
  122. package/dist-cjs/version.js +3 -3
  123. package/dist-cjs/version.js.map +1 -1
  124. package/dist-esm/index.d.mts +816 -112
  125. package/dist-esm/index.mjs +27 -9
  126. package/dist-esm/index.mjs.map +2 -2
  127. package/dist-esm/lib/TldrawEditor.mjs +62 -14
  128. package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
  129. package/dist-esm/lib/components/LiveCollaborators.mjs +1 -0
  130. package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
  131. package/dist-esm/lib/components/MenuClickCapture.mjs +100 -39
  132. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  133. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +10 -3
  134. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +3 -3
  135. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -2
  136. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  137. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -1
  138. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
  139. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +1 -0
  140. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
  141. package/dist-esm/lib/config/{createTLUser.mjs → createTLCurrentUser.mjs} +6 -6
  142. package/dist-esm/lib/config/createTLCurrentUser.mjs.map +7 -0
  143. package/dist-esm/lib/config/createTLStore.mjs +36 -1
  144. package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
  145. package/dist-esm/lib/config/defaultAssets.mjs +16 -0
  146. package/dist-esm/lib/config/defaultAssets.mjs.map +7 -0
  147. package/dist-esm/lib/editor/Editor.mjs +391 -13
  148. package/dist-esm/lib/editor/Editor.mjs.map +3 -3
  149. package/dist-esm/lib/editor/assets/AssetUtil.mjs +47 -0
  150. package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +7 -0
  151. package/dist-esm/lib/editor/bindings/BindingUtil.mjs +1 -0
  152. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +1 -1
  153. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -0
  154. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +1 -1
  155. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +1 -0
  156. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +1 -1
  157. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -0
  158. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +1 -1
  159. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +2 -0
  160. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
  161. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +2 -0
  162. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +1 -1
  163. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +12 -0
  164. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  165. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs +60 -0
  166. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs.map +7 -0
  167. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +438 -0
  168. package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +7 -0
  169. package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs +1 -0
  170. package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs.map +7 -0
  171. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +1 -0
  172. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +1 -1
  173. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +1 -0
  174. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
  175. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +1 -0
  176. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
  177. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +2 -1
  178. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  179. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +1 -0
  180. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +1 -1
  181. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +1 -0
  182. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +1 -1
  183. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +89 -0
  184. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +7 -0
  185. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +568 -0
  186. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +7 -0
  187. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -0
  188. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
  189. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +8 -4
  190. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
  191. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +56 -0
  192. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +7 -0
  193. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +32 -2
  194. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  195. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
  196. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  197. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +6 -0
  198. package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
  199. package/dist-esm/lib/editor/tools/StateNode.mjs +15 -17
  200. package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
  201. package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
  202. package/dist-esm/lib/exports/ExportDelay.mjs +1 -0
  203. package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
  204. package/dist-esm/lib/exports/StyleEmbedder.mjs +1 -0
  205. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +1 -1
  206. package/dist-esm/lib/exports/getSvgJsx.mjs +14 -11
  207. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  208. package/dist-esm/lib/globals/environment.mjs +18 -1
  209. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  210. package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -4
  211. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  212. package/dist-esm/lib/hooks/useColorMode.mjs +19 -0
  213. package/dist-esm/lib/hooks/useColorMode.mjs.map +7 -0
  214. package/dist-esm/lib/hooks/useCursor.mjs +3 -7
  215. package/dist-esm/lib/hooks/useCursor.mjs.map +2 -2
  216. package/dist-esm/lib/hooks/useDarkMode.mjs +4 -4
  217. package/dist-esm/lib/hooks/useDarkMode.mjs.map +2 -2
  218. package/dist-esm/lib/hooks/useGestureEvents.mjs +171 -127
  219. package/dist-esm/lib/hooks/useGestureEvents.mjs.map +3 -3
  220. package/dist-esm/lib/options.mjs +2 -0
  221. package/dist-esm/lib/options.mjs.map +2 -2
  222. package/dist-esm/lib/primitives/Vec.mjs +3 -0
  223. package/dist-esm/lib/primitives/Vec.mjs.map +1 -1
  224. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -0
  225. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +1 -1
  226. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +1 -0
  227. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +1 -1
  228. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +2 -0
  229. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +1 -1
  230. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +1 -0
  231. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +1 -1
  232. package/dist-esm/lib/utils/EditorAtom.mjs +2 -0
  233. package/dist-esm/lib/utils/EditorAtom.mjs.map +1 -1
  234. package/dist-esm/lib/utils/reparenting.mjs +2 -1
  235. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  236. package/dist-esm/lib/utils/richText.mjs.map +2 -2
  237. package/dist-esm/lib/utils/runtime.mjs +2 -1
  238. package/dist-esm/lib/utils/runtime.mjs.map +2 -2
  239. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +2 -0
  240. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +1 -1
  241. package/dist-esm/lib/utils/sync/hardReset.mjs +0 -8
  242. package/dist-esm/lib/utils/sync/hardReset.mjs.map +2 -2
  243. package/dist-esm/version.mjs +3 -3
  244. package/dist-esm/version.mjs.map +1 -1
  245. package/editor.css +13 -37
  246. package/package.json +8 -9
  247. package/src/index.ts +30 -7
  248. package/src/lib/TldrawEditor.tsx +98 -19
  249. package/src/lib/components/LiveCollaborators.tsx +8 -2
  250. package/src/lib/components/MenuClickCapture.tsx +129 -49
  251. package/src/lib/components/default-components/CanvasShapeIndicators.tsx +14 -3
  252. package/src/lib/components/default-components/DefaultCanvas.tsx +6 -2
  253. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +2 -2
  254. package/src/lib/components/default-components/DefaultShapeIndicators.tsx +2 -0
  255. package/src/lib/config/{createTLUser.ts → createTLCurrentUser.ts} +6 -6
  256. package/src/lib/config/createTLStore.ts +57 -2
  257. package/src/lib/config/defaultAssets.ts +19 -0
  258. package/src/lib/editor/Editor.ts +526 -42
  259. package/src/lib/editor/assets/AssetUtil.ts +85 -0
  260. package/src/lib/editor/managers/FontManager/FontManager.test.ts +9 -2
  261. package/src/lib/editor/managers/FontManager/FontManager.ts +1 -67
  262. package/src/lib/editor/managers/InputsManager/InputsManager.ts +12 -0
  263. package/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts +82 -0
  264. package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +522 -0
  265. package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +583 -0
  266. package/src/lib/editor/managers/PerformanceManager/perf-types.ts +196 -0
  267. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +13 -2
  268. package/src/lib/editor/managers/SnapManager/SnapManager.ts +1 -1
  269. package/src/lib/editor/managers/ThemeManager/ThemeManager.ts +116 -0
  270. package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +605 -0
  271. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +25 -31
  272. package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +7 -5
  273. package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +121 -0
  274. package/src/lib/editor/shapes/ShapeUtil.ts +50 -3
  275. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
  276. package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +7 -0
  277. package/src/lib/editor/tools/StateNode.ts +16 -18
  278. package/src/lib/editor/types/SvgExportContext.tsx +5 -0
  279. package/src/lib/editor/types/clipboard-types.ts +2 -1
  280. package/src/lib/editor/types/external-content.ts +1 -0
  281. package/src/lib/exports/getSvgJsx.tsx +23 -16
  282. package/src/lib/globals/environment.ts +18 -0
  283. package/src/lib/hooks/useCanvasEvents.ts +40 -3
  284. package/src/lib/hooks/{useIsDarkMode.ts → useColorMode.ts} +9 -5
  285. package/src/lib/hooks/useCursor.ts +3 -7
  286. package/src/lib/hooks/useDarkMode.ts +4 -4
  287. package/src/lib/hooks/useGestureEvents.ts +240 -168
  288. package/src/lib/options.ts +14 -0
  289. package/src/lib/primitives/Box.test.ts +30 -0
  290. package/src/lib/primitives/geometry/Geometry2d.test.ts +21 -0
  291. package/src/lib/utils/reparenting.ts +6 -2
  292. package/src/lib/utils/richText.ts +1 -1
  293. package/src/lib/utils/runtime.ts +3 -1
  294. package/src/lib/utils/sync/hardReset.ts +0 -8
  295. package/src/version.ts +3 -3
  296. package/dist-cjs/lib/config/createTLUser.js.map +0 -7
  297. package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
  298. package/dist-esm/lib/config/createTLUser.mjs.map +0 -7
  299. package/dist-esm/lib/hooks/useIsDarkMode.mjs +0 -15
  300. package/dist-esm/lib/hooks/useIsDarkMode.mjs.map +0 -7
@@ -44,7 +44,8 @@ var import_store = require("@tldraw/store");
44
44
  var import_tlschema = require("@tldraw/tlschema");
45
45
  var import_utils = require("@tldraw/utils");
46
46
  var import_eventemitter3 = __toESM(require("eventemitter3"), 1);
47
- var import_createTLUser = require("../config/createTLUser");
47
+ var import_createTLCurrentUser = require("../config/createTLCurrentUser");
48
+ var import_defaultAssets = require("../config/defaultAssets");
48
49
  var import_defaultBindings = require("../config/defaultBindings");
49
50
  var import_defaultShapes = require("../config/defaultShapes");
50
51
  var import_TLEditorSnapshot = require("../config/TLEditorSnapshot");
@@ -81,10 +82,12 @@ var import_FocusManager = require("./managers/FocusManager/FocusManager");
81
82
  var import_FontManager = require("./managers/FontManager/FontManager");
82
83
  var import_HistoryManager = require("./managers/HistoryManager/HistoryManager");
83
84
  var import_InputsManager = require("./managers/InputsManager/InputsManager");
85
+ var import_PerformanceManager = require("./managers/PerformanceManager/PerformanceManager");
84
86
  var import_ScribbleManager = require("./managers/ScribbleManager/ScribbleManager");
85
87
  var import_SnapManager = require("./managers/SnapManager/SnapManager");
86
88
  var import_SpatialIndexManager = require("./managers/SpatialIndexManager/SpatialIndexManager");
87
89
  var import_TextManager = require("./managers/TextManager/TextManager");
90
+ var import_ThemeManager = require("./managers/ThemeManager/ThemeManager");
88
91
  var import_TickManager = require("./managers/TickManager/TickManager");
89
92
  var import_UserPreferencesManager = require("./managers/UserPreferencesManager/UserPreferencesManager");
90
93
  var import_RootState = require("./tools/RootState");
@@ -95,6 +98,7 @@ class Editor extends import_eventemitter3.default {
95
98
  user,
96
99
  shapeUtils,
97
100
  bindingUtils,
101
+ assetUtils: assetUtilConstructors,
98
102
  tools,
99
103
  getContainer,
100
104
  // needs to be here for backwards compatibility with TldrawEditor
@@ -102,13 +106,15 @@ class Editor extends import_eventemitter3.default {
102
106
  cameraOptions,
103
107
  initialState,
104
108
  autoFocus,
105
- inferDarkMode,
106
109
  options: _options,
107
110
  // needs to be here for backwards compatibility with TldrawEditor
108
111
  // eslint-disable-next-line @typescript-eslint/no-deprecated
109
112
  textOptions: _textOptions,
110
113
  getShapeVisibility,
111
- fontAssetUrls
114
+ colorScheme,
115
+ fontAssetUrls,
116
+ themes,
117
+ initialTheme
112
118
  }) {
113
119
  super();
114
120
  this._getShapeVisibility = getShapeVisibility;
@@ -131,15 +137,27 @@ class Editor extends import_eventemitter3.default {
131
137
  ...cameraOptions,
132
138
  ...options?.camera
133
139
  });
140
+ this.getContainer = getContainer;
134
141
  this._textOptions = (0, import_state.atom)("text options", options?.text ?? null);
135
- this.user = new import_UserPreferencesManager.UserPreferencesManager(user ?? (0, import_createTLUser.createTLUser)(), inferDarkMode ?? false);
142
+ this.user = new import_UserPreferencesManager.UserPreferencesManager(user ?? (0, import_createTLCurrentUser.createTLCurrentUser)(), colorScheme ?? "light");
136
143
  this.disposables.add(() => this.user.dispose());
137
- this.getContainer = getContainer;
138
144
  this.textMeasure = new import_TextManager.TextManager(this);
139
145
  this.disposables.add(() => this.textMeasure.dispose());
140
- this.fonts = new import_FontManager.FontManager(this, fontAssetUrls);
146
+ this._themeManager = new import_ThemeManager.ThemeManager(this, {
147
+ themes: (0, import_ThemeManager.resolveThemes)(themes),
148
+ initial: initialTheme ?? "default"
149
+ });
150
+ this.disposables.add(() => this._themeManager.dispose());
141
151
  this._tickManager = new import_TickManager.TickManager(this);
152
+ this.disposables.add(() => this._tickManager.dispose());
153
+ this.disposables.add(() => {
154
+ this.off("tick", this._decayCameraStateTimeout);
155
+ this._setCameraState("idle");
156
+ });
157
+ this.fonts = new import_FontManager.FontManager(this, fontAssetUrls);
142
158
  this.inputs = new import_InputsManager.InputsManager(this);
159
+ this.performance = new import_PerformanceManager.PerformanceManager(this);
160
+ this.disposables.add(() => this.performance.dispose());
143
161
  class NewRoot extends import_RootState.RootState {
144
162
  static initial = initialState ?? "";
145
163
  }
@@ -167,6 +185,16 @@ class Editor extends import_eventemitter3.default {
167
185
  }
168
186
  this.shapeUtils = _shapeUtils;
169
187
  this.styleProps = _styleProps;
188
+ const _shapeUtilsByAssetType = {};
189
+ for (const Util of allShapeUtils) {
190
+ const assetTypes = Util.handledAssetTypes;
191
+ if (assetTypes) {
192
+ for (const assetType of assetTypes) {
193
+ _shapeUtilsByAssetType[assetType] = _shapeUtils[Util.type];
194
+ }
195
+ }
196
+ }
197
+ this._shapeUtilsByAssetType = _shapeUtilsByAssetType;
170
198
  const allBindingUtils = (0, import_defaultBindings.checkBindings)(bindingUtils);
171
199
  const _bindingUtils = {};
172
200
  for (const Util of allBindingUtils) {
@@ -174,6 +202,15 @@ class Editor extends import_eventemitter3.default {
174
202
  _bindingUtils[Util.type] = util;
175
203
  }
176
204
  this.bindingUtils = _bindingUtils;
205
+ if (assetUtilConstructors) {
206
+ const allAssetUtils = (0, import_defaultAssets.checkAssets)(assetUtilConstructors);
207
+ const _assetUtils = {};
208
+ for (const Util of allAssetUtils) {
209
+ const util = new Util(this);
210
+ _assetUtils[Util.type] = util;
211
+ }
212
+ this.assetUtils = _assetUtils;
213
+ }
177
214
  for (const Tool of [...tools]) {
178
215
  if ((0, import_utils.hasOwnProperty)(this.root.children, Tool.id)) {
179
216
  throw Error(`Can't override tool with id "${Tool.id}"`);
@@ -515,6 +552,14 @@ class Editor extends import_eventemitter3.default {
515
552
  })
516
553
  );
517
554
  }
555
+ this.disposables.add(
556
+ (0, import_state.react)("sync current user record", () => {
557
+ const user2 = this.store.props.users.currentUser.get();
558
+ if (user2) {
559
+ this._ensureUserRecord(user2);
560
+ }
561
+ })
562
+ );
518
563
  }
519
564
  _getShapeVisibility;
520
565
  getIsShapeHiddenCache() {
@@ -606,6 +651,17 @@ class Editor extends import_eventemitter3.default {
606
651
  * @public
607
652
  */
608
653
  snaps;
654
+ /**
655
+ * A manager for performance measurement hooks.
656
+ *
657
+ * @public
658
+ */
659
+ performance;
660
+ /**
661
+ * A manager for the spatial index, tracking where shapes exist on the canvas.
662
+ *
663
+ * @internal
664
+ */
609
665
  _spatialIndex;
610
666
  /**
611
667
  * A manager for the any asynchronous events and making sure they're
@@ -620,6 +676,12 @@ class Editor extends import_eventemitter3.default {
620
676
  * @public
621
677
  */
622
678
  user;
679
+ /**
680
+ * A manager for the editor's themes.
681
+ *
682
+ * @internal
683
+ */
684
+ _themeManager;
623
685
  /**
624
686
  * A helper for measuring text.
625
687
  *
@@ -691,12 +753,117 @@ class Editor extends import_eventemitter3.default {
691
753
  * @public
692
754
  */
693
755
  dispose() {
756
+ this.stopCameraAnimation();
757
+ if (this.getInstanceState().followingUserId) {
758
+ this.stopFollowingUser();
759
+ }
694
760
  this.disposables.forEach((dispose) => dispose());
695
761
  this.disposables.clear();
762
+ this.menus.clearOpenMenus();
696
763
  this.store.dispose();
697
764
  this.isDisposed = true;
698
765
  this.emit("dispose");
699
766
  }
767
+ /* ------------------ Themes (shadowing the theme manager) ------------------ */
768
+ /**
769
+ * Get the current color mode (`'light'` or `'dark'`), based on the user's dark mode preference.
770
+ *
771
+ * @public
772
+ */
773
+ getColorMode() {
774
+ return this._themeManager.getColorMode();
775
+ }
776
+ /**
777
+ * Set the color mode. Note that this is a convenience method that passes the mode to
778
+ * `user.updateUserPreferences`, which is the source of truth for the user's color mode preference.
779
+ *
780
+ * @public
781
+ */
782
+ setColorMode(mode) {
783
+ this.user.updateUserPreferences({ colorScheme: mode });
784
+ return this;
785
+ }
786
+ /**
787
+ * Get the id of the current theme.
788
+ *
789
+ * @public
790
+ */
791
+ getCurrentThemeId() {
792
+ return this._themeManager.getCurrentThemeId();
793
+ }
794
+ /**
795
+ * Get the current theme definition.
796
+ *
797
+ * @public
798
+ */
799
+ getCurrentTheme() {
800
+ return this._themeManager.getCurrentTheme();
801
+ }
802
+ /**
803
+ * Set the current theme by id.
804
+ *
805
+ * @public
806
+ */
807
+ setCurrentTheme(id) {
808
+ this._themeManager.setCurrentTheme(id);
809
+ return this;
810
+ }
811
+ /**
812
+ * Get all registered theme definitions.
813
+ *
814
+ * @public
815
+ */
816
+ getThemes() {
817
+ return this._themeManager.getThemes();
818
+ }
819
+ /**
820
+ * Get a single theme definition by id.
821
+ *
822
+ * @public
823
+ */
824
+ getTheme(id) {
825
+ return this._themeManager.getTheme(id);
826
+ }
827
+ /**
828
+ * Replace all theme definitions, or update them via a callback that receives a deep copy.
829
+ * The `'default'` theme must always be present in the result.
830
+ *
831
+ * @example
832
+ * ```ts
833
+ * // Replace all themes
834
+ * editor.updateThemes({ default: myDefaultTheme, ocean: myOceanTheme })
835
+ *
836
+ * // Update via callback
837
+ * editor.updateThemes((themes) => {
838
+ * delete themes.ocean
839
+ * return themes
840
+ * })
841
+ * ```
842
+ *
843
+ * @public
844
+ */
845
+ updateThemes(themes) {
846
+ this._themeManager.updateThemes(themes);
847
+ return this;
848
+ }
849
+ /**
850
+ * Register or update a single theme definition. The theme is keyed by its `id` property.
851
+ *
852
+ * @example
853
+ * ```ts
854
+ * // Override a property on the default theme
855
+ * editor.updateTheme({ ...editor.getTheme('default')!, fontSize: 24 })
856
+ *
857
+ * // Register a new theme
858
+ * editor.updateTheme({ id: 'ocean', ...myOceanTheme })
859
+ * ```
860
+ *
861
+ * @public
862
+ */
863
+ updateTheme(theme) {
864
+ this._themeManager.updateTheme(theme);
865
+ return this;
866
+ }
700
867
  /* ------------------- Shape Utils ------------------ */
701
868
  /**
702
869
  * A map of shape utility classes (TLShapeUtils) by shape type.
@@ -704,6 +871,8 @@ class Editor extends import_eventemitter3.default {
704
871
  * @public
705
872
  */
706
873
  shapeUtils;
874
+ /** @internal */
875
+ _shapeUtilsByAssetType = {};
707
876
  styleProps;
708
877
  getShapeUtil(arg) {
709
878
  const type = typeof arg === "string" ? arg : arg.type;
@@ -715,6 +884,17 @@ class Editor extends import_eventemitter3.default {
715
884
  const type = typeof arg === "string" ? arg : arg.type;
716
885
  return (0, import_utils.hasOwnProperty)(this.shapeUtils, type);
717
886
  }
887
+ /**
888
+ * Get the shape util that handles the given asset type.
889
+ * Returns the shape util whose {@link ShapeUtil.handledAssetTypes} includes
890
+ * the given asset type, or undefined if none matches.
891
+ *
892
+ * @param assetType - The asset type string.
893
+ * @public
894
+ */
895
+ getShapeUtilForAssetType(assetType) {
896
+ return (0, import_utils.getOwnProperty)(this._shapeUtilsByAssetType, assetType);
897
+ }
718
898
  /* ------------------- Binding Utils ------------------ */
719
899
  /**
720
900
  * A map of shape utility classes (TLShapeUtils) by shape type.
@@ -728,6 +908,42 @@ class Editor extends import_eventemitter3.default {
728
908
  (0, import_utils.assert)(bindingUtil, `No binding util found for type "${type}"`);
729
909
  return bindingUtil;
730
910
  }
911
+ /* ------------------- Asset Utils ------------------ */
912
+ /**
913
+ * A map of asset utility classes by asset type.
914
+ *
915
+ * @public
916
+ */
917
+ assetUtils = {};
918
+ getAssetUtil(arg) {
919
+ const type = typeof arg === "string" ? arg : arg.type;
920
+ const assetUtil = (0, import_utils.getOwnProperty)(this.assetUtils, type);
921
+ (0, import_utils.assert)(assetUtil, `No asset util found for type "${type}"`);
922
+ return assetUtil;
923
+ }
924
+ /**
925
+ * Returns true if the editor has an asset util for the given asset type.
926
+ *
927
+ * @public
928
+ */
929
+ hasAssetUtil(arg) {
930
+ const type = typeof arg === "string" ? arg : arg.type;
931
+ return (0, import_utils.hasOwnProperty)(this.assetUtils, type);
932
+ }
933
+ /**
934
+ * Get the asset util that accepts the given MIME type.
935
+ * Returns null if no registered asset util accepts the MIME type.
936
+ *
937
+ * @public
938
+ */
939
+ getAssetUtilForMimeType(mimeType) {
940
+ for (const util of Object.values(this.assetUtils)) {
941
+ if (util && util.acceptsMimeType(mimeType)) {
942
+ return util;
943
+ }
944
+ }
945
+ return null;
946
+ }
731
947
  /* --------------------- History -------------------- */
732
948
  /**
733
949
  * A manager for the editor's history.
@@ -749,6 +965,7 @@ class Editor extends import_eventemitter3.default {
749
965
  this._flushEventsForTick(0);
750
966
  this.complete();
751
967
  this.history.undo();
968
+ this.performance._notifyUndoRedo("undo", this.history.getNumUndos(), this.history.getNumRedos());
752
969
  return this;
753
970
  }
754
971
  canUndo() {
@@ -771,6 +988,7 @@ class Editor extends import_eventemitter3.default {
771
988
  this._flushEventsForTick(0);
772
989
  this.complete();
773
990
  this.history.redo();
991
+ this.performance._notifyUndoRedo("redo", this.history.getNumUndos(), this.history.getNumRedos());
774
992
  return this;
775
993
  }
776
994
  canRedo() {
@@ -2821,6 +3039,76 @@ class Editor extends import_eventemitter3.default {
2821
3039
  const currentPageId = this.getCurrentPageId();
2822
3040
  return this.getCollaborators().filter((c) => c.currentPageId === currentPageId);
2823
3041
  }
3042
+ // Attribution
3043
+ /**
3044
+ * Get the current user's ID for attribution purposes.
3045
+ * Also ensures a `user:` record exists in the store for the current user.
3046
+ * Returns `null` when the user store has no current user.
3047
+ *
3048
+ * @public
3049
+ */
3050
+ getAttributionUserId() {
3051
+ const user = this.store.props.users.currentUser.get();
3052
+ if (!user) return null;
3053
+ this._ensureUserRecord(user);
3054
+ return import_tlschema.UserRecordType.parseId(user.id);
3055
+ }
3056
+ /**
3057
+ * Ensure a user record exists in the store for the given user,
3058
+ * updating it if the data has changed.
3059
+ *
3060
+ * @internal
3061
+ */
3062
+ _ensureUserRecord(user) {
3063
+ const existing = this.store.get(user.id);
3064
+ if (existing && existing.name === user.name && existing.color === user.color && existing.imageUrl === user.imageUrl && existing.meta === user.meta) {
3065
+ return;
3066
+ }
3067
+ this.run(
3068
+ () => {
3069
+ this.store.put([user]);
3070
+ },
3071
+ { history: "ignore" }
3072
+ );
3073
+ }
3074
+ /**
3075
+ * Resolve a display name for a user ID. Asks the
3076
+ * {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
3077
+ * falling back to the `user:` record in the store.
3078
+ *
3079
+ * @public
3080
+ */
3081
+ getAttributionDisplayName(userId) {
3082
+ if (!userId) return null;
3083
+ return this.store.props.users.resolve(userId).get()?.name ?? this.store.get((0, import_tlschema.createUserId)(userId))?.name ?? null;
3084
+ }
3085
+ /**
3086
+ * Resolve a user record by ID. Asks the
3087
+ * {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
3088
+ * falling back to the `user:` record in the store.
3089
+ *
3090
+ * @public
3091
+ */
3092
+ getAttributionUser(userId) {
3093
+ if (!userId) return null;
3094
+ return this.store.props.users.resolve(userId).get() ?? this.store.get((0, import_tlschema.createUserId)(userId)) ?? null;
3095
+ }
3096
+ /**
3097
+ * Collect user IDs referenced by a set of shapes via shape-specific props
3098
+ * (e.g. `textFirstEditedBy` on notes).
3099
+ *
3100
+ * @internal
3101
+ */
3102
+ _getReferencedUserIds(shapes) {
3103
+ const userIds = /* @__PURE__ */ new Set();
3104
+ for (const shape of shapes) {
3105
+ const util = this.getShapeUtil(shape);
3106
+ for (const id of util.getReferencedUserIds(shape)) {
3107
+ userIds.add(id);
3108
+ }
3109
+ }
3110
+ return userIds;
3111
+ }
2824
3112
  // Following
2825
3113
  // When we are 'locked on' to a user, our camera is derived from their camera.
2826
3114
  _isLockedOnFollowingUser = (0, import_state.atom)("isLockedOnFollowingUser", false);
@@ -3855,7 +4143,7 @@ class Editor extends import_eventemitter3.default {
3855
4143
  const searchMargin = Math.max(innerMargin, outerMargin, this.options.hitTestMargin / zoomLevel);
3856
4144
  const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin);
3857
4145
  const shapesToCheck = (opts.renderingOnly ? this.getCurrentPageRenderingShapesSorted() : this.getCurrentPageShapesSorted()).filter((shape) => {
3858
- if (!candidateIds.has(shape.id) && !this.isShapeOfType(shape, "frame")) return false;
4146
+ if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
3859
4147
  if (shape.isLocked && !hitLocked || this.isShapeHidden(shape) || this.isShapeOfType(shape, "group"))
3860
4148
  return false;
3861
4149
  const pageMask = this.getShapeMask(shape);
@@ -3868,14 +4156,16 @@ class Editor extends import_eventemitter3.default {
3868
4156
  const geometry = this.getShapeGeometry(shape);
3869
4157
  const isGroup = geometry instanceof import_Group2d.Group2d;
3870
4158
  const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
3871
- if (this.isShapeOfType(shape, "frame") || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && this.getShapeUtil(shape).getText(shape)?.trim()) {
4159
+ const shapeUtil = this.getShapeUtil(shape);
4160
+ const isShapeFrameLike = this.isShapeFrameLike(shape);
4161
+ if (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim()) {
3872
4162
  for (const childGeometry of geometry.children) {
3873
4163
  if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
3874
4164
  return shape;
3875
4165
  }
3876
4166
  }
3877
4167
  }
3878
- if (this.isShapeOfType(shape, "frame")) {
4168
+ if (isShapeFrameLike) {
3879
4169
  const distance2 = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside);
3880
4170
  if (hitFrameInside ? distance2 > 0 && distance2 <= outerMargin || distance2 <= 0 && distance2 > -innerMargin : distance2 > 0 && distance2 <= outerMargin) {
3881
4171
  return inMarginClosestToEdgeHit || shape;
@@ -3969,7 +4259,7 @@ class Editor extends import_eventemitter3.default {
3969
4259
  const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, margin);
3970
4260
  return this.getCurrentPageShapesSorted().filter((shape) => {
3971
4261
  if (this.isShapeHidden(shape)) return false;
3972
- if (!candidateIds.has(shape.id) && !this.isShapeOfType(shape, "frame")) return false;
4262
+ if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
3973
4263
  return this.isPointInShape(shape, point, opts);
3974
4264
  }).reverse();
3975
4265
  }
@@ -4082,6 +4372,24 @@ class Editor extends import_eventemitter3.default {
4082
4372
  if (!shape) return false;
4083
4373
  return shape.type === type;
4084
4374
  }
4375
+ /**
4376
+ * Get whether a shape behaves like a frame — a container that has child
4377
+ * shapes, requires full-brush selection, blocks erasure from inside, etc.
4378
+ *
4379
+ * @example
4380
+ * ```ts
4381
+ * const isFrameLike = editor.isShapeFrameLike(someShape)
4382
+ * ```
4383
+ *
4384
+ * @param shape - The shape (or shape id) to test.
4385
+ *
4386
+ * @public
4387
+ */
4388
+ isShapeFrameLike(shape) {
4389
+ const _shape = typeof shape === "string" ? this.getShape(shape) : shape;
4390
+ if (!_shape) return false;
4391
+ return this.getShapeUtil(_shape).isFrameLike(_shape);
4392
+ }
4085
4393
  /**
4086
4394
  * Get a shape by its id.
4087
4395
  *
@@ -6534,12 +6842,22 @@ class Editor extends import_eventemitter3.default {
6534
6842
  if (!asset) continue;
6535
6843
  assets.push(asset);
6536
6844
  }
6845
+ const users = [];
6846
+ const seenUserIds = /* @__PURE__ */ new Set();
6847
+ for (const userId of this._getReferencedUserIds(shapes2)) {
6848
+ const recordId = (0, import_tlschema.createUserId)(userId);
6849
+ if (seenUserIds.has(recordId)) continue;
6850
+ seenUserIds.add(recordId);
6851
+ const user = this.store.get(recordId);
6852
+ if (user) users.push(user);
6853
+ }
6537
6854
  return {
6538
6855
  schema: this.store.schema.serialize(),
6539
6856
  shapes: shapes2,
6540
6857
  rootShapeIds,
6541
6858
  bindings,
6542
- assets
6859
+ assets,
6860
+ users
6543
6861
  };
6544
6862
  });
6545
6863
  }
@@ -6589,13 +6907,15 @@ class Editor extends import_eventemitter3.default {
6589
6907
  const assets = [];
6590
6908
  const shapes = [];
6591
6909
  const bindings = [];
6910
+ const users = [];
6592
6911
  const store = {
6593
6912
  store: {
6594
6913
  ...Object.fromEntries(content.assets.map((asset) => [asset.id, asset])),
6595
6914
  ...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape])),
6596
6915
  ...Object.fromEntries(
6597
6916
  content.bindings?.map((bindings2) => [bindings2.id, bindings2]) ?? []
6598
- )
6917
+ ),
6918
+ ...Object.fromEntries(content.users?.map((user) => [user.id, user]) ?? [])
6599
6919
  },
6600
6920
  schema: content.schema
6601
6921
  };
@@ -6617,6 +6937,19 @@ class Editor extends import_eventemitter3.default {
6617
6937
  bindings.push(record);
6618
6938
  break;
6619
6939
  }
6940
+ case "user": {
6941
+ users.push(record);
6942
+ break;
6943
+ }
6944
+ }
6945
+ }
6946
+ if (users.length > 0) {
6947
+ const existingUserIds = new Set(
6948
+ this.store.allRecords().filter((r) => r.typeName === "user").map((r) => r.id)
6949
+ );
6950
+ const usersToCreate = users.filter((u) => !existingUserIds.has(u.id));
6951
+ if (usersToCreate.length > 0) {
6952
+ this.store.put(usersToCreate);
6620
6953
  }
6621
6954
  }
6622
6955
  const shapeIdMap = new Map(
@@ -7582,6 +7915,7 @@ class Editor extends import_eventemitter3.default {
7582
7915
  ),
7583
7916
  { immediate: true }
7584
7917
  );
7918
+ this.performance._notifyCameraOperation("zooming");
7585
7919
  this.emit("event", info);
7586
7920
  return;
7587
7921
  }
@@ -7643,6 +7977,7 @@ class Editor extends import_eventemitter3.default {
7643
7977
  immediate: true
7644
7978
  });
7645
7979
  this.maybeTrackPerformance("Zooming");
7980
+ this.performance._notifyCameraOperation("zooming");
7646
7981
  this.root.handleEvent(info);
7647
7982
  this.emit("event", info);
7648
7983
  return;
@@ -7652,6 +7987,7 @@ class Editor extends import_eventemitter3.default {
7652
7987
  immediate: true
7653
7988
  });
7654
7989
  this.maybeTrackPerformance("Panning");
7990
+ this.performance._notifyCameraOperation("panning");
7655
7991
  this.root.handleEvent(info);
7656
7992
  this.emit("event", info);
7657
7993
  return;
@@ -7698,6 +8034,10 @@ class Editor extends import_eventemitter3.default {
7698
8034
  }
7699
8035
  this.inputs.setIsPanning(true);
7700
8036
  clearTimeout(this._longPressTimeout);
8037
+ } else if (info.button === import_constants.RIGHT_MOUSE_BUTTON && this.options.rightClickPanning) {
8038
+ this.inputs.setIsRightPointing(true);
8039
+ clearTimeout(this._longPressTimeout);
8040
+ return this;
7701
8041
  }
7702
8042
  if (this.inputs.getIsPanning()) {
7703
8043
  this.stopCameraAnimation();
@@ -7709,6 +8049,22 @@ class Editor extends import_eventemitter3.default {
7709
8049
  case "pointer_move": {
7710
8050
  if (!isPen && isPenMode) return;
7711
8051
  const { x: cx, y: cy, z: cz } = (0, import_state.unsafe__withoutCapture)(() => this.getCamera());
8052
+ if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
8053
+ const currentScreenPoint = this.inputs.getCurrentScreenPoint();
8054
+ const originScreenPoint = this.inputs.getOriginScreenPoint();
8055
+ if (import_Vec.Vec.Dist2(originScreenPoint, currentScreenPoint) > this.options.dragDistanceSquared) {
8056
+ this._prevCursor = this.getInstanceState().cursor.type;
8057
+ this.inputs.setIsPanning(true);
8058
+ this.setCursor({ type: "grabbing", rotation: 0 });
8059
+ this.stopCameraAnimation();
8060
+ const offset = import_Vec.Vec.Sub(currentScreenPoint, originScreenPoint);
8061
+ this.setCamera(new import_Vec.Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
8062
+ immediate: true
8063
+ });
8064
+ this.maybeTrackPerformance("Panning");
8065
+ }
8066
+ return;
8067
+ }
7712
8068
  if (this.inputs.getIsPanning() && this.inputs.getIsPointing()) {
7713
8069
  const currentScreenPoint = this.inputs.getCurrentScreenPoint();
7714
8070
  const previousScreenPoint = this.inputs.getPreviousScreenPoint();
@@ -7717,6 +8073,7 @@ class Editor extends import_eventemitter3.default {
7717
8073
  immediate: true
7718
8074
  });
7719
8075
  this.maybeTrackPerformance("Panning");
8076
+ this.performance._notifyCameraOperation("panning");
7720
8077
  return;
7721
8078
  }
7722
8079
  if (inputs.getIsPointing() && !inputs.getIsDragging() && import_Vec.Vec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
@@ -7731,6 +8088,12 @@ class Editor extends import_eventemitter3.default {
7731
8088
  clearTimeout(this._longPressTimeout);
7732
8089
  inputs.buttons.delete(info.button);
7733
8090
  if (instanceState.isPenMode && !isPen) return;
8091
+ if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
8092
+ this.inputs.setIsRightPointing(false);
8093
+ this._selectedShapeIdsAtPointerDown = [];
8094
+ break;
8095
+ }
8096
+ this.inputs.setIsRightPointing(false);
7734
8097
  if (this.capturedPointerId === info.pointerId) {
7735
8098
  this.capturedPointerId = null;
7736
8099
  info.button = 0;
@@ -7748,11 +8111,24 @@ class Editor extends import_eventemitter3.default {
7748
8111
  break;
7749
8112
  }
7750
8113
  case import_constants.MIDDLE_MOUSE_BUTTON: {
7751
- if (this.inputs.keys.has(" ")) {
8114
+ if (this.inputs.keys.has("Space")) {
7752
8115
  this.setCursor({ type: "grab", rotation: 0 });
7753
8116
  } else {
7754
8117
  this.setCursor({ type: this._prevCursor, rotation: 0 });
7755
8118
  }
8119
+ break;
8120
+ }
8121
+ case import_constants.RIGHT_MOUSE_BUTTON: {
8122
+ if (this.inputs.keys.has("Space")) {
8123
+ this.setCursor({ type: "grab", rotation: 0 });
8124
+ } else {
8125
+ this.setCursor({ type: this._prevCursor, rotation: 0 });
8126
+ }
8127
+ if (slideSpeed > 0) {
8128
+ this.slideCamera({ speed: slideSpeed, direction: slideDirection });
8129
+ }
8130
+ this._selectedShapeIdsAtPointerDown = [];
8131
+ return this;
7756
8132
  }
7757
8133
  }
7758
8134
  if (slideSpeed > 0) {