tldraw 3.16.0-canary.5dac57cf9465 → 3.16.0-canary.6074088f67bd

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 (305) hide show
  1. package/dist-cjs/index.d.ts +170 -7
  2. package/dist-cjs/index.js +13 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  7. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -3
  11. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  13. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  14. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  15. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  17. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  18. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +18 -12
  19. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  20. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  21. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  22. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  23. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  25. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  26. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  27. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  28. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
  29. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  31. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  33. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  34. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  35. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  36. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  37. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  38. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  40. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  41. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  42. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  43. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  44. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  45. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  46. package/dist-cjs/lib/ui/TldrawUi.js +27 -12
  47. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  48. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  49. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  50. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +10 -2
  51. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  52. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  53. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  54. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
  55. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  56. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  57. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  58. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  59. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  60. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +1 -1
  61. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +2 -2
  62. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  63. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  64. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -22
  65. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  66. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +188 -78
  67. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  68. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +1 -1
  69. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +2 -2
  70. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +15 -3
  71. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +155 -160
  73. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  74. package/dist-cjs/lib/ui/components/primitives/layout.js +30 -5
  75. package/dist-cjs/lib/ui/components/primitives/layout.js.map +2 -2
  76. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  78. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  79. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -19
  80. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  81. package/dist-cjs/lib/ui/context/actions.js +16 -2
  82. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  83. package/dist-cjs/lib/ui/context/components.js +2 -0
  84. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  85. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  86. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  87. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  88. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  89. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +1 -0
  90. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  91. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  92. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  93. package/dist-cjs/lib/ui/version.js +3 -3
  94. package/dist-cjs/lib/ui/version.js.map +1 -1
  95. package/dist-esm/index.d.mts +170 -7
  96. package/dist-esm/index.mjs +20 -3
  97. package/dist-esm/index.mjs.map +2 -2
  98. package/dist-esm/lib/Tldraw.mjs +14 -4
  99. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  100. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  101. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  102. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  103. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  104. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
  105. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  106. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  107. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  108. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  109. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  110. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  111. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  112. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +19 -12
  113. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  114. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  115. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  116. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  117. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  118. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  119. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  120. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  121. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  122. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
  123. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  124. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  125. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  126. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  127. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  128. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  129. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  130. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  131. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  132. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  134. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  135. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  136. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  137. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  138. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  139. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  140. package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
  141. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  142. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  143. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  144. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +10 -2
  145. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  146. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  147. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  148. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
  149. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  150. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  151. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  152. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  153. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  154. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +1 -1
  155. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  156. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  157. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  158. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -22
  159. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  160. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -80
  161. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  162. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +2 -1
  163. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  164. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +16 -4
  165. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  166. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +164 -162
  167. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  168. package/dist-esm/lib/ui/components/primitives/layout.mjs +31 -6
  169. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +2 -2
  170. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  171. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  172. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  173. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -21
  174. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  175. package/dist-esm/lib/ui/context/actions.mjs +16 -2
  176. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  177. package/dist-esm/lib/ui/context/components.mjs +2 -0
  178. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  179. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  180. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  181. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  182. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +1 -0
  183. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  184. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  185. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  186. package/dist-esm/lib/ui/version.mjs +3 -3
  187. package/dist-esm/lib/ui/version.mjs.map +1 -1
  188. package/package.json +11 -34
  189. package/src/index.ts +13 -1
  190. package/src/lib/Tldraw.tsx +15 -2
  191. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  192. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  193. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  194. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  195. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
  196. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
  197. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  198. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  199. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  200. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  201. package/src/lib/shapes/frame/FrameShapeUtil.tsx +29 -14
  202. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  203. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  204. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  205. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  206. package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
  207. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  208. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  209. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  210. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  211. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  212. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  213. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  214. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  215. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  216. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  217. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  218. package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
  219. package/src/lib/ui/TldrawUi.tsx +33 -12
  220. package/src/lib/ui/assetUrls.ts +13 -10
  221. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +13 -2
  222. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  223. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
  224. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  225. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  226. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +1 -1
  227. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  228. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -24
  229. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +208 -56
  230. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +3 -2
  231. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +22 -5
  232. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +196 -184
  233. package/src/lib/ui/components/primitives/layout.tsx +79 -5
  234. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  235. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  236. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +221 -18
  237. package/src/lib/ui/context/actions.tsx +16 -2
  238. package/src/lib/ui/context/components.tsx +3 -0
  239. package/src/lib/ui/context/events.tsx +2 -1
  240. package/src/lib/ui/hooks/useTools.tsx +140 -10
  241. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +1 -0
  242. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +1 -0
  243. package/src/lib/ui/kbd-utils.ts +10 -3
  244. package/src/lib/ui/version.ts +3 -3
  245. package/src/lib/ui.css +349 -243
  246. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  247. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  248. package/src/test/A11y.test.tsx +3 -2
  249. package/src/test/ClickManager.test.ts +7 -6
  250. package/src/test/Editor.test.tsx +20 -19
  251. package/src/test/EraserTool.test.ts +184 -13
  252. package/src/test/HandTool.test.ts +10 -9
  253. package/src/test/HighlightShape.test.ts +2 -1
  254. package/src/test/SelectTool.test.ts +3 -2
  255. package/src/test/TLUserPreferences.test.ts +4 -3
  256. package/src/test/TestEditor.ts +13 -15
  257. package/src/test/TldrawEditor.test.tsx +11 -10
  258. package/src/test/ZoomTool.test.ts +7 -6
  259. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  260. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  261. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  262. package/src/test/arrows-megabus.test.tsx +5 -4
  263. package/src/test/bindings.test.tsx +24 -37
  264. package/src/test/bookmark-shapes.test.ts +1 -8
  265. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  266. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  267. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  268. package/src/test/commands/alignShapes.test.tsx +25 -24
  269. package/src/test/commands/animationSpeed.test.ts +2 -1
  270. package/src/test/commands/centerOnPoint.test.ts +3 -2
  271. package/src/test/commands/clipboard.test.ts +3 -2
  272. package/src/test/commands/createShapes.test.ts +2 -1
  273. package/src/test/commands/deleteShapes.test.ts +2 -1
  274. package/src/test/commands/distributeShapes.test.tsx +11 -10
  275. package/src/test/commands/getSvgString.test.ts +2 -1
  276. package/src/test/commands/packShapes.test.ts +5 -4
  277. package/src/test/commands/resizeShape.test.ts +2 -1
  278. package/src/test/commands/rotateShapes.test.ts +7 -6
  279. package/src/test/commands/setCamera.test.ts +4 -3
  280. package/src/test/commands/setCurrentPage.test.ts +3 -2
  281. package/src/test/commands/stackShapes.test.ts +11 -10
  282. package/src/test/commands/stretch.test.tsx +13 -12
  283. package/src/test/createDeepLink.test.tsx +2 -1
  284. package/src/test/cropping.test.ts +3 -2
  285. package/src/test/custom-clipping.test.ts +436 -0
  286. package/src/test/drawing.test.ts +2 -1
  287. package/src/test/flipShapes.test.ts +4 -3
  288. package/src/test/frames.test.ts +25 -24
  289. package/src/test/getCulledShapes.test.tsx +3 -2
  290. package/src/test/groups.test.tsx +1 -1
  291. package/src/test/handleDeepLink.test.tsx +2 -1
  292. package/src/test/maxShapes.test.ts +3 -2
  293. package/src/test/modifiers.test.ts +5 -4
  294. package/src/test/navigation.test.ts +12 -11
  295. package/src/test/panning.test.ts +2 -1
  296. package/src/test/perf/perf.test.ts +2 -1
  297. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  298. package/src/test/resizing.test.ts +39 -38
  299. package/src/test/select.test.tsx +4 -3
  300. package/src/test/selection-omnibus.test.ts +11 -10
  301. package/src/test/shapeutils.test.ts +4 -3
  302. package/src/test/translating.test.ts +9 -8
  303. package/tldraw.css +650 -533
  304. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  305. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/Toolbar/OverflowingToolbar.tsx"],
4
- "sourcesContent": ["import {\n\tactiveElementShouldCaptureKeys,\n\tpreventDefault,\n\ttlmenus,\n\tuseEditor,\n\tuseEvent,\n\tuseUniqueSafeId,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { createContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\nimport { TldrawUiRow } from '../primitives/layout'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\nconst NUMBERED_SHORTCUT_KEYS: Record<string, number> = {\n\t'1': 0,\n\t'2': 1,\n\t'3': 2,\n\t'4': 3,\n\t'5': 4,\n\t'6': 5,\n\t'7': 6,\n\t'8': 7,\n\t'9': 8,\n\t'0': 9,\n}\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function OverflowingToolbar({ children }: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useUniqueSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\tconst rButtons = useRef<HTMLElement[]>([])\n\tconst [isOpen, setIsOpen] = useState(false)\n\n\tconst overflowIndex = Math.min(8, 5 + breakpoint)\n\n\tconst [totalItems, setTotalItems] = useState(0)\n\tconst mainToolsRef = useRef<HTMLDivElement>(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState<string | null>(null)\n\n\tconst css = useMemo(() => {\n\t\tconst activeCss = lastActiveOverflowItem ? `:not([data-value=\"${lastActiveOverflowItem}\"])` : ''\n\n\t\treturn `\n\t\t\t#${id}_main > *:nth-of-type(n + ${overflowIndex + (lastActiveOverflowItem ? 1 : 2)}):not([data-radix-popper-content-wrapper])${activeCss} {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t\t#${id}_more > *:nth-of-type(-n + ${overflowIndex}):not([data-radix-popper-content-wrapper]) {\n\t\t\t\tdisplay: none;\n\t\t\t}\n `\n\t}, [lastActiveOverflowItem, id, overflowIndex])\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst children = Array.from(mainToolsRef.current.children)\n\t\tsetTotalItems(children.length)\n\n\t\t// If the last active overflow item is no longer in the overflow, clear it\n\t\tconst lastActiveElementIdx = children.findIndex(\n\t\t\t(el) => el.getAttribute('data-value') === lastActiveOverflowItem\n\t\t)\n\t\tif (lastActiveElementIdx <= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\t// But if there's a new active item...\n\t\tconst activeElementIdx = Array.from(mainToolsRef.current.children).findIndex(\n\t\t\t(el) => el.getAttribute('aria-pressed') === 'true'\n\t\t)\n\t\tif (activeElementIdx === -1) return\n\n\t\t// ...and it's in the overflow, set it as the last active overflow item\n\t\tif (activeElementIdx >= overflowIndex) {\n\t\t\tsetLastActiveOverflowItem(children[activeElementIdx].getAttribute('data-value'))\n\t\t}\n\n\t\t// Save the buttons that are actually visible\n\t\trButtons.current = Array.from(mainToolsRef.current?.children ?? []).filter(\n\t\t\t(el): el is HTMLElement => {\n\t\t\t\t// only count html elements...\n\t\t\t\tif (!(el instanceof HTMLElement)) return false\n\n\t\t\t\t// ...that are buttons...\n\t\t\t\tif (el.tagName.toLowerCase() !== 'button') return false\n\n\t\t\t\t// ...that are actually visible\n\t\t\t\treturn !!(el.offsetWidth || el.offsetHeight)\n\t\t\t}\n\t\t)\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributeFilter: ['data-value', 'aria-pressed'],\n\t\t})\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate])\n\n\tuseEffect(() => {\n\t\tif (!editor.options.enableToolbarKeyboardShortcuts) return\n\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (areShortcutsDisabled(editor) || activeElementShouldCaptureKeys(true /* allow buttons */))\n\t\t\t\treturn\n\t\t\t// no accelerator keys\n\t\t\tif (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) return\n\t\t\tconst index = NUMBERED_SHORTCUT_KEYS[event.key]\n\t\t\tif (typeof index === 'number') {\n\t\t\t\tpreventDefault(event)\n\t\t\t\trButtons.current[index]?.click()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [editor])\n\n\tconst popoverId = 'toolbar overflow'\n\treturn (\n\t\t<>\n\t\t\t<style nonce={editor.options.nonce}>{css}</style>\n\t\t\t<TldrawUiToolbar\n\t\t\t\torientation=\"horizontal\"\n\t\t\t\tclassName={classNames('tlui-main-toolbar__tools', {\n\t\t\t\t\t'tlui-main-toolbar__tools__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,\n\t\t\t\t})}\n\t\t\t\tlabel={msg('tool-panel.title')}\n\t\t\t>\n\t\t\t\t<TldrawUiRow id={`${id}_main`} ref={mainToolsRef}>\n\t\t\t\t\t<TldrawUiMenuContextProvider type=\"toolbar\" sourceId=\"toolbar\">\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t</TldrawUiRow>\n\t\t\t\t{/* There is a +1 because if the menu is just one item, it's not necessary. */}\n\t\t\t\t{totalItems > overflowIndex + 1 && (\n\t\t\t\t\t<IsInOverflowContext.Provider value={true}>\n\t\t\t\t\t\t<TldrawUiPopover id={popoverId} open={isOpen} onOpenChange={setIsOpen}>\n\t\t\t\t\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\ttitle={msg('tool-panel.more')}\n\t\t\t\t\t\t\t\t\ttype=\"tool\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-main-toolbar__overflow\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"tools.more-button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon icon=\"chevron-up\" />\n\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t\t\t\t\t<TldrawUiPopoverContent side=\"top\" align=\"center\">\n\t\t\t\t\t\t\t\t<TldrawUiToolbar\n\t\t\t\t\t\t\t\t\torientation=\"grid\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"tools.more-content\"\n\t\t\t\t\t\t\t\t\tlabel={msg('tool-panel.more')}\n\t\t\t\t\t\t\t\t\tid={`${id}_more`}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(popoverId, editor.contextId)\n\t\t\t\t\t\t\t\t\t\tsetIsOpen(false)\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"toolbar-overflow\" sourceId=\"toolbar\">\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t\t\t\t</TldrawUiToolbar>\n\t\t\t\t\t\t\t</TldrawUiPopoverContent>\n\t\t\t\t\t\t</TldrawUiPopover>\n\t\t\t\t\t</IsInOverflowContext.Provider>\n\t\t\t\t)}\n\t\t\t</TldrawUiToolbar>\n\t\t</>\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n"],
5
- "mappings": "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",
6
- "names": ["children"]
4
+ "sourcesContent": ["import {\n\tactiveElementShouldCaptureKeys,\n\tassert,\n\tmodulate,\n\tpreventDefault,\n\ttlmenus,\n\tuseEditor,\n\tuseEvent,\n\tuseUniqueSafeId,\n} from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { createContext, useEffect, useLayoutEffect, useRef, useState } from 'react'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'\nimport { TLUiToolItem } from '../../hooks/useTools'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'\nimport {\n\tTldrawUiPopover,\n\tTldrawUiPopoverContent,\n\tTldrawUiPopoverTrigger,\n} from '../primitives/TldrawUiPopover'\nimport { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'\nimport { TldrawUiColumn, TldrawUiRow } from '../primitives/layout'\nimport { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'\n\nexport const IsInOverflowContext = createContext(false)\n\nconst NUMBERED_SHORTCUT_KEYS: Record<string, number> = {\n\t'1': 0,\n\t'2': 1,\n\t'3': 2,\n\t'4': 3,\n\t'5': 4,\n\t'6': 5,\n\t'7': 6,\n\t'8': 7,\n\t'9': 8,\n\t'0': 9,\n}\n\n/** @public */\nexport interface OverflowingToolbarProps {\n\tchildren: React.ReactNode\n\torientation: 'horizontal' | 'vertical'\n\tsizingParentClassName: string\n\tminItems: number\n\tminSizePx: number\n\tmaxItems: number\n\tmaxSizePx: number\n}\n\n/** @public @react */\nexport function OverflowingToolbar({\n\tchildren,\n\torientation,\n\tsizingParentClassName,\n\tminItems,\n\tminSizePx,\n\tmaxItems,\n\tmaxSizePx,\n}: OverflowingToolbarProps) {\n\tconst editor = useEditor()\n\tconst id = useUniqueSafeId()\n\tconst breakpoint = useBreakpoint()\n\tconst msg = useTranslation()\n\tconst rButtons = useRef<HTMLElement[]>([])\n\tconst [isOpen, setIsOpen] = useState(false)\n\n\tconst mainToolsRef = useRef<HTMLDivElement>(null)\n\n\t// we have to use state instead of a ref here so that we get\n\t// an update when the overflow popover mounts / unmounts\n\tconst [overflowTools, setOverflowTools] = useState<HTMLDivElement | null>(null)\n\tconst [lastActiveOverflowItem, setLastActiveOverflowItem] = useState<string | null>(null)\n\tconst [shouldShowOverflow, setShouldShowOverflow] = useState(false)\n\n\tconst onDomUpdate = useEvent(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\t// whenever we get an update, we need to re-calculate the number of items to show and update\n\t\t// the component accordingly.\n\t\tconst sizeProp = orientation === 'horizontal' ? 'offsetWidth' : 'offsetHeight'\n\n\t\t// toolbars can contain both single items and groups. we need to keep track of both.\n\t\ttype Items = (\n\t\t\t| { type: 'item'; element: HTMLElement }\n\t\t\t| { type: 'group'; items: Items; element: HTMLElement }\n\t\t)[]\n\n\t\t// walk through the dom and collect items so we can calculate what to show/hide\n\t\tconst mainItems = collectItems(mainToolsRef.current.children)\n\t\tconst overflowItems = overflowTools ? collectItems(overflowTools.children) : null\n\t\tfunction collectItems(collection: HTMLCollection) {\n\t\t\tconst items: Items = []\n\t\t\tfor (const child of collection) {\n\t\t\t\tif (child.classList.contains('tlui-main-toolbar__group')) {\n\t\t\t\t\titems.push({\n\t\t\t\t\t\ttype: 'group',\n\t\t\t\t\t\titems: collectItems(child.children),\n\t\t\t\t\t\telement: child as HTMLElement,\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\titems.push({ type: 'item', element: child as HTMLElement })\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn items\n\t\t}\n\n\t\t// the number of items to show is based on the space available to the toolbar.\n\t\tconst sizingParent = findParentWithClassName(mainToolsRef.current, sizingParentClassName)\n\t\tconst size = sizingParent[sizeProp]\n\t\tconst itemsToShow = Math.floor(\n\t\t\tmodulate(size, [minSizePx, maxSizePx], [minItems, maxItems], true)\n\t\t)\n\n\t\t// now we know how many items to show, we need to walk through the items we found and show /\n\t\t// hide them accordingly. We need to keep track of:\n\t\t// the number of item's we've shown in the main content so far\n\t\tlet mainItemCount = 0\n\t\t// the item that is currently active in the overflow content (if any)\n\t\tlet newActiveOverflowItem: string | null = null\n\t\t// whether the last active overflow item is actually still in the overflow content\n\t\tlet shouldInvalidateLastActiveOverflowItem = false\n\t\t// the buttons visible in the main content\n\t\tconst numberedButtons: HTMLButtonElement[] = []\n\t\tfunction visitItems(\n\t\t\tmainItems: Items,\n\t\t\toverflowItems: Items | null\n\t\t): {\n\t\t\t// for each group of items we visit, we need to know whether we showed anything in\n\t\t\t// either section\n\t\t\tdidShowAnyInMain: boolean\n\t\t\tdidShowAnyInOverflow: boolean\n\t\t} {\n\t\t\tif (overflowItems) assert(mainItems.length === overflowItems.length)\n\n\t\t\tlet didShowAnyInMain = false\n\t\t\tlet didShowAnyInOverflow = false\n\n\t\t\tfor (let i = 0; i < mainItems.length; i++) {\n\t\t\t\tconst mainItem = mainItems[i]\n\t\t\t\tconst overflowItem = overflowItems?.[i]\n\n\t\t\t\tif (mainItem.type === 'item') {\n\t\t\t\t\tconst isLastActiveOverflowItem =\n\t\t\t\t\t\tmainItem.element.getAttribute('data-value') === lastActiveOverflowItem\n\n\t\t\t\t\t// for single items, we show them in main if we have space, or if they're the\n\t\t\t\t\t// last-used item from the overflow.\n\t\t\t\t\tlet shouldShowInMain\n\t\t\t\t\tif (lastActiveOverflowItem) {\n\t\t\t\t\t\tshouldShowInMain = mainItemCount < itemsToShow || isLastActiveOverflowItem\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// we use <= here because if there is no last active overflow item, we want\n\t\t\t\t\t\t// to show at least one item in the main toolbar.\n\t\t\t\t\t\tshouldShowInMain = mainItemCount <= itemsToShow\n\t\t\t\t\t}\n\t\t\t\t\tconst shouldShowInOverflow = mainItemCount >= itemsToShow\n\n\t\t\t\t\tdidShowAnyInMain ||= shouldShowInMain\n\t\t\t\t\tdidShowAnyInOverflow ||= shouldShowInOverflow\n\n\t\t\t\t\tsetAttribute(\n\t\t\t\t\t\tmainItem.element,\n\t\t\t\t\t\t'data-toolbar-visible',\n\t\t\t\t\t\tshouldShowInMain ? 'true' : 'false'\n\t\t\t\t\t)\n\t\t\t\t\tif (overflowItem) {\n\t\t\t\t\t\tassert(overflowItem.type === 'item')\n\t\t\t\t\t\tsetAttribute(\n\t\t\t\t\t\t\toverflowItem.element,\n\t\t\t\t\t\t\t'data-toolbar-visible',\n\t\t\t\t\t\t\tshouldShowInOverflow ? 'true' : 'false'\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldShowInOverflow && mainItem.element.getAttribute('aria-pressed') === 'true') {\n\t\t\t\t\t\tnewActiveOverflowItem = mainItem.element.getAttribute('data-value')\n\t\t\t\t\t}\n\t\t\t\t\tif (shouldShowInMain && mainItem.element.tagName === 'BUTTON') {\n\t\t\t\t\t\tnumberedButtons.push(mainItem.element as HTMLButtonElement)\n\t\t\t\t\t}\n\t\t\t\t\tif (!shouldShowInOverflow && isLastActiveOverflowItem) {\n\t\t\t\t\t\tshouldInvalidateLastActiveOverflowItem = true\n\t\t\t\t\t}\n\t\t\t\t\tmainItemCount++\n\t\t\t\t} else {\n\t\t\t\t\t// for groups, we show them in main if we have space, or if they're the\n\t\t\t\t\t// last-used item from the overflow.\n\t\t\t\t\tlet result, overflowGroup\n\t\t\t\t\tif (overflowItem) {\n\t\t\t\t\t\tassert(overflowItem.type === 'group')\n\t\t\t\t\t\toverflowGroup = overflowItem\n\t\t\t\t\t\tresult = visitItems(mainItem.items, overflowGroup.items)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = visitItems(mainItem.items, null)\n\t\t\t\t\t}\n\n\t\t\t\t\tdidShowAnyInMain ||= result.didShowAnyInMain\n\t\t\t\t\tdidShowAnyInOverflow ||= result.didShowAnyInOverflow\n\n\t\t\t\t\tsetAttribute(\n\t\t\t\t\t\tmainItem.element,\n\t\t\t\t\t\t'data-toolbar-visible',\n\t\t\t\t\t\tresult.didShowAnyInMain ? 'true' : 'false'\n\t\t\t\t\t)\n\t\t\t\t\tif (overflowGroup) {\n\t\t\t\t\t\tsetAttribute(\n\t\t\t\t\t\t\toverflowGroup.element,\n\t\t\t\t\t\t\t'data-toolbar-visible',\n\t\t\t\t\t\t\tresult.didShowAnyInOverflow ? 'true' : 'false'\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\treturn { didShowAnyInMain, didShowAnyInOverflow }\n\t\t}\n\n\t\tconst { didShowAnyInOverflow } = visitItems(mainItems, overflowItems)\n\t\tsetShouldShowOverflow(didShowAnyInOverflow)\n\t\tif (newActiveOverflowItem) {\n\t\t\tsetLastActiveOverflowItem(newActiveOverflowItem)\n\t\t} else if (shouldInvalidateLastActiveOverflowItem) {\n\t\t\tsetLastActiveOverflowItem(null)\n\t\t}\n\n\t\trButtons.current = numberedButtons\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tonDomUpdate()\n\t})\n\n\tuseLayoutEffect(() => {\n\t\tif (!mainToolsRef.current) return\n\n\t\tconst mutationObserver = new MutationObserver(onDomUpdate)\n\t\tmutationObserver.observe(mainToolsRef.current, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true,\n\t\t\tattributes: true,\n\t\t\tcharacterData: true,\n\t\t})\n\n\t\tconst sizingParent = findParentWithClassName(mainToolsRef.current, sizingParentClassName)\n\t\tconst resizeObserver = new ResizeObserver(onDomUpdate)\n\t\tresizeObserver.observe(sizingParent)\n\n\t\treturn () => {\n\t\t\tmutationObserver.disconnect()\n\t\t\tresizeObserver.disconnect()\n\t\t}\n\t}, [onDomUpdate, sizingParentClassName])\n\n\tuseEffect(() => {\n\t\tif (!editor.options.enableToolbarKeyboardShortcuts) return\n\n\t\tfunction handleKeyDown(event: KeyboardEvent) {\n\t\t\tif (\n\t\t\t\tareShortcutsDisabled(editor) ||\n\t\t\t\tactiveElementShouldCaptureKeys(true /* allow buttons */)\n\t\t\t) {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// no accelerator keys\n\t\t\tif (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) return\n\t\t\tconst index = NUMBERED_SHORTCUT_KEYS[event.key]\n\t\t\tif (typeof index === 'number') {\n\t\t\t\tpreventDefault(event)\n\t\t\t\trButtons.current[index]?.click()\n\t\t\t}\n\t\t}\n\n\t\tdocument.addEventListener('keydown', handleKeyDown)\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('keydown', handleKeyDown)\n\t\t}\n\t}, [editor])\n\n\tconst popoverId = 'toolbar overflow'\n\n\tconst Layout = orientation === 'horizontal' ? TldrawUiRow : TldrawUiColumn\n\treturn (\n\t\t<>\n\t\t\t<TldrawUiToolbar\n\t\t\t\torientation={orientation}\n\t\t\t\tclassName={classNames('tlui-main-toolbar__tools', {\n\t\t\t\t\t'tlui-main-toolbar__tools__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,\n\t\t\t\t})}\n\t\t\t\tlabel={msg('tool-panel.title')}\n\t\t\t>\n\t\t\t\t<Layout id={`${id}_main`} ref={mainToolsRef}>\n\t\t\t\t\t<TldrawUiMenuContextProvider type=\"toolbar\" sourceId=\"toolbar\">\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t</Layout>\n\t\t\t\t{shouldShowOverflow && (\n\t\t\t\t\t<IsInOverflowContext.Provider value={true}>\n\t\t\t\t\t\t<TldrawUiPopover id={popoverId} open={isOpen} onOpenChange={setIsOpen}>\n\t\t\t\t\t\t\t<TldrawUiPopoverTrigger>\n\t\t\t\t\t\t\t\t<TldrawUiToolbarButton\n\t\t\t\t\t\t\t\t\ttitle={msg('tool-panel.more')}\n\t\t\t\t\t\t\t\t\ttype=\"tool\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-main-toolbar__overflow\"\n\t\t\t\t\t\t\t\t\tdata-testid=\"tools.more-button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiButtonIcon\n\t\t\t\t\t\t\t\t\t\ticon={orientation === 'horizontal' ? 'chevron-up' : 'chevron-right'}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</TldrawUiToolbarButton>\n\t\t\t\t\t\t\t</TldrawUiPopoverTrigger>\n\t\t\t\t\t\t\t<TldrawUiPopoverContent\n\t\t\t\t\t\t\t\tside={orientation === 'horizontal' ? 'top' : 'right'}\n\t\t\t\t\t\t\t\talign={orientation === 'horizontal' ? 'center' : 'end'}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<TldrawUiToolbar\n\t\t\t\t\t\t\t\t\torientation=\"grid\"\n\t\t\t\t\t\t\t\t\tclassName=\"tlui-main-toolbar__overflow-content\"\n\t\t\t\t\t\t\t\t\tref={setOverflowTools}\n\t\t\t\t\t\t\t\t\tdata-testid=\"tools.more-content\"\n\t\t\t\t\t\t\t\t\tlabel={msg('tool-panel.more')}\n\t\t\t\t\t\t\t\t\tid={`${id}_more`}\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\ttlmenus.deleteOpenMenu(popoverId, editor.contextId)\n\t\t\t\t\t\t\t\t\t\tsetIsOpen(false)\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<TldrawUiMenuContextProvider type=\"toolbar-overflow\" sourceId=\"toolbar\">\n\t\t\t\t\t\t\t\t\t\t{children}\n\t\t\t\t\t\t\t\t\t</TldrawUiMenuContextProvider>\n\t\t\t\t\t\t\t\t</TldrawUiToolbar>\n\t\t\t\t\t\t\t</TldrawUiPopoverContent>\n\t\t\t\t\t\t</TldrawUiPopover>\n\t\t\t\t\t</IsInOverflowContext.Provider>\n\t\t\t\t)}\n\t\t\t</TldrawUiToolbar>\n\t\t</>\n\t)\n}\n\nexport const isActiveTLUiToolItem = (\n\titem: TLUiToolItem,\n\tactiveToolId: string | undefined,\n\tgeoState: string | null | undefined\n) => {\n\treturn item.meta?.geo\n\t\t? activeToolId === 'geo' && geoState === item.meta?.geo\n\t\t: activeToolId === item.id\n}\n\nfunction findParentWithClassName(startingElement: HTMLElement, className: string): HTMLElement {\n\tlet element: HTMLElement | null = startingElement\n\twhile (element) {\n\t\tif (element.classList.contains(className)) {\n\t\t\treturn element\n\t\t}\n\t\telement = element.parentElement\n\t}\n\tthrow new Error('Could not find parent with class name ' + className)\n}\n\nfunction setAttribute(element: HTMLElement, name: string, value: string) {\n\tif (element.getAttribute(name) === value) return\n\telement.setAttribute(name, value)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["mainItems", "overflowItems", "didShowAnyInOverflow"]
7
7
  }
@@ -1,6 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import {
3
3
  DefaultColorStyle,
4
+ getColorValue,
4
5
  useEditor
5
6
  } from "@tldraw/editor";
6
7
  import { memo, useMemo, useRef } from "react";
@@ -95,7 +96,7 @@ const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker2(props) {
95
96
  "data-state": value.type === "shared" && value.value === item.value ? "on" : "off",
96
97
  "data-isactive": value.type === "shared" && value.value === item.value,
97
98
  title: label,
98
- style: style === DefaultColorStyle ? { color: theme[item.value].solid } : void 0,
99
+ style: style === DefaultColorStyle ? { color: getColorValue(theme, item.value, "solid") } : void 0,
99
100
  onPointerEnter: handleButtonPointerEnter,
100
101
  onPointerDown: handleButtonPointerDown,
101
102
  onPointerUp: handleButtonPointerUp,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx"],
4
- "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseEditor,\n} from '@tldraw/editor'\nimport { ReactElement, memo, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarToggleGroup, TldrawUiToolbarToggleItem } from './TldrawUiToolbar'\nimport { TldrawUiGrid, TldrawUiRow } from './layout'\n\n/** @public */\nexport interface TLUiButtonPickerProps<T extends string> {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp<T>\n\tvalue: SharedStyle<T>\n\titems: StyleValuesForUi<T>\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp<T>, value: T): void\n\tonHistoryMark?(id: string): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker<T extends string>(\n\tprops: TLUiButtonPickerProps<T>\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\tonHistoryMark,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef<HTMLElement | null>(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\twindow.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (\n\t\t\t\torigActiveEl &&\n\t\t\t\t(['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName) || origActiveEl.isContentEditable)\n\t\t\t) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t} else if (breakpoint >= PORTRAIT_BREAKPOINT.TABLET_SM) {\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = document.activeElement as HTMLElement\n\t\t\twindow.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [editor, breakpoint, value, onHistoryMark, onValueChange, style])\n\n\tconst Wrapper = items.length > 4 ? TldrawUiGrid : TldrawUiRow\n\n\treturn (\n\t\t<Wrapper asChild>\n\t\t\t<TldrawUiToolbarToggleGroup\n\t\t\t\tdata-testid={`style.${uiType}`}\n\t\t\t\ttype=\"single\"\n\t\t\t\tvalue={value.type === 'shared' ? value.value : undefined}\n\t\t\t>\n\t\t\t\t{items.map((item) => {\n\t\t\t\t\tconst label = title + ' \u2014 ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TldrawUiToolbarToggleItem\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\tdata-id={item.value}\n\t\t\t\t\t\t\tdata-testid={`style.${uiType}.${item.value}`}\n\t\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\t\tvalue={item.value}\n\t\t\t\t\t\t\tdata-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}\n\t\t\t\t\t\t\tdata-isactive={value.type === 'shared' && value.value === item.value}\n\t\t\t\t\t\t\ttitle={label}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tstyle === (DefaultColorStyle as StyleProp<unknown>)\n\t\t\t\t\t\t\t\t\t? { color: theme[item.value as TLDefaultColorStyle].solid }\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t</TldrawUiToolbarToggleItem>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</TldrawUiToolbarToggleGroup>\n\t\t</Wrapper>\n\t)\n}) as <T extends string>(props: TLUiButtonPickerProps<T>) => ReactElement\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tDefaultColorStyle,\n\tgetColorValue,\n\tSharedStyle,\n\tStyleProp,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tuseEditor,\n} from '@tldraw/editor'\nimport { memo, ReactElement, useMemo, useRef } from 'react'\nimport { StyleValuesForUi } from '../../../styles'\nimport { PORTRAIT_BREAKPOINT } from '../../constants'\nimport { useBreakpoint } from '../../context/breakpoints'\nimport { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'\nimport { useTranslation } from '../../hooks/useTranslation/useTranslation'\nimport { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'\nimport { TldrawUiToolbarToggleGroup, TldrawUiToolbarToggleItem } from './TldrawUiToolbar'\nimport { TldrawUiGrid, TldrawUiRow } from './layout'\n\n/** @public */\nexport interface TLUiButtonPickerProps<T extends string> {\n\ttitle: string\n\tuiType: string\n\tstyle: StyleProp<T>\n\tvalue: SharedStyle<T>\n\titems: StyleValuesForUi<T>\n\ttheme: TLDefaultColorTheme\n\tonValueChange(style: StyleProp<T>, value: T): void\n\tonHistoryMark?(id: string): void\n}\n\n/** @public */\nexport const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker<T extends string>(\n\tprops: TLUiButtonPickerProps<T>\n) {\n\tconst {\n\t\tuiType,\n\t\titems,\n\t\ttitle,\n\t\tstyle,\n\t\tvalue,\n\t\t// columns = clamp(items.length, 2, 4),\n\t\tonValueChange,\n\t\tonHistoryMark,\n\t\ttheme,\n\t} = props\n\tconst editor = useEditor()\n\tconst msg = useTranslation()\n\tconst breakpoint = useBreakpoint()\n\n\tconst rPointing = useRef(false)\n\tconst rPointingOriginalActiveElement = useRef<HTMLElement | null>(null)\n\n\tconst {\n\t\thandleButtonClick,\n\t\thandleButtonPointerDown,\n\t\thandleButtonPointerEnter,\n\t\thandleButtonPointerUp,\n\t} = useMemo(() => {\n\t\tconst handlePointerUp = () => {\n\t\t\trPointing.current = false\n\t\t\twindow.removeEventListener('pointerup', handlePointerUp)\n\n\t\t\t// This is fun little micro-optimization to make sure that the focus\n\t\t\t// is retained on a text label. That way, you can continue typing\n\t\t\t// after selecting a style.\n\t\t\tconst origActiveEl = rPointingOriginalActiveElement.current\n\t\t\tif (\n\t\t\t\torigActiveEl &&\n\t\t\t\t(['TEXTAREA', 'INPUT'].includes(origActiveEl.nodeName) || origActiveEl.isContentEditable)\n\t\t\t) {\n\t\t\t\torigActiveEl.focus()\n\t\t\t} else if (breakpoint >= PORTRAIT_BREAKPOINT.TABLET_SM) {\n\t\t\t\teditor.getContainer().focus()\n\t\t\t}\n\t\t\trPointingOriginalActiveElement.current = null\n\t\t}\n\n\t\tconst handleButtonClick = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerDown = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\n\t\t\tonHistoryMark?.('point picker item')\n\t\t\tonValueChange(style, id as T)\n\n\t\t\trPointing.current = true\n\t\t\trPointingOriginalActiveElement.current = document.activeElement as HTMLElement\n\t\t\twindow.addEventListener('pointerup', handlePointerUp) // see TLD-658\n\t\t}\n\n\t\tconst handleButtonPointerEnter = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tif (!rPointing.current) return\n\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\tconst handleButtonPointerUp = (e: React.PointerEvent<HTMLButtonElement>) => {\n\t\t\tconst { id } = e.currentTarget.dataset\n\t\t\tif (value.type === 'shared' && value.value === id) return\n\n\t\t\tonValueChange(style, id as T)\n\t\t}\n\n\t\treturn {\n\t\t\thandleButtonClick,\n\t\t\thandleButtonPointerDown,\n\t\t\thandleButtonPointerEnter,\n\t\t\thandleButtonPointerUp,\n\t\t}\n\t}, [editor, breakpoint, value, onHistoryMark, onValueChange, style])\n\n\tconst Wrapper = items.length > 4 ? TldrawUiGrid : TldrawUiRow\n\n\treturn (\n\t\t<Wrapper asChild>\n\t\t\t<TldrawUiToolbarToggleGroup\n\t\t\t\tdata-testid={`style.${uiType}`}\n\t\t\t\ttype=\"single\"\n\t\t\t\tvalue={value.type === 'shared' ? value.value : undefined}\n\t\t\t>\n\t\t\t\t{items.map((item) => {\n\t\t\t\t\tconst label = title + ' \u2014 ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<TldrawUiToolbarToggleItem\n\t\t\t\t\t\t\ttype=\"icon\"\n\t\t\t\t\t\t\tkey={item.value}\n\t\t\t\t\t\t\tdata-id={item.value}\n\t\t\t\t\t\t\tdata-testid={`style.${uiType}.${item.value}`}\n\t\t\t\t\t\t\taria-label={label}\n\t\t\t\t\t\t\tvalue={item.value}\n\t\t\t\t\t\t\tdata-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}\n\t\t\t\t\t\t\tdata-isactive={value.type === 'shared' && value.value === item.value}\n\t\t\t\t\t\t\ttitle={label}\n\t\t\t\t\t\t\tstyle={\n\t\t\t\t\t\t\t\tstyle === (DefaultColorStyle as StyleProp<unknown>)\n\t\t\t\t\t\t\t\t\t? { color: getColorValue(theme, item.value as TLDefaultColorStyle, 'solid') }\n\t\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonPointerEnter={handleButtonPointerEnter}\n\t\t\t\t\t\t\tonPointerDown={handleButtonPointerDown}\n\t\t\t\t\t\t\tonPointerUp={handleButtonPointerUp}\n\t\t\t\t\t\t\tonClick={handleButtonClick}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<TldrawUiButtonIcon icon={item.icon} />\n\t\t\t\t\t\t</TldrawUiToolbarToggleItem>\n\t\t\t\t\t)\n\t\t\t\t})}\n\t\t\t</TldrawUiToolbarToggleGroup>\n\t\t</Wrapper>\n\t)\n}) as <T extends string>(props: TLUiButtonPickerProps<T>) => ReactElement\n"],
5
+ "mappings": "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",
6
6
  "names": ["TldrawUiButtonPicker", "handleButtonClick", "handleButtonPointerDown", "handleButtonPointerEnter", "handleButtonPointerUp"]
7
7
  }
@@ -2,12 +2,24 @@ import { jsx } from "react/jsx-runtime";
2
2
  import classnames from "classnames";
3
3
  import { Toolbar as _Toolbar } from "radix-ui";
4
4
  import React from "react";
5
- import { TldrawUiGrid, TldrawUiRow } from "./layout.mjs";
5
+ import { TldrawUiColumn, TldrawUiGrid, TldrawUiRow } from "./layout.mjs";
6
6
  import { TldrawUiTooltip } from "./TldrawUiTooltip.mjs";
7
+ const LayoutByOrientation = {
8
+ horizontal: TldrawUiRow,
9
+ vertical: TldrawUiColumn,
10
+ grid: TldrawUiGrid
11
+ };
7
12
  const TldrawUiToolbar = React.forwardRef(
8
- ({ children, className, label, orientation = "horizontal", ...props }, ref) => {
9
- const Layout = orientation === "grid" ? TldrawUiGrid : TldrawUiRow;
10
- return /* @__PURE__ */ jsx(Layout, { asChild: true, children: /* @__PURE__ */ jsx(
13
+ ({
14
+ children,
15
+ className,
16
+ label,
17
+ orientation = "horizontal",
18
+ tooltipSide,
19
+ ...props
20
+ }, ref) => {
21
+ const Layout = LayoutByOrientation[orientation];
22
+ return /* @__PURE__ */ jsx(Layout, { asChild: true, tooltipSide, children: /* @__PURE__ */ jsx(
11
23
  _Toolbar.Root,
12
24
  {
13
25
  ref,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiToolbar.tsx"],
4
- "sourcesContent": ["import classnames from 'classnames'\nimport { Toolbar as _Toolbar } from 'radix-ui'\nimport React from 'react'\nimport { TldrawUiGrid, TldrawUiRow } from './layout'\nimport { TldrawUiTooltip } from './TldrawUiTooltip'\n\n/** @public */\nexport interface TLUiToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tlabel: string\n\torientation?: 'horizontal' | 'grid'\n}\n\n/** @public @react */\nexport const TldrawUiToolbar = React.forwardRef<HTMLDivElement, TLUiToolbarProps>(\n\t({ children, className, label, orientation = 'horizontal', ...props }: TLUiToolbarProps, ref) => {\n\t\tconst Layout = orientation === 'grid' ? TldrawUiGrid : TldrawUiRow\n\t\treturn (\n\t\t\t<Layout asChild>\n\t\t\t\t<_Toolbar.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...props}\n\t\t\t\t\tclassName={classnames('tlui-toolbar', className)}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\torientation={orientation === 'grid' ? 'horizontal' : orientation}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</_Toolbar.Root>\n\t\t\t</Layout>\n\t\t)\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarButtonProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tasChild?: boolean\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdisabled?: boolean\n\tisActive?: boolean\n\ttype: 'icon' | 'tool' | 'menu'\n\ttooltip?: string\n}\n\n/** @public @react */\nexport const TldrawUiToolbarButton = React.forwardRef<HTMLButtonElement, TLUiToolbarButtonProps>(\n\t({ asChild, children, type, isActive, tooltip, ...props }: TLUiToolbarButtonProps, ref) => {\n\t\tconst button = (\n\t\t\t<_Toolbar.Button\n\t\t\t\tref={ref}\n\t\t\t\tasChild={asChild}\n\t\t\t\tdraggable={false}\n\t\t\t\tdata-isactive={isActive}\n\t\t\t\t{...props}\n\t\t\t\t// The tooltip takes care of this.\n\t\t\t\ttitle={undefined}\n\t\t\t\tclassName={classnames('tlui-button', `tlui-button__${type}`, props.className)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</_Toolbar.Button>\n\t\t)\n\n\t\tconst tooltipContent = tooltip || props.title\n\n\t\treturn <TldrawUiTooltip content={tooltipContent}>{button}</TldrawUiTooltip>\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarToggleGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tvalue: any\n\t// TODO: fix up this type later\n\tdefaultValue?: any\n\ttype: 'single' | 'multiple'\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleGroup = ({\n\tchildren,\n\tclassName,\n\ttype,\n\t...props\n}: TLUiToolbarToggleGroupProps) => {\n\treturn (\n\t\t<_Toolbar.ToggleGroup\n\t\t\ttype={type}\n\t\t\t{...props}\n\t\t\t// TODO: this fixes a bug in Radix until they fix it.\n\t\t\t// https://github.com/radix-ui/primitives/issues/3188\n\t\t\t// https://github.com/radix-ui/primitives/pull/3189\n\t\t\trole=\"radiogroup\"\n\t\t\tclassName={classnames('tlui-toolbar-toggle-group', className)}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleGroup>\n\t)\n}\n\n/** @public */\nexport interface TLUiToolbarToggleItemProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\ttype: 'icon' | 'tool'\n\tvalue: string\n\ttooltip?: string\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleItem = ({\n\tchildren,\n\tclassName,\n\ttype,\n\tvalue,\n\ttooltip,\n\t...props\n}: TLUiToolbarToggleItemProps) => {\n\tconst toggleItem = (\n\t\t<_Toolbar.ToggleItem\n\t\t\t{...props}\n\t\t\t// The tooltip takes care of this.\n\t\t\ttitle={undefined}\n\t\t\tclassName={classnames(\n\t\t\t\t'tlui-button',\n\t\t\t\t`tlui-button__${type}`,\n\t\t\t\t'tlui-toolbar-toggle-group-item',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tvalue={value}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleItem>\n\t)\n\n\tconst tooltipContent = tooltip || props.title\n\n\treturn <TldrawUiTooltip content={tooltipContent}>{toggleItem}</TldrawUiTooltip>\n}\n"],
5
- "mappings": "AAqBI;AArBJ,OAAO,gBAAgB;AACvB,SAAS,WAAW,gBAAgB;AACpC,OAAO,WAAW;AAClB,SAAS,cAAc,mBAAmB;AAC1C,SAAS,uBAAuB;AAYzB,MAAM,kBAAkB,MAAM;AAAA,EACpC,CAAC,EAAE,UAAU,WAAW,OAAO,cAAc,cAAc,GAAG,MAAM,GAAqB,QAAQ;AAChG,UAAM,SAAS,gBAAgB,SAAS,eAAe;AACvD,WACC,oBAAC,UAAO,SAAO,MACd;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QACJ,WAAW,WAAW,gBAAgB,SAAS;AAAA,QAC/C,cAAY;AAAA,QACZ,aAAa,gBAAgB,SAAS,eAAe;AAAA,QAEpD;AAAA;AAAA,IACF,GACD;AAAA,EAEF;AACD;AAcO,MAAM,wBAAwB,MAAM;AAAA,EAC1C,CAAC,EAAE,SAAS,UAAU,MAAM,UAAU,SAAS,GAAG,MAAM,GAA2B,QAAQ;AAC1F,UAAM,SACL;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,iBAAe;AAAA,QACd,GAAG;AAAA,QAEJ,OAAO;AAAA,QACP,WAAW,WAAW,eAAe,gBAAgB,IAAI,IAAI,MAAM,SAAS;AAAA,QAE3E;AAAA;AAAA,IACF;AAGD,UAAM,iBAAiB,WAAW,MAAM;AAExC,WAAO,oBAAC,mBAAgB,SAAS,gBAAiB,kBAAO;AAAA,EAC1D;AACD;AAcO,MAAM,6BAA6B,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,MAAmC;AAClC,SACC;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAIJ,MAAK;AAAA,MACL,WAAW,WAAW,6BAA6B,SAAS;AAAA,MAE3D;AAAA;AAAA,EACF;AAEF;AAYO,MAAM,4BAA4B,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,MAAkC;AACjC,QAAM,aACL;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC,GAAG;AAAA,MAEJ,OAAO;AAAA,MACP,WAAW;AAAA,QACV;AAAA,QACA,gBAAgB,IAAI;AAAA,QACpB;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACF;AAGD,QAAM,iBAAiB,WAAW,MAAM;AAExC,SAAO,oBAAC,mBAAgB,SAAS,gBAAiB,sBAAW;AAC9D;",
4
+ "sourcesContent": ["import classnames from 'classnames'\nimport { Toolbar as _Toolbar } from 'radix-ui'\nimport React from 'react'\nimport { TldrawUiColumn, TldrawUiGrid, TldrawUiRow } from './layout'\nimport { TldrawUiTooltip } from './TldrawUiTooltip'\n\n/** @public */\nexport interface TLUiToolbarProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tlabel: string\n\torientation?: 'horizontal' | 'vertical' | 'grid'\n\ttooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n}\n\nconst LayoutByOrientation = {\n\thorizontal: TldrawUiRow,\n\tvertical: TldrawUiColumn,\n\tgrid: TldrawUiGrid,\n}\n\n/** @public @react */\nexport const TldrawUiToolbar = React.forwardRef<HTMLDivElement, TLUiToolbarProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tclassName,\n\t\t\tlabel,\n\t\t\torientation = 'horizontal',\n\t\t\ttooltipSide,\n\t\t\t...props\n\t\t}: TLUiToolbarProps,\n\t\tref\n\t) => {\n\t\tconst Layout = LayoutByOrientation[orientation]\n\t\treturn (\n\t\t\t<Layout asChild tooltipSide={tooltipSide}>\n\t\t\t\t<_Toolbar.Root\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...props}\n\t\t\t\t\tclassName={classnames('tlui-toolbar', className)}\n\t\t\t\t\taria-label={label}\n\t\t\t\t\torientation={orientation === 'grid' ? 'horizontal' : orientation}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</_Toolbar.Root>\n\t\t\t</Layout>\n\t\t)\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarButtonProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tasChild?: boolean\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdisabled?: boolean\n\tisActive?: boolean\n\ttype: 'icon' | 'tool' | 'menu'\n\ttooltip?: string\n}\n\n/** @public @react */\nexport const TldrawUiToolbarButton = React.forwardRef<HTMLButtonElement, TLUiToolbarButtonProps>(\n\t({ asChild, children, type, isActive, tooltip, ...props }: TLUiToolbarButtonProps, ref) => {\n\t\tconst button = (\n\t\t\t<_Toolbar.Button\n\t\t\t\tref={ref}\n\t\t\t\tasChild={asChild}\n\t\t\t\tdraggable={false}\n\t\t\t\tdata-isactive={isActive}\n\t\t\t\t{...props}\n\t\t\t\t// The tooltip takes care of this.\n\t\t\t\ttitle={undefined}\n\t\t\t\tclassName={classnames('tlui-button', `tlui-button__${type}`, props.className)}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</_Toolbar.Button>\n\t\t)\n\n\t\tconst tooltipContent = tooltip || props.title\n\n\t\treturn <TldrawUiTooltip content={tooltipContent}>{button}</TldrawUiTooltip>\n\t}\n)\n\n/** @public */\nexport interface TLUiToolbarToggleGroupProps extends React.HTMLAttributes<HTMLDivElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\tdir?: 'ltr' | 'rtl'\n\tvalue: any\n\t// TODO: fix up this type later\n\tdefaultValue?: any\n\ttype: 'single' | 'multiple'\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleGroup = ({\n\tchildren,\n\tclassName,\n\ttype,\n\t...props\n}: TLUiToolbarToggleGroupProps) => {\n\treturn (\n\t\t<_Toolbar.ToggleGroup\n\t\t\ttype={type}\n\t\t\t{...props}\n\t\t\t// TODO: this fixes a bug in Radix until they fix it.\n\t\t\t// https://github.com/radix-ui/primitives/issues/3188\n\t\t\t// https://github.com/radix-ui/primitives/pull/3189\n\t\t\trole=\"radiogroup\"\n\t\t\tclassName={classnames('tlui-toolbar-toggle-group', className)}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleGroup>\n\t)\n}\n\n/** @public */\nexport interface TLUiToolbarToggleItemProps extends React.HTMLAttributes<HTMLButtonElement> {\n\tchildren?: React.ReactNode\n\tclassName?: string\n\ttype: 'icon' | 'tool'\n\tvalue: string\n\ttooltip?: string\n}\n\n/** @public @react */\nexport const TldrawUiToolbarToggleItem = ({\n\tchildren,\n\tclassName,\n\ttype,\n\tvalue,\n\ttooltip,\n\t...props\n}: TLUiToolbarToggleItemProps) => {\n\tconst toggleItem = (\n\t\t<_Toolbar.ToggleItem\n\t\t\t{...props}\n\t\t\t// The tooltip takes care of this.\n\t\t\ttitle={undefined}\n\t\t\tclassName={classnames(\n\t\t\t\t'tlui-button',\n\t\t\t\t`tlui-button__${type}`,\n\t\t\t\t'tlui-toolbar-toggle-group-item',\n\t\t\t\tclassName\n\t\t\t)}\n\t\t\tvalue={value}\n\t\t>\n\t\t\t{children}\n\t\t</_Toolbar.ToggleItem>\n\t)\n\n\tconst tooltipContent = tooltip || props.title\n\n\treturn <TldrawUiTooltip content={tooltipContent}>{toggleItem}</TldrawUiTooltip>\n}\n"],
5
+ "mappings": "AAsCI;AAtCJ,OAAO,gBAAgB;AACvB,SAAS,WAAW,gBAAgB;AACpC,OAAO,WAAW;AAClB,SAAS,gBAAgB,cAAc,mBAAmB;AAC1D,SAAS,uBAAuB;AAYhC,MAAM,sBAAsB;AAAA,EAC3B,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,MAAM;AACP;AAGO,MAAM,kBAAkB,MAAM;AAAA,EACpC,CACC;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA,GAAG;AAAA,EACJ,GACA,QACI;AACJ,UAAM,SAAS,oBAAoB,WAAW;AAC9C,WACC,oBAAC,UAAO,SAAO,MAAC,aACf;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QACJ,WAAW,WAAW,gBAAgB,SAAS;AAAA,QAC/C,cAAY;AAAA,QACZ,aAAa,gBAAgB,SAAS,eAAe;AAAA,QAEpD;AAAA;AAAA,IACF,GACD;AAAA,EAEF;AACD;AAcO,MAAM,wBAAwB,MAAM;AAAA,EAC1C,CAAC,EAAE,SAAS,UAAU,MAAM,UAAU,SAAS,GAAG,MAAM,GAA2B,QAAQ;AAC1F,UAAM,SACL;AAAA,MAAC,SAAS;AAAA,MAAT;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW;AAAA,QACX,iBAAe;AAAA,QACd,GAAG;AAAA,QAEJ,OAAO;AAAA,QACP,WAAW,WAAW,eAAe,gBAAgB,IAAI,IAAI,MAAM,SAAS;AAAA,QAE3E;AAAA;AAAA,IACF;AAGD,UAAM,iBAAiB,WAAW,MAAM;AAExC,WAAO,oBAAC,mBAAgB,SAAS,gBAAiB,kBAAO;AAAA,EAC1D;AACD;AAcO,MAAM,6BAA6B,CAAC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,MAAmC;AAClC,SACC;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAIJ,MAAK;AAAA,MACL,WAAW,WAAW,6BAA6B,SAAS;AAAA,MAE3D;AAAA;AAAA,EACF;AAEF;AAYO,MAAM,4BAA4B,CAAC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACJ,MAAkC;AACjC,QAAM,aACL;AAAA,IAAC,SAAS;AAAA,IAAT;AAAA,MACC,GAAG;AAAA,MAEJ,OAAO;AAAA,MACP,WAAW;AAAA,QACV;AAAA,QACA,gBAAgB,IAAI;AAAA,QACpB;AAAA,QACA;AAAA,MACD;AAAA,MACA;AAAA,MAEC;AAAA;AAAA,EACF;AAGD,QAAM,iBAAiB,WAAW,MAAM;AAExC,SAAO,oBAAC,mBAAgB,SAAS,gBAAiB,sBAAW;AAC9D;",
6
6
  "names": []
7
7
  }
@@ -1,68 +1,75 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { uniqueId, useMaybeEditor, Vec } from "@tldraw/editor";
2
+ import { assert, atom, uniqueId, useMaybeEditor, useValue } from "@tldraw/editor";
3
3
  import { Tooltip as _Tooltip } from "radix-ui";
4
- import React, { createContext, useContext, useEffect, useRef, useState } from "react";
5
- import { usePrefersReducedMotion } from "../../../shapes/shared/usePrefersReducedMotion.mjs";
4
+ import React, {
5
+ createContext,
6
+ forwardRef,
7
+ useContext,
8
+ useEffect,
9
+ useRef,
10
+ useState
11
+ } from "react";
12
+ import { useTldrawUiOrientation } from "./layout.mjs";
6
13
  const DEFAULT_TOOLTIP_DELAY_MS = 700;
7
14
  class TooltipManager {
8
15
  static instance = null;
9
- currentTooltipId = null;
10
- currentContent = "";
11
- currentSide = "bottom";
12
- currentSideOffset = 5;
16
+ currentTooltip = atom("current tooltip", null);
13
17
  destroyTimeoutId = null;
14
- subscribers = /* @__PURE__ */ new Set();
15
- activeElement = null;
16
- editor = null;
17
18
  static getInstance() {
18
19
  if (!TooltipManager.instance) {
19
20
  TooltipManager.instance = new TooltipManager();
20
21
  }
21
22
  return TooltipManager.instance;
22
23
  }
23
- setEditor(editor) {
24
- this.editor = editor;
25
- }
26
- subscribe(callback) {
27
- this.subscribers.add(callback);
28
- return () => this.subscribers.delete(callback);
29
- }
30
- notify() {
31
- this.subscribers.forEach((callback) => callback());
32
- }
33
- showTooltip(tooltipId, content, element, side = "bottom", sideOffset = 5) {
24
+ showTooltip(tooltipId, content, targetElement, side, sideOffset, showOnMobile, delayDuration) {
34
25
  if (this.destroyTimeoutId) {
35
26
  clearTimeout(this.destroyTimeoutId);
36
27
  this.destroyTimeoutId = null;
37
28
  }
38
- this.currentTooltipId = tooltipId;
39
- this.currentContent = content;
40
- this.currentSide = side;
41
- this.currentSideOffset = sideOffset;
42
- this.activeElement = element;
43
- this.notify();
29
+ this.currentTooltip.set({
30
+ id: tooltipId,
31
+ content,
32
+ side,
33
+ sideOffset,
34
+ showOnMobile,
35
+ targetElement,
36
+ delayDuration
37
+ });
44
38
  }
45
- hideTooltip(tooltipId) {
46
- if (this.currentTooltipId === tooltipId) {
47
- if (this.editor) {
48
- this.destroyTimeoutId = this.editor.timers.setTimeout(() => {
49
- this.currentTooltipId = null;
50
- this.currentContent = "";
51
- this.activeElement = null;
52
- this.destroyTimeoutId = null;
53
- this.notify();
54
- }, 300);
39
+ hideTooltip(editor, tooltipId, instant = false) {
40
+ const hide = () => {
41
+ if (this.currentTooltip.get()?.id === tooltipId) {
42
+ this.currentTooltip.set(null);
43
+ this.destroyTimeoutId = null;
55
44
  }
45
+ };
46
+ if (editor && !instant) {
47
+ this.destroyTimeoutId = editor.timers.setTimeout(hide, 300);
48
+ } else {
49
+ hide();
56
50
  }
57
51
  }
52
+ hideAllTooltips() {
53
+ this.currentTooltip.set(null);
54
+ this.destroyTimeoutId = null;
55
+ }
58
56
  getCurrentTooltipData() {
59
- return {
60
- id: this.currentTooltipId,
61
- content: this.currentContent,
62
- side: this.currentSide,
63
- sideOffset: this.currentSideOffset,
64
- element: this.activeElement
65
- };
57
+ const currentTooltip = this.currentTooltip.get();
58
+ if (!currentTooltip) return null;
59
+ if (!this.supportsHover() && !currentTooltip.showOnMobile) return null;
60
+ return currentTooltip;
61
+ }
62
+ supportsHoverAtom = null;
63
+ supportsHover() {
64
+ if (!this.supportsHoverAtom) {
65
+ const mediaQuery = window.matchMedia("(hover: hover)");
66
+ const supportsHover = atom("has hover", mediaQuery.matches);
67
+ this.supportsHoverAtom = supportsHover;
68
+ mediaQuery.addEventListener("change", (e) => {
69
+ supportsHover.set(e.matches);
70
+ });
71
+ }
72
+ return this.supportsHoverAtom.get();
66
73
  }
67
74
  }
68
75
  const tooltipManager = TooltipManager.getInstance();
@@ -74,45 +81,19 @@ function TldrawUiTooltipProvider({ children }) {
74
81
  ] }) });
75
82
  }
76
83
  function TooltipSingleton() {
77
- const editor = useMaybeEditor();
78
- const [, forceUpdate] = useState({});
79
84
  const [isOpen, setIsOpen] = useState(false);
80
85
  const triggerRef = useRef(null);
81
- const previousPositionRef = useRef(null);
82
- const prefersReducedMotion = usePrefersReducedMotion();
83
- const [shouldAnimate, setShouldAnimate] = useState(false);
84
86
  const isFirstShowRef = useRef(true);
85
- const showTimeoutRef = useRef(null);
86
- useEffect(() => {
87
- tooltipManager.setEditor(editor);
88
- }, [editor]);
87
+ const currentTooltip = useValue(
88
+ "current tooltip",
89
+ () => tooltipManager.getCurrentTooltipData(),
90
+ []
91
+ );
89
92
  useEffect(() => {
90
- const unsubscribe = tooltipManager.subscribe(() => {
91
- forceUpdate({});
92
- });
93
- return unsubscribe;
94
- }, []);
95
- const tooltipData = tooltipManager.getCurrentTooltipData();
96
- useEffect(() => {
97
- const shouldBeOpen = Boolean(tooltipData.id && tooltipData.element);
98
- if (showTimeoutRef.current) {
99
- clearTimeout(showTimeoutRef.current);
100
- showTimeoutRef.current = null;
101
- }
102
- if (shouldBeOpen && tooltipData.element && triggerRef.current) {
103
- const activeRect = tooltipData.element.getBoundingClientRect();
93
+ let timer = null;
94
+ if (currentTooltip && triggerRef.current) {
95
+ const activeRect = currentTooltip.targetElement.getBoundingClientRect();
104
96
  const trigger = triggerRef.current;
105
- const newPosition = {
106
- x: activeRect.left + activeRect.width / 2,
107
- y: activeRect.top + activeRect.height / 2
108
- };
109
- let shouldAnimateCheck = false;
110
- if (previousPositionRef.current) {
111
- const isNearPrevious = Vec.DistMin(previousPositionRef.current, newPosition, 200);
112
- shouldAnimateCheck = !prefersReducedMotion && isNearPrevious && Math.abs(newPosition.y - previousPositionRef.current.y) < 50;
113
- }
114
- setShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck);
115
- previousPositionRef.current = newPosition;
116
97
  trigger.style.position = "fixed";
117
98
  trigger.style.left = `${activeRect.left}px`;
118
99
  trigger.style.top = `${activeRect.top}px`;
@@ -120,22 +101,25 @@ function TooltipSingleton() {
120
101
  trigger.style.height = `${activeRect.height}px`;
121
102
  trigger.style.pointerEvents = "none";
122
103
  trigger.style.zIndex = "9999";
123
- if (isFirstShowRef.current && editor) {
124
- showTimeoutRef.current = editor.timers.setTimeout(() => {
104
+ if (isFirstShowRef.current) {
105
+ timer = setTimeout(() => {
125
106
  setIsOpen(true);
126
107
  isFirstShowRef.current = false;
127
- }, editor.options.tooltipDelayMs);
108
+ }, currentTooltip.delayDuration);
128
109
  } else {
129
110
  setIsOpen(true);
130
111
  }
131
- } else if (!shouldBeOpen) {
112
+ } else {
132
113
  setIsOpen(false);
133
- previousPositionRef.current = null;
134
- setShouldAnimate(false);
135
114
  isFirstShowRef.current = true;
136
115
  }
137
- }, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion]);
138
- if (!tooltipData.id) {
116
+ return () => {
117
+ if (timer !== null) {
118
+ clearTimeout(timer);
119
+ }
120
+ };
121
+ }, [currentTooltip]);
122
+ if (!currentTooltip) {
139
123
  return null;
140
124
  }
141
125
  return /* @__PURE__ */ jsxs(_Tooltip.Root, { open: isOpen, delayDuration: 0, children: [
@@ -144,94 +128,112 @@ function TooltipSingleton() {
144
128
  _Tooltip.Content,
145
129
  {
146
130
  className: "tlui-tooltip",
147
- "data-should-animate": shouldAnimate,
148
- side: tooltipData.side,
149
- sideOffset: tooltipData.sideOffset,
131
+ side: currentTooltip.side,
132
+ sideOffset: currentTooltip.sideOffset,
150
133
  avoidCollisions: true,
151
134
  collisionPadding: 8,
152
135
  dir: "ltr",
153
136
  children: [
154
- tooltipData.content,
137
+ currentTooltip.content,
155
138
  /* @__PURE__ */ jsx(_Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
156
139
  ]
157
140
  }
158
141
  )
159
142
  ] });
160
143
  }
161
- function TldrawUiTooltip({
162
- children,
163
- content,
164
- side = "bottom",
165
- sideOffset = 5,
166
- disabled = false
167
- }) {
168
- const editor = useMaybeEditor();
169
- const tooltipId = useRef(uniqueId());
170
- const hasProvider = useContext(TooltipSingletonContext);
171
- if (disabled || !content) {
172
- return /* @__PURE__ */ jsx(Fragment, { children });
173
- }
174
- if (!hasProvider) {
175
- return /* @__PURE__ */ jsxs(
176
- _Tooltip.Root,
177
- {
178
- delayDuration: editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS,
179
- disableHoverableContent: true,
180
- children: [
181
- /* @__PURE__ */ jsx(_Tooltip.Trigger, { asChild: true, children }),
182
- /* @__PURE__ */ jsxs(
183
- _Tooltip.Content,
184
- {
185
- className: "tlui-tooltip",
186
- side,
187
- sideOffset,
188
- avoidCollisions: true,
189
- collisionPadding: 8,
190
- dir: "ltr",
191
- children: [
192
- content,
193
- /* @__PURE__ */ jsx(_Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
194
- ]
195
- }
196
- )
197
- ]
198
- }
199
- );
144
+ const TldrawUiTooltip = forwardRef(
145
+ ({
146
+ children,
147
+ content,
148
+ side,
149
+ sideOffset = 5,
150
+ disabled = false,
151
+ showOnMobile = false,
152
+ delayDuration
153
+ }, ref) => {
154
+ const editor = useMaybeEditor();
155
+ const tooltipId = useRef(uniqueId());
156
+ const hasProvider = useContext(TooltipSingletonContext);
157
+ const orientationCtx = useTldrawUiOrientation();
158
+ const sideToUse = side ?? orientationCtx.tooltipSide;
159
+ useEffect(() => {
160
+ const currentTooltipId = tooltipId.current;
161
+ return () => {
162
+ if (hasProvider) {
163
+ tooltipManager.hideTooltip(editor, currentTooltipId, true);
164
+ }
165
+ };
166
+ }, [editor, hasProvider]);
167
+ if (disabled || !content) {
168
+ return /* @__PURE__ */ jsx(Fragment, { children });
169
+ }
170
+ const delayDurationToUse = delayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS);
171
+ if (!hasProvider) {
172
+ return /* @__PURE__ */ jsxs(_Tooltip.Root, { delayDuration: delayDurationToUse, disableHoverableContent: true, children: [
173
+ /* @__PURE__ */ jsx(_Tooltip.Trigger, { asChild: true, ref, children }),
174
+ /* @__PURE__ */ jsxs(
175
+ _Tooltip.Content,
176
+ {
177
+ className: "tlui-tooltip",
178
+ side: sideToUse,
179
+ sideOffset,
180
+ avoidCollisions: true,
181
+ collisionPadding: 8,
182
+ dir: "ltr",
183
+ children: [
184
+ content,
185
+ /* @__PURE__ */ jsx(_Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
186
+ ]
187
+ }
188
+ )
189
+ ] });
190
+ }
191
+ const child = React.Children.only(children);
192
+ assert(React.isValidElement(child), "TldrawUiTooltip children must be a single element");
193
+ const handleMouseEnter = (event) => {
194
+ child.props.onMouseEnter?.(event);
195
+ tooltipManager.showTooltip(
196
+ tooltipId.current,
197
+ content,
198
+ event.currentTarget,
199
+ sideToUse,
200
+ sideOffset,
201
+ showOnMobile,
202
+ delayDurationToUse
203
+ );
204
+ };
205
+ const handleMouseLeave = (event) => {
206
+ child.props.onMouseLeave?.(event);
207
+ tooltipManager.hideTooltip(editor, tooltipId.current);
208
+ };
209
+ const handleFocus = (event) => {
210
+ child.props.onFocus?.(event);
211
+ tooltipManager.showTooltip(
212
+ tooltipId.current,
213
+ content,
214
+ event.currentTarget,
215
+ sideToUse,
216
+ sideOffset,
217
+ showOnMobile,
218
+ delayDurationToUse
219
+ );
220
+ };
221
+ const handleBlur = (event) => {
222
+ child.props.onBlur?.(event);
223
+ tooltipManager.hideTooltip(editor, tooltipId.current);
224
+ };
225
+ const childrenWithHandlers = React.cloneElement(children, {
226
+ onMouseEnter: handleMouseEnter,
227
+ onMouseLeave: handleMouseLeave,
228
+ onFocus: handleFocus,
229
+ onBlur: handleBlur
230
+ });
231
+ return childrenWithHandlers;
200
232
  }
201
- const handleMouseEnter = (event) => {
202
- tooltipManager.showTooltip(
203
- tooltipId.current,
204
- content,
205
- event.currentTarget,
206
- side,
207
- sideOffset
208
- );
209
- };
210
- const handleMouseLeave = () => {
211
- tooltipManager.hideTooltip(tooltipId.current);
212
- };
213
- const handleFocus = (event) => {
214
- tooltipManager.showTooltip(
215
- tooltipId.current,
216
- content,
217
- event.currentTarget,
218
- side,
219
- sideOffset
220
- );
221
- };
222
- const handleBlur = () => {
223
- tooltipManager.hideTooltip(tooltipId.current);
224
- };
225
- const childrenWithHandlers = React.cloneElement(children, {
226
- onMouseEnter: handleMouseEnter,
227
- onMouseLeave: handleMouseLeave,
228
- onFocus: handleFocus,
229
- onBlur: handleBlur
230
- });
231
- return childrenWithHandlers;
232
- }
233
+ );
233
234
  export {
234
235
  TldrawUiTooltip,
235
- TldrawUiTooltipProvider
236
+ TldrawUiTooltipProvider,
237
+ tooltipManager
236
238
  };
237
239
  //# sourceMappingURL=TldrawUiTooltip.mjs.map