tldraw 3.16.0-canary.a2491e00987a → 3.16.0-canary.a675c73ef29d

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 (359) hide show
  1. package/dist-cjs/index.d.ts +230 -106
  2. package/dist-cjs/index.js +33 -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 +5 -4
  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 +12 -5
  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/ShapeFill.js +1 -1
  27. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  28. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  29. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -4
  30. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  31. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  32. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  33. package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -2
  34. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  35. package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
  36. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  37. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  38. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  39. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  40. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  41. package/dist-cjs/lib/ui/TldrawUi.js +13 -12
  42. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  43. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  44. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  45. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  46. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  47. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  48. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  49. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
  50. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  51. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
  52. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  53. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  54. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  55. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  56. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  57. package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
  58. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  59. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  60. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  61. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  62. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  63. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +24 -21
  64. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  65. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  66. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  67. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
  68. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  69. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
  70. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  71. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  72. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  73. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
  74. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  75. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +11 -2
  76. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
  78. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  79. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
  80. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  81. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -0
  82. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  83. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +125 -122
  84. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  85. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  86. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +0 -10
  87. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  88. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +8 -24
  89. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  90. package/dist-cjs/lib/ui/context/actions.js +23 -10
  91. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  92. package/dist-cjs/lib/ui/context/components.js +2 -0
  93. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  94. package/dist-cjs/lib/ui/context/events.js.map +1 -1
  95. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  96. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  97. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  98. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  99. package/dist-cjs/lib/ui/hooks/useTools.js +22 -4
  100. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  101. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  102. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -2
  103. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  104. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  105. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  106. package/dist-cjs/lib/ui/version.js +3 -3
  107. package/dist-cjs/lib/ui/version.js.map +1 -1
  108. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  109. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  110. package/dist-cjs/lib/utils/export/export.js +0 -20
  111. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  112. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  113. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  114. package/dist-esm/index.d.mts +230 -106
  115. package/dist-esm/index.mjs +61 -29
  116. package/dist-esm/index.mjs.map +2 -2
  117. package/dist-esm/lib/Tldraw.mjs +14 -4
  118. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  119. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  120. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  121. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  122. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  123. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +5 -5
  124. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  125. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +12 -5
  126. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  127. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +3 -3
  128. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  129. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
  130. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  131. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -0
  132. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
  134. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  135. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
  136. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  137. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  138. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  139. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +1 -1
  140. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  141. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  142. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +4 -5
  143. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  144. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  145. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  146. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -3
  147. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  148. package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
  149. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  150. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  151. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  152. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  153. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  154. package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
  155. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  156. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  157. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  158. package/dist-esm/lib/ui/components/A11y.mjs +2 -2
  159. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  160. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  161. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  162. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
  163. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  164. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -2
  165. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  166. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  167. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  168. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  169. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  170. package/dist-esm/lib/ui/components/{primitives/TldrawUiButtonPicker.mjs → StylePanel/StylePanelButtonPicker.mjs} +54 -43
  171. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  172. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  173. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  174. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  175. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  176. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +21 -18
  177. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  178. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  179. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  180. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
  181. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  182. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
  183. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  184. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  185. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  186. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
  187. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  188. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +12 -3
  189. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  190. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +3 -3
  191. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  192. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
  193. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  194. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +2 -0
  195. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  196. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +135 -124
  197. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  198. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  199. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +0 -10
  200. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  201. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +8 -24
  202. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  203. package/dist-esm/lib/ui/context/actions.mjs +23 -10
  204. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  205. package/dist-esm/lib/ui/context/components.mjs +2 -0
  206. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  207. package/dist-esm/lib/ui/context/events.mjs.map +1 -1
  208. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +2 -2
  209. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  210. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  211. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  212. package/dist-esm/lib/ui/hooks/useTools.mjs +23 -4
  213. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  214. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -2
  215. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  216. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  217. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  218. package/dist-esm/lib/ui/version.mjs +3 -3
  219. package/dist-esm/lib/ui/version.mjs.map +1 -1
  220. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  221. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  222. package/dist-esm/lib/utils/export/export.mjs +0 -20
  223. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  224. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  225. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  226. package/package.json +11 -34
  227. package/src/index.ts +44 -22
  228. package/src/lib/Tldraw.tsx +15 -2
  229. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  230. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  231. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +6 -5
  232. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +48 -6
  233. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  234. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +5 -5
  235. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  236. package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -4
  237. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +3 -3
  238. package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
  239. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -0
  240. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  241. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  242. package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
  243. package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
  244. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  245. package/src/lib/shapes/shared/ShapeFill.tsx +1 -1
  246. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  247. package/src/lib/shapes/shared/useEditablePlainText.ts +5 -9
  248. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  249. package/src/lib/shapes/text/PlainTextArea.tsx +3 -3
  250. package/src/lib/shapes/text/RichTextArea.tsx +3 -4
  251. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  252. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  253. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  254. package/src/lib/ui/TldrawUi.tsx +16 -10
  255. package/src/lib/ui/assetUrls.ts +13 -10
  256. package/src/lib/ui/components/A11y.tsx +2 -2
  257. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  258. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
  259. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +2 -2
  260. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  261. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  262. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +63 -50
  263. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  264. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  265. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  266. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  267. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
  268. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
  269. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  270. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
  271. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +8 -3
  272. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +3 -3
  273. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
  274. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +3 -0
  275. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +146 -124
  276. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  277. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +0 -10
  278. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +11 -24
  279. package/src/lib/ui/context/actions.tsx +23 -10
  280. package/src/lib/ui/context/components.tsx +3 -0
  281. package/src/lib/ui/context/events.tsx +1 -1
  282. package/src/lib/ui/hooks/useClipboardEvents.ts +2 -2
  283. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  284. package/src/lib/ui/hooks/useTools.tsx +26 -4
  285. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  286. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -2
  287. package/src/lib/ui/kbd-utils.ts +10 -3
  288. package/src/lib/ui/version.ts +3 -3
  289. package/src/lib/ui.css +24 -8
  290. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  291. package/src/lib/utils/export/copyAs.ts +1 -24
  292. package/src/lib/utils/export/export.ts +0 -36
  293. package/src/lib/utils/export/exportAs.ts +1 -32
  294. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  295. package/src/test/A11y.test.tsx +3 -2
  296. package/src/test/ClickManager.test.ts +7 -6
  297. package/src/test/Editor.test.tsx +20 -19
  298. package/src/test/EraserTool.test.ts +184 -13
  299. package/src/test/HandTool.test.ts +10 -9
  300. package/src/test/HighlightShape.test.ts +2 -1
  301. package/src/test/SelectTool.test.ts +3 -2
  302. package/src/test/TLUserPreferences.test.ts +4 -3
  303. package/src/test/TestEditor.ts +13 -15
  304. package/src/test/TldrawEditor.test.tsx +11 -10
  305. package/src/test/ZoomTool.test.ts +7 -6
  306. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  307. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  308. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  309. package/src/test/arrows-megabus.test.tsx +5 -4
  310. package/src/test/bindings.test.tsx +24 -37
  311. package/src/test/bookmark-shapes.test.ts +1 -8
  312. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  313. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  314. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  315. package/src/test/commands/alignShapes.test.tsx +25 -24
  316. package/src/test/commands/animationSpeed.test.ts +2 -1
  317. package/src/test/commands/centerOnPoint.test.ts +3 -2
  318. package/src/test/commands/clipboard.test.ts +3 -2
  319. package/src/test/commands/createShapes.test.ts +2 -1
  320. package/src/test/commands/deleteShapes.test.ts +2 -1
  321. package/src/test/commands/distributeShapes.test.tsx +11 -10
  322. package/src/test/commands/getSvgString.test.ts +2 -1
  323. package/src/test/commands/packShapes.test.ts +5 -4
  324. package/src/test/commands/resizeShape.test.ts +2 -1
  325. package/src/test/commands/rotateShapes.test.ts +7 -6
  326. package/src/test/commands/setCamera.test.ts +4 -3
  327. package/src/test/commands/setCurrentPage.test.ts +3 -2
  328. package/src/test/commands/stackShapes.test.ts +11 -10
  329. package/src/test/commands/stretch.test.tsx +13 -12
  330. package/src/test/createDeepLink.test.tsx +2 -1
  331. package/src/test/cropping.test.ts +3 -2
  332. package/src/test/custom-clipping.test.ts +436 -0
  333. package/src/test/drawing.test.ts +2 -1
  334. package/src/test/flipShapes.test.ts +4 -3
  335. package/src/test/frames.test.ts +25 -24
  336. package/src/test/getCulledShapes.test.tsx +74 -4
  337. package/src/test/groups.test.tsx +1 -1
  338. package/src/test/handleDeepLink.test.tsx +2 -1
  339. package/src/test/maxShapes.test.ts +3 -2
  340. package/src/test/modifiers.test.ts +5 -4
  341. package/src/test/navigation.test.ts +12 -11
  342. package/src/test/panning.test.ts +2 -1
  343. package/src/test/perf/perf.test.ts +2 -1
  344. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  345. package/src/test/resizing.test.ts +39 -38
  346. package/src/test/select.test.tsx +4 -3
  347. package/src/test/selection-omnibus.test.ts +11 -10
  348. package/src/test/shapeutils.test.ts +4 -3
  349. package/src/test/translating.test.ts +9 -8
  350. package/tldraw.css +40 -11
  351. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  352. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  353. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  354. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  355. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  356. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  357. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  358. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  359. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -120,7 +120,6 @@ export function TldrawUiMenuItem<
120
120
  type="menu"
121
121
  data-testid={`${sourceId}.${id}`}
122
122
  disabled={disabled}
123
- title={titleStr}
124
123
  onClick={(e) => {
125
124
  if (noClose) {
126
125
  preventDefault(e)
@@ -146,7 +145,6 @@ export function TldrawUiMenuItem<
146
145
  return (
147
146
  <_ContextMenu.Item
148
147
  dir="ltr"
149
- title={titleStr}
150
148
  draggable={false}
151
149
  className="tlui-button tlui-button__menu"
152
150
  data-testid={`${sourceId}.${id}`}
@@ -168,20 +166,6 @@ export function TldrawUiMenuItem<
168
166
  </_ContextMenu.Item>
169
167
  )
170
168
  }
171
- case 'panel': {
172
- return (
173
- <TldrawUiButton
174
- data-testid={`${sourceId}.${id}`}
175
- type="menu"
176
- title={titleStr}
177
- disabled={disabled}
178
- onClick={() => onSelect(sourceId)}
179
- >
180
- <TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>
181
- {spinner ? <Spinner /> : icon && <TldrawUiButtonIcon icon={icon} />}
182
- </TldrawUiButton>
183
- )
184
- }
185
169
  case 'small-icons':
186
170
  case 'icons': {
187
171
  return (
@@ -229,7 +213,7 @@ export function TldrawUiMenuItem<
229
213
  icon={icon}
230
214
  onSelect={onSelect}
231
215
  onDragStart={onDragStart}
232
- labelToUse={labelToUse}
216
+ labelStr={labelStr}
233
217
  titleStr={titleStr}
234
218
  disabled={disabled}
235
219
  isSelected={isSelected}
@@ -263,7 +247,7 @@ export function TldrawUiMenuItem<
263
247
  icon={icon}
264
248
  onSelect={onSelect}
265
249
  onDragStart={onDragStart}
266
- labelToUse={labelToUse}
250
+ labelStr={labelStr}
267
251
  titleStr={titleStr}
268
252
  disabled={disabled}
269
253
  isSelected={isSelected}
@@ -332,8 +316,8 @@ function useDraggableEvents(
332
316
  if (
333
317
  distanceSq >
334
318
  (editor.getInstanceState().isCoarsePointer
335
- ? editor.options.coarseDragDistanceSquared
336
- : editor.options.dragDistanceSquared)
319
+ ? editor.options.uiCoarseDragDistanceSquared
320
+ : editor.options.uiDragDistanceSquared)
337
321
  ) {
338
322
  const screenSpaceStart = state.screenSpaceStart
339
323
  state = {
@@ -342,6 +326,8 @@ function useDraggableEvents(
342
326
  }
343
327
 
344
328
  editor.run(() => {
329
+ editor.setCurrentTool('select')
330
+
345
331
  // Set origin point
346
332
  editor.dispatch({
347
333
  type: 'pointer',
@@ -364,6 +350,7 @@ function useDraggableEvents(
364
350
  })
365
351
 
366
352
  tooltipManager.hideAllTooltips()
353
+ editor.getContainer().focus()
367
354
  })
368
355
  }
369
356
  }
@@ -405,7 +392,7 @@ function useDraggableEvents(
405
392
 
406
393
  function DraggableToolbarButton({
407
394
  id,
408
- labelToUse,
395
+ labelStr,
409
396
  titleStr,
410
397
  disabled,
411
398
  isSelected,
@@ -416,7 +403,7 @@ function DraggableToolbarButton({
416
403
  }: {
417
404
  id: string
418
405
  disabled: boolean
419
- labelToUse?: string
406
+ labelStr?: string
420
407
  titleStr?: string
421
408
  isSelected?: boolean
422
409
  icon: TLUiMenuItemProps['icon']
@@ -429,7 +416,7 @@ function DraggableToolbarButton({
429
416
  if (overflow) {
430
417
  return (
431
418
  <TldrawUiToolbarButton
432
- aria-label={labelToUse}
419
+ aria-label={labelStr}
433
420
  aria-pressed={isSelected ? 'true' : 'false'}
434
421
  isActive={isSelected}
435
422
  className="tlui-button-grid__button"
@@ -447,7 +434,7 @@ function DraggableToolbarButton({
447
434
 
448
435
  return (
449
436
  <TldrawUiToolbarButton
450
- aria-label={labelToUse}
437
+ aria-label={labelStr}
451
438
  aria-pressed={isSelected ? 'true' : 'false'}
452
439
  data-testid={`tools.${id}`}
453
440
  data-value={id}
@@ -36,6 +36,7 @@ import { useTranslation } from '../hooks/useTranslation/useTranslation'
36
36
  import { TLUiIconType } from '../icon-types'
37
37
  import { TLUiOverrideHelpers, useDefaultHelpers } from '../overrides'
38
38
  import { useA11y } from './a11y'
39
+ import { useTldrawUiComponents } from './components'
39
40
  import { TLUiEventSource, useUiEvents } from './events'
40
41
 
41
42
  /** @public */
@@ -98,6 +99,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
98
99
  const _editor = useMaybeEditor()
99
100
  const showCollaborationUi = useShowCollaborationUi()
100
101
  const helpers = useDefaultHelpers()
102
+ const components = useTldrawUiComponents()
101
103
  const trackEvent = useUiEvents()
102
104
  const a11y = useA11y()
103
105
  const msg = useTranslation()
@@ -176,7 +178,9 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
176
178
  kbd: 'cmd+alt+/,ctrl+alt+/',
177
179
  onSelect(source) {
178
180
  trackEvent('open-kbd-shortcuts', { source })
179
- helpers.addDialog({ component: DefaultKeyboardShortcutsDialog })
181
+ helpers.addDialog({
182
+ component: components.KeyboardShortcutsDialog ?? DefaultKeyboardShortcutsDialog,
183
+ })
180
184
  },
181
185
  },
182
186
  {
@@ -221,7 +225,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
221
225
  if (ids.length === 0) ids = Array.from(editor.getCurrentPageShapeIds().values())
222
226
  if (ids.length === 0) return
223
227
  trackEvent('export-as', { format: 'svg', source })
224
- helpers.exportAs(ids, 'svg', getExportName(editor, defaultDocumentName))
228
+ helpers.exportAs(ids, { format: 'svg', name: getExportName(editor, defaultDocumentName) })
225
229
  },
226
230
  },
227
231
  {
@@ -237,7 +241,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
237
241
  if (ids.length === 0) ids = Array.from(editor.getCurrentPageShapeIds().values())
238
242
  if (ids.length === 0) return
239
243
  trackEvent('export-as', { format: 'png', source })
240
- helpers.exportAs(ids, 'png', getExportName(editor, defaultDocumentName))
244
+ helpers.exportAs(ids, { format: 'png', name: getExportName(editor, defaultDocumentName) })
241
245
  },
242
246
  },
243
247
  {
@@ -253,11 +257,10 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
253
257
  if (ids.length === 0) ids = Array.from(editor.getCurrentPageShapeIds().values())
254
258
  if (ids.length === 0) return
255
259
  trackEvent('export-all-as', { format: 'svg', source })
256
- helpers.exportAs(
257
- Array.from(editor.getCurrentPageShapeIds()),
258
- 'svg',
259
- getExportName(editor, defaultDocumentName)
260
- )
260
+ helpers.exportAs(Array.from(editor.getCurrentPageShapeIds()), {
261
+ format: 'svg',
262
+ name: getExportName(editor, defaultDocumentName),
263
+ })
261
264
  },
262
265
  },
263
266
  {
@@ -272,7 +275,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
272
275
  const ids = Array.from(editor.getCurrentPageShapeIds().values())
273
276
  if (ids.length === 0) return
274
277
  trackEvent('export-all-as', { format: 'png', source })
275
- helpers.exportAs(ids, 'png', getExportName(editor, defaultDocumentName))
278
+ helpers.exportAs(ids, { format: 'png', name: getExportName(editor, defaultDocumentName) })
276
279
  },
277
280
  },
278
281
  {
@@ -1755,7 +1758,17 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
1755
1758
  }
1756
1759
 
1757
1760
  return actions
1758
- }, [helpers, _editor, trackEvent, overrides, defaultDocumentName, showCollaborationUi, msg, a11y])
1761
+ }, [
1762
+ helpers,
1763
+ _editor,
1764
+ trackEvent,
1765
+ overrides,
1766
+ defaultDocumentName,
1767
+ showCollaborationUi,
1768
+ msg,
1769
+ a11y,
1770
+ components,
1771
+ ])
1759
1772
 
1760
1773
  return <ActionsContext.Provider value={asActions(actions)}>{children}</ActionsContext.Provider>
1761
1774
  }
@@ -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({
@@ -3,6 +3,8 @@ import {
3
3
  createShapeId,
4
4
  Editor,
5
5
  GeoShapeGeoStyle,
6
+ getIndicesBetween,
7
+ TLLineShape,
6
8
  TLPointerEventInfo,
7
9
  TLShapeId,
8
10
  toRichText,
@@ -153,7 +155,8 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
153
155
  },
154
156
  onDragStart(source: TLUiEventSource, info: TLPointerEventInfo) {
155
157
  onDragFromToolbarToCreateShape(editor, info, {
156
- createShape: (id) => editor.createShape({ id, type: 'geo', props: { geo } }),
158
+ createShape: (id) =>
159
+ editor.createShape({ id, type: 'geo', props: { w: 200, h: 200, geo } }),
157
160
  })
158
161
  trackEvent('drag-tool', { source, id: 'geo' })
159
162
  },
@@ -173,7 +176,7 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
173
176
  editor.createShape({
174
177
  id,
175
178
  type: 'arrow',
176
- props: { start: { x: 0, y: 0 }, end: { x: 200, y: 0 } },
179
+ props: { start: { x: 0, y: 200 }, end: { x: 200, y: 0 } },
177
180
  }),
178
181
  })
179
182
  trackEvent('drag-tool', { source, id: 'arrow' })
@@ -188,6 +191,24 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
188
191
  editor.setCurrentTool('line')
189
192
  onToolSelect(source, this)
190
193
  },
194
+ onDragStart(source, info) {
195
+ onDragFromToolbarToCreateShape(editor, info, {
196
+ createShape: (id) => {
197
+ const [start, end] = getIndicesBetween(null, null, 2)
198
+ editor.createShape<TLLineShape>({
199
+ id,
200
+ type: 'line',
201
+ props: {
202
+ points: {
203
+ [start]: { id: start, index: start, x: 0, y: 200 },
204
+ [end]: { id: end, index: end, x: 200, y: 0 },
205
+ },
206
+ },
207
+ })
208
+ },
209
+ })
210
+ trackEvent('drag-tool', { source, id: 'line' })
211
+ },
191
212
  },
192
213
  {
193
214
  id: 'frame',
@@ -219,8 +240,8 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
219
240
  createShape: (id) =>
220
241
  editor.createShape({ id, type: 'text', props: { richText: toRichText('Text') } }),
221
242
  onDragEnd: (id) => {
222
- editor.emit('select-all-text', { shapeId: id })
223
243
  editor.setEditingShape(id)
244
+ editor.emit('select-all-text', { shapeId: id })
224
245
  },
225
246
  })
226
247
  trackEvent('drag-tool', { source, id: 'text' })
@@ -249,8 +270,8 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
249
270
  onDragFromToolbarToCreateShape(editor, info, {
250
271
  createShape: (id) => editor.createShape({ id, type: 'note' }),
251
272
  onDragEnd: (id) => {
252
- editor.emit('select-all-text', { shapeId: id })
253
273
  editor.setEditingShape(id)
274
+ editor.emit('select-all-text', { shapeId: id })
254
275
  },
255
276
  })
256
277
  trackEvent('drag-tool', { source, id: 'note' })
@@ -365,5 +386,6 @@ export function onDragFromToolbarToCreateShape(
365
386
  opts.onDragEnd?.(id)
366
387
  },
367
388
  })
389
+
368
390
  editor.getCurrentTool().setCurrentToolIdMask(shape.type)
369
391
  }
@@ -186,6 +186,7 @@ export type TLUiTranslationKey =
186
186
  | 'geo-style.pentagon'
187
187
  | 'geo-style.rectangle'
188
188
  | 'geo-style.rhombus'
189
+ | 'geo-style.rhombus-2'
189
190
  | 'geo-style.star'
190
191
  | 'geo-style.trapezoid'
191
192
  | 'geo-style.triangle'
@@ -260,6 +261,7 @@ export type TLUiTranslationKey =
260
261
  | 'tool.aspect-ratio.wide'
261
262
  | 'tool.image-toolbar-title'
262
263
  | 'tool.image-crop'
264
+ | 'tool.image-crop-confirm'
263
265
  | 'tool.media-alt-text'
264
266
  | 'tool.media-alt-text-desc'
265
267
  | 'tool.media-alt-text-confirm'
@@ -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',
@@ -187,6 +187,7 @@ export const DEFAULT_TRANSLATION = {
187
187
  'geo-style.pentagon': 'Pentagon',
188
188
  'geo-style.rectangle': 'Rectangle',
189
189
  'geo-style.rhombus': 'Rhombus',
190
+ 'geo-style.rhombus-2': 'Rhombus left',
190
191
  'geo-style.star': 'Star',
191
192
  'geo-style.trapezoid': 'Trapezoid',
192
193
  'geo-style.triangle': 'Triangle',
@@ -261,6 +262,7 @@ export const DEFAULT_TRANSLATION = {
261
262
  'tool.aspect-ratio.wide': 'Wide (16:9)',
262
263
  'tool.image-toolbar-title': 'Image tools',
263
264
  'tool.image-crop': 'Crop image',
265
+ 'tool.image-crop-confirm': 'Confirm',
264
266
  'tool.media-alt-text': 'Alternative text',
265
267
  'tool.media-alt-text-desc': 'Give a description…',
266
268
  'tool.media-alt-text-confirm': 'Confirm',
@@ -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()
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.16.0-canary.a2491e00987a'
4
+ export const version = '3.16.0-canary.a675c73ef29d'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-08-12T12:23:37.583Z',
8
- patch: '2025-08-12T12:23:37.583Z',
7
+ minor: '2025-09-15T12:46:50.613Z',
8
+ patch: '2025-09-15T12:46:50.613Z',
9
9
  }
package/src/lib/ui.css CHANGED
@@ -1007,9 +1007,23 @@
1007
1007
  flex-direction: column;
1008
1008
  }
1009
1009
 
1010
- .tlui-style-panel__section:nth-of-type(n + 2):not(:last-child) {
1010
+ /*
1011
+ add a border to the bottom of all but the last section. we have to handle empty sections too, which
1012
+ are hidden and shouldn't be counted
1013
+ */
1014
+ .tlui-style-panel__section:not(:nth-last-child(-n + 1 of .tlui-style-panel__section:not(:empty))) {
1011
1015
  border-bottom: 1px solid var(--tl-color-divider);
1012
1016
  }
1017
+ /*
1018
+ if a section ends with a slider and we're adding a border, we need some extra space for visual
1019
+ balance. we need to handle empty sections as above. is this the most complex css selector in all of
1020
+ tldraw? probably.
1021
+ */
1022
+ .tlui-style-panel__section:has(.tlui-slider__container:last-child):not(
1023
+ :nth-last-child(-n + 1 of .tlui-style-panel__section:not(:empty))
1024
+ ) {
1025
+ margin-bottom: 7px;
1026
+ }
1013
1027
 
1014
1028
  .tlui-style-panel__section:empty {
1015
1029
  display: none;
@@ -1021,7 +1035,7 @@
1021
1035
  }
1022
1036
 
1023
1037
  .tlui-style-panel__dropdown-picker:only-child {
1024
- width: 100%;
1038
+ flex: 1;
1025
1039
  }
1026
1040
 
1027
1041
  .tlui-style-panel__double-select-picker {
@@ -1047,6 +1061,9 @@
1047
1061
  }
1048
1062
 
1049
1063
  @media (hover: hover) {
1064
+ .tlui-style-panel .tlui-button[aria-expanded='true'] {
1065
+ background: none;
1066
+ }
1050
1067
  .tlui-style-panel .tlui-button[data-state='open']:not(:hover)::after {
1051
1068
  opacity: 1;
1052
1069
  background: linear-gradient(270deg, rgba(144, 144, 144, 0) 0%, var(--tl-color-muted-2) 100%);
@@ -1078,7 +1095,6 @@
1078
1095
  .tlui-layout__bottom {
1079
1096
  grid-row: 2;
1080
1097
  width: 100%;
1081
- overflow: hidden;
1082
1098
  }
1083
1099
 
1084
1100
  .tlui-layout__bottom__main {
@@ -1270,6 +1286,10 @@
1270
1286
  opacity: 1;
1271
1287
  }
1272
1288
 
1289
+ .tlui-main-toolbar__overflow-content {
1290
+ touch-action: none;
1291
+ }
1292
+
1273
1293
  .tlui-main-toolbar__tools [data-toolbar-visible='false'],
1274
1294
  .tlui-main-toolbar__overflow-content [data-toolbar-visible='false'] {
1275
1295
  display: none;
@@ -1319,7 +1339,6 @@
1319
1339
  max-width: 400px;
1320
1340
  width: fit-content;
1321
1341
  text-align: center;
1322
- pointer-events: none;
1323
1342
  will-change: transform, opacity;
1324
1343
  z-index: 2;
1325
1344
  }
@@ -1331,10 +1350,7 @@
1331
1350
 
1332
1351
  [data-radix-popper-content-wrapper]:has(.tlui-tooltip) {
1333
1352
  z-index: var(--tl-layer-toasts) !important;
1334
- }
1335
-
1336
- [data-radix-popper-content-wrapper]:has(.tlui-tooltip[data-should-animate='true']) {
1337
- transition: all 0.1s ease-out;
1353
+ pointer-events: none;
1338
1354
  }
1339
1355
 
1340
1356
  /* ------------------- Debug panel ------------------ */
@@ -1,6 +1,6 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
- exports[`putExcalidrawContent test fixtures bound-arrows.json 1`] = `
3
+ exports[`putExcalidrawContent test fixtures > bound-arrows.json 1`] = `
4
4
  {
5
5
  "binding:8": {
6
6
  "fromId": "shape:7",
@@ -173,7 +173,7 @@ exports[`putExcalidrawContent test fixtures bound-arrows.json 1`] = `
173
173
  }
174
174
  `;
175
175
 
176
- exports[`putExcalidrawContent test fixtures bound-elbow-arrows.json 1`] = `
176
+ exports[`putExcalidrawContent test fixtures > bound-elbow-arrows.json 1`] = `
177
177
  {
178
178
  "binding:7": {
179
179
  "fromId": "shape:6",
@@ -346,7 +346,7 @@ exports[`putExcalidrawContent test fixtures bound-elbow-arrows.json 1`] = `
346
346
  }
347
347
  `;
348
348
 
349
- exports[`putExcalidrawContent test fixtures image.json 1`] = `
349
+ exports[`putExcalidrawContent test fixtures > image.json 1`] = `
350
350
  {
351
351
  "asset:5": {
352
352
  "id": "asset:5",
@@ -404,7 +404,7 @@ exports[`putExcalidrawContent test fixtures image.json 1`] = `
404
404
  }
405
405
  `;
406
406
 
407
- exports[`putExcalidrawContent test fixtures line-drawing.json 1`] = `
407
+ exports[`putExcalidrawContent test fixtures > line-drawing.json 1`] = `
408
408
  {
409
409
  "document:document": {
410
410
  "gridSize": 10,
@@ -31,30 +31,7 @@ export interface CopyAsOptions extends TLImageExportOptions {
31
31
  *
32
32
  * @public
33
33
  */
34
- export function copyAs(editor: Editor, ids: TLShapeId[], opts: CopyAsOptions): Promise<void>
35
- /**
36
- * @deprecated The format parameter is now part of the opts object.
37
- * @public
38
- */
39
- export function copyAs(
40
- editor: Editor,
41
- ids: TLShapeId[],
42
- format: TLCopyType,
43
- opts?: TLImageExportOptions & { format?: undefined }
44
- ): Promise<void>
45
- export function copyAs(
46
- ...args:
47
- | [editor: Editor, ids: TLShapeId[], opts: TLImageExportOptions & { format: TLCopyType }]
48
- | [
49
- editor: Editor,
50
- ids: TLShapeId[],
51
- format: TLCopyType,
52
- opts?: TLImageExportOptions & { format?: undefined },
53
- ]
54
- ) {
55
- const [editor, ids, opts] =
56
- typeof args[2] === 'string' ? [args[0], args[1], { ...args[3], format: args[2] }] : args
57
-
34
+ export function copyAs(editor: Editor, ids: TLShapeId[], opts: CopyAsOptions): Promise<void> {
58
35
  // Note: it's important that this function itself isn't async and doesn't really use promises -
59
36
  // we need to create the relevant `ClipboardItem`s and call navigator.clipboard.write
60
37
  // synchronously to make sure safari knows that the user _wants_ to copy See
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  Editor,
3
3
  FileHelpers,
4
- TLExportType,
5
4
  TLImageExportOptions,
6
5
  TLShapeId,
7
6
  exhaustiveSwitchError,
@@ -35,41 +34,6 @@ export async function exportToString(
35
34
  }
36
35
  }
37
36
 
38
- /**
39
- * Export the given shapes as a blob.
40
- * @param editor - The editor instance.
41
- * @param ids - The ids of the shapes to export.
42
- * @param format - The format to export as.
43
- * @param opts - Rendering options.
44
- * @returns A promise that resolves to a blob.
45
- * @deprecated Use {@link @tldraw/editor#Editor.toImage} instead.
46
- * @public
47
- */
48
- export async function exportToBlob({
49
- editor,
50
- ids,
51
- format,
52
- opts = {},
53
- }: {
54
- editor: Editor
55
- ids: TLShapeId[]
56
- format: TLExportType
57
- opts?: TLImageExportOptions
58
- }): Promise<Blob> {
59
- const idsToUse = ids?.length ? ids : [...editor.getCurrentPageShapeIds()]
60
- switch (format) {
61
- case 'jpeg':
62
- case 'png':
63
- case 'webp':
64
- case 'svg': {
65
- return (await editor.toImage(idsToUse, { ...opts, format })).blob
66
- }
67
- default: {
68
- exhaustiveSwitchError(format)
69
- }
70
- }
71
- }
72
-
73
37
  const clipboardMimeTypesByFormat = {
74
38
  jpeg: 'image/jpeg',
75
39
  png: 'image/png',
@@ -28,38 +28,7 @@ export async function exportAs(
28
28
  editor: Editor,
29
29
  ids: TLShapeId[],
30
30
  opts: ExportAsOptions
31
- ): Promise<void>
32
- /**
33
- * @deprecated The format & name parameters are now part of the opts object.
34
- * @public
35
- */
36
- export async function exportAs(
37
- editor: Editor,
38
- ids: TLShapeId[],
39
- format?: TLExportType,
40
- name?: string,
41
- opts?: TLImageExportOptions
42
- ): Promise<void>
43
- export async function exportAs(
44
- ...args:
45
- | [
46
- editor: Editor,
47
- ids: TLShapeId[],
48
- opts: TLImageExportOptions & { format: TLExportType; name?: string },
49
- ]
50
- | [
51
- editor: Editor,
52
- ids: TLShapeId[],
53
- format?: TLExportType,
54
- name?: string,
55
- opts?: TLImageExportOptions,
56
- ]
57
- ) {
58
- const [editor, ids, opts] =
59
- typeof args[2] === 'object'
60
- ? args
61
- : [args[0], args[1], { ...args[4], format: args[2] ?? 'png', name: args[3] }]
62
-
31
+ ): Promise<void> {
63
32
  // If we don't get name then use a predefined one
64
33
  let name = opts.name
65
34
  if (!name) {