tldraw 3.16.0-canary.9a94aba7bcaa → 3.16.0-canary.9abe0dac1e0f

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 (380) hide show
  1. package/dist-cjs/index.d.ts +240 -110
  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 +15 -4
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  8. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  9. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  10. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  11. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +3 -2
  12. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  13. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +4 -4
  14. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +8 -1
  16. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  17. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +8 -2
  18. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  19. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -0
  20. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  21. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -0
  22. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  23. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +2 -1
  24. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  25. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +4 -4
  26. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  27. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  28. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  29. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  30. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +3 -5
  31. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  32. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  33. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  34. package/dist-cjs/lib/shapes/text/PlainTextArea.js +3 -2
  35. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  36. package/dist-cjs/lib/shapes/text/RichTextArea.js +3 -3
  37. package/dist-cjs/lib/shapes/text/RichTextArea.js.map +2 -2
  38. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  39. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  40. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  41. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  42. package/dist-cjs/lib/ui/TldrawUi.js +13 -12
  43. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  44. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  45. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  46. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  47. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  48. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  49. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  50. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
  51. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  52. package/dist-cjs/lib/ui/components/LanguageMenu.js +1 -0
  53. package/dist-cjs/lib/ui/components/LanguageMenu.js.map +2 -2
  54. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +2 -1
  55. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  56. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
  57. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  58. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  59. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  60. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  61. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  62. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +147 -0
  63. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  64. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  65. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  66. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  67. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  68. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +24 -21
  69. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  70. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  71. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  72. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +2 -0
  73. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  74. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +38 -9
  75. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  76. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  77. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  78. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +2 -1
  79. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  80. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
  81. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
  82. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +6 -2
  83. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  84. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +11 -2
  85. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  86. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +5 -3
  87. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  88. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
  89. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  90. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +3 -0
  91. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  92. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +96 -43
  93. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  94. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +3 -0
  95. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  96. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +10 -9
  97. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  98. package/dist-cjs/lib/ui/context/actions.js +29 -10
  99. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  100. package/dist-cjs/lib/ui/context/components.js +2 -0
  101. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  102. package/dist-cjs/lib/ui/context/events.js.map +1 -1
  103. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  104. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  105. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  106. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  107. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  108. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  109. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  110. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +6 -2
  111. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  112. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  113. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  114. package/dist-cjs/lib/ui/version.js +3 -3
  115. package/dist-cjs/lib/ui/version.js.map +1 -1
  116. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  117. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  118. package/dist-cjs/lib/utils/export/export.js +0 -20
  119. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  120. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  121. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  122. package/dist-esm/index.d.mts +240 -110
  123. package/dist-esm/index.mjs +61 -29
  124. package/dist-esm/index.mjs.map +2 -2
  125. package/dist-esm/lib/Tldraw.mjs +14 -4
  126. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  127. package/dist-esm/lib/defaultExternalContentHandlers.mjs +15 -4
  128. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  129. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  130. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  131. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +3 -2
  132. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +4 -5
  134. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  135. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +8 -1
  136. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  137. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +9 -3
  138. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  139. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
  140. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  141. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -0
  142. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  143. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
  144. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  145. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +5 -5
  146. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  147. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  148. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  149. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  150. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +3 -6
  151. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  152. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  153. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  154. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +4 -3
  155. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  156. package/dist-esm/lib/shapes/text/RichTextArea.mjs +3 -4
  157. package/dist-esm/lib/shapes/text/RichTextArea.mjs.map +2 -2
  158. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  159. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  160. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  161. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  162. package/dist-esm/lib/ui/TldrawUi.mjs +13 -12
  163. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  164. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  165. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  166. package/dist-esm/lib/ui/components/A11y.mjs +1 -2
  167. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  168. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  169. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  170. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
  171. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  172. package/dist-esm/lib/ui/components/LanguageMenu.mjs +1 -0
  173. package/dist-esm/lib/ui/components/LanguageMenu.mjs.map +2 -2
  174. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +2 -1
  175. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  176. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +1 -2
  177. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  178. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  179. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  180. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  181. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  182. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +135 -0
  183. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  184. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  185. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  186. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  187. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  188. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +21 -18
  189. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  190. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  191. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  192. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +2 -0
  193. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  194. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +38 -9
  195. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  196. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  197. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  198. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +2 -1
  199. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  200. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +1 -1
  201. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
  202. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +6 -2
  203. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  204. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +11 -3
  205. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  206. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +6 -4
  207. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  208. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
  209. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  210. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +3 -0
  211. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  212. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +97 -43
  213. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  214. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +3 -0
  215. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  216. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +10 -9
  217. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  218. package/dist-esm/lib/ui/context/actions.mjs +29 -10
  219. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  220. package/dist-esm/lib/ui/context/components.mjs +2 -0
  221. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  222. package/dist-esm/lib/ui/context/events.mjs.map +1 -1
  223. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +1 -2
  224. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  225. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  226. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  227. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  228. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  229. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +6 -2
  230. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  231. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  232. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  233. package/dist-esm/lib/ui/version.mjs +3 -3
  234. package/dist-esm/lib/ui/version.mjs.map +1 -1
  235. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  236. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  237. package/dist-esm/lib/utils/export/export.mjs +0 -20
  238. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  239. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  240. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  241. package/package.json +11 -34
  242. package/src/index.ts +44 -22
  243. package/src/lib/Tldraw.tsx +15 -2
  244. package/src/lib/defaultExternalContentHandlers.ts +26 -4
  245. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +85 -14
  246. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +6 -5
  247. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +48 -6
  248. package/src/lib/shapes/arrow/arrow-types.ts +3 -5
  249. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  250. package/src/lib/shapes/arrow/arrowTargetState.ts +4 -3
  251. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +4 -5
  252. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  253. package/src/lib/shapes/frame/FrameShapeUtil.tsx +9 -0
  254. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +10 -3
  255. package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
  256. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -0
  257. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  258. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  259. package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
  260. package/src/lib/shapes/shared/HyperlinkButton.tsx +5 -5
  261. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  262. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  263. package/src/lib/shapes/shared/useEditablePlainText.ts +3 -10
  264. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  265. package/src/lib/shapes/text/PlainTextArea.tsx +4 -3
  266. package/src/lib/shapes/text/RichTextArea.tsx +3 -4
  267. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  268. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  269. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  270. package/src/lib/ui/TldrawUi.tsx +16 -10
  271. package/src/lib/ui/assetUrls.ts +13 -10
  272. package/src/lib/ui/components/A11y.tsx +1 -2
  273. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  274. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
  275. package/src/lib/ui/components/LanguageMenu.tsx +1 -0
  276. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +2 -1
  277. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +1 -2
  278. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  279. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  280. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +70 -50
  281. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  282. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  283. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  284. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  285. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +2 -0
  286. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +32 -15
  287. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  288. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +1 -0
  289. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +1 -1
  290. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +9 -2
  291. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +7 -3
  292. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +6 -3
  293. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
  294. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +5 -1
  295. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +109 -31
  296. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +4 -0
  297. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +12 -11
  298. package/src/lib/ui/context/actions.tsx +36 -10
  299. package/src/lib/ui/context/components.tsx +3 -0
  300. package/src/lib/ui/context/events.tsx +1 -1
  301. package/src/lib/ui/hooks/useClipboardEvents.ts +1 -2
  302. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  303. package/src/lib/ui/hooks/useTools.tsx +1 -1
  304. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +4 -0
  305. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +6 -2
  306. package/src/lib/ui/kbd-utils.ts +10 -3
  307. package/src/lib/ui/version.ts +3 -3
  308. package/src/lib/ui.css +33 -2
  309. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  310. package/src/lib/utils/export/copyAs.ts +1 -24
  311. package/src/lib/utils/export/export.ts +0 -36
  312. package/src/lib/utils/export/exportAs.ts +1 -32
  313. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  314. package/src/test/A11y.test.tsx +3 -2
  315. package/src/test/ClickManager.test.ts +7 -6
  316. package/src/test/Editor.test.tsx +20 -19
  317. package/src/test/EraserTool.test.ts +184 -13
  318. package/src/test/HandTool.test.ts +10 -9
  319. package/src/test/HighlightShape.test.ts +2 -1
  320. package/src/test/SelectTool.test.ts +3 -2
  321. package/src/test/TLUserPreferences.test.ts +4 -3
  322. package/src/test/TestEditor.ts +13 -15
  323. package/src/test/TldrawEditor.test.tsx +11 -10
  324. package/src/test/ZoomTool.test.ts +7 -6
  325. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  326. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  327. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  328. package/src/test/arrows-megabus.test.tsx +5 -4
  329. package/src/test/bindings.test.tsx +24 -37
  330. package/src/test/bookmark-shapes.test.ts +1 -8
  331. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  332. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  333. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  334. package/src/test/commands/alignShapes.test.tsx +25 -24
  335. package/src/test/commands/animationSpeed.test.ts +2 -1
  336. package/src/test/commands/centerOnPoint.test.ts +3 -2
  337. package/src/test/commands/clipboard.test.ts +3 -2
  338. package/src/test/commands/createShapes.test.ts +2 -1
  339. package/src/test/commands/deleteShapes.test.ts +2 -1
  340. package/src/test/commands/distributeShapes.test.tsx +11 -10
  341. package/src/test/commands/getSvgString.test.ts +2 -1
  342. package/src/test/commands/packShapes.test.ts +5 -4
  343. package/src/test/commands/resizeShape.test.ts +2 -1
  344. package/src/test/commands/rotateShapes.test.ts +7 -6
  345. package/src/test/commands/setCamera.test.ts +4 -3
  346. package/src/test/commands/setCurrentPage.test.ts +3 -2
  347. package/src/test/commands/stackShapes.test.ts +11 -10
  348. package/src/test/commands/stretch.test.tsx +13 -12
  349. package/src/test/createDeepLink.test.tsx +2 -1
  350. package/src/test/cropping.test.ts +3 -2
  351. package/src/test/custom-clipping.test.ts +436 -0
  352. package/src/test/drawing.test.ts +2 -1
  353. package/src/test/flipShapes.test.ts +4 -3
  354. package/src/test/frames.test.ts +25 -24
  355. package/src/test/getCulledShapes.test.tsx +74 -4
  356. package/src/test/groups.test.tsx +1 -1
  357. package/src/test/handleDeepLink.test.tsx +2 -1
  358. package/src/test/maxShapes.test.ts +3 -2
  359. package/src/test/modifiers.test.ts +5 -4
  360. package/src/test/navigation.test.ts +12 -11
  361. package/src/test/panning.test.ts +2 -1
  362. package/src/test/perf/perf.test.ts +2 -1
  363. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  364. package/src/test/resizing.test.ts +39 -38
  365. package/src/test/select.test.tsx +4 -3
  366. package/src/test/selection-omnibus.test.ts +11 -10
  367. package/src/test/shapeutils.test.ts +4 -3
  368. package/src/test/translating.test.ts +9 -8
  369. package/tldraw.css +49 -5
  370. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  371. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  372. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  373. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +0 -131
  374. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  375. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  376. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  377. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  378. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -115
  379. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  380. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -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
  {
@@ -1581,6 +1584,19 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
1581
1584
  onSelect: async (source) => {
1582
1585
  if (!canApplySelectionAction()) return
1583
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
+
1584
1600
  const firstButton = editor
1585
1601
  .getContainer()
1586
1602
  .querySelector('.tlui-style-panel button') as HTMLElement | null
@@ -1755,7 +1771,17 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
1755
1771
  }
1756
1772
 
1757
1773
  return actions
1758
- }, [helpers, _editor, trackEvent, overrides, defaultDocumentName, showCollaborationUi, msg, a11y])
1774
+ }, [
1775
+ helpers,
1776
+ _editor,
1777
+ trackEvent,
1778
+ overrides,
1779
+ defaultDocumentName,
1780
+ showCollaborationUi,
1781
+ msg,
1782
+ a11y,
1783
+ components,
1784
+ ])
1759
1785
 
1760
1786
  return <ActionsContext.Provider value={asActions(actions)}>{children}</ActionsContext.Provider>
1761
1787
  }
@@ -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
@@ -8,7 +8,6 @@ import {
8
8
  compact,
9
9
  isDefined,
10
10
  preventDefault,
11
- stopEventPropagation,
12
11
  uniq,
13
12
  useEditor,
14
13
  useMaybeEditor,
@@ -763,7 +762,7 @@ export function useNativeClipboardEvents() {
763
762
 
764
763
  const paste = (e: ClipboardEvent) => {
765
764
  if (disablingMiddleClickPaste) {
766
- stopEventPropagation(e)
765
+ editor.markEventAsHandled(e)
767
766
  return
768
767
  }
769
768
 
@@ -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()
@@ -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.9a94aba7bcaa'
4
+ export const version = '3.16.0-canary.9abe0dac1e0f'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-08-13T18:40:42.507Z',
8
- patch: '2025-08-13T18:40:42.507Z',
7
+ minor: '2025-09-17T22:54:50.695Z',
8
+ patch: '2025-09-17T22:54:50.695Z',
9
9
  }
package/src/lib/ui.css CHANGED
@@ -494,6 +494,10 @@
494
494
  -webkit-user-select: auto !important;
495
495
  }
496
496
 
497
+ .tlui-input::placeholder {
498
+ color: var(--tl-color-text-3);
499
+ }
500
+
497
501
  .tlui-input__wrapper {
498
502
  width: 100%;
499
503
  height: 44px;
@@ -578,6 +582,12 @@
578
582
  box-shadow: var(--tl-shadow-3);
579
583
  }
580
584
 
585
+ @media (max-height: 600px) {
586
+ .tlui-menu {
587
+ max-height: 70vh;
588
+ }
589
+ }
590
+
581
591
  .tlui-menu::-webkit-scrollbar {
582
592
  display: none;
583
593
  }
@@ -1007,21 +1017,39 @@
1007
1017
  flex-direction: column;
1008
1018
  }
1009
1019
 
1010
- .tlui-style-panel__section:nth-of-type(n + 2):not(:last-child) {
1020
+ /*
1021
+ add a border to the bottom of all but the last section. we have to handle empty sections too, which
1022
+ are hidden and shouldn't be counted
1023
+ */
1024
+ .tlui-style-panel__section:not(:nth-last-child(-n + 1 of .tlui-style-panel__section:not(:empty))) {
1011
1025
  border-bottom: 1px solid var(--tl-color-divider);
1012
1026
  }
1027
+ /*
1028
+ if a section ends with a slider and we're adding a border, we need some extra space for visual
1029
+ balance. we need to handle empty sections as above. is this the most complex css selector in all of
1030
+ tldraw? probably.
1031
+ */
1032
+ .tlui-style-panel__section:has(.tlui-slider__container:last-child):not(
1033
+ :nth-last-child(-n + 1 of .tlui-style-panel__section:not(:empty))
1034
+ ) {
1035
+ margin-bottom: 7px;
1036
+ }
1013
1037
 
1014
1038
  .tlui-style-panel__section:empty {
1015
1039
  display: none;
1016
1040
  }
1017
1041
 
1042
+ .tlui-style-panel[data-ismobile='true'] .tlui-style-panel__section .tlui-row.tlui-toolbar {
1043
+ flex-wrap: wrap;
1044
+ }
1045
+
1018
1046
  .tlui-style-panel__section__common:not(:only-child) {
1019
1047
  margin-bottom: 7px;
1020
1048
  border-bottom: 1px solid var(--tl-color-divider);
1021
1049
  }
1022
1050
 
1023
1051
  .tlui-style-panel__dropdown-picker:only-child {
1024
- width: 100%;
1052
+ flex: 1;
1025
1053
  }
1026
1054
 
1027
1055
  .tlui-style-panel__double-select-picker {
@@ -1047,6 +1075,9 @@
1047
1075
  }
1048
1076
 
1049
1077
  @media (hover: hover) {
1078
+ .tlui-style-panel .tlui-button[aria-expanded='true'] {
1079
+ background: none;
1080
+ }
1050
1081
  .tlui-style-panel .tlui-button[data-state='open']:not(:hover)::after {
1051
1082
  opacity: 1;
1052
1083
  background: linear-gradient(270deg, rgba(144, 144, 144, 0) 0%, var(--tl-color-muted-2) 100%);
@@ -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) {
@@ -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[`buildFromV1Document test fixtures arrow-binding.tldr 1`] = `
3
+ exports[`buildFromV1Document test fixtures > arrow-binding.tldr 1`] = `
4
4
  {
5
5
  "binding:12": {
6
6
  "fromId": "shape:11",
@@ -173,7 +173,7 @@ exports[`buildFromV1Document test fixtures arrow-binding.tldr 1`] = `
173
173
  }
174
174
  `;
175
175
 
176
- exports[`buildFromV1Document test fixtures exact-arrow-binding.tldr 1`] = `
176
+ exports[`buildFromV1Document test fixtures > exact-arrow-binding.tldr 1`] = `
177
177
  {
178
178
  "binding:11": {
179
179
  "fromId": "shape:10",
@@ -346,7 +346,7 @@ exports[`buildFromV1Document test fixtures exact-arrow-binding.tldr 1`] = `
346
346
  }
347
347
  `;
348
348
 
349
- exports[`buildFromV1Document test fixtures incorrect-arrow-binding.tldr 1`] = `
349
+ exports[`buildFromV1Document test fixtures > incorrect-arrow-binding.tldr 1`] = `
350
350
  {
351
351
  "binding:11": {
352
352
  "fromId": "shape:10",
@@ -1,16 +1,17 @@
1
1
  import { createShapeId, toRichText } from '@tldraw/editor'
2
+ import { Mock, vi } from 'vitest'
2
3
  import { generateShapeAnnouncementMessage } from '../lib/ui/components/A11y'
3
4
  import { TestEditor } from './TestEditor'
4
5
 
5
6
  describe('A11y Shape Announcements', () => {
6
7
  let editor: TestEditor
7
- let mockTranslate: jest.Mock
8
+ let mockTranslate: Mock
8
9
 
9
10
  beforeEach(() => {
10
11
  editor = new TestEditor()
11
12
 
12
13
  // Create a simple translation mock
13
- mockTranslate = jest.fn((key) => {
14
+ mockTranslate = vi.fn((key) => {
14
15
  if (key === 'a11y.multiple-shapes') return '{num} shapes selected'
15
16
  if (key === 'a11y.shape') return 'Shape'
16
17
  if (key === 'a11y.text') return 'Text'
@@ -1,3 +1,4 @@
1
+ import { vi } from 'vitest'
1
2
  import { TestEditor } from './TestEditor'
2
3
 
3
4
  let editor: TestEditor
@@ -10,7 +11,7 @@ beforeEach(() => {
10
11
  editor._transformPointerUpSpy.mockRestore()
11
12
  })
12
13
 
13
- jest.useFakeTimers()
14
+ vi.useFakeTimers()
14
15
 
15
16
  describe('Handles events', () => {
16
17
  it('Emits single click events', () => {
@@ -23,7 +24,7 @@ describe('Handles events', () => {
23
24
  const eventsBeforeSettle = [{ name: 'pointer_down' }, { name: 'pointer_up' }]
24
25
 
25
26
  // allow time for settle
26
- jest.advanceTimersByTime(500)
27
+ vi.advanceTimersByTime(500)
27
28
 
28
29
  // nothing should have settled
29
30
  expect(events).toMatchObject(eventsBeforeSettle)
@@ -64,7 +65,7 @@ describe('Handles events', () => {
64
65
  }
65
66
 
66
67
  // allow double click to settle
67
- jest.advanceTimersByTime(500)
68
+ vi.advanceTimersByTime(500)
68
69
 
69
70
  expect(events).toMatchObject([
70
71
  ...eventsBeforeSettle,
@@ -110,7 +111,7 @@ describe('Handles events', () => {
110
111
  expect(eventsBeforeSettle).toMatchObject(eventsBeforeSettle)
111
112
 
112
113
  // allow double click to settle
113
- jest.advanceTimersByTime(500)
114
+ vi.advanceTimersByTime(500)
114
115
 
115
116
  expect(events).toMatchObject([
116
117
  ...eventsBeforeSettle,
@@ -162,7 +163,7 @@ describe('Handles events', () => {
162
163
  expect(events).toMatchObject(eventsBeforeSettle)
163
164
 
164
165
  // allow double click to settle
165
- jest.advanceTimersByTime(500)
166
+ vi.advanceTimersByTime(500)
166
167
 
167
168
  expect(events).toMatchObject([
168
169
  ...eventsBeforeSettle,
@@ -218,7 +219,7 @@ describe('Handles events', () => {
218
219
  expect(events).toMatchObject(eventsBeforeSettle)
219
220
 
220
221
  // allow double click to settle
221
- jest.advanceTimersByTime(500)
222
+ vi.advanceTimersByTime(500)
222
223
 
223
224
  expect(events).toMatchObject(eventsBeforeSettle)
224
225