tldraw 4.2.2 → 4.2.3

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 (621) hide show
  1. package/dist-cjs/index.d.ts +242 -311
  2. package/dist-cjs/index.js +5 -13
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
  5. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +4 -7
  6. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  7. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -5
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  10. package/dist-cjs/lib/defaultSideEffects.js +1 -6
  11. package/dist-cjs/lib/defaultSideEffects.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +13 -14
  13. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  15. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +1 -1
  16. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  17. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  18. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  19. package/dist-cjs/lib/shapes/arrow/elbow/elbowArrowSnapLines.js.map +2 -2
  20. package/dist-cjs/lib/shapes/arrow/shared.js.map +2 -2
  21. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js +10 -4
  22. package/dist-cjs/lib/shapes/arrow/toolStates/Idle.js.map +2 -2
  23. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +4 -7
  24. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  25. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +1 -1
  26. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  27. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  28. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +22 -24
  29. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/draw/getPath.js +11 -20
  31. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  32. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +86 -82
  33. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +3 -3
  34. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +0 -6
  35. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +1 -1
  37. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +5 -6
  38. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +142 -146
  40. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  41. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js +10 -5
  42. package/dist-cjs/lib/shapes/geo/toolStates/Idle.js.map +2 -2
  43. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -3
  44. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  45. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +21 -23
  46. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  47. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +3 -3
  48. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  49. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +11 -6
  50. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  51. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  52. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +10 -5
  53. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  54. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +2 -3
  55. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  56. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +2 -14
  57. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +3 -3
  58. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +4 -12
  59. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +3 -3
  60. package/dist-cjs/lib/shapes/shared/ShapeFill.js +2 -2
  61. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  62. package/dist-cjs/lib/shapes/shared/crop.js +0 -1
  63. package/dist-cjs/lib/shapes/shared/crop.js.map +2 -2
  64. package/dist-cjs/lib/shapes/shared/interpolate-props.js +3 -3
  65. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  66. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  67. package/dist-cjs/lib/shapes/shared/useEditableRichText.js.map +2 -2
  68. package/dist-cjs/lib/shapes/shared/{useEfficientZoomThreshold.js → useForceSolid.js} +7 -10
  69. package/dist-cjs/lib/shapes/shared/useForceSolid.js.map +7 -0
  70. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +1 -1
  71. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  72. package/dist-cjs/lib/shapes/text/RichTextArea.js +0 -5
  73. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  74. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -5
  75. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  76. package/dist-cjs/lib/shapes/text/toolStates/Idle.js +10 -4
  77. package/dist-cjs/lib/shapes/text/toolStates/Idle.js.map +2 -2
  78. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +5 -7
  79. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  80. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  81. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
  82. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +5 -4
  83. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  84. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +4 -2
  85. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  86. package/dist-cjs/lib/tools/HandTool/HandTool.js +5 -3
  87. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  88. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +2 -3
  89. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  90. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js +1 -1
  91. package/dist-cjs/lib/tools/HandTool/childStates/Pointing.js.map +2 -2
  92. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js +1 -1
  93. package/dist-cjs/lib/tools/LaserTool/childStates/Lasering.js.map +2 -2
  94. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js +11 -10
  95. package/dist-cjs/lib/tools/SelectTool/DragAndDropManager.js.map +2 -2
  96. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js +5 -6
  97. package/dist-cjs/lib/tools/SelectTool/childStates/Brushing.js.map +2 -2
  98. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +6 -4
  99. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  100. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  101. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  102. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +1 -1
  103. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
  104. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +1 -1
  105. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  106. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js +1 -2
  107. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.js.map +2 -2
  108. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js +1 -1
  109. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.js.map +2 -2
  110. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +6 -8
  111. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  112. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js +11 -38
  113. package/dist-cjs/lib/tools/SelectTool/childStates/EditingShape.js.map +2 -2
  114. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +50 -42
  115. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  116. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +6 -6
  117. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  118. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js +1 -1
  119. package/dist-cjs/lib/tools/SelectTool/childStates/PointingCanvas.js.map +2 -2
  120. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js +14 -4
  121. package/dist-cjs/lib/tools/SelectTool/childStates/PointingHandle.js.map +2 -2
  122. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +1 -1
  123. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  124. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +1 -1
  125. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  126. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js +2 -2
  127. package/dist-cjs/lib/tools/SelectTool/childStates/PointingSelection.js.map +2 -2
  128. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +13 -4
  129. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  130. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +6 -5
  131. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  132. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +3 -2
  133. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  134. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js +6 -7
  135. package/dist-cjs/lib/tools/SelectTool/childStates/ScribbleBrushing.js.map +2 -2
  136. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +11 -13
  137. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  138. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js +4 -15
  139. package/dist-cjs/lib/tools/SelectTool/selectHelpers.js.map +2 -2
  140. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js +1 -1
  141. package/dist-cjs/lib/tools/ZoomTool/ZoomTool.js.map +2 -2
  142. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js +3 -3
  143. package/dist-cjs/lib/tools/ZoomTool/childStates/Pointing.js.map +2 -2
  144. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js +6 -5
  145. package/dist-cjs/lib/tools/ZoomTool/childStates/ZoomBrushing.js.map +2 -2
  146. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js +3 -1
  147. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  148. package/dist-cjs/lib/{utils/test-helpers.js → tools/selection-logic/getShouldEnterCropModeOnPointerDown.js} +8 -21
  149. package/dist-cjs/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.js.map +7 -0
  150. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js +1 -1
  151. package/dist-cjs/lib/tools/selection-logic/selectOnCanvasPointerUp.js.map +2 -2
  152. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js +1 -1
  153. package/dist-cjs/lib/tools/selection-logic/updateHoveredShapeId.js.map +2 -2
  154. package/dist-cjs/lib/ui/TldrawUi.js +2 -2
  155. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  156. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js +9 -3
  157. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js.map +2 -2
  158. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +3 -1
  159. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  160. package/dist-cjs/lib/ui/components/CursorChatBubble.js +1 -1
  161. package/dist-cjs/lib/ui/components/CursorChatBubble.js.map +2 -2
  162. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js +21 -1
  163. package/dist-cjs/lib/ui/components/DefaultDebugPanel.js.map +2 -2
  164. package/dist-cjs/lib/ui/components/EditLinkDialog.js +1 -11
  165. package/dist-cjs/lib/ui/components/EditLinkDialog.js.map +2 -2
  166. package/dist-cjs/lib/ui/components/HelperButtons/StopFollowing.js.map +2 -2
  167. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
  168. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  169. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +15 -2
  170. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js.map +3 -3
  171. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js +1 -3
  172. package/dist-cjs/lib/ui/components/PageMenu/PageItemInput.js.map +2 -2
  173. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +0 -6
  174. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
  175. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  176. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js +1 -1
  177. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js.map +2 -2
  178. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js +1 -1
  179. package/dist-cjs/lib/ui/components/Toolbar/DefaultRichTextToolbar.js.map +2 -2
  180. package/dist-cjs/lib/ui/components/TopPanel/CenteredTopPanelContainer.js.map +1 -1
  181. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js +32 -0
  182. package/dist-cjs/lib/ui/components/TopPanel/DefaultTopPanel.js.map +7 -0
  183. package/dist-cjs/lib/ui/components/menu-items.js +1 -3
  184. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  185. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -3
  186. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  187. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  188. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  189. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +93 -149
  190. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  191. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.js.map +2 -2
  192. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.js.map +2 -2
  193. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +1 -1
  194. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  195. package/dist-cjs/lib/ui/context/actions.js +8 -7
  196. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  197. package/dist-cjs/lib/ui/context/components.js +2 -1
  198. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  199. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  200. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +2 -2
  201. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  202. package/dist-cjs/lib/ui/hooks/useFlatten.js.map +2 -2
  203. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
  204. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  205. package/dist-cjs/lib/ui/hooks/useTools.js +5 -4
  206. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  207. package/dist-cjs/lib/ui/version.js +3 -3
  208. package/dist-cjs/lib/ui/version.js.map +1 -1
  209. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +6 -16
  210. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  211. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  212. package/dist-cjs/lib/utils/frames/frames.js.map +2 -2
  213. package/dist-cjs/lib/utils/text/richText.js +2 -4
  214. package/dist-cjs/lib/utils/text/richText.js.map +2 -2
  215. package/dist-cjs/lib/utils/text/textDirection.js +51 -0
  216. package/dist-cjs/lib/utils/text/textDirection.js.map +7 -0
  217. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +2 -7
  218. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  219. package/dist-esm/index.d.mts +242 -311
  220. package/dist-esm/index.mjs +5 -14
  221. package/dist-esm/index.mjs.map +2 -2
  222. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  223. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +4 -8
  224. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  225. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  226. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -5
  227. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  228. package/dist-esm/lib/defaultSideEffects.mjs +1 -6
  229. package/dist-esm/lib/defaultSideEffects.mjs.map +2 -2
  230. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +15 -15
  231. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  232. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +1 -1
  233. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  234. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  235. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  236. package/dist-esm/lib/shapes/arrow/elbow/elbowArrowSnapLines.mjs.map +2 -2
  237. package/dist-esm/lib/shapes/arrow/shared.mjs.map +2 -2
  238. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs +10 -4
  239. package/dist-esm/lib/shapes/arrow/toolStates/Idle.mjs.map +2 -2
  240. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +4 -7
  241. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  242. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +1 -1
  243. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  244. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  245. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +24 -29
  246. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  247. package/dist-esm/lib/shapes/draw/getPath.mjs +11 -21
  248. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  249. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +86 -83
  250. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +3 -3
  251. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +0 -6
  252. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  253. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +1 -1
  254. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +5 -6
  255. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  256. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +142 -147
  257. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  258. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs +10 -5
  259. package/dist-esm/lib/shapes/geo/toolStates/Idle.mjs.map +2 -2
  260. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +3 -3
  261. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  262. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +22 -24
  263. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  264. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +3 -3
  265. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  266. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +12 -7
  267. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  268. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  269. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +10 -5
  270. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  271. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +3 -4
  272. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  273. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +2 -14
  274. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  275. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -12
  276. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  277. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +2 -2
  278. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  279. package/dist-esm/lib/shapes/shared/crop.mjs +0 -1
  280. package/dist-esm/lib/shapes/shared/crop.mjs.map +2 -2
  281. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +4 -4
  282. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  283. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  284. package/dist-esm/lib/shapes/shared/useEditableRichText.mjs.map +2 -2
  285. package/dist-esm/lib/shapes/shared/useForceSolid.mjs +9 -0
  286. package/dist-esm/lib/shapes/shared/useForceSolid.mjs.map +7 -0
  287. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +1 -1
  288. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  289. package/dist-esm/lib/shapes/text/RichTextArea.mjs +0 -5
  290. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  291. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +2 -5
  292. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  293. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs +10 -4
  294. package/dist-esm/lib/shapes/text/toolStates/Idle.mjs.map +2 -2
  295. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +5 -7
  296. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  297. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +1 -1
  298. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
  299. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +5 -4
  300. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  301. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +8 -3
  302. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  303. package/dist-esm/lib/tools/HandTool/HandTool.mjs +5 -3
  304. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  305. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +2 -3
  306. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  307. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs +1 -1
  308. package/dist-esm/lib/tools/HandTool/childStates/Pointing.mjs.map +2 -2
  309. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs +1 -1
  310. package/dist-esm/lib/tools/LaserTool/childStates/Lasering.mjs.map +2 -2
  311. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs +11 -10
  312. package/dist-esm/lib/tools/SelectTool/DragAndDropManager.mjs.map +2 -2
  313. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs +5 -6
  314. package/dist-esm/lib/tools/SelectTool/childStates/Brushing.mjs.map +2 -2
  315. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +6 -4
  316. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  317. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  318. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  319. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +1 -1
  320. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
  321. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +1 -1
  322. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  323. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs +1 -2
  324. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.mjs.map +2 -2
  325. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs +1 -1
  326. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.mjs.map +2 -2
  327. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +6 -8
  328. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  329. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs +11 -38
  330. package/dist-esm/lib/tools/SelectTool/childStates/EditingShape.mjs.map +2 -2
  331. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +51 -43
  332. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  333. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +6 -6
  334. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  335. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs +1 -1
  336. package/dist-esm/lib/tools/SelectTool/childStates/PointingCanvas.mjs.map +2 -2
  337. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs +19 -6
  338. package/dist-esm/lib/tools/SelectTool/childStates/PointingHandle.mjs.map +2 -2
  339. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +1 -1
  340. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  341. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +1 -1
  342. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  343. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs +2 -2
  344. package/dist-esm/lib/tools/SelectTool/childStates/PointingSelection.mjs.map +2 -2
  345. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +13 -4
  346. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  347. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +6 -5
  348. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  349. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +3 -2
  350. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  351. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs +6 -7
  352. package/dist-esm/lib/tools/SelectTool/childStates/ScribbleBrushing.mjs.map +2 -2
  353. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +11 -13
  354. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  355. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs +4 -17
  356. package/dist-esm/lib/tools/SelectTool/selectHelpers.mjs.map +2 -2
  357. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs +1 -1
  358. package/dist-esm/lib/tools/ZoomTool/ZoomTool.mjs.map +2 -2
  359. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs +3 -3
  360. package/dist-esm/lib/tools/ZoomTool/childStates/Pointing.mjs.map +2 -2
  361. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs +6 -5
  362. package/dist-esm/lib/tools/ZoomTool/childStates/ZoomBrushing.mjs.map +2 -2
  363. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs +3 -1
  364. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  365. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs +8 -0
  366. package/dist-esm/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.mjs.map +7 -0
  367. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs +1 -1
  368. package/dist-esm/lib/tools/selection-logic/selectOnCanvasPointerUp.mjs.map +2 -2
  369. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs +1 -1
  370. package/dist-esm/lib/tools/selection-logic/updateHoveredShapeId.mjs.map +2 -2
  371. package/dist-esm/lib/ui/TldrawUi.mjs +2 -2
  372. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  373. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs +8 -2
  374. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs.map +2 -2
  375. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +3 -1
  376. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  377. package/dist-esm/lib/ui/components/CursorChatBubble.mjs +1 -1
  378. package/dist-esm/lib/ui/components/CursorChatBubble.mjs.map +2 -2
  379. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs +30 -3
  380. package/dist-esm/lib/ui/components/DefaultDebugPanel.mjs.map +2 -2
  381. package/dist-esm/lib/ui/components/EditLinkDialog.mjs +1 -11
  382. package/dist-esm/lib/ui/components/EditLinkDialog.mjs.map +2 -2
  383. package/dist-esm/lib/ui/components/HelperButtons/StopFollowing.mjs.map +2 -2
  384. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -1
  385. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  386. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs +6 -3
  387. package/dist-esm/lib/ui/components/OfflineIndicator/OfflineIndicator.mjs.map +2 -2
  388. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs +1 -3
  389. package/dist-esm/lib/ui/components/PageMenu/PageItemInput.mjs.map +2 -2
  390. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +0 -6
  391. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
  392. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  393. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs +1 -1
  394. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs.map +2 -2
  395. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs +1 -1
  396. package/dist-esm/lib/ui/components/Toolbar/DefaultRichTextToolbar.mjs.map +2 -2
  397. package/dist-esm/lib/ui/components/TopPanel/CenteredTopPanelContainer.mjs.map +1 -1
  398. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs +12 -0
  399. package/dist-esm/lib/ui/components/TopPanel/DefaultTopPanel.mjs.map +7 -0
  400. package/dist-esm/lib/ui/components/menu-items.mjs +5 -4
  401. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  402. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -3
  403. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  404. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -2
  405. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  406. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +95 -157
  407. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  408. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.mjs.map +2 -2
  409. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.mjs.map +2 -2
  410. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -2
  411. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  412. package/dist-esm/lib/ui/context/actions.mjs +8 -7
  413. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  414. package/dist-esm/lib/ui/context/components.mjs +2 -1
  415. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  416. package/dist-esm/lib/ui/hooks/menu-hooks.mjs +4 -1
  417. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  418. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  419. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  420. package/dist-esm/lib/ui/hooks/useFlatten.mjs.map +2 -2
  421. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
  422. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  423. package/dist-esm/lib/ui/hooks/useTools.mjs +5 -4
  424. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  425. package/dist-esm/lib/ui/version.mjs +3 -3
  426. package/dist-esm/lib/ui/version.mjs.map +1 -1
  427. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +6 -17
  428. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  429. package/dist-esm/lib/utils/export/exportAs.mjs +3 -1
  430. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  431. package/dist-esm/lib/utils/frames/frames.mjs.map +2 -2
  432. package/dist-esm/lib/utils/text/richText.mjs +2 -5
  433. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  434. package/dist-esm/lib/utils/text/textDirection.mjs +31 -0
  435. package/dist-esm/lib/utils/text/textDirection.mjs.map +7 -0
  436. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +2 -8
  437. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  438. package/package.json +16 -18
  439. package/src/index.ts +2 -6
  440. package/src/lib/Tldraw.test.tsx +1 -46
  441. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +1 -1
  442. package/src/lib/canvas/TldrawSelectionForeground.tsx +9 -20
  443. package/src/lib/defaultEmbedDefinitions.ts +0 -1
  444. package/src/lib/defaultExternalContentHandlers.ts +14 -13
  445. package/src/lib/defaultSideEffects.ts +1 -6
  446. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +133 -40
  447. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +8 -8
  448. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +2 -2
  449. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +16 -16
  450. package/src/lib/shapes/arrow/arrow-types.ts +0 -2
  451. package/src/lib/shapes/arrow/arrowLabel.ts +2 -2
  452. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -2
  453. package/src/lib/shapes/arrow/elbow/elbowArrowSnapLines.tsx +3 -3
  454. package/src/lib/shapes/arrow/shared.ts +4 -4
  455. package/src/lib/shapes/arrow/toolStates/Idle.tsx +14 -4
  456. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +5 -8
  457. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +1 -1
  458. package/src/lib/shapes/bookmark/bookmarks.ts +3 -3
  459. package/src/lib/shapes/draw/DrawShapeUtil.tsx +26 -30
  460. package/src/lib/shapes/draw/getPath.ts +10 -31
  461. package/src/lib/shapes/draw/toolStates/Drawing.ts +90 -100
  462. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -8
  463. package/src/lib/shapes/frame/FrameShapeTool.ts +1 -1
  464. package/src/lib/shapes/frame/FrameShapeUtil.tsx +4 -10
  465. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +2 -10
  466. package/src/lib/shapes/geo/GeoShapeUtil.tsx +176 -228
  467. package/src/lib/shapes/geo/toolStates/Idle.ts +15 -5
  468. package/src/lib/shapes/geo/toolStates/Pointing.ts +6 -6
  469. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +24 -25
  470. package/src/lib/shapes/line/LineShapeTool.test.ts +6 -6
  471. package/src/lib/shapes/line/LineShapeUtil.test.tsx +5 -5
  472. package/src/lib/shapes/line/toolStates/Pointing.ts +4 -4
  473. package/src/lib/shapes/note/NoteShapeTool.test.ts +1 -2
  474. package/src/lib/shapes/note/NoteShapeUtil.tsx +10 -9
  475. package/src/lib/shapes/note/noteCloning.test.ts +1 -3
  476. package/src/lib/shapes/note/noteHelpers.ts +2 -2
  477. package/src/lib/shapes/note/toolStates/Pointing.ts +10 -5
  478. package/src/lib/shapes/shared/HyperlinkButton.tsx +3 -4
  479. package/src/lib/shapes/shared/PlainTextLabel.tsx +2 -12
  480. package/src/lib/shapes/shared/RichTextLabel.tsx +4 -14
  481. package/src/lib/shapes/shared/ShapeFill.tsx +2 -2
  482. package/src/lib/shapes/shared/crop.ts +0 -1
  483. package/src/lib/shapes/shared/interpolate-props.ts +4 -4
  484. package/src/lib/shapes/shared/useEditablePlainText.ts +3 -7
  485. package/src/lib/shapes/shared/useEditableRichText.ts +3 -7
  486. package/src/lib/shapes/shared/useForceSolid.ts +6 -0
  487. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +1 -1
  488. package/src/lib/shapes/text/RichTextArea.tsx +0 -5
  489. package/src/lib/shapes/text/TextShapeTool.test.ts +4 -4
  490. package/src/lib/shapes/text/TextShapeUtil.tsx +0 -5
  491. package/src/lib/shapes/text/toolStates/Idle.ts +14 -4
  492. package/src/lib/shapes/text/toolStates/Pointing.ts +8 -8
  493. package/src/lib/shapes/video/VideoShapeUtil.tsx +1 -2
  494. package/src/lib/tools/EraserTool/childStates/Erasing.ts +10 -7
  495. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -5
  496. package/src/lib/tools/HandTool/HandTool.ts +5 -3
  497. package/src/lib/tools/HandTool/childStates/Dragging.ts +2 -3
  498. package/src/lib/tools/HandTool/childStates/Pointing.ts +1 -1
  499. package/src/lib/tools/LaserTool/childStates/Lasering.ts +1 -1
  500. package/src/lib/tools/SelectTool/DragAndDropManager.ts +11 -14
  501. package/src/lib/tools/SelectTool/childStates/Brushing.ts +11 -8
  502. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +6 -7
  503. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +4 -3
  504. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +1 -1
  505. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +1 -1
  506. package/src/lib/tools/SelectTool/childStates/Crop/children/TranslatingCrop.ts +1 -2
  507. package/src/lib/tools/SelectTool/childStates/Crop/children/crop_helpers.ts +1 -1
  508. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +12 -11
  509. package/src/lib/tools/SelectTool/childStates/EditingShape.ts +16 -57
  510. package/src/lib/tools/SelectTool/childStates/Idle.ts +81 -64
  511. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +8 -7
  512. package/src/lib/tools/SelectTool/childStates/PointingCanvas.ts +1 -1
  513. package/src/lib/tools/SelectTool/childStates/PointingHandle.ts +17 -9
  514. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +1 -1
  515. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +1 -1
  516. package/src/lib/tools/SelectTool/childStates/PointingSelection.ts +4 -4
  517. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +14 -4
  518. package/src/lib/tools/SelectTool/childStates/Resizing.ts +10 -8
  519. package/src/lib/tools/SelectTool/childStates/Rotating.ts +3 -2
  520. package/src/lib/tools/SelectTool/childStates/ScribbleBrushing.ts +10 -9
  521. package/src/lib/tools/SelectTool/childStates/Translating.ts +15 -16
  522. package/src/lib/tools/SelectTool/selectHelpers.ts +4 -39
  523. package/src/lib/tools/ZoomTool/ZoomTool.ts +1 -1
  524. package/src/lib/tools/ZoomTool/childStates/Pointing.ts +3 -3
  525. package/src/lib/tools/ZoomTool/childStates/ZoomBrushing.ts +6 -5
  526. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +3 -1
  527. package/src/lib/tools/selection-logic/getShouldEnterCropModeOnPointerDown.ts +10 -0
  528. package/src/lib/tools/selection-logic/selectOnCanvasPointerUp.ts +1 -1
  529. package/src/lib/tools/selection-logic/updateHoveredShapeId.ts +1 -1
  530. package/src/lib/ui/TldrawUi.tsx +2 -5
  531. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx +9 -1
  532. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +3 -1
  533. package/src/lib/ui/components/CursorChatBubble.tsx +2 -2
  534. package/src/lib/ui/components/DefaultDebugPanel.tsx +42 -3
  535. package/src/lib/ui/components/EditLinkDialog.tsx +6 -16
  536. package/src/lib/ui/components/HelperButtons/StopFollowing.tsx +2 -2
  537. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -1
  538. package/src/lib/ui/components/OfflineIndicator/OfflineIndicator.tsx +5 -6
  539. package/src/lib/ui/components/PageMenu/PageItemInput.tsx +1 -3
  540. package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +0 -8
  541. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -2
  542. package/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx +1 -1
  543. package/src/lib/ui/components/Toolbar/DefaultRichTextToolbar.tsx +1 -1
  544. package/src/lib/ui/components/TopPanel/CenteredTopPanelContainer.tsx +1 -1
  545. package/src/lib/ui/components/TopPanel/DefaultTopPanel.tsx +10 -0
  546. package/src/lib/ui/components/menu-items.tsx +15 -9
  547. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +3 -5
  548. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
  549. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +113 -208
  550. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionCheckboxItem.tsx +1 -1
  551. package/src/lib/ui/components/primitives/menus/TldrawUiMenuActionItem.tsx +1 -1
  552. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +2 -2
  553. package/src/lib/ui/context/actions.tsx +19 -15
  554. package/src/lib/ui/context/components.tsx +2 -1
  555. package/src/lib/ui/hooks/menu-hooks.ts +19 -9
  556. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  557. package/src/lib/ui/hooks/useFlatten.ts +2 -1
  558. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +2 -2
  559. package/src/lib/ui/hooks/useTools.tsx +7 -5
  560. package/src/lib/ui/version.ts +3 -3
  561. package/src/lib/ui.css +29 -31
  562. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +48 -12
  563. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +6 -19
  564. package/src/lib/utils/export/exportAs.ts +9 -2
  565. package/src/lib/utils/frames/frames.ts +1 -1
  566. package/src/lib/utils/text/richText.ts +5 -6
  567. package/src/lib/utils/text/textDirection.ts +32 -0
  568. package/src/lib/utils/tldr/buildFromV1Document.ts +19 -21
  569. package/src/test/Editor.test.tsx +41 -78
  570. package/src/test/EraserTool.test.ts +12 -10
  571. package/src/test/SelectTool.test.ts +19 -11
  572. package/src/test/TestEditor.ts +51 -49
  573. package/src/test/TldrawEditor.test.tsx +20 -24
  574. package/src/test/__snapshots__/drawing.test.ts.snap +1257 -3
  575. package/src/test/__snapshots__/resizing.test.ts.snap +12 -3
  576. package/src/test/arrows-megabus.test.tsx +1 -1
  577. package/src/test/bindings.test.tsx +25 -29
  578. package/src/test/bindingsIndex.test.tsx +4 -4
  579. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +10 -10
  580. package/src/test/commands/createShapes.test.ts +1 -15
  581. package/src/test/commands/getSvgString.test.ts +2 -2
  582. package/src/test/commands/putContent.test.ts +1 -80
  583. package/src/test/commands/setCamera.test.ts +11 -13
  584. package/src/test/commands/stackShapes.test.ts +8 -34
  585. package/src/test/commands/updateShapes.test.ts +5 -21
  586. package/src/test/commands/zoomToBounds.test.ts +3 -19
  587. package/src/test/commands/zoomToSelection.test.ts +3 -14
  588. package/src/test/custom-clipping.test.ts +44 -52
  589. package/src/test/customSnapping.test.tsx +62 -77
  590. package/src/test/drawing.test.ts +10 -17
  591. package/src/test/duplicate.test.ts +1 -1
  592. package/src/test/flipShapes.test.ts +0 -33
  593. package/src/test/frames.test.ts +2 -94
  594. package/src/test/getCulledShapes.test.tsx +3 -11
  595. package/src/test/getShapeAtPoint.test.ts +2 -2
  596. package/src/test/groups.test.tsx +4 -7
  597. package/src/test/modifiers.test.ts +6 -6
  598. package/src/test/resizing.test.ts +22 -16
  599. package/src/test/selection-omnibus.test.ts +13 -13
  600. package/src/test/shapeutils.test.ts +1 -1
  601. package/src/test/spacebarPanning.test.ts +10 -28
  602. package/src/test/styles2.test.tsx +1 -1
  603. package/src/test/styles3.test.ts +5 -5
  604. package/src/test/test-jsx.tsx +57 -72
  605. package/src/test/text.test.ts +17 -15
  606. package/src/test/translating.test.ts +8 -6
  607. package/tldraw.css +41 -45
  608. package/dist-cjs/lib/shapes/shared/useEfficientZoomThreshold.js.map +0 -7
  609. package/dist-cjs/lib/utils/test-helpers.js.map +0 -7
  610. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs +0 -12
  611. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs.map +0 -7
  612. package/dist-esm/lib/utils/test-helpers.mjs +0 -21
  613. package/dist-esm/lib/utils/test-helpers.mjs.map +0 -7
  614. package/src/lib/shapes/draw/DrawShapeUtil.test.ts +0 -146
  615. package/src/lib/shapes/highlight/HighlightShapeUtil.test.ts +0 -146
  616. package/src/lib/shapes/shared/useEfficientZoomThreshold.ts +0 -10
  617. package/src/lib/utils/test-helpers.ts +0 -60
  618. package/src/test/commands/cameraState.test.ts +0 -299
  619. package/src/test/commands/createShape.test.ts +0 -64
  620. package/src/test/commands/isShapeOfType.test.ts +0 -44
  621. package/src/test/commands/updateShape.test.ts +0 -67
@@ -47,7 +47,9 @@ const DefaultContextMenu = memo(function DefaultContextMenu2({
47
47
  });
48
48
  if (editor.getInstanceState().isCoarsePointer) {
49
49
  const selectedShapes = editor.getSelectedShapes();
50
- const currentPagePoint = editor.inputs.getCurrentPagePoint();
50
+ const {
51
+ inputs: { currentPagePoint }
52
+ } = editor;
51
53
  const shapesAtPoint = editor.getShapesAtPoint(currentPagePoint);
52
54
  if (
53
55
  // if there are no selected shapes
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx"],
4
- "sourcesContent": ["import { preventDefault, useContainer, useEditor, useEditorComponents } from '@tldraw/editor'\nimport { ContextMenu as _ContextMenu } from 'radix-ui'\nimport { ReactNode, memo, useCallback, useEffect } from 'react'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\nimport { DefaultContextMenuContent } from './DefaultContextMenuContent'\n\n/** @public */\nexport interface TLUiContextMenuProps {\n\tchildren?: ReactNode\n\tdisabled?: boolean\n}\n\n/** @public @react */\nexport const DefaultContextMenu = memo(function DefaultContextMenu({\n\tchildren,\n\tdisabled = false,\n}: TLUiContextMenuProps) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst { Canvas } = useEditorComponents()\n\n\t// When hitting `Escape` while the context menu is open, we want to prevent\n\t// the default behavior of losing focus on the shape. Otherwise,\n\t// it's pretty annoying from an accessibility perspective.\n\tconst preventEscapeFromLosingShapeFocus = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\te.stopPropagation()\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\t// Cleanup the event listener when the component unmounts.\n\t\t\tdocument.body.removeEventListener('keydown', preventEscapeFromLosingShapeFocus, {\n\t\t\t\tcapture: true,\n\t\t\t})\n\t\t}\n\t}, [preventEscapeFromLosingShapeFocus])\n\n\tconst cb = useCallback(\n\t\t(isOpen: boolean) => {\n\t\t\tif (!isOpen) {\n\t\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\t\t\t\tif (onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)) {\n\t\t\t\t\teditor.setSelectedShapes([])\n\t\t\t\t}\n\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdocument.body.removeEventListener('keydown', preventEscapeFromLosingShapeFocus, {\n\t\t\t\t\t\tcapture: true,\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tdocument.body.addEventListener('keydown', preventEscapeFromLosingShapeFocus, {\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\n\t\t\t\t// Weird route: selecting locked shapes on long press\n\t\t\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\t\t\t\t\tconst currentPagePoint = editor.inputs.getCurrentPagePoint()\n\n\t\t\t\t\t// get all of the shapes under the current pointer\n\t\t\t\t\tconst shapesAtPoint = editor.getShapesAtPoint(currentPagePoint)\n\n\t\t\t\t\tif (\n\t\t\t\t\t\t// if there are no selected shapes\n\t\t\t\t\t\t!editor.getSelectedShapes().length ||\n\t\t\t\t\t\t// OR if none of the shapes at the point include the selected shape\n\t\t\t\t\t\t!shapesAtPoint.some((s) => selectedShapes.includes(s))\n\t\t\t\t\t) {\n\t\t\t\t\t\t// then are there any locked shapes under the current pointer?\n\t\t\t\t\t\tconst lockedShapes = shapesAtPoint.filter((s) => editor.isShapeOrAncestorLocked(s))\n\n\t\t\t\t\t\tif (lockedShapes.length) {\n\t\t\t\t\t\t\t// nice, let's select them\n\t\t\t\t\t\t\teditor.select(...lockedShapes.map((s) => s.id))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, preventEscapeFromLosingShapeFocus]\n\t)\n\n\tconst container = useContainer()\n\tconst [isOpen, handleOpenChange] = useMenuIsOpen('context menu', cb)\n\n\t// Get the context menu content, either the default component or the user's\n\t// override. If there's no menu content, then the user has set it to null,\n\t// so skip rendering the menu.\n\tconst content = children ?? <DefaultContextMenuContent />\n\n\treturn (\n\t\t<_ContextMenu.Root dir=\"ltr\" onOpenChange={handleOpenChange} modal={false}>\n\t\t\t<_ContextMenu.Trigger onContextMenu={undefined} dir=\"ltr\" disabled={disabled}>\n\t\t\t\t{Canvas ? <Canvas /> : null}\n\t\t\t</_ContextMenu.Trigger>\n\t\t\t{isOpen && (\n\t\t\t\t<_ContextMenu.Portal container={container}>\n\t\t\t\t\t<_ContextMenu.Content\n\t\t\t\t\t\tclassName=\"tlui-menu tlui-scrollable\"\n\t\t\t\t\t\tdata-testid=\"context-menu\"\n\t\t\t\t\t\taria-label={msg('context-menu.title')}\n\t\t\t\t\t\talignOffset={-4}\n\t\t\t\t\t\tcollisionPadding={4}\n\t\t\t\t\t\tonContextMenu={preventDefault}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"context-menu\" sourceId=\"context-menu\">\n\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t</_ContextMenu.Content>\n\t\t\t\t</_ContextMenu.Portal>\n\t\t\t)}\n\t\t</_ContextMenu.Root>\n\t)\n})\n"],
5
- "mappings": "AAmG6B,cAG3B,YAH2B;AAnG7B,SAAS,gBAAgB,cAAc,WAAW,2BAA2B;AAC7E,SAAS,eAAe,oBAAoB;AAC5C,SAAoB,MAAM,aAAa,iBAAiB;AACxD,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,mCAAmC;AAC5C,SAAS,iCAAiC;AASnC,MAAM,qBAAqB,KAAK,SAASA,oBAAmB;AAAA,EAClE;AAAA,EACA,WAAW;AACZ,GAAyB;AACxB,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,eAAe;AAE3B,QAAM,EAAE,OAAO,IAAI,oBAAoB;AAKvC,QAAM,oCAAoC;AAAA,IACzC,CAAC,MAAqB;AACrB,UAAI,EAAE,QAAQ,UAAU;AACvB,UAAE,gBAAgB;AAClB,eAAO,aAAa,EAAE,MAAM;AAAA,MAC7B;AAAA,IACD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,YAAU,MAAM;AACf,WAAO,MAAM;AAEZ,eAAS,KAAK,oBAAoB,WAAW,mCAAmC;AAAA,QAC/E,SAAS;AAAA,MACV,CAAC;AAAA,IACF;AAAA,EACD,GAAG,CAAC,iCAAiC,CAAC;AAEtC,QAAM,KAAK;AAAA,IACV,CAACC,YAAoB;AACpB,UAAI,CAACA,SAAQ;AACZ,cAAM,oBAAoB,OAAO,qBAAqB;AAEtD,YAAI,qBAAqB,OAAO,wBAAwB,iBAAiB,GAAG;AAC3E,iBAAO,kBAAkB,CAAC,CAAC;AAAA,QAC5B;AAEA,eAAO,OAAO,sBAAsB,MAAM;AACzC,mBAAS,KAAK,oBAAoB,WAAW,mCAAmC;AAAA,YAC/E,SAAS;AAAA,UACV,CAAC;AAAA,QACF,CAAC;AAAA,MACF,OAAO;AACN,iBAAS,KAAK,iBAAiB,WAAW,mCAAmC;AAAA,UAC5E,SAAS;AAAA,QACV,CAAC;AAGD,YAAI,OAAO,iBAAiB,EAAE,iBAAiB;AAC9C,gBAAM,iBAAiB,OAAO,kBAAkB;AAChD,gBAAM,mBAAmB,OAAO,OAAO,oBAAoB;AAG3D,gBAAM,gBAAgB,OAAO,iBAAiB,gBAAgB;AAE9D;AAAA;AAAA,YAEC,CAAC,OAAO,kBAAkB,EAAE;AAAA,YAE5B,CAAC,cAAc,KAAK,CAAC,MAAM,eAAe,SAAS,CAAC,CAAC;AAAA,YACpD;AAED,kBAAM,eAAe,cAAc,OAAO,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAC;AAElF,gBAAI,aAAa,QAAQ;AAExB,qBAAO,OAAO,GAAG,aAAa,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,YAC/C;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,iCAAiC;AAAA,EAC3C;AAEA,QAAM,YAAY,aAAa;AAC/B,QAAM,CAAC,QAAQ,gBAAgB,IAAI,cAAc,gBAAgB,EAAE;AAKnE,QAAM,UAAU,YAAY,oBAAC,6BAA0B;AAEvD,SACC,qBAAC,aAAa,MAAb,EAAkB,KAAI,OAAM,cAAc,kBAAkB,OAAO,OACnE;AAAA,wBAAC,aAAa,SAAb,EAAqB,eAAe,QAAW,KAAI,OAAM,UACxD,mBAAS,oBAAC,UAAO,IAAK,MACxB;AAAA,IACC,UACA,oBAAC,aAAa,QAAb,EAAoB,WACpB;AAAA,MAAC,aAAa;AAAA,MAAb;AAAA,QACA,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,cAAY,IAAI,oBAAoB;AAAA,QACpC,aAAa;AAAA,QACb,kBAAkB;AAAA,QAClB,eAAe;AAAA,QAEf,8BAAC,+BAA4B,MAAK,gBAAe,UAAS,gBACxD,mBACF;AAAA;AAAA,IACD,GACD;AAAA,KAEF;AAEF,CAAC;",
4
+ "sourcesContent": ["import { preventDefault, useContainer, useEditor, useEditorComponents } from '@tldraw/editor'\nimport { ContextMenu as _ContextMenu } from 'radix-ui'\nimport { ReactNode, memo, useCallback, useEffect } from 'react'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\nimport { DefaultContextMenuContent } from './DefaultContextMenuContent'\n\n/** @public */\nexport interface TLUiContextMenuProps {\n\tchildren?: ReactNode\n\tdisabled?: boolean\n}\n\n/** @public @react */\nexport const DefaultContextMenu = memo(function DefaultContextMenu({\n\tchildren,\n\tdisabled = false,\n}: TLUiContextMenuProps) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst { Canvas } = useEditorComponents()\n\n\t// When hitting `Escape` while the context menu is open, we want to prevent\n\t// the default behavior of losing focus on the shape. Otherwise,\n\t// it's pretty annoying from an accessibility perspective.\n\tconst preventEscapeFromLosingShapeFocus = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\te.stopPropagation()\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\t// Cleanup the event listener when the component unmounts.\n\t\t\tdocument.body.removeEventListener('keydown', preventEscapeFromLosingShapeFocus, {\n\t\t\t\tcapture: true,\n\t\t\t})\n\t\t}\n\t}, [preventEscapeFromLosingShapeFocus])\n\n\tconst cb = useCallback(\n\t\t(isOpen: boolean) => {\n\t\t\tif (!isOpen) {\n\t\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\t\t\t\tif (onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)) {\n\t\t\t\t\teditor.setSelectedShapes([])\n\t\t\t\t}\n\n\t\t\t\teditor.timers.requestAnimationFrame(() => {\n\t\t\t\t\tdocument.body.removeEventListener('keydown', preventEscapeFromLosingShapeFocus, {\n\t\t\t\t\t\tcapture: true,\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tdocument.body.addEventListener('keydown', preventEscapeFromLosingShapeFocus, {\n\t\t\t\t\tcapture: true,\n\t\t\t\t})\n\n\t\t\t\t// Weird route: selecting locked shapes on long press\n\t\t\t\tif (editor.getInstanceState().isCoarsePointer) {\n\t\t\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\t\t\t\t\tconst {\n\t\t\t\t\t\tinputs: { currentPagePoint },\n\t\t\t\t\t} = editor\n\n\t\t\t\t\t// get all of the shapes under the current pointer\n\t\t\t\t\tconst shapesAtPoint = editor.getShapesAtPoint(currentPagePoint)\n\n\t\t\t\t\tif (\n\t\t\t\t\t\t// if there are no selected shapes\n\t\t\t\t\t\t!editor.getSelectedShapes().length ||\n\t\t\t\t\t\t// OR if none of the shapes at the point include the selected shape\n\t\t\t\t\t\t!shapesAtPoint.some((s) => selectedShapes.includes(s))\n\t\t\t\t\t) {\n\t\t\t\t\t\t// then are there any locked shapes under the current pointer?\n\t\t\t\t\t\tconst lockedShapes = shapesAtPoint.filter((s) => editor.isShapeOrAncestorLocked(s))\n\n\t\t\t\t\t\tif (lockedShapes.length) {\n\t\t\t\t\t\t\t// nice, let's select them\n\t\t\t\t\t\t\teditor.select(...lockedShapes.map((s) => s.id))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, preventEscapeFromLosingShapeFocus]\n\t)\n\n\tconst container = useContainer()\n\tconst [isOpen, handleOpenChange] = useMenuIsOpen('context menu', cb)\n\n\t// Get the context menu content, either the default component or the user's\n\t// override. If there's no menu content, then the user has set it to null,\n\t// so skip rendering the menu.\n\tconst content = children ?? <DefaultContextMenuContent />\n\n\treturn (\n\t\t<_ContextMenu.Root dir=\"ltr\" onOpenChange={handleOpenChange} modal={false}>\n\t\t\t<_ContextMenu.Trigger onContextMenu={undefined} dir=\"ltr\" disabled={disabled}>\n\t\t\t\t{Canvas ? <Canvas /> : null}\n\t\t\t</_ContextMenu.Trigger>\n\t\t\t{isOpen && (\n\t\t\t\t<_ContextMenu.Portal container={container}>\n\t\t\t\t\t<_ContextMenu.Content\n\t\t\t\t\t\tclassName=\"tlui-menu tlui-scrollable\"\n\t\t\t\t\t\tdata-testid=\"context-menu\"\n\t\t\t\t\t\taria-label={msg('context-menu.title')}\n\t\t\t\t\t\talignOffset={-4}\n\t\t\t\t\t\tcollisionPadding={4}\n\t\t\t\t\t\tonContextMenu={preventDefault}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"context-menu\" sourceId=\"context-menu\">\n\t\t\t\t\t\t\t{content}\n\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t</_ContextMenu.Content>\n\t\t\t\t</_ContextMenu.Portal>\n\t\t\t)}\n\t\t</_ContextMenu.Root>\n\t)\n})\n"],
5
+ "mappings": "AAqG6B,cAG3B,YAH2B;AArG7B,SAAS,gBAAgB,cAAc,WAAW,2BAA2B;AAC7E,SAAS,eAAe,oBAAoB;AAC5C,SAAoB,MAAM,aAAa,iBAAiB;AACxD,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,mCAAmC;AAC5C,SAAS,iCAAiC;AASnC,MAAM,qBAAqB,KAAK,SAASA,oBAAmB;AAAA,EAClE;AAAA,EACA,WAAW;AACZ,GAAyB;AACxB,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,eAAe;AAE3B,QAAM,EAAE,OAAO,IAAI,oBAAoB;AAKvC,QAAM,oCAAoC;AAAA,IACzC,CAAC,MAAqB;AACrB,UAAI,EAAE,QAAQ,UAAU;AACvB,UAAE,gBAAgB;AAClB,eAAO,aAAa,EAAE,MAAM;AAAA,MAC7B;AAAA,IACD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AAEA,YAAU,MAAM;AACf,WAAO,MAAM;AAEZ,eAAS,KAAK,oBAAoB,WAAW,mCAAmC;AAAA,QAC/E,SAAS;AAAA,MACV,CAAC;AAAA,IACF;AAAA,EACD,GAAG,CAAC,iCAAiC,CAAC;AAEtC,QAAM,KAAK;AAAA,IACV,CAACC,YAAoB;AACpB,UAAI,CAACA,SAAQ;AACZ,cAAM,oBAAoB,OAAO,qBAAqB;AAEtD,YAAI,qBAAqB,OAAO,wBAAwB,iBAAiB,GAAG;AAC3E,iBAAO,kBAAkB,CAAC,CAAC;AAAA,QAC5B;AAEA,eAAO,OAAO,sBAAsB,MAAM;AACzC,mBAAS,KAAK,oBAAoB,WAAW,mCAAmC;AAAA,YAC/E,SAAS;AAAA,UACV,CAAC;AAAA,QACF,CAAC;AAAA,MACF,OAAO;AACN,iBAAS,KAAK,iBAAiB,WAAW,mCAAmC;AAAA,UAC5E,SAAS;AAAA,QACV,CAAC;AAGD,YAAI,OAAO,iBAAiB,EAAE,iBAAiB;AAC9C,gBAAM,iBAAiB,OAAO,kBAAkB;AAChD,gBAAM;AAAA,YACL,QAAQ,EAAE,iBAAiB;AAAA,UAC5B,IAAI;AAGJ,gBAAM,gBAAgB,OAAO,iBAAiB,gBAAgB;AAE9D;AAAA;AAAA,YAEC,CAAC,OAAO,kBAAkB,EAAE;AAAA,YAE5B,CAAC,cAAc,KAAK,CAAC,MAAM,eAAe,SAAS,CAAC,CAAC;AAAA,YACpD;AAED,kBAAM,eAAe,cAAc,OAAO,CAAC,MAAM,OAAO,wBAAwB,CAAC,CAAC;AAElF,gBAAI,aAAa,QAAQ;AAExB,qBAAO,OAAO,GAAG,aAAa,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,YAC/C;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC,QAAQ,iCAAiC;AAAA,EAC3C;AAEA,QAAM,YAAY,aAAa;AAC/B,QAAM,CAAC,QAAQ,gBAAgB,IAAI,cAAc,gBAAgB,EAAE;AAKnE,QAAM,UAAU,YAAY,oBAAC,6BAA0B;AAEvD,SACC,qBAAC,aAAa,MAAb,EAAkB,KAAI,OAAM,cAAc,kBAAkB,OAAO,OACnE;AAAA,wBAAC,aAAa,SAAb,EAAqB,eAAe,QAAW,KAAI,OAAM,UACxD,mBAAS,oBAAC,UAAO,IAAK,MACxB;AAAA,IACC,UACA,oBAAC,aAAa,QAAb,EAAoB,WACpB;AAAA,MAAC,aAAa;AAAA,MAAb;AAAA,QACA,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,cAAY,IAAI,oBAAoB;AAAA,QACpC,aAAa;AAAA,QACb,kBAAkB;AAAA,QAClB,eAAe;AAAA,QAEf,8BAAC,+BAA4B,MAAK,gBAAe,UAAS,gBACxD,mBACF;AAAA;AAAA,IACD,GACD;AAAA,KAEF;AAEF,CAAC;",
6
6
  "names": ["DefaultContextMenu", "isOpen"]
7
7
  }
@@ -38,7 +38,7 @@ function usePositionBubble(ref) {
38
38
  useLayoutEffect(() => {
39
39
  const elm = ref.current;
40
40
  if (!elm) return;
41
- const { x, y } = editor.inputs.getCurrentScreenPoint();
41
+ const { x, y } = editor.inputs.currentScreenPoint;
42
42
  ref.current?.style.setProperty("transform", `translate(${x}px, ${y}px)`);
43
43
  function positionChatBubble(e) {
44
44
  const { minX, minY } = editor.getViewportScreenBounds();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/CursorChatBubble.tsx"],
4
- "sourcesContent": ["import { preventDefault, track, useEditor } from '@tldraw/editor'\nimport {\n\tChangeEvent,\n\tClipboardEvent,\n\tKeyboardEvent,\n\tRefObject,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\n\n// todo:\n// - not cleaning up\nconst CHAT_MESSAGE_TIMEOUT_CLOSING = 2000\nconst CHAT_MESSAGE_TIMEOUT_CHATTING = 5000\n\nexport const CursorChatBubble = track(function CursorChatBubble() {\n\tconst editor = useEditor()\n\tconst { isChatting, chatMessage } = editor.getInstanceState()\n\n\tconst rTimeout = useRef<any>(-1)\n\tconst [value, setValue] = useState('')\n\n\tuseEffect(() => {\n\t\tconst closingUp = !isChatting && chatMessage\n\t\tif (closingUp || isChatting) {\n\t\t\tconst duration = isChatting ? CHAT_MESSAGE_TIMEOUT_CHATTING : CHAT_MESSAGE_TIMEOUT_CLOSING\n\t\t\trTimeout.current = editor.timers.setTimeout(() => {\n\t\t\t\teditor.updateInstanceState({ chatMessage: '', isChatting: false })\n\t\t\t\tsetValue('')\n\t\t\t\teditor.focus()\n\t\t\t}, duration)\n\t\t}\n\n\t\treturn () => {\n\t\t\tclearTimeout(rTimeout.current)\n\t\t}\n\t}, [editor, chatMessage, isChatting])\n\n\tif (isChatting)\n\t\treturn <CursorChatInput value={value} setValue={setValue} chatMessage={chatMessage} />\n\n\treturn chatMessage.trim() ? <NotEditingChatMessage chatMessage={chatMessage} /> : null\n})\n\nfunction usePositionBubble(ref: RefObject<HTMLInputElement | null>) {\n\tconst editor = useEditor()\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = ref.current\n\t\tif (!elm) return\n\n\t\tconst { x, y } = editor.inputs.getCurrentScreenPoint()\n\t\tref.current?.style.setProperty('transform', `translate(${x}px, ${y}px)`)\n\n\t\t// Positioning the chat bubble\n\t\tfunction positionChatBubble(e: PointerEvent) {\n\t\t\tconst { minX, minY } = editor.getViewportScreenBounds()\n\t\t\tref.current?.style.setProperty(\n\t\t\t\t'transform',\n\t\t\t\t`translate(${e.clientX - minX}px, ${e.clientY - minY}px)`\n\t\t\t)\n\t\t}\n\n\t\twindow.addEventListener('pointermove', positionChatBubble)\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener('pointermove', positionChatBubble)\n\t\t}\n\t}, [ref, editor])\n}\n\nconst NotEditingChatMessage = ({ chatMessage }: { chatMessage: string }) => {\n\tconst editor = useEditor()\n\tconst ref = useRef<HTMLInputElement>(null)\n\n\tusePositionBubble(ref)\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName=\"tl-cursor-chat tl-cursor-chat__bubble\"\n\t\t\tstyle={{ backgroundColor: editor.user.getColor() }}\n\t\t>\n\t\t\t{chatMessage}\n\t\t</div>\n\t)\n}\n\nconst CursorChatInput = track(function CursorChatInput({\n\tchatMessage,\n\tvalue,\n\tsetValue,\n}: {\n\tchatMessage: string\n\tvalue: string\n\tsetValue(value: string): void\n}) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst ref = useRef<HTMLInputElement>(null)\n\tconst placeholder = chatMessage || msg('cursor-chat.type-to-chat')\n\n\tusePositionBubble(ref)\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = ref.current\n\t\tif (!elm) return\n\n\t\tconst textMeasurement = editor.textMeasure.measureText(value || placeholder, {\n\t\t\tfontFamily: 'var(--font-body)',\n\t\t\tfontSize: 12,\n\t\t\tfontWeight: '500',\n\t\t\tfontStyle: 'normal',\n\t\t\tmaxWidth: null,\n\t\t\tlineHeight: 1,\n\t\t\tpadding: '6px',\n\t\t})\n\n\t\telm.style.setProperty('width', textMeasurement.w + 'px')\n\t}, [editor, value, placeholder])\n\n\tuseLayoutEffect(() => {\n\t\t// Focus the input\n\t\tconst raf = editor.timers.requestAnimationFrame(() => {\n\t\t\tref.current?.focus()\n\t\t})\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(raf)\n\t\t}\n\t}, [editor])\n\n\tconst stopChatting = useCallback(() => {\n\t\teditor.updateInstanceState({ isChatting: false })\n\t\teditor.focus()\n\t}, [editor])\n\n\t// Update the chat message as the user types\n\tconst handleChange = useCallback(\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst { value } = e.target\n\t\t\tsetValue(value.slice(0, 64))\n\t\t\teditor.updateInstanceState({ chatMessage: value })\n\t\t},\n\t\t[editor, setValue]\n\t)\n\n\t// Handle some keyboard shortcuts\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tconst elm = ref.current\n\t\t\tif (!elm) return\n\n\t\t\t// get this from the element so that this hook doesn't depend on value\n\t\t\tconst { value: currentValue } = elm\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\te.stopPropagation()\n\n\t\t\t\t\t// If the user hasn't typed anything, stop chatting\n\t\t\t\t\tif (!currentValue) {\n\t\t\t\t\t\tstopChatting()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t// Otherwise, 'send' the message\n\t\t\t\t\tsetValue('')\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\tstopChatting()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[stopChatting, setValue]\n\t)\n\n\tconst handlePaste = useCallback((e: ClipboardEvent) => {\n\t\te.stopPropagation()\n\t}, [])\n\n\treturn (\n\t\t<input\n\t\t\tref={ref}\n\t\t\tclassName={`tl-cursor-chat`}\n\t\t\tstyle={{ backgroundColor: editor.user.getColor() }}\n\t\t\tonBlur={stopChatting}\n\t\t\tonChange={handleChange}\n\t\t\tonKeyDown={handleKeyDown}\n\t\t\tonPaste={handlePaste}\n\t\t\tvalue={value}\n\t\t\tplaceholder={placeholder}\n\t\t\tspellCheck={false}\n\t\t/>\n\t)\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { preventDefault, track, useEditor } from '@tldraw/editor'\nimport {\n\tChangeEvent,\n\tClipboardEvent,\n\tKeyboardEvent,\n\tRefObject,\n\tuseCallback,\n\tuseEffect,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\n\n// todo:\n// - not cleaning up\nconst CHAT_MESSAGE_TIMEOUT_CLOSING = 2000\nconst CHAT_MESSAGE_TIMEOUT_CHATTING = 5000\n\nexport const CursorChatBubble = track(function CursorChatBubble() {\n\tconst editor = useEditor()\n\tconst { isChatting, chatMessage } = editor.getInstanceState()\n\n\tconst rTimeout = useRef<any>(-1)\n\tconst [value, setValue] = useState('')\n\n\tuseEffect(() => {\n\t\tconst closingUp = !isChatting && chatMessage\n\t\tif (closingUp || isChatting) {\n\t\t\tconst duration = isChatting ? CHAT_MESSAGE_TIMEOUT_CHATTING : CHAT_MESSAGE_TIMEOUT_CLOSING\n\t\t\trTimeout.current = editor.timers.setTimeout(() => {\n\t\t\t\teditor.updateInstanceState({ chatMessage: '', isChatting: false })\n\t\t\t\tsetValue('')\n\t\t\t\teditor.focus()\n\t\t\t}, duration)\n\t\t}\n\n\t\treturn () => {\n\t\t\tclearTimeout(rTimeout.current)\n\t\t}\n\t}, [editor, chatMessage, isChatting])\n\n\tif (isChatting)\n\t\treturn <CursorChatInput value={value} setValue={setValue} chatMessage={chatMessage} />\n\n\treturn chatMessage.trim() ? <NotEditingChatMessage chatMessage={chatMessage} /> : null\n})\n\nfunction usePositionBubble(ref: RefObject<HTMLInputElement>) {\n\tconst editor = useEditor()\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = ref.current\n\t\tif (!elm) return\n\n\t\tconst { x, y } = editor.inputs.currentScreenPoint\n\t\tref.current?.style.setProperty('transform', `translate(${x}px, ${y}px)`)\n\n\t\t// Positioning the chat bubble\n\t\tfunction positionChatBubble(e: PointerEvent) {\n\t\t\tconst { minX, minY } = editor.getViewportScreenBounds()\n\t\t\tref.current?.style.setProperty(\n\t\t\t\t'transform',\n\t\t\t\t`translate(${e.clientX - minX}px, ${e.clientY - minY}px)`\n\t\t\t)\n\t\t}\n\n\t\twindow.addEventListener('pointermove', positionChatBubble)\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener('pointermove', positionChatBubble)\n\t\t}\n\t}, [ref, editor])\n}\n\nconst NotEditingChatMessage = ({ chatMessage }: { chatMessage: string }) => {\n\tconst editor = useEditor()\n\tconst ref = useRef<HTMLInputElement>(null)\n\n\tusePositionBubble(ref)\n\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\tclassName=\"tl-cursor-chat tl-cursor-chat__bubble\"\n\t\t\tstyle={{ backgroundColor: editor.user.getColor() }}\n\t\t>\n\t\t\t{chatMessage}\n\t\t</div>\n\t)\n}\n\nconst CursorChatInput = track(function CursorChatInput({\n\tchatMessage,\n\tvalue,\n\tsetValue,\n}: {\n\tchatMessage: string\n\tvalue: string\n\tsetValue(value: string): void\n}) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst ref = useRef<HTMLInputElement>(null)\n\tconst placeholder = chatMessage || msg('cursor-chat.type-to-chat')\n\n\tusePositionBubble(ref)\n\n\tuseLayoutEffect(() => {\n\t\tconst elm = ref.current\n\t\tif (!elm) return\n\n\t\tconst textMeasurement = editor.textMeasure.measureText(value || placeholder, {\n\t\t\tfontFamily: 'var(--font-body)',\n\t\t\tfontSize: 12,\n\t\t\tfontWeight: '500',\n\t\t\tfontStyle: 'normal',\n\t\t\tmaxWidth: null,\n\t\t\tlineHeight: 1,\n\t\t\tpadding: '6px',\n\t\t})\n\n\t\telm.style.setProperty('width', textMeasurement.w + 'px')\n\t}, [editor, value, placeholder])\n\n\tuseLayoutEffect(() => {\n\t\t// Focus the input\n\t\tconst raf = editor.timers.requestAnimationFrame(() => {\n\t\t\tref.current?.focus()\n\t\t})\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(raf)\n\t\t}\n\t}, [editor])\n\n\tconst stopChatting = useCallback(() => {\n\t\teditor.updateInstanceState({ isChatting: false })\n\t\teditor.focus()\n\t}, [editor])\n\n\t// Update the chat message as the user types\n\tconst handleChange = useCallback(\n\t\t(e: ChangeEvent<HTMLInputElement>) => {\n\t\t\tconst { value } = e.target\n\t\t\tsetValue(value.slice(0, 64))\n\t\t\teditor.updateInstanceState({ chatMessage: value })\n\t\t},\n\t\t[editor, setValue]\n\t)\n\n\t// Handle some keyboard shortcuts\n\tconst handleKeyDown = useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tconst elm = ref.current\n\t\t\tif (!elm) return\n\n\t\t\t// get this from the element so that this hook doesn't depend on value\n\t\t\tconst { value: currentValue } = elm\n\n\t\t\tswitch (e.key) {\n\t\t\t\tcase 'Enter': {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\te.stopPropagation()\n\n\t\t\t\t\t// If the user hasn't typed anything, stop chatting\n\t\t\t\t\tif (!currentValue) {\n\t\t\t\t\t\tstopChatting()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\t// Otherwise, 'send' the message\n\t\t\t\t\tsetValue('')\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'Escape': {\n\t\t\t\t\tpreventDefault(e)\n\t\t\t\t\te.stopPropagation()\n\t\t\t\t\tstopChatting()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[stopChatting, setValue]\n\t)\n\n\tconst handlePaste = useCallback((e: ClipboardEvent) => {\n\t\te.stopPropagation()\n\t}, [])\n\n\treturn (\n\t\t<input\n\t\t\tref={ref}\n\t\t\tclassName={`tl-cursor-chat`}\n\t\t\tstyle={{ backgroundColor: editor.user.getColor() }}\n\t\t\tonBlur={stopChatting}\n\t\t\tonChange={handleChange}\n\t\t\tonKeyDown={handleKeyDown}\n\t\t\tonPaste={handlePaste}\n\t\t\tvalue={value}\n\t\t\tplaceholder={placeholder}\n\t\t\tspellCheck={false}\n\t\t/>\n\t)\n})\n"],
5
+ "mappings": "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",
6
6
  "names": ["CursorChatBubble", "CursorChatInput", "value"]
7
7
  }
@@ -1,6 +1,13 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { debugFlags, track, useEditor, usePassThroughWheelEvents, useValue } from "@tldraw/editor";
3
- import { memo, useEffect, useRef } from "react";
2
+ import {
3
+ debugFlags,
4
+ track,
5
+ useEditor,
6
+ usePassThroughWheelEvents,
7
+ useValue,
8
+ Vec
9
+ } from "@tldraw/editor";
10
+ import { memo, useEffect, useRef, useState } from "react";
4
11
  import { useTldrawUiComponents } from "../context/components.mjs";
5
12
  const DefaultDebugPanel = memo(function DefaultDebugPanel2() {
6
13
  const { DebugMenu } = useTldrawUiComponents();
@@ -12,10 +19,30 @@ const DefaultDebugPanel = memo(function DefaultDebugPanel2() {
12
19
  DebugMenu && /* @__PURE__ */ jsx(DebugMenu, {})
13
20
  ] });
14
21
  });
22
+ function useTick(isEnabled = true) {
23
+ const [_, setTick] = useState(0);
24
+ const editor = useEditor();
25
+ useEffect(() => {
26
+ if (!isEnabled) return;
27
+ const update = () => setTick((tick) => tick + 1);
28
+ editor.on("tick", update);
29
+ return () => {
30
+ editor.off("tick", update);
31
+ };
32
+ }, [editor, isEnabled]);
33
+ }
15
34
  const CurrentState = track(function CurrentState2() {
35
+ useTick();
16
36
  const editor = useEditor();
17
37
  const path = editor.getPath();
18
- return /* @__PURE__ */ jsx("div", { className: "tlui-debug-panel__current-state", children: `${path}` });
38
+ const hoverShape = editor.getHoveredShape();
39
+ const selectedShape = editor.getOnlySelectedShape();
40
+ const shape = path === "select.idle" || !path.includes("select.") ? hoverShape : selectedShape;
41
+ const shapeInfo = shape && path.includes("select.") ? ` / ${shape.type || ""}${"geo" in shape.props ? " / " + shape.props.geo : ""} / [${Vec.ToInt(editor.getPointInShapeSpace(shape, editor.inputs.currentPagePoint))}]` : "";
42
+ const ruler = path.startsWith("select.") && !path.includes(".idle") ? ` / [${Vec.ToInt(editor.inputs.originPagePoint)}] \u2192 [${Vec.ToInt(
43
+ editor.inputs.currentPagePoint
44
+ )}] = ${Vec.Dist(editor.inputs.originPagePoint, editor.inputs.currentPagePoint).toFixed(0)}` : "";
45
+ return /* @__PURE__ */ jsx("div", { className: "tlui-debug-panel__current-state", children: `${path}${shapeInfo}${ruler}` });
19
46
  });
20
47
  function FPS() {
21
48
  const editor = useEditor();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/DefaultDebugPanel.tsx"],
4
- "sourcesContent": ["import { debugFlags, track, useEditor, usePassThroughWheelEvents, useValue } from '@tldraw/editor'\nimport { memo, useEffect, useRef } from 'react'\nimport { useTldrawUiComponents } from '../context/components'\n\n/** @internal */\nexport const DefaultDebugPanel = memo(function DefaultDebugPanel() {\n\tconst { DebugMenu } = useTldrawUiComponents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\treturn (\n\t\t<footer ref={ref} className=\"tlui-debug-panel\">\n\t\t\t<CurrentState />\n\t\t\t<FPS />\n\t\t\t{DebugMenu && <DebugMenu />}\n\t\t</footer>\n\t)\n})\n\nconst CurrentState = track(function CurrentState() {\n\tconst editor = useEditor()\n\tconst path = editor.getPath()\n\treturn <div className=\"tlui-debug-panel__current-state\">{`${path}`}</div>\n})\n\nfunction FPS() {\n\tconst editor = useEditor()\n\tconst showFps = useValue('show_fps', () => debugFlags.showFps.get(), [debugFlags])\n\n\tconst fpsRef = useRef<HTMLDivElement>(null)\n\n\tuseEffect(() => {\n\t\tif (!showFps) return\n\n\t\tconst TICK_LENGTH = 250\n\t\tlet maxKnownFps = 0\n\t\tlet raf = -1\n\n\t\tlet start = performance.now()\n\t\tlet currentTickLength = 0\n\t\tlet framesInCurrentTick = 0\n\t\tlet isSlow = false\n\n\t\t// A \"tick\" is the amount of time between renders. Even though\n\t\t// we'll loop on every frame, we will only paint when the time\n\t\t// since the last paint is greater than the tick length.\n\n\t\t// When we paint, we'll calculate the FPS based on the number\n\t\t// of frames that we've seen since the last time we rendered,\n\t\t// and the actual time since the last render.\n\t\tfunction loop() {\n\t\t\t// Count the frame\n\t\t\tframesInCurrentTick++\n\n\t\t\t// Check if we should render\n\t\t\tcurrentTickLength = performance.now() - start\n\n\t\t\tif (currentTickLength > TICK_LENGTH) {\n\t\t\t\t// Calculate the FPS and paint it\n\t\t\t\tconst fps = Math.round(\n\t\t\t\t\tframesInCurrentTick * (TICK_LENGTH / currentTickLength) * (1000 / TICK_LENGTH)\n\t\t\t\t)\n\n\t\t\t\tif (fps > maxKnownFps) {\n\t\t\t\t\tmaxKnownFps = fps\n\t\t\t\t}\n\n\t\t\t\tconst slowFps = maxKnownFps * 0.75\n\t\t\t\tif ((fps < slowFps && !isSlow) || (fps >= slowFps && isSlow)) {\n\t\t\t\t\tisSlow = !isSlow\n\t\t\t\t}\n\n\t\t\t\tfpsRef.current!.innerHTML = `FPS ${fps.toString()}`\n\t\t\t\tfpsRef.current!.className =\n\t\t\t\t\t`tlui-debug-panel__fps` + (isSlow ? ` tlui-debug-panel__fps__slow` : ``)\n\n\t\t\t\t// Reset the values\n\t\t\t\tcurrentTickLength -= TICK_LENGTH\n\t\t\t\tframesInCurrentTick = 0\n\t\t\t\tstart = performance.now()\n\t\t\t}\n\n\t\t\traf = editor.timers.requestAnimationFrame(loop)\n\t\t}\n\n\t\tloop()\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(raf)\n\t\t}\n\t}, [showFps, editor])\n\n\tif (!showFps) return null\n\n\treturn <div ref={fpsRef} />\n}\n"],
5
- "mappings": "AAYE,SACC,KADD;AAZF,SAAS,YAAY,OAAO,WAAW,2BAA2B,gBAAgB;AAClF,SAAS,MAAM,WAAW,cAAc;AACxC,SAAS,6BAA6B;AAG/B,MAAM,oBAAoB,KAAK,SAASA,qBAAoB;AAClE,QAAM,EAAE,UAAU,IAAI,sBAAsB;AAE5C,QAAM,MAAM,OAAuB,IAAI;AACvC,4BAA0B,GAAG;AAE7B,SACC,qBAAC,YAAO,KAAU,WAAU,oBAC3B;AAAA,wBAAC,gBAAa;AAAA,IACd,oBAAC,OAAI;AAAA,IACJ,aAAa,oBAAC,aAAU;AAAA,KAC1B;AAEF,CAAC;AAED,MAAM,eAAe,MAAM,SAASC,gBAAe;AAClD,QAAM,SAAS,UAAU;AACzB,QAAM,OAAO,OAAO,QAAQ;AAC5B,SAAO,oBAAC,SAAI,WAAU,mCAAmC,aAAG,IAAI,IAAG;AACpE,CAAC;AAED,SAAS,MAAM;AACd,QAAM,SAAS,UAAU;AACzB,QAAM,UAAU,SAAS,YAAY,MAAM,WAAW,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC;AAEjF,QAAM,SAAS,OAAuB,IAAI;AAE1C,YAAU,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,UAAM,cAAc;AACpB,QAAI,cAAc;AAClB,QAAI,MAAM;AAEV,QAAI,QAAQ,YAAY,IAAI;AAC5B,QAAI,oBAAoB;AACxB,QAAI,sBAAsB;AAC1B,QAAI,SAAS;AASb,aAAS,OAAO;AAEf;AAGA,0BAAoB,YAAY,IAAI,IAAI;AAExC,UAAI,oBAAoB,aAAa;AAEpC,cAAM,MAAM,KAAK;AAAA,UAChB,uBAAuB,cAAc,sBAAsB,MAAO;AAAA,QACnE;AAEA,YAAI,MAAM,aAAa;AACtB,wBAAc;AAAA,QACf;AAEA,cAAM,UAAU,cAAc;AAC9B,YAAK,MAAM,WAAW,CAAC,UAAY,OAAO,WAAW,QAAS;AAC7D,mBAAS,CAAC;AAAA,QACX;AAEA,eAAO,QAAS,YAAY,OAAO,IAAI,SAAS,CAAC;AACjD,eAAO,QAAS,YACf,2BAA2B,SAAS,iCAAiC;AAGtE,6BAAqB;AACrB,8BAAsB;AACtB,gBAAQ,YAAY,IAAI;AAAA,MACzB;AAEA,YAAM,OAAO,OAAO,sBAAsB,IAAI;AAAA,IAC/C;AAEA,SAAK;AAEL,WAAO,MAAM;AACZ,2BAAqB,GAAG;AAAA,IACzB;AAAA,EACD,GAAG,CAAC,SAAS,MAAM,CAAC;AAEpB,MAAI,CAAC,QAAS,QAAO;AAErB,SAAO,oBAAC,SAAI,KAAK,QAAQ;AAC1B;",
4
+ "sourcesContent": ["import {\n\tdebugFlags,\n\ttrack,\n\tuseEditor,\n\tusePassThroughWheelEvents,\n\tuseValue,\n\tVec,\n} from '@tldraw/editor'\nimport { memo, useEffect, useRef, useState } from 'react'\nimport { useTldrawUiComponents } from '../context/components'\n\n/** @internal */\nexport const DefaultDebugPanel = memo(function DefaultDebugPanel() {\n\tconst { DebugMenu } = useTldrawUiComponents()\n\n\tconst ref = useRef<HTMLDivElement>(null)\n\tusePassThroughWheelEvents(ref)\n\n\treturn (\n\t\t<footer ref={ref} className=\"tlui-debug-panel\">\n\t\t\t<CurrentState />\n\t\t\t<FPS />\n\t\t\t{DebugMenu && <DebugMenu />}\n\t\t</footer>\n\t)\n})\n\nfunction useTick(isEnabled = true) {\n\tconst [_, setTick] = useState(0)\n\tconst editor = useEditor()\n\tuseEffect(() => {\n\t\tif (!isEnabled) return\n\t\tconst update = () => setTick((tick) => tick + 1)\n\t\teditor.on('tick', update)\n\t\treturn () => {\n\t\t\teditor.off('tick', update)\n\t\t}\n\t}, [editor, isEnabled])\n}\n\nconst CurrentState = track(function CurrentState() {\n\tuseTick()\n\n\tconst editor = useEditor()\n\n\tconst path = editor.getPath()\n\tconst hoverShape = editor.getHoveredShape()\n\tconst selectedShape = editor.getOnlySelectedShape()\n\tconst shape = path === 'select.idle' || !path.includes('select.') ? hoverShape : selectedShape\n\tconst shapeInfo =\n\t\tshape && path.includes('select.')\n\t\t\t? ` / ${shape.type || ''}${\n\t\t\t\t\t'geo' in shape.props ? ' / ' + shape.props.geo : ''\n\t\t\t\t} / [${Vec.ToInt(editor.getPointInShapeSpace(shape, editor.inputs.currentPagePoint))}]`\n\t\t\t: ''\n\tconst ruler =\n\t\tpath.startsWith('select.') && !path.includes('.idle')\n\t\t\t? ` / [${Vec.ToInt(editor.inputs.originPagePoint)}] \u2192 [${Vec.ToInt(\n\t\t\t\t\teditor.inputs.currentPagePoint\n\t\t\t\t)}] = ${Vec.Dist(editor.inputs.originPagePoint, editor.inputs.currentPagePoint).toFixed(0)}`\n\t\t\t: ''\n\n\treturn <div className=\"tlui-debug-panel__current-state\">{`${path}${shapeInfo}${ruler}`}</div>\n})\n\nfunction FPS() {\n\tconst editor = useEditor()\n\tconst showFps = useValue('show_fps', () => debugFlags.showFps.get(), [debugFlags])\n\n\tconst fpsRef = useRef<HTMLDivElement>(null)\n\n\tuseEffect(() => {\n\t\tif (!showFps) return\n\n\t\tconst TICK_LENGTH = 250\n\t\tlet maxKnownFps = 0\n\t\tlet raf = -1\n\n\t\tlet start = performance.now()\n\t\tlet currentTickLength = 0\n\t\tlet framesInCurrentTick = 0\n\t\tlet isSlow = false\n\n\t\t// A \"tick\" is the amount of time between renders. Even though\n\t\t// we'll loop on every frame, we will only paint when the time\n\t\t// since the last paint is greater than the tick length.\n\n\t\t// When we paint, we'll calculate the FPS based on the number\n\t\t// of frames that we've seen since the last time we rendered,\n\t\t// and the actual time since the last render.\n\t\tfunction loop() {\n\t\t\t// Count the frame\n\t\t\tframesInCurrentTick++\n\n\t\t\t// Check if we should render\n\t\t\tcurrentTickLength = performance.now() - start\n\n\t\t\tif (currentTickLength > TICK_LENGTH) {\n\t\t\t\t// Calculate the FPS and paint it\n\t\t\t\tconst fps = Math.round(\n\t\t\t\t\tframesInCurrentTick * (TICK_LENGTH / currentTickLength) * (1000 / TICK_LENGTH)\n\t\t\t\t)\n\n\t\t\t\tif (fps > maxKnownFps) {\n\t\t\t\t\tmaxKnownFps = fps\n\t\t\t\t}\n\n\t\t\t\tconst slowFps = maxKnownFps * 0.75\n\t\t\t\tif ((fps < slowFps && !isSlow) || (fps >= slowFps && isSlow)) {\n\t\t\t\t\tisSlow = !isSlow\n\t\t\t\t}\n\n\t\t\t\tfpsRef.current!.innerHTML = `FPS ${fps.toString()}`\n\t\t\t\tfpsRef.current!.className =\n\t\t\t\t\t`tlui-debug-panel__fps` + (isSlow ? ` tlui-debug-panel__fps__slow` : ``)\n\n\t\t\t\t// Reset the values\n\t\t\t\tcurrentTickLength -= TICK_LENGTH\n\t\t\t\tframesInCurrentTick = 0\n\t\t\t\tstart = performance.now()\n\t\t\t}\n\n\t\t\traf = editor.timers.requestAnimationFrame(loop)\n\t\t}\n\n\t\tloop()\n\n\t\treturn () => {\n\t\t\tcancelAnimationFrame(raf)\n\t\t}\n\t}, [showFps, editor])\n\n\tif (!showFps) return null\n\n\treturn <div ref={fpsRef} />\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["DefaultDebugPanel", "CurrentState"]
7
7
  }
@@ -21,18 +21,10 @@ function validateUrl(url) {
21
21
  }
22
22
  return { isValid: false, hasProtocol: false };
23
23
  }
24
- function isShapeWithUrl(shape) {
25
- return !!(shape && "url" in shape.props && typeof shape.props.url === "string");
26
- }
27
- function assertShapeWithUrl(shape) {
28
- if (!isShapeWithUrl(shape)) {
29
- throw new Error("Shape is not a valid ShapeWithUrl");
30
- }
31
- }
32
24
  const EditLinkDialog = track(function EditLinkDialog2({ onClose }) {
33
25
  const editor = useEditor();
34
26
  const selectedShape = editor.getOnlySelectedShape();
35
- if (!isShapeWithUrl(selectedShape)) {
27
+ if (!(selectedShape && "url" in selectedShape.props && typeof selectedShape.props.url === "string")) {
36
28
  return null;
37
29
  }
38
30
  return /* @__PURE__ */ jsx(EditLinkDialogInner, { onClose, selectedShape });
@@ -72,7 +64,6 @@ const EditLinkDialogInner = track(function EditLinkDialogInner2({
72
64
  const handleClear = useCallback(() => {
73
65
  const onlySelectedShape = editor.getOnlySelectedShape();
74
66
  if (!onlySelectedShape) return;
75
- assertShapeWithUrl(onlySelectedShape);
76
67
  editor.updateShapes([
77
68
  { id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: "" } }
78
69
  ]);
@@ -81,7 +72,6 @@ const EditLinkDialogInner = track(function EditLinkDialogInner2({
81
72
  const handleComplete = useCallback(() => {
82
73
  const onlySelectedShape = editor.getOnlySelectedShape();
83
74
  if (!onlySelectedShape) return;
84
- assertShapeWithUrl(onlySelectedShape);
85
75
  if (onlySelectedShape && "url" in onlySelectedShape.props) {
86
76
  if (onlySelectedShape.props.url !== urlInputState.safe) {
87
77
  editor.updateShapes([
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/components/EditLinkDialog.tsx"],
4
- "sourcesContent": ["import { ExtractShapeByProps, T, TLShape, track, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { TLUiDialogProps } from '../context/dialogs'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonLabel } from './primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiDialogBody,\n\tTldrawUiDialogCloseButton,\n\tTldrawUiDialogFooter,\n\tTldrawUiDialogHeader,\n\tTldrawUiDialogTitle,\n} from './primitives/TldrawUiDialog'\nimport { TldrawUiInput } from './primitives/TldrawUiInput'\n\n// A url can either be invalid, or valid with a protocol, or valid without a protocol.\n// For example, \"aol.com\" would be valid with a protocol ()\nfunction validateUrl(url: string) {\n\tif (T.linkUrl.isValid(url)) {\n\t\treturn { isValid: true, hasProtocol: true }\n\t}\n\tif (T.linkUrl.isValid('https://' + url)) {\n\t\treturn { isValid: true, hasProtocol: false }\n\t}\n\treturn { isValid: false, hasProtocol: false }\n}\n\ntype ShapeWithUrl = ExtractShapeByProps<{ url: string }>\n\nfunction isShapeWithUrl(shape: TLShape | null | undefined): shape is ShapeWithUrl {\n\treturn !!(shape && 'url' in shape.props && typeof shape.props.url === 'string')\n}\n\nfunction assertShapeWithUrl(shape: TLShape | null | undefined): asserts shape is ShapeWithUrl {\n\tif (!isShapeWithUrl(shape)) {\n\t\tthrow new Error('Shape is not a valid ShapeWithUrl')\n\t}\n}\n\nexport const EditLinkDialog = track(function EditLinkDialog({ onClose }: TLUiDialogProps) {\n\tconst editor = useEditor()\n\n\tconst selectedShape = editor.getOnlySelectedShape()\n\n\tif (!isShapeWithUrl(selectedShape)) {\n\t\treturn null\n\t}\n\n\treturn <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape} />\n})\n\nexport const EditLinkDialogInner = track(function EditLinkDialogInner({\n\tonClose,\n\tselectedShape,\n}: TLUiDialogProps & { selectedShape: ShapeWithUrl }) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst rInput = useRef<HTMLInputElement>(null)\n\n\tuseEffect(() => {\n\t\teditor.timers.requestAnimationFrame(() => rInput.current?.focus())\n\t}, [editor])\n\n\tconst rInitialValue = useRef(selectedShape.props.url)\n\n\tconst [urlInputState, setUrlInputState] = useState(() => {\n\t\tconst urlValidResult = validateUrl(selectedShape.props.url)\n\n\t\tconst initialValue =\n\t\t\turlValidResult.isValid === true\n\t\t\t\t? urlValidResult.hasProtocol\n\t\t\t\t\t? selectedShape.props.url\n\t\t\t\t\t: 'https://' + selectedShape.props.url\n\t\t\t\t: 'https://'\n\n\t\treturn {\n\t\t\tactual: initialValue,\n\t\t\tsafe: initialValue,\n\t\t\tvalid: true,\n\t\t}\n\t})\n\n\tconst handleChange = useCallback((rawValue: string) => {\n\t\t// Just auto-correct double https:// from a bad paste.\n\t\tconst fixedRawValue = rawValue.replace(/https?:\\/\\/(https?:\\/\\/)/, (_match, arg1) => {\n\t\t\treturn arg1\n\t\t})\n\n\t\tconst urlValidResult = validateUrl(fixedRawValue)\n\n\t\tconst safeValue =\n\t\t\turlValidResult.isValid === true\n\t\t\t\t? urlValidResult.hasProtocol\n\t\t\t\t\t? fixedRawValue\n\t\t\t\t\t: 'https://' + fixedRawValue\n\t\t\t\t: 'https://'\n\n\t\tsetUrlInputState({\n\t\t\tactual: fixedRawValue,\n\t\t\tsafe: safeValue,\n\t\t\tvalid: urlValidResult.isValid,\n\t\t})\n\t}, [])\n\n\tconst handleClear = useCallback(() => {\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return\n\t\tassertShapeWithUrl(onlySelectedShape)\n\t\teditor.updateShapes([\n\t\t\t{ id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: '' } },\n\t\t])\n\t\tonClose()\n\t}, [editor, onClose])\n\n\tconst handleComplete = useCallback(() => {\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\t\tif (!onlySelectedShape) return\n\t\tassertShapeWithUrl(onlySelectedShape)\n\n\t\t// ? URL is a magic value\n\t\tif (onlySelectedShape && 'url' in onlySelectedShape.props) {\n\t\t\t// Here would be a good place to validate the next shape\u2014would setting the empty\n\t\t\tif (onlySelectedShape.props.url !== urlInputState.safe) {\n\t\t\t\teditor.updateShapes([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: onlySelectedShape.id,\n\t\t\t\t\t\ttype: onlySelectedShape.type,\n\t\t\t\t\t\tprops: { url: urlInputState.safe },\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t}\n\t\t}\n\t\tonClose()\n\t}, [editor, onClose, urlInputState])\n\n\tconst handleCancel = useCallback(() => {\n\t\tonClose()\n\t}, [onClose])\n\n\tif (!selectedShape) {\n\t\t// dismiss modal\n\t\tonClose()\n\t\treturn null\n\t}\n\n\t// Are we going from a valid state to an invalid state?\n\tconst isRemoving = rInitialValue.current && !urlInputState.valid\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiDialogHeader>\n\t\t\t\t<TldrawUiDialogTitle>{msg('edit-link-dialog.title')}</TldrawUiDialogTitle>\n\t\t\t\t<TldrawUiDialogCloseButton />\n\t\t\t</TldrawUiDialogHeader>\n\t\t\t<TldrawUiDialogBody>\n\t\t\t\t<div className=\"tlui-edit-link-dialog\">\n\t\t\t\t\t<TldrawUiInput\n\t\t\t\t\t\tref={rInput}\n\t\t\t\t\t\tclassName=\"tlui-edit-link-dialog__input\"\n\t\t\t\t\t\tlabel=\"edit-link-dialog.url\"\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tautoSelect\n\t\t\t\t\t\tplaceholder=\"https://example.com\"\n\t\t\t\t\t\tvalue={urlInputState.actual}\n\t\t\t\t\t\tonValueChange={handleChange}\n\t\t\t\t\t\tonComplete={handleComplete}\n\t\t\t\t\t\tonCancel={handleCancel}\n\t\t\t\t\t/>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{urlInputState.valid\n\t\t\t\t\t\t\t? msg('edit-link-dialog.detail')\n\t\t\t\t\t\t\t: msg('edit-link-dialog.invalid-url')}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiDialogBody>\n\t\t\t<TldrawUiDialogFooter className=\"tlui-dialog__footer__actions\">\n\t\t\t\t<TldrawUiButton type=\"normal\" onClick={handleCancel} onTouchEnd={handleCancel}>\n\t\t\t\t\t<TldrawUiButtonLabel>{msg('edit-link-dialog.cancel')}</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t\t{isRemoving ? (\n\t\t\t\t\t<TldrawUiButton type={'danger'} onTouchEnd={handleClear} onClick={handleClear}>\n\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('edit-link-dialog.clear')}</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t) : (\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"primary\"\n\t\t\t\t\t\tdisabled={!urlInputState.valid}\n\t\t\t\t\t\tonTouchEnd={handleComplete}\n\t\t\t\t\t\tonClick={handleComplete}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('edit-link-dialog.save')}</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t)}\n\t\t\t</TldrawUiDialogFooter>\n\t\t</>\n\t)\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { T, TLBaseShape, track, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { TLUiDialogProps } from '../context/dialogs'\nimport { useTranslation } from '../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from './primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonLabel } from './primitives/Button/TldrawUiButtonLabel'\nimport {\n\tTldrawUiDialogBody,\n\tTldrawUiDialogCloseButton,\n\tTldrawUiDialogFooter,\n\tTldrawUiDialogHeader,\n\tTldrawUiDialogTitle,\n} from './primitives/TldrawUiDialog'\nimport { TldrawUiInput } from './primitives/TldrawUiInput'\n\n// A url can either be invalid, or valid with a protocol, or valid without a protocol.\n// For example, \"aol.com\" would be valid with a protocol ()\nfunction validateUrl(url: string) {\n\tif (T.linkUrl.isValid(url)) {\n\t\treturn { isValid: true, hasProtocol: true }\n\t}\n\tif (T.linkUrl.isValid('https://' + url)) {\n\t\treturn { isValid: true, hasProtocol: false }\n\t}\n\treturn { isValid: false, hasProtocol: false }\n}\n\ntype ShapeWithUrl = TLBaseShape<string, { url: string }>\n\nexport const EditLinkDialog = track(function EditLinkDialog({ onClose }: TLUiDialogProps) {\n\tconst editor = useEditor()\n\n\tconst selectedShape = editor.getOnlySelectedShape()\n\n\tif (\n\t\t!(selectedShape && 'url' in selectedShape.props && typeof selectedShape.props.url === 'string')\n\t) {\n\t\treturn null\n\t}\n\n\treturn <EditLinkDialogInner onClose={onClose} selectedShape={selectedShape as ShapeWithUrl} />\n})\n\nexport const EditLinkDialogInner = track(function EditLinkDialogInner({\n\tonClose,\n\tselectedShape,\n}: TLUiDialogProps & { selectedShape: ShapeWithUrl }) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst rInput = useRef<HTMLInputElement>(null)\n\n\tuseEffect(() => {\n\t\teditor.timers.requestAnimationFrame(() => rInput.current?.focus())\n\t}, [editor])\n\n\tconst rInitialValue = useRef(selectedShape.props.url)\n\n\tconst [urlInputState, setUrlInputState] = useState(() => {\n\t\tconst urlValidResult = validateUrl(selectedShape.props.url)\n\n\t\tconst initialValue =\n\t\t\turlValidResult.isValid === true\n\t\t\t\t? urlValidResult.hasProtocol\n\t\t\t\t\t? selectedShape.props.url\n\t\t\t\t\t: 'https://' + selectedShape.props.url\n\t\t\t\t: 'https://'\n\n\t\treturn {\n\t\t\tactual: initialValue,\n\t\t\tsafe: initialValue,\n\t\t\tvalid: true,\n\t\t}\n\t})\n\n\tconst handleChange = useCallback((rawValue: string) => {\n\t\t// Just auto-correct double https:// from a bad paste.\n\t\tconst fixedRawValue = rawValue.replace(/https?:\\/\\/(https?:\\/\\/)/, (_match, arg1) => {\n\t\t\treturn arg1\n\t\t})\n\n\t\tconst urlValidResult = validateUrl(fixedRawValue)\n\n\t\tconst safeValue =\n\t\t\turlValidResult.isValid === true\n\t\t\t\t? urlValidResult.hasProtocol\n\t\t\t\t\t? fixedRawValue\n\t\t\t\t\t: 'https://' + fixedRawValue\n\t\t\t\t: 'https://'\n\n\t\tsetUrlInputState({\n\t\t\tactual: fixedRawValue,\n\t\t\tsafe: safeValue,\n\t\t\tvalid: urlValidResult.isValid,\n\t\t})\n\t}, [])\n\n\tconst handleClear = useCallback(() => {\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return\n\t\teditor.updateShapes([\n\t\t\t{ id: onlySelectedShape.id, type: onlySelectedShape.type, props: { url: '' } },\n\t\t])\n\t\tonClose()\n\t}, [editor, onClose])\n\n\tconst handleComplete = useCallback(() => {\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\n\t\tif (!onlySelectedShape) return\n\n\t\t// ? URL is a magic value\n\t\tif (onlySelectedShape && 'url' in onlySelectedShape.props) {\n\t\t\t// Here would be a good place to validate the next shape\u2014would setting the empty\n\t\t\tif (onlySelectedShape.props.url !== urlInputState.safe) {\n\t\t\t\teditor.updateShapes([\n\t\t\t\t\t{\n\t\t\t\t\t\tid: onlySelectedShape.id,\n\t\t\t\t\t\ttype: onlySelectedShape.type,\n\t\t\t\t\t\tprops: { url: urlInputState.safe },\n\t\t\t\t\t},\n\t\t\t\t])\n\t\t\t}\n\t\t}\n\t\tonClose()\n\t}, [editor, onClose, urlInputState])\n\n\tconst handleCancel = useCallback(() => {\n\t\tonClose()\n\t}, [onClose])\n\n\tif (!selectedShape) {\n\t\t// dismiss modal\n\t\tonClose()\n\t\treturn null\n\t}\n\n\t// Are we going from a valid state to an invalid state?\n\tconst isRemoving = rInitialValue.current && !urlInputState.valid\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiDialogHeader>\n\t\t\t\t<TldrawUiDialogTitle>{msg('edit-link-dialog.title')}</TldrawUiDialogTitle>\n\t\t\t\t<TldrawUiDialogCloseButton />\n\t\t\t</TldrawUiDialogHeader>\n\t\t\t<TldrawUiDialogBody>\n\t\t\t\t<div className=\"tlui-edit-link-dialog\">\n\t\t\t\t\t<TldrawUiInput\n\t\t\t\t\t\tref={rInput}\n\t\t\t\t\t\tclassName=\"tlui-edit-link-dialog__input\"\n\t\t\t\t\t\tlabel=\"edit-link-dialog.url\"\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tautoSelect\n\t\t\t\t\t\tplaceholder=\"https://example.com\"\n\t\t\t\t\t\tvalue={urlInputState.actual}\n\t\t\t\t\t\tonValueChange={handleChange}\n\t\t\t\t\t\tonComplete={handleComplete}\n\t\t\t\t\t\tonCancel={handleCancel}\n\t\t\t\t\t/>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{urlInputState.valid\n\t\t\t\t\t\t\t? msg('edit-link-dialog.detail')\n\t\t\t\t\t\t\t: msg('edit-link-dialog.invalid-url')}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</TldrawUiDialogBody>\n\t\t\t<TldrawUiDialogFooter className=\"tlui-dialog__footer__actions\">\n\t\t\t\t<TldrawUiButton type=\"normal\" onClick={handleCancel} onTouchEnd={handleCancel}>\n\t\t\t\t\t<TldrawUiButtonLabel>{msg('edit-link-dialog.cancel')}</TldrawUiButtonLabel>\n\t\t\t\t</TldrawUiButton>\n\t\t\t\t{isRemoving ? (\n\t\t\t\t\t<TldrawUiButton type={'danger'} onTouchEnd={handleClear} onClick={handleClear}>\n\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('edit-link-dialog.clear')}</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t) : (\n\t\t\t\t\t<TldrawUiButton\n\t\t\t\t\t\ttype=\"primary\"\n\t\t\t\t\t\tdisabled={!urlInputState.valid}\n\t\t\t\t\t\tonTouchEnd={handleComplete}\n\t\t\t\t\t\tonClick={handleComplete}\n\t\t\t\t\t>\n\t\t\t\t\t\t<TldrawUiButtonLabel>{msg('edit-link-dialog.save')}</TldrawUiButtonLabel>\n\t\t\t\t\t</TldrawUiButton>\n\t\t\t\t)}\n\t\t\t</TldrawUiDialogFooter>\n\t\t</>\n\t)\n})\n"],
5
+ "mappings": "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",
6
6
  "names": ["EditLinkDialog", "EditLinkDialogInner"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/HelperButtons/StopFollowing.tsx"],
4
- "sourcesContent": ["import { useEditor, useValue } from '@tldraw/editor'\nimport { useActions } from '../../context/actions'\nimport { TldrawUiMenuItem, type TLUiMenuItemProps } from '../primitives/menus/TldrawUiMenuItem'\n\nexport function StopFollowing() {\n\tconst editor = useEditor()\n\tconst actions = useActions()\n\n\tconst followingUser = useValue(\n\t\t'is following user',\n\t\t() => !!editor.getInstanceState().followingUserId,\n\t\t[editor]\n\t)\n\tif (!followingUser) return null\n\n\treturn <TldrawUiMenuItem {...(actions['stop-following'] as TLUiMenuItemProps)} />\n}\n"],
5
- "mappings": "AAeQ;AAfR,SAAS,WAAW,gBAAgB;AACpC,SAAS,kBAAkB;AAC3B,SAAS,wBAAgD;AAElD,SAAS,gBAAgB;AAC/B,QAAM,SAAS,UAAU;AACzB,QAAM,UAAU,WAAW;AAE3B,QAAM,gBAAgB;AAAA,IACrB;AAAA,IACA,MAAM,CAAC,CAAC,OAAO,iBAAiB,EAAE;AAAA,IAClC,CAAC,MAAM;AAAA,EACR;AACA,MAAI,CAAC,cAAe,QAAO;AAE3B,SAAO,oBAAC,oBAAkB,GAAI,QAAQ,gBAAgB,GAAyB;AAChF;",
4
+ "sourcesContent": ["import { useEditor, useValue } from '@tldraw/editor'\nimport { useActions } from '../../context/actions'\nimport { TldrawUiMenuItem } from '../primitives/menus/TldrawUiMenuItem'\n\nexport function StopFollowing() {\n\tconst editor = useEditor()\n\tconst actions = useActions()\n\n\tconst followingUser = useValue(\n\t\t'is following user',\n\t\t() => !!editor.getInstanceState().followingUserId,\n\t\t[editor]\n\t)\n\tif (!followingUser) return null\n\n\treturn <TldrawUiMenuItem {...actions['stop-following']} />\n}\n"],
5
+ "mappings": "AAeQ;AAfR,SAAS,WAAW,gBAAgB;AACpC,SAAS,kBAAkB;AAC3B,SAAS,wBAAwB;AAE1B,SAAS,gBAAgB;AAC/B,QAAM,SAAS,UAAU;AACzB,QAAM,UAAU,WAAW;AAE3B,QAAM,gBAAgB;AAAA,IACrB;AAAA,IACA,MAAM,CAAC,CAAC,OAAO,iBAAiB,EAAE;AAAA,IAClC,CAAC,MAAM;AAAA,EACR;AACA,MAAI,CAAC,cAAe,QAAO;AAE3B,SAAO,oBAAC,oBAAkB,GAAG,QAAQ,gBAAgB,GAAG;AACzD;",
6
6
  "names": []
7
7
  }
@@ -20,7 +20,7 @@ function DefaultMinimap() {
20
20
  const msg = useTranslation();
21
21
  const rCanvas = React.useRef(null);
22
22
  const rPointing = React.useRef(false);
23
- const minimapRef = React.useRef(void 0);
23
+ const minimapRef = React.useRef();
24
24
  React.useEffect(() => {
25
25
  try {
26
26
  const minimap = new MinimapManager(editor, rCanvas.current, container);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/Minimap/DefaultMinimap.tsx"],
4
- "sourcesContent": ["import {\n\tBox,\n\tTLPointerEventInfo,\n\tVec,\n\tgetPointerInfo,\n\tisAccelKey,\n\tnormalizeWheel,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseIsDarkMode,\n} from '@tldraw/editor'\nimport * as React from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { MinimapManager } from './MinimapManager'\n\n/** @public @react */\nexport function DefaultMinimap() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\tconst msg = useTranslation()\n\n\tconst rCanvas = React.useRef<HTMLCanvasElement>(null!)\n\tconst rPointing = React.useRef(false)\n\n\tconst minimapRef = React.useRef<MinimapManager | undefined>(undefined)\n\n\tReact.useEffect(() => {\n\t\ttry {\n\t\t\tconst minimap = new MinimapManager(editor, rCanvas.current, container)\n\t\t\tminimapRef.current = minimap\n\t\t\treturn minimapRef.current.close\n\t\t} catch (e) {\n\t\t\teditor.annotateError(e, {\n\t\t\t\torigin: 'minimap',\n\t\t\t\twillCrashApp: false,\n\t\t\t})\n\t\t\teditor.timers.setTimeout(() => {\n\t\t\t\tthrow e\n\t\t\t})\n\t\t}\n\t}, [editor, container])\n\n\tconst onDoubleClick = React.useCallback(\n\t\t(e: React.MouseEvent<HTMLCanvasElement>) => {\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\t\t\tif (!minimapRef.current) return\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\tminimapRef.current.originPageCenter.setTo(editor.getViewportPageBounds().center)\n\n\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerDown = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst elm = e.currentTarget\n\t\t\tsetPointerCapture(elm, e)\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\n\t\t\trPointing.current = true\n\n\t\t\tminimapRef.current.isInViewport = false\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst _vpPageBounds = editor.getViewportPageBounds()\n\t\t\tconst commonBounds = minimapRef.current.getContentPageBounds()\n\t\t\tconst allowedBounds = new Box(\n\t\t\t\tcommonBounds.x - _vpPageBounds.width / 2,\n\t\t\t\tcommonBounds.y - _vpPageBounds.height / 2,\n\t\t\t\tcommonBounds.width + _vpPageBounds.width,\n\t\t\t\tcommonBounds.height + _vpPageBounds.height\n\t\t\t)\n\n\t\t\t// If we clicked inside of the allowed area, but outside of the viewport\n\t\t\tif (allowedBounds.containsPoint(point) && !_vpPageBounds.containsPoint(point)) {\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(point)\n\t\t\t\tconst delta = Vec.Sub(_vpPageBounds.center, _vpPageBounds.point)\n\t\t\t\tconst pagePoint = Vec.Add(point, delta)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(pagePoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(point)\n\t\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t\t} else {\n\t\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\t\te.clientX,\n\t\t\t\t\te.clientY,\n\t\t\t\t\tfalse,\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(_vpPageBounds.center)\n\t\t\t}\n\n\t\t\tfunction release(e: PointerEvent) {\n\t\t\t\tif (elm) {\n\t\t\t\t\treleasePointerCapture(elm, e)\n\t\t\t\t}\n\t\t\t\trPointing.current = false\n\t\t\t\tdocument.body.removeEventListener('pointerup', release)\n\t\t\t}\n\n\t\t\tdocument.body.addEventListener('pointerup', release)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerMove = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\te.shiftKey,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tif (rPointing.current) {\n\t\t\t\tif (minimapRef.current.isInViewport) {\n\t\t\t\t\tconst delta = minimapRef.current.originPagePoint\n\t\t\t\t\t\t.clone()\n\t\t\t\t\t\t.sub(minimapRef.current.originPageCenter)\n\t\t\t\t\teditor.centerOnPoint(Vec.Sub(point, delta))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\teditor.centerOnPoint(point)\n\t\t\t}\n\n\t\t\tconst pagePoint = minimapRef.current.getMinimapPagePoint(e.clientX, e.clientY)\n\n\t\t\tconst screenPoint = editor.pageToScreen(pagePoint)\n\n\t\t\tconst info: TLPointerEventInfo = {\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\tpoint: screenPoint,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onWheel = React.useCallback(\n\t\t(e: React.WheelEvent<HTMLCanvasElement>) => {\n\t\t\tconst offset = normalizeWheel(e)\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'wheel',\n\t\t\t\tname: 'wheel',\n\t\t\t\tdelta: offset,\n\t\t\t\tpoint: new Vec(e.clientX, e.clientY),\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t})\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst isDarkMode = useIsDarkMode()\n\n\tReact.useEffect(() => {\n\t\t// need to wait a tick for next theme css to be applied\n\t\t// otherwise the minimap will render with the wrong colors\n\t\teditor.timers.setTimeout(() => {\n\t\t\tminimapRef.current?.updateColors()\n\t\t\tminimapRef.current?.render()\n\t\t})\n\t}, [isDarkMode, editor])\n\n\treturn (\n\t\t<div className=\"tlui-minimap\">\n\t\t\t<canvas\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={msg('navigation-zone.minimap')}\n\t\t\t\tdata-testid=\"minimap.canvas\"\n\t\t\t\tref={rCanvas}\n\t\t\t\tclassName=\"tlui-minimap__canvas\"\n\t\t\t\tonDoubleClick={onDoubleClick}\n\t\t\t\tonPointerMove={onPointerMove}\n\t\t\t\tonPointerDown={onPointerDown}\n\t\t\t\tonWheelCapture={onWheel}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tTLPointerEventInfo,\n\tVec,\n\tgetPointerInfo,\n\tisAccelKey,\n\tnormalizeWheel,\n\treleasePointerCapture,\n\tsetPointerCapture,\n\tuseContainer,\n\tuseEditor,\n\tuseIsDarkMode,\n} from '@tldraw/editor'\nimport * as React from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { MinimapManager } from './MinimapManager'\n\n/** @public @react */\nexport function DefaultMinimap() {\n\tconst editor = useEditor()\n\tconst container = useContainer()\n\tconst msg = useTranslation()\n\n\tconst rCanvas = React.useRef<HTMLCanvasElement>(null!)\n\tconst rPointing = React.useRef(false)\n\n\tconst minimapRef = React.useRef<MinimapManager>()\n\n\tReact.useEffect(() => {\n\t\ttry {\n\t\t\tconst minimap = new MinimapManager(editor, rCanvas.current, container)\n\t\t\tminimapRef.current = minimap\n\t\t\treturn minimapRef.current.close\n\t\t} catch (e) {\n\t\t\teditor.annotateError(e, {\n\t\t\t\torigin: 'minimap',\n\t\t\t\twillCrashApp: false,\n\t\t\t})\n\t\t\teditor.timers.setTimeout(() => {\n\t\t\t\tthrow e\n\t\t\t})\n\t\t}\n\t}, [editor, container])\n\n\tconst onDoubleClick = React.useCallback(\n\t\t(e: React.MouseEvent<HTMLCanvasElement>) => {\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\t\t\tif (!minimapRef.current) return\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\tminimapRef.current.originPageCenter.setTo(editor.getViewportPageBounds().center)\n\n\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerDown = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst elm = e.currentTarget\n\t\t\tsetPointerCapture(elm, e)\n\t\t\tif (!editor.getCurrentPageShapeIds().size) return\n\n\t\t\trPointing.current = true\n\n\t\t\tminimapRef.current.isInViewport = false\n\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\tfalse,\n\t\t\t\tfalse\n\t\t\t)\n\n\t\t\tconst _vpPageBounds = editor.getViewportPageBounds()\n\t\t\tconst commonBounds = minimapRef.current.getContentPageBounds()\n\t\t\tconst allowedBounds = new Box(\n\t\t\t\tcommonBounds.x - _vpPageBounds.width / 2,\n\t\t\t\tcommonBounds.y - _vpPageBounds.height / 2,\n\t\t\t\tcommonBounds.width + _vpPageBounds.width,\n\t\t\t\tcommonBounds.height + _vpPageBounds.height\n\t\t\t)\n\n\t\t\t// If we clicked inside of the allowed area, but outside of the viewport\n\t\t\tif (allowedBounds.containsPoint(point) && !_vpPageBounds.containsPoint(point)) {\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(point)\n\t\t\t\tconst delta = Vec.Sub(_vpPageBounds.center, _vpPageBounds.point)\n\t\t\t\tconst pagePoint = Vec.Add(point, delta)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(pagePoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(point)\n\t\t\t\teditor.centerOnPoint(point, { animation: { duration: editor.options.animationMediumMs } })\n\t\t\t} else {\n\t\t\t\tconst clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\t\te.clientX,\n\t\t\t\t\te.clientY,\n\t\t\t\t\tfalse,\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t\tminimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)\n\t\t\t\tminimapRef.current.originPagePoint.setTo(clampedPoint)\n\t\t\t\tminimapRef.current.originPageCenter.setTo(_vpPageBounds.center)\n\t\t\t}\n\n\t\t\tfunction release(e: PointerEvent) {\n\t\t\t\tif (elm) {\n\t\t\t\t\treleasePointerCapture(elm, e)\n\t\t\t\t}\n\t\t\t\trPointing.current = false\n\t\t\t\tdocument.body.removeEventListener('pointerup', release)\n\t\t\t}\n\n\t\t\tdocument.body.addEventListener('pointerup', release)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onPointerMove = React.useCallback(\n\t\t(e: React.PointerEvent<HTMLCanvasElement>) => {\n\t\t\tif (!minimapRef.current) return\n\t\t\tconst point = minimapRef.current.minimapScreenPointToPagePoint(\n\t\t\t\te.clientX,\n\t\t\t\te.clientY,\n\t\t\t\te.shiftKey,\n\t\t\t\ttrue\n\t\t\t)\n\n\t\t\tif (rPointing.current) {\n\t\t\t\tif (minimapRef.current.isInViewport) {\n\t\t\t\t\tconst delta = minimapRef.current.originPagePoint\n\t\t\t\t\t\t.clone()\n\t\t\t\t\t\t.sub(minimapRef.current.originPageCenter)\n\t\t\t\t\teditor.centerOnPoint(Vec.Sub(point, delta))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\teditor.centerOnPoint(point)\n\t\t\t}\n\n\t\t\tconst pagePoint = minimapRef.current.getMinimapPagePoint(e.clientX, e.clientY)\n\n\t\t\tconst screenPoint = editor.pageToScreen(pagePoint)\n\n\t\t\tconst info: TLPointerEventInfo = {\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\tpoint: screenPoint,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst onWheel = React.useCallback(\n\t\t(e: React.WheelEvent<HTMLCanvasElement>) => {\n\t\t\tconst offset = normalizeWheel(e)\n\n\t\t\teditor.dispatch({\n\t\t\t\ttype: 'wheel',\n\t\t\t\tname: 'wheel',\n\t\t\t\tdelta: offset,\n\t\t\t\tpoint: new Vec(e.clientX, e.clientY),\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t})\n\t\t},\n\t\t[editor]\n\t)\n\n\tconst isDarkMode = useIsDarkMode()\n\n\tReact.useEffect(() => {\n\t\t// need to wait a tick for next theme css to be applied\n\t\t// otherwise the minimap will render with the wrong colors\n\t\teditor.timers.setTimeout(() => {\n\t\t\tminimapRef.current?.updateColors()\n\t\t\tminimapRef.current?.render()\n\t\t})\n\t}, [isDarkMode, editor])\n\n\treturn (\n\t\t<div className=\"tlui-minimap\">\n\t\t\t<canvas\n\t\t\t\trole=\"img\"\n\t\t\t\taria-label={msg('navigation-zone.minimap')}\n\t\t\t\tdata-testid=\"minimap.canvas\"\n\t\t\t\tref={rCanvas}\n\t\t\t\tclassName=\"tlui-minimap__canvas\"\n\t\t\t\tonDoubleClick={onDoubleClick}\n\t\t\t\tonPointerMove={onPointerMove}\n\t\t\t\tonPointerDown={onPointerDown}\n\t\t\t\tonWheelCapture={onWheel}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["e"]
7
7
  }
@@ -1,10 +1,13 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import classNames from "classnames";
2
3
  import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs";
3
4
  import { TldrawUiIcon } from "../primitives/TldrawUiIcon.mjs";
4
- import { TldrawUiTooltip } from "../primitives/TldrawUiTooltip.mjs";
5
5
  function OfflineIndicator() {
6
6
  const msg = useTranslation();
7
- return /* @__PURE__ */ jsx(TldrawUiTooltip, { content: msg("status.offline"), children: /* @__PURE__ */ jsx("div", { className: "tlui-offline-indicator", children: /* @__PURE__ */ jsx(TldrawUiIcon, { icon: "status-offline", label: msg("status.offline"), small: true }) }) });
7
+ return /* @__PURE__ */ jsxs("div", { className: classNames("tlui-offline-indicator"), children: [
8
+ msg("status.offline"),
9
+ /* @__PURE__ */ jsx(TldrawUiIcon, { label: msg("status.offline"), icon: "status-offline", small: true })
10
+ ] });
8
11
  }
9
12
  export {
10
13
  OfflineIndicator
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/OfflineIndicator/OfflineIndicator.tsx"],
4
- "sourcesContent": ["import { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiIcon } from '../primitives/TldrawUiIcon'\nimport { TldrawUiTooltip } from '../primitives/TldrawUiTooltip'\n\n/** @public @react */\nexport function OfflineIndicator() {\n\tconst msg = useTranslation()\n\n\treturn (\n\t\t<TldrawUiTooltip content={msg('status.offline')}>\n\t\t\t<div className=\"tlui-offline-indicator\">\n\t\t\t\t<TldrawUiIcon icon=\"status-offline\" label={msg('status.offline')} small />\n\t\t\t</div>\n\t\t</TldrawUiTooltip>\n\t)\n}\n"],
5
- "mappings": "AAWI;AAXJ,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAGzB,SAAS,mBAAmB;AAClC,QAAM,MAAM,eAAe;AAE3B,SACC,oBAAC,mBAAgB,SAAS,IAAI,gBAAgB,GAC7C,8BAAC,SAAI,WAAU,0BACd,8BAAC,gBAAa,MAAK,kBAAiB,OAAO,IAAI,gBAAgB,GAAG,OAAK,MAAC,GACzE,GACD;AAEF;",
4
+ "sourcesContent": ["import classNames from 'classnames'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiIcon } from '../primitives/TldrawUiIcon'\n\n/** @public @react */\nexport function OfflineIndicator() {\n\tconst msg = useTranslation()\n\n\treturn (\n\t\t<div className={classNames('tlui-offline-indicator')}>\n\t\t\t{msg('status.offline')}\n\t\t\t<TldrawUiIcon label={msg('status.offline')} icon=\"status-offline\" small />\n\t\t</div>\n\t)\n}\n"],
5
+ "mappings": "AASE,SAEC,KAFD;AATF,OAAO,gBAAgB;AACvB,SAAS,sBAAsB;AAC/B,SAAS,oBAAoB;AAGtB,SAAS,mBAAmB;AAClC,QAAM,MAAM,eAAe;AAE3B,SACC,qBAAC,SAAI,WAAW,WAAW,wBAAwB,GACjD;AAAA,QAAI,gBAAgB;AAAA,IACrB,oBAAC,gBAAa,OAAO,IAAI,gBAAgB,GAAG,MAAK,kBAAiB,OAAK,MAAC;AAAA,KACzE;AAEF;",
6
6
  "names": []
7
7
  }
@@ -34,9 +34,7 @@ const PageItemInput = function PageItemInput2({
34
34
  TldrawUiInput,
35
35
  {
36
36
  className: "tlui-page-menu__item__input",
37
- ref: (el) => {
38
- rInput.current = el;
39
- },
37
+ ref: (el) => rInput.current = el,
40
38
  defaultValue: name,
41
39
  onValueChange: handleChange,
42
40
  onComplete,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/PageMenu/PageItemInput.tsx"],
4
- "sourcesContent": ["import { TLPageId, useEditor } from '@tldraw/editor'\nimport { useCallback, useRef } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { TldrawUiInput } from '../primitives/TldrawUiInput'\n\n/** @public */\nexport interface PageItemInputProps {\n\tname: string\n\tid: TLPageId\n\tisCurrentPage: boolean\n\tonCancel(): void\n\tonComplete?(): void\n}\n\n/** @public @react */\nexport const PageItemInput = function PageItemInput({\n\tname,\n\tid,\n\tisCurrentPage,\n\tonCancel,\n\tonComplete,\n}: PageItemInputProps) {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst rInput = useRef<HTMLInputElement | null>(null)\n\tconst rMark = useRef<string | null>(null)\n\n\tconst handleFocus = useCallback(() => {\n\t\trMark.current = editor.markHistoryStoppingPoint('rename page')\n\t}, [editor])\n\n\tconst handleChange = useCallback(\n\t\t(value: string) => {\n\t\t\teditor.renamePage(id, value || 'New Page')\n\t\t\ttrackEvent('rename-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, id, trackEvent]\n\t)\n\n\tconst handleCancel = useCallback(() => {\n\t\tif (rMark.current) {\n\t\t\teditor.bailToMark(rMark.current)\n\t\t}\n\t\tonCancel()\n\t}, [editor, onCancel])\n\n\treturn (\n\t\t<TldrawUiInput\n\t\t\tclassName=\"tlui-page-menu__item__input\"\n\t\t\tref={(el) => {\n\t\t\t\trInput.current = el\n\t\t\t}}\n\t\t\tdefaultValue={name}\n\t\t\tonValueChange={handleChange}\n\t\t\tonComplete={onComplete}\n\t\t\tonCancel={handleCancel}\n\t\t\tonFocus={handleFocus}\n\t\t\tshouldManuallyMaintainScrollPositionWhenFocused\n\t\t\tautoFocus={isCurrentPage}\n\t\t\tautoSelect\n\t\t/>\n\t)\n}\n"],
5
- "mappings": "AAgDE;AAhDF,SAAmB,iBAAiB;AACpC,SAAS,aAAa,cAAc;AACpC,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAYvB,MAAM,gBAAgB,SAASA,eAAc;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAuB;AACtB,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,YAAY;AAE/B,QAAM,SAAS,OAAgC,IAAI;AACnD,QAAM,QAAQ,OAAsB,IAAI;AAExC,QAAM,cAAc,YAAY,MAAM;AACrC,UAAM,UAAU,OAAO,yBAAyB,aAAa;AAAA,EAC9D,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAe;AAAA,IACpB,CAAC,UAAkB;AAClB,aAAO,WAAW,IAAI,SAAS,UAAU;AACzC,iBAAW,eAAe,EAAE,QAAQ,YAAY,CAAC;AAAA,IAClD;AAAA,IACA,CAAC,QAAQ,IAAI,UAAU;AAAA,EACxB;AAEA,QAAM,eAAe,YAAY,MAAM;AACtC,QAAI,MAAM,SAAS;AAClB,aAAO,WAAW,MAAM,OAAO;AAAA,IAChC;AACA,aAAS;AAAA,EACV,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,KAAK,CAAC,OAAO;AACZ,eAAO,UAAU;AAAA,MAClB;AAAA,MACA,cAAc;AAAA,MACd,eAAe;AAAA,MACf;AAAA,MACA,UAAU;AAAA,MACV,SAAS;AAAA,MACT,iDAA+C;AAAA,MAC/C,WAAW;AAAA,MACX,YAAU;AAAA;AAAA,EACX;AAEF;",
4
+ "sourcesContent": ["import { TLPageId, useEditor } from '@tldraw/editor'\nimport { useCallback, useRef } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { TldrawUiInput } from '../primitives/TldrawUiInput'\n\n/** @public */\nexport interface PageItemInputProps {\n\tname: string\n\tid: TLPageId\n\tisCurrentPage: boolean\n\tonCancel(): void\n\tonComplete?(): void\n}\n\n/** @public @react */\nexport const PageItemInput = function PageItemInput({\n\tname,\n\tid,\n\tisCurrentPage,\n\tonCancel,\n\tonComplete,\n}: PageItemInputProps) {\n\tconst editor = useEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst rInput = useRef<HTMLInputElement | null>(null)\n\tconst rMark = useRef<string | null>(null)\n\n\tconst handleFocus = useCallback(() => {\n\t\trMark.current = editor.markHistoryStoppingPoint('rename page')\n\t}, [editor])\n\n\tconst handleChange = useCallback(\n\t\t(value: string) => {\n\t\t\teditor.renamePage(id, value || 'New Page')\n\t\t\ttrackEvent('rename-page', { source: 'page-menu' })\n\t\t},\n\t\t[editor, id, trackEvent]\n\t)\n\n\tconst handleCancel = useCallback(() => {\n\t\tif (rMark.current) {\n\t\t\teditor.bailToMark(rMark.current)\n\t\t}\n\t\tonCancel()\n\t}, [editor, onCancel])\n\n\treturn (\n\t\t<TldrawUiInput\n\t\t\tclassName=\"tlui-page-menu__item__input\"\n\t\t\tref={(el) => (rInput.current = el)}\n\t\t\tdefaultValue={name}\n\t\t\tonValueChange={handleChange}\n\t\t\tonComplete={onComplete}\n\t\t\tonCancel={handleCancel}\n\t\t\tonFocus={handleFocus}\n\t\t\tshouldManuallyMaintainScrollPositionWhenFocused\n\t\t\tautoFocus={isCurrentPage}\n\t\t\tautoSelect\n\t\t/>\n\t)\n}\n"],
5
+ "mappings": "AAgDE;AAhDF,SAAmB,iBAAiB;AACpC,SAAS,aAAa,cAAc;AACpC,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAYvB,MAAM,gBAAgB,SAASA,eAAc;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAuB;AACtB,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,YAAY;AAE/B,QAAM,SAAS,OAAgC,IAAI;AACnD,QAAM,QAAQ,OAAsB,IAAI;AAExC,QAAM,cAAc,YAAY,MAAM;AACrC,UAAM,UAAU,OAAO,yBAAyB,aAAa;AAAA,EAC9D,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAe;AAAA,IACpB,CAAC,UAAkB;AAClB,aAAO,WAAW,IAAI,SAAS,UAAU;AACzC,iBAAW,eAAe,EAAE,QAAQ,YAAY,CAAC;AAAA,IAClD;AAAA,IACA,CAAC,QAAQ,IAAI,UAAU;AAAA,EACxB;AAEA,QAAM,eAAe,YAAY,MAAM;AACtC,QAAI,MAAM,SAAS;AAClB,aAAO,WAAW,MAAM,OAAO;AAAA,IAChC;AACA,aAAS;AAAA,EACV,GAAG,CAAC,QAAQ,QAAQ,CAAC;AAErB,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAU;AAAA,MACV,KAAK,CAAC,OAAQ,OAAO,UAAU;AAAA,MAC/B,cAAc;AAAA,MACd,eAAe;AAAA,MACf;AAAA,MACA,UAAU;AAAA,MACV,SAAS;AAAA,MACT,iDAA+C;AAAA,MAC/C,WAAW;AAAA,MACX,YAAU;AAAA;AAAA,EACX;AAEF;",
6
6
  "names": ["PageItemInput"]
7
7
  }
@@ -3,10 +3,8 @@ import { useContainer, useEditor, usePeerIds, useValue } from "@tldraw/editor";
3
3
  import { Popover as _Popover } from "radix-ui";
4
4
  import { PORTRAIT_BREAKPOINT } from "../../constants.mjs";
5
5
  import { useBreakpoint } from "../../context/breakpoints.mjs";
6
- import { useCollaborationStatus } from "../../hooks/useCollaborationStatus.mjs";
7
6
  import { useMenuIsOpen } from "../../hooks/useMenuIsOpen.mjs";
8
7
  import { useTranslation } from "../../hooks/useTranslation/useTranslation.mjs";
9
- import { OfflineIndicator } from "../OfflineIndicator/OfflineIndicator.mjs";
10
8
  import { PeopleMenuAvatar } from "./PeopleMenuAvatar.mjs";
11
9
  import { PeopleMenuItem } from "./PeopleMenuItem.mjs";
12
10
  import { PeopleMenuMore } from "./PeopleMenuMore.mjs";
@@ -21,10 +19,6 @@ function PeopleMenu({ children }) {
21
19
  const [isOpen, onOpenChange] = useMenuIsOpen("people menu");
22
20
  const breakpoint = useBreakpoint();
23
21
  const maxAvatars = breakpoint <= PORTRAIT_BREAKPOINT.MOBILE_XS ? 1 : 5;
24
- const collaborationStatus = useCollaborationStatus();
25
- if (collaborationStatus === "offline") {
26
- return /* @__PURE__ */ jsx(OfflineIndicator, {});
27
- }
28
22
  if (!userIds.length) return null;
29
23
  return /* @__PURE__ */ jsxs(_Popover.Root, { onOpenChange, open: isOpen, children: [
30
24
  /* @__PURE__ */ jsx(_Popover.Trigger, { dir: "ltr", asChild: true, children: /* @__PURE__ */ jsx("button", { className: "tlui-people-menu__avatars-button", title: msg("people-menu.title"), children: /* @__PURE__ */ jsxs("div", { className: "tlui-people-menu__avatars", children: [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/SharePanel/PeopleMenu.tsx"],
4
- "sourcesContent": ["import { useContainer, useEditor, usePeerIds, useValue } from '@tldraw/editor'\nimport { Popover as _Popover } from 'radix-ui'\nimport { ReactNode } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { useCollaborationStatus } from '../../hooks/useCollaborationStatus'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { OfflineIndicator } from '../OfflineIndicator/OfflineIndicator'\nimport { PeopleMenuAvatar } from './PeopleMenuAvatar'\nimport { PeopleMenuItem } from './PeopleMenuItem'\nimport { PeopleMenuMore } from './PeopleMenuMore'\nimport { UserPresenceEditor } from './UserPresenceEditor'\n\n/** @public */\nexport interface PeopleMenuProps {\n\tchildren?: ReactNode\n}\n\n/** @public @react */\nexport function PeopleMenu({ children }: PeopleMenuProps) {\n\tconst msg = useTranslation()\n\n\tconst container = useContainer()\n\tconst editor = useEditor()\n\n\tconst userIds = usePeerIds()\n\tconst userColor = useValue('user', () => editor.user.getColor(), [editor])\n\tconst userName = useValue('user', () => editor.user.getName(), [editor])\n\n\tconst [isOpen, onOpenChange] = useMenuIsOpen('people menu')\n\tconst breakpoint = useBreakpoint()\n\tconst maxAvatars = breakpoint <= PORTRAIT_BREAKPOINT.MOBILE_XS ? 1 : 5\n\n\tconst collaborationStatus = useCollaborationStatus()\n\n\tif (collaborationStatus === 'offline') {\n\t\treturn <OfflineIndicator />\n\t}\n\n\tif (!userIds.length) return null\n\n\treturn (\n\t\t<_Popover.Root onOpenChange={onOpenChange} open={isOpen}>\n\t\t\t<_Popover.Trigger dir=\"ltr\" asChild>\n\t\t\t\t<button className=\"tlui-people-menu__avatars-button\" title={msg('people-menu.title')}>\n\t\t\t\t\t<div className=\"tlui-people-menu__avatars\">\n\t\t\t\t\t\t{userIds.slice(-maxAvatars).map((userId) => (\n\t\t\t\t\t\t\t<PeopleMenuAvatar key={userId} userId={userId} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{userIds.length > 0 && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tlui-people-menu__avatar\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundColor: userColor,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{userName?.[0] ?? ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{userIds.length > maxAvatars && <PeopleMenuMore count={userIds.length - maxAvatars} />}\n\t\t\t\t\t</div>\n\t\t\t\t</button>\n\t\t\t</_Popover.Trigger>\n\t\t\t<_Popover.Portal container={container}>\n\t\t\t\t<_Popover.Content\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tclassName=\"tlui-menu\"\n\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\tsideOffset={2}\n\t\t\t\t\tcollisionPadding={4}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"tlui-people-menu__wrapper\">\n\t\t\t\t\t\t<div className=\"tlui-people-menu__section\">\n\t\t\t\t\t\t\t<UserPresenceEditor />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{userIds.length > 0 && (\n\t\t\t\t\t\t\t<div className=\"tlui-people-menu__section\">\n\t\t\t\t\t\t\t\t{userIds.map((userId) => {\n\t\t\t\t\t\t\t\t\treturn <PeopleMenuItem key={userId + '_presence'} userId={userId} />\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</div>\n\t\t\t\t</_Popover.Content>\n\t\t\t</_Popover.Portal>\n\t\t</_Popover.Root>\n\t)\n}\n"],
5
- "mappings": "AAqCS,cASJ,YATI;AArCT,SAAS,cAAc,WAAW,YAAY,gBAAgB;AAC9D,SAAS,WAAW,gBAAgB;AAEpC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,8BAA8B;AACvC,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AAQ5B,SAAS,WAAW,EAAE,SAAS,GAAoB;AACzD,QAAM,MAAM,eAAe;AAE3B,QAAM,YAAY,aAAa;AAC/B,QAAM,SAAS,UAAU;AAEzB,QAAM,UAAU,WAAW;AAC3B,QAAM,YAAY,SAAS,QAAQ,MAAM,OAAO,KAAK,SAAS,GAAG,CAAC,MAAM,CAAC;AACzE,QAAM,WAAW,SAAS,QAAQ,MAAM,OAAO,KAAK,QAAQ,GAAG,CAAC,MAAM,CAAC;AAEvE,QAAM,CAAC,QAAQ,YAAY,IAAI,cAAc,aAAa;AAC1D,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,cAAc,oBAAoB,YAAY,IAAI;AAErE,QAAM,sBAAsB,uBAAuB;AAEnD,MAAI,wBAAwB,WAAW;AACtC,WAAO,oBAAC,oBAAiB;AAAA,EAC1B;AAEA,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAE5B,SACC,qBAAC,SAAS,MAAT,EAAc,cAA4B,MAAM,QAChD;AAAA,wBAAC,SAAS,SAAT,EAAiB,KAAI,OAAM,SAAO,MAClC,8BAAC,YAAO,WAAU,oCAAmC,OAAO,IAAI,mBAAmB,GAClF,+BAAC,SAAI,WAAU,6BACb;AAAA,cAAQ,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,WAChC,oBAAC,oBAA8B,UAAR,MAAwB,CAC/C;AAAA,MACA,QAAQ,SAAS,KACjB;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,iBAAiB;AAAA,UAClB;AAAA,UAEC,qBAAW,CAAC,KAAK;AAAA;AAAA,MACnB;AAAA,MAEA,QAAQ,SAAS,cAAc,oBAAC,kBAAe,OAAO,QAAQ,SAAS,YAAY;AAAA,OACrF,GACD,GACD;AAAA,IACA,oBAAC,SAAS,QAAT,EAAgB,WAChB;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA,KAAI;AAAA,QACJ,WAAU;AAAA,QACV,MAAK;AAAA,QACL,YAAY;AAAA,QACZ,kBAAkB;AAAA,QAElB,+BAAC,SAAI,WAAU,6BACd;AAAA,8BAAC,SAAI,WAAU,6BACd,8BAAC,sBAAmB,GACrB;AAAA,UACC,QAAQ,SAAS,KACjB,oBAAC,SAAI,WAAU,6BACb,kBAAQ,IAAI,CAAC,WAAW;AACxB,mBAAO,oBAAC,kBAA0C,UAAtB,SAAS,WAA6B;AAAA,UACnE,CAAC,GACF;AAAA,UAEA;AAAA,WACF;AAAA;AAAA,IACD,GACD;AAAA,KACD;AAEF;",
4
+ "sourcesContent": ["import { useContainer, useEditor, usePeerIds, useValue } from '@tldraw/editor'\nimport { Popover as _Popover } from 'radix-ui'\nimport { ReactNode } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { useMenuIsOpen } from '../../hooks/useMenuIsOpen'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { PeopleMenuAvatar } from './PeopleMenuAvatar'\nimport { PeopleMenuItem } from './PeopleMenuItem'\nimport { PeopleMenuMore } from './PeopleMenuMore'\nimport { UserPresenceEditor } from './UserPresenceEditor'\n\n/** @public */\nexport interface PeopleMenuProps {\n\tchildren?: ReactNode\n}\n\n/** @public @react */\nexport function PeopleMenu({ children }: PeopleMenuProps) {\n\tconst msg = useTranslation()\n\n\tconst container = useContainer()\n\tconst editor = useEditor()\n\n\tconst userIds = usePeerIds()\n\tconst userColor = useValue('user', () => editor.user.getColor(), [editor])\n\tconst userName = useValue('user', () => editor.user.getName(), [editor])\n\n\tconst [isOpen, onOpenChange] = useMenuIsOpen('people menu')\n\tconst breakpoint = useBreakpoint()\n\tconst maxAvatars = breakpoint <= PORTRAIT_BREAKPOINT.MOBILE_XS ? 1 : 5\n\n\tif (!userIds.length) return null\n\n\treturn (\n\t\t<_Popover.Root onOpenChange={onOpenChange} open={isOpen}>\n\t\t\t<_Popover.Trigger dir=\"ltr\" asChild>\n\t\t\t\t<button className=\"tlui-people-menu__avatars-button\" title={msg('people-menu.title')}>\n\t\t\t\t\t<div className=\"tlui-people-menu__avatars\">\n\t\t\t\t\t\t{userIds.slice(-maxAvatars).map((userId) => (\n\t\t\t\t\t\t\t<PeopleMenuAvatar key={userId} userId={userId} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{userIds.length > 0 && (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName=\"tlui-people-menu__avatar\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackgroundColor: userColor,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{userName?.[0] ?? ''}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{userIds.length > maxAvatars && <PeopleMenuMore count={userIds.length - maxAvatars} />}\n\t\t\t\t\t</div>\n\t\t\t\t</button>\n\t\t\t</_Popover.Trigger>\n\t\t\t<_Popover.Portal container={container}>\n\t\t\t\t<_Popover.Content\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\tclassName=\"tlui-menu\"\n\t\t\t\t\tside=\"bottom\"\n\t\t\t\t\tsideOffset={2}\n\t\t\t\t\tcollisionPadding={4}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"tlui-people-menu__wrapper\">\n\t\t\t\t\t\t<div className=\"tlui-people-menu__section\">\n\t\t\t\t\t\t\t<UserPresenceEditor />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{userIds.length > 0 && (\n\t\t\t\t\t\t\t<div className=\"tlui-people-menu__section\">\n\t\t\t\t\t\t\t\t{userIds.map((userId) => {\n\t\t\t\t\t\t\t\t\treturn <PeopleMenuItem key={userId + '_presence'} userId={userId} />\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</div>\n\t\t\t\t</_Popover.Content>\n\t\t\t</_Popover.Portal>\n\t\t</_Popover.Root>\n\t)\n}\n"],
5
+ "mappings": "AAsCK,SAEE,KAFF;AAtCL,SAAS,cAAc,WAAW,YAAY,gBAAgB;AAC9D,SAAS,WAAW,gBAAgB;AAEpC,SAAS,2BAA2B;AACpC,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AAQ5B,SAAS,WAAW,EAAE,SAAS,GAAoB;AACzD,QAAM,MAAM,eAAe;AAE3B,QAAM,YAAY,aAAa;AAC/B,QAAM,SAAS,UAAU;AAEzB,QAAM,UAAU,WAAW;AAC3B,QAAM,YAAY,SAAS,QAAQ,MAAM,OAAO,KAAK,SAAS,GAAG,CAAC,MAAM,CAAC;AACzE,QAAM,WAAW,SAAS,QAAQ,MAAM,OAAO,KAAK,QAAQ,GAAG,CAAC,MAAM,CAAC;AAEvE,QAAM,CAAC,QAAQ,YAAY,IAAI,cAAc,aAAa;AAC1D,QAAM,aAAa,cAAc;AACjC,QAAM,aAAa,cAAc,oBAAoB,YAAY,IAAI;AAErE,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAE5B,SACC,qBAAC,SAAS,MAAT,EAAc,cAA4B,MAAM,QAChD;AAAA,wBAAC,SAAS,SAAT,EAAiB,KAAI,OAAM,SAAO,MAClC,8BAAC,YAAO,WAAU,oCAAmC,OAAO,IAAI,mBAAmB,GAClF,+BAAC,SAAI,WAAU,6BACb;AAAA,cAAQ,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,WAChC,oBAAC,oBAA8B,UAAR,MAAwB,CAC/C;AAAA,MACA,QAAQ,SAAS,KACjB;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,iBAAiB;AAAA,UAClB;AAAA,UAEC,qBAAW,CAAC,KAAK;AAAA;AAAA,MACnB;AAAA,MAEA,QAAQ,SAAS,cAAc,oBAAC,kBAAe,OAAO,QAAQ,SAAS,YAAY;AAAA,OACrF,GACD,GACD;AAAA,IACA,oBAAC,SAAS,QAAT,EAAgB,WAChB;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA,KAAI;AAAA,QACJ,WAAU;AAAA,QACV,MAAK;AAAA,QACL,YAAY;AAAA,QACZ,kBAAkB;AAAA,QAElB,+BAAC,SAAI,WAAU,6BACd;AAAA,8BAAC,SAAI,WAAU,6BACd,8BAAC,sBAAmB,GACrB;AAAA,UACC,QAAQ,SAAS,KACjB,oBAAC,SAAI,WAAU,6BACb,kBAAQ,IAAI,CAAC,WAAW;AACxB,mBAAO,oBAAC,kBAA0C,UAAtB,SAAS,WAA6B;AAAA,UACnE,CAAC,GACF;AAAA,UAEA;AAAA,WACF;AAAA;AAAA,IACD,GACD;AAAA,KACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/Toolbar/AltTextEditor.tsx"],
4
- "sourcesContent": ["import { ExtractShapeByProps, preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiInput } from '../primitives/TldrawUiInput'\n\n/** @public */\nexport interface AltTextEditorProps {\n\tshapeId: TLShapeId\n\tonClose(): void\n\tsource: 'image-toolbar' | 'video-toolbar'\n}\n\n/** @public @react */\nexport function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps) {\n\tconst editor = useEditor()\n\tconst [altText, setAltText] = useState(() => {\n\t\tconst shape = editor.getShape<TLShape>(shapeId)\n\t\tif (!shape) return ''\n\t\tif (!('altText' in shape.props)) throw Error('Shape does not have altText property')\n\t\treturn shape.props.altText || ''\n\t})\n\tconst msg = useTranslation()\n\tconst ref = useRef<HTMLInputElement>(null)\n\tconst trackEvent = useUiEvents()\n\tconst isReadonly = editor.getIsReadonly()\n\n\tconst handleValueChange = (value: string) => setAltText(value)\n\n\tconst handleComplete = () => {\n\t\ttrackEvent('set-alt-text', { source })\n\t\tconst shape = editor.getShape<ExtractShapeByProps<{ altText: string }>>(shapeId)\n\t\tif (!shape) return\n\t\teditor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { altText },\n\t\t\t},\n\t\t])\n\t\tonClose()\n\t}\n\n\tconst handleConfirm = () => handleComplete()\n\tconst handleAltTextCancel = useCallback(() => onClose(), [onClose])\n\n\tuseEffect(() => {\n\t\tref.current?.select()\n\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\thandleAltTextCancel()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown, { capture: true })\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown, { capture: true })\n\t\t}\n\t}, [handleAltTextCancel])\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiInput\n\t\t\t\tref={ref}\n\t\t\t\tclassName=\"tlui-media__toolbar-alt-text-input\"\n\t\t\t\tdata-testid=\"media-toolbar.alt-text-input\"\n\t\t\t\tvalue={altText}\n\t\t\t\tplaceholder={msg('tool.media-alt-text-desc')}\n\t\t\t\taria-label={msg('tool.media-alt-text-desc')}\n\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\tonComplete={handleComplete}\n\t\t\t\tonCancel={handleAltTextCancel}\n\t\t\t\tdisabled={isReadonly}\n\t\t\t/>\n\t\t\t{!isReadonly && (\n\t\t\t\t<TldrawUiButton\n\t\t\t\t\ttitle={msg('tool.media-alt-text-confirm')}\n\t\t\t\t\tdata-testid=\"tool.media-alt-text-confirm\"\n\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\t\tonClick={handleConfirm}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon small icon=\"check\" />\n\t\t\t\t</TldrawUiButton>\n\t\t\t)}\n\t\t</>\n\t)\n}\n"],
5
- "mappings": "AAiEE,mBACC,KADD;AAjEF,SAA8B,gBAAoC,iBAAiB;AACnF,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAUvB,SAAS,cAAc,EAAE,SAAS,SAAS,OAAO,GAAuB;AAC/E,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,MAAM;AAC5C,UAAM,QAAQ,OAAO,SAAkB,OAAO;AAC9C,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,EAAE,aAAa,MAAM,OAAQ,OAAM,MAAM,sCAAsC;AACnF,WAAO,MAAM,MAAM,WAAW;AAAA,EAC/B,CAAC;AACD,QAAM,MAAM,eAAe;AAC3B,QAAM,MAAM,OAAyB,IAAI;AACzC,QAAM,aAAa,YAAY;AAC/B,QAAM,aAAa,OAAO,cAAc;AAExC,QAAM,oBAAoB,CAAC,UAAkB,WAAW,KAAK;AAE7D,QAAM,iBAAiB,MAAM;AAC5B,eAAW,gBAAgB,EAAE,OAAO,CAAC;AACrC,UAAM,QAAQ,OAAO,SAAmD,OAAO;AAC/E,QAAI,CAAC,MAAO;AACZ,WAAO,aAAa;AAAA,MACnB;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,QAAQ;AAAA,MAClB;AAAA,IACD,CAAC;AACD,YAAQ;AAAA,EACT;AAEA,QAAM,gBAAgB,MAAM,eAAe;AAC3C,QAAM,sBAAsB,YAAY,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC;AAElE,YAAU,MAAM;AACf,QAAI,SAAS,OAAO;AAEpB,aAAS,cAAc,OAAsB;AAC5C,UAAI,MAAM,QAAQ,UAAU;AAC3B,cAAM,gBAAgB;AACtB,4BAAoB;AAAA,MACrB;AAAA,IACD;AAEA,aAAS,iBAAiB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AACrE,WAAO,MAAM;AACZ,eAAS,oBAAoB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,IACzE;AAAA,EACD,GAAG,CAAC,mBAAmB,CAAC;AAExB,SACC,iCACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,OAAO;AAAA,QACP,aAAa,IAAI,0BAA0B;AAAA,QAC3C,cAAY,IAAI,0BAA0B;AAAA,QAC1C,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA;AAAA,IACX;AAAA,IACC,CAAC,cACD;AAAA,MAAC;AAAA;AAAA,QACA,OAAO,IAAI,6BAA6B;AAAA,QACxC,eAAY;AAAA,QACZ,MAAK;AAAA,QACL,eAAe;AAAA,QACf,SAAS;AAAA,QAET,8BAAC,sBAAmB,OAAK,MAAC,MAAK,SAAQ;AAAA;AAAA,IACxC;AAAA,KAEF;AAEF;",
4
+ "sourcesContent": ["import { preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useUiEvents } from '../../context/events'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButton } from '../primitives/Button/TldrawUiButton'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport { TldrawUiInput } from '../primitives/TldrawUiInput'\n\n/** @public */\nexport interface AltTextEditorProps {\n\tshapeId: TLShapeId\n\tonClose(): void\n\tsource: 'image-toolbar' | 'video-toolbar'\n}\n\n/** @public @react */\nexport function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps) {\n\tconst editor = useEditor()\n\tconst [altText, setAltText] = useState(() => {\n\t\tconst shape = editor.getShape<TLShape>(shapeId)\n\t\tif (!shape) return ''\n\t\tif (!('altText' in shape.props)) throw Error('Shape does not have altText property')\n\t\treturn shape.props.altText || ''\n\t})\n\tconst msg = useTranslation()\n\tconst ref = useRef<HTMLInputElement>(null)\n\tconst trackEvent = useUiEvents()\n\tconst isReadonly = editor.getIsReadonly()\n\n\tconst handleValueChange = (value: string) => setAltText(value)\n\n\tconst handleComplete = () => {\n\t\ttrackEvent('set-alt-text', { source })\n\t\tconst shape = editor.getShape<TLShape & { props: { altText: string } }>(shapeId)\n\t\tif (!shape) return\n\t\teditor.updateShapes([\n\t\t\t{\n\t\t\t\tid: shape.id,\n\t\t\t\ttype: shape.type,\n\t\t\t\tprops: { altText },\n\t\t\t},\n\t\t])\n\t\tonClose()\n\t}\n\n\tconst handleConfirm = () => handleComplete()\n\tconst handleAltTextCancel = useCallback(() => onClose(), [onClose])\n\n\tuseEffect(() => {\n\t\tref.current?.select()\n\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tevent.stopPropagation()\n\t\t\t\thandleAltTextCancel()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown, { capture: true })\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown, { capture: true })\n\t\t}\n\t}, [handleAltTextCancel])\n\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiInput\n\t\t\t\tref={ref}\n\t\t\t\tclassName=\"tlui-media__toolbar-alt-text-input\"\n\t\t\t\tdata-testid=\"media-toolbar.alt-text-input\"\n\t\t\t\tvalue={altText}\n\t\t\t\tplaceholder={msg('tool.media-alt-text-desc')}\n\t\t\t\taria-label={msg('tool.media-alt-text-desc')}\n\t\t\t\tonValueChange={handleValueChange}\n\t\t\t\tonComplete={handleComplete}\n\t\t\t\tonCancel={handleAltTextCancel}\n\t\t\t\tdisabled={isReadonly}\n\t\t\t/>\n\t\t\t{!isReadonly && (\n\t\t\t\t<TldrawUiButton\n\t\t\t\t\ttitle={msg('tool.media-alt-text-confirm')}\n\t\t\t\t\tdata-testid=\"tool.media-alt-text-confirm\"\n\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\tonPointerDown={preventDefault}\n\t\t\t\t\tonClick={handleConfirm}\n\t\t\t\t>\n\t\t\t\t\t<TldrawUiButtonIcon small icon=\"check\" />\n\t\t\t\t</TldrawUiButton>\n\t\t\t)}\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "AAiEE,mBACC,KADD;AAjEF,SAAS,gBAAoC,iBAAiB;AAC9D,SAAS,aAAa,WAAW,QAAQ,gBAAgB;AACzD,SAAS,mBAAmB;AAC5B,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,0BAA0B;AACnC,SAAS,qBAAqB;AAUvB,SAAS,cAAc,EAAE,SAAS,SAAS,OAAO,GAAuB;AAC/E,QAAM,SAAS,UAAU;AACzB,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,MAAM;AAC5C,UAAM,QAAQ,OAAO,SAAkB,OAAO;AAC9C,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,EAAE,aAAa,MAAM,OAAQ,OAAM,MAAM,sCAAsC;AACnF,WAAO,MAAM,MAAM,WAAW;AAAA,EAC/B,CAAC;AACD,QAAM,MAAM,eAAe;AAC3B,QAAM,MAAM,OAAyB,IAAI;AACzC,QAAM,aAAa,YAAY;AAC/B,QAAM,aAAa,OAAO,cAAc;AAExC,QAAM,oBAAoB,CAAC,UAAkB,WAAW,KAAK;AAE7D,QAAM,iBAAiB,MAAM;AAC5B,eAAW,gBAAgB,EAAE,OAAO,CAAC;AACrC,UAAM,QAAQ,OAAO,SAAmD,OAAO;AAC/E,QAAI,CAAC,MAAO;AACZ,WAAO,aAAa;AAAA,MACnB;AAAA,QACC,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,OAAO,EAAE,QAAQ;AAAA,MAClB;AAAA,IACD,CAAC;AACD,YAAQ;AAAA,EACT;AAEA,QAAM,gBAAgB,MAAM,eAAe;AAC3C,QAAM,sBAAsB,YAAY,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC;AAElE,YAAU,MAAM;AACf,QAAI,SAAS,OAAO;AAEpB,aAAS,cAAc,OAAsB;AAC5C,UAAI,MAAM,QAAQ,UAAU;AAC3B,cAAM,gBAAgB;AACtB,4BAAoB;AAAA,MACrB;AAAA,IACD;AAEA,aAAS,iBAAiB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AACrE,WAAO,MAAM;AACZ,eAAS,oBAAoB,WAAW,eAAe,EAAE,SAAS,KAAK,CAAC;AAAA,IACzE;AAAA,EACD,GAAG,CAAC,mBAAmB,CAAC;AAExB,SACC,iCACC;AAAA;AAAA,MAAC;AAAA;AAAA,QACA;AAAA,QACA,WAAU;AAAA,QACV,eAAY;AAAA,QACZ,OAAO;AAAA,QACP,aAAa,IAAI,0BAA0B;AAAA,QAC3C,cAAY,IAAI,0BAA0B;AAAA,QAC1C,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,UAAU;AAAA;AAAA,IACX;AAAA,IACC,CAAC,cACD;AAAA,MAAC;AAAA;AAAA,QACA,OAAO,IAAI,6BAA6B;AAAA,QACxC,eAAY;AAAA,QACZ,MAAK;AAAA,QACL,eAAe;AAAA,QACf,SAAS;AAAA,QAET,8BAAC,sBAAmB,OAAK,MAAC,MAAK,SAAQ;AAAA;AAAA,IACxC;AAAA,KAEF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -46,7 +46,7 @@ function ContextualToolbarInner({
46
46
  );
47
47
  const camera = useValue("camera", () => editor.getCamera(), [editor]);
48
48
  const isInCropTool = useValue("editor path", () => editor.isIn("select.crop."), [editor]);
49
- const previousSelectionBounds = useRef(void 0);
49
+ const previousSelectionBounds = useRef();
50
50
  const handleManipulatingEnd = useCallback(() => {
51
51
  editor.setCroppingShape(null);
52
52
  editor.setCurrentTool("select.idle");
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx"],
4
- "sourcesContent": ["import { Box, TLImageShape, useEditor, useValue } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiContextualToolbar } from '../primitives/TldrawUiContextualToolbar'\nimport { AltTextEditor } from './AltTextEditor'\nimport { DefaultImageToolbarContent } from './DefaultImageToolbarContent'\n\n/** @public */\nexport interface TLUiImageToolbarProps {\n\tchildren?: React.ReactNode\n}\n\n/** @public @react */\nexport function DefaultImageToolbar({ children }: TLUiImageToolbarProps) {\n\tconst editor = useEditor()\n\tconst imageShapeId = useValue(\n\t\t'imageShape',\n\t\t() => {\n\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\t\tif (!onlySelectedShape || onlySelectedShape.type !== 'image') return null\n\t\t\treturn onlySelectedShape.id\n\t\t},\n\t\t[editor]\n\t)\n\tconst showToolbar = useValue(\n\t\t'showToolbar',\n\t\t() => editor.isInAny('select.idle', 'select.pointing_shape', 'select.crop'),\n\t\t[editor]\n\t)\n\tconst isLocked = useValue(\n\t\t'locked',\n\t\t() => (imageShapeId ? editor.getShape<TLImageShape>(imageShapeId)?.isLocked : false),\n\t\t[editor, imageShapeId]\n\t)\n\tif (!imageShapeId || !showToolbar || isLocked) return null\n\n\treturn (\n\t\t<ContextualToolbarInner key={imageShapeId} imageShapeId={imageShapeId}>\n\t\t\t{children}\n\t\t</ContextualToolbarInner>\n\t)\n}\n\nfunction ContextualToolbarInner({\n\tchildren,\n\timageShapeId,\n}: {\n\tchildren?: React.ReactNode\n\timageShapeId: TLImageShape['id']\n}) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst isChangingCrop = useValue(\n\t\t'editor path',\n\t\t() =>\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.cropping',\n\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t'select.crop.translating_crop'\n\t\t\t),\n\t\t[editor]\n\t)\n\tconst camera = useValue('camera', () => editor.getCamera(), [editor])\n\tconst isInCropTool = useValue('editor path', () => editor.isIn('select.crop.'), [editor])\n\tconst previousSelectionBounds = useRef<Box | undefined>(undefined)\n\tconst handleManipulatingEnd = useCallback(() => {\n\t\teditor.setCroppingShape(null)\n\t\teditor.setCurrentTool('select.idle')\n\t}, [editor])\n\n\tconst [isEditingAltText, setIsEditingAltText] = useState(false)\n\tconst handleEditAltTextStart = useCallback(() => setIsEditingAltText(true), [])\n\tconst handleManipulatingStart = useCallback(\n\t\t() => editor.setCurrentTool('select.crop.idle'),\n\t\t[editor]\n\t)\n\tconst onEditAltTextClose = useCallback(() => setIsEditingAltText(false), [])\n\n\tuseEffect(() => {\n\t\tpreviousSelectionBounds.current = undefined\n\t}, [camera])\n\n\tconst getSelectionBounds = useCallback(() => {\n\t\tif (isInCropTool && previousSelectionBounds.current) {\n\t\t\t// If we're cropping we want to be able to keep the toolbar in the same position.\n\t\t\treturn previousSelectionBounds.current\n\t\t}\n\t\tconst fullBounds = editor.getSelectionScreenBounds()\n\t\tif (!fullBounds) return undefined\n\t\tconst bounds = new Box(fullBounds.x, fullBounds.y, fullBounds.width, 0)\n\t\tpreviousSelectionBounds.current = bounds\n\t\treturn bounds\n\t}, [editor, isInCropTool])\n\n\tif (isChangingCrop) {\n\t\tpreviousSelectionBounds.current = undefined\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<TldrawUiContextualToolbar\n\t\t\tclassName=\"tlui-image__toolbar\"\n\t\t\tgetSelectionBounds={getSelectionBounds}\n\t\t\tlabel={msg('tool.image-toolbar-title')}\n\t\t>\n\t\t\t{children ? (\n\t\t\t\tchildren\n\t\t\t) : isEditingAltText ? (\n\t\t\t\t<AltTextEditor shapeId={imageShapeId} onClose={onEditAltTextClose} source=\"image-toolbar\" />\n\t\t\t) : (\n\t\t\t\t<DefaultImageToolbarContent\n\t\t\t\t\timageShapeId={imageShapeId}\n\t\t\t\t\tisManipulating={isInCropTool}\n\t\t\t\t\tonEditAltTextStart={handleEditAltTextStart}\n\t\t\t\t\tonManipulatingStart={handleManipulatingStart}\n\t\t\t\t\tonManipulatingEnd={handleManipulatingEnd}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</TldrawUiContextualToolbar>\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Box, TLImageShape, useEditor, useValue } from '@tldraw/editor'\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiContextualToolbar } from '../primitives/TldrawUiContextualToolbar'\nimport { AltTextEditor } from './AltTextEditor'\nimport { DefaultImageToolbarContent } from './DefaultImageToolbarContent'\n\n/** @public */\nexport interface TLUiImageToolbarProps {\n\tchildren?: React.ReactNode\n}\n\n/** @public @react */\nexport function DefaultImageToolbar({ children }: TLUiImageToolbarProps) {\n\tconst editor = useEditor()\n\tconst imageShapeId = useValue(\n\t\t'imageShape',\n\t\t() => {\n\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\t\tif (!onlySelectedShape || onlySelectedShape.type !== 'image') return null\n\t\t\treturn onlySelectedShape.id\n\t\t},\n\t\t[editor]\n\t)\n\tconst showToolbar = useValue(\n\t\t'showToolbar',\n\t\t() => editor.isInAny('select.idle', 'select.pointing_shape', 'select.crop'),\n\t\t[editor]\n\t)\n\tconst isLocked = useValue(\n\t\t'locked',\n\t\t() => (imageShapeId ? editor.getShape<TLImageShape>(imageShapeId)?.isLocked : false),\n\t\t[editor, imageShapeId]\n\t)\n\tif (!imageShapeId || !showToolbar || isLocked) return null\n\n\treturn (\n\t\t<ContextualToolbarInner key={imageShapeId} imageShapeId={imageShapeId}>\n\t\t\t{children}\n\t\t</ContextualToolbarInner>\n\t)\n}\n\nfunction ContextualToolbarInner({\n\tchildren,\n\timageShapeId,\n}: {\n\tchildren?: React.ReactNode\n\timageShapeId: TLImageShape['id']\n}) {\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\n\tconst isChangingCrop = useValue(\n\t\t'editor path',\n\t\t() =>\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.cropping',\n\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t'select.crop.translating_crop'\n\t\t\t),\n\t\t[editor]\n\t)\n\tconst camera = useValue('camera', () => editor.getCamera(), [editor])\n\tconst isInCropTool = useValue('editor path', () => editor.isIn('select.crop.'), [editor])\n\tconst previousSelectionBounds = useRef<Box | undefined>()\n\tconst handleManipulatingEnd = useCallback(() => {\n\t\teditor.setCroppingShape(null)\n\t\teditor.setCurrentTool('select.idle')\n\t}, [editor])\n\n\tconst [isEditingAltText, setIsEditingAltText] = useState(false)\n\tconst handleEditAltTextStart = useCallback(() => setIsEditingAltText(true), [])\n\tconst handleManipulatingStart = useCallback(\n\t\t() => editor.setCurrentTool('select.crop.idle'),\n\t\t[editor]\n\t)\n\tconst onEditAltTextClose = useCallback(() => setIsEditingAltText(false), [])\n\n\tuseEffect(() => {\n\t\tpreviousSelectionBounds.current = undefined\n\t}, [camera])\n\n\tconst getSelectionBounds = useCallback(() => {\n\t\tif (isInCropTool && previousSelectionBounds.current) {\n\t\t\t// If we're cropping we want to be able to keep the toolbar in the same position.\n\t\t\treturn previousSelectionBounds.current\n\t\t}\n\t\tconst fullBounds = editor.getSelectionScreenBounds()\n\t\tif (!fullBounds) return undefined\n\t\tconst bounds = new Box(fullBounds.x, fullBounds.y, fullBounds.width, 0)\n\t\tpreviousSelectionBounds.current = bounds\n\t\treturn bounds\n\t}, [editor, isInCropTool])\n\n\tif (isChangingCrop) {\n\t\tpreviousSelectionBounds.current = undefined\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<TldrawUiContextualToolbar\n\t\t\tclassName=\"tlui-image__toolbar\"\n\t\t\tgetSelectionBounds={getSelectionBounds}\n\t\t\tlabel={msg('tool.image-toolbar-title')}\n\t\t>\n\t\t\t{children ? (\n\t\t\t\tchildren\n\t\t\t) : isEditingAltText ? (\n\t\t\t\t<AltTextEditor shapeId={imageShapeId} onClose={onEditAltTextClose} source=\"image-toolbar\" />\n\t\t\t) : (\n\t\t\t\t<DefaultImageToolbarContent\n\t\t\t\t\timageShapeId={imageShapeId}\n\t\t\t\t\tisManipulating={isInCropTool}\n\t\t\t\t\tonEditAltTextStart={handleEditAltTextStart}\n\t\t\t\t\tonManipulatingStart={handleManipulatingStart}\n\t\t\t\t\tonManipulatingEnd={handleManipulatingEnd}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</TldrawUiContextualToolbar>\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -20,7 +20,7 @@ function ContextualToolbarInner({
20
20
  }) {
21
21
  const { isEditingLink, onEditLinkStart, onEditLinkClose } = useEditingLinkBehavior(textEditor);
22
22
  const [currentSelection, setCurrentSelection] = useState(null);
23
- const previousSelectionBounds = useRef(void 0);
23
+ const previousSelectionBounds = useRef();
24
24
  const isMousingDown = useIsMousingDownOnTextEditor(textEditor);
25
25
  const msg = useTranslation();
26
26
  const getSelectionBounds = useCallback(() => {