tldraw 3.16.0-internal.a478398270c6 → 3.16.0-next.15f085081fd5

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 (534) hide show
  1. package/dist-cjs/index.d.ts +316 -23
  2. package/dist-cjs/index.js +34 -2
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/Tldraw.js +12 -2
  5. package/dist-cjs/lib/Tldraw.js.map +2 -2
  6. package/dist-cjs/lib/TldrawImage.js +5 -2
  7. package/dist-cjs/lib/TldrawImage.js.map +3 -3
  8. package/dist-cjs/lib/canvas/TldrawCropHandles.js +1 -1
  9. package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
  10. package/dist-cjs/lib/canvas/TldrawHandles.js +1 -1
  11. package/dist-cjs/lib/canvas/TldrawHandles.js.map +2 -2
  12. package/dist-cjs/lib/canvas/TldrawOverlays.js +1 -1
  13. package/dist-cjs/lib/canvas/TldrawOverlays.js.map +2 -2
  14. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  15. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  16. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +279 -271
  17. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  18. package/dist-cjs/lib/defaultExternalContentHandlers.js +6 -4
  19. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  20. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +27 -44
  21. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  22. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +16 -4
  23. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  24. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  25. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  26. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  27. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  28. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  29. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  30. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -6
  31. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  33. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  34. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +20 -17
  35. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  37. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  38. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  39. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  40. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  41. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  42. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -4
  43. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  44. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
  45. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  46. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +20 -5
  47. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  48. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +6 -5
  49. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  50. package/dist-cjs/lib/shapes/shared/PathBuilder.js +21 -3
  51. package/dist-cjs/lib/shapes/shared/PathBuilder.js.map +2 -2
  52. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -0
  53. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  54. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +5 -2
  55. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  56. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  57. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  58. package/dist-cjs/lib/shapes/shared/SvgTextLabel.js +4 -3
  59. package/dist-cjs/lib/shapes/shared/SvgTextLabel.js.map +2 -2
  60. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  61. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
  62. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
  63. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +7 -13
  64. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  65. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  66. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  67. package/dist-cjs/lib/styles.js.map +2 -2
  68. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  69. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  70. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  71. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  72. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +7 -1
  73. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
  74. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +43 -22
  75. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  76. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -15
  77. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  78. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +5 -0
  79. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  80. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +8 -0
  81. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  82. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +8 -0
  83. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  84. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +8 -0
  85. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  86. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  87. package/dist-cjs/lib/ui/TldrawUi.js +27 -12
  88. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  89. package/dist-cjs/lib/ui/components/A11y.js +14 -12
  90. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  91. package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
  92. package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
  93. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  94. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  95. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  96. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  97. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  98. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  99. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +57 -7
  100. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  101. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +3 -2
  102. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  103. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  104. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  105. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  106. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  107. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +4 -5
  108. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  109. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
  110. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  111. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  112. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  113. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  114. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  115. package/dist-cjs/lib/ui/components/Spinner.js +2 -25
  116. package/dist-cjs/lib/ui/components/Spinner.js.map +2 -2
  117. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
  118. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  119. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -139
  120. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  121. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
  122. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
  123. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
  124. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
  125. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js +21 -7
  126. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js.map +3 -3
  127. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  128. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  129. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  130. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  131. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  132. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  133. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
  134. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  135. package/dist-cjs/lib/ui/components/menu-items.js +22 -0
  136. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  137. package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButtonIcon.js.map +2 -2
  138. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +7 -16
  139. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
  140. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  141. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  142. package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js +1 -1
  143. package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js.map +2 -2
  144. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +35 -1
  145. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
  146. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  147. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  148. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +6 -2
  149. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  150. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +31 -7
  151. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  152. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +262 -0
  153. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
  154. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  155. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  156. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  157. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  158. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  159. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  160. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -22
  161. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  162. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
  163. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
  164. package/dist-cjs/lib/ui/context/actions.js +72 -9
  165. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  166. package/dist-cjs/lib/ui/context/components.js +2 -0
  167. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  168. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  169. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  170. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
  171. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  172. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  173. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  174. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  175. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +12 -0
  176. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  177. package/dist-cjs/lib/ui/kbd-utils.js +11 -4
  178. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  179. package/dist-cjs/lib/ui/version.js +3 -3
  180. package/dist-cjs/lib/ui/version.js.map +1 -1
  181. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
  182. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  183. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +3 -2
  184. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  185. package/dist-esm/index.d.mts +316 -23
  186. package/dist-esm/index.mjs +57 -5
  187. package/dist-esm/index.mjs.map +2 -2
  188. package/dist-esm/lib/Tldraw.mjs +14 -4
  189. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  190. package/dist-esm/lib/TldrawImage.mjs +5 -2
  191. package/dist-esm/lib/TldrawImage.mjs.map +2 -2
  192. package/dist-esm/lib/canvas/TldrawCropHandles.mjs +1 -1
  193. package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
  194. package/dist-esm/lib/canvas/TldrawHandles.mjs +1 -1
  195. package/dist-esm/lib/canvas/TldrawHandles.mjs.map +2 -2
  196. package/dist-esm/lib/canvas/TldrawOverlays.mjs +1 -1
  197. package/dist-esm/lib/canvas/TldrawOverlays.mjs.map +2 -2
  198. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  199. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  200. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +279 -271
  201. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  202. package/dist-esm/lib/defaultExternalContentHandlers.mjs +6 -4
  203. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  204. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +30 -44
  205. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  206. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +19 -5
  207. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  208. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  209. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  210. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  211. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  212. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +3 -0
  213. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  214. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -6
  215. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  216. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  217. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  218. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +21 -17
  219. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  220. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  221. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  222. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  223. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  224. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  225. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  226. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -4
  227. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  228. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
  229. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  230. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +21 -5
  231. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  232. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +7 -5
  233. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  234. package/dist-esm/lib/shapes/shared/PathBuilder.mjs +22 -3
  235. package/dist-esm/lib/shapes/shared/PathBuilder.mjs.map +2 -2
  236. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -0
  237. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  238. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +5 -2
  239. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  240. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  241. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  242. package/dist-esm/lib/shapes/shared/SvgTextLabel.mjs +4 -3
  243. package/dist-esm/lib/shapes/shared/SvgTextLabel.mjs.map +2 -2
  244. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  245. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
  246. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
  247. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +8 -13
  248. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  249. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  250. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  251. package/dist-esm/lib/styles.mjs.map +2 -2
  252. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  253. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  254. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  255. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  256. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +7 -1
  257. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
  258. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +43 -22
  259. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  260. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -15
  261. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  262. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +5 -0
  263. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  264. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +8 -0
  265. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  266. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +8 -0
  267. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  268. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +8 -0
  269. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  270. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  271. package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
  272. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  273. package/dist-esm/lib/ui/components/A11y.mjs +14 -12
  274. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  275. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
  276. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
  277. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  278. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  279. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  280. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  281. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
  282. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
  283. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +57 -7
  284. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  285. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +3 -3
  286. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
  287. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  288. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  289. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  290. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  291. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +4 -5
  292. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  293. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
  294. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  295. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
  296. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
  297. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
  298. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
  299. package/dist-esm/lib/ui/components/Spinner.mjs +3 -26
  300. package/dist-esm/lib/ui/components/Spinner.mjs.map +2 -2
  301. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +3 -1
  302. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  303. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +171 -139
  304. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  305. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
  306. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
  307. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
  308. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  309. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs +23 -9
  310. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs.map +3 -3
  311. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  312. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  313. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
  314. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  315. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
  316. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  317. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +5 -4
  318. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  319. package/dist-esm/lib/ui/components/menu-items.mjs +22 -0
  320. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  321. package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButtonIcon.mjs.map +2 -2
  322. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +8 -6
  323. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  324. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
  325. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  326. package/dist-esm/lib/ui/components/primitives/TldrawUiDialog.mjs +1 -1
  327. package/dist-esm/lib/ui/components/primitives/TldrawUiDialog.mjs.map +2 -2
  328. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +36 -2
  329. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
  330. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
  331. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  332. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +6 -2
  333. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  334. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +31 -7
  335. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  336. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +239 -0
  337. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +7 -0
  338. package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
  339. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
  340. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  341. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  342. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  343. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  344. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -24
  345. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  346. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +3 -2
  347. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
  348. package/dist-esm/lib/ui/context/actions.mjs +72 -9
  349. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  350. package/dist-esm/lib/ui/context/components.mjs +2 -0
  351. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  352. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  353. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  354. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
  355. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  356. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  357. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  358. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +12 -0
  359. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  360. package/dist-esm/lib/ui/kbd-utils.mjs +11 -4
  361. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  362. package/dist-esm/lib/ui/version.mjs +3 -3
  363. package/dist-esm/lib/ui/version.mjs.map +1 -1
  364. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
  365. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  366. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +3 -2
  367. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  368. package/package.json +12 -34
  369. package/src/index.ts +42 -3
  370. package/src/lib/Tldraw.tsx +15 -2
  371. package/src/lib/TldrawImage.tsx +6 -2
  372. package/src/lib/canvas/TldrawCropHandles.tsx +3 -1
  373. package/src/lib/canvas/TldrawHandles.tsx +5 -1
  374. package/src/lib/canvas/TldrawOverlays.tsx +1 -1
  375. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  376. package/src/lib/canvas/TldrawSelectionForeground.tsx +5 -1
  377. package/src/lib/defaultExternalContentHandlers.ts +14 -5
  378. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  379. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  380. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +12 -11
  381. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +30 -46
  382. package/src/lib/shapes/arrow/arrowLabel.ts +23 -3
  383. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -1
  384. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  385. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +3 -0
  386. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  387. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -7
  388. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  389. package/src/lib/shapes/frame/FrameShapeUtil.tsx +30 -21
  390. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  391. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  392. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  393. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -4
  394. package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
  395. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  396. package/src/lib/shapes/line/LineShapeUtil.tsx +25 -6
  397. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  398. package/src/lib/shapes/note/NoteShapeUtil.tsx +10 -4
  399. package/src/lib/shapes/shared/PathBuilder.test.tsx +1 -1
  400. package/src/lib/shapes/shared/PathBuilder.tsx +35 -1
  401. package/src/lib/shapes/shared/PlainTextLabel.tsx +1 -0
  402. package/src/lib/shapes/shared/RichTextLabel.tsx +4 -0
  403. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  404. package/src/lib/shapes/shared/SvgTextLabel.tsx +4 -2
  405. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  406. package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
  407. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  408. package/src/lib/shapes/text/TextShapeUtil.tsx +8 -14
  409. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  410. package/src/lib/styles.tsx +3 -1
  411. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  412. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  413. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +8 -1
  414. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +54 -30
  415. package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -24
  416. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +7 -0
  417. package/src/lib/tools/SelectTool/childStates/Resizing.ts +12 -1
  418. package/src/lib/tools/SelectTool/childStates/Rotating.ts +11 -0
  419. package/src/lib/tools/SelectTool/childStates/Translating.ts +11 -1
  420. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -0
  421. package/src/lib/ui/TldrawUi.tsx +33 -12
  422. package/src/lib/ui/components/A11y.tsx +15 -13
  423. package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
  424. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  425. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  426. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  427. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +46 -6
  428. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -2
  429. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  430. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  431. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +4 -5
  432. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
  433. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  434. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  435. package/src/lib/ui/components/Spinner.tsx +2 -24
  436. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
  437. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -106
  438. package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
  439. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
  440. package/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx +25 -9
  441. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  442. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  443. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  444. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +17 -12
  445. package/src/lib/ui/components/menu-items.tsx +25 -0
  446. package/src/lib/ui/components/primitives/Button/TldrawUiButtonIcon.tsx +2 -2
  447. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -35
  448. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
  449. package/src/lib/ui/components/primitives/TldrawUiDialog.tsx +1 -1
  450. package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +41 -3
  451. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  452. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +6 -1
  453. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +56 -12
  454. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +325 -0
  455. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  456. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +2 -2
  457. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  458. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  459. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +224 -23
  460. package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
  461. package/src/lib/ui/context/actions.tsx +74 -10
  462. package/src/lib/ui/context/components.tsx +3 -0
  463. package/src/lib/ui/context/events.tsx +6 -2
  464. package/src/lib/ui/hooks/menu-hooks.ts +1 -0
  465. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +3 -2
  466. package/src/lib/ui/hooks/useTools.tsx +142 -11
  467. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +12 -0
  468. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +12 -0
  469. package/src/lib/ui/kbd-utils.ts +12 -4
  470. package/src/lib/ui/version.ts +3 -3
  471. package/src/lib/ui.css +417 -314
  472. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +21 -7
  473. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
  474. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +28 -7
  475. package/src/lib/utils/tldr/buildFromV1Document.ts +2 -1
  476. package/src/test/A11y.test.tsx +3 -2
  477. package/src/test/ClickManager.test.ts +7 -6
  478. package/src/test/Editor.test.tsx +21 -20
  479. package/src/test/EraserTool.test.ts +184 -13
  480. package/src/test/HandTool.test.ts +10 -9
  481. package/src/test/HighlightShape.test.ts +2 -1
  482. package/src/test/SelectTool.test.ts +40 -13
  483. package/src/test/TLUserPreferences.test.ts +4 -3
  484. package/src/test/TestEditor.ts +13 -15
  485. package/src/test/TldrawEditor.test.tsx +11 -10
  486. package/src/test/ZoomTool.test.ts +7 -6
  487. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  488. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  489. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  490. package/src/test/arrows-megabus.test.tsx +17 -10
  491. package/src/test/bindings.test.tsx +24 -37
  492. package/src/test/bookmark-shapes.test.ts +1 -8
  493. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  494. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  495. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  496. package/src/test/commands/alignShapes.test.tsx +25 -24
  497. package/src/test/commands/animationSpeed.test.ts +2 -1
  498. package/src/test/commands/centerOnPoint.test.ts +3 -2
  499. package/src/test/commands/clipboard.test.ts +3 -2
  500. package/src/test/commands/createShapes.test.ts +2 -1
  501. package/src/test/commands/deletePage.test.ts +84 -1
  502. package/src/test/commands/deleteShapes.test.ts +2 -1
  503. package/src/test/commands/distributeShapes.test.tsx +11 -10
  504. package/src/test/commands/getSvgString.test.ts +2 -1
  505. package/src/test/commands/packShapes.test.ts +5 -4
  506. package/src/test/commands/resizeShape.test.ts +2 -1
  507. package/src/test/commands/rotateShapes.test.ts +7 -6
  508. package/src/test/commands/setCamera.test.ts +4 -3
  509. package/src/test/commands/setCurrentPage.test.ts +3 -2
  510. package/src/test/commands/stackShapes.test.ts +11 -10
  511. package/src/test/commands/stretch.test.tsx +13 -12
  512. package/src/test/createDeepLink.test.tsx +2 -1
  513. package/src/test/cropping.test.ts +3 -2
  514. package/src/test/drawing.test.ts +2 -1
  515. package/src/test/flipShapes.test.ts +4 -3
  516. package/src/test/frames.test.ts +25 -24
  517. package/src/test/getCulledShapes.test.tsx +3 -2
  518. package/src/test/groups.test.tsx +2 -2
  519. package/src/test/handleDeepLink.test.tsx +2 -1
  520. package/src/test/inner-outer-margin.test.ts +315 -0
  521. package/src/test/maxShapes.test.ts +3 -2
  522. package/src/test/modifiers.test.ts +5 -4
  523. package/src/test/navigation.test.ts +264 -9
  524. package/src/test/panning.test.ts +2 -1
  525. package/src/test/perf/perf.test.ts +2 -1
  526. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  527. package/src/test/resizing.test.ts +39 -38
  528. package/src/test/select.test.tsx +4 -3
  529. package/src/test/selection-omnibus.test.ts +11 -10
  530. package/src/test/shapeutils.test.ts +398 -48
  531. package/src/test/translating.test.ts +10 -9
  532. package/tldraw.css +737 -627
  533. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  534. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/hooks/menu-hooks.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tTLArrowShape,\n\tTLDrawShape,\n\tTLGroupShape,\n\tTLImageShape,\n\tTLLineShape,\n\tTLTextShape,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { getArrowBindings } from '../../shapes/arrow/shared'\n\nfunction shapesWithUnboundArrows(editor: Editor) {\n\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\tconst selectedShapes = selectedShapeIds.map((id) => {\n\t\treturn editor.getShape(id)\n\t})\n\n\treturn selectedShapes.filter((shape) => {\n\t\tif (!shape) return false\n\t\tif (editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {\n\t\t\tconst bindings = getArrowBindings(editor, shape)\n\t\t\tif (bindings.start || bindings.end) return false\n\t\t}\n\t\treturn true\n\t})\n}\n\n/** @internal */\nexport const useThreeStackableItems = () => {\n\tconst editor = useEditor()\n\treturn useValue('threeStackableItems', () => shapesWithUnboundArrows(editor).length > 2, [editor])\n}\n\n/** @internal */\nexport const useIsInSelectState = () => {\n\tconst editor = useEditor()\n\treturn useValue('isInSelectState', () => editor.isIn('select'), [editor])\n}\n\n/** @internal */\nexport const useAllowGroup = () => {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'allow group',\n\t\t() => {\n\t\t\t// We can't group arrows that are bound to shapes that aren't selected\n\t\t\t// if more than one shape has an arrow bound to it, allow group\n\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\n\t\t\tif (selectedShapes.length < 2) return false\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\tif (editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {\n\t\t\t\t\tconst bindings = getArrowBindings(editor, shape)\n\t\t\t\t\tif (bindings.start) {\n\t\t\t\t\t\t// if the other shape is not among the selected shapes...\n\t\t\t\t\t\tif (!selectedShapes.some((s) => s.id === bindings.start!.toId)) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (bindings.end) {\n\t\t\t\t\t\t// if the other shape is not among the selected shapes...\n\t\t\t\t\t\tif (!selectedShapes.some((s) => s.id === bindings.end!.toId)) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\t\t[editor]\n\t)\n}\n\n/** @internal */\nexport const useAllowUngroup = () => {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'allowUngroup',\n\t\t() => editor.getSelectedShapeIds().some((id) => editor.getShape(id)?.type === 'group'),\n\t\t[editor]\n\t)\n}\n\nexport const showMenuPaste =\n\ttypeof window !== 'undefined' &&\n\t'navigator' in window &&\n\tBoolean(navigator.clipboard) &&\n\tBoolean(navigator.clipboard.read)\n\n/**\n * Returns true if the number of LOCKED OR UNLOCKED selected shapes is at least min or at most max.\n */\nexport function useAnySelectedShapesCount(min?: number, max?: number) {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'selectedShapes',\n\t\t() => {\n\t\t\tconst len = editor.getSelectedShapes().length\n\t\t\tif (min === undefined) {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// just length\n\t\t\t\t\treturn len\n\t\t\t\t} else {\n\t\t\t\t\t// max but no min\n\t\t\t\t\treturn len <= max\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// min but no max\n\t\t\t\t\treturn len >= min\n\t\t\t\t} else {\n\t\t\t\t\t// max and min\n\t\t\t\t\treturn len >= min && len <= max\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, min, max]\n\t)\n}\n\n/**\n * Returns true if the number of UNLOCKED selected shapes is at least min or at most max.\n */\nexport function useUnlockedSelectedShapesCount(min?: number, max?: number) {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'selectedShapes',\n\t\t() => {\n\t\t\tconst len = editor\n\t\t\t\t.getSelectedShapes()\n\t\t\t\t.filter((s) => !editor.isShapeOrAncestorLocked(s)).length\n\t\t\tif (min === undefined) {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// just length\n\t\t\t\t\treturn len\n\t\t\t\t} else {\n\t\t\t\t\t// max but no min\n\t\t\t\t\treturn len <= max\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// min but no max\n\t\t\t\t\treturn len >= min\n\t\t\t\t} else {\n\t\t\t\t\t// max and min\n\t\t\t\t\treturn len >= min && len <= max\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n}\n\nexport function useShowAutoSizeToggle() {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'showAutoSizeToggle',\n\t\t() => {\n\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\t\t\treturn (\n\t\t\t\tselectedShapes.length === 1 &&\n\t\t\t\teditor.isShapeOfType<TLTextShape>(selectedShapes[0], 'text') &&\n\t\t\t\tselectedShapes[0].props.autoSize === false\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n}\n\nexport function useHasLinkShapeSelected() {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'hasLinkShapeSelected',\n\t\t() => {\n\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\t\treturn !!(\n\t\t\t\tonlySelectedShape &&\n\t\t\t\tonlySelectedShape.type !== 'embed' &&\n\t\t\t\t'url' in onlySelectedShape.props &&\n\t\t\t\t!onlySelectedShape.isLocked\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n}\n\nexport function useOnlyFlippableShape() {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'onlyFlippableShape',\n\t\t() => {\n\t\t\tconst shape = editor.getOnlySelectedShape()\n\t\t\treturn (\n\t\t\t\tshape &&\n\t\t\t\t(editor.isShapeOfType<TLGroupShape>(shape, 'group') ||\n\t\t\t\t\teditor.isShapeOfType<TLImageShape>(shape, 'image') ||\n\t\t\t\t\teditor.isShapeOfType<TLArrowShape>(shape, 'arrow') ||\n\t\t\t\t\teditor.isShapeOfType<TLLineShape>(shape, 'line') ||\n\t\t\t\t\teditor.isShapeOfType<TLDrawShape>(shape, 'draw'))\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n}\n\n/** @public */\nexport function useCanRedo() {\n\tconst editor = useEditor()\n\treturn useValue('useCanRedo', () => editor.getCanRedo(), [editor])\n}\n\n/** @public */\nexport function useCanUndo() {\n\tconst editor = useEditor()\n\treturn useValue('useCanUndo', () => editor.getCanUndo(), [editor])\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tTLArrowShape,\n\tTLDrawShape,\n\tTLGroupShape,\n\tTLImageShape,\n\tTLLineShape,\n\tTLTextShape,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { getArrowBindings } from '../../shapes/arrow/shared'\n\nfunction shapesWithUnboundArrows(editor: Editor) {\n\tconst selectedShapeIds = editor.getSelectedShapeIds()\n\tconst selectedShapes = selectedShapeIds.map((id) => {\n\t\treturn editor.getShape(id)\n\t})\n\n\treturn selectedShapes.filter((shape) => {\n\t\tif (!shape) return false\n\t\tif (editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {\n\t\t\tconst bindings = getArrowBindings(editor, shape)\n\t\t\tif (bindings.start || bindings.end) return false\n\t\t}\n\t\treturn true\n\t})\n}\n\n/** @internal */\nexport const useThreeStackableItems = () => {\n\tconst editor = useEditor()\n\treturn useValue('threeStackableItems', () => shapesWithUnboundArrows(editor).length > 2, [editor])\n}\n\n/** @internal */\nexport const useIsInSelectState = () => {\n\tconst editor = useEditor()\n\treturn useValue('isInSelectState', () => editor.isIn('select'), [editor])\n}\n\n/** @internal */\nexport const useAllowGroup = () => {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'allow group',\n\t\t() => {\n\t\t\t// We can't group arrows that are bound to shapes that aren't selected\n\t\t\t// if more than one shape has an arrow bound to it, allow group\n\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\n\t\t\tif (selectedShapes.length < 2) return false\n\n\t\t\tfor (const shape of selectedShapes) {\n\t\t\t\tif (editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) {\n\t\t\t\t\tconst bindings = getArrowBindings(editor, shape)\n\t\t\t\t\tif (bindings.start) {\n\t\t\t\t\t\t// if the other shape is not among the selected shapes...\n\t\t\t\t\t\tif (!selectedShapes.some((s) => s.id === bindings.start!.toId)) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (bindings.end) {\n\t\t\t\t\t\t// if the other shape is not among the selected shapes...\n\t\t\t\t\t\tif (!selectedShapes.some((s) => s.id === bindings.end!.toId)) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true\n\t\t},\n\t\t[editor]\n\t)\n}\n\n/** @internal */\nexport const useAllowUngroup = () => {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'allowUngroup',\n\t\t() => editor.getSelectedShapeIds().some((id) => editor.getShape(id)?.type === 'group'),\n\t\t[editor]\n\t)\n}\n\nexport const showMenuPaste =\n\ttypeof window !== 'undefined' &&\n\t'navigator' in window &&\n\tBoolean(navigator.clipboard) &&\n\tBoolean(navigator.clipboard.read)\n\n/**\n * Returns true if the number of LOCKED OR UNLOCKED selected shapes is at least min or at most max.\n */\nexport function useAnySelectedShapesCount(min?: number, max?: number) {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'selectedShapes',\n\t\t() => {\n\t\t\tconst len = editor.getSelectedShapes().length\n\t\t\tif (min === undefined) {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// just length\n\t\t\t\t\treturn len\n\t\t\t\t} else {\n\t\t\t\t\t// max but no min\n\t\t\t\t\treturn len <= max\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// min but no max\n\t\t\t\t\treturn len >= min\n\t\t\t\t} else {\n\t\t\t\t\t// max and min\n\t\t\t\t\treturn len >= min && len <= max\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor, min, max]\n\t)\n}\n\n/**\n * Returns true if the number of UNLOCKED selected shapes is at least min or at most max.\n * @public\n */\nexport function useUnlockedSelectedShapesCount(min?: number, max?: number) {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'selectedShapes',\n\t\t() => {\n\t\t\tconst len = editor\n\t\t\t\t.getSelectedShapes()\n\t\t\t\t.filter((s) => !editor.isShapeOrAncestorLocked(s)).length\n\t\t\tif (min === undefined) {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// just length\n\t\t\t\t\treturn len\n\t\t\t\t} else {\n\t\t\t\t\t// max but no min\n\t\t\t\t\treturn len <= max\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (max === undefined) {\n\t\t\t\t\t// min but no max\n\t\t\t\t\treturn len >= min\n\t\t\t\t} else {\n\t\t\t\t\t// max and min\n\t\t\t\t\treturn len >= min && len <= max\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[editor]\n\t)\n}\n\nexport function useShowAutoSizeToggle() {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'showAutoSizeToggle',\n\t\t() => {\n\t\t\tconst selectedShapes = editor.getSelectedShapes()\n\t\t\treturn (\n\t\t\t\tselectedShapes.length === 1 &&\n\t\t\t\teditor.isShapeOfType<TLTextShape>(selectedShapes[0], 'text') &&\n\t\t\t\tselectedShapes[0].props.autoSize === false\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n}\n\nexport function useHasLinkShapeSelected() {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'hasLinkShapeSelected',\n\t\t() => {\n\t\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\t\treturn !!(\n\t\t\t\tonlySelectedShape &&\n\t\t\t\tonlySelectedShape.type !== 'embed' &&\n\t\t\t\t'url' in onlySelectedShape.props &&\n\t\t\t\t!onlySelectedShape.isLocked\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n}\n\nexport function useOnlyFlippableShape() {\n\tconst editor = useEditor()\n\treturn useValue(\n\t\t'onlyFlippableShape',\n\t\t() => {\n\t\t\tconst shape = editor.getOnlySelectedShape()\n\t\t\treturn (\n\t\t\t\tshape &&\n\t\t\t\t(editor.isShapeOfType<TLGroupShape>(shape, 'group') ||\n\t\t\t\t\teditor.isShapeOfType<TLImageShape>(shape, 'image') ||\n\t\t\t\t\teditor.isShapeOfType<TLArrowShape>(shape, 'arrow') ||\n\t\t\t\t\teditor.isShapeOfType<TLLineShape>(shape, 'line') ||\n\t\t\t\t\teditor.isShapeOfType<TLDrawShape>(shape, 'draw'))\n\t\t\t)\n\t\t},\n\t\t[editor]\n\t)\n}\n\n/** @public */\nexport function useCanRedo() {\n\tconst editor = useEditor()\n\treturn useValue('useCanRedo', () => editor.getCanRedo(), [editor])\n}\n\n/** @public */\nexport function useCanUndo() {\n\tconst editor = useEditor()\n\treturn useValue('useCanUndo', () => editor.getCanUndo(), [editor])\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -48,7 +48,7 @@ function useKeyboardShortcuts() {
48
48
  if (isReadonlyMode && !action.readonlyOk) continue;
49
49
  if (SKIP_KBDS.includes(action.id)) continue;
50
50
  hot(getHotkeysStringFromKbd(action.kbd), (event) => {
51
- if (areShortcutsDisabled(editor)) return;
51
+ if (areShortcutsDisabled(editor) && !action.isRequiredA11yAction) return;
52
52
  preventDefault(event);
53
53
  action.onSelect("kbd");
54
54
  });
@@ -115,7 +115,7 @@ function useKeyboardShortcuts() {
115
115
  }, [actions, tools, isReadonlyMode, editor, isFocused]);
116
116
  }
117
117
  function areShortcutsDisabled(editor) {
118
- return editor.menus.hasAnyOpenMenus() || editor.getEditingShapeId() !== null || editor.getCrashingError();
118
+ return editor.menus.hasAnyOpenMenus() || editor.getEditingShapeId() !== null || editor.getCrashingError() || !editor.user.getAreKeyboardShortcutsEnabled();
119
119
  }
120
120
  function getHotkeysStringFromKbd(kbd) {
121
121
  return getKeys(kbd).map((kbd2) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/hooks/useKeyboardShortcuts.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tTLPointerEventInfo,\n\tisAccelKey,\n\tpreventDefault,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\t\tconst container = editor.getContainer()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(\n\t\t\t\tkeys,\n\t\t\t\t{ element: container.ownerDocument.body, keyup: true, keydown: false },\n\t\t\t\tcallback\n\t\t\t)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getIsReadonly())) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, isFocused])\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn (\n\t\teditor.menus.hasAnyOpenMenus() ||\n\t\teditor.getEditingShapeId() !== null ||\n\t\teditor.getCrashingError()\n\t)\n}\n\n// The \"raw\" kbd here will look something like \"a\" or a combination of keys \"del,backspace\".\n// We need to first split them up by comma, then parse each key to ensure backwards compatibility\n// with the old kbd format. We used to have symbols to denote cmd/alt/shift,\n// using ! for shift, $ for cmd, and ? for alt.\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\n\t\t\tconst shift = kbd.includes('!')\n\t\t\tconst alt = kbd.includes('?')\n\t\t\tconst cmd = kbd.includes('$')\n\n\t\t\t// remove the modifiers; the remaining string are the actual key\n\t\t\tconst k = kbd.replace(/[!?$]/g, '')\n\n\t\t\tif (shift && alt && cmd) {\n\t\t\t\tstr = `cmd+shift+alt+${k},ctrl+shift+alt+${k}`\n\t\t\t} else if (shift && cmd) {\n\t\t\t\tstr = `cmd+shift+${k},ctrl+shift+${k}`\n\t\t\t} else if (alt && cmd) {\n\t\t\t\tstr = `cmd+alt+${k},ctrl+alt+${k}`\n\t\t\t} else if (alt && shift) {\n\t\t\t\tstr = `shift+alt+${k}`\n\t\t\t} else if (shift) {\n\t\t\t\tstr = `shift+${k}`\n\t\t\t} else if (alt) {\n\t\t\t\tstr = `alt+${k}`\n\t\t\t} else if (cmd) {\n\t\t\t\tstr = `cmd+${k},ctrl+${k}`\n\t\t\t} else {\n\t\t\t\tstr = k\n\t\t\t}\n\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tTLPointerEventInfo,\n\tisAccelKey,\n\tpreventDefault,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport hotkeys from 'hotkeys-js'\nimport { useEffect } from 'react'\nimport { useActions } from '../context/actions'\nimport { useReadonly } from './useReadonly'\nimport { useTools } from './useTools'\n\nconst SKIP_KBDS = [\n\t// we set these in useNativeClipboardEvents instead\n\t'copy',\n\t'cut',\n\t'paste',\n\t// There's also an upload asset action, so we don't want to set the kbd twice\n\t'asset',\n]\n\n/** @public */\nexport function useKeyboardShortcuts() {\n\tconst editor = useEditor()\n\n\tconst isReadonlyMode = useReadonly()\n\tconst actions = useActions()\n\tconst tools = useTools()\n\tconst isFocused = useValue('is focused', () => editor.getInstanceState().isFocused, [editor])\n\tuseEffect(() => {\n\t\tif (!isFocused) return\n\n\t\tconst disposables = new Array<() => void>()\n\t\tconst container = editor.getContainer()\n\n\t\tconst hot = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(keys, { element: container.ownerDocument.body }, callback)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\tconst hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {\n\t\t\thotkeys(\n\t\t\t\tkeys,\n\t\t\t\t{ element: container.ownerDocument.body, keyup: true, keydown: false },\n\t\t\t\tcallback\n\t\t\t)\n\t\t\tdisposables.push(() => {\n\t\t\t\thotkeys.unbind(keys, callback)\n\t\t\t})\n\t\t}\n\n\t\t// Add hotkeys for actions and tools.\n\t\t// Except those that in SKIP_KBDS!\n\t\tfor (const action of Object.values(actions)) {\n\t\t\tif (!action.kbd) continue\n\t\t\tif (isReadonlyMode && !action.readonlyOk) continue\n\t\t\tif (SKIP_KBDS.includes(action.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(action.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor) && !action.isRequiredA11yAction) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\taction.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\tfor (const tool of Object.values(tools)) {\n\t\t\tif (!tool.kbd || (!tool.readonlyOk && editor.getIsReadonly())) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (SKIP_KBDS.includes(tool.id)) continue\n\n\t\t\thot(getHotkeysStringFromKbd(tool.kbd), (event) => {\n\t\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\t\tpreventDefault(event)\n\t\t\t\ttool.onSelect('kbd')\n\t\t\t})\n\t\t}\n\n\t\thot(',', (e) => {\n\t\t\t// Skip if shortcuts are disabled\n\t\t\tif (areShortcutsDisabled(editor)) return\n\n\t\t\t// Don't press again if already pressed\n\t\t\tif (editor.inputs.keys.has('Comma')) return\n\n\t\t\tpreventDefault(e) // prevent whatever would normally happen\n\t\t\teditor.focus() // Focus if not already focused\n\n\t\t\teditor.inputs.keys.add('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentPagePoint\n\t\t\tconst screenpoints = editor.pageToScreen({ x, y })\n\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_down',\n\t\t\t\tpoint: { x: screenpoints.x, y: screenpoints.y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\thotUp(',', (e) => {\n\t\t\tif (areShortcutsDisabled(editor)) return\n\t\t\tif (!editor.inputs.keys.has('Comma')) return\n\n\t\t\teditor.inputs.keys.delete('Comma')\n\n\t\t\tconst { x, y, z } = editor.inputs.currentScreenPoint\n\t\t\tconst info: TLPointerEventInfo = {\n\t\t\t\ttype: 'pointer',\n\t\t\t\tname: 'pointer_up',\n\t\t\t\tpoint: { x, y, z },\n\t\t\t\tshiftKey: e.shiftKey,\n\t\t\t\taltKey: e.altKey,\n\t\t\t\tctrlKey: e.metaKey || e.ctrlKey,\n\t\t\t\tmetaKey: e.metaKey,\n\t\t\t\taccelKey: isAccelKey(e),\n\t\t\t\tpointerId: 0,\n\t\t\t\tbutton: 0,\n\t\t\t\tisPen: editor.getInstanceState().isPenMode,\n\t\t\t\ttarget: 'canvas',\n\t\t\t}\n\n\t\t\teditor.dispatch(info)\n\t\t})\n\n\t\treturn () => {\n\t\t\tdisposables.forEach((d) => d())\n\t\t}\n\t}, [actions, tools, isReadonlyMode, editor, isFocused])\n}\n\nexport function areShortcutsDisabled(editor: Editor) {\n\treturn (\n\t\teditor.menus.hasAnyOpenMenus() ||\n\t\teditor.getEditingShapeId() !== null ||\n\t\teditor.getCrashingError() ||\n\t\t!editor.user.getAreKeyboardShortcutsEnabled()\n\t)\n}\n\n// The \"raw\" kbd here will look something like \"a\" or a combination of keys \"del,backspace\".\n// We need to first split them up by comma, then parse each key to ensure backwards compatibility\n// with the old kbd format. We used to have symbols to denote cmd/alt/shift,\n// using ! for shift, $ for cmd, and ? for alt.\nfunction getHotkeysStringFromKbd(kbd: string) {\n\treturn getKeys(kbd)\n\t\t.map((kbd) => {\n\t\t\tlet str = ''\n\n\t\t\tconst shift = kbd.includes('!')\n\t\t\tconst alt = kbd.includes('?')\n\t\t\tconst cmd = kbd.includes('$')\n\n\t\t\t// remove the modifiers; the remaining string are the actual key\n\t\t\tconst k = kbd.replace(/[!?$]/g, '')\n\n\t\t\tif (shift && alt && cmd) {\n\t\t\t\tstr = `cmd+shift+alt+${k},ctrl+shift+alt+${k}`\n\t\t\t} else if (shift && cmd) {\n\t\t\t\tstr = `cmd+shift+${k},ctrl+shift+${k}`\n\t\t\t} else if (alt && cmd) {\n\t\t\t\tstr = `cmd+alt+${k},ctrl+alt+${k}`\n\t\t\t} else if (alt && shift) {\n\t\t\t\tstr = `shift+alt+${k}`\n\t\t\t} else if (shift) {\n\t\t\t\tstr = `shift+${k}`\n\t\t\t} else if (alt) {\n\t\t\t\tstr = `alt+${k}`\n\t\t\t} else if (cmd) {\n\t\t\t\tstr = `cmd+${k},ctrl+${k}`\n\t\t\t} else {\n\t\t\t\tstr = k\n\t\t\t}\n\n\t\t\treturn str\n\t\t})\n\t\t.join(',')\n}\n\n// Logic to split kbd string from hotkeys-js util.\nfunction getKeys(key: string) {\n\tif (typeof key !== 'string') key = ''\n\tkey = key.replace(/\\s/g, '')\n\tconst keys = key.split(',')\n\tlet index = keys.lastIndexOf('')\n\n\tfor (; index >= 0; ) {\n\t\tkeys[index - 1] += ','\n\t\tkeys.splice(index, 1)\n\t\tindex = keys.lastIndexOf('')\n\t}\n\n\treturn keys\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["kbd"]
7
7
  }
@@ -1,5 +1,12 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { GeoShapeGeoStyle, useMaybeEditor } from "@tldraw/editor";
2
+ import {
3
+ assertExists,
4
+ createShapeId,
5
+ GeoShapeGeoStyle,
6
+ getIndicesBetween,
7
+ toRichText,
8
+ useMaybeEditor
9
+ } from "@tldraw/editor";
3
10
  import * as React from "react";
4
11
  import { EmbedDialog } from "../components/EmbedDialog.mjs";
5
12
  import { useA11y } from "../context/a11y.mjs";
@@ -70,20 +77,26 @@ function ToolsProvider({ overrides, children }) {
70
77
  onToolSelect(source, this);
71
78
  }
72
79
  },
73
- ...[...GeoShapeGeoStyle.values].map((id) => ({
74
- id,
75
- label: `tool.${id}`,
80
+ ...[...GeoShapeGeoStyle.values].map((geo) => ({
81
+ id: geo,
82
+ label: `tool.${geo}`,
76
83
  meta: {
77
- geo: id
84
+ geo
78
85
  },
79
- kbd: id === "rectangle" ? "r" : id === "ellipse" ? "o" : void 0,
80
- icon: "geo-" + id,
86
+ kbd: geo === "rectangle" ? "r" : geo === "ellipse" ? "o" : void 0,
87
+ icon: "geo-" + geo,
81
88
  onSelect(source) {
82
89
  editor.run(() => {
83
- editor.setStyleForNextShapes(GeoShapeGeoStyle, id);
90
+ editor.setStyleForNextShapes(GeoShapeGeoStyle, geo);
84
91
  editor.setCurrentTool("geo");
85
- onToolSelect(source, this, `geo-${id}`);
92
+ onToolSelect(source, this, `geo-${geo}`);
86
93
  });
94
+ },
95
+ onDragStart(source, info) {
96
+ onDragFromToolbarToCreateShape(editor, info, {
97
+ createShape: (id) => editor.createShape({ id, type: "geo", props: { w: 200, h: 200, geo } })
98
+ });
99
+ trackEvent("drag-tool", { source, id: "geo" });
87
100
  }
88
101
  })),
89
102
  {
@@ -94,6 +107,16 @@ function ToolsProvider({ overrides, children }) {
94
107
  onSelect(source) {
95
108
  editor.setCurrentTool("arrow");
96
109
  onToolSelect(source, this);
110
+ },
111
+ onDragStart(source, info) {
112
+ onDragFromToolbarToCreateShape(editor, info, {
113
+ createShape: (id) => editor.createShape({
114
+ id,
115
+ type: "arrow",
116
+ props: { start: { x: 0, y: 0 }, end: { x: 200, y: 0 } }
117
+ })
118
+ });
119
+ trackEvent("drag-tool", { source, id: "arrow" });
97
120
  }
98
121
  },
99
122
  {
@@ -104,6 +127,24 @@ function ToolsProvider({ overrides, children }) {
104
127
  onSelect(source) {
105
128
  editor.setCurrentTool("line");
106
129
  onToolSelect(source, this);
130
+ },
131
+ onDragStart(source, info) {
132
+ onDragFromToolbarToCreateShape(editor, info, {
133
+ createShape: (id) => {
134
+ const [start, end] = getIndicesBetween(null, null, 2);
135
+ editor.createShape({
136
+ id,
137
+ type: "line",
138
+ props: {
139
+ points: {
140
+ [start]: { id: start, index: start, x: 0, y: 200 },
141
+ [end]: { id: end, index: end, x: 200, y: 0 }
142
+ }
143
+ }
144
+ });
145
+ }
146
+ });
147
+ trackEvent("drag-tool", { source, id: "line" });
107
148
  }
108
149
  },
109
150
  {
@@ -114,6 +155,12 @@ function ToolsProvider({ overrides, children }) {
114
155
  onSelect(source) {
115
156
  editor.setCurrentTool("frame");
116
157
  onToolSelect(source, this);
158
+ },
159
+ onDragStart(source, info) {
160
+ onDragFromToolbarToCreateShape(editor, info, {
161
+ createShape: (id) => editor.createShape({ id, type: "frame" })
162
+ });
163
+ trackEvent("drag-tool", { source, id: "frame" });
117
164
  }
118
165
  },
119
166
  {
@@ -124,6 +171,16 @@ function ToolsProvider({ overrides, children }) {
124
171
  onSelect(source) {
125
172
  editor.setCurrentTool("text");
126
173
  onToolSelect(source, this);
174
+ },
175
+ onDragStart(source, info) {
176
+ onDragFromToolbarToCreateShape(editor, info, {
177
+ createShape: (id) => editor.createShape({ id, type: "text", props: { richText: toRichText("Text") } }),
178
+ onDragEnd: (id) => {
179
+ editor.setEditingShape(id);
180
+ editor.emit("select-all-text", { shapeId: id });
181
+ }
182
+ });
183
+ trackEvent("drag-tool", { source, id: "text" });
127
184
  }
128
185
  },
129
186
  {
@@ -144,6 +201,16 @@ function ToolsProvider({ overrides, children }) {
144
201
  onSelect(source) {
145
202
  editor.setCurrentTool("note");
146
203
  onToolSelect(source, this);
204
+ },
205
+ onDragStart(source, info) {
206
+ onDragFromToolbarToCreateShape(editor, info, {
207
+ createShape: (id) => editor.createShape({ id, type: "note" }),
208
+ onDragEnd: (id) => {
209
+ editor.setEditingShape(id);
210
+ editor.emit("select-all-text", { shapeId: id });
211
+ }
212
+ });
213
+ trackEvent("drag-tool", { source, id: "note" });
147
214
  }
148
215
  },
149
216
  {
@@ -184,7 +251,7 @@ function ToolsProvider({ overrides, children }) {
184
251
  return overrides(editor, tools2, helpers);
185
252
  }
186
253
  return tools2;
187
- }, [overrides, editor, helpers, onToolSelect]);
254
+ }, [overrides, editor, helpers, onToolSelect, trackEvent]);
188
255
  return /* @__PURE__ */ jsx(ToolsContext.Provider, { value: tools, children });
189
256
  }
190
257
  function useTools() {
@@ -194,9 +261,34 @@ function useTools() {
194
261
  }
195
262
  return ctx;
196
263
  }
264
+ function onDragFromToolbarToCreateShape(editor, info, opts) {
265
+ const { x, y } = editor.inputs.currentPagePoint;
266
+ const stoppingPoint = editor.markHistoryStoppingPoint("drag shape tool");
267
+ editor.setCurrentTool("select.translating");
268
+ const id = createShapeId();
269
+ opts.createShape(id);
270
+ const shape = assertExists(editor.getShape(id), "Shape not found");
271
+ const { w, h } = editor.getShapePageBounds(id);
272
+ editor.updateShape({ id, type: shape.type, x: x - w / 2, y: y - h / 2 });
273
+ editor.select(id);
274
+ editor.setCurrentTool("select.translating", {
275
+ ...info,
276
+ target: "shape",
277
+ shape: editor.getShape(id),
278
+ isCreating: true,
279
+ creatingMarkId: stoppingPoint,
280
+ onCreate() {
281
+ editor.setCurrentTool("select.idle");
282
+ editor.select(id);
283
+ opts.onDragEnd?.(id);
284
+ }
285
+ });
286
+ editor.getCurrentTool().setCurrentToolIdMask(shape.type);
287
+ }
197
288
  export {
198
289
  ToolsContext,
199
290
  ToolsProvider,
291
+ onDragFromToolbarToCreateShape,
200
292
  useTools
201
293
  };
202
294
  //# sourceMappingURL=useTools.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/ui/hooks/useTools.tsx"],
4
- "sourcesContent": ["import { Editor, GeoShapeGeoStyle, useMaybeEditor } from '@tldraw/editor'\nimport * as React from 'react'\nimport { EmbedDialog } from '../components/EmbedDialog'\nimport { useA11y } from '../context/a11y'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { TLUiIconType } from '../icon-types'\nimport { TLUiOverrideHelpers, useDefaultHelpers } from '../overrides'\nimport { TLUiTranslationKey } from './useTranslation/TLUiTranslationKey'\nimport { useTranslation } from './useTranslation/useTranslation'\n\n/** @public */\nexport interface TLUiToolItem<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n> {\n\tid: string\n\tlabel: TranslationKey\n\tshortcutsLabel?: TranslationKey\n\ticon: IconType\n\tonSelect(source: TLUiEventSource): void\n\t/**\n\t * The keyboard shortcut for this tool. This is a string that can be a single key,\n\t * or a combination of keys.\n\t * For example, `cmd+z` or `cmd+shift+z` or `cmd+u,ctrl+u`, or just `v` or `a`.\n\t * We have backwards compatibility with the old system, where we used to use\n\t * symbols to denote cmd/alt/shift, using `!` for shift, `$` for cmd, and `?` for alt.\n\t */\n\tkbd?: string\n\treadonlyOk?: boolean\n\tmeta?: {\n\t\t[key: string]: any\n\t}\n}\n\n/** @public */\nexport type TLUiToolsContextType = Record<string, TLUiToolItem>\n\n/** @internal */\nexport const ToolsContext = React.createContext<null | TLUiToolsContextType>(null)\n\n/** @public */\nexport interface TLUiToolsProviderProps {\n\toverrides?(\n\t\teditor: Editor,\n\t\ttools: TLUiToolsContextType,\n\t\thelpers: Partial<TLUiOverrideHelpers>\n\t): TLUiToolsContextType\n\tchildren: React.ReactNode\n}\n\n/** @internal */\nexport function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {\n\tconst editor = useMaybeEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst a11y = useA11y()\n\tconst msg = useTranslation()\n\tconst helpers = useDefaultHelpers()\n\n\tconst onToolSelect = React.useCallback(\n\t\t(\n\t\t\tsource: TLUiEventSource,\n\t\t\ttool: TLUiToolItem<TLUiTranslationKey, TLUiIconType>,\n\t\t\tid?: string\n\t\t) => {\n\t\t\ta11y.announce({ msg: msg(tool.label) })\n\t\t\ttrackEvent('select-tool', { source, id: id ?? tool.id })\n\t\t},\n\t\t[a11y, msg, trackEvent]\n\t)\n\n\tconst tools = React.useMemo<TLUiToolsContextType>(() => {\n\t\tif (!editor) return {}\n\t\tconst toolsArray: TLUiToolItem<TLUiTranslationKey, TLUiIconType>[] = [\n\t\t\t{\n\t\t\t\tid: 'select',\n\t\t\t\tlabel: 'tool.select',\n\t\t\t\ticon: 'tool-pointer',\n\t\t\t\tkbd: 'v',\n\t\t\t\treadonlyOk: true,\n\t\t\t\tonSelect(source) {\n\t\t\t\t\tif (editor.isIn('select')) {\n\t\t\t\t\t\t// There's a quirk of select mode, where editing a shape is a sub-state of select.\n\t\t\t\t\t\t// Because the text tool can be locked/sticky, we need to make sure we exit the\n\t\t\t\t\t\t// text tool.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// psst, if you're changing this code, also change the code\n\t\t\t\t\t\t// in strange-tools.test.ts! Sadly it's duplicated there.\n\t\t\t\t\t\tconst currentNode = editor.root.getCurrent()!\n\t\t\t\t\t\tcurrentNode.exit({}, currentNode.id)\n\t\t\t\t\t\tcurrentNode.enter({}, currentNode.id)\n\t\t\t\t\t}\n\t\t\t\t\teditor.setCurrentTool('select')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'hand',\n\t\t\t\tlabel: 'tool.hand',\n\t\t\t\ticon: 'tool-hand',\n\t\t\t\tkbd: 'h',\n\t\t\t\treadonlyOk: true,\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('hand')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'eraser',\n\t\t\t\tlabel: 'tool.eraser',\n\t\t\t\ticon: 'tool-eraser',\n\t\t\t\tkbd: 'e',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('eraser')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'draw',\n\t\t\t\tlabel: 'tool.draw',\n\t\t\t\ticon: 'tool-pencil',\n\t\t\t\tkbd: 'd,b,x',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('draw')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t...[...GeoShapeGeoStyle.values].map((id) => ({\n\t\t\t\tid,\n\t\t\t\tlabel: `tool.${id}` as TLUiTranslationKey,\n\t\t\t\tmeta: {\n\t\t\t\t\tgeo: id,\n\t\t\t\t},\n\t\t\t\tkbd: id === 'rectangle' ? 'r' : id === 'ellipse' ? 'o' : undefined,\n\t\t\t\ticon: ('geo-' + id) as TLUiIconType,\n\t\t\t\tonSelect(source: TLUiEventSource) {\n\t\t\t\t\teditor.run(() => {\n\t\t\t\t\t\teditor.setStyleForNextShapes(GeoShapeGeoStyle, id)\n\t\t\t\t\t\teditor.setCurrentTool('geo')\n\t\t\t\t\t\tonToolSelect(source, this, `geo-${id}`)\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t})),\n\t\t\t{\n\t\t\t\tid: 'arrow',\n\t\t\t\tlabel: 'tool.arrow',\n\t\t\t\ticon: 'tool-arrow',\n\t\t\t\tkbd: 'a',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('arrow')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'line',\n\t\t\t\tlabel: 'tool.line',\n\t\t\t\ticon: 'tool-line',\n\t\t\t\tkbd: 'l',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('line')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'frame',\n\t\t\t\tlabel: 'tool.frame',\n\t\t\t\ticon: 'tool-frame',\n\t\t\t\tkbd: 'f',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('frame')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'text',\n\t\t\t\tlabel: 'tool.text',\n\t\t\t\ticon: 'tool-text',\n\t\t\t\tkbd: 't',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('text')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'asset',\n\t\t\t\tlabel: 'tool.media',\n\t\t\t\ticon: 'tool-media',\n\t\t\t\tkbd: 'cmd+u,ctrl+u',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\thelpers.insertMedia()\n\t\t\t\t\tonToolSelect(source, this, 'media')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'note',\n\t\t\t\tlabel: 'tool.note',\n\t\t\t\ticon: 'tool-note',\n\t\t\t\tkbd: 'n',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('note')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'laser',\n\t\t\t\tlabel: 'tool.laser',\n\t\t\t\treadonlyOk: true,\n\t\t\t\ticon: 'tool-laser',\n\t\t\t\tkbd: 'k',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('laser')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'embed',\n\t\t\t\tlabel: 'tool.embed',\n\t\t\t\ticon: 'dot',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\thelpers.addDialog({ component: EmbedDialog })\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'highlight',\n\t\t\t\tlabel: 'tool.highlight',\n\t\t\t\ticon: 'tool-highlight',\n\t\t\t\t// TODO: pick a better shortcut\n\t\t\t\tkbd: 'shift+d',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('highlight')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t]\n\n\t\ttoolsArray.forEach((t) => (t.onSelect = t.onSelect.bind(t)))\n\n\t\tconst tools = Object.fromEntries(toolsArray.map((t) => [t.id, t]))\n\n\t\tif (overrides) {\n\t\t\treturn overrides(editor, tools, helpers)\n\t\t}\n\n\t\treturn tools\n\t}, [overrides, editor, helpers, onToolSelect])\n\n\treturn <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>\n}\n\n/** @public */\nexport function useTools() {\n\tconst ctx = React.useContext(ToolsContext)\n\n\tif (!ctx) {\n\t\tthrow new Error('useTools must be used within a ToolProvider')\n\t}\n\n\treturn ctx\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tassertExists,\n\tcreateShapeId,\n\tEditor,\n\tGeoShapeGeoStyle,\n\tgetIndicesBetween,\n\tTLLineShape,\n\tTLPointerEventInfo,\n\tTLShapeId,\n\ttoRichText,\n\tuseMaybeEditor,\n} from '@tldraw/editor'\nimport * as React from 'react'\nimport { EmbedDialog } from '../components/EmbedDialog'\nimport { TLUiIconJsx } from '../components/primitives/TldrawUiIcon'\nimport { useA11y } from '../context/a11y'\nimport { TLUiEventSource, useUiEvents } from '../context/events'\nimport { TLUiIconType } from '../icon-types'\nimport { TLUiOverrideHelpers, useDefaultHelpers } from '../overrides'\nimport { TLUiTranslationKey } from './useTranslation/TLUiTranslationKey'\nimport { useTranslation } from './useTranslation/useTranslation'\n\n/** @public */\nexport interface TLUiToolItem<\n\tTranslationKey extends string = string,\n\tIconType extends string = string,\n> {\n\tid: string\n\tlabel: TranslationKey\n\tshortcutsLabel?: TranslationKey\n\ticon: IconType | TLUiIconJsx\n\tonSelect(source: TLUiEventSource): void\n\tonDragStart?(source: TLUiEventSource, info: TLPointerEventInfo): void\n\t/**\n\t * The keyboard shortcut for this tool. This is a string that can be a single key,\n\t * or a combination of keys.\n\t * For example, `cmd+z` or `cmd+shift+z` or `cmd+u,ctrl+u`, or just `v` or `a`.\n\t * We have backwards compatibility with the old system, where we used to use\n\t * symbols to denote cmd/alt/shift, using `!` for shift, `$` for cmd, and `?` for alt.\n\t */\n\tkbd?: string\n\treadonlyOk?: boolean\n\tmeta?: {\n\t\t[key: string]: any\n\t}\n}\n\n/** @public */\nexport type TLUiToolsContextType = Record<string, TLUiToolItem>\n\n/** @internal */\nexport const ToolsContext = React.createContext<null | TLUiToolsContextType>(null)\n\n/** @public */\nexport interface TLUiToolsProviderProps {\n\toverrides?(\n\t\teditor: Editor,\n\t\ttools: TLUiToolsContextType,\n\t\thelpers: Partial<TLUiOverrideHelpers>\n\t): TLUiToolsContextType\n\tchildren: React.ReactNode\n}\n\n/** @internal */\nexport function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {\n\tconst editor = useMaybeEditor()\n\tconst trackEvent = useUiEvents()\n\n\tconst a11y = useA11y()\n\tconst msg = useTranslation()\n\tconst helpers = useDefaultHelpers()\n\n\tconst onToolSelect = React.useCallback(\n\t\t(\n\t\t\tsource: TLUiEventSource,\n\t\t\ttool: TLUiToolItem<TLUiTranslationKey, TLUiIconType>,\n\t\t\tid?: string\n\t\t) => {\n\t\t\ta11y.announce({ msg: msg(tool.label) })\n\t\t\ttrackEvent('select-tool', { source, id: id ?? tool.id })\n\t\t},\n\t\t[a11y, msg, trackEvent]\n\t)\n\n\tconst tools = React.useMemo<TLUiToolsContextType>(() => {\n\t\tif (!editor) return {}\n\t\tconst toolsArray: TLUiToolItem<TLUiTranslationKey, TLUiIconType>[] = [\n\t\t\t{\n\t\t\t\tid: 'select',\n\t\t\t\tlabel: 'tool.select',\n\t\t\t\ticon: 'tool-pointer',\n\t\t\t\tkbd: 'v',\n\t\t\t\treadonlyOk: true,\n\t\t\t\tonSelect(source) {\n\t\t\t\t\tif (editor.isIn('select')) {\n\t\t\t\t\t\t// There's a quirk of select mode, where editing a shape is a sub-state of select.\n\t\t\t\t\t\t// Because the text tool can be locked/sticky, we need to make sure we exit the\n\t\t\t\t\t\t// text tool.\n\t\t\t\t\t\t//\n\t\t\t\t\t\t// psst, if you're changing this code, also change the code\n\t\t\t\t\t\t// in strange-tools.test.ts! Sadly it's duplicated there.\n\t\t\t\t\t\tconst currentNode = editor.root.getCurrent()!\n\t\t\t\t\t\tcurrentNode.exit({}, currentNode.id)\n\t\t\t\t\t\tcurrentNode.enter({}, currentNode.id)\n\t\t\t\t\t}\n\t\t\t\t\teditor.setCurrentTool('select')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'hand',\n\t\t\t\tlabel: 'tool.hand',\n\t\t\t\ticon: 'tool-hand',\n\t\t\t\tkbd: 'h',\n\t\t\t\treadonlyOk: true,\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('hand')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'eraser',\n\t\t\t\tlabel: 'tool.eraser',\n\t\t\t\ticon: 'tool-eraser',\n\t\t\t\tkbd: 'e',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('eraser')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'draw',\n\t\t\t\tlabel: 'tool.draw',\n\t\t\t\ticon: 'tool-pencil',\n\t\t\t\tkbd: 'd,b,x',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('draw')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t...[...GeoShapeGeoStyle.values].map((geo) => ({\n\t\t\t\tid: geo,\n\t\t\t\tlabel: `tool.${geo}` as TLUiTranslationKey,\n\t\t\t\tmeta: {\n\t\t\t\t\tgeo,\n\t\t\t\t},\n\t\t\t\tkbd: geo === 'rectangle' ? 'r' : geo === 'ellipse' ? 'o' : undefined,\n\t\t\t\ticon: ('geo-' + geo) as TLUiIconType,\n\t\t\t\tonSelect(source: TLUiEventSource) {\n\t\t\t\t\teditor.run(() => {\n\t\t\t\t\t\teditor.setStyleForNextShapes(GeoShapeGeoStyle, geo)\n\t\t\t\t\t\teditor.setCurrentTool('geo')\n\t\t\t\t\t\tonToolSelect(source, this, `geo-${geo}`)\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t\tonDragStart(source: TLUiEventSource, info: TLPointerEventInfo) {\n\t\t\t\t\tonDragFromToolbarToCreateShape(editor, info, {\n\t\t\t\t\t\tcreateShape: (id) =>\n\t\t\t\t\t\t\teditor.createShape({ id, type: 'geo', props: { w: 200, h: 200, geo } }),\n\t\t\t\t\t})\n\t\t\t\t\ttrackEvent('drag-tool', { source, id: 'geo' })\n\t\t\t\t},\n\t\t\t})),\n\t\t\t{\n\t\t\t\tid: 'arrow',\n\t\t\t\tlabel: 'tool.arrow',\n\t\t\t\ticon: 'tool-arrow',\n\t\t\t\tkbd: 'a',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('arrow')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t\tonDragStart(source: TLUiEventSource, info: TLPointerEventInfo) {\n\t\t\t\t\tonDragFromToolbarToCreateShape(editor, info, {\n\t\t\t\t\t\tcreateShape: (id) =>\n\t\t\t\t\t\t\teditor.createShape({\n\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\ttype: 'arrow',\n\t\t\t\t\t\t\t\tprops: { start: { x: 0, y: 0 }, end: { x: 200, y: 0 } },\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t})\n\t\t\t\t\ttrackEvent('drag-tool', { source, id: 'arrow' })\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'line',\n\t\t\t\tlabel: 'tool.line',\n\t\t\t\ticon: 'tool-line',\n\t\t\t\tkbd: 'l',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('line')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t\tonDragStart(source, info) {\n\t\t\t\t\tonDragFromToolbarToCreateShape(editor, info, {\n\t\t\t\t\t\tcreateShape: (id) => {\n\t\t\t\t\t\t\tconst [start, end] = getIndicesBetween(null, null, 2)\n\t\t\t\t\t\t\teditor.createShape<TLLineShape>({\n\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\ttype: 'line',\n\t\t\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\t\t\tpoints: {\n\t\t\t\t\t\t\t\t\t\t[start]: { id: start, index: start, x: 0, y: 200 },\n\t\t\t\t\t\t\t\t\t\t[end]: { id: end, index: end, x: 200, y: 0 },\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\ttrackEvent('drag-tool', { source, id: 'line' })\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'frame',\n\t\t\t\tlabel: 'tool.frame',\n\t\t\t\ticon: 'tool-frame',\n\t\t\t\tkbd: 'f',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('frame')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t\tonDragStart(source, info) {\n\t\t\t\t\tonDragFromToolbarToCreateShape(editor, info, {\n\t\t\t\t\t\tcreateShape: (id) => editor.createShape({ id, type: 'frame' }),\n\t\t\t\t\t})\n\t\t\t\t\ttrackEvent('drag-tool', { source, id: 'frame' })\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'text',\n\t\t\t\tlabel: 'tool.text',\n\t\t\t\ticon: 'tool-text',\n\t\t\t\tkbd: 't',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('text')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t\tonDragStart(source, info) {\n\t\t\t\t\tonDragFromToolbarToCreateShape(editor, info, {\n\t\t\t\t\t\tcreateShape: (id) =>\n\t\t\t\t\t\t\teditor.createShape({ id, type: 'text', props: { richText: toRichText('Text') } }),\n\t\t\t\t\t\tonDragEnd: (id) => {\n\t\t\t\t\t\t\teditor.setEditingShape(id)\n\t\t\t\t\t\t\teditor.emit('select-all-text', { shapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\ttrackEvent('drag-tool', { source, id: 'text' })\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'asset',\n\t\t\t\tlabel: 'tool.media',\n\t\t\t\ticon: 'tool-media',\n\t\t\t\tkbd: 'cmd+u,ctrl+u',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\thelpers.insertMedia()\n\t\t\t\t\tonToolSelect(source, this, 'media')\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'note',\n\t\t\t\tlabel: 'tool.note',\n\t\t\t\ticon: 'tool-note',\n\t\t\t\tkbd: 'n',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('note')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t\tonDragStart(source, info) {\n\t\t\t\t\tonDragFromToolbarToCreateShape(editor, info, {\n\t\t\t\t\t\tcreateShape: (id) => editor.createShape({ id, type: 'note' }),\n\t\t\t\t\t\tonDragEnd: (id) => {\n\t\t\t\t\t\t\teditor.setEditingShape(id)\n\t\t\t\t\t\t\teditor.emit('select-all-text', { shapeId: id })\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\ttrackEvent('drag-tool', { source, id: 'note' })\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'laser',\n\t\t\t\tlabel: 'tool.laser',\n\t\t\t\treadonlyOk: true,\n\t\t\t\ticon: 'tool-laser',\n\t\t\t\tkbd: 'k',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('laser')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'embed',\n\t\t\t\tlabel: 'tool.embed',\n\t\t\t\ticon: 'dot',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\thelpers.addDialog({ component: EmbedDialog })\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'highlight',\n\t\t\t\tlabel: 'tool.highlight',\n\t\t\t\ticon: 'tool-highlight',\n\t\t\t\t// TODO: pick a better shortcut\n\t\t\t\tkbd: 'shift+d',\n\t\t\t\tonSelect(source) {\n\t\t\t\t\teditor.setCurrentTool('highlight')\n\t\t\t\t\tonToolSelect(source, this)\n\t\t\t\t},\n\t\t\t},\n\t\t]\n\n\t\ttoolsArray.forEach((t) => (t.onSelect = t.onSelect.bind(t)))\n\n\t\tconst tools = Object.fromEntries(toolsArray.map((t) => [t.id, t]))\n\n\t\tif (overrides) {\n\t\t\treturn overrides(editor, tools, helpers)\n\t\t}\n\n\t\treturn tools\n\t}, [overrides, editor, helpers, onToolSelect, trackEvent])\n\n\treturn <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>\n}\n\n/** @public */\nexport function useTools() {\n\tconst ctx = React.useContext(ToolsContext)\n\n\tif (!ctx) {\n\t\tthrow new Error('useTools must be used within a ToolProvider')\n\t}\n\n\treturn ctx\n}\n\n/**\n * Options for {@link onDragFromToolbarToCreateShape}.\n * @public\n */\nexport interface OnDragFromToolbarToCreateShapesOpts {\n\t/**\n\t * Create the shape being dragged. You don't need to worry about positioning it, as it'll be\n\t * immediately updated with the correct position.\n\t */\n\tcreateShape(id: TLShapeId): void\n\t/**\n\t * Called once the drag interaction has finished.\n\t */\n\tonDragEnd?(id: TLShapeId): void\n}\n\n/**\n * A helper method to use in {@link TLUiToolItem#onDragStart} to create a shape by dragging it from\n * the toolbar.\n * @public\n */\nexport function onDragFromToolbarToCreateShape(\n\teditor: Editor,\n\tinfo: TLPointerEventInfo,\n\topts: OnDragFromToolbarToCreateShapesOpts\n) {\n\tconst { x, y } = editor.inputs.currentPagePoint\n\n\tconst stoppingPoint = editor.markHistoryStoppingPoint('drag shape tool')\n\teditor.setCurrentTool('select.translating')\n\n\tconst id = createShapeId()\n\topts.createShape(id)\n\tconst shape = assertExists(editor.getShape(id), 'Shape not found')\n\n\tconst { w, h } = editor.getShapePageBounds(id)!\n\teditor.updateShape({ id, type: shape.type, x: x - w / 2, y: y - h / 2 })\n\teditor.select(id)\n\n\teditor.setCurrentTool('select.translating', {\n\t\t...info,\n\t\ttarget: 'shape',\n\t\tshape: editor.getShape(id),\n\t\tisCreating: true,\n\t\tcreatingMarkId: stoppingPoint,\n\t\tonCreate() {\n\t\t\teditor.setCurrentTool('select.idle')\n\t\t\teditor.select(id)\n\t\t\topts.onDragEnd?.(id)\n\t\t},\n\t})\n\n\teditor.getCurrentTool().setCurrentToolIdMask(shape.type)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["tools"]
7
7
  }
@@ -51,6 +51,7 @@ const DEFAULT_TRANSLATION = {
51
51
  "action.new-project": "New project",
52
52
  "action.new-shared-project": "New shared project",
53
53
  "action.open-cursor-chat": "Cursor chat",
54
+ "action.open-kbd-shortcuts": "Open keyboard shortcuts",
54
55
  "action.open-file": "Open file",
55
56
  "action.pack": "Pack",
56
57
  "action.paste": "Paste",
@@ -86,6 +87,10 @@ const DEFAULT_TRANSLATION = {
86
87
  "action.toggle-wrap-mode": "Toggle Select on wrap",
87
88
  "action.toggle-reduce-motion.menu": "Reduce motion",
88
89
  "action.toggle-reduce-motion": "Toggle reduce motion",
90
+ "action.toggle-keyboard-shortcuts.menu": "Keyboard shortcuts",
91
+ "action.toggle-keyboard-shortcuts": "Toggle keyboard shortcuts",
92
+ "action.toggle-ui-labels.menu": "UI labels",
93
+ "action.toggle-ui-labels": "Toggle UI labels",
89
94
  "action.toggle-edge-scrolling.menu": "Edge scrolling",
90
95
  "action.toggle-edge-scrolling": "Toggle edge scrolling",
91
96
  "action.toggle-debug-mode.menu": "Debug mode",
@@ -177,6 +182,7 @@ const DEFAULT_TRANSLATION = {
177
182
  "geo-style.pentagon": "Pentagon",
178
183
  "geo-style.rectangle": "Rectangle",
179
184
  "geo-style.rhombus": "Rhombus",
185
+ "geo-style.rhombus-2": "Rhombus left",
180
186
  "geo-style.star": "Star",
181
187
  "geo-style.trapezoid": "Trapezoid",
182
188
  "geo-style.triangle": "Triangle",
@@ -279,13 +285,19 @@ const DEFAULT_TRANSLATION = {
279
285
  "a11y.repeat-shape": "Repeat shape",
280
286
  "a11y.move-shape": "Move shape",
281
287
  "a11y.move-shape-faster": "Move shape faster",
288
+ "a11y.rotate-shape-cw": "Rotate shape clockwise",
289
+ "a11y.rotate-shape-ccw": "Rotate shape counterclockwise",
290
+ "a11y.rotate-shape-cw-fine": "Rotate shape clockwise (fine)",
291
+ "a11y.rotate-shape-ccw-fine": "Rotate shape counterclockwise (fine)",
282
292
  "a11y.enlarge-shape": "Enlarge shape",
283
293
  "a11y.shrink-shape": "Shrink shape",
284
294
  "a11y.pan-camera": "Pan camera",
285
295
  "a11y.adjust-shape-styles": "Adjust shape styles",
286
296
  "a11y.open-context-menu": "Open context menu",
297
+ "a11y.open-keyboard-shortcuts": "Open keyboard shortcuts",
287
298
  "menu.title": "Menu",
288
299
  "menu.theme": "Theme",
300
+ "menu.accessibility": "Accessibility",
289
301
  "menu.copy-as": "Copy as",
290
302
  "menu.edit": "Edit",
291
303
  "menu.export-as": "Export as",