tldraw 3.16.0-canary.5dac57cf9465 → 3.16.0-canary.5f8d98bccb38

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 (403) hide show
  1. package/dist-cjs/index.d.ts +299 -105
  2. package/dist-cjs/index.js +37 -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/canvas/TldrawScribble.js +1 -1
  7. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  10. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -3
  11. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
  13. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
  14. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  15. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  16. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  17. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  19. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  20. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +18 -12
  21. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  22. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  23. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  24. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  25. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  26. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  27. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  28. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  29. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  30. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
  31. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  32. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
  33. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  34. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  35. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  36. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
  37. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  38. package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
  39. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  40. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  41. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +0 -2
  42. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  43. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
  44. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  45. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  46. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  47. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  48. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  49. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  50. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  51. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  52. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  53. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  54. package/dist-cjs/lib/ui/TldrawUi.js +27 -12
  55. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  56. package/dist-cjs/lib/ui/assetUrls.js +13 -10
  57. package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
  58. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +10 -2
  59. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  60. package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
  61. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
  62. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
  63. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  64. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  65. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  66. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  67. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  68. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
  69. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  70. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
  71. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
  73. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
  74. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
  75. package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
  76. package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
  77. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
  78. package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +24 -21
  79. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
  80. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
  81. package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
  82. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
  83. package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
  84. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +39 -10
  85. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  86. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -22
  87. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  88. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
  89. package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
  90. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
  91. package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
  92. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +188 -78
  93. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  94. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +10 -1
  95. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  96. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +17 -4
  97. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  98. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +17 -3
  99. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  100. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +167 -159
  101. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  102. package/dist-cjs/lib/ui/components/primitives/layout.js +30 -5
  103. package/dist-cjs/lib/ui/components/primitives/layout.js.map +2 -2
  104. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  105. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  106. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  107. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +154 -19
  108. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  109. package/dist-cjs/lib/ui/context/actions.js +23 -10
  110. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  111. package/dist-cjs/lib/ui/context/components.js +2 -0
  112. package/dist-cjs/lib/ui/context/components.js.map +2 -2
  113. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  114. package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
  115. package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
  116. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  117. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  118. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  119. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -2
  120. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  121. package/dist-cjs/lib/ui/kbd-utils.js +9 -3
  122. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  123. package/dist-cjs/lib/ui/version.js +3 -3
  124. package/dist-cjs/lib/ui/version.js.map +1 -1
  125. package/dist-cjs/lib/utils/export/copyAs.js +1 -2
  126. package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
  127. package/dist-cjs/lib/utils/export/export.js +0 -20
  128. package/dist-cjs/lib/utils/export/export.js.map +2 -2
  129. package/dist-cjs/lib/utils/export/exportAs.js +1 -2
  130. package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
  131. package/dist-esm/index.d.mts +299 -105
  132. package/dist-esm/index.mjs +70 -30
  133. package/dist-esm/index.mjs.map +2 -2
  134. package/dist-esm/lib/Tldraw.mjs +14 -4
  135. package/dist-esm/lib/Tldraw.mjs.map +2 -2
  136. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  137. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  138. package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
  139. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  140. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +4 -3
  141. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  142. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
  143. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
  144. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  145. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  146. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  147. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  148. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  149. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  150. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +19 -12
  151. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  152. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  153. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  154. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  155. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  156. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  157. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  158. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  159. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  160. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
  161. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  162. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
  163. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  164. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  165. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  166. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
  167. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  168. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
  169. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  170. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  171. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +0 -2
  172. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  173. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
  174. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  175. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  176. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  177. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  178. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  179. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  180. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  181. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  182. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  183. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  184. package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
  185. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  186. package/dist-esm/lib/ui/assetUrls.mjs +13 -10
  187. package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
  188. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +10 -2
  189. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  190. package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
  191. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
  192. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
  193. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  194. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  195. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  196. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  197. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  198. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
  199. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  200. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
  201. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  202. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +126 -0
  203. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
  204. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
  205. package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
  206. package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
  207. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
  208. package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +21 -18
  209. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
  210. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
  211. package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
  212. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
  213. package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
  214. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +39 -10
  215. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  216. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -22
  217. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  218. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
  219. package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
  220. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
  221. package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
  222. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -80
  223. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  224. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +10 -1
  225. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  226. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +17 -4
  227. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  228. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +18 -4
  229. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  230. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +176 -161
  231. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  232. package/dist-esm/lib/ui/components/primitives/layout.mjs +31 -6
  233. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +2 -2
  234. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  235. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  236. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  237. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +162 -21
  238. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  239. package/dist-esm/lib/ui/context/actions.mjs +23 -10
  240. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  241. package/dist-esm/lib/ui/context/components.mjs +2 -0
  242. package/dist-esm/lib/ui/context/components.mjs.map +2 -2
  243. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  244. package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
  245. package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
  246. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  247. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  248. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -2
  249. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  250. package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
  251. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  252. package/dist-esm/lib/ui/version.mjs +3 -3
  253. package/dist-esm/lib/ui/version.mjs.map +1 -1
  254. package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
  255. package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
  256. package/dist-esm/lib/utils/export/export.mjs +0 -20
  257. package/dist-esm/lib/utils/export/export.mjs.map +2 -2
  258. package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
  259. package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
  260. package/package.json +11 -34
  261. package/src/index.ts +51 -22
  262. package/src/lib/Tldraw.tsx +15 -2
  263. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  264. package/src/lib/defaultExternalContentHandlers.ts +12 -4
  265. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  266. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  267. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
  268. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
  269. package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
  270. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  271. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  272. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  273. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  274. package/src/lib/shapes/frame/FrameShapeUtil.tsx +29 -14
  275. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  276. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  277. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  278. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  279. package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
  280. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  281. package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
  282. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  283. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  284. package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
  285. package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
  286. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  287. package/src/lib/shapes/shared/useEditablePlainText.ts +0 -6
  288. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
  289. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  290. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  291. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  292. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  293. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  294. package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
  295. package/src/lib/ui/TldrawUi.tsx +33 -12
  296. package/src/lib/ui/assetUrls.ts +13 -10
  297. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +13 -2
  298. package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
  299. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
  300. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  301. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  302. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
  303. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
  304. package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +65 -51
  305. package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
  306. package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
  307. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
  308. package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
  309. package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
  310. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +33 -16
  311. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -24
  312. package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
  313. package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
  314. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +208 -56
  315. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +6 -1
  316. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +50 -30
  317. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +25 -5
  318. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +209 -181
  319. package/src/lib/ui/components/primitives/layout.tsx +79 -5
  320. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  321. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  322. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +221 -18
  323. package/src/lib/ui/context/actions.tsx +23 -10
  324. package/src/lib/ui/context/components.tsx +3 -0
  325. package/src/lib/ui/context/events.tsx +2 -1
  326. package/src/lib/ui/hooks/useExportAs.ts +3 -2
  327. package/src/lib/ui/hooks/useTools.tsx +140 -10
  328. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  329. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -2
  330. package/src/lib/ui/kbd-utils.ts +10 -3
  331. package/src/lib/ui/version.ts +3 -3
  332. package/src/lib/ui.css +365 -245
  333. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  334. package/src/lib/utils/export/copyAs.ts +1 -24
  335. package/src/lib/utils/export/export.ts +0 -36
  336. package/src/lib/utils/export/exportAs.ts +1 -32
  337. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  338. package/src/test/A11y.test.tsx +3 -2
  339. package/src/test/ClickManager.test.ts +7 -6
  340. package/src/test/Editor.test.tsx +20 -19
  341. package/src/test/EraserTool.test.ts +184 -13
  342. package/src/test/HandTool.test.ts +10 -9
  343. package/src/test/HighlightShape.test.ts +2 -1
  344. package/src/test/SelectTool.test.ts +3 -2
  345. package/src/test/TLUserPreferences.test.ts +4 -3
  346. package/src/test/TestEditor.ts +13 -15
  347. package/src/test/TldrawEditor.test.tsx +11 -10
  348. package/src/test/ZoomTool.test.ts +7 -6
  349. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  350. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  351. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  352. package/src/test/arrows-megabus.test.tsx +5 -4
  353. package/src/test/bindings.test.tsx +24 -37
  354. package/src/test/bookmark-shapes.test.ts +1 -8
  355. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  356. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  357. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  358. package/src/test/commands/alignShapes.test.tsx +25 -24
  359. package/src/test/commands/animationSpeed.test.ts +2 -1
  360. package/src/test/commands/centerOnPoint.test.ts +3 -2
  361. package/src/test/commands/clipboard.test.ts +3 -2
  362. package/src/test/commands/createShapes.test.ts +2 -1
  363. package/src/test/commands/deleteShapes.test.ts +2 -1
  364. package/src/test/commands/distributeShapes.test.tsx +11 -10
  365. package/src/test/commands/getSvgString.test.ts +2 -1
  366. package/src/test/commands/packShapes.test.ts +5 -4
  367. package/src/test/commands/resizeShape.test.ts +2 -1
  368. package/src/test/commands/rotateShapes.test.ts +7 -6
  369. package/src/test/commands/setCamera.test.ts +4 -3
  370. package/src/test/commands/setCurrentPage.test.ts +3 -2
  371. package/src/test/commands/stackShapes.test.ts +11 -10
  372. package/src/test/commands/stretch.test.tsx +13 -12
  373. package/src/test/createDeepLink.test.tsx +2 -1
  374. package/src/test/cropping.test.ts +3 -2
  375. package/src/test/custom-clipping.test.ts +436 -0
  376. package/src/test/drawing.test.ts +2 -1
  377. package/src/test/flipShapes.test.ts +4 -3
  378. package/src/test/frames.test.ts +25 -24
  379. package/src/test/getCulledShapes.test.tsx +74 -4
  380. package/src/test/groups.test.tsx +1 -1
  381. package/src/test/handleDeepLink.test.tsx +2 -1
  382. package/src/test/maxShapes.test.ts +3 -2
  383. package/src/test/modifiers.test.ts +5 -4
  384. package/src/test/navigation.test.ts +12 -11
  385. package/src/test/panning.test.ts +2 -1
  386. package/src/test/perf/perf.test.ts +2 -1
  387. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  388. package/src/test/resizing.test.ts +39 -38
  389. package/src/test/select.test.tsx +4 -3
  390. package/src/test/selection-omnibus.test.ts +11 -10
  391. package/src/test/shapeutils.test.ts +4 -3
  392. package/src/test/translating.test.ts +9 -8
  393. package/tldraw.css +673 -537
  394. package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
  395. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
  396. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
  397. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
  398. package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
  399. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
  400. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
  401. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -114
  402. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
  403. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
@@ -1,48 +1,55 @@
1
1
  import {
2
2
  DefaultColorStyle,
3
+ getColorValue,
3
4
  SharedStyle,
4
5
  StyleProp,
5
6
  TLDefaultColorStyle,
6
- TLDefaultColorTheme,
7
7
  useEditor,
8
8
  } from '@tldraw/editor'
9
- import { ReactElement, memo, useMemo, useRef } from 'react'
9
+ import { memo, ReactElement, useMemo, useRef } from 'react'
10
+ import { useDefaultColorTheme } from '../../../shapes/shared/useDefaultColorTheme'
10
11
  import { StyleValuesForUi } from '../../../styles'
11
12
  import { PORTRAIT_BREAKPOINT } from '../../constants'
12
13
  import { useBreakpoint } from '../../context/breakpoints'
13
14
  import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
14
15
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
15
- import { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'
16
- import { TldrawUiToolbarToggleGroup, TldrawUiToolbarToggleItem } from './TldrawUiToolbar'
17
- import { TldrawUiGrid, TldrawUiRow } from './layout'
16
+ import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
17
+ import {
18
+ TldrawUiToolbar,
19
+ TldrawUiToolbarToggleGroup,
20
+ TldrawUiToolbarToggleItem,
21
+ } from '../primitives/TldrawUiToolbar'
22
+ import { TldrawUiGrid, TldrawUiRow } from '../primitives/layout'
23
+ import { useStylePanelContext } from './StylePanelContext'
24
+ import { StylePanelSubheading } from './StylePanelSubheading'
18
25
 
19
26
  /** @public */
20
- export interface TLUiButtonPickerProps<T extends string> {
27
+ export interface StylePanelButtonPickerProps<T extends string> {
21
28
  title: string
22
29
  uiType: string
23
30
  style: StyleProp<T>
24
31
  value: SharedStyle<T>
25
32
  items: StyleValuesForUi<T>
26
- theme: TLDefaultColorTheme
27
- onValueChange(style: StyleProp<T>, value: T): void
33
+ onValueChange?(style: StyleProp<T>, value: T): void
28
34
  onHistoryMark?(id: string): void
29
35
  }
30
36
 
31
37
  /** @public */
32
- export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker<T extends string>(
33
- props: TLUiButtonPickerProps<T>
38
+ export const StylePanelButtonPicker = memo(function StylePanelButtonPicker<T extends string>(
39
+ props: StylePanelButtonPickerProps<T>
34
40
  ) {
41
+ const ctx = useStylePanelContext()
42
+
35
43
  const {
36
44
  uiType,
37
45
  items,
38
46
  title,
39
47
  style,
40
48
  value,
41
- // columns = clamp(items.length, 2, 4),
42
- onValueChange,
43
- onHistoryMark,
44
- theme,
49
+ onValueChange = ctx.onValueChange,
50
+ onHistoryMark = ctx.onHistoryMark,
45
51
  } = props
52
+ const theme = useDefaultColorTheme()
46
53
  const editor = useEditor()
47
54
  const msg = useTranslation()
48
55
  const breakpoint = useBreakpoint()
@@ -116,43 +123,50 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker<T extends
116
123
  }
117
124
  }, [editor, breakpoint, value, onHistoryMark, onValueChange, style])
118
125
 
119
- const Wrapper = items.length > 4 ? TldrawUiGrid : TldrawUiRow
126
+ const Layout = items.length > 4 ? TldrawUiGrid : TldrawUiRow
120
127
 
121
128
  return (
122
- <Wrapper asChild>
123
- <TldrawUiToolbarToggleGroup
124
- data-testid={`style.${uiType}`}
125
- type="single"
126
- value={value.type === 'shared' ? value.value : undefined}
127
- >
128
- {items.map((item) => {
129
- const label = title + ' — ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
130
- return (
131
- <TldrawUiToolbarToggleItem
132
- type="icon"
133
- key={item.value}
134
- data-id={item.value}
135
- data-testid={`style.${uiType}.${item.value}`}
136
- aria-label={label}
137
- value={item.value}
138
- data-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}
139
- data-isactive={value.type === 'shared' && value.value === item.value}
140
- title={label}
141
- style={
142
- style === (DefaultColorStyle as StyleProp<unknown>)
143
- ? { color: theme[item.value as TLDefaultColorStyle].solid }
144
- : undefined
145
- }
146
- onPointerEnter={handleButtonPointerEnter}
147
- onPointerDown={handleButtonPointerDown}
148
- onPointerUp={handleButtonPointerUp}
149
- onClick={handleButtonClick}
150
- >
151
- <TldrawUiButtonIcon icon={item.icon} />
152
- </TldrawUiToolbarToggleItem>
153
- )
154
- })}
155
- </TldrawUiToolbarToggleGroup>
156
- </Wrapper>
129
+ <>
130
+ {ctx.showUiLabels && <StylePanelSubheading>{title}</StylePanelSubheading>}
131
+ <TldrawUiToolbar label={title}>
132
+ <TldrawUiToolbarToggleGroup
133
+ data-testid={`style.${uiType}`}
134
+ type="single"
135
+ value={value.type === 'shared' ? value.value : undefined}
136
+ asChild
137
+ >
138
+ <Layout>
139
+ {items.map((item) => {
140
+ const label =
141
+ title + ' — ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
142
+ return (
143
+ <TldrawUiToolbarToggleItem
144
+ type="icon"
145
+ key={item.value}
146
+ data-id={item.value}
147
+ data-testid={`style.${uiType}.${item.value}`}
148
+ aria-label={label}
149
+ value={item.value}
150
+ data-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}
151
+ data-isactive={value.type === 'shared' && value.value === item.value}
152
+ title={label}
153
+ style={
154
+ style === (DefaultColorStyle as StyleProp<unknown>)
155
+ ? { color: getColorValue(theme, item.value as TLDefaultColorStyle, 'solid') }
156
+ : undefined
157
+ }
158
+ onPointerEnter={handleButtonPointerEnter}
159
+ onPointerDown={handleButtonPointerDown}
160
+ onPointerUp={handleButtonPointerUp}
161
+ onClick={handleButtonClick}
162
+ >
163
+ <TldrawUiButtonIcon icon={item.icon} />
164
+ </TldrawUiToolbarToggleItem>
165
+ )
166
+ })}
167
+ </Layout>
168
+ </TldrawUiToolbarToggleGroup>
169
+ </TldrawUiToolbar>
170
+ </>
157
171
  )
158
- }) as <T extends string>(props: TLUiButtonPickerProps<T>) => ReactElement
172
+ }) as <T extends string>(props: StylePanelButtonPickerProps<T>) => ReactElement
@@ -0,0 +1,63 @@
1
+ import { ReadonlySharedStyleMap, StyleProp, useEditor, useValue } from '@tldraw/editor'
2
+ import { createContext, useCallback, useContext } from 'react'
3
+ import { useUiEvents } from '../../context/events'
4
+
5
+ /** @public */
6
+ export interface StylePanelContext {
7
+ styles: ReadonlySharedStyleMap
8
+ showUiLabels: boolean
9
+ onHistoryMark(id: string): void
10
+ onValueChange<T>(style: StyleProp<T>, value: T): void
11
+ }
12
+ const StylePanelContext = createContext<null | StylePanelContext>(null)
13
+
14
+ /** @public */
15
+ export interface StylePanelContextProviderProps {
16
+ children: React.ReactNode
17
+ styles: ReadonlySharedStyleMap
18
+ }
19
+
20
+ /** @public @react */
21
+ export function StylePanelContextProvider({ children, styles }: StylePanelContextProviderProps) {
22
+ const editor = useEditor()
23
+ const trackEvent = useUiEvents()
24
+
25
+ const onHistoryMark = useCallback((id: string) => editor.markHistoryStoppingPoint(id), [editor])
26
+ const showUiLabels = useValue('showUiLabels', () => editor.user.getShowUiLabels(), [editor])
27
+ const onValueChange = useCallback(
28
+ function <T>(style: StyleProp<T>, value: T) {
29
+ editor.run(() => {
30
+ if (editor.isIn('select')) {
31
+ editor.setStyleForSelectedShapes(style, value)
32
+ }
33
+ editor.setStyleForNextShapes(style, value)
34
+ editor.updateInstanceState({ isChangingStyle: true })
35
+ })
36
+
37
+ trackEvent('set-style', { source: 'style-panel', id: style.id, value: value as string })
38
+ },
39
+ [editor, trackEvent]
40
+ )
41
+
42
+ return (
43
+ <StylePanelContext.Provider
44
+ value={{
45
+ styles: styles,
46
+ showUiLabels,
47
+ onHistoryMark,
48
+ onValueChange,
49
+ }}
50
+ >
51
+ {children}
52
+ </StylePanelContext.Provider>
53
+ )
54
+ }
55
+
56
+ /** @public */
57
+ export function useStylePanelContext() {
58
+ const context = useContext(StylePanelContext)
59
+ if (!context) {
60
+ throw new Error('useStylePanelContext must be used within a StylePanelContextProvider')
61
+ }
62
+ return context
63
+ }
@@ -11,8 +11,10 @@ import {
11
11
  } from '../primitives/TldrawUiPopover'
12
12
  import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
13
13
  import { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'
14
+ import { useStylePanelContext } from './StylePanelContext'
14
15
 
15
- interface DoubleDropdownPickerProps<T extends string> {
16
+ /** @public */
17
+ export interface StylePanelDoubleDropdownPickerProps<T extends string> {
16
18
  uiTypeA: string
17
19
  uiTypeB: string
18
20
  label: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>
@@ -24,23 +26,27 @@ interface DoubleDropdownPickerProps<T extends string> {
24
26
  styleB: StyleProp<T>
25
27
  valueA: SharedStyle<T>
26
28
  valueB: SharedStyle<T>
27
- onValueChange(style: StyleProp<T>, value: T): void
29
+ onValueChange?(style: StyleProp<T>, value: T): void
28
30
  }
29
31
 
30
- function DoubleDropdownPickerInner<T extends string>({
31
- label,
32
- uiTypeA,
33
- uiTypeB,
34
- labelA,
35
- labelB,
36
- itemsA,
37
- itemsB,
38
- styleA,
39
- styleB,
40
- valueA,
41
- valueB,
42
- onValueChange,
43
- }: DoubleDropdownPickerProps<T>) {
32
+ function DoubleDropdownPickerInner<T extends string>(
33
+ props: StylePanelDoubleDropdownPickerProps<T>
34
+ ) {
35
+ const ctx = useStylePanelContext()
36
+ const {
37
+ label,
38
+ uiTypeA,
39
+ uiTypeB,
40
+ labelA,
41
+ labelB,
42
+ itemsA,
43
+ itemsB,
44
+ styleA,
45
+ styleB,
46
+ valueA,
47
+ valueB,
48
+ onValueChange = ctx.onValueChange,
49
+ } = props
44
50
  const editor = useEditor()
45
51
  const msg = useTranslation()
46
52
  const [isOpenA, setIsOpenA] = React.useState(false)
@@ -155,6 +161,9 @@ function DoubleDropdownPickerInner<T extends string>({
155
161
  }
156
162
 
157
163
  // need to memo like this to get generics
158
- export const DoubleDropdownPicker = React.memo(
159
- DoubleDropdownPickerInner
160
- ) as typeof DoubleDropdownPickerInner
164
+ /** @public @react */
165
+ export const StylePanelDoubleDropdownPicker = React.memo(DoubleDropdownPickerInner) as <
166
+ T extends string,
167
+ >(
168
+ props: StylePanelDoubleDropdownPickerProps<T>
169
+ ) => React.JSX.Element
@@ -0,0 +1,119 @@
1
+ import { SharedStyle, StyleProp, tlmenus, useEditor } from '@tldraw/editor'
2
+ import * as React from 'react'
3
+ import { StyleValuesForUi } from '../../../styles'
4
+ import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
5
+ import { useTranslation } from '../../hooks/useTranslation/useTranslation'
6
+ import { TLUiIconType } from '../../icon-types'
7
+ import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
8
+ import { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'
9
+ import {
10
+ TldrawUiPopover,
11
+ TldrawUiPopoverContent,
12
+ TldrawUiPopoverTrigger,
13
+ } from '../primitives/TldrawUiPopover'
14
+ import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
15
+ import { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'
16
+ import { useStylePanelContext } from './StylePanelContext'
17
+
18
+ /** @public */
19
+ export interface StylePanelDropdownPickerProps<T extends string> {
20
+ id: string
21
+ label?: TLUiTranslationKey | Exclude<string, TLUiTranslationKey>
22
+ uiType: string
23
+ stylePanelType: string
24
+ style: StyleProp<T>
25
+ value: SharedStyle<T>
26
+ items: StyleValuesForUi<T>
27
+ type: 'icon' | 'tool' | 'menu'
28
+ onValueChange?(style: StyleProp<T>, value: T): void
29
+ }
30
+
31
+ function DropdownPickerInner<T extends string>(props: StylePanelDropdownPickerProps<T>) {
32
+ const ctx = useStylePanelContext()
33
+ const {
34
+ id,
35
+ label,
36
+ uiType,
37
+ stylePanelType,
38
+ style,
39
+ items,
40
+ type,
41
+ value,
42
+ onValueChange = ctx.onValueChange,
43
+ } = props
44
+ const msg = useTranslation()
45
+ const editor = useEditor()
46
+ const [isOpen, setIsOpen] = React.useState(false)
47
+
48
+ const icon = React.useMemo(
49
+ () => items.find((item) => value.type === 'shared' && item.value === value.value)?.icon,
50
+ [items, value]
51
+ )
52
+
53
+ const stylePanelName = msg(`style-panel.${stylePanelType}` as TLUiTranslationKey)
54
+
55
+ const titleStr =
56
+ value.type === 'mixed'
57
+ ? msg('style-panel.mixed')
58
+ : stylePanelName + ' — ' + msg(`${uiType}-style.${value.value}` as TLUiTranslationKey)
59
+ const labelStr = label ? msg(label) : ''
60
+
61
+ const popoverId = `style panel ${id}`
62
+ return (
63
+ <TldrawUiToolbar label={stylePanelName}>
64
+ <TldrawUiPopover
65
+ id={popoverId}
66
+ open={isOpen}
67
+ onOpenChange={setIsOpen}
68
+ className="tlui-style-panel__dropdown-picker"
69
+ >
70
+ <TldrawUiPopoverTrigger>
71
+ <TldrawUiToolbarButton
72
+ type={type}
73
+ data-testid={`style.${uiType}`}
74
+ data-direction="left"
75
+ title={titleStr}
76
+ >
77
+ {labelStr && <TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>}
78
+ <TldrawUiButtonIcon icon={(icon as TLUiIconType) ?? 'mixed'} />
79
+ </TldrawUiToolbarButton>
80
+ </TldrawUiPopoverTrigger>
81
+ <TldrawUiPopoverContent side="left" align="center">
82
+ <TldrawUiToolbar orientation={items.length > 4 ? 'grid' : 'horizontal'} label={labelStr}>
83
+ <TldrawUiMenuContextProvider type="icons" sourceId="style-panel">
84
+ {items.map((item) => {
85
+ return (
86
+ <TldrawUiToolbarButton
87
+ key={item.value}
88
+ type="icon"
89
+ data-testid={`style.${uiType}.${item.value}`}
90
+ title={
91
+ stylePanelName +
92
+ ' — ' +
93
+ msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
94
+ }
95
+ isActive={icon === item.icon}
96
+ onClick={() => {
97
+ ctx.onHistoryMark('select style dropdown item')
98
+ onValueChange(style, item.value)
99
+ tlmenus.deleteOpenMenu(popoverId, editor.contextId)
100
+ setIsOpen(false)
101
+ }}
102
+ >
103
+ <TldrawUiButtonIcon icon={item.icon} />
104
+ </TldrawUiToolbarButton>
105
+ )
106
+ })}
107
+ </TldrawUiMenuContextProvider>
108
+ </TldrawUiToolbar>
109
+ </TldrawUiPopoverContent>
110
+ </TldrawUiPopover>
111
+ </TldrawUiToolbar>
112
+ )
113
+ }
114
+
115
+ // need to export like this to get generics
116
+ /** @public @react */
117
+ export const StylePanelDropdownPicker = React.memo(DropdownPickerInner) as <T extends string>(
118
+ props: StylePanelDropdownPickerProps<T>
119
+ ) => React.JSX.Element
@@ -0,0 +1,9 @@
1
+ /** @public */
2
+ export interface StylePanelSubheadingProps {
3
+ children: React.ReactNode
4
+ }
5
+
6
+ /** @public @react */
7
+ export function StylePanelSubheading({ children }: StylePanelSubheadingProps) {
8
+ return <h3 className="tlui-style-panel__subheading">{children}</h3>
9
+ }
@@ -2,9 +2,9 @@ import { preventDefault, TLShape, TLShapeId, useEditor } from '@tldraw/editor'
2
2
  import { useCallback, useEffect, useRef, useState } from 'react'
3
3
  import { useUiEvents } from '../../context/events'
4
4
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
5
- import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
6
5
  import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
7
6
  import { TldrawUiInput } from '../primitives/TldrawUiInput'
7
+ import { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
8
8
 
9
9
  /** @public */
10
10
  export interface AltTextEditorProps {
@@ -76,14 +76,15 @@ export function AltTextEditor({ shapeId, onClose, source }: AltTextEditorProps)
76
76
  disabled={isReadonly}
77
77
  />
78
78
  {!isReadonly && (
79
- <TldrawUiButton
79
+ <TldrawUiToolbarButton
80
80
  title={msg('tool.media-alt-text-confirm')}
81
+ data-testid="tool.media-alt-text-confirm"
81
82
  type="icon"
82
83
  onPointerDown={preventDefault}
83
84
  onClick={handleConfirm}
84
85
  >
85
86
  <TldrawUiButtonIcon small icon="check" />
86
- </TldrawUiButton>
87
+ </TldrawUiToolbarButton>
87
88
  )}
88
89
  </>
89
90
  )
@@ -22,7 +22,6 @@ import {
22
22
  import { useActions } from '../../context/actions'
23
23
  import { useUiEvents } from '../../context/events'
24
24
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
25
- import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
26
25
  import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
27
26
  import { TldrawUiButtonLabel } from '../primitives/Button/TldrawUiButtonLabel'
28
27
  import {
@@ -32,6 +31,7 @@ import {
32
31
  TldrawUiDropdownMenuTrigger,
33
32
  } from '../primitives/TldrawUiDropdownMenu'
34
33
  import { TldrawUiSlider } from '../primitives/TldrawUiSlider'
34
+ import { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
35
35
 
36
36
  /** @public */
37
37
  export interface DefaultImageToolbarContentProps {
@@ -226,9 +226,13 @@ export const DefaultImageToolbarContent = track(function DefaultImageToolbarCont
226
226
  />
227
227
  <TldrawUiDropdownMenuRoot id="image-toolbar-aspect-ratio">
228
228
  <TldrawUiDropdownMenuTrigger>
229
- <TldrawUiButton title={msg('tool.aspect-ratio')} type="icon">
229
+ <TldrawUiToolbarButton
230
+ title={msg('tool.aspect-ratio')}
231
+ type="icon"
232
+ data-testid="tool.image-aspect-ratio"
233
+ >
230
234
  <TldrawUiButtonIcon icon="corners" />
231
- </TldrawUiButton>
235
+ </TldrawUiToolbarButton>
232
236
  </TldrawUiDropdownMenuTrigger>
233
237
  <TldrawUiDropdownMenuContent side="top" align="center">
234
238
  {ASPECT_RATIO_OPTIONS.map((aspectRatio) => {
@@ -268,14 +272,15 @@ export const DefaultImageToolbarContent = track(function DefaultImageToolbarCont
268
272
  })}
269
273
  </TldrawUiDropdownMenuContent>
270
274
  </TldrawUiDropdownMenuRoot>
271
- <TldrawUiButton
275
+ <TldrawUiToolbarButton
272
276
  type="icon"
273
277
  onClick={onManipulatingEnd}
274
- data-testid="tool.image-confirm"
275
- style={{ borderLeft: '1px solid var(--color-divider)', marginLeft: '2px' }}
278
+ data-testid="tool.image-crop-confirm"
279
+ style={{ borderLeft: '1px solid var(--tl-color-divider)', marginLeft: '2px' }}
280
+ title={msg('tool.image-crop-confirm')}
276
281
  >
277
282
  <TldrawUiButtonIcon small icon="check" />
278
- </TldrawUiButton>
283
+ </TldrawUiToolbarButton>
279
284
  </>
280
285
  )
281
286
  }
@@ -283,33 +288,45 @@ export const DefaultImageToolbarContent = track(function DefaultImageToolbarCont
283
288
  return (
284
289
  <>
285
290
  {!isReadonly && (
286
- <TldrawUiButton type="icon" title={msg('tool.replace-media')} onClick={handleImageReplace}>
291
+ <TldrawUiToolbarButton
292
+ type="icon"
293
+ data-testid="tool.image-replace"
294
+ onClick={handleImageReplace}
295
+ title={msg('tool.replace-media')}
296
+ >
287
297
  <TldrawUiButtonIcon small icon="tool-media" />
288
- </TldrawUiButton>
298
+ </TldrawUiToolbarButton>
289
299
  )}
290
300
  {!isReadonly && (
291
- <TldrawUiButton type="icon" title={msg('tool.image-crop')} onClick={onManipulatingStart}>
301
+ <TldrawUiToolbarButton
302
+ type="icon"
303
+ title={msg('tool.image-crop')}
304
+ onClick={onManipulatingStart}
305
+ data-testid="tool.image-crop"
306
+ >
292
307
  <TldrawUiButtonIcon small icon="crop" />
293
- </TldrawUiButton>
308
+ </TldrawUiToolbarButton>
294
309
  )}
295
- <TldrawUiButton
310
+ <TldrawUiToolbarButton
296
311
  type="icon"
297
312
  title={msg('action.download-original')}
298
313
  onClick={handleImageDownload}
314
+ data-testid="tool.image-download"
299
315
  >
300
316
  <TldrawUiButtonIcon small icon="download" />
301
- </TldrawUiButton>
317
+ </TldrawUiToolbarButton>
302
318
  {(altText || !isReadonly) && (
303
- <TldrawUiButton
304
- type="normal"
319
+ <TldrawUiToolbarButton
320
+ type="icon"
305
321
  title={msg('tool.media-alt-text')}
322
+ data-testid="tool.image-alt-text"
306
323
  onClick={() => {
307
324
  trackEvent('alt-text-start', { source })
308
325
  onEditAltTextStart()
309
326
  }}
310
327
  >
311
328
  <TldrawUiButtonIcon small icon="alt" />
312
- </TldrawUiButton>
329
+ </TldrawUiToolbarButton>
313
330
  )}
314
331
  </>
315
332
  )
@@ -1,4 +1,5 @@
1
1
  import { useEditor, usePassThroughWheelEvents, useValue } from '@tldraw/editor'
2
+ import classNames from 'classnames'
2
3
  import { ReactNode, memo, useRef } from 'react'
3
4
  import { PORTRAIT_BREAKPOINT } from '../../constants'
4
5
  import { useBreakpoint } from '../../context/breakpoints'
@@ -6,6 +7,7 @@ import { useTldrawUiComponents } from '../../context/components'
6
7
  import { useReadonly } from '../../hooks/useReadonly'
7
8
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
8
9
  import { MobileStylePanel } from '../MobileStylePanel'
10
+ import { TldrawUiOrientationProvider } from '../primitives/layout'
9
11
  import { TldrawUiToolbar } from '../primitives/TldrawUiToolbar'
10
12
  import { DefaultToolbarContent } from './DefaultToolbarContent'
11
13
  import { OverflowingToolbar } from './OverflowingToolbar'
@@ -14,6 +16,11 @@ import { ToggleToolLockedButton } from './ToggleToolLockedButton'
14
16
  /** @public */
15
17
  export interface DefaultToolbarProps {
16
18
  children?: ReactNode
19
+ orientation?: 'horizontal' | 'vertical'
20
+ minItems?: number
21
+ minSizePx?: number
22
+ maxItems?: number
23
+ maxSizePx?: number
17
24
  }
18
25
 
19
26
  /**
@@ -24,7 +31,14 @@ export interface DefaultToolbarProps {
24
31
  * @public
25
32
  * @react
26
33
  */
27
- export const DefaultToolbar = memo(function DefaultToolbar({ children }: DefaultToolbarProps) {
34
+ export const DefaultToolbar = memo(function DefaultToolbar({
35
+ children,
36
+ orientation = 'horizontal',
37
+ minItems = 4,
38
+ minSizePx = 310,
39
+ maxItems = 8,
40
+ maxSizePx = 470,
41
+ }: DefaultToolbarProps) {
28
42
  const editor = useEditor()
29
43
  const msg = useTranslation()
30
44
  const breakpoint = useBreakpoint()
@@ -44,32 +58,49 @@ export const DefaultToolbar = memo(function DefaultToolbar({ children }: Default
44
58
  : breakpoint < PORTRAIT_BREAKPOINT.TABLET
45
59
 
46
60
  return (
47
- <div ref={ref} className="tlui-main-toolbar">
48
- <div className="tlui-main-toolbar__inner">
49
- <div className="tlui-main-toolbar__left">
50
- {!isReadonlyMode && (
51
- <div className="tlui-main-toolbar__extras">
52
- {showQuickActions && (
53
- <TldrawUiToolbar
54
- orientation="horizontal"
55
- className="tlui-main-toolbar__extras__controls"
56
- label={msg('actions-menu.title')}
57
- >
58
- {QuickActions && <QuickActions />}
59
- {ActionsMenu && <ActionsMenu />}
60
- </TldrawUiToolbar>
61
- )}
62
- <ToggleToolLockedButton activeToolId={activeToolId} />
61
+ <TldrawUiOrientationProvider
62
+ orientation={orientation}
63
+ tooltipSide={orientation === 'horizontal' ? 'top' : 'right'}
64
+ >
65
+ <div
66
+ ref={ref}
67
+ className={classNames('tlui-main-toolbar', `tlui-main-toolbar--${orientation}`)}
68
+ >
69
+ <div className="tlui-main-toolbar__inner">
70
+ <div className="tlui-main-toolbar__left">
71
+ {!isReadonlyMode && (
72
+ <div className="tlui-main-toolbar__extras">
73
+ {showQuickActions && (
74
+ <TldrawUiToolbar
75
+ orientation={orientation}
76
+ className="tlui-main-toolbar__extras__controls"
77
+ label={msg('actions-menu.title')}
78
+ >
79
+ {QuickActions && <QuickActions />}
80
+ {ActionsMenu && <ActionsMenu />}
81
+ </TldrawUiToolbar>
82
+ )}
83
+ <ToggleToolLockedButton activeToolId={activeToolId} />
84
+ </div>
85
+ )}
86
+ <OverflowingToolbar
87
+ orientation={orientation}
88
+ sizingParentClassName="tlui-main-toolbar"
89
+ minItems={minItems}
90
+ maxItems={maxItems}
91
+ minSizePx={minSizePx}
92
+ maxSizePx={maxSizePx}
93
+ >
94
+ {children ?? <DefaultToolbarContent />}
95
+ </OverflowingToolbar>
96
+ </div>
97
+ {breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && !isReadonlyMode && (
98
+ <div className="tlui-main-toolbar__tools tlui-main-toolbar__mobile-style-panel">
99
+ <MobileStylePanel />
63
100
  </div>
64
101
  )}
65
- <OverflowingToolbar>{children ?? <DefaultToolbarContent />}</OverflowingToolbar>
66
102
  </div>
67
- {breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM && !isReadonlyMode && (
68
- <div className="tlui-main-toolbar__tools">
69
- <MobileStylePanel />
70
- </div>
71
- )}
72
103
  </div>
73
- </div>
104
+ </TldrawUiOrientationProvider>
74
105
  )
75
106
  })