tldraw 3.16.0-canary.fa3749606e52 → 3.16.0-next.282b7be564ae

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 (275) hide show
  1. package/dist-cjs/index.d.ts +100 -5
  2. package/dist-cjs/index.js +13 -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/arrowTargetState.js +1 -1
  9. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  11. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  12. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  13. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  15. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  16. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +12 -12
  17. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  19. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  20. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  21. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  22. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  23. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  24. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  25. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  26. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
  27. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
  28. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  29. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  31. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  33. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  34. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
  35. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
  36. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  37. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  38. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  39. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  40. package/dist-cjs/lib/ui/TldrawUi.js +14 -0
  41. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  42. package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
  43. package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
  44. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  45. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  46. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  47. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  48. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +3 -3
  49. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  50. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  51. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  52. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  53. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  54. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
  55. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  56. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
  57. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  58. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  59. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  60. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  61. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  62. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
  63. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  64. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -140
  65. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  66. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
  67. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
  68. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
  69. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
  70. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  71. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  73. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  74. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  75. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  76. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
  77. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  78. package/dist-cjs/lib/ui/components/menu-items.js +6 -0
  79. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  80. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
  81. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
  82. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  83. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  84. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  85. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  86. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +30 -7
  87. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  88. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +268 -0
  89. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
  90. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  91. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  92. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  93. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  94. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  95. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +11 -26
  96. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  97. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
  98. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
  99. package/dist-cjs/lib/ui/context/actions.js +15 -0
  100. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  101. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  102. package/dist-cjs/lib/ui/hooks/useTools.js +21 -3
  103. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  104. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  105. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +3 -0
  106. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  107. package/dist-cjs/lib/ui/version.js +3 -3
  108. package/dist-cjs/lib/ui/version.js.map +1 -1
  109. package/dist-esm/index.d.mts +100 -5
  110. package/dist-esm/index.mjs +23 -1
  111. package/dist-esm/index.mjs.map +2 -2
  112. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  113. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  114. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
  115. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  116. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  117. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  118. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  119. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  120. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  121. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  122. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  123. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  124. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +13 -12
  125. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  126. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  127. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  128. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  129. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  130. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  131. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  132. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  133. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  134. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
  135. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
  136. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  137. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  138. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  139. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  140. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  141. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  142. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
  143. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
  144. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  145. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  146. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  147. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  148. package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
  149. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  150. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
  151. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
  152. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  153. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  154. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
  155. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
  156. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +3 -5
  157. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
  158. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  159. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  160. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  161. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  162. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
  163. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  164. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
  165. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  166. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
  167. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
  168. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
  169. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
  170. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +3 -1
  171. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  172. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +171 -140
  173. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  174. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
  175. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
  176. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
  177. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  178. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  179. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  180. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
  181. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  182. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
  183. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  184. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +5 -4
  185. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  186. package/dist-esm/lib/ui/components/menu-items.mjs +6 -0
  187. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  188. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +6 -6
  189. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  190. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
  191. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  192. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
  193. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  194. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +30 -7
  195. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  196. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +245 -0
  197. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +7 -0
  198. package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
  199. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
  200. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  201. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  202. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  203. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +11 -26
  204. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  205. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +3 -2
  206. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
  207. package/dist-esm/lib/ui/context/actions.mjs +15 -0
  208. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  209. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  210. package/dist-esm/lib/ui/hooks/useTools.mjs +22 -3
  211. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  212. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +3 -0
  213. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  214. package/dist-esm/lib/ui/version.mjs +3 -3
  215. package/dist-esm/lib/ui/version.mjs.map +1 -1
  216. package/package.json +3 -3
  217. package/src/index.ts +18 -0
  218. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  219. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
  220. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -1
  221. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  222. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  223. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  224. package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -14
  225. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  226. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  227. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  228. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  229. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
  230. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  231. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  232. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  233. package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
  234. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  235. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  236. package/src/lib/ui/TldrawUi.tsx +17 -2
  237. package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
  238. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  239. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  240. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -4
  241. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  242. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  243. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
  244. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
  245. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  246. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  247. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
  248. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -107
  249. package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
  250. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
  251. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  252. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  253. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  254. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +14 -11
  255. package/src/lib/ui/components/menu-items.tsx +8 -0
  256. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
  257. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
  258. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  259. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +51 -12
  260. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +327 -0
  261. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  262. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  263. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  264. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +15 -25
  265. package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
  266. package/src/lib/ui/context/actions.tsx +15 -0
  267. package/src/lib/ui/context/events.tsx +1 -0
  268. package/src/lib/ui/hooks/useTools.tsx +25 -3
  269. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +3 -0
  270. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +3 -0
  271. package/src/lib/ui/version.ts +3 -3
  272. package/src/lib/ui.css +406 -292
  273. package/src/test/arrows-megabus.test.tsx +12 -6
  274. package/src/test/inner-outer-margin.test.ts +315 -0
  275. package/tldraw.css +699 -580
@@ -288,11 +288,13 @@ describe('When shapes are overlapping', () => {
288
288
  editor.pointerDown(0, 50) // over nothing
289
289
  editor.pointerMove(125, 50) // over box1 only
290
290
  expect(bindings().end).toMatchObject({ toId: ids.box1 })
291
- editor.pointerMove(175, 50) // box2 is higher but box1 is filled?
291
+ editor.pointerMove(175, 50) // box2 is higher but box1 is filled, but we're on the edge ofd box 2
292
+ expect(bindings().end).toMatchObject({ toId: ids.box2 })
293
+ editor.pointerMove(175, 70) // box2 is higher but box1 is filled, and we're inside of box2
292
294
  expect(bindings().end).toMatchObject({ toId: ids.box1 })
293
- editor.pointerMove(225, 50) // box3 is higher
295
+ editor.pointerMove(225, 70) // box3 is higher
294
296
  expect(bindings().end).toMatchObject({ toId: ids.box3 })
295
- editor.pointerMove(275, 50) // box4 is higher but box 3 is filled
297
+ editor.pointerMove(275, 70) // box4 is higher but box 3 is filled
296
298
  expect(bindings().end).toMatchObject({ toId: ids.box3 })
297
299
  })
298
300
 
@@ -304,14 +306,18 @@ describe('When shapes are overlapping', () => {
304
306
  ])
305
307
  editor.setCurrentTool('arrow')
306
308
  editor.pointerDown(0, 50)
307
- editor.pointerMove(175, 50) // box1 is smaller even though it's behind box2
309
+ editor.pointerMove(175, 50) // box1 is smaller even though it's behind box2, but we're on the edge of box 2
310
+ expect(bindings().end).toMatchObject({ toId: ids.box2 })
311
+ editor.pointerMove(175, 70) // box1 is smaller even though it's behind box2
308
312
  expect(bindings().end).toMatchObject({ toId: ids.box1 })
309
- editor.pointerMove(150, 90) // box3 is smaller and at the front
313
+ editor.pointerMove(150, 90) // box3 is smaller and at the front but we're on the edge of box 2
314
+ expect(bindings().end).toMatchObject({ toId: ids.box2 })
315
+ editor.pointerMove(160, 90) // box3 is smaller and at the front and we're in box1 and box 3 and box 2
310
316
  expect(bindings().end).toMatchObject({ toId: ids.box3 })
311
317
  editor.sendToBack([ids.box3])
312
318
  editor.pointerMove(149, 90) // box3 is smaller, even when at the back
313
319
  expect(bindings().end).toMatchObject({ toId: ids.box3 })
314
- editor.pointerMove(175, 50)
320
+ editor.pointerMove(175, 60) // inside of box1 and box 2, but box 1 is smaller
315
321
  expect(bindings().end).toMatchObject({ toId: ids.box1 })
316
322
  })
317
323
  })
@@ -0,0 +1,315 @@
1
+ import { TLArrowShape, createShapeId } from '@tldraw/editor'
2
+ import { getArrowBindings } from '../lib/shapes/arrow/shared'
3
+ import { TestEditor } from './TestEditor'
4
+
5
+ let editor: TestEditor
6
+
7
+ const ids = {
8
+ solidShape: createShapeId('solidShape'),
9
+ hollowShape: createShapeId('hollowShape'),
10
+ arrow: createShapeId('arrow'),
11
+ }
12
+
13
+ const _arrow = () => editor.getOnlySelectedShape() as TLArrowShape
14
+
15
+ beforeEach(() => {
16
+ editor = new TestEditor()
17
+ })
18
+
19
+ describe('Inner/Outer Margin Shape Detection', () => {
20
+ describe('getShapeAtPoint with inner/outer margins', () => {
21
+ beforeEach(() => {
22
+ // Create a solid filled shape
23
+ editor.createShape({
24
+ id: ids.solidShape,
25
+ type: 'geo',
26
+ x: 100,
27
+ y: 100,
28
+ props: {
29
+ w: 100,
30
+ h: 100,
31
+ fill: 'solid',
32
+ },
33
+ })
34
+
35
+ // Create a hollow shape on top (same position, smaller size)
36
+ editor.createShape({
37
+ id: ids.hollowShape,
38
+ type: 'geo',
39
+ x: 125,
40
+ y: 125,
41
+ props: {
42
+ w: 50,
43
+ h: 50,
44
+ // No fill property - defaults to 'none' (hollow)
45
+ },
46
+ })
47
+ })
48
+
49
+ it('should support inner/outer margin options', () => {
50
+ // Test that the new margin options are accepted
51
+ const point = { x: 150, y: 150 }
52
+
53
+ // Test with array margin [innerMargin, outerMargin]
54
+ const arrayMarginHit = editor.getShapeAtPoint(point, {
55
+ hitInside: true,
56
+ margin: [8, 4],
57
+ })
58
+ expect(arrayMarginHit).toBeDefined()
59
+
60
+ // Test with insideMargin option
61
+ const insideMarginHit = editor.getShapeAtPoint(point, {
62
+ hitInside: true,
63
+ })
64
+ expect(insideMarginHit).toBeDefined()
65
+
66
+ // Test with single number margin (should use same for both)
67
+ const singleMarginHit = editor.getShapeAtPoint(point, {
68
+ hitInside: true,
69
+ margin: 8,
70
+ })
71
+ expect(singleMarginHit).toBeDefined()
72
+ })
73
+
74
+ it('should respect hitInside option for hollow shapes', () => {
75
+ const point = { x: 150, y: 150 }
76
+
77
+ // Without hitInside, should not hit hollow shape
78
+ const noHitInsideHit = editor.getShapeAtPoint(point, {
79
+ margin: [8, 0],
80
+ })
81
+ expect(noHitInsideHit?.id).toBe(ids.solidShape)
82
+
83
+ // With hitInside, should be able to hit hollow shape
84
+ const withHitInsideHit = editor.getShapeAtPoint(point, {
85
+ hitInside: true,
86
+ margin: [8, 0],
87
+ })
88
+ expect(withHitInsideHit).toBeDefined()
89
+ })
90
+
91
+ it('should handle edge cases correctly', () => {
92
+ // Test point exactly on the edge of hollow shape
93
+ const edgePoint = { x: 125, y: 150 }
94
+
95
+ const edgeHit = editor.getShapeAtPoint(edgePoint, {
96
+ hitInside: true,
97
+ margin: [8, 8],
98
+ })
99
+ expect(edgeHit).toBeDefined()
100
+ })
101
+ })
102
+
103
+ describe('Arrow binding with inner/outer margins', () => {
104
+ beforeEach(() => {
105
+ // Create a solid filled shape
106
+ editor.createShape({
107
+ id: ids.solidShape,
108
+ type: 'geo',
109
+ x: 100,
110
+ y: 100,
111
+ props: {
112
+ w: 100,
113
+ h: 100,
114
+ fill: 'solid',
115
+ },
116
+ })
117
+
118
+ // Create a hollow shape on top (same position, smaller size)
119
+ editor.createShape({
120
+ id: ids.hollowShape,
121
+ type: 'geo',
122
+ x: 125,
123
+ y: 125,
124
+ props: {
125
+ w: 50,
126
+ h: 50,
127
+ // No fill property - defaults to 'none' (hollow)
128
+ },
129
+ })
130
+ })
131
+
132
+ it('should create arrow bindings with inner/outer margin support', () => {
133
+ editor.setCurrentTool('arrow')
134
+
135
+ // Start arrow outside both shapes
136
+ editor.pointerDown(50, 150)
137
+
138
+ // Move to center of hollow shape (which overlaps solid shape)
139
+ editor.pointerMove(150, 150)
140
+ editor.pointerUp()
141
+
142
+ const createdArrow = editor
143
+ .getCurrentPageShapes()
144
+ .find((s) => s.type === 'arrow') as TLArrowShape
145
+ expect(createdArrow).toBeDefined()
146
+
147
+ const arrowBindings = getArrowBindings(editor, createdArrow)
148
+ expect(arrowBindings.end).toBeDefined()
149
+ // The binding should be to one of the shapes
150
+ expect([ids.solidShape, ids.hollowShape]).toContain(arrowBindings.end?.toId)
151
+ })
152
+
153
+ it('should bind to solid shape when no hollow shape is present', () => {
154
+ // Remove the hollow shape
155
+ editor.deleteShape(ids.hollowShape)
156
+
157
+ editor.setCurrentTool('arrow')
158
+
159
+ // Start arrow outside shape
160
+ editor.pointerDown(50, 150)
161
+
162
+ // Move to center of solid shape
163
+ editor.pointerMove(150, 150)
164
+ editor.pointerUp()
165
+
166
+ const createdArrow = editor
167
+ .getCurrentPageShapes()
168
+ .find((s) => s.type === 'arrow') as TLArrowShape
169
+ expect(createdArrow).toBeDefined()
170
+
171
+ const arrowBindings = getArrowBindings(editor, createdArrow)
172
+ expect(arrowBindings.end).toBeDefined()
173
+ expect(arrowBindings.end?.toId).toBe(ids.solidShape)
174
+ })
175
+ })
176
+
177
+ describe('Complex overlapping scenarios', () => {
178
+ it('should handle multiple overlapping shapes correctly', () => {
179
+ // Create multiple shapes with different fill states
180
+ editor.createShape({
181
+ id: ids.solidShape,
182
+ type: 'geo',
183
+ x: 100,
184
+ y: 100,
185
+ props: {
186
+ w: 100,
187
+ h: 100,
188
+ fill: 'solid',
189
+ },
190
+ })
191
+
192
+ editor.createShape({
193
+ id: ids.hollowShape,
194
+ type: 'geo',
195
+ x: 125,
196
+ y: 125,
197
+ props: {
198
+ w: 50,
199
+ h: 50,
200
+ // No fill property - defaults to 'none' (hollow)
201
+ },
202
+ })
203
+
204
+ // Create another hollow shape
205
+ const hollowShape2 = createShapeId('hollowShape2')
206
+ editor.createShape({
207
+ id: hollowShape2,
208
+ type: 'geo',
209
+ x: 140,
210
+ y: 140,
211
+ props: {
212
+ w: 30,
213
+ h: 30,
214
+ // No fill property - defaults to 'none' (hollow)
215
+ },
216
+ })
217
+
218
+ // Test point in the innermost hollow shape
219
+ const point = { x: 155, y: 155 }
220
+
221
+ const hit = editor.getShapeAtPoint(point, {
222
+ hitInside: true,
223
+ margin: [8, 8],
224
+ })
225
+ expect(hit).toBeDefined()
226
+ // Should hit one of the shapes
227
+ expect([ids.solidShape, ids.hollowShape, hollowShape2]).toContain(hit?.id)
228
+ })
229
+
230
+ it('should handle shapes with different geometries', () => {
231
+ // Create a solid rectangle
232
+ editor.createShape({
233
+ id: ids.solidShape,
234
+ type: 'geo',
235
+ x: 100,
236
+ y: 100,
237
+ props: {
238
+ w: 100,
239
+ h: 100,
240
+ fill: 'solid',
241
+ },
242
+ })
243
+
244
+ // Create a hollow circle on top
245
+ editor.createShape({
246
+ id: ids.hollowShape,
247
+ type: 'geo',
248
+ x: 125,
249
+ y: 125,
250
+ props: {
251
+ w: 50,
252
+ h: 50,
253
+ geo: 'ellipse',
254
+ // No fill property - defaults to 'none' (hollow)
255
+ },
256
+ })
257
+
258
+ // Test point inside the circle
259
+ const point = { x: 150, y: 150 }
260
+
261
+ const hit = editor.getShapeAtPoint(point, {
262
+ hitInside: true,
263
+ margin: [8, 8],
264
+ })
265
+ expect(hit).toBeDefined()
266
+ // Should hit one of the shapes
267
+ expect([ids.solidShape, ids.hollowShape]).toContain(hit?.id)
268
+ })
269
+ })
270
+
271
+ describe('Regression tests for the original bug', () => {
272
+ it('should support binding to hollow shapes when overlapping solid shapes', () => {
273
+ // This test verifies that the infrastructure exists for the bug fix
274
+ // Create a solid shape
275
+ editor.createShape({
276
+ id: ids.solidShape,
277
+ type: 'geo',
278
+ x: 100,
279
+ y: 100,
280
+ props: {
281
+ w: 100,
282
+ h: 100,
283
+ fill: 'solid',
284
+ },
285
+ })
286
+
287
+ // Create a hollow shape on top
288
+ editor.createShape({
289
+ id: ids.hollowShape,
290
+ type: 'geo',
291
+ x: 125,
292
+ y: 125,
293
+ props: {
294
+ w: 50,
295
+ h: 50,
296
+ // No fill property - defaults to 'none' (hollow)
297
+ },
298
+ })
299
+
300
+ // Test that we can detect both shapes
301
+ const point = { x: 150, y: 150 }
302
+
303
+ // Should be able to hit the solid shape without hitInside
304
+ const solidHit = editor.getShapeAtPoint(point)
305
+ expect(solidHit?.id).toBe(ids.solidShape)
306
+
307
+ // Should be able to hit the hollow shape with hitInside and inner margin
308
+ const hollowHit = editor.getShapeAtPoint(point, {
309
+ hitInside: true,
310
+ margin: [8, 0],
311
+ })
312
+ expect(hollowHit).toBeDefined()
313
+ })
314
+ })
315
+ })