tldraw 3.16.0-canary.2b8b5023f0a5 → 3.16.0-canary.36b89de88b02

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 (209) hide show
  1. package/dist-cjs/index.d.ts +116 -4
  2. package/dist-cjs/index.js +8 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  5. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  6. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  7. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  8. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  9. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  10. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +4 -4
  11. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  13. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  14. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
  15. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
  16. package/dist-cjs/lib/shapes/shared/ShapeFill.js +1 -1
  17. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  18. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  19. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  20. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  21. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
  22. package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
  23. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
  24. package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
  25. package/dist-cjs/lib/ui/TldrawUi.js +14 -0
  26. package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
  27. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js +10 -2
  28. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
  29. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +1 -1
  30. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  31. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  32. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  33. package/dist-cjs/lib/ui/components/MobileStylePanel.js +4 -2
  34. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  35. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  36. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  37. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -22
  38. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
  39. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +188 -78
  40. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
  41. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +15 -3
  42. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
  43. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +144 -160
  44. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  45. package/dist-cjs/lib/ui/components/primitives/layout.js +30 -5
  46. package/dist-cjs/lib/ui/components/primitives/layout.js.map +2 -2
  47. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  48. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
  49. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  50. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +3 -19
  51. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  52. package/dist-cjs/lib/ui/context/actions.js +16 -2
  53. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  54. package/dist-cjs/lib/ui/hooks/useTools.js +21 -3
  55. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  56. package/dist-cjs/lib/ui/version.js +3 -3
  57. package/dist-cjs/lib/ui/version.js.map +1 -1
  58. package/dist-esm/index.d.mts +116 -4
  59. package/dist-esm/index.mjs +12 -2
  60. package/dist-esm/index.mjs.map +2 -2
  61. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  62. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  63. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  64. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  65. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  66. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  67. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +4 -4
  68. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  69. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  70. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  71. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
  72. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
  73. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +1 -1
  74. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  75. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  76. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  77. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  78. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
  79. package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
  80. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
  81. package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
  82. package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
  83. package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
  84. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs +10 -2
  85. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
  86. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +1 -1
  87. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  88. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  89. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  90. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +4 -2
  91. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  92. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  93. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  94. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -22
  95. package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
  96. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -80
  97. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
  98. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +16 -4
  99. package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
  100. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +153 -162
  101. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  102. package/dist-esm/lib/ui/components/primitives/layout.mjs +31 -6
  103. package/dist-esm/lib/ui/components/primitives/layout.mjs.map +2 -2
  104. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  105. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
  106. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  107. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +3 -19
  108. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  109. package/dist-esm/lib/ui/context/actions.mjs +16 -2
  110. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  111. package/dist-esm/lib/ui/hooks/useTools.mjs +22 -3
  112. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  113. package/dist-esm/lib/ui/version.mjs +3 -3
  114. package/dist-esm/lib/ui/version.mjs.map +1 -1
  115. package/package.json +11 -34
  116. package/src/index.ts +8 -0
  117. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  118. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
  119. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
  120. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
  121. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  122. package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
  123. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  124. package/src/lib/shapes/frame/FrameShapeUtil.tsx +12 -4
  125. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  126. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
  127. package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
  128. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
  129. package/src/lib/shapes/shared/ShapeFill.tsx +1 -1
  130. package/src/lib/shapes/shared/freehand/svg.ts +2 -0
  131. package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
  132. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  133. package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
  134. package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
  135. package/src/lib/ui/TldrawUi.tsx +17 -2
  136. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +13 -2
  137. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +1 -1
  138. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  139. package/src/lib/ui/components/MobileStylePanel.tsx +4 -3
  140. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  141. package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -24
  142. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +208 -56
  143. package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +22 -5
  144. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +175 -180
  145. package/src/lib/ui/components/primitives/layout.tsx +79 -5
  146. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  147. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
  148. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +5 -18
  149. package/src/lib/ui/context/actions.tsx +16 -2
  150. package/src/lib/ui/hooks/useTools.tsx +25 -3
  151. package/src/lib/ui/version.ts +3 -3
  152. package/src/lib/ui.css +346 -243
  153. package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
  154. package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
  155. package/src/test/A11y.test.tsx +3 -2
  156. package/src/test/ClickManager.test.ts +7 -6
  157. package/src/test/Editor.test.tsx +20 -19
  158. package/src/test/EraserTool.test.ts +184 -13
  159. package/src/test/HandTool.test.ts +10 -9
  160. package/src/test/HighlightShape.test.ts +2 -1
  161. package/src/test/SelectTool.test.ts +3 -2
  162. package/src/test/TLUserPreferences.test.ts +4 -3
  163. package/src/test/TestEditor.ts +13 -15
  164. package/src/test/TldrawEditor.test.tsx +11 -10
  165. package/src/test/ZoomTool.test.ts +7 -6
  166. package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
  167. package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
  168. package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
  169. package/src/test/arrows-megabus.test.tsx +5 -4
  170. package/src/test/bindings.test.tsx +24 -37
  171. package/src/test/bookmark-shapes.test.ts +1 -8
  172. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
  173. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
  174. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  175. package/src/test/commands/alignShapes.test.tsx +25 -24
  176. package/src/test/commands/animationSpeed.test.ts +2 -1
  177. package/src/test/commands/centerOnPoint.test.ts +3 -2
  178. package/src/test/commands/clipboard.test.ts +3 -2
  179. package/src/test/commands/createShapes.test.ts +2 -1
  180. package/src/test/commands/deleteShapes.test.ts +2 -1
  181. package/src/test/commands/distributeShapes.test.tsx +11 -10
  182. package/src/test/commands/getSvgString.test.ts +2 -1
  183. package/src/test/commands/packShapes.test.ts +5 -4
  184. package/src/test/commands/resizeShape.test.ts +2 -1
  185. package/src/test/commands/rotateShapes.test.ts +7 -6
  186. package/src/test/commands/setCamera.test.ts +4 -3
  187. package/src/test/commands/setCurrentPage.test.ts +3 -2
  188. package/src/test/commands/stackShapes.test.ts +11 -10
  189. package/src/test/commands/stretch.test.tsx +13 -12
  190. package/src/test/createDeepLink.test.tsx +2 -1
  191. package/src/test/cropping.test.ts +3 -2
  192. package/src/test/drawing.test.ts +2 -1
  193. package/src/test/flipShapes.test.ts +4 -3
  194. package/src/test/frames.test.ts +25 -24
  195. package/src/test/getCulledShapes.test.tsx +3 -2
  196. package/src/test/groups.test.tsx +1 -1
  197. package/src/test/handleDeepLink.test.tsx +2 -1
  198. package/src/test/maxShapes.test.ts +3 -2
  199. package/src/test/modifiers.test.ts +5 -4
  200. package/src/test/navigation.test.ts +12 -11
  201. package/src/test/panning.test.ts +2 -1
  202. package/src/test/perf/perf.test.ts +2 -1
  203. package/src/test/registerDeepLinkListener.test.tsx +10 -9
  204. package/src/test/resizing.test.ts +39 -38
  205. package/src/test/select.test.tsx +4 -3
  206. package/src/test/selection-omnibus.test.ts +11 -10
  207. package/src/test/shapeutils.test.ts +4 -3
  208. package/src/test/translating.test.ts +9 -8
  209. package/tldraw.css +639 -533
@@ -4,6 +4,7 @@ import {
4
4
  TLGroupShape,
5
5
  TLPointerEventInfo,
6
6
  TLShapeId,
7
+ isAccelKey,
7
8
  pointInPolygon,
8
9
  } from '@tldraw/editor'
9
10
 
@@ -15,7 +16,15 @@ export class Erasing extends StateNode {
15
16
  private markId = ''
16
17
  private excludedShapeIds = new Set<TLShapeId>()
17
18
 
19
+ _isHoldingAccelKey = false
20
+ _firstErasingShapeId: TLShapeId | null = null
21
+ _erasingShapeIds: TLShapeId[] = []
22
+
18
23
  override onEnter(info: TLPointerEventInfo) {
24
+ this._isHoldingAccelKey = isAccelKey(this.editor.inputs)
25
+ this._firstErasingShapeId = this.editor.getErasingShapeIds()[0] // the first one should be the first one we hit... is it?
26
+ this._erasingShapeIds = this.editor.getErasingShapeIds()
27
+
19
28
  this.markId = this.editor.markHistoryStoppingPoint('erase scribble begin')
20
29
  this.info = info
21
30
 
@@ -76,6 +85,16 @@ export class Erasing extends StateNode {
76
85
  this.complete()
77
86
  }
78
87
 
88
+ override onKeyUp() {
89
+ this._isHoldingAccelKey = isAccelKey(this.editor.inputs)
90
+ this.update()
91
+ }
92
+
93
+ override onKeyDown() {
94
+ this._isHoldingAccelKey = isAccelKey(this.editor.inputs)
95
+ this.update()
96
+ }
97
+
79
98
  update() {
80
99
  const { editor, excludedShapeIds } = this
81
100
  const erasingShapeIds = editor.getErasingShapeIds()
@@ -87,6 +106,7 @@ export class Erasing extends StateNode {
87
106
 
88
107
  this.pushPointToScribble()
89
108
 
109
+ // Otherwise, erasing shapes are all the shapes that were hit before plus any new shapes that are hit
90
110
  const erasing = new Set<TLShapeId>(erasingShapeIds)
91
111
  const minDist = this.editor.options.hitTestMargin / zoomLevel
92
112
 
@@ -121,18 +141,31 @@ export class Erasing extends StateNode {
121
141
  if (geometry.hitTestLineSegment(A, B, minDist)) {
122
142
  erasing.add(editor.getOutermostSelectableShape(shape).id)
123
143
  }
144
+
145
+ this._erasingShapeIds = [...erasing]
146
+ }
147
+
148
+ // If the user is holding the meta / ctrl key, we should only erase the first shape we hit
149
+ if (this._isHoldingAccelKey && this._firstErasingShapeId) {
150
+ const erasingShapeId = this._firstErasingShapeId
151
+ if (erasingShapeId && this.editor.getShape(erasingShapeId)) {
152
+ editor.setErasingShapes([erasingShapeId])
153
+ }
154
+ return
124
155
  }
125
156
 
126
157
  // Remove the hit shapes, except if they're in the list of excluded shapes
127
158
  // (these excluded shapes will be any frames or groups the pointer was inside of
128
159
  // when the user started erasing)
129
- this.editor.setErasingShapes([...erasing].filter((id) => !excludedShapeIds.has(id)))
160
+ this.editor.setErasingShapes(this._erasingShapeIds.filter((id) => !excludedShapeIds.has(id)))
130
161
  }
131
162
 
132
163
  complete() {
133
164
  const { editor } = this
134
165
  editor.deleteShapes(editor.getCurrentPageState().erasingShapeIds)
135
166
  this.parent.transition('idle')
167
+ this._erasingShapeIds = []
168
+ this._firstErasingShapeId = null
136
169
  }
137
170
 
138
171
  cancel() {
@@ -1,4 +1,5 @@
1
1
  import {
2
+ isAccelKey,
2
3
  StateNode,
3
4
  TLFrameShape,
4
5
  TLGroupShape,
@@ -9,7 +10,11 @@ import {
9
10
  export class Pointing extends StateNode {
10
11
  static override id = 'pointing'
11
12
 
13
+ _isHoldingAccelKey = false
14
+
12
15
  override onEnter() {
16
+ this._isHoldingAccelKey = isAccelKey(this.editor.inputs)
17
+
13
18
  const zoomLevel = this.editor.getZoomLevel()
14
19
  const currentPageShapesSorted = this.editor.getCurrentPageRenderingShapesSorted()
15
20
  const {
@@ -45,12 +50,25 @@ export class Pointing extends StateNode {
45
50
  }
46
51
 
47
52
  erasing.add(hitShape.id)
53
+
54
+ // If the user is holding the meta / ctrl key, stop after the first shape
55
+ if (this._isHoldingAccelKey) {
56
+ break
57
+ }
48
58
  }
49
59
  }
50
60
 
51
61
  this.editor.setErasingShapes([...erasing])
52
62
  }
53
63
 
64
+ override onKeyUp() {
65
+ this._isHoldingAccelKey = isAccelKey(this.editor.inputs)
66
+ }
67
+
68
+ override onKeyDown() {
69
+ this._isHoldingAccelKey = isAccelKey(this.editor.inputs)
70
+ }
71
+
54
72
  override onLongPress(info: TLPointerEventInfo) {
55
73
  this.startErasing(info)
56
74
  }
@@ -62,6 +80,8 @@ export class Pointing extends StateNode {
62
80
  }
63
81
 
64
82
  override onPointerMove(info: TLPointerEventInfo) {
83
+ if (this._isHoldingAccelKey) return
84
+
65
85
  if (this.editor.inputs.isDragging) {
66
86
  this.startErasing(info)
67
87
  }
@@ -1,12 +1,12 @@
1
1
  import { tlenv, useEditor, useReactor, useValue } from '@tldraw/editor'
2
2
  import classNames from 'classnames'
3
- import React, { ReactNode, useRef, useState } from 'react'
3
+ import React, { ReactNode, useMemo, useRef, useState } from 'react'
4
4
  import { TLUiAssetUrlOverrides } from './assetUrls'
5
5
  import { SkipToMainContent } from './components/A11y'
6
6
  import { FollowingIndicator } from './components/FollowingIndicator'
7
7
  import { TldrawUiButton } from './components/primitives/Button/TldrawUiButton'
8
8
  import { TldrawUiButtonIcon } from './components/primitives/Button/TldrawUiButtonIcon'
9
- import { PORTRAIT_BREAKPOINT } from './constants'
9
+ import { PORTRAIT_BREAKPOINT, PORTRAIT_BREAKPOINTS } from './constants'
10
10
  import {
11
11
  TLUiContextProviderProps,
12
12
  TldrawUiContextProvider,
@@ -160,6 +160,19 @@ const TldrawUiContent = React.memo(function TldrawUI() {
160
160
 
161
161
  const { 'toggle-focus-mode': toggleFocus } = useActions()
162
162
 
163
+ const { breakpointsAbove, breakpointsBelow } = useMemo(() => {
164
+ const breakpointsAbove = []
165
+ const breakpointsBelow = []
166
+ for (let bp = 0; bp < PORTRAIT_BREAKPOINTS.length; bp++) {
167
+ if (bp <= breakpoint) {
168
+ breakpointsAbove.push(bp)
169
+ } else {
170
+ breakpointsBelow.push(bp)
171
+ }
172
+ }
173
+ return { breakpointsAbove, breakpointsBelow }
174
+ }, [breakpoint])
175
+
163
176
  return (
164
177
  <div
165
178
  className={classNames('tlui-layout', {
@@ -169,6 +182,8 @@ const TldrawUiContent = React.memo(function TldrawUI() {
169
182
  // But when the virtual keyboard is closing we want to wait a bit before showing it again.
170
183
  data-iseditinganything={hideToolbarWhileEditing}
171
184
  data-breakpoint={breakpoint}
185
+ data-breakpoints-above={breakpointsAbove.join(' ')}
186
+ data-breakpoints-below={breakpointsBelow.join(' ')}
172
187
  >
173
188
  <SkipToMainContent />
174
189
  {isFocusMode ? (
@@ -11,6 +11,7 @@ import {
11
11
  TldrawUiPopoverTrigger,
12
12
  } from '../primitives/TldrawUiPopover'
13
13
  import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
14
+ import { useTldrawUiOrientation } from '../primitives/layout'
14
15
  import { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'
15
16
  import { DefaultActionsMenuContent } from './DefaultActionsMenuContent'
16
17
 
@@ -26,6 +27,7 @@ export const DefaultActionsMenu = memo(function DefaultActionsMenu({
26
27
  const msg = useTranslation()
27
28
  const breakpoint = useBreakpoint()
28
29
  const isReadonlyMode = useReadonly()
30
+ const { orientation } = useTldrawUiOrientation()
29
31
 
30
32
  const ref = useRef<HTMLDivElement>(null)
31
33
  usePassThroughWheelEvents(ref)
@@ -52,11 +54,20 @@ export const DefaultActionsMenu = memo(function DefaultActionsMenu({
52
54
  data-testid="actions-menu.button"
53
55
  title={msg('actions-menu.title')}
54
56
  >
55
- <TldrawUiButtonIcon icon="dots-vertical" small />
57
+ <TldrawUiButtonIcon
58
+ icon={orientation === 'horizontal' ? 'dots-vertical' : 'dots-horizontal'}
59
+ small
60
+ />
56
61
  </TldrawUiToolbarButton>
57
62
  </TldrawUiPopoverTrigger>
58
63
  <TldrawUiPopoverContent
59
- side={breakpoint >= PORTRAIT_BREAKPOINT.TABLET ? 'bottom' : 'top'}
64
+ side={
65
+ orientation === 'horizontal'
66
+ ? breakpoint >= PORTRAIT_BREAKPOINT.TABLET
67
+ ? 'bottom'
68
+ : 'top'
69
+ : 'right'
70
+ }
60
71
  sideOffset={6}
61
72
  >
62
73
  <TldrawUiToolbar
@@ -123,7 +123,7 @@ export function DefaultKeyboardShortcutsDialogContent() {
123
123
  <TldrawUiMenuItem
124
124
  id="text-header"
125
125
  label="tool.rich-text-header"
126
- kbd="cmd+shift+[[1-6]]"
126
+ kbd="cmd+alt+[[1-6]]"
127
127
  onSelect={() => {
128
128
  /* do nothing */
129
129
  }}
@@ -46,10 +46,10 @@ export class MinimapManager {
46
46
  const style = getComputedStyle(this.editor.getContainer())
47
47
 
48
48
  return {
49
- shapeFill: getRgba(style.getPropertyValue('--color-text-3').trim()),
50
- selectFill: getRgba(style.getPropertyValue('--color-selected').trim()),
51
- viewportFill: getRgba(style.getPropertyValue('--color-muted-1').trim()),
52
- background: getRgba(style.getPropertyValue('--color-low').trim()),
49
+ shapeFill: getRgba(style.getPropertyValue('--tl-color-text-3').trim()),
50
+ selectFill: getRgba(style.getPropertyValue('--tl-color-selected').trim()),
51
+ viewportFill: getRgba(style.getPropertyValue('--tl-color-muted-1').trim()),
52
+ background: getRgba(style.getPropertyValue('--tl-color-low').trim()),
53
53
  }
54
54
  }
55
55
 
@@ -17,12 +17,13 @@ import {
17
17
  TldrawUiPopoverContent,
18
18
  TldrawUiPopoverTrigger,
19
19
  } from './primitives/TldrawUiPopover'
20
+ import { useTldrawUiOrientation } from './primitives/layout'
20
21
 
21
22
  /** @public @react */
22
23
  export function MobileStylePanel() {
23
24
  const editor = useEditor()
24
25
  const msg = useTranslation()
25
-
26
+ const { orientation } = useTldrawUiOrientation()
26
27
  const relevantStyles = useRelevantStyles()
27
28
  const color = relevantStyles?.get(DefaultColorStyle)
28
29
  const theme = getDefaultColorTheme({ isDarkMode: editor.user.getIsDarkMode() })
@@ -56,7 +57,7 @@ export function MobileStylePanel() {
56
57
  type="tool"
57
58
  data-testid="mobile-styles.button"
58
59
  style={{
59
- color: disableStylePanel ? 'var(--color-muted-1)' : currentColor,
60
+ color: disableStylePanel ? 'var(--tl-color-muted-1)' : currentColor,
60
61
  }}
61
62
  title={msg('style-panel.title')}
62
63
  disabled={disableStylePanel}
@@ -66,7 +67,7 @@ export function MobileStylePanel() {
66
67
  />
67
68
  </TldrawUiButton>
68
69
  </TldrawUiPopoverTrigger>
69
- <TldrawUiPopoverContent side="top" align="end">
70
+ <TldrawUiPopoverContent side={orientation === 'horizontal' ? 'top' : 'right'} align="end">
70
71
  {StylePanel && <StylePanel isMobile />}
71
72
  </TldrawUiPopoverContent>
72
73
  </TldrawUiPopover>
@@ -272,7 +272,7 @@ export const DefaultImageToolbarContent = track(function DefaultImageToolbarCont
272
272
  type="icon"
273
273
  onClick={onManipulatingEnd}
274
274
  data-testid="tool.image-confirm"
275
- style={{ borderLeft: '1px solid var(--color-divider)', marginLeft: '2px' }}
275
+ style={{ borderLeft: '1px solid var(--tl-color-divider)', marginLeft: '2px' }}
276
276
  >
277
277
  <TldrawUiButtonIcon small icon="check" />
278
278
  </TldrawUiButton>
@@ -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
  })