@tldraw/editor 4.6.0-next.fecc64eee134 → 5.0.1

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 (324) hide show
  1. package/dist-cjs/index.d.ts +493 -170
  2. package/dist-cjs/index.js +14 -23
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +3 -0
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/MenuClickCapture.js +93 -47
  7. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  8. package/dist-cjs/lib/components/default-components/CanvasOverlays.js +180 -0
  9. package/dist-cjs/lib/components/default-components/CanvasOverlays.js.map +7 -0
  10. package/dist-cjs/lib/components/default-components/DefaultCanvas.js +46 -248
  11. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +3 -3
  12. package/dist-cjs/lib/editor/Editor.js +142 -33
  13. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  14. package/dist-cjs/lib/editor/assets/AssetUtil.js +1 -0
  15. package/dist-cjs/lib/editor/assets/AssetUtil.js.map +1 -1
  16. package/dist-cjs/lib/editor/bindings/BindingUtil.js +1 -0
  17. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +1 -1
  18. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -0
  19. package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +1 -1
  20. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +98 -0
  21. package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +7 -0
  22. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +1 -0
  23. package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +1 -1
  24. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -0
  25. package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +1 -1
  26. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +2 -0
  27. package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +1 -1
  28. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +2 -0
  29. package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +1 -1
  30. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +12 -0
  31. package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
  32. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +1 -0
  33. package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +1 -1
  34. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +1 -0
  35. package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
  36. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +1 -0
  37. package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
  38. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +2 -1
  39. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  40. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +1 -0
  41. package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +1 -1
  42. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +1 -0
  43. package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +1 -1
  44. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +1 -0
  45. package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +1 -1
  46. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +14 -0
  47. package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +2 -2
  48. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -0
  49. package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
  50. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +2 -0
  51. package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +1 -1
  52. package/dist-cjs/lib/editor/overlays/OverlayManager.js +154 -0
  53. package/dist-cjs/lib/editor/overlays/OverlayManager.js.map +7 -0
  54. package/dist-cjs/lib/editor/overlays/OverlayUtil.js +92 -0
  55. package/dist-cjs/lib/editor/overlays/OverlayUtil.js.map +7 -0
  56. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +161 -0
  57. package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
  58. package/dist-cjs/lib/editor/overlays/getOverlayDisplayValues.js +39 -0
  59. package/dist-cjs/lib/editor/overlays/getOverlayDisplayValues.js.map +7 -0
  60. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +79 -0
  61. package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +7 -0
  62. package/dist-cjs/lib/editor/shapes/ShapeUtil.js +36 -23
  63. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  64. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +32 -2
  65. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  66. package/dist-cjs/lib/editor/tools/StateNode.js +1 -0
  67. package/dist-cjs/lib/editor/tools/StateNode.js.map +1 -1
  68. package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
  69. package/dist-cjs/lib/exports/ExportDelay.js +1 -0
  70. package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
  71. package/dist-cjs/lib/exports/StyleEmbedder.js +1 -0
  72. package/dist-cjs/lib/exports/StyleEmbedder.js.map +1 -1
  73. package/dist-cjs/lib/exports/fetchCache.js +1 -1
  74. package/dist-cjs/lib/exports/fetchCache.js.map +2 -2
  75. package/dist-cjs/lib/exports/getSvgJsx.js +2 -1
  76. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  77. package/dist-cjs/lib/hooks/EditorComponentsContext.js.map +2 -2
  78. package/dist-cjs/lib/hooks/useCanvasEvents.js +25 -4
  79. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  80. package/dist-cjs/lib/hooks/useEditorComponents.js +0 -28
  81. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  82. package/dist-cjs/lib/hooks/usePeerIds.js +1 -36
  83. package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
  84. package/dist-cjs/lib/hooks/useShapeCulling.js +2 -1
  85. package/dist-cjs/lib/hooks/useShapeCulling.js.map +2 -2
  86. package/dist-cjs/lib/options.js +1 -0
  87. package/dist-cjs/lib/options.js.map +2 -2
  88. package/dist-cjs/lib/primitives/Vec.js +3 -0
  89. package/dist-cjs/lib/primitives/Vec.js.map +1 -1
  90. package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -0
  91. package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +1 -1
  92. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -0
  93. package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +1 -1
  94. package/dist-cjs/lib/primitives/geometry/Geometry2d.js +2 -0
  95. package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +1 -1
  96. package/dist-cjs/lib/primitives/geometry/Stadium2d.js +1 -0
  97. package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +1 -1
  98. package/dist-cjs/lib/utils/EditorAtom.js +2 -0
  99. package/dist-cjs/lib/utils/EditorAtom.js.map +1 -1
  100. package/dist-cjs/lib/utils/reparenting.js +20 -7
  101. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  102. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +5 -0
  103. package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
  104. package/dist-cjs/version.js +4 -4
  105. package/dist-cjs/version.js.map +1 -1
  106. package/dist-esm/index.d.mts +493 -170
  107. package/dist-esm/index.mjs +21 -41
  108. package/dist-esm/index.mjs.map +2 -2
  109. package/dist-esm/lib/TldrawEditor.mjs +3 -0
  110. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  111. package/dist-esm/lib/components/MenuClickCapture.mjs +94 -48
  112. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  113. package/dist-esm/lib/components/default-components/CanvasOverlays.mjs +160 -0
  114. package/dist-esm/lib/components/default-components/CanvasOverlays.mjs.map +7 -0
  115. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +47 -249
  116. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +3 -3
  117. package/dist-esm/lib/editor/Editor.mjs +143 -35
  118. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  119. package/dist-esm/lib/editor/assets/AssetUtil.mjs +1 -0
  120. package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +1 -1
  121. package/dist-esm/lib/editor/bindings/BindingUtil.mjs +1 -0
  122. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +1 -1
  123. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -0
  124. package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +1 -1
  125. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +83 -0
  126. package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +7 -0
  127. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +1 -0
  128. package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +1 -1
  129. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -0
  130. package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +1 -1
  131. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +2 -0
  132. package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +1 -1
  133. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +2 -0
  134. package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +1 -1
  135. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +12 -0
  136. package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
  137. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +1 -0
  138. package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +1 -1
  139. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +1 -0
  140. package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
  141. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +1 -0
  142. package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
  143. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +2 -1
  144. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  145. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +1 -0
  146. package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +1 -1
  147. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +1 -0
  148. package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +1 -1
  149. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +1 -0
  150. package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +1 -1
  151. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +14 -0
  152. package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +2 -2
  153. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -0
  154. package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
  155. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +2 -0
  156. package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +1 -1
  157. package/dist-esm/lib/editor/overlays/OverlayManager.mjs +136 -0
  158. package/dist-esm/lib/editor/overlays/OverlayManager.mjs.map +7 -0
  159. package/dist-esm/lib/editor/overlays/OverlayUtil.mjs +72 -0
  160. package/dist-esm/lib/editor/overlays/OverlayUtil.mjs.map +7 -0
  161. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +141 -0
  162. package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
  163. package/dist-esm/lib/editor/overlays/getOverlayDisplayValues.mjs +19 -0
  164. package/dist-esm/lib/editor/overlays/getOverlayDisplayValues.mjs.map +7 -0
  165. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +59 -0
  166. package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +7 -0
  167. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +36 -23
  168. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  169. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +32 -2
  170. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  171. package/dist-esm/lib/editor/tools/StateNode.mjs +1 -0
  172. package/dist-esm/lib/editor/tools/StateNode.mjs.map +1 -1
  173. package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
  174. package/dist-esm/lib/exports/ExportDelay.mjs +1 -0
  175. package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
  176. package/dist-esm/lib/exports/StyleEmbedder.mjs +1 -0
  177. package/dist-esm/lib/exports/StyleEmbedder.mjs.map +1 -1
  178. package/dist-esm/lib/exports/fetchCache.mjs +2 -2
  179. package/dist-esm/lib/exports/fetchCache.mjs.map +2 -2
  180. package/dist-esm/lib/exports/getSvgJsx.mjs +2 -1
  181. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  182. package/dist-esm/lib/hooks/EditorComponentsContext.mjs.map +2 -2
  183. package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -4
  184. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  185. package/dist-esm/lib/hooks/useEditorComponents.mjs +0 -28
  186. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  187. package/dist-esm/lib/hooks/usePeerIds.mjs +2 -40
  188. package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
  189. package/dist-esm/lib/hooks/useShapeCulling.mjs +2 -1
  190. package/dist-esm/lib/hooks/useShapeCulling.mjs.map +2 -2
  191. package/dist-esm/lib/options.mjs +1 -0
  192. package/dist-esm/lib/options.mjs.map +2 -2
  193. package/dist-esm/lib/primitives/Vec.mjs +3 -0
  194. package/dist-esm/lib/primitives/Vec.mjs.map +1 -1
  195. package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -0
  196. package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +1 -1
  197. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +1 -0
  198. package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +1 -1
  199. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +2 -0
  200. package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +1 -1
  201. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +1 -0
  202. package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +1 -1
  203. package/dist-esm/lib/utils/EditorAtom.mjs +2 -0
  204. package/dist-esm/lib/utils/EditorAtom.mjs.map +1 -1
  205. package/dist-esm/lib/utils/reparenting.mjs +20 -7
  206. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  207. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +5 -0
  208. package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
  209. package/dist-esm/version.mjs +4 -4
  210. package/dist-esm/version.mjs.map +1 -1
  211. package/editor.css +4 -243
  212. package/package.json +7 -7
  213. package/src/index.ts +18 -39
  214. package/src/lib/TldrawEditor.tsx +9 -0
  215. package/src/lib/components/MenuClickCapture.tsx +124 -64
  216. package/src/lib/components/default-components/CanvasOverlays.tsx +208 -0
  217. package/src/lib/components/default-components/DefaultCanvas.tsx +51 -322
  218. package/src/lib/editor/Editor.test.ts +3 -1
  219. package/src/lib/editor/Editor.ts +167 -38
  220. package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +98 -0
  221. package/src/lib/editor/managers/InputsManager/InputsManager.ts +12 -0
  222. package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +13 -2
  223. package/src/lib/editor/managers/SnapManager/SnapManager.ts +1 -1
  224. package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +14 -0
  225. package/src/lib/editor/overlays/OverlayManager.ts +183 -0
  226. package/src/lib/editor/overlays/OverlayUtil.ts +143 -0
  227. package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +216 -0
  228. package/src/lib/editor/overlays/getOverlayDisplayValues.ts +51 -0
  229. package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +128 -0
  230. package/src/lib/editor/shapes/ShapeUtil.ts +45 -26
  231. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +40 -3
  232. package/src/lib/editor/types/event-types.ts +2 -0
  233. package/src/lib/exports/fetchCache.ts +2 -4
  234. package/src/lib/exports/getSvgJsx.test.ts +3 -1
  235. package/src/lib/exports/getSvgJsx.tsx +2 -1
  236. package/src/lib/hooks/EditorComponentsContext.tsx +0 -27
  237. package/src/lib/hooks/useCanvasEvents.ts +45 -3
  238. package/src/lib/hooks/useEditorComponents.tsx +0 -28
  239. package/src/lib/hooks/usePeerIds.ts +6 -55
  240. package/src/lib/hooks/useShapeCulling.tsx +3 -1
  241. package/src/lib/options.ts +7 -0
  242. package/src/lib/utils/reparenting.ts +22 -9
  243. package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -0
  244. package/src/version.ts +4 -4
  245. package/dist-cjs/lib/components/GeometryDebuggingView.js +0 -115
  246. package/dist-cjs/lib/components/GeometryDebuggingView.js.map +0 -7
  247. package/dist-cjs/lib/components/LiveCollaborators.js +0 -151
  248. package/dist-cjs/lib/components/LiveCollaborators.js.map +0 -7
  249. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +0 -227
  250. package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +0 -7
  251. package/dist-cjs/lib/components/default-components/DefaultBrush.js +0 -38
  252. package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +0 -7
  253. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +0 -71
  254. package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +0 -7
  255. package/dist-cjs/lib/components/default-components/DefaultCursor.js +0 -59
  256. package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +0 -7
  257. package/dist-cjs/lib/components/default-components/DefaultHandle.js +0 -56
  258. package/dist-cjs/lib/components/default-components/DefaultHandle.js.map +0 -7
  259. package/dist-cjs/lib/components/default-components/DefaultHandles.js +0 -28
  260. package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +0 -7
  261. package/dist-cjs/lib/components/default-components/DefaultScribble.js +0 -51
  262. package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +0 -7
  263. package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js +0 -69
  264. package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js.map +0 -7
  265. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +0 -107
  266. package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +0 -7
  267. package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js +0 -28
  268. package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js.map +0 -7
  269. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +0 -101
  270. package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +0 -7
  271. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +0 -170
  272. package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +0 -7
  273. package/dist-cjs/lib/hooks/useHandleEvents.js +0 -100
  274. package/dist-cjs/lib/hooks/useHandleEvents.js.map +0 -7
  275. package/dist-cjs/lib/hooks/useSelectionEvents.js +0 -98
  276. package/dist-cjs/lib/hooks/useSelectionEvents.js.map +0 -7
  277. package/dist-esm/lib/components/GeometryDebuggingView.mjs +0 -95
  278. package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +0 -7
  279. package/dist-esm/lib/components/LiveCollaborators.mjs +0 -134
  280. package/dist-esm/lib/components/LiveCollaborators.mjs.map +0 -7
  281. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +0 -207
  282. package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +0 -7
  283. package/dist-esm/lib/components/default-components/DefaultBrush.mjs +0 -18
  284. package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +0 -7
  285. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +0 -41
  286. package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +0 -7
  287. package/dist-esm/lib/components/default-components/DefaultCursor.mjs +0 -29
  288. package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +0 -7
  289. package/dist-esm/lib/components/default-components/DefaultHandle.mjs +0 -26
  290. package/dist-esm/lib/components/default-components/DefaultHandle.mjs.map +0 -7
  291. package/dist-esm/lib/components/default-components/DefaultHandles.mjs +0 -8
  292. package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +0 -7
  293. package/dist-esm/lib/components/default-components/DefaultScribble.mjs +0 -21
  294. package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +0 -7
  295. package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs +0 -39
  296. package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map +0 -7
  297. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +0 -77
  298. package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +0 -7
  299. package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs +0 -8
  300. package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map +0 -7
  301. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +0 -81
  302. package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +0 -7
  303. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +0 -142
  304. package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +0 -7
  305. package/dist-esm/lib/hooks/useHandleEvents.mjs +0 -70
  306. package/dist-esm/lib/hooks/useHandleEvents.mjs.map +0 -7
  307. package/dist-esm/lib/hooks/useSelectionEvents.mjs +0 -78
  308. package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +0 -7
  309. package/src/lib/components/GeometryDebuggingView.tsx +0 -108
  310. package/src/lib/components/LiveCollaborators.tsx +0 -174
  311. package/src/lib/components/default-components/CanvasShapeIndicators.tsx +0 -289
  312. package/src/lib/components/default-components/DefaultBrush.tsx +0 -35
  313. package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +0 -52
  314. package/src/lib/components/default-components/DefaultCursor.tsx +0 -59
  315. package/src/lib/components/default-components/DefaultHandle.tsx +0 -42
  316. package/src/lib/components/default-components/DefaultHandles.tsx +0 -15
  317. package/src/lib/components/default-components/DefaultScribble.tsx +0 -31
  318. package/src/lib/components/default-components/DefaultSelectionForeground.tsx +0 -50
  319. package/src/lib/components/default-components/DefaultShapeIndicator.tsx +0 -104
  320. package/src/lib/components/default-components/DefaultShapeIndicatorErrorFallback.tsx +0 -9
  321. package/src/lib/components/default-components/DefaultShapeIndicators.tsx +0 -116
  322. package/src/lib/components/default-components/DefaultSnapIndictor.tsx +0 -174
  323. package/src/lib/hooks/useHandleEvents.ts +0 -88
  324. package/src/lib/hooks/useSelectionEvents.ts +0 -97
@@ -1,9 +1,11 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useValue } from "@tldraw/state-react";
3
- import { useCallback, useRef, useState } from "react";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { flushSync } from "react-dom";
4
5
  import { useCanvasEvents } from "../hooks/useCanvasEvents.mjs";
5
6
  import { useEditor } from "../hooks/useEditor.mjs";
6
7
  import { Vec } from "../primitives/Vec.mjs";
8
+ import { releasePointerCapture, setPointerCapture } from "../utils/dom.mjs";
7
9
  import { getPointerInfo } from "../utils/getPointerInfo.mjs";
8
10
  function MenuClickCapture() {
9
11
  const editor = useEditor();
@@ -14,81 +16,125 @@ function MenuClickCapture() {
14
16
  const rPointerState = useRef({
15
17
  isDown: false,
16
18
  isDragging: false,
19
+ button: 0,
17
20
  start: new Vec()
18
21
  });
22
+ const rCancelContextMenuSwallow = useRef(null);
23
+ useEffect(
24
+ () => () => {
25
+ rCancelContextMenuSwallow.current?.();
26
+ rCancelContextMenuSwallow.current = null;
27
+ },
28
+ []
29
+ );
30
+ const swallowNextNativeContextMenu = useCallback(() => {
31
+ rCancelContextMenuSwallow.current?.();
32
+ const doc = editor.getContainerDocument();
33
+ const onContextMenu = (event) => {
34
+ if (!event.isTrusted) return;
35
+ rCancelContextMenuSwallow.current?.();
36
+ rCancelContextMenuSwallow.current = null;
37
+ event.preventDefault();
38
+ event.stopImmediatePropagation();
39
+ };
40
+ const cancel = () => doc.removeEventListener("contextmenu", onContextMenu, true);
41
+ rCancelContextMenuSwallow.current = cancel;
42
+ doc.addEventListener("contextmenu", onContextMenu, true);
43
+ doc.defaultView?.setTimeout(() => {
44
+ if (rCancelContextMenuSwallow.current === cancel) {
45
+ cancel();
46
+ rCancelContextMenuSwallow.current = null;
47
+ }
48
+ }, 0);
49
+ }, [editor]);
19
50
  const handlePointerDown = useCallback(
20
51
  (e) => {
21
- if (e.button === 0) {
22
- setIsPointing(true);
23
- rPointerState.current = {
24
- isDown: true,
25
- isDragging: false,
26
- start: new Vec(e.clientX, e.clientY)
27
- };
28
- rDidAPointerDownAndDragWhileMenuWasOpen.current = false;
29
- }
52
+ if (e.button !== 0 && e.button !== 2) return;
53
+ flushSync(() => setIsPointing(true));
54
+ setPointerCapture(e.currentTarget, e);
55
+ rPointerState.current = {
56
+ isDown: true,
57
+ isDragging: false,
58
+ button: e.button,
59
+ start: new Vec(e.clientX, e.clientY)
60
+ };
30
61
  if (e.button === 2) {
31
- const ownerDocument = editor.getContainerDocument();
32
- ownerDocument.addEventListener(
33
- "contextmenu",
34
- (event) => {
35
- event.preventDefault();
36
- event.stopImmediatePropagation();
37
- },
38
- { capture: true, once: true }
39
- );
62
+ if (!editor.options.rightClickPanning) {
63
+ swallowNextNativeContextMenu();
64
+ editor.menus.clearOpenMenus();
65
+ return;
66
+ }
67
+ const canvas = editor.getContainer().querySelector(".tl-canvas") ?? e.currentTarget;
68
+ canvasEvents.onPointerDown?.({ ...e, currentTarget: canvas });
69
+ swallowNextNativeContextMenu();
70
+ return;
40
71
  }
41
72
  editor.menus.clearOpenMenus();
42
73
  },
43
- [editor]
74
+ [canvasEvents, editor, swallowNextNativeContextMenu]
44
75
  );
45
- const rDidAPointerDownAndDragWhileMenuWasOpen = useRef(false);
46
76
  const handlePointerMove = useCallback(
47
77
  (e) => {
48
- if (!rPointerState.current.isDown) return;
49
- const { x, y } = rPointerState.current.start;
50
- if (!rDidAPointerDownAndDragWhileMenuWasOpen.current) {
51
- if (
52
- // We're pointing, but are we dragging?
53
- Vec.Dist2(rPointerState.current.start, new Vec(e.clientX, e.clientY)) > editor.options.dragDistanceSquared
54
- ) {
55
- rDidAPointerDownAndDragWhileMenuWasOpen.current = true;
56
- rPointerState.current = {
57
- ...rPointerState.current,
58
- isDown: true,
59
- isDragging: true
60
- };
61
- canvasEvents.onPointerDown?.({
62
- ...e,
63
- clientX: x,
64
- clientY: y,
65
- button: 0
66
- });
78
+ const state = rPointerState.current;
79
+ if (!state.isDown) return;
80
+ if (state.button !== 2 && !state.isDragging) {
81
+ if (Vec.Dist2(state.start, new Vec(e.clientX, e.clientY)) <= editor.options.dragDistanceSquared) {
82
+ return;
67
83
  }
68
- }
69
- if (rDidAPointerDownAndDragWhileMenuWasOpen.current) {
84
+ state.isDragging = true;
70
85
  editor.dispatch({
71
86
  type: "pointer",
72
87
  target: "canvas",
73
- name: "pointer_move",
74
- ...getPointerInfo(editor, e)
88
+ name: "pointer_down",
89
+ ...getPointerInfo(editor, { ...e, clientX: state.start.x, clientY: state.start.y })
75
90
  });
76
91
  }
92
+ editor.dispatch({
93
+ type: "pointer",
94
+ target: "canvas",
95
+ name: "pointer_move",
96
+ ...getPointerInfo(editor, e)
97
+ });
77
98
  },
78
- [canvasEvents, editor]
99
+ [editor]
79
100
  );
80
101
  const handlePointerUp = useCallback(
81
102
  (e) => {
82
- canvasEvents.onPointerUp?.(e);
103
+ const isStaticRightClick = e.button === 2 && !rPointerState.current.isDragging;
104
+ editor.dispatch({
105
+ type: "pointer",
106
+ target: "canvas",
107
+ name: "pointer_up",
108
+ ...getPointerInfo(editor, e)
109
+ });
110
+ if (isStaticRightClick && editor.options.rightClickPanning) {
111
+ const canvas = editor.getContainer().querySelector(".tl-canvas");
112
+ const trigger = canvas?.parentElement ?? e.currentTarget;
113
+ editor.timers.requestAnimationFrame(() => {
114
+ trigger.dispatchEvent(
115
+ new PointerEvent("contextmenu", {
116
+ bubbles: true,
117
+ clientX: e.clientX,
118
+ clientY: e.clientY,
119
+ button: 2,
120
+ buttons: 0,
121
+ pointerId: e.pointerId,
122
+ pointerType: e.pointerType,
123
+ isPrimary: e.isPrimary
124
+ })
125
+ );
126
+ });
127
+ }
128
+ releasePointerCapture(e.currentTarget, e);
83
129
  setIsPointing(false);
84
130
  rPointerState.current = {
85
131
  isDown: false,
86
132
  isDragging: false,
133
+ button: 0,
87
134
  start: new Vec(e.clientX, e.clientY)
88
135
  };
89
- rDidAPointerDownAndDragWhileMenuWasOpen.current = false;
90
136
  },
91
- [canvasEvents]
137
+ [editor]
92
138
  );
93
139
  return showElement && /* @__PURE__ */ jsx(
94
140
  "div",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/components/MenuClickCapture.tsx"],
4
- "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { PointerEvent, useCallback, useRef, useState } from 'react'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { Vec } from '../primitives/Vec'\nimport { getPointerInfo } from '../utils/getPointerInfo'\n\n/**\n * When a menu is open, this component prevents the user from interacting with the canvas.\n *\n * @public @react\n */\nexport function MenuClickCapture() {\n\tconst editor = useEditor()\n\n\t// Whether any menus are open\n\tconst isMenuOpen = useValue('is menu open', () => editor.menus.hasAnyOpenMenus(), [editor])\n\n\t// Whether we're pointing or not\u2014keep this component visible if we're pointing\n\tconst [isPointing, setIsPointing] = useState(false)\n\n\tconst showElement = isMenuOpen || isPointing\n\n\t// Get the same events that we use on the canvas\n\tconst canvasEvents = useCanvasEvents()\n\n\t// Keep track of the pointer state\n\tconst rPointerState = useRef({\n\t\tisDown: false,\n\t\tisDragging: false,\n\t\tstart: new Vec(),\n\t})\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tsetIsPointing(true)\n\t\t\t\trPointerState.current = {\n\t\t\t\t\tisDown: true,\n\t\t\t\t\tisDragging: false,\n\t\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t\t}\n\t\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = false\n\t\t\t}\n\t\t\tif (e.button === 2) {\n\t\t\t\t// Swallow the contextmenu event that follows this right-click pointerdown.\n\t\t\t\t// clearOpenMenus() below triggers a synchronous render that unmounts this\n\t\t\t\t// component, so our React onContextMenu handler won't be around to catch it.\n\t\t\t\t// Without this, the contextmenu event reaches the Radix Trigger and briefly\n\t\t\t\t// opens a new context menu (which then immediately dismisses \u2014 causing a flash).\n\t\t\t\tconst ownerDocument = editor.getContainerDocument()\n\t\t\t\townerDocument.addEventListener(\n\t\t\t\t\t'contextmenu',\n\t\t\t\t\t(event) => {\n\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\tevent.stopImmediatePropagation()\n\t\t\t\t\t},\n\t\t\t\t\t{ capture: true, once: true }\n\t\t\t\t)\n\t\t\t}\n\t\t\teditor.menus.clearOpenMenus()\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst rDidAPointerDownAndDragWhileMenuWasOpen = useRef(false)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\t// Do nothing unless we're pointing\n\t\t\tif (!rPointerState.current.isDown) return\n\n\t\t\t// call the onPointerDown with the original pointer position\n\t\t\tconst { x, y } = rPointerState.current.start\n\n\t\t\tif (!rDidAPointerDownAndDragWhileMenuWasOpen.current) {\n\t\t\t\tif (\n\t\t\t\t\t// We're pointing, but are we dragging?\n\t\t\t\t\tVec.Dist2(rPointerState.current.start, new Vec(e.clientX, e.clientY)) >\n\t\t\t\t\teditor.options.dragDistanceSquared\n\t\t\t\t) {\n\t\t\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = true\n\t\t\t\t\t// Wehaddaeventitsadrag\n\t\t\t\t\trPointerState.current = {\n\t\t\t\t\t\t...rPointerState.current,\n\t\t\t\t\t\tisDown: true,\n\t\t\t\t\t\tisDragging: true,\n\t\t\t\t\t}\n\t\t\t\t\tcanvasEvents.onPointerDown?.({\n\t\t\t\t\t\t...e,\n\t\t\t\t\t\tclientX: x,\n\t\t\t\t\t\tclientY: y,\n\t\t\t\t\t\tbutton: 0,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (rDidAPointerDownAndDragWhileMenuWasOpen.current) {\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_move',\n\t\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t\t})\n\t\t\t}\n\t\t},\n\t\t[canvasEvents, editor]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\t// Run the pointer up\n\t\t\tcanvasEvents.onPointerUp?.(e)\n\t\t\t// Then turn off pointing\n\t\t\tsetIsPointing(false)\n\t\t\t// Reset the pointer state\n\t\t\trPointerState.current = {\n\t\t\t\tisDown: false,\n\t\t\t\tisDragging: false,\n\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t}\n\t\t\trDidAPointerDownAndDragWhileMenuWasOpen.current = false\n\t\t},\n\t\t[canvasEvents]\n\t)\n\n\treturn (\n\t\tshowElement && (\n\t\t\t<div\n\t\t\t\tclassName=\"tlui-menu-click-capture\"\n\t\t\t\tdata-testid=\"menu-click-capture.content\"\n\t\t\t\t{...canvasEvents}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\tonContextMenu={(e) => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}}\n\t\t\t/>\n\t\t)\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useValue } from '@tldraw/state-react'\nimport { type PointerEvent, useCallback, useEffect, useRef, useState } from 'react'\nimport { flushSync } from 'react-dom'\nimport { useCanvasEvents } from '../hooks/useCanvasEvents'\nimport { useEditor } from '../hooks/useEditor'\nimport { Vec } from '../primitives/Vec'\nimport { releasePointerCapture, setPointerCapture } from '../utils/dom'\nimport { getPointerInfo } from '../utils/getPointerInfo'\n\n/**\n * When a menu is open, this component prevents the user from interacting with the canvas.\n *\n * @public @react\n */\nexport function MenuClickCapture() {\n\tconst editor = useEditor()\n\n\tconst isMenuOpen = useValue('is menu open', () => editor.menus.hasAnyOpenMenus(), [editor])\n\n\t// Keep this component mounted while the pointer is down so pointerup/move still\n\t// land here after a synchronous clearOpenMenus() flips isMenuOpen to false.\n\tconst [isPointing, setIsPointing] = useState(false)\n\tconst showElement = isMenuOpen || isPointing\n\n\tconst canvasEvents = useCanvasEvents()\n\n\tconst rPointerState = useRef({\n\t\tisDown: false,\n\t\tisDragging: false,\n\t\tbutton: 0,\n\t\tstart: new Vec(),\n\t})\n\n\t// Swallow the native contextmenu that follows a right-click pointerdown. Without\n\t// this, Radix's trigger catches the native event and opens a menu at the pointer-\n\t// DOWN position \u2014 then our own synthetic contextmenu (fired on pointerup) opens it\n\t// again at the release position, producing a visible flash.\n\tconst rCancelContextMenuSwallow = useRef<null | (() => void)>(null)\n\tuseEffect(\n\t\t() => () => {\n\t\t\trCancelContextMenuSwallow.current?.()\n\t\t\trCancelContextMenuSwallow.current = null\n\t\t},\n\t\t[]\n\t)\n\tconst swallowNextNativeContextMenu = useCallback(() => {\n\t\trCancelContextMenuSwallow.current?.()\n\t\tconst doc = editor.getContainerDocument()\n\t\tconst onContextMenu = (event: MouseEvent) => {\n\t\t\t// Skip our own synthetic contextmenu \u2014 only swallow the real browser one\n\t\t\tif (!event.isTrusted) return\n\t\t\trCancelContextMenuSwallow.current?.()\n\t\t\trCancelContextMenuSwallow.current = null\n\t\t\tevent.preventDefault()\n\t\t\tevent.stopImmediatePropagation()\n\t\t}\n\t\tconst cancel = () => doc.removeEventListener('contextmenu', onContextMenu, true)\n\t\trCancelContextMenuSwallow.current = cancel\n\t\tdoc.addEventListener('contextmenu', onContextMenu, true)\n\t\t// Drop the listener on the next tick if it never fires (e.g. pointer moved off-screen)\n\t\tdoc.defaultView?.setTimeout(() => {\n\t\t\tif (rCancelContextMenuSwallow.current === cancel) {\n\t\t\t\tcancel()\n\t\t\t\trCancelContextMenuSwallow.current = null\n\t\t\t}\n\t\t}, 0)\n\t}, [editor])\n\n\tconst handlePointerDown = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tif (e.button !== 0 && e.button !== 2) return\n\n\t\t\tflushSync(() => setIsPointing(true))\n\t\t\tsetPointerCapture(e.currentTarget, e)\n\t\t\trPointerState.current = {\n\t\t\t\tisDown: true,\n\t\t\t\tisDragging: false,\n\t\t\t\tbutton: e.button,\n\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t}\n\n\t\t\tif (e.button === 2) {\n\t\t\t\tif (!editor.options.rightClickPanning) {\n\t\t\t\t\t// Right-click panning off: close the open menu and swallow the native\n\t\t\t\t\t// contextmenu that would otherwise briefly open a new one (causing a flash).\n\t\t\t\t\tswallowNextNativeContextMenu()\n\t\t\t\t\teditor.menus.clearOpenMenus()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// Forward right-click pointerdown through the canvas's own handler so\n\t\t\t\t// pointer capture is also set on the canvas (load-bearing: without this\n\t\t\t\t// the context menu briefly flashes closed during consecutive right-clicks).\n\t\t\t\t// We don't clearOpenMenus() \u2014 Radix's DismissableLayer closes the menu\n\t\t\t\t// via outside-click detection, keeping its internal state in sync.\n\t\t\t\tconst canvas =\n\t\t\t\t\teditor.getContainer().querySelector<HTMLDivElement>('.tl-canvas') ?? e.currentTarget\n\t\t\t\tcanvasEvents.onPointerDown?.({ ...e, currentTarget: canvas })\n\t\t\t\tswallowNextNativeContextMenu()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\teditor.menus.clearOpenMenus()\n\t\t},\n\t\t[canvasEvents, editor, swallowNextNativeContextMenu]\n\t)\n\n\tconst handlePointerMove = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tconst state = rPointerState.current\n\t\t\tif (!state.isDown) return\n\n\t\t\t// Left-click: wait for the drag threshold before forwarding anything, then\n\t\t\t// replay pointerdown at the original start so the editor records the\n\t\t\t// correct drag origin. Right-click forwards moves immediately (pointerdown\n\t\t\t// was already dispatched in handlePointerDown).\n\t\t\tif (state.button !== 2 && !state.isDragging) {\n\t\t\t\tif (\n\t\t\t\t\tVec.Dist2(state.start, new Vec(e.clientX, e.clientY)) <=\n\t\t\t\t\teditor.options.dragDistanceSquared\n\t\t\t\t) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tstate.isDragging = true\n\t\t\t\teditor.dispatch({\n\t\t\t\t\ttype: 'pointer',\n\t\t\t\t\ttarget: 'canvas',\n\t\t\t\t\tname: 'pointer_down',\n\t\t\t\t\t...getPointerInfo(editor, { ...e, clientX: state.start.x, clientY: state.start.y }),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'pointer',\n\t\t\t\ttarget: 'canvas',\n\t\t\t\tname: 'pointer_move',\n\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t})\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst handlePointerUp = useCallback(\n\t\t(e: PointerEvent) => {\n\t\t\tconst isStaticRightClick = e.button === 2 && !rPointerState.current.isDragging\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'pointer',\n\t\t\t\ttarget: 'canvas',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\t...getPointerInfo(editor, e),\n\t\t\t})\n\n\t\t\tif (isStaticRightClick && editor.options.rightClickPanning) {\n\t\t\t\t// Dispatch contextmenu on the canvas's parent (Radix's trigger) so the\n\t\t\t\t// menu opens at the release position. Bypassing the canvas avoids its\n\t\t\t\t// own onContextMenu handler, which preventDefaults non-synthesized events.\n\t\t\t\tconst canvas = editor.getContainer().querySelector<HTMLDivElement>('.tl-canvas')\n\t\t\t\tconst trigger = canvas?.parentElement ?? e.currentTarget\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\ttrigger.dispatchEvent(\n\t\t\t\t\t\tnew PointerEvent('contextmenu', {\n\t\t\t\t\t\t\tbubbles: true,\n\t\t\t\t\t\t\tclientX: e.clientX,\n\t\t\t\t\t\t\tclientY: e.clientY,\n\t\t\t\t\t\t\tbutton: 2,\n\t\t\t\t\t\t\tbuttons: 0,\n\t\t\t\t\t\t\tpointerId: e.pointerId,\n\t\t\t\t\t\t\tpointerType: e.pointerType,\n\t\t\t\t\t\t\tisPrimary: e.isPrimary,\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treleasePointerCapture(e.currentTarget, e)\n\t\t\tsetIsPointing(false)\n\t\t\trPointerState.current = {\n\t\t\t\tisDown: false,\n\t\t\t\tisDragging: false,\n\t\t\t\tbutton: 0,\n\t\t\t\tstart: new Vec(e.clientX, e.clientY),\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\treturn (\n\t\tshowElement && (\n\t\t\t<div\n\t\t\t\tclassName=\"tlui-menu-click-capture\"\n\t\t\t\tdata-testid=\"menu-click-capture.content\"\n\t\t\t\t{...canvasEvents}\n\t\t\t\tonPointerDown={handlePointerDown}\n\t\t\t\tonPointerMove={handlePointerMove}\n\t\t\t\tonPointerUp={handlePointerUp}\n\t\t\t\tonContextMenu={(e) => {\n\t\t\t\t\te.preventDefault()\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t}}\n\t\t\t/>\n\t\t)\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,160 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { EffectScheduler, computed } from "@tldraw/state";
3
+ import { memo, useEffect, useRef } from "react";
4
+ import { useEditor } from "../../hooks/useEditor.mjs";
5
+ import { Group2d } from "../../primitives/geometry/Group2d.mjs";
6
+ import { debugFlags } from "../../utils/debug-flags.mjs";
7
+ const CanvasOverlays = memo(function CanvasOverlays2() {
8
+ const editor = useEditor();
9
+ const canvasRef = useRef(null);
10
+ useEffect(() => {
11
+ const renderInputs$ = computed(
12
+ "canvas overlays render inputs",
13
+ () => {
14
+ const instance = editor.getInstanceState();
15
+ const camera = editor.getCamera();
16
+ return {
17
+ dpr: instance.devicePixelRatio,
18
+ w: instance.screenBounds.w,
19
+ h: instance.screenBounds.h,
20
+ cx: camera.x,
21
+ cy: camera.y,
22
+ zoom: camera.z
23
+ };
24
+ },
25
+ {
26
+ isEqual: (a, b) => a.dpr === b.dpr && a.w === b.w && a.h === b.h && a.cx === b.cx && a.cy === b.cy && a.zoom === b.zoom
27
+ }
28
+ );
29
+ const scheduler = new EffectScheduler("canvas overlays render", () => {
30
+ const canvas = canvasRef.current;
31
+ if (!canvas) return;
32
+ const ctx = canvas.getContext("2d");
33
+ if (!ctx) return;
34
+ const { dpr, w, h, cx, cy, zoom } = renderInputs$.get();
35
+ const canvasWidth = Math.ceil(w * dpr);
36
+ const canvasHeight = Math.ceil(h * dpr);
37
+ if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {
38
+ canvas.width = canvasWidth;
39
+ canvas.height = canvasHeight;
40
+ canvas.style.width = `${w}px`;
41
+ canvas.style.height = `${h}px`;
42
+ }
43
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
44
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
45
+ const s = dpr * zoom;
46
+ ctx.setTransform(s, 0, 0, s, s * cx, s * cy);
47
+ for (const { util, overlays } of editor.overlays.getActiveOverlayEntries()) {
48
+ ctx.save();
49
+ util.render(ctx, overlays);
50
+ ctx.restore();
51
+ }
52
+ if (debugFlags.debugGeometry.get()) {
53
+ const currentPagePoint = editor.inputs.getCurrentPagePoint();
54
+ const renderingShapes = editor.getRenderingShapes();
55
+ for (const result of renderingShapes) {
56
+ const shape = editor.getShape(result.id);
57
+ if (!shape || shape.type === "group") continue;
58
+ const geometry = editor.getShapeGeometry(shape);
59
+ const pageTransform = editor.getShapePageTransform(shape);
60
+ if (!pageTransform) continue;
61
+ ctx.save();
62
+ const m = pageTransform;
63
+ ctx.transform(m.a, m.b, m.c, m.d, m.e, m.f);
64
+ ctx.strokeStyle = geometry.debugColor ?? "red";
65
+ ctx.lineWidth = 2 / zoom;
66
+ ctx.fillStyle = "none";
67
+ drawGeometryStroke(ctx, geometry);
68
+ const { vertices } = geometry;
69
+ for (let i = 0; i < vertices.length; i++) {
70
+ const v = vertices[i];
71
+ const hue = vertices.length > 1 ? 120 + (200 - 120) * i / (vertices.length - 1) : 160;
72
+ ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
73
+ ctx.strokeStyle = "black";
74
+ ctx.lineWidth = 1 / zoom;
75
+ ctx.beginPath();
76
+ ctx.arc(v.x, v.y, 2 / zoom, 0, Math.PI * 2);
77
+ ctx.fill();
78
+ ctx.stroke();
79
+ }
80
+ const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint);
81
+ const dist = Math.abs(geometry.distanceToPoint(pointInShapeSpace, true)) * zoom;
82
+ if (dist < 150) {
83
+ const nearestPoint = geometry.nearestPoint(pointInShapeSpace);
84
+ const hitInside = geometry.distanceToPoint(pointInShapeSpace, true) < 0;
85
+ ctx.strokeStyle = hitInside ? "goldenrod" : "dodgerblue";
86
+ ctx.lineWidth = 2 / zoom;
87
+ ctx.globalAlpha = 1 - dist / 150;
88
+ ctx.beginPath();
89
+ ctx.moveTo(nearestPoint.x, nearestPoint.y);
90
+ ctx.lineTo(pointInShapeSpace.x, pointInShapeSpace.y);
91
+ ctx.stroke();
92
+ ctx.globalAlpha = 1;
93
+ }
94
+ ctx.restore();
95
+ }
96
+ ctx.save();
97
+ ctx.strokeStyle = "magenta";
98
+ ctx.fillStyle = "rgba(255, 0, 255, 0.1)";
99
+ ctx.lineWidth = 1 / zoom;
100
+ for (const { overlays } of editor.overlays.getActiveOverlayEntries()) {
101
+ for (const overlay of overlays) {
102
+ const geometry = editor.overlays.getOverlayGeometry(overlay);
103
+ if (!geometry) continue;
104
+ const vertices = geometry.vertices;
105
+ if (vertices.length < 2) continue;
106
+ ctx.beginPath();
107
+ ctx.moveTo(vertices[0].x, vertices[0].y);
108
+ for (let i = 1; i < vertices.length; i++) {
109
+ ctx.lineTo(vertices[i].x, vertices[i].y);
110
+ }
111
+ if (geometry.isClosed) {
112
+ ctx.closePath();
113
+ ctx.fill();
114
+ }
115
+ ctx.stroke();
116
+ for (const v of vertices) {
117
+ ctx.beginPath();
118
+ ctx.arc(v.x, v.y, 2 / zoom, 0, Math.PI * 2);
119
+ ctx.fill();
120
+ }
121
+ }
122
+ }
123
+ ctx.restore();
124
+ }
125
+ });
126
+ scheduler.attach();
127
+ scheduler.execute();
128
+ return () => scheduler.detach();
129
+ }, [editor]);
130
+ return /* @__PURE__ */ jsx("canvas", { ref: canvasRef, className: "tl-canvas-overlays" });
131
+ });
132
+ function drawGeometryStroke(ctx, geometry) {
133
+ if (geometry instanceof Group2d) {
134
+ const prevStroke = ctx.strokeStyle;
135
+ for (const child of geometry.children) {
136
+ if (child.debugColor) ctx.strokeStyle = child.debugColor;
137
+ drawGeometryStroke(ctx, child);
138
+ ctx.strokeStyle = prevStroke;
139
+ }
140
+ for (const child of geometry.ignoredChildren) {
141
+ if (child.debugColor) ctx.strokeStyle = child.debugColor;
142
+ drawGeometryStroke(ctx, child);
143
+ ctx.strokeStyle = prevStroke;
144
+ }
145
+ return;
146
+ }
147
+ const vertices = geometry.vertices;
148
+ if (vertices.length < 2) return;
149
+ ctx.beginPath();
150
+ ctx.moveTo(vertices[0].x, vertices[0].y);
151
+ for (let i = 1; i < vertices.length; i++) {
152
+ ctx.lineTo(vertices[i].x, vertices[i].y);
153
+ }
154
+ if (geometry.isClosed) ctx.closePath();
155
+ ctx.stroke();
156
+ }
157
+ export {
158
+ CanvasOverlays
159
+ };
160
+ //# sourceMappingURL=CanvasOverlays.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/lib/components/default-components/CanvasOverlays.tsx"],
4
+ "sourcesContent": ["import { EffectScheduler, computed } from '@tldraw/state'\nimport { memo, useEffect, useRef } from 'react'\nimport { useEditor } from '../../hooks/useEditor'\nimport { Geometry2d } from '../../primitives/geometry/Geometry2d'\nimport { Group2d } from '../../primitives/geometry/Group2d'\nimport { debugFlags } from '../../utils/debug-flags'\n\ninterface RenderInputs {\n\tdpr: number\n\tw: number\n\th: number\n\tcx: number\n\tcy: number\n\tzoom: number\n}\n\n/** @internal @react */\nexport const CanvasOverlays = memo(function CanvasOverlays() {\n\tconst editor = useEditor()\n\tconst canvasRef = useRef<HTMLCanvasElement>(null)\n\n\tuseEffect(() => {\n\t\t// Bundle the primitive scalars the renderer needs into one computed so the\n\t\t// effect only refires on actual visual change. Reading the whole instance\n\t\t// state directly would otherwise wake the renderer on every cursor move,\n\t\t// brush update, etc.\n\n\t\tconst renderInputs$ = computed<RenderInputs>(\n\t\t\t'canvas overlays render inputs',\n\t\t\t() => {\n\t\t\t\tconst instance = editor.getInstanceState()\n\t\t\t\tconst camera = editor.getCamera()\n\t\t\t\treturn {\n\t\t\t\t\tdpr: instance.devicePixelRatio,\n\t\t\t\t\tw: instance.screenBounds.w,\n\t\t\t\t\th: instance.screenBounds.h,\n\t\t\t\t\tcx: camera.x,\n\t\t\t\t\tcy: camera.y,\n\t\t\t\t\tzoom: camera.z,\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tisEqual: (a, b) =>\n\t\t\t\t\ta.dpr === b.dpr &&\n\t\t\t\t\ta.w === b.w &&\n\t\t\t\t\ta.h === b.h &&\n\t\t\t\t\ta.cx === b.cx &&\n\t\t\t\t\ta.cy === b.cy &&\n\t\t\t\t\ta.zoom === b.zoom,\n\t\t\t}\n\t\t)\n\n\t\tconst scheduler = new EffectScheduler('canvas overlays render', () => {\n\t\t\tconst canvas = canvasRef.current\n\t\t\tif (!canvas) return\n\n\t\t\tconst ctx = canvas.getContext('2d')\n\t\t\tif (!ctx) return\n\n\t\t\tconst { dpr, w, h, cx, cy, zoom } = renderInputs$.get()\n\n\t\t\tconst canvasWidth = Math.ceil(w * dpr)\n\t\t\tconst canvasHeight = Math.ceil(h * dpr)\n\n\t\t\tif (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {\n\t\t\t\tcanvas.width = canvasWidth\n\t\t\t\tcanvas.height = canvasHeight\n\t\t\t\tcanvas.style.width = `${w}px`\n\t\t\t\tcanvas.style.height = `${h}px`\n\t\t\t}\n\n\t\t\tctx.setTransform(1, 0, 0, 1, 0, 0)\n\t\t\tctx.clearRect(0, 0, canvas.width, canvas.height)\n\n\t\t\t// One setTransform = DPR scale * zoom scale * camera translate, into page space.\n\t\t\tconst s = dpr * zoom\n\t\t\tctx.setTransform(s, 0, 0, s, s * cx, s * cy)\n\n\t\t\t// Render all active overlay utils in zIndex order (low to high).\n\t\t\tfor (const { util, overlays } of editor.overlays.getActiveOverlayEntries()) {\n\t\t\t\tctx.save()\n\t\t\t\tutil.render(ctx, overlays)\n\t\t\t\tctx.restore()\n\t\t\t}\n\n\t\t\t// Debug: draw all geometry\n\t\t\tif (debugFlags.debugGeometry.get()) {\n\t\t\t\tconst currentPagePoint = editor.inputs.getCurrentPagePoint()\n\n\t\t\t\t// Shape geometries\n\t\t\t\tconst renderingShapes = editor.getRenderingShapes()\n\t\t\t\tfor (const result of renderingShapes) {\n\t\t\t\t\tconst shape = editor.getShape(result.id)\n\t\t\t\t\tif (!shape || shape.type === 'group') continue\n\n\t\t\t\t\tconst geometry = editor.getShapeGeometry(shape)\n\t\t\t\t\tconst pageTransform = editor.getShapePageTransform(shape)\n\t\t\t\t\tif (!pageTransform) continue\n\n\t\t\t\t\tctx.save()\n\t\t\t\t\tconst m = pageTransform\n\t\t\t\t\tctx.transform(m.a, m.b, m.c, m.d, m.e, m.f)\n\n\t\t\t\t\t// Outline\n\t\t\t\t\tctx.strokeStyle = geometry.debugColor ?? 'red'\n\t\t\t\t\tctx.lineWidth = 2 / zoom\n\t\t\t\t\tctx.fillStyle = 'none'\n\t\t\t\t\tdrawGeometryStroke(ctx, geometry)\n\n\t\t\t\t\t// Vertices\n\t\t\t\t\tconst { vertices } = geometry\n\t\t\t\t\tfor (let i = 0; i < vertices.length; i++) {\n\t\t\t\t\t\tconst v = vertices[i]\n\t\t\t\t\t\tconst hue = vertices.length > 1 ? 120 + ((200 - 120) * i) / (vertices.length - 1) : 160\n\t\t\t\t\t\tctx.fillStyle = `hsl(${hue}, 100%, 50%)`\n\t\t\t\t\t\tctx.strokeStyle = 'black'\n\t\t\t\t\t\tctx.lineWidth = 1 / zoom\n\t\t\t\t\t\tctx.beginPath()\n\t\t\t\t\t\tctx.arc(v.x, v.y, 2 / zoom, 0, Math.PI * 2)\n\t\t\t\t\t\tctx.fill()\n\t\t\t\t\t\tctx.stroke()\n\t\t\t\t\t}\n\n\t\t\t\t\t// Nearest point line\n\t\t\t\t\tconst pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint)\n\t\t\t\t\tconst dist = Math.abs(geometry.distanceToPoint(pointInShapeSpace, true)) * zoom\n\t\t\t\t\tif (dist < 150) {\n\t\t\t\t\t\tconst nearestPoint = geometry.nearestPoint(pointInShapeSpace)\n\t\t\t\t\t\tconst hitInside = geometry.distanceToPoint(pointInShapeSpace, true) < 0\n\t\t\t\t\t\tctx.strokeStyle = hitInside ? 'goldenrod' : 'dodgerblue'\n\t\t\t\t\t\tctx.lineWidth = 2 / zoom\n\t\t\t\t\t\tctx.globalAlpha = 1 - dist / 150\n\t\t\t\t\t\tctx.beginPath()\n\t\t\t\t\t\tctx.moveTo(nearestPoint.x, nearestPoint.y)\n\t\t\t\t\t\tctx.lineTo(pointInShapeSpace.x, pointInShapeSpace.y)\n\t\t\t\t\t\tctx.stroke()\n\t\t\t\t\t\tctx.globalAlpha = 1\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore()\n\t\t\t\t}\n\n\t\t\t\t// Overlay hit-test geometries\n\t\t\t\tctx.save()\n\t\t\t\tctx.strokeStyle = 'magenta'\n\t\t\t\tctx.fillStyle = 'rgba(255, 0, 255, 0.1)'\n\t\t\t\tctx.lineWidth = 1 / zoom\n\t\t\t\tfor (const { overlays } of editor.overlays.getActiveOverlayEntries()) {\n\t\t\t\t\tfor (const overlay of overlays) {\n\t\t\t\t\t\tconst geometry = editor.overlays.getOverlayGeometry(overlay)\n\t\t\t\t\t\tif (!geometry) continue\n\t\t\t\t\t\tconst vertices = geometry.vertices\n\t\t\t\t\t\tif (vertices.length < 2) continue\n\t\t\t\t\t\tctx.beginPath()\n\t\t\t\t\t\tctx.moveTo(vertices[0].x, vertices[0].y)\n\t\t\t\t\t\tfor (let i = 1; i < vertices.length; i++) {\n\t\t\t\t\t\t\tctx.lineTo(vertices[i].x, vertices[i].y)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (geometry.isClosed) {\n\t\t\t\t\t\t\tctx.closePath()\n\t\t\t\t\t\t\tctx.fill()\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.stroke()\n\t\t\t\t\t\tfor (const v of vertices) {\n\t\t\t\t\t\t\tctx.beginPath()\n\t\t\t\t\t\t\tctx.arc(v.x, v.y, 2 / zoom, 0, Math.PI * 2)\n\t\t\t\t\t\t\tctx.fill()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tctx.restore()\n\t\t\t}\n\t\t})\n\n\t\tscheduler.attach()\n\t\tscheduler.execute()\n\t\treturn () => scheduler.detach()\n\t}, [editor])\n\n\treturn <canvas ref={canvasRef} className=\"tl-canvas-overlays\" />\n})\n\nfunction drawGeometryStroke(ctx: CanvasRenderingContext2D, geometry: Geometry2d) {\n\tif (geometry instanceof Group2d) {\n\t\tconst prevStroke = ctx.strokeStyle\n\t\tfor (const child of geometry.children) {\n\t\t\tif (child.debugColor) ctx.strokeStyle = child.debugColor\n\t\t\tdrawGeometryStroke(ctx, child)\n\t\t\tctx.strokeStyle = prevStroke\n\t\t}\n\t\tfor (const child of geometry.ignoredChildren) {\n\t\t\tif (child.debugColor) ctx.strokeStyle = child.debugColor\n\t\t\tdrawGeometryStroke(ctx, child)\n\t\t\tctx.strokeStyle = prevStroke\n\t\t}\n\t\treturn\n\t}\n\n\tconst vertices = geometry.vertices\n\tif (vertices.length < 2) return\n\tctx.beginPath()\n\tctx.moveTo(vertices[0].x, vertices[0].y)\n\tfor (let i = 1; i < vertices.length; i++) {\n\t\tctx.lineTo(vertices[i].x, vertices[i].y)\n\t}\n\tif (geometry.isClosed) ctx.closePath()\n\tctx.stroke()\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["CanvasOverlays"]
7
+ }