tldraw 3.16.0-canary.efdec30fc411 → 3.16.0-canary.f293c3bb58f5

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 (264) hide show
  1. package/dist-cjs/index.d.ts +116 -4
  2. package/dist-cjs/index.js +8 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  5. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  6. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -3
  7. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  9. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  10. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  11. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  13. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  14. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +12 -12
  15. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  17. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  18. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  19. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  20. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  21. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  22. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  23. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  24. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
  25. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
  26. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  27. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  28. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  29. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  31. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  32. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  33. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  34. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  35. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  36. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  37. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  38. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  39. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  40. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  41. package/dist-cjs/lib/ui/TldrawUi.js +14 -0
  42. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  43. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  44. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  45. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +10 -2
  46. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  47. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +1 -1
  48. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  49. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  50. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  51. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  52. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  53. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +1 -1
  54. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +2 -2
  55. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  56. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  57. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -22
  58. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  59. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +188 -78
  60. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  61. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +1 -1
  62. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +2 -2
  63. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +15 -3
  64. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  65. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +146 -168
  66. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  67. package/dist-cjs/lib/ui/components/primitives/layout.js +30 -5
  68. package/dist-cjs/lib/ui/components/primitives/layout.js.map +2 -2
  69. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  70. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  71. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +3 -19
  73. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  74. package/dist-cjs/lib/ui/context/actions.js +16 -2
  75. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  76. package/dist-cjs/lib/ui/hooks/useTools.js +21 -3
  77. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  78. package/dist-cjs/lib/ui/version.js +3 -3
  79. package/dist-cjs/lib/ui/version.js.map +1 -1
  80. package/dist-esm/index.d.mts +116 -4
  81. package/dist-esm/index.mjs +12 -2
  82. package/dist-esm/index.mjs.map +2 -2
  83. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  84. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  85. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
  86. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  87. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  88. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  89. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  90. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  91. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  92. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  93. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +13 -12
  94. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  95. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  96. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  97. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  98. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  99. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  100. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  101. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  102. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  103. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
  104. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
  105. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  106. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  107. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  108. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  109. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  110. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  111. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  112. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  113. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  114. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  115. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  116. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  117. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  118. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  119. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  120. package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
  121. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  122. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  123. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  124. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +10 -2
  125. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  126. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +1 -1
  127. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  128. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  129. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  130. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  131. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  132. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +1 -1
  133. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  134. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  135. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  136. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -22
  137. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  138. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -80
  139. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  140. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +2 -1
  141. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  142. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +16 -4
  143. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  144. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +155 -170
  145. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  146. package/dist-esm/lib/ui/components/primitives/layout.mjs +31 -6
  147. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +2 -2
  148. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  149. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  150. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  151. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +3 -19
  152. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  153. package/dist-esm/lib/ui/context/actions.mjs +16 -2
  154. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  155. package/dist-esm/lib/ui/hooks/useTools.mjs +22 -3
  156. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  157. package/dist-esm/lib/ui/version.mjs +3 -3
  158. package/dist-esm/lib/ui/version.mjs.map +1 -1
  159. package/package.json +11 -34
  160. package/src/index.ts +8 -0
  161. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  162. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  163. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  164. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
  165. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
  166. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  167. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  168. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  169. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  170. package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -14
  171. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  172. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  173. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  174. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  175. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
  176. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  177. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  178. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  179. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  180. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  181. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  182. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  183. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  184. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  185. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  186. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  187. package/src/lib/ui/TldrawUi.tsx +17 -2
  188. package/src/lib/ui/assetUrls.ts +13 -10
  189. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +13 -2
  190. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +1 -1
  191. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  192. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  193. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +1 -1
  194. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  195. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -24
  196. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +208 -56
  197. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +3 -2
  198. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +22 -5
  199. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +184 -191
  200. package/src/lib/ui/components/primitives/layout.tsx +79 -5
  201. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  202. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  203. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +5 -18
  204. package/src/lib/ui/context/actions.tsx +16 -2
  205. package/src/lib/ui/hooks/useTools.tsx +25 -3
  206. package/src/lib/ui/version.ts +3 -3
  207. package/src/lib/ui.css +349 -243
  208. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  209. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  210. package/src/test/A11y.test.tsx +3 -2
  211. package/src/test/ClickManager.test.ts +7 -6
  212. package/src/test/Editor.test.tsx +20 -19
  213. package/src/test/EraserTool.test.ts +184 -13
  214. package/src/test/HandTool.test.ts +10 -9
  215. package/src/test/HighlightShape.test.ts +2 -1
  216. package/src/test/SelectTool.test.ts +3 -2
  217. package/src/test/TLUserPreferences.test.ts +4 -3
  218. package/src/test/TestEditor.ts +13 -15
  219. package/src/test/TldrawEditor.test.tsx +11 -10
  220. package/src/test/ZoomTool.test.ts +7 -6
  221. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  222. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  223. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  224. package/src/test/arrows-megabus.test.tsx +5 -4
  225. package/src/test/bindings.test.tsx +24 -37
  226. package/src/test/bookmark-shapes.test.ts +1 -8
  227. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  228. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  229. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  230. package/src/test/commands/alignShapes.test.tsx +25 -24
  231. package/src/test/commands/animationSpeed.test.ts +2 -1
  232. package/src/test/commands/centerOnPoint.test.ts +3 -2
  233. package/src/test/commands/clipboard.test.ts +3 -2
  234. package/src/test/commands/createShapes.test.ts +2 -1
  235. package/src/test/commands/deleteShapes.test.ts +2 -1
  236. package/src/test/commands/distributeShapes.test.tsx +11 -10
  237. package/src/test/commands/getSvgString.test.ts +2 -1
  238. package/src/test/commands/packShapes.test.ts +5 -4
  239. package/src/test/commands/resizeShape.test.ts +2 -1
  240. package/src/test/commands/rotateShapes.test.ts +7 -6
  241. package/src/test/commands/setCamera.test.ts +4 -3
  242. package/src/test/commands/setCurrentPage.test.ts +3 -2
  243. package/src/test/commands/stackShapes.test.ts +11 -10
  244. package/src/test/commands/stretch.test.tsx +13 -12
  245. package/src/test/createDeepLink.test.tsx +2 -1
  246. package/src/test/cropping.test.ts +3 -2
  247. package/src/test/drawing.test.ts +2 -1
  248. package/src/test/flipShapes.test.ts +4 -3
  249. package/src/test/frames.test.ts +25 -24
  250. package/src/test/getCulledShapes.test.tsx +3 -2
  251. package/src/test/groups.test.tsx +1 -1
  252. package/src/test/handleDeepLink.test.tsx +2 -1
  253. package/src/test/maxShapes.test.ts +3 -2
  254. package/src/test/modifiers.test.ts +5 -4
  255. package/src/test/navigation.test.ts +12 -11
  256. package/src/test/panning.test.ts +2 -1
  257. package/src/test/perf/perf.test.ts +2 -1
  258. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  259. package/src/test/resizing.test.ts +39 -38
  260. package/src/test/select.test.tsx +4 -3
  261. package/src/test/selection-omnibus.test.ts +11 -10
  262. package/src/test/shapeutils.test.ts +4 -3
  263. package/src/test/translating.test.ts +9 -8
  264. package/tldraw.css +642 -533
@@ -37,77 +37,67 @@ var import_jsx_runtime = require("react/jsx-runtime");
37
37
  var import_editor = require("@tldraw/editor");
38
38
  var import_radix_ui = require("radix-ui");
39
39
  var import_react = __toESM(require("react"));
40
- var import_usePrefersReducedMotion = require("../../../shapes/shared/usePrefersReducedMotion");
40
+ var import_layout = require("./layout");
41
41
  const DEFAULT_TOOLTIP_DELAY_MS = 700;
42
42
  class TooltipManager {
43
43
  static instance = null;
44
- currentTooltipId = null;
45
- currentContent = "";
46
- currentSide = "bottom";
47
- currentSideOffset = 5;
44
+ currentTooltip = (0, import_editor.atom)("current tooltip", null);
48
45
  destroyTimeoutId = null;
49
- subscribers = /* @__PURE__ */ new Set();
50
- activeElement = null;
51
- editor = null;
52
46
  static getInstance() {
53
47
  if (!TooltipManager.instance) {
54
48
  TooltipManager.instance = new TooltipManager();
55
49
  }
56
50
  return TooltipManager.instance;
57
51
  }
58
- setEditor(editor) {
59
- this.editor = editor;
60
- }
61
- subscribe(callback) {
62
- this.subscribers.add(callback);
63
- return () => this.subscribers.delete(callback);
64
- }
65
- notify() {
66
- this.subscribers.forEach((callback) => callback());
67
- }
68
- showTooltip(tooltipId, content, element, side = "bottom", sideOffset = 5) {
52
+ showTooltip(tooltipId, content, targetElement, side, sideOffset, showOnMobile, delayDuration) {
69
53
  if (this.destroyTimeoutId) {
70
54
  clearTimeout(this.destroyTimeoutId);
71
55
  this.destroyTimeoutId = null;
72
56
  }
73
- this.currentTooltipId = tooltipId;
74
- this.currentContent = content;
75
- this.currentSide = side;
76
- this.currentSideOffset = sideOffset;
77
- this.activeElement = element;
78
- this.notify();
57
+ this.currentTooltip.set({
58
+ id: tooltipId,
59
+ content,
60
+ side,
61
+ sideOffset,
62
+ showOnMobile,
63
+ targetElement,
64
+ delayDuration
65
+ });
79
66
  }
80
- hideTooltip(tooltipId, instant = false) {
67
+ hideTooltip(editor, tooltipId, instant = false) {
81
68
  const hide = () => {
82
- if (this.currentTooltipId === tooltipId) {
83
- this.currentTooltipId = null;
84
- this.currentContent = "";
85
- this.activeElement = null;
69
+ if (this.currentTooltip.get()?.id === tooltipId) {
70
+ this.currentTooltip.set(null);
86
71
  this.destroyTimeoutId = null;
87
- this.notify();
88
72
  }
89
73
  };
90
- if (instant) {
74
+ if (editor && !instant) {
75
+ this.destroyTimeoutId = editor.timers.setTimeout(hide, 300);
76
+ } else {
91
77
  hide();
92
- } else if (this.editor) {
93
- this.destroyTimeoutId = this.editor.timers.setTimeout(hide, 300);
94
78
  }
95
79
  }
96
80
  hideAllTooltips() {
97
- this.currentTooltipId = null;
98
- this.currentContent = "";
99
- this.activeElement = null;
81
+ this.currentTooltip.set(null);
100
82
  this.destroyTimeoutId = null;
101
- this.notify();
102
83
  }
103
84
  getCurrentTooltipData() {
104
- return {
105
- id: this.currentTooltipId,
106
- content: this.currentContent,
107
- side: this.currentSide,
108
- sideOffset: this.currentSideOffset,
109
- element: this.activeElement
110
- };
85
+ const currentTooltip = this.currentTooltip.get();
86
+ if (!currentTooltip) return null;
87
+ if (!this.supportsHover() && !currentTooltip.showOnMobile) return null;
88
+ return currentTooltip;
89
+ }
90
+ supportsHoverAtom = null;
91
+ supportsHover() {
92
+ if (!this.supportsHoverAtom) {
93
+ const mediaQuery = window.matchMedia("(hover: hover)");
94
+ const supportsHover = (0, import_editor.atom)("has hover", mediaQuery.matches);
95
+ this.supportsHoverAtom = supportsHover;
96
+ mediaQuery.addEventListener("change", (e) => {
97
+ supportsHover.set(e.matches);
98
+ });
99
+ }
100
+ return this.supportsHoverAtom.get();
111
101
  }
112
102
  }
113
103
  const tooltipManager = TooltipManager.getInstance();
@@ -119,45 +109,19 @@ function TldrawUiTooltipProvider({ children }) {
119
109
  ] }) });
120
110
  }
121
111
  function TooltipSingleton() {
122
- const editor = (0, import_editor.useMaybeEditor)();
123
- const [, forceUpdate] = (0, import_react.useState)({});
124
112
  const [isOpen, setIsOpen] = (0, import_react.useState)(false);
125
113
  const triggerRef = (0, import_react.useRef)(null);
126
- const previousPositionRef = (0, import_react.useRef)(null);
127
- const prefersReducedMotion = (0, import_usePrefersReducedMotion.usePrefersReducedMotion)();
128
- const [shouldAnimate, setShouldAnimate] = (0, import_react.useState)(false);
129
114
  const isFirstShowRef = (0, import_react.useRef)(true);
130
- const showTimeoutRef = (0, import_react.useRef)(null);
115
+ const currentTooltip = (0, import_editor.useValue)(
116
+ "current tooltip",
117
+ () => tooltipManager.getCurrentTooltipData(),
118
+ []
119
+ );
131
120
  (0, import_react.useEffect)(() => {
132
- tooltipManager.setEditor(editor);
133
- }, [editor]);
134
- (0, import_react.useEffect)(() => {
135
- const unsubscribe = tooltipManager.subscribe(() => {
136
- forceUpdate({});
137
- });
138
- return unsubscribe;
139
- }, []);
140
- const tooltipData = tooltipManager.getCurrentTooltipData();
141
- (0, import_react.useEffect)(() => {
142
- const shouldBeOpen = Boolean(tooltipData.id && tooltipData.element);
143
- if (showTimeoutRef.current) {
144
- clearTimeout(showTimeoutRef.current);
145
- showTimeoutRef.current = null;
146
- }
147
- if (shouldBeOpen && tooltipData.element && triggerRef.current) {
148
- const activeRect = tooltipData.element.getBoundingClientRect();
121
+ let timer = null;
122
+ if (currentTooltip && triggerRef.current) {
123
+ const activeRect = currentTooltip.targetElement.getBoundingClientRect();
149
124
  const trigger = triggerRef.current;
150
- const newPosition = {
151
- x: activeRect.left + activeRect.width / 2,
152
- y: activeRect.top + activeRect.height / 2
153
- };
154
- let shouldAnimateCheck = false;
155
- if (previousPositionRef.current) {
156
- const isNearPrevious = import_editor.Vec.DistMin(previousPositionRef.current, newPosition, 200);
157
- shouldAnimateCheck = !prefersReducedMotion && isNearPrevious && Math.abs(newPosition.y - previousPositionRef.current.y) < 50;
158
- }
159
- setShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck);
160
- previousPositionRef.current = newPosition;
161
125
  trigger.style.position = "fixed";
162
126
  trigger.style.left = `${activeRect.left}px`;
163
127
  trigger.style.top = `${activeRect.top}px`;
@@ -165,22 +129,25 @@ function TooltipSingleton() {
165
129
  trigger.style.height = `${activeRect.height}px`;
166
130
  trigger.style.pointerEvents = "none";
167
131
  trigger.style.zIndex = "9999";
168
- if (isFirstShowRef.current && editor) {
169
- showTimeoutRef.current = editor.timers.setTimeout(() => {
132
+ if (isFirstShowRef.current) {
133
+ timer = setTimeout(() => {
170
134
  setIsOpen(true);
171
135
  isFirstShowRef.current = false;
172
- }, editor.options.tooltipDelayMs);
136
+ }, currentTooltip.delayDuration);
173
137
  } else {
174
138
  setIsOpen(true);
175
139
  }
176
- } else if (!shouldBeOpen) {
140
+ } else {
177
141
  setIsOpen(false);
178
- previousPositionRef.current = null;
179
- setShouldAnimate(false);
180
142
  isFirstShowRef.current = true;
181
143
  }
182
- }, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion]);
183
- if (!tooltipData.id) {
144
+ return () => {
145
+ if (timer !== null) {
146
+ clearTimeout(timer);
147
+ }
148
+ };
149
+ }, [currentTooltip]);
150
+ if (!currentTooltip) {
184
151
  return null;
185
152
  }
186
153
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_radix_ui.Tooltip.Root, { open: isOpen, delayDuration: 0, children: [
@@ -189,96 +156,107 @@ function TooltipSingleton() {
189
156
  import_radix_ui.Tooltip.Content,
190
157
  {
191
158
  className: "tlui-tooltip",
192
- "data-should-animate": shouldAnimate,
193
- side: tooltipData.side,
194
- sideOffset: tooltipData.sideOffset,
159
+ side: currentTooltip.side,
160
+ sideOffset: currentTooltip.sideOffset,
195
161
  avoidCollisions: true,
196
162
  collisionPadding: 8,
197
163
  dir: "ltr",
198
164
  children: [
199
- tooltipData.content,
165
+ currentTooltip.content,
200
166
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
201
167
  ]
202
168
  }
203
169
  )
204
170
  ] });
205
171
  }
206
- function TldrawUiTooltip({
207
- children,
208
- content,
209
- side = "bottom",
210
- sideOffset = 5,
211
- disabled = false
212
- }) {
213
- const editor = (0, import_editor.useMaybeEditor)();
214
- const tooltipId = (0, import_react.useRef)((0, import_editor.uniqueId)());
215
- const hasProvider = (0, import_react.useContext)(TooltipSingletonContext);
216
- if (disabled || !content) {
217
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
218
- }
219
- if (!hasProvider) {
220
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
221
- import_radix_ui.Tooltip.Root,
222
- {
223
- delayDuration: editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS,
224
- disableHoverableContent: true,
225
- children: [
226
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Tooltip.Trigger, { asChild: true, children }),
227
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
228
- import_radix_ui.Tooltip.Content,
229
- {
230
- className: "tlui-tooltip",
231
- side,
232
- sideOffset,
233
- avoidCollisions: true,
234
- collisionPadding: 8,
235
- dir: "ltr",
236
- children: [
237
- content,
238
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
239
- ]
240
- }
241
- )
242
- ]
243
- }
244
- );
172
+ const TldrawUiTooltip = (0, import_react.forwardRef)(
173
+ ({
174
+ children,
175
+ content,
176
+ side,
177
+ sideOffset = 5,
178
+ disabled = false,
179
+ showOnMobile = false,
180
+ delayDuration
181
+ }, ref) => {
182
+ const editor = (0, import_editor.useMaybeEditor)();
183
+ const tooltipId = (0, import_react.useRef)((0, import_editor.uniqueId)());
184
+ const hasProvider = (0, import_react.useContext)(TooltipSingletonContext);
185
+ const orientationCtx = (0, import_layout.useTldrawUiOrientation)();
186
+ const sideToUse = side ?? orientationCtx.tooltipSide;
187
+ (0, import_react.useEffect)(() => {
188
+ const currentTooltipId = tooltipId.current;
189
+ return () => {
190
+ if (hasProvider) {
191
+ tooltipManager.hideTooltip(editor, currentTooltipId, true);
192
+ }
193
+ };
194
+ }, [editor, hasProvider]);
195
+ if (disabled || !content) {
196
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children });
197
+ }
198
+ const delayDurationToUse = delayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS);
199
+ if (!hasProvider) {
200
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_radix_ui.Tooltip.Root, { delayDuration: delayDurationToUse, disableHoverableContent: true, children: [
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Tooltip.Trigger, { asChild: true, ref, children }),
202
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
203
+ import_radix_ui.Tooltip.Content,
204
+ {
205
+ className: "tlui-tooltip",
206
+ side: sideToUse,
207
+ sideOffset,
208
+ avoidCollisions: true,
209
+ collisionPadding: 8,
210
+ dir: "ltr",
211
+ children: [
212
+ content,
213
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_radix_ui.Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
214
+ ]
215
+ }
216
+ )
217
+ ] });
218
+ }
219
+ const child = import_react.default.Children.only(children);
220
+ (0, import_editor.assert)(import_react.default.isValidElement(child), "TldrawUiTooltip children must be a single element");
221
+ const handleMouseEnter = (event) => {
222
+ child.props.onMouseEnter?.(event);
223
+ tooltipManager.showTooltip(
224
+ tooltipId.current,
225
+ content,
226
+ event.currentTarget,
227
+ sideToUse,
228
+ sideOffset,
229
+ showOnMobile,
230
+ delayDurationToUse
231
+ );
232
+ };
233
+ const handleMouseLeave = (event) => {
234
+ child.props.onMouseLeave?.(event);
235
+ tooltipManager.hideTooltip(editor, tooltipId.current);
236
+ };
237
+ const handleFocus = (event) => {
238
+ child.props.onFocus?.(event);
239
+ tooltipManager.showTooltip(
240
+ tooltipId.current,
241
+ content,
242
+ event.currentTarget,
243
+ sideToUse,
244
+ sideOffset,
245
+ showOnMobile,
246
+ delayDurationToUse
247
+ );
248
+ };
249
+ const handleBlur = (event) => {
250
+ child.props.onBlur?.(event);
251
+ tooltipManager.hideTooltip(editor, tooltipId.current);
252
+ };
253
+ const childrenWithHandlers = import_react.default.cloneElement(children, {
254
+ onMouseEnter: handleMouseEnter,
255
+ onMouseLeave: handleMouseLeave,
256
+ onFocus: handleFocus,
257
+ onBlur: handleBlur
258
+ });
259
+ return childrenWithHandlers;
245
260
  }
246
- const child = import_react.default.Children.only(children);
247
- (0, import_editor.assert)(import_react.default.isValidElement(child), "TldrawUiTooltip children must be a single element");
248
- const handleMouseEnter = (event) => {
249
- child.props.onMouseEnter?.(event);
250
- tooltipManager.showTooltip(
251
- tooltipId.current,
252
- content,
253
- event.currentTarget,
254
- side,
255
- sideOffset
256
- );
257
- };
258
- const handleMouseLeave = (event) => {
259
- child.props.onMouseLeave?.(event);
260
- tooltipManager.hideTooltip(tooltipId.current);
261
- };
262
- const handleFocus = (event) => {
263
- child.props.onFocus?.(event);
264
- tooltipManager.showTooltip(
265
- tooltipId.current,
266
- content,
267
- event.currentTarget,
268
- side,
269
- sideOffset
270
- );
271
- };
272
- const handleBlur = (event) => {
273
- child.props.onBlur?.(event);
274
- tooltipManager.hideTooltip(tooltipId.current);
275
- };
276
- const childrenWithHandlers = import_react.default.cloneElement(children, {
277
- onMouseEnter: handleMouseEnter,
278
- onMouseLeave: handleMouseLeave,
279
- onFocus: handleFocus,
280
- onBlur: handleBlur
281
- });
282
- return childrenWithHandlers;
283
- }
261
+ );
284
262
  //# sourceMappingURL=TldrawUiTooltip.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiTooltip.tsx"],
4
- "sourcesContent": ["import { assert, Editor, uniqueId, useMaybeEditor, Vec } from '@tldraw/editor'\nimport { Tooltip as _Tooltip } from 'radix-ui'\nimport React, { createContext, useContext, useEffect, useRef, useState } from 'react'\nimport { usePrefersReducedMotion } from '../../../shapes/shared/usePrefersReducedMotion'\n\nconst DEFAULT_TOOLTIP_DELAY_MS = 700\n\n/** @public */\nexport interface TldrawUiTooltipProps {\n\tchildren: React.ReactNode\n\tcontent?: string | React.ReactNode\n\tside?: 'top' | 'right' | 'bottom' | 'left'\n\tsideOffset?: number\n\tdisabled?: boolean\n}\n\n// Singleton tooltip manager\nclass TooltipManager {\n\tprivate static instance: TooltipManager | null = null\n\tprivate currentTooltipId: string | null = null\n\tprivate currentContent: string | React.ReactNode = ''\n\tprivate currentSide: 'top' | 'right' | 'bottom' | 'left' = 'bottom'\n\tprivate currentSideOffset: number = 5\n\tprivate destroyTimeoutId: number | null = null\n\tprivate subscribers: Set<() => void> = new Set()\n\tprivate activeElement: HTMLElement | null = null\n\tprivate editor: Editor | null = null\n\n\tstatic getInstance(): TooltipManager {\n\t\tif (!TooltipManager.instance) {\n\t\t\tTooltipManager.instance = new TooltipManager()\n\t\t}\n\t\treturn TooltipManager.instance\n\t}\n\n\tsetEditor(editor: Editor | null) {\n\t\tthis.editor = editor\n\t}\n\n\tsubscribe(callback: () => void): () => void {\n\t\tthis.subscribers.add(callback)\n\t\treturn () => this.subscribers.delete(callback)\n\t}\n\n\tprivate notify() {\n\t\tthis.subscribers.forEach((callback) => callback())\n\t}\n\n\tshowTooltip(\n\t\ttooltipId: string,\n\t\tcontent: string | React.ReactNode,\n\t\telement: HTMLElement,\n\t\tside: 'top' | 'right' | 'bottom' | 'left' = 'bottom',\n\t\tsideOffset: number = 5\n\t) {\n\t\t// Clear any existing destroy timeout\n\t\tif (this.destroyTimeoutId) {\n\t\t\tclearTimeout(this.destroyTimeoutId)\n\t\t\tthis.destroyTimeoutId = null\n\t\t}\n\n\t\t// Update current tooltip\n\t\tthis.currentTooltipId = tooltipId\n\t\tthis.currentContent = content\n\t\tthis.currentSide = side\n\t\tthis.currentSideOffset = sideOffset\n\t\tthis.activeElement = element\n\n\t\tthis.notify()\n\t}\n\n\thideTooltip(tooltipId: string, instant: boolean = false) {\n\t\tconst hide = () => {\n\t\t\t// Only hide if this is the current tooltip\n\t\t\tif (this.currentTooltipId === tooltipId) {\n\t\t\t\tthis.currentTooltipId = null\n\t\t\t\tthis.currentContent = ''\n\t\t\t\tthis.activeElement = null\n\t\t\t\tthis.destroyTimeoutId = null\n\t\t\t\tthis.notify()\n\t\t\t}\n\t\t}\n\n\t\tif (instant) {\n\t\t\thide()\n\t\t} else if (this.editor) {\n\t\t\t// Start destroy timeout (1 second)\n\t\t\tthis.destroyTimeoutId = this.editor.timers.setTimeout(hide, 300)\n\t\t}\n\t}\n\n\thideAllTooltips() {\n\t\tthis.currentTooltipId = null\n\t\tthis.currentContent = ''\n\t\tthis.activeElement = null\n\t\tthis.destroyTimeoutId = null\n\t\tthis.notify()\n\t}\n\n\tgetCurrentTooltipData() {\n\t\treturn {\n\t\t\tid: this.currentTooltipId,\n\t\t\tcontent: this.currentContent,\n\t\t\tside: this.currentSide,\n\t\t\tsideOffset: this.currentSideOffset,\n\t\t\telement: this.activeElement,\n\t\t}\n\t}\n}\n\nexport const tooltipManager = TooltipManager.getInstance()\n\n// Context for the tooltip singleton\nconst TooltipSingletonContext = createContext<boolean>(false)\n\n/** @public */\nexport interface TldrawUiTooltipProviderProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderProps) {\n\treturn (\n\t\t<_Tooltip.Provider skipDelayDuration={700}>\n\t\t\t<TooltipSingletonContext.Provider value={true}>\n\t\t\t\t{children}\n\t\t\t\t<TooltipSingleton />\n\t\t\t</TooltipSingletonContext.Provider>\n\t\t</_Tooltip.Provider>\n\t)\n}\n\n// The singleton tooltip component that renders once\nfunction TooltipSingleton() {\n\tconst editor = useMaybeEditor()\n\tconst [, forceUpdate] = useState({})\n\tconst [isOpen, setIsOpen] = useState(false)\n\tconst triggerRef = useRef<HTMLDivElement>(null)\n\tconst previousPositionRef = useRef<{ x: number; y: number } | null>(null)\n\tconst prefersReducedMotion = usePrefersReducedMotion()\n\tconst [shouldAnimate, setShouldAnimate] = useState(false)\n\tconst isFirstShowRef = useRef(true)\n\tconst showTimeoutRef = useRef<number | null>(null)\n\n\t// Set editor in tooltip manager\n\tuseEffect(() => {\n\t\ttooltipManager.setEditor(editor)\n\t}, [editor])\n\n\t// Subscribe to tooltip manager updates\n\tuseEffect(() => {\n\t\tconst unsubscribe = tooltipManager.subscribe(() => {\n\t\t\tforceUpdate({})\n\t\t})\n\t\treturn unsubscribe\n\t}, [])\n\n\tconst tooltipData = tooltipManager.getCurrentTooltipData()\n\n\t// Update open state and trigger position\n\tuseEffect(() => {\n\t\tconst shouldBeOpen = Boolean(tooltipData.id && tooltipData.element)\n\n\t\t// Clear any existing show timeout\n\t\tif (showTimeoutRef.current) {\n\t\t\tclearTimeout(showTimeoutRef.current)\n\t\t\tshowTimeoutRef.current = null\n\t\t}\n\n\t\tif (shouldBeOpen && tooltipData.element && triggerRef.current) {\n\t\t\t// Position the invisible trigger element over the active element\n\t\t\tconst activeRect = tooltipData.element.getBoundingClientRect()\n\t\t\tconst trigger = triggerRef.current\n\n\t\t\tconst newPosition = {\n\t\t\t\tx: activeRect.left + activeRect.width / 2,\n\t\t\t\ty: activeRect.top + activeRect.height / 2,\n\t\t\t}\n\n\t\t\t// Determine if we should animate\n\t\t\tlet shouldAnimateCheck = false\n\t\t\tif (previousPositionRef.current) {\n\t\t\t\tconst isNearPrevious = Vec.DistMin(previousPositionRef.current, newPosition, 200)\n\t\t\t\t// Only animate if the distance is less than 200px (nearby tooltips)\n\t\t\t\tshouldAnimateCheck =\n\t\t\t\t\t!prefersReducedMotion &&\n\t\t\t\t\tisNearPrevious &&\n\t\t\t\t\tMath.abs(newPosition.y - previousPositionRef.current.y) < 50\n\t\t\t}\n\t\t\t// Don't animate on initial show (previousPositionRef.current is null)\n\n\t\t\tsetShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck)\n\t\t\tpreviousPositionRef.current = newPosition\n\n\t\t\ttrigger.style.position = 'fixed'\n\t\t\ttrigger.style.left = `${activeRect.left}px`\n\t\t\ttrigger.style.top = `${activeRect.top}px`\n\t\t\ttrigger.style.width = `${activeRect.width}px`\n\t\t\ttrigger.style.height = `${activeRect.height}px`\n\t\t\ttrigger.style.pointerEvents = 'none'\n\t\t\ttrigger.style.zIndex = '9999'\n\n\t\t\t// Handle delay for first show\n\t\t\tif (isFirstShowRef.current && editor) {\n\t\t\t\tshowTimeoutRef.current = editor.timers.setTimeout(() => {\n\t\t\t\t\tsetIsOpen(true)\n\t\t\t\t\tisFirstShowRef.current = false\n\t\t\t\t}, editor.options.tooltipDelayMs)\n\t\t\t} else {\n\t\t\t\t// Subsequent tooltips show immediately\n\t\t\t\tsetIsOpen(true)\n\t\t\t}\n\t\t} else if (!shouldBeOpen) {\n\t\t\t// Hide tooltip immediately\n\t\t\tsetIsOpen(false)\n\t\t\t// Reset position tracking when tooltip closes\n\t\t\tpreviousPositionRef.current = null\n\t\t\tsetShouldAnimate(false)\n\t\t\t// Reset first show state after tooltip is hidden\n\t\t\tisFirstShowRef.current = true\n\t\t}\n\t}, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion])\n\n\tif (!tooltipData.id) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<_Tooltip.Root open={isOpen} delayDuration={0}>\n\t\t\t<_Tooltip.Trigger asChild>\n\t\t\t\t<div ref={triggerRef} />\n\t\t\t</_Tooltip.Trigger>\n\t\t\t<_Tooltip.Content\n\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\tdata-should-animate={shouldAnimate}\n\t\t\t\tside={tooltipData.side}\n\t\t\t\tsideOffset={tooltipData.sideOffset}\n\t\t\t\tavoidCollisions\n\t\t\t\tcollisionPadding={8}\n\t\t\t\tdir=\"ltr\"\n\t\t\t>\n\t\t\t\t{tooltipData.content}\n\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t</_Tooltip.Content>\n\t\t</_Tooltip.Root>\n\t)\n}\n\n/** @public @react */\nexport function TldrawUiTooltip({\n\tchildren,\n\tcontent,\n\tside = 'bottom',\n\tsideOffset = 5,\n\tdisabled = false,\n}: TldrawUiTooltipProps) {\n\tconst editor = useMaybeEditor()\n\tconst tooltipId = useRef<string>(uniqueId())\n\tconst hasProvider = useContext(TooltipSingletonContext)\n\n\t// Don't show tooltip if disabled, no content, or UI labels are disabled\n\tif (disabled || !content) {\n\t\treturn <>{children}</>\n\t}\n\n\t// Fallback to old behavior if no provider\n\tif (!hasProvider) {\n\t\treturn (\n\t\t\t<_Tooltip.Root\n\t\t\t\tdelayDuration={editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS}\n\t\t\t\tdisableHoverableContent\n\t\t\t>\n\t\t\t\t<_Tooltip.Trigger asChild>{children}</_Tooltip.Trigger>\n\t\t\t\t<_Tooltip.Content\n\t\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\t\tside={side}\n\t\t\t\t\tsideOffset={sideOffset}\n\t\t\t\t\tavoidCollisions\n\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t>\n\t\t\t\t\t{content}\n\t\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t\t</_Tooltip.Content>\n\t\t\t</_Tooltip.Root>\n\t\t)\n\t}\n\n\tconst child = React.Children.only(children)\n\tassert(React.isValidElement(child), 'TldrawUiTooltip children must be a single element')\n\n\tconst handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {\n\t\tchild.props.onMouseEnter?.(event)\n\t\ttooltipManager.showTooltip(\n\t\t\ttooltipId.current,\n\t\t\tcontent,\n\t\t\tevent.currentTarget as HTMLElement,\n\t\t\tside,\n\t\t\tsideOffset\n\t\t)\n\t}\n\n\tconst handleMouseLeave = (event: React.MouseEvent<HTMLElement>) => {\n\t\tchild.props.onMouseLeave?.(event)\n\t\ttooltipManager.hideTooltip(tooltipId.current)\n\t}\n\n\tconst handleFocus = (event: React.FocusEvent<HTMLElement>) => {\n\t\tchild.props.onFocus?.(event)\n\t\ttooltipManager.showTooltip(\n\t\t\ttooltipId.current,\n\t\t\tcontent,\n\t\t\tevent.currentTarget as HTMLElement,\n\t\t\tside,\n\t\t\tsideOffset\n\t\t)\n\t}\n\n\tconst handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n\t\tchild.props.onBlur?.(event)\n\t\ttooltipManager.hideTooltip(tooltipId.current)\n\t}\n\n\tconst childrenWithHandlers = React.cloneElement(children as React.ReactElement, {\n\t\tonMouseEnter: handleMouseEnter,\n\t\tonMouseLeave: handleMouseLeave,\n\t\tonFocus: handleFocus,\n\t\tonBlur: handleBlur,\n\t})\n\n\treturn childrenWithHandlers\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { assert, Atom, atom, Editor, uniqueId, useMaybeEditor, useValue } from '@tldraw/editor'\nimport { Tooltip as _Tooltip } from 'radix-ui'\nimport React, {\n\tcreateContext,\n\tforwardRef,\n\tReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseRef,\n\tuseState,\n} from 'react'\nimport { useTldrawUiOrientation } from './layout'\n\nconst DEFAULT_TOOLTIP_DELAY_MS = 700\n\n/** @public */\nexport interface TldrawUiTooltipProps {\n\tchildren: React.ReactNode\n\tcontent?: string | React.ReactNode\n\tside?: 'top' | 'right' | 'bottom' | 'left'\n\tsideOffset?: number\n\tdisabled?: boolean\n\tshowOnMobile?: boolean\n\tdelayDuration?: number\n}\n\n// Singleton tooltip manager\nclass TooltipManager {\n\tprivate static instance: TooltipManager | null = null\n\tprivate currentTooltip = atom<{\n\t\tid: string\n\t\tcontent: ReactNode\n\t\tside: 'top' | 'right' | 'bottom' | 'left'\n\t\tsideOffset: number\n\t\tshowOnMobile: boolean\n\t\ttargetElement: HTMLElement\n\t\tdelayDuration: number\n\t} | null>('current tooltip', null)\n\tprivate destroyTimeoutId: number | null = null\n\n\tstatic getInstance(): TooltipManager {\n\t\tif (!TooltipManager.instance) {\n\t\t\tTooltipManager.instance = new TooltipManager()\n\t\t}\n\t\treturn TooltipManager.instance\n\t}\n\n\tshowTooltip(\n\t\ttooltipId: string,\n\t\tcontent: string | React.ReactNode,\n\t\ttargetElement: HTMLElement,\n\t\tside: 'top' | 'right' | 'bottom' | 'left',\n\t\tsideOffset: number,\n\t\tshowOnMobile: boolean,\n\t\tdelayDuration: number\n\t) {\n\t\t// Clear any existing destroy timeout\n\t\tif (this.destroyTimeoutId) {\n\t\t\tclearTimeout(this.destroyTimeoutId)\n\t\t\tthis.destroyTimeoutId = null\n\t\t}\n\n\t\t// Update current tooltip\n\t\tthis.currentTooltip.set({\n\t\t\tid: tooltipId,\n\t\t\tcontent,\n\t\t\tside,\n\t\t\tsideOffset,\n\t\t\tshowOnMobile,\n\t\t\ttargetElement,\n\t\t\tdelayDuration,\n\t\t})\n\t}\n\n\thideTooltip(editor: Editor | null, tooltipId: string, instant: boolean = false) {\n\t\tconst hide = () => {\n\t\t\t// Only hide if this is the current tooltip\n\t\t\tif (this.currentTooltip.get()?.id === tooltipId) {\n\t\t\t\tthis.currentTooltip.set(null)\n\t\t\t\tthis.destroyTimeoutId = null\n\t\t\t}\n\t\t}\n\n\t\tif (editor && !instant) {\n\t\t\t// Start destroy timeout (1 second)\n\t\t\tthis.destroyTimeoutId = editor.timers.setTimeout(hide, 300)\n\t\t} else {\n\t\t\thide()\n\t\t}\n\t}\n\n\thideAllTooltips() {\n\t\tthis.currentTooltip.set(null)\n\t\tthis.destroyTimeoutId = null\n\t}\n\n\tgetCurrentTooltipData() {\n\t\tconst currentTooltip = this.currentTooltip.get()\n\t\tif (!currentTooltip) return null\n\t\tif (!this.supportsHover() && !currentTooltip.showOnMobile) return null\n\t\treturn currentTooltip\n\t}\n\n\tprivate supportsHoverAtom: Atom<boolean> | null = null\n\tsupportsHover() {\n\t\tif (!this.supportsHoverAtom) {\n\t\t\tconst mediaQuery = window.matchMedia('(hover: hover)')\n\t\t\tconst supportsHover = atom('has hover', mediaQuery.matches)\n\t\t\tthis.supportsHoverAtom = supportsHover\n\t\t\tmediaQuery.addEventListener('change', (e) => {\n\t\t\t\tsupportsHover.set(e.matches)\n\t\t\t})\n\t\t}\n\t\treturn this.supportsHoverAtom.get()\n\t}\n}\n\nexport const tooltipManager = TooltipManager.getInstance()\n\n// Context for the tooltip singleton\nconst TooltipSingletonContext = createContext<boolean>(false)\n\n/** @public */\nexport interface TldrawUiTooltipProviderProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderProps) {\n\treturn (\n\t\t<_Tooltip.Provider skipDelayDuration={700}>\n\t\t\t<TooltipSingletonContext.Provider value={true}>\n\t\t\t\t{children}\n\t\t\t\t<TooltipSingleton />\n\t\t\t</TooltipSingletonContext.Provider>\n\t\t</_Tooltip.Provider>\n\t)\n}\n\n// The singleton tooltip component that renders once\nfunction TooltipSingleton() {\n\tconst [isOpen, setIsOpen] = useState(false)\n\tconst triggerRef = useRef<HTMLDivElement>(null)\n\tconst isFirstShowRef = useRef(true)\n\n\tconst currentTooltip = useValue(\n\t\t'current tooltip',\n\t\t() => tooltipManager.getCurrentTooltipData(),\n\t\t[]\n\t)\n\n\t// Update open state and trigger position\n\tuseEffect(() => {\n\t\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t\tif (currentTooltip && triggerRef.current) {\n\t\t\t// Position the invisible trigger element over the active element\n\t\t\tconst activeRect = currentTooltip.targetElement.getBoundingClientRect()\n\t\t\tconst trigger = triggerRef.current\n\n\t\t\ttrigger.style.position = 'fixed'\n\t\t\ttrigger.style.left = `${activeRect.left}px`\n\t\t\ttrigger.style.top = `${activeRect.top}px`\n\t\t\ttrigger.style.width = `${activeRect.width}px`\n\t\t\ttrigger.style.height = `${activeRect.height}px`\n\t\t\ttrigger.style.pointerEvents = 'none'\n\t\t\ttrigger.style.zIndex = '9999'\n\n\t\t\t// Handle delay for first show\n\t\t\tif (isFirstShowRef.current) {\n\t\t\t\t// eslint-disable-next-line no-restricted-globals\n\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\tsetIsOpen(true)\n\t\t\t\t\tisFirstShowRef.current = false\n\t\t\t\t}, currentTooltip.delayDuration)\n\t\t\t} else {\n\t\t\t\t// Subsequent tooltips show immediately\n\t\t\t\tsetIsOpen(true)\n\t\t\t}\n\t\t} else {\n\t\t\t// Hide tooltip immediately\n\t\t\tsetIsOpen(false)\n\t\t\t// Reset first show state after tooltip is hidden\n\t\t\tisFirstShowRef.current = true\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (timer !== null) {\n\t\t\t\tclearTimeout(timer)\n\t\t\t}\n\t\t}\n\t}, [currentTooltip])\n\n\tif (!currentTooltip) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<_Tooltip.Root open={isOpen} delayDuration={0}>\n\t\t\t<_Tooltip.Trigger asChild>\n\t\t\t\t<div ref={triggerRef} />\n\t\t\t</_Tooltip.Trigger>\n\t\t\t<_Tooltip.Content\n\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\tside={currentTooltip.side}\n\t\t\t\tsideOffset={currentTooltip.sideOffset}\n\t\t\t\tavoidCollisions\n\t\t\t\tcollisionPadding={8}\n\t\t\t\tdir=\"ltr\"\n\t\t\t>\n\t\t\t\t{currentTooltip.content}\n\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t</_Tooltip.Content>\n\t\t</_Tooltip.Root>\n\t)\n}\n\n/** @public @react */\nexport const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProps>(\n\t(\n\t\t{\n\t\t\tchildren,\n\t\t\tcontent,\n\t\t\tside,\n\t\t\tsideOffset = 5,\n\t\t\tdisabled = false,\n\t\t\tshowOnMobile = false,\n\t\t\tdelayDuration,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst editor = useMaybeEditor()\n\t\tconst tooltipId = useRef<string>(uniqueId())\n\t\tconst hasProvider = useContext(TooltipSingletonContext)\n\n\t\tconst orientationCtx = useTldrawUiOrientation()\n\t\tconst sideToUse = side ?? orientationCtx.tooltipSide\n\n\t\tuseEffect(() => {\n\t\t\tconst currentTooltipId = tooltipId.current\n\t\t\treturn () => {\n\t\t\t\tif (hasProvider) {\n\t\t\t\t\ttooltipManager.hideTooltip(editor, currentTooltipId, true)\n\t\t\t\t}\n\t\t\t}\n\t\t}, [editor, hasProvider])\n\n\t\t// Don't show tooltip if disabled, no content, or UI labels are disabled\n\t\tif (disabled || !content) {\n\t\t\treturn <>{children}</>\n\t\t}\n\n\t\tconst delayDurationToUse =\n\t\t\tdelayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS)\n\n\t\t// Fallback to old behavior if no provider\n\t\tif (!hasProvider) {\n\t\t\treturn (\n\t\t\t\t<_Tooltip.Root delayDuration={delayDurationToUse} disableHoverableContent>\n\t\t\t\t\t<_Tooltip.Trigger asChild ref={ref}>\n\t\t\t\t\t\t{children}\n\t\t\t\t\t</_Tooltip.Trigger>\n\t\t\t\t\t<_Tooltip.Content\n\t\t\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\t\t\tside={sideToUse}\n\t\t\t\t\t\tsideOffset={sideOffset}\n\t\t\t\t\t\tavoidCollisions\n\t\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{content}\n\t\t\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t\t\t</_Tooltip.Content>\n\t\t\t\t</_Tooltip.Root>\n\t\t\t)\n\t\t}\n\n\t\tconst child = React.Children.only(children)\n\t\tassert(React.isValidElement(child), 'TldrawUiTooltip children must be a single element')\n\n\t\tconst handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {\n\t\t\tchild.props.onMouseEnter?.(event)\n\t\t\ttooltipManager.showTooltip(\n\t\t\t\ttooltipId.current,\n\t\t\t\tcontent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\tsideToUse,\n\t\t\t\tsideOffset,\n\t\t\t\tshowOnMobile,\n\t\t\t\tdelayDurationToUse\n\t\t\t)\n\t\t}\n\n\t\tconst handleMouseLeave = (event: React.MouseEvent<HTMLElement>) => {\n\t\t\tchild.props.onMouseLeave?.(event)\n\t\t\ttooltipManager.hideTooltip(editor, tooltipId.current)\n\t\t}\n\n\t\tconst handleFocus = (event: React.FocusEvent<HTMLElement>) => {\n\t\t\tchild.props.onFocus?.(event)\n\t\t\ttooltipManager.showTooltip(\n\t\t\t\ttooltipId.current,\n\t\t\t\tcontent,\n\t\t\t\tevent.currentTarget as HTMLElement,\n\t\t\t\tsideToUse,\n\t\t\t\tsideOffset,\n\t\t\t\tshowOnMobile,\n\t\t\t\tdelayDurationToUse\n\t\t\t)\n\t\t}\n\n\t\tconst handleBlur = (event: React.FocusEvent<HTMLElement>) => {\n\t\t\tchild.props.onBlur?.(event)\n\t\t\ttooltipManager.hideTooltip(editor, tooltipId.current)\n\t\t}\n\n\t\tconst childrenWithHandlers = React.cloneElement(children as React.ReactElement, {\n\t\t\tonMouseEnter: handleMouseEnter,\n\t\t\tonMouseLeave: handleMouseLeave,\n\t\t\tonFocus: handleFocus,\n\t\t\tonBlur: handleBlur,\n\t\t})\n\n\t\treturn childrenWithHandlers\n\t}\n)\n"],
5
+ "mappings": "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",
6
6
  "names": ["_Tooltip", "React"]
7
7
  }
@@ -28,24 +28,49 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var layout_exports = {};
30
30
  __export(layout_exports, {
31
+ TldrawUiColumn: () => TldrawUiColumn,
31
32
  TldrawUiGrid: () => TldrawUiGrid,
32
- TldrawUiRow: () => TldrawUiRow
33
+ TldrawUiOrientationProvider: () => TldrawUiOrientationProvider,
34
+ TldrawUiRow: () => TldrawUiRow,
35
+ useTldrawUiOrientation: () => useTldrawUiOrientation
33
36
  });
34
37
  module.exports = __toCommonJS(layout_exports);
35
38
  var import_jsx_runtime = require("react/jsx-runtime");
36
39
  var import_classnames = __toESM(require("classnames"));
37
40
  var import_radix_ui = require("radix-ui");
38
41
  var import_react = require("react");
42
+ const TldrawUiOrientationContext = (0, import_react.createContext)({
43
+ orientation: "horizontal",
44
+ tooltipSide: "bottom"
45
+ });
46
+ function TldrawUiOrientationProvider({
47
+ children,
48
+ orientation,
49
+ tooltipSide
50
+ }) {
51
+ const prevContext = useTldrawUiOrientation();
52
+ const tooltipSideToUse = tooltipSide ?? (orientation === prevContext.orientation ? prevContext.tooltipSide : orientation === "horizontal" ? "bottom" : "right");
53
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TldrawUiOrientationContext.Provider, { value: { orientation, tooltipSide: tooltipSideToUse }, children });
54
+ }
55
+ function useTldrawUiOrientation() {
56
+ return (0, import_react.useContext)(TldrawUiOrientationContext);
57
+ }
39
58
  const TldrawUiRow = (0, import_react.forwardRef)(
40
- ({ asChild, className, ...props }, ref) => {
59
+ ({ asChild, className, tooltipSide, ...props }, ref) => {
60
+ const Component = asChild ? import_radix_ui.Slot.Root : "div";
61
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TldrawUiOrientationProvider, { orientation: "horizontal", tooltipSide, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ref, className: (0, import_classnames.default)("tlui-row", className), ...props }) });
62
+ }
63
+ );
64
+ const TldrawUiColumn = (0, import_react.forwardRef)(
65
+ ({ asChild, className, tooltipSide, ...props }, ref) => {
41
66
  const Component = asChild ? import_radix_ui.Slot.Root : "div";
42
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ref, className: (0, import_classnames.default)("tlui-row", className), ...props });
67
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TldrawUiOrientationProvider, { orientation: "vertical", tooltipSide, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ref, className: (0, import_classnames.default)("tlui-column", className), ...props }) });
43
68
  }
44
69
  );
45
70
  const TldrawUiGrid = (0, import_react.forwardRef)(
46
- ({ asChild, className, ...props }, ref) => {
71
+ ({ asChild, className, tooltipSide, ...props }, ref) => {
47
72
  const Component = asChild ? import_radix_ui.Slot.Root : "div";
48
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ref, className: (0, import_classnames.default)("tlui-grid", className), ...props });
73
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TldrawUiOrientationProvider, { orientation: "horizontal", tooltipSide, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { ref, className: (0, import_classnames.default)("tlui-grid", className), ...props }) });
49
74
  }
50
75
  );
51
76
  //# sourceMappingURL=layout.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/lib/ui/components/primitives/layout.tsx"],
4
- "sourcesContent": ["import classNames from 'classnames'\nimport { Slot } from 'radix-ui'\nimport { HTMLAttributes, ReactNode, forwardRef } from 'react'\n\n/** @public */\nexport interface TLUiLayoutProps extends HTMLAttributes<HTMLDivElement> {\n\tchildren: ReactNode\n\tasChild?: boolean\n}\n\n/**\n * A row, usually of UI controls like buttons, select dropdown, checkboxes, etc.\n *\n * @public @react\n */\nexport const TldrawUiRow = forwardRef<HTMLDivElement, TLUiLayoutProps>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Component = asChild ? Slot.Root : 'div'\n\t\treturn <Component ref={ref} className={classNames('tlui-row', className)} {...props} />\n\t}\n)\n\n/**\n * A tight grid 4 elements wide, usually of UI controls like buttons, select dropdown, checkboxes,\n * etc.\n *\n * @public @react */\nexport const TldrawUiGrid = forwardRef<HTMLDivElement, TLUiLayoutProps>(\n\t({ asChild, className, ...props }, ref) => {\n\t\tconst Component = asChild ? Slot.Root : 'div'\n\t\treturn <Component ref={ref} className={classNames('tlui-grid', className)} {...props} />\n\t}\n)\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBS;AAlBT,wBAAuB;AACvB,sBAAqB;AACrB,mBAAsD;AAa/C,MAAM,kBAAc;AAAA,EAC1B,CAAC,EAAE,SAAS,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC1C,UAAM,YAAY,UAAU,qBAAK,OAAO;AACxC,WAAO,4CAAC,aAAU,KAAU,eAAW,kBAAAA,SAAW,YAAY,SAAS,GAAI,GAAG,OAAO;AAAA,EACtF;AACD;AAOO,MAAM,mBAAe;AAAA,EAC3B,CAAC,EAAE,SAAS,WAAW,GAAG,MAAM,GAAG,QAAQ;AAC1C,UAAM,YAAY,UAAU,qBAAK,OAAO;AACxC,WAAO,4CAAC,aAAU,KAAU,eAAW,kBAAAA,SAAW,aAAa,SAAS,GAAI,GAAG,OAAO;AAAA,EACvF;AACD;",
4
+ "sourcesContent": ["import classNames from 'classnames'\nimport { Slot } from 'radix-ui'\nimport { HTMLAttributes, ReactNode, createContext, forwardRef, useContext } from 'react'\n\n/** @public */\nexport interface TldrawUiOrientationContext {\n\torientation: 'horizontal' | 'vertical'\n\ttooltipSide: 'top' | 'right' | 'bottom' | 'left'\n}\n\nconst TldrawUiOrientationContext = createContext<TldrawUiOrientationContext>({\n\torientation: 'horizontal',\n\ttooltipSide: 'bottom',\n})\n\n/** @public */\nexport interface TldrawUiOrientationProviderProps {\n\tchildren: ReactNode\n\torientation: 'horizontal' | 'vertical'\n\ttooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n}\n/** @public @react */\nexport function TldrawUiOrientationProvider({\n\tchildren,\n\torientation,\n\ttooltipSide,\n}: TldrawUiOrientationProviderProps) {\n\tconst prevContext = useTldrawUiOrientation()\n\t// generally, we want tooltip side to cascade down through the layout - apart from when the\n\t// orientation changes. If the tooltip side is \"bottom\", and then I include some vertical layout\n\t// elements, keeping the tooltip side as bottom will cause the tooltip to overlap elements\n\t// stacked on top of each other. In the absence of a tooltip side, we pick a default side based\n\t// on the orientation whenever the orientation changes.\n\tconst tooltipSideToUse =\n\t\ttooltipSide ??\n\t\t(orientation === prevContext.orientation\n\t\t\t? prevContext.tooltipSide\n\t\t\t: orientation === 'horizontal'\n\t\t\t\t? 'bottom'\n\t\t\t\t: 'right')\n\n\treturn (\n\t\t<TldrawUiOrientationContext.Provider value={{ orientation, tooltipSide: tooltipSideToUse }}>\n\t\t\t{children}\n\t\t</TldrawUiOrientationContext.Provider>\n\t)\n}\n\n/** @public */\nexport function useTldrawUiOrientation() {\n\treturn useContext(TldrawUiOrientationContext)\n}\n\n/** @public */\nexport interface TLUiLayoutProps extends HTMLAttributes<HTMLDivElement> {\n\tchildren: ReactNode\n\ttooltipSide?: 'top' | 'right' | 'bottom' | 'left'\n\tasChild?: boolean\n}\n\n/**\n * A row, usually of UI controls like buttons, select dropdown, checkboxes, etc.\n *\n * @public @react\n */\nexport const TldrawUiRow = forwardRef<HTMLDivElement, TLUiLayoutProps>(\n\t({ asChild, className, tooltipSide, ...props }, ref) => {\n\t\tconst Component = asChild ? Slot.Root : 'div'\n\t\treturn (\n\t\t\t<TldrawUiOrientationProvider orientation=\"horizontal\" tooltipSide={tooltipSide}>\n\t\t\t\t<Component ref={ref} className={classNames('tlui-row', className)} {...props} />\n\t\t\t</TldrawUiOrientationProvider>\n\t\t)\n\t}\n)\n\n/**\n * A column, usually of UI controls like buttons, select dropdown, checkboxes, etc.\n *\n * @public @react\n */\nexport const TldrawUiColumn = forwardRef<HTMLDivElement, TLUiLayoutProps>(\n\t({ asChild, className, tooltipSide, ...props }, ref) => {\n\t\tconst Component = asChild ? Slot.Root : 'div'\n\t\treturn (\n\t\t\t<TldrawUiOrientationProvider orientation=\"vertical\" tooltipSide={tooltipSide}>\n\t\t\t\t<Component ref={ref} className={classNames('tlui-column', className)} {...props} />\n\t\t\t</TldrawUiOrientationProvider>\n\t\t)\n\t}\n)\n\n/**\n * A tight grid 4 elements wide, usually of UI controls like buttons, select dropdown, checkboxes,\n * etc.\n *\n * @public @react */\nexport const TldrawUiGrid = forwardRef<HTMLDivElement, TLUiLayoutProps>(\n\t({ asChild, className, tooltipSide, ...props }, ref) => {\n\t\tconst Component = asChild ? Slot.Root : 'div'\n\t\treturn (\n\t\t\t<TldrawUiOrientationProvider orientation=\"horizontal\" tooltipSide={tooltipSide}>\n\t\t\t\t<Component ref={ref} className={classNames('tlui-grid', className)} {...props} />\n\t\t\t</TldrawUiOrientationProvider>\n\t\t)\n\t}\n)\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CE;AA1CF,wBAAuB;AACvB,sBAAqB;AACrB,mBAAiF;AAQjF,MAAM,iCAA6B,4BAA0C;AAAA,EAC5E,aAAa;AAAA,EACb,aAAa;AACd,CAAC;AASM,SAAS,4BAA4B;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACD,GAAqC;AACpC,QAAM,cAAc,uBAAuB;AAM3C,QAAM,mBACL,gBACC,gBAAgB,YAAY,cAC1B,YAAY,cACZ,gBAAgB,eACf,WACA;AAEL,SACC,4CAAC,2BAA2B,UAA3B,EAAoC,OAAO,EAAE,aAAa,aAAa,iBAAiB,GACvF,UACF;AAEF;AAGO,SAAS,yBAAyB;AACxC,aAAO,yBAAW,0BAA0B;AAC7C;AAcO,MAAM,kBAAc;AAAA,EAC1B,CAAC,EAAE,SAAS,WAAW,aAAa,GAAG,MAAM,GAAG,QAAQ;AACvD,UAAM,YAAY,UAAU,qBAAK,OAAO;AACxC,WACC,4CAAC,+BAA4B,aAAY,cAAa,aACrD,sDAAC,aAAU,KAAU,eAAW,kBAAAA,SAAW,YAAY,SAAS,GAAI,GAAG,OAAO,GAC/E;AAAA,EAEF;AACD;AAOO,MAAM,qBAAiB;AAAA,EAC7B,CAAC,EAAE,SAAS,WAAW,aAAa,GAAG,MAAM,GAAG,QAAQ;AACvD,UAAM,YAAY,UAAU,qBAAK,OAAO;AACxC,WACC,4CAAC,+BAA4B,aAAY,YAAW,aACnD,sDAAC,aAAU,KAAU,eAAW,kBAAAA,SAAW,eAAe,SAAS,GAAI,GAAG,OAAO,GAClF;AAAA,EAEF;AACD;AAOO,MAAM,mBAAe;AAAA,EAC3B,CAAC,EAAE,SAAS,WAAW,aAAa,GAAG,MAAM,GAAG,QAAQ;AACvD,UAAM,YAAY,UAAU,qBAAK,OAAO;AACxC,WACC,4CAAC,+BAA4B,aAAY,cAAa,aACrD,sDAAC,aAAU,KAAU,eAAW,kBAAAA,SAAW,aAAa,SAAS,GAAI,GAAG,OAAO,GAChF;AAAA,EAEF;AACD;",
6
6
  "names": ["classNames"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx"],
4
- "sourcesContent": ["import { createContext, useContext } from 'react'\nimport { TLUiEventSource } from '../../../context/events'\n\n/** @public */\nexport type TLUiMenuContextType =\n\t| 'panel'\n\t| 'menu'\n\t| 'small-icons'\n\t| 'context-menu'\n\t| 'icons'\n\t| 'keyboard-shortcuts'\n\t| 'helper-buttons'\n\t| 'toolbar'\n\t| 'toolbar-overflow'\n\nconst menuContext = createContext<{\n\ttype: TLUiMenuContextType\n\tsourceId: TLUiEventSource\n} | null>(null)\n\n/** @public */\nexport function useTldrawUiMenuContext() {\n\tconst context = useContext(menuContext)\n\tif (!context) {\n\t\tthrow new Error('useTldrawUiMenuContext must be used within a TldrawUiMenuContextProvider')\n\t}\n\treturn context\n}\n\n/** @public */\nexport interface TLUiMenuContextProviderProps {\n\ttype: TLUiMenuContextType\n\tsourceId: TLUiEventSource\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiMenuContextProvider({\n\ttype,\n\tsourceId,\n\tchildren,\n}: TLUiMenuContextProviderProps) {\n\treturn <menuContext.Provider value={{ type, sourceId }}>{children}</menuContext.Provider>\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CQ;AA1CR,mBAA0C;AAe1C,MAAM,kBAAc,4BAGV,IAAI;AAGP,SAAS,yBAAyB;AACxC,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACb,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC3F;AACA,SAAO;AACR;AAUO,SAAS,4BAA4B;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACD,GAAiC;AAChC,SAAO,4CAAC,YAAY,UAAZ,EAAqB,OAAO,EAAE,MAAM,SAAS,GAAI,UAAS;AACnE;",
4
+ "sourcesContent": ["import { createContext, useContext } from 'react'\nimport { TLUiEventSource } from '../../../context/events'\n\n/** @public */\nexport type TLUiMenuContextType =\n\t| 'menu'\n\t| 'small-icons'\n\t| 'context-menu'\n\t| 'icons'\n\t| 'keyboard-shortcuts'\n\t| 'helper-buttons'\n\t| 'toolbar'\n\t| 'toolbar-overflow'\n\nconst menuContext = createContext<{\n\ttype: TLUiMenuContextType\n\tsourceId: TLUiEventSource\n} | null>(null)\n\n/** @public */\nexport function useTldrawUiMenuContext() {\n\tconst context = useContext(menuContext)\n\tif (!context) {\n\t\tthrow new Error('useTldrawUiMenuContext must be used within a TldrawUiMenuContextProvider')\n\t}\n\treturn context\n}\n\n/** @public */\nexport interface TLUiMenuContextProviderProps {\n\ttype: TLUiMenuContextType\n\tsourceId: TLUiEventSource\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiMenuContextProvider({\n\ttype,\n\tsourceId,\n\tchildren,\n}: TLUiMenuContextProviderProps) {\n\treturn <menuContext.Provider value={{ type, sourceId }}>{children}</menuContext.Provider>\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCQ;AAzCR,mBAA0C;AAc1C,MAAM,kBAAc,4BAGV,IAAI;AAGP,SAAS,yBAAyB;AACxC,QAAM,cAAU,yBAAW,WAAW;AACtC,MAAI,CAAC,SAAS;AACb,UAAM,IAAI,MAAM,0EAA0E;AAAA,EAC3F;AACA,SAAO;AACR;AAUO,SAAS,4BAA4B;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AACD,GAAiC;AAChC,SAAO,4CAAC,YAAY,UAAZ,EAAqB,OAAO,EAAE,MAAM,SAAS,GAAI,UAAS;AACnE;",
6
6
  "names": []
7
7
  }
@@ -35,44 +35,57 @@ var import_jsx_runtime = require("react/jsx-runtime");
35
35
  var import_classnames = __toESM(require("classnames"));
36
36
  var import_actions = require("../../../context/actions");
37
37
  var import_useTranslation = require("../../../hooks/useTranslation/useTranslation");
38
+ var import_layout = require("../layout");
38
39
  var import_TldrawUiDropdownMenu = require("../TldrawUiDropdownMenu");
39
40
  var import_TldrawUiMenuContext = require("./TldrawUiMenuContext");
40
41
  function TldrawUiMenuGroup({ id, label, className, children }) {
41
- const { type: menuType, sourceId } = (0, import_TldrawUiMenuContext.useTldrawUiMenuContext)();
42
+ const menu = (0, import_TldrawUiMenuContext.useTldrawUiMenuContext)();
43
+ const { orientation } = (0, import_layout.useTldrawUiOrientation)();
42
44
  const msg = (0, import_useTranslation.useTranslation)();
43
- const labelToUse = (0, import_actions.unwrapLabel)(label, menuType);
45
+ const labelToUse = (0, import_actions.unwrapLabel)(label, menu.type);
44
46
  const labelStr = labelToUse ? msg(labelToUse) : void 0;
45
- switch (menuType) {
46
- case "panel": {
47
+ switch (menu.type) {
48
+ case "menu": {
47
49
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
48
- "div",
50
+ import_TldrawUiDropdownMenu.TldrawUiDropdownMenuGroup,
49
51
  {
50
- className: (0, import_classnames.default)("tlui-menu__group", className),
51
- "data-testid": `${sourceId}-group.${id}`,
52
+ className,
53
+ "data-testid": `${menu.sourceId}-group.${id}`,
52
54
  children
53
55
  }
54
56
  );
55
57
  }
56
- case "menu": {
57
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_TldrawUiDropdownMenu.TldrawUiDropdownMenuGroup, { className, "data-testid": `${sourceId}-group.${id}`, children });
58
- }
59
58
  case "context-menu": {
60
59
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
61
60
  "div",
62
61
  {
63
62
  dir: "ltr",
64
63
  className: (0, import_classnames.default)("tlui-menu__group", className),
65
- "data-testid": `${sourceId}-group.${id}`,
64
+ "data-testid": `${menu.sourceId}-group.${id}`,
66
65
  children
67
66
  }
68
67
  );
69
68
  }
70
69
  case "keyboard-shortcuts": {
71
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tlui-shortcuts-dialog__group", "data-testid": `${sourceId}-group.${id}`, children: [
70
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "tlui-shortcuts-dialog__group", "data-testid": `${menu.sourceId}-group.${id}`, children: [
72
71
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "tlui-shortcuts-dialog__group__title", children: labelStr }),
73
72
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tlui-shortcuts-dialog__group__content", children })
74
73
  ] });
75
74
  }
75
+ case "toolbar": {
76
+ const Layout = orientation === "horizontal" ? import_layout.TldrawUiRow : import_layout.TldrawUiColumn;
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Layout, { className: "tlui-main-toolbar__group", "data-testid": `${menu.sourceId}-group.${id}`, children });
78
+ }
79
+ case "toolbar-overflow": {
80
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
81
+ import_layout.TldrawUiGrid,
82
+ {
83
+ className: "tlui-main-toolbar__group",
84
+ "data-testid": `${menu.sourceId}-group.${id}`,
85
+ children
86
+ }
87
+ );
88
+ }
76
89
  default: {
77
90
  return children;
78
91
  }