tldraw 3.15.1 → 3.16.0-canary.03ed24d72068

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 (360) hide show
  1. package/dist-cjs/index.d.ts +198 -9
  2. package/dist-cjs/index.js +24 -2
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
  5. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  6. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  7. package/dist-cjs/lib/defaultExternalContentHandlers.js +1 -0
  8. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  9. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +25 -39
  10. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  11. package/dist-cjs/lib/shapes/arrow/arrowLabel.js +16 -4
  12. package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
  13. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
  14. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  16. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  17. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  18. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  19. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  20. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  21. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  22. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  23. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +12 -12
  24. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  25. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  26. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  27. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +2 -2
  28. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
  30. package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
  31. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
  32. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  33. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
  34. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
  35. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +20 -2
  36. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  37. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
  38. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/shared/ShapeFill.js +5 -5
  40. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  41. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +10 -1
  42. package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
  43. package/dist-cjs/lib/shapes/text/TextShapeUtil.js +2 -2
  44. package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
  45. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  46. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  47. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +43 -22
  48. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  49. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +2 -15
  50. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  51. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +5 -0
  52. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  53. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +8 -0
  54. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  55. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +8 -0
  56. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  57. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +8 -0
  58. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  59. package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
  60. package/dist-cjs/lib/ui/TldrawUi.js +14 -0
  61. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  62. package/dist-cjs/lib/ui/components/AccessibilityMenu.js +35 -0
  63. package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +7 -0
  64. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +12 -3
  65. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  66. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
  67. package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
  68. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +40 -0
  69. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  70. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +3 -3
  71. package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
  72. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  73. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  74. package/dist-cjs/lib/ui/components/MobileStylePanel.js +5 -3
  75. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  76. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
  77. package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
  78. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
  79. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  80. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
  81. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
  82. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
  83. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
  84. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +2 -0
  85. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
  86. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +171 -140
  87. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  88. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
  89. package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
  90. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
  91. package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
  92. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  93. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  94. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
  95. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  96. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
  97. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  98. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +5 -4
  99. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  100. package/dist-cjs/lib/ui/components/menu-items.js +6 -0
  101. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  102. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
  103. package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
  104. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  105. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  106. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
  107. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
  108. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -0
  109. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  110. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +30 -7
  111. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  112. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +253 -0
  113. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +7 -0
  114. package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
  115. package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
  116. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  117. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  118. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  119. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +153 -20
  120. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  121. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +3 -2
  122. package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
  123. package/dist-cjs/lib/ui/context/actions.js +29 -7
  124. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  125. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  126. package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
  127. package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
  128. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  129. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  130. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +7 -0
  131. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  132. package/dist-cjs/lib/ui/kbd-utils.js +2 -1
  133. package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
  134. package/dist-cjs/lib/ui/version.js +3 -3
  135. package/dist-cjs/lib/ui/version.js.map +1 -1
  136. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
  137. package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
  138. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +3 -2
  139. package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
  140. package/dist-esm/index.d.mts +198 -9
  141. package/dist-esm/index.mjs +40 -3
  142. package/dist-esm/index.mjs.map +2 -2
  143. package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
  144. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  145. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  146. package/dist-esm/lib/defaultExternalContentHandlers.mjs +1 -0
  147. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  148. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +28 -39
  149. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  150. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +19 -5
  151. package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
  152. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
  153. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  154. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  155. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  156. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +3 -0
  157. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  158. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +4 -3
  159. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  160. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  161. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  162. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +13 -12
  163. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  164. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  165. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  166. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -2
  167. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  168. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
  169. package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
  170. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
  171. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  172. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
  173. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
  174. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +21 -2
  175. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  176. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
  177. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  178. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +6 -5
  179. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  180. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +10 -1
  181. package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
  182. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +3 -2
  183. package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
  184. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  185. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  186. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +43 -22
  187. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  188. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +2 -15
  189. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  190. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +5 -0
  191. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  192. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +8 -0
  193. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  194. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +8 -0
  195. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  196. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +8 -0
  197. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  198. package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
  199. package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
  200. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  201. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +19 -0
  202. package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +7 -0
  203. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +12 -3
  204. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  205. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
  206. package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
  207. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +40 -0
  208. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  209. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +3 -5
  210. package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
  211. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  212. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  213. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +6 -3
  214. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  215. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
  216. package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
  217. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
  218. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  219. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
  220. package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
  221. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
  222. package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
  223. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +3 -1
  224. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
  225. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +171 -140
  226. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  227. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
  228. package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
  229. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
  230. package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
  231. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  232. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  233. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
  234. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  235. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
  236. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  237. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +5 -4
  238. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  239. package/dist-esm/lib/ui/components/menu-items.mjs +6 -0
  240. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  241. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +6 -6
  242. package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
  243. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
  244. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  245. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
  246. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  247. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +1 -0
  248. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  249. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +30 -7
  250. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  251. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +230 -0
  252. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +7 -0
  253. package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
  254. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
  255. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  256. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  257. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  258. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +161 -22
  259. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  260. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +3 -2
  261. package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
  262. package/dist-esm/lib/ui/context/actions.mjs +29 -7
  263. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  264. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  265. package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
  266. package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
  267. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  268. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +7 -0
  269. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  270. package/dist-esm/lib/ui/kbd-utils.mjs +2 -1
  271. package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
  272. package/dist-esm/lib/ui/version.mjs +3 -3
  273. package/dist-esm/lib/ui/version.mjs.map +1 -1
  274. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
  275. package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
  276. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +3 -2
  277. package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
  278. package/package.json +3 -3
  279. package/src/index.ts +29 -1
  280. package/src/lib/canvas/TldrawCropHandles.tsx +2 -0
  281. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  282. package/src/lib/defaultExternalContentHandlers.ts +2 -1
  283. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +5 -5
  284. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +29 -42
  285. package/src/lib/shapes/arrow/arrowLabel.ts +23 -3
  286. package/src/lib/shapes/arrow/arrowTargetState.ts +2 -1
  287. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  288. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +3 -0
  289. package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
  290. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  291. package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -14
  292. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  293. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
  294. package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
  295. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
  296. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
  297. package/src/lib/shapes/line/LineShapeUtil.tsx +25 -3
  298. package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
  299. package/src/lib/shapes/shared/ShapeFill.tsx +6 -5
  300. package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +11 -1
  301. package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
  302. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  303. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +54 -30
  304. package/src/lib/tools/SelectTool/childStates/Idle.ts +2 -24
  305. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +7 -0
  306. package/src/lib/tools/SelectTool/childStates/Resizing.ts +12 -1
  307. package/src/lib/tools/SelectTool/childStates/Rotating.ts +11 -0
  308. package/src/lib/tools/SelectTool/childStates/Translating.ts +11 -1
  309. package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +1 -0
  310. package/src/lib/ui/TldrawUi.tsx +17 -2
  311. package/src/lib/ui/components/AccessibilityMenu.tsx +20 -0
  312. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
  313. package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
  314. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +32 -0
  315. package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +4 -4
  316. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  317. package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
  318. package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
  319. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
  320. package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
  321. package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
  322. package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +3 -1
  323. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +146 -107
  324. package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
  325. package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
  326. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  327. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
  328. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
  329. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +17 -12
  330. package/src/lib/ui/components/menu-items.tsx +8 -0
  331. package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
  332. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
  333. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
  334. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +1 -0
  335. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +51 -12
  336. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +301 -0
  337. package/src/lib/ui/components/primitives/layout.tsx +107 -0
  338. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  339. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  340. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +220 -19
  341. package/src/lib/ui/context/TldrawUiContextProvider.tsx +23 -20
  342. package/src/lib/ui/context/actions.tsx +29 -7
  343. package/src/lib/ui/context/events.tsx +4 -2
  344. package/src/lib/ui/hooks/menu-hooks.ts +1 -0
  345. package/src/lib/ui/hooks/useTools.tsx +138 -10
  346. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +7 -0
  347. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +7 -0
  348. package/src/lib/ui/kbd-utils.ts +2 -1
  349. package/src/lib/ui/version.ts +3 -3
  350. package/src/lib/ui.css +406 -292
  351. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +16 -2
  352. package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
  353. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +24 -3
  354. package/src/lib/utils/tldr/buildFromV1Document.ts +2 -1
  355. package/src/test/SelectTool.test.ts +37 -11
  356. package/src/test/arrows-megabus.test.tsx +12 -6
  357. package/src/test/commands/deletePage.test.ts +84 -1
  358. package/src/test/inner-outer-margin.test.ts +315 -0
  359. package/src/test/shapeutils.test.ts +394 -45
  360. package/tldraw.css +703 -603
@@ -1,4 +1,4 @@
1
- import { HALF_PI, TLArrowShape, TLShapeId, createShapeId } from '@tldraw/editor'
1
+ import { HALF_PI, TLArrowShape, TLShapeId, createShapeId, toRichText } from '@tldraw/editor'
2
2
  import { TestEditor } from '../../../test/TestEditor'
3
3
  import { createOrUpdateArrowBinding, getArrowBindings } from './shared'
4
4
 
@@ -333,7 +333,7 @@ describe('Arrow labels', () => {
333
333
  editor.setCurrentTool('arrow').pointerDown(10, 10).pointerMove(100, 100).pointerUp()
334
334
  const arrowId = editor.getOnlySelectedShape()!.id
335
335
  editor.updateShapes<TLArrowShape>([
336
- { id: arrowId, type: 'arrow', props: { text: 'Test Label' } },
336
+ { id: arrowId, type: 'arrow', props: { richText: toRichText('Test Label') } },
337
337
  ])
338
338
  })
339
339
 
@@ -341,7 +341,7 @@ describe('Arrow labels', () => {
341
341
  const arrowId = editor.getOnlySelectedShape()!.id
342
342
  expect(arrow(arrowId)).toMatchObject({
343
343
  props: {
344
- text: 'Test Label',
344
+ richText: toRichText('Test Label'),
345
345
  },
346
346
  })
347
347
  })
@@ -349,11 +349,11 @@ describe('Arrow labels', () => {
349
349
  it('should update the label of an arrow', () => {
350
350
  const arrowId = editor.getOnlySelectedShape()!.id
351
351
  editor.updateShapes<TLArrowShape>([
352
- { id: arrowId, type: 'arrow', props: { text: 'New Label' } },
352
+ { id: arrowId, type: 'arrow', props: { richText: toRichText('New Label') } },
353
353
  ])
354
354
  expect(arrow(arrowId)).toMatchObject({
355
355
  props: {
356
- text: 'New Label',
356
+ richText: toRichText('New Label'),
357
357
  },
358
358
  })
359
359
  })
@@ -31,13 +31,16 @@ import {
31
31
  clamp,
32
32
  debugFlags,
33
33
  exhaustiveSwitchError,
34
+ getColorValue,
34
35
  getDefaultColorTheme,
36
+ getFontsFromRichText,
35
37
  invLerp,
36
38
  lerp,
37
39
  mapObjectMapValues,
38
40
  maybeSnapToGrid,
39
41
  structuredClone,
40
42
  toDomPrecision,
43
+ toRichText,
41
44
  track,
42
45
  useEditor,
43
46
  useIsEditing,
@@ -46,12 +49,11 @@ import {
46
49
  } from '@tldraw/editor'
47
50
  import React, { useMemo } from 'react'
48
51
  import { updateArrowTerminal } from '../../bindings/arrow/ArrowBindingUtil'
52
+ import { isEmptyRichText, renderPlaintextFromRichText } from '../../utils/text/richText'
49
53
  import { PathBuilder } from '../shared/PathBuilder'
50
- import { PlainTextLabel } from '../shared/PlainTextLabel'
54
+ import { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'
51
55
  import { ShapeFill } from '../shared/ShapeFill'
52
- import { SvgTextLabel } from '../shared/SvgTextLabel'
53
56
  import { ARROW_LABEL_PADDING, STROKE_SIZES, TEXT_PROPS } from '../shared/default-shape-constants'
54
- import { DefaultFontFaces } from '../shared/defaultFonts'
55
57
  import { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'
56
58
  import { useDefaultColorTheme } from '../shared/useDefaultColorTheme'
57
59
  import { getArrowBodyPath, getArrowHandlePath } from './ArrowPath'
@@ -156,8 +158,13 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
156
158
  }
157
159
 
158
160
  override getFontFaces(shape: TLArrowShape) {
159
- if (!shape.props.text) return EMPTY_ARRAY
160
- return [DefaultFontFaces[`tldraw_${shape.props.font}`].normal.normal]
161
+ if (isEmptyRichText(shape.props.richText)) return EMPTY_ARRAY
162
+
163
+ return getFontsFromRichText(this.editor, shape.props.richText, {
164
+ family: `tldraw_${shape.props.font}`,
165
+ weight: 'normal',
166
+ style: 'normal',
167
+ })
161
168
  }
162
169
 
163
170
  override getDefaultProps(): TLArrowShape['props'] {
@@ -174,7 +181,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
174
181
  end: { x: 2, y: 0 },
175
182
  arrowheadStart: 'none',
176
183
  arrowheadEnd: 'arrow',
177
- text: '',
184
+ richText: toRichText(''),
178
185
  labelPosition: 0.5,
179
186
  font: 'draw',
180
187
  scale: 1,
@@ -204,7 +211,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
204
211
  : new Polyline2d({ points: info.route.points })
205
212
 
206
213
  let labelGeom
207
- if (isEditing || shape.props.text.trim()) {
214
+ if (isEditing || !isEmptyRichText(shape.props.richText)) {
208
215
  const labelPosition = getArrowLabelPosition(this.editor, shape)
209
216
  if (debugFlags.debugGeometry.get()) {
210
217
  debugGeom.push(...labelPosition.debugGeom)
@@ -276,7 +283,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
276
283
  }
277
284
 
278
285
  override getText(shape: TLArrowShape) {
279
- return shape.props.text
286
+ return renderPlaintextFromRichText(this.editor, shape.props.richText)
280
287
  }
281
288
 
282
289
  override onHandleDrag(shape: TLArrowShape, info: TLHandleDragInfo<TLArrowShape>) {
@@ -757,7 +764,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
757
764
  const labelPosition = getArrowLabelPosition(this.editor, shape)
758
765
  const isSelected = shape.id === this.editor.getOnlySelectedShapeId()
759
766
  const isEditing = this.editor.getEditingShapeId() === shape.id
760
- const showArrowLabel = isEditing || shape.props.text
767
+ const showArrowLabel = isEditing || !isEmptyRichText(shape.props.richText)
761
768
 
762
769
  return (
763
770
  <>
@@ -771,17 +778,16 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
771
778
  )}
772
779
  </SVGContainer>
773
780
  {showArrowLabel && (
774
- <PlainTextLabel
781
+ <RichTextLabel
775
782
  shapeId={shape.id}
776
- classNamePrefix="tl-arrow"
777
783
  type="arrow"
778
784
  font={shape.props.font}
779
785
  fontSize={getArrowLabelFontSize(shape)}
780
786
  lineHeight={TEXT_PROPS.lineHeight}
781
787
  align="middle"
782
788
  verticalAlign="middle"
783
- text={shape.props.text}
784
- labelColor={theme[shape.props.labelColor].solid}
789
+ labelColor={getColorValue(theme, shape.props.labelColor, 'solid')}
790
+ richText={shape.props.richText}
785
791
  textWidth={labelPosition.box.w - ARROW_LABEL_PADDING * 2 * shape.props.scale}
786
792
  isSelected={isSelected}
787
793
  padding={0}
@@ -806,9 +812,9 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
806
812
  const { start, end } = getArrowTerminalsInArrowSpace(this.editor, shape, info?.bindings)
807
813
  const geometry = this.editor.getShapeGeometry<Group2d>(shape)
808
814
  const bounds = geometry.bounds
815
+ const isEmpty = isEmptyRichText(shape.props.richText)
809
816
 
810
- const labelGeometry =
811
- isEditing || shape.props.text.trim() ? (geometry.children[1] as Rectangle2d) : null
817
+ const labelGeometry = isEditing || !isEmpty ? (geometry.children[1] as Rectangle2d) : null
812
818
 
813
819
  if (Vec.Equals(start, end)) return null
814
820
 
@@ -847,7 +853,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
847
853
  <defs>
848
854
  <ArrowClipPath
849
855
  radius={3.5 * shape.props.scale}
850
- hasText={shape.props.text.trim().length > 0}
856
+ hasText={!isEmpty}
851
857
  bounds={bounds}
852
858
  labelBounds={labelBounds}
853
859
  as={clipStartArrowhead && as ? as : ''}
@@ -905,7 +911,7 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
905
911
  }
906
912
 
907
913
  override onEditStart(shape: TLArrowShape) {
908
- if (shape.props.text.trim() === '') {
914
+ if (isEmptyRichText(shape.props.richText)) {
909
915
  // editing text for the first time, so set the position to the default:
910
916
  const labelPosition = getArrowLabelDefaultPosition(this.editor, shape)
911
917
  this.editor.updateShape<TLArrowShape>({
@@ -916,26 +922,6 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
916
922
  }
917
923
  }
918
924
 
919
- override onEditEnd(shape: TLArrowShape) {
920
- const {
921
- id,
922
- type,
923
- props: { text },
924
- } = shape
925
-
926
- if (text.trimEnd() !== shape.props.text) {
927
- this.editor.updateShapes<TLArrowShape>([
928
- {
929
- id,
930
- type,
931
- props: {
932
- text: text.trimEnd(),
933
- },
934
- },
935
- ])
936
- }
937
- }
938
-
939
925
  override toSvg(shape: TLArrowShape, ctx: SvgExportContext) {
940
926
  ctx.addExportDef(getFillDefForExport(shape.props.fill))
941
927
  const theme = getDefaultColorTheme(ctx)
@@ -944,13 +930,13 @@ export class ArrowShapeUtil extends ShapeUtil<TLArrowShape> {
944
930
  return (
945
931
  <g transform={`scale(${scaleFactor})`}>
946
932
  <ArrowSvg shape={shape} shouldDisplayHandles={false} />
947
- <SvgTextLabel
933
+ <RichTextSVG
948
934
  fontSize={getArrowLabelFontSize(shape)}
949
935
  font={shape.props.font}
950
936
  align="middle"
951
937
  verticalAlign="middle"
952
- text={shape.props.text}
953
- labelColor={theme[shape.props.labelColor].solid}
938
+ labelColor={getColorValue(theme, shape.props.labelColor, 'solid')}
939
+ richText={shape.props.richText}
954
940
  bounds={getArrowLabelPosition(this.editor, shape)
955
941
  .box.clone()
956
942
  .expandBy(-ARROW_LABEL_PADDING * shape.props.scale)}
@@ -1031,6 +1017,7 @@ const ArrowSvg = track(function ArrowSvg({
1031
1017
  if (!geometry) return null
1032
1018
  const bounds = Box.ZeroFix(geometry.bounds)
1033
1019
  const bindings = getArrowBindings(editor, shape)
1020
+ const isEmpty = isEmptyRichText(shape.props.richText)
1034
1021
 
1035
1022
  if (!info?.isValid) return null
1036
1023
 
@@ -1081,7 +1068,7 @@ const ArrowSvg = track(function ArrowSvg({
1081
1068
  <clipPath id={clipPathId}>
1082
1069
  <ArrowClipPath
1083
1070
  radius={3.5 * shape.props.scale}
1084
- hasText={isEditing || shape.props.text.trim().length > 0}
1071
+ hasText={isEditing || !isEmpty}
1085
1072
  bounds={bounds}
1086
1073
  labelBounds={labelPosition.box}
1087
1074
  as={clipStartArrowhead && as ? as : ''}
@@ -1091,7 +1078,7 @@ const ArrowSvg = track(function ArrowSvg({
1091
1078
  </defs>
1092
1079
  <g
1093
1080
  fill="none"
1094
- stroke={theme[shape.props.color].solid}
1081
+ stroke={getColorValue(theme, shape.props.color, 'solid')}
1095
1082
  strokeWidth={strokeWidth}
1096
1083
  strokeLinejoin="round"
1097
1084
  strokeLinecap="round"
@@ -9,13 +9,17 @@ import {
9
9
  Polygon2d,
10
10
  Polyline2d,
11
11
  TLArrowShape,
12
+ TLShape,
12
13
  Vec,
13
14
  VecLike,
14
15
  clamp,
15
16
  createComputedCache,
16
17
  exhaustiveSwitchError,
17
18
  getChangedKeys,
19
+ pointInPolygon,
20
+ toRichText,
18
21
  } from '@tldraw/editor'
22
+ import { isEmptyRichText, renderHtmlFromRichTextForMeasurement } from '../../utils/text/richText'
19
23
  import {
20
24
  ARROW_LABEL_FONT_SIZES,
21
25
  ARROW_LABEL_PADDING,
@@ -59,14 +63,18 @@ const labelSizeCache = createComputedCache(
59
63
 
60
64
  const bodyGeom = getArrowBodyGeometry(editor, shape)
61
65
  // We use 'i' as a default label to measure against as a minimum width.
62
- const text = shape.props.text || 'i'
66
+ const isEmpty = isEmptyRichText(shape.props.richText)
67
+ const html = renderHtmlFromRichTextForMeasurement(
68
+ editor,
69
+ isEmpty ? toRichText('i') : shape.props.richText
70
+ )
63
71
 
64
72
  const bodyBounds = bodyGeom.bounds
65
73
 
66
74
  const fontSize = getArrowLabelFontSize(shape)
67
75
 
68
76
  // First we measure the text with no constraints
69
- const { w, h } = editor.textMeasure.measureText(text, {
77
+ const { w, h } = editor.textMeasure.measureHtml(html, {
70
78
  ...TEXT_PROPS,
71
79
  fontFamily: FONT_FAMILIES[shape.props.font],
72
80
  fontSize,
@@ -96,7 +104,7 @@ const labelSizeCache = createComputedCache(
96
104
  }
97
105
 
98
106
  if (shouldSquish) {
99
- const { w: squishedWidth, h: squishedHeight } = editor.textMeasure.measureText(text, {
107
+ const { w: squishedWidth, h: squishedHeight } = editor.textMeasure.measureHtml(html, {
100
108
  ...TEXT_PROPS,
101
109
  fontFamily: FONT_FAMILIES[shape.props.font],
102
110
  fontSize,
@@ -292,3 +300,15 @@ export function getArrowLabelDefaultPosition(editor: Editor, shape: TLArrowShape
292
300
  exhaustiveSwitchError(info, 'type')
293
301
  }
294
302
  }
303
+
304
+ /** @internal */
305
+ export function isOverArrowLabel(editor: Editor, shape: TLShape) {
306
+ if (!editor.isShapeOfType<TLArrowShape>(shape, 'arrow')) return false
307
+
308
+ const pointInShapeSpace = editor.getPointInShapeSpace(shape, editor.inputs.currentPagePoint)
309
+ // How should we handle multiple labels? Do shapes ever have multiple labels?
310
+ const labelGeometry = editor.getShapeGeometry<Group2d>(shape).children[1]
311
+ // Knowing what we know about arrows... if the shape has no text in its label,
312
+ // then the label geometry should not be there.
313
+ return labelGeometry && pointInPolygon(pointInShapeSpace, labelGeometry.vertices)
314
+ }
@@ -94,7 +94,7 @@ export function updateArrowTargetState({
94
94
  const target = editor.getShapeAtPoint(pointInPageSpace, {
95
95
  hitInside: true,
96
96
  hitFrameInside: true,
97
- margin: arrowKind === 'elbow' ? 8 : 0,
97
+ margin: arrowKind === 'elbow' ? 8 : [8, 0],
98
98
  filter: (targetShape) => {
99
99
  return (
100
100
  !targetShape.isLocked &&
@@ -187,6 +187,7 @@ export function updateArrowTargetState({
187
187
  }
188
188
 
189
189
  const shouldSnapCenter = !isExact && precise && targetGeometryInTargetSpace.isClosed
190
+ // const shouldSnapEdges = !isExact && (precise || !targetGeometryInTargetSpace.isClosed)
190
191
  const shouldSnapEdges =
191
192
  !isExact && ((precise && arrowKind === 'elbow') || !targetGeometryInTargetSpace.isClosed)
192
193
  const shouldSnapEdgePoints =
@@ -98,7 +98,7 @@ export function ElbowArrowDebug({ arrow }: { arrow: TLArrowShape }) {
98
98
  y={fullBox.minY - 3}
99
99
  fontSize={10}
100
100
  fill="black"
101
- stroke="var(--color-background)"
101
+ stroke="var(--tl-color-background)"
102
102
  strokeWidth={2}
103
103
  paintOrder="stroke"
104
104
  >
@@ -109,7 +109,7 @@ export function ElbowArrowDebug({ arrow }: { arrow: TLArrowShape }) {
109
109
  y={info.A.expanded.y}
110
110
  fontSize={10}
111
111
  fill="black"
112
- stroke="var(--color-background)"
112
+ stroke="var(--tl-color-background)"
113
113
  strokeWidth={2}
114
114
  paintOrder="stroke"
115
115
  >
@@ -121,7 +121,7 @@ export function ElbowArrowDebug({ arrow }: { arrow: TLArrowShape }) {
121
121
  y={info.B.expanded.y}
122
122
  fontSize={10}
123
123
  fill="black"
124
- stroke="var(--color-background)"
124
+ stroke="var(--tl-color-background)"
125
125
  strokeWidth={2}
126
126
  paintOrder="stroke"
127
127
  >
@@ -118,6 +118,7 @@ export class Pointing extends StateNode {
118
118
  const change = util.onHandleDrag?.(shape, {
119
119
  handle: { ...startHandle, x: 0, y: 0 },
120
120
  isPrecise: true,
121
+ isCreatingShape: true,
121
122
  initial: initial,
122
123
  })
123
124
 
@@ -145,6 +146,7 @@ export class Pointing extends StateNode {
145
146
  const change = util.onHandleDrag?.(shape, {
146
147
  handle: { ...startHandle, x: 0, y: 0 },
147
148
  isPrecise: this.isPrecise,
149
+ isCreatingShape: true,
148
150
  initial: initial,
149
151
  })
150
152
 
@@ -162,6 +164,7 @@ export class Pointing extends StateNode {
162
164
  const change = util.onHandleDrag?.(this.editor.getShape(shape)!, {
163
165
  handle: { ...endHandle, x: point.x, y: point.y },
164
166
  isPrecise: false,
167
+ isCreatingShape: true,
165
168
  initial: initial,
166
169
  })
167
170
 
@@ -14,6 +14,7 @@ import {
14
14
  VecLike,
15
15
  drawShapeMigrations,
16
16
  drawShapeProps,
17
+ getColorValue,
17
18
  last,
18
19
  lerp,
19
20
  rng,
@@ -289,7 +290,7 @@ function DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverrid
289
290
  <path
290
291
  d={svgInk(allPointsFromSegments, options)}
291
292
  strokeLinecap="round"
292
- fill={theme[shape.props.color].solid}
293
+ fill={getColorValue(theme, shape.props.color, 'solid')}
293
294
  />
294
295
  </>
295
296
  )
@@ -313,8 +314,8 @@ function DrawShapeSvg({ shape, zoomOverride }: { shape: TLDrawShape; zoomOverrid
313
314
  <path
314
315
  d={solidStrokePath}
315
316
  strokeLinecap="round"
316
- fill={isDot ? theme[shape.props.color].solid : 'none'}
317
- stroke={theme[shape.props.color].solid}
317
+ fill={isDot ? getColorValue(theme, shape.props.color, 'solid') : 'none'}
318
+ stroke={getColorValue(theme, shape.props.color, 'solid')}
318
319
  strokeWidth={sw}
319
320
  strokeDasharray={isDot ? 'none' : getDrawShapeStrokeDashArray(shape, sw, dotAdjustment)}
320
321
  strokeDashoffset="0"
@@ -144,7 +144,7 @@ export class EmbedShapeUtil extends BaseBoxShapeUtil<TLEmbedShape> {
144
144
  border: 0,
145
145
  boxShadow: getRotatedBoxShadow(pageRotation),
146
146
  borderRadius: embedInfo?.definition.overrideOutlineRadius ?? 8,
147
- background: embedInfo?.definition.backgroundColor ?? 'var(--color-background)',
147
+ background: embedInfo?.definition.backgroundColor ?? 'var(--tl-color-background)',
148
148
  width: w,
149
149
  height: h,
150
150
  }}
@@ -19,6 +19,7 @@ import {
19
19
  compact,
20
20
  frameShapeMigrations,
21
21
  frameShapeProps,
22
+ getColorValue,
22
23
  getDefaultColorTheme,
23
24
  lerp,
24
25
  resizeBox,
@@ -220,13 +221,16 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
220
221
  )
221
222
 
222
223
  const showFrameColors = this.options.showColors
223
-
224
- const color = theme[shape.props.color]
225
- const frameFill = showFrameColors ? color.frame.fill : theme.black.frame.fill
226
- const frameStroke = showFrameColors ? color.frame.stroke : theme.black.frame.stroke
227
- const frameHeadingStroke = showFrameColors ? color.frame.headingStroke : theme.background
228
- const frameHeadingFill = showFrameColors ? color.frame.headingFill : theme.background
229
- const frameHeadingText = showFrameColors ? color.frame.text : theme.text
224
+ const colorToUse = showFrameColors ? shape.props.color : 'black'
225
+ const frameFill = getColorValue(theme, colorToUse, 'frameFill')
226
+ const frameStroke = getColorValue(theme, colorToUse, 'frameStroke')
227
+ const frameHeadingStroke = showFrameColors
228
+ ? getColorValue(theme, colorToUse, 'frameHeadingStroke')
229
+ : theme.background
230
+ const frameHeadingFill = showFrameColors
231
+ ? getColorValue(theme, colorToUse, 'frameHeadingFill')
232
+ : theme.background
233
+ const frameHeadingText = getColorValue(theme, colorToUse, 'frameText')
230
234
 
231
235
  return (
232
236
  <>
@@ -277,13 +281,16 @@ export class FrameShapeUtil extends BaseBoxShapeUtil<TLFrameShape> {
277
281
  const text = createTextJsxFromSpans(this.editor, spans, opts)
278
282
 
279
283
  const showFrameColors = this.options.showColors
280
-
281
- const color = theme[shape.props.color]
282
- const frameFill = showFrameColors ? color.frame.fill : theme.black.frame.fill
283
- const frameStroke = showFrameColors ? color.frame.stroke : theme.black.frame.stroke
284
- const frameHeadingStroke = showFrameColors ? color.frame.headingStroke : theme.background
285
- const frameHeadingFill = showFrameColors ? color.frame.headingFill : theme.background
286
- const frameHeadingText = showFrameColors ? color.frame.text : theme.text
284
+ const colorToUse = showFrameColors ? shape.props.color : 'black'
285
+ const frameFill = getColorValue(theme, colorToUse, 'frameFill')
286
+ const frameStroke = getColorValue(theme, colorToUse, 'frameStroke')
287
+ const frameHeadingStroke = showFrameColors
288
+ ? getColorValue(theme, colorToUse, 'frameHeadingStroke')
289
+ : theme.background
290
+ const frameHeadingFill = showFrameColors
291
+ ? getColorValue(theme, colorToUse, 'frameHeadingFill')
292
+ : theme.background
293
+ const frameHeadingText = getColorValue(theme, colorToUse, 'frameText')
287
294
 
288
295
  return (
289
296
  <>
@@ -64,7 +64,7 @@ export const FrameHeading = memo(function FrameHeading({
64
64
  overflow: isEditing ? 'visible' : 'hidden',
65
65
  maxWidth: `calc(var(--tl-zoom) * ${
66
66
  side === 0 || side === 2 ? Math.ceil(width) : Math.ceil(height)
67
- }px + ${showColors ? '0px' : 'var(--frame-offset-width)'})`,
67
+ }px + ${showColors ? '0px' : 'var(--tl-frame-offset-width)'})`,
68
68
  bottom: '100%',
69
69
  transform: `${translation} scale(var(--tl-scale)) translateX(${offsetX}px)`,
70
70
  }}
@@ -18,6 +18,7 @@ import {
18
18
  exhaustiveSwitchError,
19
19
  geoShapeMigrations,
20
20
  geoShapeProps,
21
+ getColorValue,
21
22
  getDefaultColorTheme,
22
23
  getFontsFromRichText,
23
24
  isEqual,
@@ -220,7 +221,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
220
221
  verticalAlign={verticalAlign}
221
222
  richText={richText}
222
223
  isSelected={isOnlySelected}
223
- labelColor={theme[props.labelColor].solid}
224
+ labelColor={getColorValue(theme, props.labelColor, 'solid')}
224
225
  wrap
225
226
  />
226
227
  </HTMLContainer>
@@ -278,7 +279,7 @@ export class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {
278
279
  align={props.align}
279
280
  verticalAlign={props.verticalAlign}
280
281
  richText={props.richText}
281
- labelColor={theme[props.labelColor].solid}
282
+ labelColor={getColorValue(theme, props.labelColor, 'solid')}
282
283
  bounds={bounds}
283
284
  padding={LABEL_PADDING}
284
285
  />
@@ -1,4 +1,4 @@
1
- import { TLGeoShape } from '@tldraw/editor'
1
+ import { getColorValue, TLGeoShape } from '@tldraw/editor'
2
2
  import { ShapeFill } from '../../shared/ShapeFill'
3
3
  import { STROKE_SIZES } from '../../shared/default-shape-constants'
4
4
  import { useDefaultColorTheme } from '../../shared/useDefaultColorTheme'
@@ -33,7 +33,7 @@ export function GeoShapeBody({
33
33
  strokeWidth,
34
34
  forceSolid,
35
35
  randomSeed: shape.id,
36
- props: { fill: 'none', stroke: theme[color].solid },
36
+ props: { fill: 'none', stroke: getColorValue(theme, color, 'solid') },
37
37
  })}
38
38
  </>
39
39
  )
@@ -10,6 +10,7 @@ import {
10
10
  TLHighlightShapeProps,
11
11
  TLResizeInfo,
12
12
  VecLike,
13
+ getColorValue,
13
14
  highlightShapeMigrations,
14
15
  highlightShapeProps,
15
16
  last,
@@ -289,7 +290,12 @@ function HighlightRenderer({
289
290
  : getShapeDot(shape.props.segments[0].points[0])
290
291
 
291
292
  const colorSpace = useColorSpace()
292
- const color = theme[shape.props.color].highlight[colorSpace]
293
+
294
+ const color = getColorValue(
295
+ theme,
296
+ shape.props.color,
297
+ colorSpace === 'p3' ? 'highlightP3' : 'highlightSrgb'
298
+ )
293
299
 
294
300
  return (
295
301
  <path
@@ -314,9 +314,9 @@ const ImageShape = memo(function ImageShape({ shape }: { shape: TLImageShape })
314
314
  overflow: 'hidden',
315
315
  width: shape.props.w,
316
316
  height: shape.props.h,
317
- color: 'var(--color-text-3)',
318
- backgroundColor: 'var(--color-low)',
319
- border: '1px solid var(--color-low-border)',
317
+ color: 'var(--tl-color-text-3)',
318
+ backgroundColor: 'var(--tl-color-low)',
319
+ border: '1px solid var(--tl-color-low-border)',
320
320
  }}
321
321
  >
322
322
  <div
@@ -12,6 +12,7 @@ import {
12
12
  WeakCache,
13
13
  ZERO_INDEX_KEY,
14
14
  assert,
15
+ getColorValue,
15
16
  getIndexAbove,
16
17
  getIndexBetween,
17
18
  getIndices,
@@ -145,8 +146,6 @@ export class LineShapeUtil extends ShapeUtil<TLLineShape> {
145
146
  }
146
147
 
147
148
  override onHandleDrag(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {
148
- // we should only ever be dragging vertex handles
149
- if (handle.type !== 'vertex') return
150
149
  const newPoint = maybeSnapToGrid(new Vec(handle.x, handle.y), this.editor)
151
150
  return {
152
151
  ...shape,
@@ -160,6 +159,25 @@ export class LineShapeUtil extends ShapeUtil<TLLineShape> {
160
159
  }
161
160
  }
162
161
 
162
+ override onHandleDragStart(shape: TLLineShape, { handle }: TLHandleDragInfo<TLLineShape>) {
163
+ // For line shapes, if we're dragging a "create" handle, then
164
+ // create a new vertex handle at that point; and make this handle
165
+ // the handle that we're dragging.
166
+ if (handle.type === 'create') {
167
+ return {
168
+ ...shape,
169
+ props: {
170
+ ...shape.props,
171
+ points: {
172
+ ...shape.props.points,
173
+ [handle.index]: { id: handle.index, index: handle.index, x: handle.x, y: handle.y },
174
+ },
175
+ },
176
+ }
177
+ }
178
+ return
179
+ }
180
+
163
181
  component(shape: TLLineShape) {
164
182
  return (
165
183
  <SVGContainer style={{ minWidth: 50, minHeight: 50 }}>
@@ -329,6 +347,10 @@ function LineShapeSvg({
329
347
  strokeWidth,
330
348
  forceSolid,
331
349
  randomSeed: shape.id,
332
- props: { transform: `scale(${scale})`, stroke: theme[color].solid, fill: 'none' },
350
+ props: {
351
+ transform: `scale(${scale})`,
352
+ stroke: getColorValue(theme, color, 'solid'),
353
+ fill: 'none',
354
+ },
333
355
  })
334
356
  }
@@ -17,6 +17,7 @@ import {
17
17
  Vec,
18
18
  WeakCache,
19
19
  exhaustiveSwitchError,
20
+ getColorValue,
20
21
  getDefaultColorTheme,
21
22
  getFontsFromRichText,
22
23
  isEqual,
@@ -288,7 +289,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
288
289
  style={{
289
290
  width: nw,
290
291
  height: nh,
291
- backgroundColor: theme[color].note.fill,
292
+ backgroundColor: getColorValue(theme, color, 'noteFill'),
292
293
  borderBottom: hideShadows
293
294
  ? isDarkMode
294
295
  ? `${2 * scale}px solid rgb(20, 20, 20)`
@@ -308,7 +309,11 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
308
309
  verticalAlign={verticalAlign}
309
310
  richText={richText}
310
311
  isSelected={isSelected}
311
- labelColor={labelColor === 'black' ? theme[color].note.text : theme[labelColor].fill}
312
+ labelColor={
313
+ labelColor === 'black'
314
+ ? getColorValue(theme, color, 'noteText')
315
+ : getColorValue(theme, labelColor, 'fill')
316
+ }
312
317
  wrap
313
318
  padding={LABEL_PADDING * scale}
314
319
  hasCustomTabBehavior
@@ -343,7 +348,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
343
348
  align={shape.props.align}
344
349
  verticalAlign={shape.props.verticalAlign}
345
350
  richText={shape.props.richText}
346
- labelColor={theme[shape.props.color].note.text}
351
+ labelColor={getColorValue(theme, shape.props.color, 'noteText')}
347
352
  bounds={bounds}
348
353
  padding={LABEL_PADDING}
349
354
  showTextOutline={false}
@@ -357,7 +362,7 @@ export class NoteShapeUtil extends ShapeUtil<TLNoteShape> {
357
362
  rx={1}
358
363
  width={NOTE_SIZE}
359
364
  height={bounds.h}
360
- fill={theme[shape.props.color].note.fill}
365
+ fill={getColorValue(theme, shape.props.color, 'noteFill')}
361
366
  />
362
367
  {textLabel}
363
368
  </>