tldraw 3.16.0-canary.b802b60e813f → 3.16.0-canary.ba3bc37d4418

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 (285) hide show
  1. package/dist-cjs/index.d.ts +149 -107
  2. package/dist-cjs/index.js +28 -14
  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/defaultExternalContentHandlers.js +10 -0
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  9. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  10. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
  11. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +8 -1
  13. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +2 -2
  15. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  16. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -0
  17. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -0
  19. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  20. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +2 -1
  21. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  22. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
  23. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  24. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  25. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  26. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -4
  27. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  28. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  29. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  30. package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -2
  31. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  32. package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
  33. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  34. package/dist-cjs/lib/ui/TldrawUi.js +13 -12
  35. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  36. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  37. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  38. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  39. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  40. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +5 -5
  41. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  42. package/dist-cjs/lib/ui/components/LanguageMenu.js +1 -0
  43. package/dist-cjs/lib/ui/components/LanguageMenu.js.map +2 -2
  44. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -0
  45. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  46. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
  47. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  48. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  49. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  50. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  51. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  52. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +147 -0
  53. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  54. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  55. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  56. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  57. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  58. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +23 -20
  59. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  60. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  61. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  62. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +4 -2
  63. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  64. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
  65. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  66. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  67. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  68. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +5 -4
  69. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  70. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +11 -2
  71. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
  73. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  74. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
  75. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  76. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +3 -0
  77. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  78. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +44 -1
  79. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  80. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +3 -0
  81. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  82. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +5 -5
  83. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +1 -1
  84. package/dist-cjs/lib/ui/context/actions.js +13 -8
  85. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  86. package/dist-cjs/lib/ui/context/components.js +2 -0
  87. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  88. package/dist-cjs/lib/ui/context/events.js.map +1 -1
  89. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  90. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  91. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  92. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  93. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  94. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  95. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  96. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +6 -2
  97. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  98. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  99. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  100. package/dist-cjs/lib/ui/version.js +3 -3
  101. package/dist-cjs/lib/ui/version.js.map +1 -1
  102. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  103. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  104. package/dist-cjs/lib/utils/export/export.js +0 -20
  105. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  106. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  107. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  108. package/dist-esm/index.d.mts +149 -107
  109. package/dist-esm/index.mjs +55 -29
  110. package/dist-esm/index.mjs.map +2 -2
  111. package/dist-esm/lib/Tldraw.mjs +14 -4
  112. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  113. package/dist-esm/lib/defaultExternalContentHandlers.mjs +10 -0
  114. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  115. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  116. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  117. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +5 -5
  118. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  119. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +8 -1
  120. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  121. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +3 -3
  122. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  123. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
  124. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  125. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -0
  126. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  127. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
  128. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  129. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
  130. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  131. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  132. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +4 -5
  134. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  135. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  136. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  137. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -3
  138. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  139. package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
  140. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  141. package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
  142. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  143. package/dist-esm/lib/ui/components/A11y.mjs +2 -2
  144. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  145. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  146. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  147. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +5 -5
  148. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  149. package/dist-esm/lib/ui/components/LanguageMenu.mjs +1 -0
  150. package/dist-esm/lib/ui/components/LanguageMenu.mjs.map +2 -2
  151. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -0
  152. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  153. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -2
  154. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  155. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  156. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  157. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  158. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  159. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +135 -0
  160. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  161. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  162. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  163. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  164. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  165. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +20 -17
  166. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  167. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  168. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  169. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +4 -2
  170. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  171. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
  172. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  173. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  174. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  175. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +5 -4
  176. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  177. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +12 -3
  178. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  179. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +3 -3
  180. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  181. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
  182. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  183. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +3 -0
  184. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  185. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +45 -1
  186. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  187. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +3 -0
  188. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  189. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +5 -5
  190. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +1 -1
  191. package/dist-esm/lib/ui/context/actions.mjs +13 -8
  192. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  193. package/dist-esm/lib/ui/context/components.mjs +2 -0
  194. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  195. package/dist-esm/lib/ui/context/events.mjs.map +1 -1
  196. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  197. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  198. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  199. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  200. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  201. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  202. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +6 -2
  203. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  204. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  205. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  206. package/dist-esm/lib/ui/version.mjs +3 -3
  207. package/dist-esm/lib/ui/version.mjs.map +1 -1
  208. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  209. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  210. package/dist-esm/lib/utils/export/export.mjs +0 -20
  211. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  212. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  213. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  214. package/package.json +3 -3
  215. package/src/index.ts +40 -22
  216. package/src/lib/Tldraw.tsx +15 -2
  217. package/src/lib/defaultExternalContentHandlers.ts +14 -0
  218. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +2 -2
  219. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +41 -0
  220. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  221. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +5 -5
  222. package/src/lib/shapes/frame/FrameShapeUtil.tsx +9 -0
  223. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +3 -3
  224. package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
  225. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -0
  226. package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
  227. package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
  228. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  229. package/src/lib/shapes/shared/useEditablePlainText.ts +5 -9
  230. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  231. package/src/lib/shapes/text/PlainTextArea.tsx +3 -3
  232. package/src/lib/shapes/text/RichTextArea.tsx +3 -4
  233. package/src/lib/ui/TldrawUi.tsx +16 -10
  234. package/src/lib/ui/components/A11y.tsx +2 -2
  235. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  236. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +5 -5
  237. package/src/lib/ui/components/LanguageMenu.tsx +1 -0
  238. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -0
  239. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +2 -2
  240. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  241. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  242. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +70 -50
  243. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  244. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  245. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  246. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  247. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +5 -3
  248. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
  249. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  250. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +6 -5
  251. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +8 -3
  252. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +3 -3
  253. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
  254. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +5 -1
  255. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +64 -11
  256. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +4 -0
  257. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +6 -6
  258. package/src/lib/ui/context/actions.tsx +20 -8
  259. package/src/lib/ui/context/components.tsx +3 -0
  260. package/src/lib/ui/context/events.tsx +1 -1
  261. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  262. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  263. package/src/lib/ui/hooks/useTools.tsx +1 -1
  264. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +4 -0
  265. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +6 -2
  266. package/src/lib/ui/kbd-utils.ts +10 -3
  267. package/src/lib/ui/version.ts +3 -3
  268. package/src/lib/ui.css +26 -2
  269. package/src/lib/utils/export/copyAs.ts +1 -24
  270. package/src/lib/utils/export/export.ts +0 -36
  271. package/src/lib/utils/export/exportAs.ts +1 -32
  272. package/src/test/custom-clipping.test.ts +436 -0
  273. package/src/test/getCulledShapes.test.tsx +71 -2
  274. package/tldraw.css +42 -5
  275. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  276. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  277. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  278. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +0 -131
  279. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  280. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  281. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  282. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  283. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -115
  284. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  285. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -3,8 +3,8 @@ import {
3
3
  Box,
4
4
  clamp,
5
5
  Editor,
6
+ markEventAsHandled,
6
7
  react,
7
- stopEventPropagation,
8
8
  useAtom,
9
9
  useEditor,
10
10
  usePassThroughMouseOverEvents,
@@ -170,9 +170,14 @@ export const TldrawUiContextualToolbar = ({
170
170
  data-visible={false}
171
171
  data-testid="contextual-toolbar"
172
172
  className={classNames('tlui-contextual-toolbar', className)}
173
- onPointerDown={stopEventPropagation}
173
+ onPointerDown={markEventAsHandled}
174
174
  >
175
- <TldrawUiToolbar orientation="horizontal" className="tlui-menu" label={label}>
175
+ <TldrawUiToolbar
176
+ orientation="horizontal"
177
+ className="tlui-menu"
178
+ label={label}
179
+ tooltipSide="top"
180
+ >
176
181
  {children}
177
182
  </TldrawUiToolbar>
178
183
  </div>
@@ -1,4 +1,4 @@
1
- import { stopEventPropagation, tlenv, tltime, useMaybeEditor } from '@tldraw/editor'
1
+ import { tlenv, tltime, useMaybeEditor } from '@tldraw/editor'
2
2
  import classNames from 'classnames'
3
3
  import * as React from 'react'
4
4
  import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
@@ -118,7 +118,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
118
118
  // `onChange` with a duplicated text value.
119
119
  if (isComposing.current) return
120
120
  e.currentTarget.blur()
121
- stopEventPropagation(e)
121
+ e.stopPropagation()
122
122
  onComplete?.(e.currentTarget.value)
123
123
  break
124
124
  }
@@ -126,7 +126,7 @@ export const TldrawUiInput = React.forwardRef<HTMLInputElement, TLUiInputProps>(
126
126
  e.currentTarget.value = rInitialValue.current
127
127
  onCancel?.(e.currentTarget.value)
128
128
  e.currentTarget.blur()
129
- stopEventPropagation(e)
129
+ e.stopPropagation()
130
130
  break
131
131
  }
132
132
  }
@@ -1,7 +1,9 @@
1
+ import { tltime } from '@tldraw/editor'
1
2
  import { Slider as _Slider } from 'radix-ui'
2
3
  import React, { useCallback, useEffect, useState } from 'react'
3
4
  import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
4
5
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
6
+ import { TldrawUiTooltip, tooltipManager } from './TldrawUiTooltip'
5
7
 
6
8
  /** @public */
7
9
  export interface TLUiSliderProps {
@@ -11,7 +13,7 @@ export interface TLUiSliderProps {
11
13
  label: string
12
14
  title: string
13
15
  onValueChange(value: number): void
14
- onHistoryMark(id: string): void
16
+ onHistoryMark?(id: string): void
15
17
  'data-testid'?: string
16
18
  ariaValueModifier?: number
17
19
  }
@@ -32,6 +34,7 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
32
34
  ref
33
35
  ) {
34
36
  const msg = useTranslation()
37
+ const [titleAndLabel, setTitleAndLabel] = useState('')
35
38
 
36
39
  // XXX: Radix starts out our slider with a tabIndex of 0
37
40
  // This causes some tab focusing issues, most prevelant in MobileStylePanel,
@@ -49,9 +52,25 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
49
52
  )
50
53
 
51
54
  const handlePointerDown = useCallback(() => {
52
- onHistoryMark('click slider')
55
+ tooltipManager.hideAllTooltips()
56
+ onHistoryMark?.('click slider')
53
57
  }, [onHistoryMark])
54
58
 
59
+ // N.B. This is a bit silly. The Radix slider auto-focuses which
60
+ // triggers TldrawUiTooltip handleFocus when we dbl-click to edit an image,
61
+ // which in turn makes the tooltip display prematurely.
62
+ // This makes it wait until we've focused to show the tooltip.
63
+ useEffect(() => {
64
+ const timeout = tltime.setTimeout(
65
+ 'set title and label',
66
+ () => {
67
+ setTitleAndLabel(title + ' — ' + msg(label as TLUiTranslationKey))
68
+ },
69
+ 0
70
+ )
71
+ return () => clearTimeout(timeout)
72
+ }, [label, msg, title])
73
+
55
74
  // N.B. Annoying. For a11y purposes, we need Tab to work.
56
75
  // For some reason, Radix has some custom behavior here
57
76
  // that interferes with tabbing past the slider and then
@@ -64,36 +83,37 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
64
83
 
65
84
  return (
66
85
  <div className="tlui-slider__container">
67
- <_Slider.Root
68
- data-testid={testId}
69
- className="tlui-slider"
70
- dir="ltr"
71
- min={min ?? 0}
72
- max={steps}
73
- step={1}
74
- value={value !== null ? [value] : undefined}
75
- onPointerDown={handlePointerDown}
76
- onValueChange={handleValueChange}
77
- onKeyDownCapture={handleKeyEvent}
78
- onKeyUpCapture={handleKeyEvent}
79
- title={title + ' — ' + msg(label as TLUiTranslationKey)}
80
- >
81
- <_Slider.Track className="tlui-slider__track" dir="ltr">
82
- {value !== null && <_Slider.Range className="tlui-slider__range" dir="ltr" />}
83
- </_Slider.Track>
84
- {value !== null && (
85
- <_Slider.Thumb
86
- aria-valuemin={(min ?? 0) * ariaValueModifier}
87
- aria-valuenow={value * ariaValueModifier}
88
- aria-valuemax={steps * ariaValueModifier}
89
- aria-label={title + ' — ' + msg(label as TLUiTranslationKey)}
90
- className="tlui-slider__thumb"
91
- dir="ltr"
92
- ref={ref}
93
- tabIndex={tabIndex}
94
- />
95
- )}
96
- </_Slider.Root>
86
+ <TldrawUiTooltip content={titleAndLabel}>
87
+ <_Slider.Root
88
+ data-testid={testId}
89
+ className="tlui-slider"
90
+ dir="ltr"
91
+ min={min ?? 0}
92
+ max={steps}
93
+ step={1}
94
+ value={value !== null ? [value] : undefined}
95
+ onPointerDown={handlePointerDown}
96
+ onValueChange={handleValueChange}
97
+ onKeyDownCapture={handleKeyEvent}
98
+ onKeyUpCapture={handleKeyEvent}
99
+ >
100
+ <_Slider.Track className="tlui-slider__track" dir="ltr">
101
+ {value !== null && <_Slider.Range className="tlui-slider__range" dir="ltr" />}
102
+ </_Slider.Track>
103
+ {value !== null && (
104
+ <_Slider.Thumb
105
+ aria-valuemin={(min ?? 0) * ariaValueModifier}
106
+ aria-valuenow={value * ariaValueModifier}
107
+ aria-valuemax={steps * ariaValueModifier}
108
+ aria-label={titleAndLabel}
109
+ className="tlui-slider__thumb"
110
+ dir="ltr"
111
+ ref={ref}
112
+ tabIndex={tabIndex}
113
+ />
114
+ )}
115
+ </_Slider.Root>
116
+ </TldrawUiTooltip>
97
117
  </div>
98
118
  )
99
119
  })
@@ -71,6 +71,7 @@ export const TldrawUiToolbarButton = React.forwardRef<HTMLButtonElement, TLUiToo
71
71
  draggable={false}
72
72
  data-isactive={isActive}
73
73
  {...props}
74
+ aria-label={props.title}
74
75
  // The tooltip takes care of this.
75
76
  title={undefined}
76
77
  className={classnames('tlui-button', `tlui-button__${type}`, props.className)}
@@ -94,6 +95,7 @@ export interface TLUiToolbarToggleGroupProps extends React.HTMLAttributes<HTMLDi
94
95
  // TODO: fix up this type later
95
96
  defaultValue?: any
96
97
  type: 'single' | 'multiple'
98
+ asChild?: boolean
97
99
  }
98
100
 
99
101
  /** @public @react */
@@ -101,10 +103,12 @@ export const TldrawUiToolbarToggleGroup = ({
101
103
  children,
102
104
  className,
103
105
  type,
106
+ asChild,
104
107
  ...props
105
108
  }: TLUiToolbarToggleGroupProps) => {
106
109
  return (
107
110
  <_Toolbar.ToggleGroup
111
+ asChild={asChild}
108
112
  type={type}
109
113
  {...props}
110
114
  // TODO: this fixes a bug in Radix until they fix it.
@@ -124,7 +128,7 @@ export interface TLUiToolbarToggleItemProps extends React.HTMLAttributes<HTMLBut
124
128
  className?: string
125
129
  type: 'icon' | 'tool'
126
130
  value: string
127
- tooltip?: string
131
+ tooltip?: React.ReactNode
128
132
  }
129
133
 
130
134
  /** @public @react */
@@ -6,6 +6,7 @@ import React, {
6
6
  ReactNode,
7
7
  useContext,
8
8
  useEffect,
9
+ useLayoutEffect,
9
10
  useRef,
10
11
  useState,
11
12
  } from 'react'
@@ -24,18 +25,20 @@ export interface TldrawUiTooltipProps {
24
25
  delayDuration?: number
25
26
  }
26
27
 
28
+ interface CurrentTooltip {
29
+ id: string
30
+ content: ReactNode
31
+ side: 'top' | 'right' | 'bottom' | 'left'
32
+ sideOffset: number
33
+ showOnMobile: boolean
34
+ targetElement: HTMLElement
35
+ delayDuration: number
36
+ }
37
+
27
38
  // Singleton tooltip manager
28
39
  class TooltipManager {
29
40
  private static instance: TooltipManager | null = null
30
- private currentTooltip = atom<{
31
- id: string
32
- content: ReactNode
33
- side: 'top' | 'right' | 'bottom' | 'left'
34
- sideOffset: number
35
- showOnMobile: boolean
36
- targetElement: HTMLElement
37
- delayDuration: number
38
- } | null>('current tooltip', null)
41
+ private currentTooltip = atom<CurrentTooltip | null>('current tooltip', null)
39
42
  private destroyTimeoutId: number | null = null
40
43
 
41
44
  static getInstance(): TooltipManager {
@@ -72,6 +75,15 @@ class TooltipManager {
72
75
  })
73
76
  }
74
77
 
78
+ updateCurrentTooltip(tooltipId: string, update: (tooltip: CurrentTooltip) => CurrentTooltip) {
79
+ this.currentTooltip.update((tooltip) => {
80
+ if (tooltip?.id === tooltipId) {
81
+ return update(tooltip)
82
+ }
83
+ return tooltip
84
+ })
85
+ }
86
+
75
87
  hideTooltip(editor: Editor | null, tooltipId: string, instant: boolean = false) {
76
88
  const hide = () => {
77
89
  // Only hide if this is the current tooltip
@@ -142,6 +154,7 @@ function TooltipSingleton() {
142
154
  const [isOpen, setIsOpen] = useState(false)
143
155
  const triggerRef = useRef<HTMLDivElement>(null)
144
156
  const isFirstShowRef = useRef(true)
157
+ const editor = useMaybeEditor()
145
158
 
146
159
  const currentTooltip = useValue(
147
160
  'current tooltip',
@@ -149,6 +162,28 @@ function TooltipSingleton() {
149
162
  []
150
163
  )
151
164
 
165
+ const cameraState = useValue('camera state', () => editor?.getCameraState(), [editor])
166
+
167
+ // Hide tooltip when camera is moving (panning/zooming)
168
+ useEffect(() => {
169
+ if (cameraState === 'moving' && isOpen && currentTooltip) {
170
+ tooltipManager.hideTooltip(editor, currentTooltip.id, true)
171
+ }
172
+ }, [cameraState, isOpen, currentTooltip, editor])
173
+
174
+ useEffect(() => {
175
+ function handleKeyDown(event: KeyboardEvent) {
176
+ if (event.key === 'Escape' && currentTooltip) {
177
+ tooltipManager.hideTooltip(editor, currentTooltip.id)
178
+ }
179
+ }
180
+
181
+ document.addEventListener('keydown', handleKeyDown)
182
+ return () => {
183
+ document.removeEventListener('keydown', handleKeyDown)
184
+ }
185
+ }, [editor, currentTooltip])
186
+
152
187
  // Update open state and trigger position
153
188
  useEffect(() => {
154
189
  let timer: ReturnType<typeof setTimeout> | null = null
@@ -231,6 +266,7 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
231
266
  const editor = useMaybeEditor()
232
267
  const tooltipId = useRef<string>(uniqueId())
233
268
  const hasProvider = useContext(TooltipSingletonContext)
269
+ const showUiLabels = useValue('showUiLabels', () => editor?.user.getShowUiLabels(), [editor])
234
270
 
235
271
  const orientationCtx = useTldrawUiOrientation()
236
272
  const sideToUse = side ?? orientationCtx.tooltipSide
@@ -244,13 +280,30 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
244
280
  }
245
281
  }, [editor, hasProvider])
246
282
 
283
+ useLayoutEffect(() => {
284
+ if (hasProvider && tooltipManager.getCurrentTooltipData()?.id === tooltipId.current) {
285
+ tooltipManager.updateCurrentTooltip(tooltipId.current, (tooltip) => ({
286
+ ...tooltip,
287
+ content,
288
+ side: sideToUse,
289
+ sideOffset,
290
+ showOnMobile,
291
+ }))
292
+ }
293
+ }, [content, sideToUse, sideOffset, showOnMobile, hasProvider])
294
+
247
295
  // Don't show tooltip if disabled, no content, or UI labels are disabled
248
296
  if (disabled || !content) {
249
297
  return <>{children}</>
250
298
  }
251
299
 
252
- const delayDurationToUse =
253
- delayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS)
300
+ let delayDurationToUse
301
+ if (showUiLabels) {
302
+ delayDurationToUse = 0
303
+ } else {
304
+ delayDurationToUse =
305
+ delayDuration ?? (editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS)
306
+ }
254
307
 
255
308
  // Fallback to old behavior if no provider
256
309
  if (!hasProvider) {
@@ -19,6 +19,7 @@ export interface TLUiMenuCheckboxItemProps<
19
19
  kbd?: string
20
20
  title?: string
21
21
  label?: TranslationKey | { [key: string]: TranslationKey }
22
+ lang?: string
22
23
  readonlyOk?: boolean
23
24
  onSelect(source: TLUiEventSource): Promise<void> | void
24
25
  toggle?: boolean
@@ -34,6 +35,7 @@ export function TldrawUiMenuCheckboxItem<
34
35
  id,
35
36
  kbd,
36
37
  label,
38
+ lang,
37
39
  readonlyOk,
38
40
  onSelect,
39
41
  toggle = false,
@@ -55,6 +57,7 @@ export function TldrawUiMenuCheckboxItem<
55
57
  return (
56
58
  <_DropdownMenu.CheckboxItem
57
59
  dir="ltr"
60
+ lang={lang}
58
61
  className="tlui-button tlui-button__menu tlui-button__checkbox"
59
62
  title={labelStr}
60
63
  onSelect={(e) => {
@@ -84,6 +87,7 @@ export function TldrawUiMenuCheckboxItem<
84
87
  key={id}
85
88
  className="tlui-button tlui-button__menu tlui-button__checkbox"
86
89
  dir="ltr"
90
+ lang={lang}
87
91
  title={labelStr}
88
92
  onSelect={(e) => {
89
93
  onSelect(sourceId)
@@ -213,7 +213,7 @@ export function TldrawUiMenuItem<
213
213
  icon={icon}
214
214
  onSelect={onSelect}
215
215
  onDragStart={onDragStart}
216
- labelToUse={labelToUse}
216
+ labelStr={labelStr}
217
217
  titleStr={titleStr}
218
218
  disabled={disabled}
219
219
  isSelected={isSelected}
@@ -247,7 +247,7 @@ export function TldrawUiMenuItem<
247
247
  icon={icon}
248
248
  onSelect={onSelect}
249
249
  onDragStart={onDragStart}
250
- labelToUse={labelToUse}
250
+ labelStr={labelStr}
251
251
  titleStr={titleStr}
252
252
  disabled={disabled}
253
253
  isSelected={isSelected}
@@ -392,7 +392,7 @@ function useDraggableEvents(
392
392
 
393
393
  function DraggableToolbarButton({
394
394
  id,
395
- labelToUse,
395
+ labelStr,
396
396
  titleStr,
397
397
  disabled,
398
398
  isSelected,
@@ -403,7 +403,7 @@ function DraggableToolbarButton({
403
403
  }: {
404
404
  id: string
405
405
  disabled: boolean
406
- labelToUse?: string
406
+ labelStr?: string
407
407
  titleStr?: string
408
408
  isSelected?: boolean
409
409
  icon: TLUiMenuItemProps['icon']
@@ -416,7 +416,7 @@ function DraggableToolbarButton({
416
416
  if (overflow) {
417
417
  return (
418
418
  <TldrawUiToolbarButton
419
- aria-label={labelToUse}
419
+ aria-label={labelStr}
420
420
  aria-pressed={isSelected ? 'true' : 'false'}
421
421
  isActive={isSelected}
422
422
  className="tlui-button-grid__button"
@@ -434,7 +434,7 @@ function DraggableToolbarButton({
434
434
 
435
435
  return (
436
436
  <TldrawUiToolbarButton
437
- aria-label={labelToUse}
437
+ aria-label={labelStr}
438
438
  aria-pressed={isSelected ? 'true' : 'false'}
439
439
  data-testid={`tools.${id}`}
440
440
  data-value={id}
@@ -225,7 +225,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
225
225
  if (ids.length === 0) ids = Array.from(editor.getCurrentPageShapeIds().values())
226
226
  if (ids.length === 0) return
227
227
  trackEvent('export-as', { format: 'svg', source })
228
- helpers.exportAs(ids, 'svg', getExportName(editor, defaultDocumentName))
228
+ helpers.exportAs(ids, { format: 'svg', name: getExportName(editor, defaultDocumentName) })
229
229
  },
230
230
  },
231
231
  {
@@ -241,7 +241,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
241
241
  if (ids.length === 0) ids = Array.from(editor.getCurrentPageShapeIds().values())
242
242
  if (ids.length === 0) return
243
243
  trackEvent('export-as', { format: 'png', source })
244
- helpers.exportAs(ids, 'png', getExportName(editor, defaultDocumentName))
244
+ helpers.exportAs(ids, { format: 'png', name: getExportName(editor, defaultDocumentName) })
245
245
  },
246
246
  },
247
247
  {
@@ -257,11 +257,10 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
257
257
  if (ids.length === 0) ids = Array.from(editor.getCurrentPageShapeIds().values())
258
258
  if (ids.length === 0) return
259
259
  trackEvent('export-all-as', { format: 'svg', source })
260
- helpers.exportAs(
261
- Array.from(editor.getCurrentPageShapeIds()),
262
- 'svg',
263
- getExportName(editor, defaultDocumentName)
264
- )
260
+ helpers.exportAs(Array.from(editor.getCurrentPageShapeIds()), {
261
+ format: 'svg',
262
+ name: getExportName(editor, defaultDocumentName),
263
+ })
265
264
  },
266
265
  },
267
266
  {
@@ -276,7 +275,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
276
275
  const ids = Array.from(editor.getCurrentPageShapeIds().values())
277
276
  if (ids.length === 0) return
278
277
  trackEvent('export-all-as', { format: 'png', source })
279
- helpers.exportAs(ids, 'png', getExportName(editor, defaultDocumentName))
278
+ helpers.exportAs(ids, { format: 'png', name: getExportName(editor, defaultDocumentName) })
280
279
  },
281
280
  },
282
281
  {
@@ -1585,6 +1584,19 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
1585
1584
  onSelect: async (source) => {
1586
1585
  if (!canApplySelectionAction()) return
1587
1586
 
1587
+ const onlySelectedShape = editor.getOnlySelectedShape()
1588
+ if (
1589
+ onlySelectedShape &&
1590
+ (editor.isShapeOfType<TLImageShape>(onlySelectedShape, 'image') ||
1591
+ editor.isShapeOfType<TLVideoShape>(onlySelectedShape, 'video'))
1592
+ ) {
1593
+ const firstToolbarButton = editor
1594
+ .getContainer()
1595
+ .querySelector('.tlui-contextual-toolbar button:first-child') as HTMLElement | null
1596
+ firstToolbarButton?.focus()
1597
+ return
1598
+ }
1599
+
1588
1600
  const firstButton = editor
1589
1601
  .getContainer()
1590
1602
  .querySelector('.tlui-style-panel button') as HTMLElement | null
@@ -12,6 +12,7 @@ import {
12
12
  import { CursorChatBubble } from '../components/CursorChatBubble'
13
13
  import { DefaultDebugMenu } from '../components/DebugMenu/DefaultDebugMenu'
14
14
  import { DefaultDebugPanel } from '../components/DefaultDebugPanel'
15
+ import { DefaultFollowingIndicator } from '../components/DefaultFollowingIndicator'
15
16
  import { DefaultMenuPanel } from '../components/DefaultMenuPanel'
16
17
  import { DefaultDialogs } from '../components/Dialogs'
17
18
  import { TLUiHelpMenuProps } from '../components/HelpMenu/DefaultHelpMenu'
@@ -72,6 +73,7 @@ export interface TLUiComponents {
72
73
  Dialogs?: ComponentType | null
73
74
  Toasts?: ComponentType | null
74
75
  A11y?: ComponentType | null
76
+ FollowingIndicator?: ComponentType | null
75
77
  }
76
78
 
77
79
  const TldrawUiComponentsContext = createContext<TLUiComponents | null>(null)
@@ -119,6 +121,7 @@ export function TldrawUiComponentsProvider({
119
121
  Dialogs: DefaultDialogs,
120
122
  Toasts: DefaultToasts,
121
123
  A11y: DefaultA11yAnnouncer,
124
+ FollowingIndicator: DefaultFollowingIndicator,
122
125
  ..._overrides,
123
126
  }),
124
127
  [_overrides, showCollaborationUi]
@@ -123,7 +123,7 @@ export interface TLUiEventMap {
123
123
  'shrink-shapes': null
124
124
  'flatten-to-image': null
125
125
  'a11y-repeat-shape-announce': null
126
- 'open-url': { url: string }
126
+ 'open-url': { destinationUrl: string }
127
127
  'open-context-menu': null
128
128
  'adjust-shape-styles': null
129
129
  'copy-link': null
@@ -7,8 +7,8 @@ import {
7
7
  assert,
8
8
  compact,
9
9
  isDefined,
10
+ markEventAsHandled,
10
11
  preventDefault,
11
- stopEventPropagation,
12
12
  uniq,
13
13
  useEditor,
14
14
  useMaybeEditor,
@@ -763,7 +763,7 @@ export function useNativeClipboardEvents() {
763
763
 
764
764
  const paste = (e: ClipboardEvent) => {
765
765
  if (disablingMiddleClickPaste) {
766
- stopEventPropagation(e)
766
+ markEventAsHandled(e)
767
767
  return
768
768
  }
769
769
 
@@ -11,12 +11,13 @@ export function useExportAs() {
11
11
  const msg = useTranslation()
12
12
 
13
13
  return useCallback(
14
- (ids: TLShapeId[], format: TLExportType = 'png', name: string | undefined) => {
14
+ (ids: TLShapeId[], opts: { format?: TLExportType; name?: string; scale?: number } = {}) => {
15
15
  assert(editor, 'useExportAs: editor is required')
16
+ const { format = 'png', name, scale = 1 } = opts
16
17
  exportAs(editor, ids, {
17
18
  format,
18
19
  name,
19
- scale: 1,
20
+ scale,
20
21
  }).catch((e) => {
21
22
  console.error(e.message)
22
23
  addToast({
@@ -176,7 +176,7 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
176
176
  editor.createShape({
177
177
  id,
178
178
  type: 'arrow',
179
- props: { start: { x: 0, y: 0 }, end: { x: 200, y: 0 } },
179
+ props: { start: { x: 0, y: 200 }, end: { x: 200, y: 0 } },
180
180
  }),
181
181
  })
182
182
  trackEvent('drag-tool', { source, id: 'arrow' })
@@ -122,6 +122,7 @@ export type TLUiTranslationKey =
122
122
  | 'action.zoom-to-fit'
123
123
  | 'action.zoom-to-selection'
124
124
  | 'assets.files.size-too-big'
125
+ | 'assets.files.maximum-size'
125
126
  | 'assets.files.type-not-allowed'
126
127
  | 'assets.files.upload-failed'
127
128
  | 'assets.files.amount-too-many'
@@ -186,6 +187,7 @@ export type TLUiTranslationKey =
186
187
  | 'geo-style.pentagon'
187
188
  | 'geo-style.rectangle'
188
189
  | 'geo-style.rhombus'
190
+ | 'geo-style.rhombus-2'
189
191
  | 'geo-style.star'
190
192
  | 'geo-style.trapezoid'
191
193
  | 'geo-style.triangle'
@@ -260,6 +262,7 @@ export type TLUiTranslationKey =
260
262
  | 'tool.aspect-ratio.wide'
261
263
  | 'tool.image-toolbar-title'
262
264
  | 'tool.image-crop'
265
+ | 'tool.image-crop-confirm'
263
266
  | 'tool.media-alt-text'
264
267
  | 'tool.media-alt-text-desc'
265
268
  | 'tool.media-alt-text-confirm'
@@ -409,6 +412,7 @@ export type TLUiTranslationKey =
409
412
  | 'style-panel.opacity'
410
413
  | 'style-panel.size'
411
414
  | 'style-panel.spline'
415
+ | 'style-panel.selected'
412
416
  | 'tool-panel.title'
413
417
  | 'tool-panel.more'
414
418
  | 'navigation-zone.title'
@@ -92,9 +92,9 @@ export const DEFAULT_TRANSLATION = {
92
92
  'action.toggle-wrap-mode': 'Toggle Select on wrap',
93
93
  'action.toggle-reduce-motion.menu': 'Reduce motion',
94
94
  'action.toggle-reduce-motion': 'Toggle reduce motion',
95
- 'action.toggle-keyboard-shortcuts.menu': 'Keyboard shortcuts',
95
+ 'action.toggle-keyboard-shortcuts.menu': 'Enable keyboard shortcuts',
96
96
  'action.toggle-keyboard-shortcuts': 'Toggle keyboard shortcuts',
97
- 'action.toggle-ui-labels.menu': 'UI labels',
97
+ 'action.toggle-ui-labels.menu': 'Enable UI labels',
98
98
  'action.toggle-ui-labels': 'Toggle UI labels',
99
99
  'action.toggle-edge-scrolling.menu': 'Edge scrolling',
100
100
  'action.toggle-edge-scrolling': 'Toggle edge scrolling',
@@ -123,6 +123,7 @@ export const DEFAULT_TRANSLATION = {
123
123
  'action.zoom-to-fit': 'Zoom to fit',
124
124
  'action.zoom-to-selection': 'Zoom to selection',
125
125
  'assets.files.size-too-big': 'File size is too big',
126
+ 'assets.files.maximum-size': 'Maximum file size is {size}',
126
127
  'assets.files.type-not-allowed': 'File type is not allowed',
127
128
  'assets.files.upload-failed': 'Upload failed',
128
129
  'assets.files.amount-too-many': 'Too many files',
@@ -187,6 +188,7 @@ export const DEFAULT_TRANSLATION = {
187
188
  'geo-style.pentagon': 'Pentagon',
188
189
  'geo-style.rectangle': 'Rectangle',
189
190
  'geo-style.rhombus': 'Rhombus',
191
+ 'geo-style.rhombus-2': 'Rhombus left',
190
192
  'geo-style.star': 'Star',
191
193
  'geo-style.trapezoid': 'Trapezoid',
192
194
  'geo-style.triangle': 'Triangle',
@@ -261,6 +263,7 @@ export const DEFAULT_TRANSLATION = {
261
263
  'tool.aspect-ratio.wide': 'Wide (16:9)',
262
264
  'tool.image-toolbar-title': 'Image tools',
263
265
  'tool.image-crop': 'Crop image',
266
+ 'tool.image-crop-confirm': 'Confirm',
264
267
  'tool.media-alt-text': 'Alternative text',
265
268
  'tool.media-alt-text-desc': 'Give a description…',
266
269
  'tool.media-alt-text-confirm': 'Confirm',
@@ -412,6 +415,7 @@ export const DEFAULT_TRANSLATION = {
412
415
  'style-panel.opacity': 'Opacity',
413
416
  'style-panel.size': 'Size',
414
417
  'style-panel.spline': 'Spline',
418
+ 'style-panel.selected': 'selected',
415
419
  'tool-panel.title': 'Tools',
416
420
  'tool-panel.more': 'More',
417
421
  'navigation-zone.title': 'Navigation',
@@ -31,9 +31,16 @@ export function kbd(str: string) {
31
31
  )
32
32
  .flat()
33
33
  .map((sub, index) => {
34
- if (sub === '__CTRL__') return 'Ctrl'
35
- if (sub === '__ALT__') return 'Alt'
36
- const modifiedKey = sub[0].toUpperCase() + sub.slice(1)
34
+ if (sub[0] === '+') return []
35
+
36
+ let modifiedKey
37
+ if (sub === '__CTRL__') {
38
+ modifiedKey = 'Ctrl'
39
+ } else if (sub === '__ALT__') {
40
+ modifiedKey = 'Alt'
41
+ } else {
42
+ modifiedKey = sub[0].toUpperCase() + sub.slice(1)
43
+ }
37
44
  return tlenv.isDarwin || !index ? modifiedKey : ['+', modifiedKey]
38
45
  })
39
46
  .flat()