tldraw 3.16.0-canary.aa1aff3ffe55 → 3.16.0-canary.cf24aedcd577

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 (228) hide show
  1. package/dist-cjs/index.d.ts +129 -5
  2. package/dist-cjs/index.js +14 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -3
  5. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  6. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  7. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  8. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +12 -12
  9. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  11. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  13. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  14. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  15. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  17. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  19. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  20. package/dist-cjs/lib/shapes/shared/ShapeFill.js +5 -5
  21. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  22. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
  23. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
  24. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  25. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  26. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  27. package/dist-cjs/lib/ui/TldrawUi.js +14 -0
  28. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  29. package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
  30. package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
  31. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  32. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  33. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  34. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  35. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +3 -3
  36. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  37. package/dist-cjs/lib/ui/components/MobileStylePanel.js +4 -2
  38. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  39. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
  40. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  41. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
  42. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  43. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  44. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  45. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  46. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  47. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
  48. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  49. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -140
  50. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  51. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
  52. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
  53. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
  54. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
  55. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  56. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  57. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  58. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  59. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
  60. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  61. package/dist-cjs/lib/ui/components/menu-items.js +6 -0
  62. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  63. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
  64. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
  65. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  66. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  67. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  68. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  69. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +30 -7
  70. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  71. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +291 -0
  72. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
  73. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  74. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  75. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +30 -7
  76. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +152 -2
  78. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  79. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
  80. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
  81. package/dist-cjs/lib/ui/context/actions.js +15 -0
  82. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  83. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  84. package/dist-cjs/lib/ui/hooks/useTools.js +76 -9
  85. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  86. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  87. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +3 -0
  88. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  89. package/dist-cjs/lib/ui/version.js +3 -3
  90. package/dist-cjs/lib/ui/version.js.map +1 -1
  91. package/dist-esm/index.d.mts +129 -5
  92. package/dist-esm/index.mjs +25 -1
  93. package/dist-esm/index.mjs.map +2 -2
  94. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
  95. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  96. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  97. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  98. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +13 -12
  99. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  100. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  101. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  102. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  103. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  104. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  105. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  106. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  107. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  108. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  109. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  110. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +6 -5
  111. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  112. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
  113. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
  114. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  115. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  116. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  117. package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
  118. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  119. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
  120. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
  121. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  122. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  123. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
  124. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
  125. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +3 -5
  126. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
  127. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +5 -2
  128. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  129. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
  130. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  131. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
  132. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  133. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
  134. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
  135. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
  136. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
  137. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +3 -1
  138. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  139. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +171 -140
  140. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  141. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
  142. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
  143. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
  144. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  145. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
  146. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  147. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
  148. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  149. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +5 -4
  150. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  151. package/dist-esm/lib/ui/components/menu-items.mjs +6 -0
  152. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  153. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +6 -6
  154. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  155. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
  156. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  157. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
  158. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  159. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +30 -7
  160. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  161. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +261 -0
  162. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +7 -0
  163. package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
  164. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
  165. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +30 -7
  166. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  167. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +160 -4
  168. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  169. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +3 -2
  170. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
  171. package/dist-esm/lib/ui/context/actions.mjs +15 -0
  172. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  173. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  174. package/dist-esm/lib/ui/hooks/useTools.mjs +83 -10
  175. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  176. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +3 -0
  177. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  178. package/dist-esm/lib/ui/version.mjs +3 -3
  179. package/dist-esm/lib/ui/version.mjs.map +1 -1
  180. package/package.json +3 -3
  181. package/src/index.ts +20 -0
  182. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
  183. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  184. package/src/lib/shapes/frame/FrameShapeUtil.tsx +13 -14
  185. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  186. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  187. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  188. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  189. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  190. package/src/lib/shapes/shared/ShapeFill.tsx +6 -5
  191. package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
  192. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  193. package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
  194. package/src/lib/ui/TldrawUi.tsx +17 -2
  195. package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
  196. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  197. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  198. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -4
  199. package/src/lib/ui/components/MobileStylePanel.tsx +8 -5
  200. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
  201. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
  202. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  203. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  204. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
  205. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -107
  206. package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
  207. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
  208. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  209. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  210. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +14 -11
  211. package/src/lib/ui/components/menu-items.tsx +8 -0
  212. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
  213. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
  214. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  215. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +51 -12
  216. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +343 -0
  217. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  218. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +30 -7
  219. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +218 -3
  220. package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
  221. package/src/lib/ui/context/actions.tsx +15 -0
  222. package/src/lib/ui/context/events.tsx +2 -0
  223. package/src/lib/ui/hooks/useTools.tsx +118 -10
  224. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +3 -0
  225. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +3 -0
  226. package/src/lib/ui/version.ts +3 -3
  227. package/src/lib/ui.css +199 -84
  228. package/tldraw.css +201 -84
@@ -1,9 +1,18 @@
1
- import { exhaustiveSwitchError, preventDefault } from '@tldraw/editor'
1
+ import {
2
+ exhaustiveSwitchError,
3
+ getPointerInfo,
4
+ preventDefault,
5
+ TLPointerEventInfo,
6
+ useEditor,
7
+ Vec,
8
+ VecModel,
9
+ } from '@tldraw/editor'
2
10
  import { ContextMenu as _ContextMenu } from 'radix-ui'
3
- import { useState } from 'react'
11
+ import { useMemo, useState } from 'react'
4
12
  import { unwrapLabel } from '../../../context/actions'
5
13
  import { TLUiEventSource } from '../../../context/events'
6
14
  import { useReadonly } from '../../../hooks/useReadonly'
15
+ import { TLUiToolItem } from '../../../hooks/useTools'
7
16
  import { TLUiTranslationKey } from '../../../hooks/useTranslation/TLUiTranslationKey'
8
17
  import { useTranslation } from '../../../hooks/useTranslation/useTranslation'
9
18
  import { kbdStr } from '../../../kbd-utils'
@@ -15,6 +24,7 @@ import { TldrawUiDropdownMenuItem } from '../TldrawUiDropdownMenu'
15
24
  import { TLUiIconJsx } from '../TldrawUiIcon'
16
25
  import { TldrawUiKbd } from '../TldrawUiKbd'
17
26
  import { TldrawUiToolbarButton } from '../TldrawUiToolbar'
27
+ import { tooltipManager } from '../TldrawUiTooltip'
18
28
  import { useTldrawUiMenuContext } from './TldrawUiMenuContext'
19
29
 
20
30
  /** @public */
@@ -63,6 +73,10 @@ export interface TLUiMenuItemProps<
63
73
  * Whether the item is selected.
64
74
  */
65
75
  isSelected?: boolean
76
+ /**
77
+ * The function to call when the item is dragged. If this is provided, the item will be draggable.
78
+ */
79
+ onDragStart?(source: TLUiEventSource, info: TLPointerEventInfo): void
66
80
  }
67
81
 
68
82
  /** @public @react */
@@ -81,6 +95,7 @@ export function TldrawUiMenuItem<
81
95
  onSelect,
82
96
  noClose,
83
97
  isSelected,
98
+ onDragStart,
84
99
  }: TLUiMenuItemProps<TranslationKey, IconType>) {
85
100
  const { type: menuType, sourceId } = useTldrawUiMenuContext()
86
101
 
@@ -207,6 +222,20 @@ export function TldrawUiMenuItem<
207
222
  )
208
223
  }
209
224
  case 'toolbar': {
225
+ if (onDragStart) {
226
+ return (
227
+ <DraggableToolbarButton
228
+ id={id}
229
+ icon={icon}
230
+ onSelect={onSelect}
231
+ onDragStart={onDragStart}
232
+ labelToUse={labelToUse}
233
+ titleStr={titleStr}
234
+ disabled={disabled}
235
+ isSelected={isSelected}
236
+ />
237
+ )
238
+ }
210
239
  return (
211
240
  <TldrawUiToolbarButton
212
241
  aria-label={labelStr}
@@ -227,12 +256,26 @@ export function TldrawUiMenuItem<
227
256
  )
228
257
  }
229
258
  case 'toolbar-overflow': {
259
+ if (onDragStart) {
260
+ return (
261
+ <DraggableToolbarButton
262
+ id={id}
263
+ icon={icon}
264
+ onSelect={onSelect}
265
+ onDragStart={onDragStart}
266
+ labelToUse={labelToUse}
267
+ titleStr={titleStr}
268
+ disabled={disabled}
269
+ isSelected={isSelected}
270
+ overflow
271
+ />
272
+ )
273
+ }
230
274
  return (
231
275
  <TldrawUiToolbarButton
232
276
  aria-label={labelStr}
233
277
  aria-pressed={isSelected ? 'true' : 'false'}
234
278
  isActive={isSelected}
235
- className="tlui-button-grid__button"
236
279
  data-testid={`tools.more.${id}`}
237
280
  data-value={id}
238
281
  disabled={disabled}
@@ -249,3 +292,175 @@ export function TldrawUiMenuItem<
249
292
  }
250
293
  }
251
294
  }
295
+
296
+ function useDraggableEvents(
297
+ onDragStart: TLUiToolItem['onDragStart'],
298
+ onSelect: TLUiToolItem['onSelect']
299
+ ) {
300
+ const editor = useEditor()
301
+ const events = useMemo(() => {
302
+ let state = { name: 'idle' } as
303
+ | {
304
+ name: 'idle'
305
+ }
306
+ | {
307
+ name: 'pointing'
308
+ screenSpaceStart: VecModel
309
+ }
310
+ | {
311
+ name: 'dragging'
312
+ screenSpaceStart: VecModel
313
+ }
314
+ | {
315
+ name: 'dragged'
316
+ }
317
+
318
+ function handlePointerDown(e: React.PointerEvent<HTMLButtonElement>) {
319
+ state = {
320
+ name: 'pointing',
321
+ screenSpaceStart: { x: e.clientX, y: e.clientY },
322
+ }
323
+
324
+ e.currentTarget.setPointerCapture(e.pointerId)
325
+ }
326
+
327
+ function handlePointerMove(e: React.PointerEvent<HTMLButtonElement>) {
328
+ if ((e as any).isSpecialRedispatchedEvent) return
329
+
330
+ if (state.name === 'pointing') {
331
+ const distanceSq = Vec.Dist2(state.screenSpaceStart, { x: e.clientX, y: e.clientY })
332
+ if (
333
+ distanceSq >
334
+ (editor.getInstanceState().isCoarsePointer
335
+ ? editor.options.coarseDragDistanceSquared
336
+ : editor.options.dragDistanceSquared)
337
+ ) {
338
+ const screenSpaceStart = state.screenSpaceStart
339
+ state = {
340
+ name: 'dragging',
341
+ screenSpaceStart,
342
+ }
343
+
344
+ editor.run(() => {
345
+ // Set origin point
346
+ editor.dispatch({
347
+ type: 'pointer',
348
+ target: 'canvas',
349
+ name: 'pointer_down',
350
+ ...getPointerInfo(e),
351
+ point: screenSpaceStart,
352
+ })
353
+
354
+ // Pointer down potentially selects shapes, so we need to deselect them.
355
+ editor.selectNone()
356
+
357
+ // start drag
358
+ onDragStart?.('toolbar', {
359
+ type: 'pointer',
360
+ target: 'canvas',
361
+ name: 'pointer_move',
362
+ ...getPointerInfo(e),
363
+ point: screenSpaceStart,
364
+ })
365
+
366
+ tooltipManager.hideAllTooltips()
367
+ })
368
+ }
369
+ }
370
+ }
371
+
372
+ function handlePointerUp(e: React.PointerEvent<HTMLButtonElement>) {
373
+ if ((e as any).isSpecialRedispatchedEvent) return
374
+
375
+ e.currentTarget.releasePointerCapture(e.pointerId)
376
+
377
+ editor.dispatch({
378
+ type: 'pointer',
379
+ target: 'canvas',
380
+ name: 'pointer_up',
381
+ ...getPointerInfo(e),
382
+ })
383
+ }
384
+
385
+ function handleClick() {
386
+ if (state.name === 'dragging' || state.name === 'dragged') {
387
+ state = { name: 'idle' }
388
+ return true
389
+ }
390
+
391
+ state = { name: 'idle' }
392
+ onSelect?.('toolbar')
393
+ }
394
+
395
+ return {
396
+ onPointerDown: handlePointerDown,
397
+ onPointerMove: handlePointerMove,
398
+ onPointerUp: handlePointerUp,
399
+ onClick: handleClick,
400
+ }
401
+ }, [onDragStart, editor, onSelect])
402
+
403
+ return events
404
+ }
405
+
406
+ function DraggableToolbarButton({
407
+ id,
408
+ labelToUse,
409
+ titleStr,
410
+ disabled,
411
+ isSelected,
412
+ icon,
413
+ onSelect,
414
+ onDragStart,
415
+ overflow,
416
+ }: {
417
+ id: string
418
+ disabled: boolean
419
+ labelToUse?: string
420
+ titleStr?: string
421
+ isSelected?: boolean
422
+ icon: TLUiMenuItemProps['icon']
423
+ onSelect: TLUiMenuItemProps['onSelect']
424
+ onDragStart: TLUiMenuItemProps['onDragStart']
425
+ overflow?: boolean
426
+ }) {
427
+ const events = useDraggableEvents(onDragStart, onSelect)
428
+
429
+ if (overflow) {
430
+ return (
431
+ <TldrawUiToolbarButton
432
+ aria-label={labelToUse}
433
+ aria-pressed={isSelected ? 'true' : 'false'}
434
+ isActive={isSelected}
435
+ className="tlui-button-grid__button"
436
+ data-testid={`tools.more.${id}`}
437
+ data-value={id}
438
+ disabled={disabled}
439
+ title={titleStr}
440
+ type="icon"
441
+ {...events}
442
+ >
443
+ <TldrawUiButtonIcon icon={icon!} />
444
+ </TldrawUiToolbarButton>
445
+ )
446
+ }
447
+
448
+ return (
449
+ <TldrawUiToolbarButton
450
+ aria-label={labelToUse}
451
+ aria-pressed={isSelected ? 'true' : 'false'}
452
+ data-testid={`tools.${id}`}
453
+ data-value={id}
454
+ disabled={disabled}
455
+ onTouchStart={(e) => {
456
+ preventDefault(e)
457
+ onSelect('toolbar')
458
+ }}
459
+ title={titleStr}
460
+ type="tool"
461
+ {...events}
462
+ >
463
+ <TldrawUiButtonIcon icon={icon!} />
464
+ </TldrawUiToolbarButton>
465
+ )
466
+ }
@@ -1,6 +1,7 @@
1
1
  import { RecursivePartial, defaultUserPreferences, track, useMaybeEditor } from '@tldraw/editor'
2
2
  import { ReactNode } from 'react'
3
3
  import { TLUiAssetUrls, useDefaultUiAssetUrlsWithOverrides } from '../assetUrls'
4
+ import { TldrawUiTooltipProvider } from '../components/primitives/TldrawUiTooltip'
4
5
  import { ToolsProvider } from '../hooks/useTools'
5
6
  import { TldrawUiTranslationProvider } from '../hooks/useTranslation/useTranslation'
6
7
  import {
@@ -72,26 +73,28 @@ export const TldrawUiContextProvider = track(function TldrawUiContextProvider({
72
73
  const editor = useMaybeEditor()
73
74
  return (
74
75
  <MimeTypeContext.Provider value={mediaMimeTypes}>
75
- <AssetUrlsProvider assetUrls={useDefaultUiAssetUrlsWithOverrides(assetUrls)}>
76
- <TldrawUiTranslationProvider
77
- overrides={useMergedTranslationOverrides(overrides)}
78
- locale={editor?.user.getLocale() ?? defaultUserPreferences.locale}
79
- >
80
- <TldrawUiEventsProvider onEvent={onUiEvent}>
81
- <TldrawUiToastsProvider>
82
- <TldrawUiDialogsProvider context={'tla'}>
83
- <TldrawUiA11yProvider>
84
- <BreakPointProvider forceMobile={forceMobile}>
85
- <TldrawUiComponentsProvider overrides={components}>
86
- <InternalProviders overrides={overrides}>{children}</InternalProviders>
87
- </TldrawUiComponentsProvider>
88
- </BreakPointProvider>
89
- </TldrawUiA11yProvider>
90
- </TldrawUiDialogsProvider>
91
- </TldrawUiToastsProvider>
92
- </TldrawUiEventsProvider>
93
- </TldrawUiTranslationProvider>
94
- </AssetUrlsProvider>
76
+ <TldrawUiTooltipProvider>
77
+ <AssetUrlsProvider assetUrls={useDefaultUiAssetUrlsWithOverrides(assetUrls)}>
78
+ <TldrawUiTranslationProvider
79
+ overrides={useMergedTranslationOverrides(overrides)}
80
+ locale={editor?.user.getLocale() ?? defaultUserPreferences.locale}
81
+ >
82
+ <TldrawUiEventsProvider onEvent={onUiEvent}>
83
+ <TldrawUiToastsProvider>
84
+ <TldrawUiDialogsProvider context={'tla'}>
85
+ <TldrawUiA11yProvider>
86
+ <BreakPointProvider forceMobile={forceMobile}>
87
+ <TldrawUiComponentsProvider overrides={components}>
88
+ <InternalProviders overrides={overrides}>{children}</InternalProviders>
89
+ </TldrawUiComponentsProvider>
90
+ </BreakPointProvider>
91
+ </TldrawUiA11yProvider>
92
+ </TldrawUiDialogsProvider>
93
+ </TldrawUiToastsProvider>
94
+ </TldrawUiEventsProvider>
95
+ </TldrawUiTranslationProvider>
96
+ </AssetUrlsProvider>
97
+ </TldrawUiTooltipProvider>
95
98
  </MimeTypeContext.Provider>
96
99
  )
97
100
  })
@@ -1266,6 +1266,21 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
1266
1266
  },
1267
1267
  checkbox: true,
1268
1268
  },
1269
+ {
1270
+ id: 'toggle-ui-labels',
1271
+ label: {
1272
+ default: 'action.toggle-ui-labels',
1273
+ menu: 'action.toggle-ui-labels.menu',
1274
+ },
1275
+ readonlyOk: true,
1276
+ onSelect(source) {
1277
+ trackEvent('toggle-ui-labels', { source })
1278
+ editor.user.updateUserPreferences({
1279
+ showUiLabels: !editor.user.getShowUiLabels(),
1280
+ })
1281
+ },
1282
+ checkbox: true,
1283
+ },
1269
1284
  {
1270
1285
  id: 'toggle-edge-scrolling',
1271
1286
  label: {
@@ -108,6 +108,7 @@ export interface TLUiEventMap {
108
108
  'toggle-lock': null
109
109
  'toggle-reduce-motion': null
110
110
  'toggle-keyboard-shortcuts': null
111
+ 'toggle-ui-labels': null
111
112
  'toggle-edge-scrolling': null
112
113
  'color-scheme': { value: string }
113
114
  'exit-pen-mode': null
@@ -126,6 +127,7 @@ export interface TLUiEventMap {
126
127
  'open-context-menu': null
127
128
  'adjust-shape-styles': null
128
129
  'copy-link': null
130
+ 'drag-tool': { id: string }
129
131
  'image-replace': null
130
132
  'video-replace': null
131
133
  'open-kbd-shortcuts': null
@@ -1,4 +1,13 @@
1
- import { Editor, GeoShapeGeoStyle, useMaybeEditor } from '@tldraw/editor'
1
+ import {
2
+ assertExists,
3
+ createShapeId,
4
+ Editor,
5
+ GeoShapeGeoStyle,
6
+ TLPointerEventInfo,
7
+ TLShapeId,
8
+ toRichText,
9
+ useMaybeEditor,
10
+ } from '@tldraw/editor'
2
11
  import * as React from 'react'
3
12
  import { EmbedDialog } from '../components/EmbedDialog'
4
13
  import { TLUiIconJsx } from '../components/primitives/TldrawUiIcon'
@@ -19,6 +28,7 @@ export interface TLUiToolItem<
19
28
  shortcutsLabel?: TranslationKey
20
29
  icon: IconType | TLUiIconJsx
21
30
  onSelect(source: TLUiEventSource): void
31
+ onDragStart?(source: TLUiEventSource, info: TLPointerEventInfo): void
22
32
  /**
23
33
  * The keyboard shortcut for this tool. This is a string that can be a single key,
24
34
  * or a combination of keys.
@@ -126,21 +136,27 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
126
136
  onToolSelect(source, this)
127
137
  },
128
138
  },
129
- ...[...GeoShapeGeoStyle.values].map((id) => ({
130
- id,
131
- label: `tool.${id}` as TLUiTranslationKey,
139
+ ...[...GeoShapeGeoStyle.values].map((geo) => ({
140
+ id: geo,
141
+ label: `tool.${geo}` as TLUiTranslationKey,
132
142
  meta: {
133
- geo: id,
143
+ geo,
134
144
  },
135
- kbd: id === 'rectangle' ? 'r' : id === 'ellipse' ? 'o' : undefined,
136
- icon: ('geo-' + id) as TLUiIconType,
145
+ kbd: geo === 'rectangle' ? 'r' : geo === 'ellipse' ? 'o' : undefined,
146
+ icon: ('geo-' + geo) as TLUiIconType,
137
147
  onSelect(source: TLUiEventSource) {
138
148
  editor.run(() => {
139
- editor.setStyleForNextShapes(GeoShapeGeoStyle, id)
149
+ editor.setStyleForNextShapes(GeoShapeGeoStyle, geo)
140
150
  editor.setCurrentTool('geo')
141
- onToolSelect(source, this, `geo-${id}`)
151
+ onToolSelect(source, this, `geo-${geo}`)
142
152
  })
143
153
  },
154
+ onDragStart(source: TLUiEventSource, info: TLPointerEventInfo) {
155
+ onDragFromToolbarToCreateShape(editor, info, {
156
+ createShape: (id) => editor.createShape({ id, type: 'geo', props: { geo } }),
157
+ })
158
+ trackEvent('drag-tool', { source, id: 'geo' })
159
+ },
144
160
  })),
145
161
  {
146
162
  id: 'arrow',
@@ -151,6 +167,17 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
151
167
  editor.setCurrentTool('arrow')
152
168
  onToolSelect(source, this)
153
169
  },
170
+ onDragStart(source: TLUiEventSource, info: TLPointerEventInfo) {
171
+ onDragFromToolbarToCreateShape(editor, info, {
172
+ createShape: (id) =>
173
+ editor.createShape({
174
+ id,
175
+ type: 'arrow',
176
+ props: { start: { x: 0, y: 0 }, end: { x: 200, y: 0 } },
177
+ }),
178
+ })
179
+ trackEvent('drag-tool', { source, id: 'arrow' })
180
+ },
154
181
  },
155
182
  {
156
183
  id: 'line',
@@ -171,6 +198,12 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
171
198
  editor.setCurrentTool('frame')
172
199
  onToolSelect(source, this)
173
200
  },
201
+ onDragStart(source, info) {
202
+ onDragFromToolbarToCreateShape(editor, info, {
203
+ createShape: (id) => editor.createShape({ id, type: 'frame' }),
204
+ })
205
+ trackEvent('drag-tool', { source, id: 'frame' })
206
+ },
174
207
  },
175
208
  {
176
209
  id: 'text',
@@ -181,6 +214,17 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
181
214
  editor.setCurrentTool('text')
182
215
  onToolSelect(source, this)
183
216
  },
217
+ onDragStart(source, info) {
218
+ onDragFromToolbarToCreateShape(editor, info, {
219
+ createShape: (id) =>
220
+ editor.createShape({ id, type: 'text', props: { richText: toRichText('Text') } }),
221
+ onDragEnd: (id) => {
222
+ editor.emit('select-all-text', { shapeId: id })
223
+ editor.setEditingShape(id)
224
+ },
225
+ })
226
+ trackEvent('drag-tool', { source, id: 'text' })
227
+ },
184
228
  },
185
229
  {
186
230
  id: 'asset',
@@ -201,6 +245,16 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
201
245
  editor.setCurrentTool('note')
202
246
  onToolSelect(source, this)
203
247
  },
248
+ onDragStart(source, info) {
249
+ onDragFromToolbarToCreateShape(editor, info, {
250
+ createShape: (id) => editor.createShape({ id, type: 'note' }),
251
+ onDragEnd: (id) => {
252
+ editor.emit('select-all-text', { shapeId: id })
253
+ editor.setEditingShape(id)
254
+ },
255
+ })
256
+ trackEvent('drag-tool', { source, id: 'note' })
257
+ },
204
258
  },
205
259
  {
206
260
  id: 'laser',
@@ -244,7 +298,7 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
244
298
  }
245
299
 
246
300
  return tools
247
- }, [overrides, editor, helpers, onToolSelect])
301
+ }, [overrides, editor, helpers, onToolSelect, trackEvent])
248
302
 
249
303
  return <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>
250
304
  }
@@ -259,3 +313,57 @@ export function useTools() {
259
313
 
260
314
  return ctx
261
315
  }
316
+
317
+ /**
318
+ * Options for {@link onDragFromToolbarToCreateShape}.
319
+ * @public
320
+ */
321
+ export interface OnDragFromToolbarToCreateShapesOpts {
322
+ /**
323
+ * Create the shape being dragged. You don't need to worry about positioning it, as it'll be
324
+ * immediately updated with the correct position.
325
+ */
326
+ createShape(id: TLShapeId): void
327
+ /**
328
+ * Called once the drag interaction has finished.
329
+ */
330
+ onDragEnd?(id: TLShapeId): void
331
+ }
332
+
333
+ /**
334
+ * A helper method to use in {@link TLUiToolItem#onDragStart} to create a shape by dragging it from
335
+ * the toolbar.
336
+ * @public
337
+ */
338
+ export function onDragFromToolbarToCreateShape(
339
+ editor: Editor,
340
+ info: TLPointerEventInfo,
341
+ opts: OnDragFromToolbarToCreateShapesOpts
342
+ ) {
343
+ const { x, y } = editor.inputs.currentPagePoint
344
+
345
+ const stoppingPoint = editor.markHistoryStoppingPoint('drag shape tool')
346
+ editor.setCurrentTool('select.translating')
347
+
348
+ const id = createShapeId()
349
+ opts.createShape(id)
350
+ const shape = assertExists(editor.getShape(id), 'Shape not found')
351
+
352
+ const { w, h } = editor.getShapePageBounds(id)!
353
+ editor.updateShape({ id, type: shape.type, x: x - w / 2, y: y - h / 2 })
354
+ editor.select(id)
355
+
356
+ editor.setCurrentTool('select.translating', {
357
+ ...info,
358
+ target: 'shape',
359
+ shape: editor.getShape(id),
360
+ isCreating: true,
361
+ creatingMarkId: stoppingPoint,
362
+ onCreate() {
363
+ editor.setCurrentTool('select.idle')
364
+ editor.select(id)
365
+ opts.onDragEnd?.(id)
366
+ },
367
+ })
368
+ editor.getCurrentTool().setCurrentToolIdMask(shape.type)
369
+ }
@@ -93,6 +93,8 @@ export type TLUiTranslationKey =
93
93
  | 'action.toggle-reduce-motion'
94
94
  | 'action.toggle-keyboard-shortcuts.menu'
95
95
  | 'action.toggle-keyboard-shortcuts'
96
+ | 'action.toggle-ui-labels.menu'
97
+ | 'action.toggle-ui-labels'
96
98
  | 'action.toggle-edge-scrolling.menu'
97
99
  | 'action.toggle-edge-scrolling'
98
100
  | 'action.toggle-debug-mode.menu'
@@ -298,6 +300,7 @@ export type TLUiTranslationKey =
298
300
  | 'a11y.open-keyboard-shortcuts'
299
301
  | 'menu.title'
300
302
  | 'menu.theme'
303
+ | 'menu.accessibility'
301
304
  | 'menu.copy-as'
302
305
  | 'menu.edit'
303
306
  | 'menu.export-as'
@@ -94,6 +94,8 @@ export const DEFAULT_TRANSLATION = {
94
94
  'action.toggle-reduce-motion': 'Toggle reduce motion',
95
95
  'action.toggle-keyboard-shortcuts.menu': 'Keyboard shortcuts',
96
96
  'action.toggle-keyboard-shortcuts': 'Toggle keyboard shortcuts',
97
+ 'action.toggle-ui-labels.menu': 'UI labels',
98
+ 'action.toggle-ui-labels': 'Toggle UI labels',
97
99
  'action.toggle-edge-scrolling.menu': 'Edge scrolling',
98
100
  'action.toggle-edge-scrolling': 'Toggle edge scrolling',
99
101
  'action.toggle-debug-mode.menu': 'Debug mode',
@@ -299,6 +301,7 @@ export const DEFAULT_TRANSLATION = {
299
301
  'a11y.open-keyboard-shortcuts': 'Open keyboard shortcuts',
300
302
  'menu.title': 'Menu',
301
303
  'menu.theme': 'Theme',
304
+ 'menu.accessibility': 'Accessibility',
302
305
  'menu.copy-as': 'Copy as',
303
306
  'menu.edit': 'Edit',
304
307
  'menu.export-as': 'Export as',
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.16.0-canary.aa1aff3ffe55'
4
+ export const version = '3.16.0-canary.cf24aedcd577'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-08-06T11:17:10.614Z',
8
- patch: '2025-08-06T11:17:10.614Z',
7
+ minor: '2025-08-11T15:30:09.531Z',
8
+ patch: '2025-08-11T15:30:09.531Z',
9
9
  }