tldraw 4.1.0-canary.9c36de6e611c → 4.1.0-canary.a152954244d2

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 (225) hide show
  1. package/dist-cjs/index.d.ts +46 -12
  2. package/dist-cjs/index.js +6 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawCropHandles.js +1 -1
  5. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  6. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +1 -1
  7. package/dist-cjs/lib/defaultEmbedDefinitions.js +25 -30
  8. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  9. package/dist-cjs/lib/defaultExternalContentHandlers.js +10 -33
  10. package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
  11. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +3 -0
  12. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  13. package/dist-cjs/lib/shapes/arrow/curved-arrow.js +8 -2
  14. package/dist-cjs/lib/shapes/arrow/curved-arrow.js.map +2 -2
  15. package/dist-cjs/lib/shapes/arrow/straight-arrow.js +4 -1
  16. package/dist-cjs/lib/shapes/arrow/straight-arrow.js.map +2 -2
  17. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +44 -102
  18. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  19. package/dist-cjs/lib/shapes/bookmark/bookmarks.js +138 -0
  20. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +7 -0
  21. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +25 -3
  22. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  23. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +1 -1
  24. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +1 -1
  25. package/dist-cjs/lib/shapes/line/LineShapeUtil.js +3 -0
  26. package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
  27. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +1 -1
  28. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -1
  29. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +2 -2
  30. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  31. package/dist-cjs/lib/shapes/shared/ShapeFill.js +1 -1
  32. package/dist-cjs/lib/shapes/text/PlainTextArea.js +1 -1
  33. package/dist-cjs/lib/shapes/text/RichTextArea.js +1 -1
  34. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  35. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js +20 -4
  36. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Cropping.js.map +2 -2
  37. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js +1 -1
  38. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/Idle.js.map +2 -2
  39. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js +23 -11
  40. package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.js.map +2 -2
  41. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +27 -6
  42. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  43. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +1 -1
  44. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  45. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js +21 -9
  46. package/dist-cjs/lib/tools/SelectTool/childStates/PointingArrowLabel.js.map +2 -2
  47. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js +24 -8
  48. package/dist-cjs/lib/tools/SelectTool/childStates/PointingResizeHandle.js.map +2 -2
  49. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js +21 -9
  50. package/dist-cjs/lib/tools/SelectTool/childStates/PointingRotateHandle.js.map +2 -2
  51. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +23 -8
  52. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  53. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +21 -9
  54. package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
  55. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +26 -11
  56. package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
  57. package/dist-cjs/lib/ui/TldrawUi.js +2 -2
  58. package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js +3 -3
  59. package/dist-cjs/lib/ui/components/DebugMenu/DefaultDebugMenuContent.js.map +1 -1
  60. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialog.js +1 -1
  61. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +1 -1
  62. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
  63. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
  64. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +5 -0
  65. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  66. package/dist-cjs/lib/ui/components/OfflineIndicator/OfflineIndicator.js +1 -1
  67. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js +6 -2
  68. package/dist-cjs/lib/ui/components/SharePanel/PeopleMenu.js.map +2 -2
  69. package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +1 -1
  70. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +1 -1
  71. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +64 -56
  72. package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
  73. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +54 -47
  74. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +3 -3
  75. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js +63 -56
  76. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +2 -2
  77. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js +13 -6
  78. package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +2 -2
  79. package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +1 -1
  80. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
  81. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +1 -1
  82. package/dist-cjs/lib/ui/components/menu-items.js +2 -2
  83. package/dist-cjs/lib/ui/components/menu-items.js.map +1 -1
  84. package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButton.js +2 -2
  85. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  86. package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js +1 -1
  87. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +1 -1
  88. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +1 -1
  89. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -2
  90. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -2
  91. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  92. package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -2
  93. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +1 -1
  94. package/dist-cjs/lib/ui/components/primitives/layout.js +1 -1
  95. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +1 -1
  96. package/dist-cjs/lib/ui/context/actions.js +44 -30
  97. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  98. package/dist-cjs/lib/ui/context/breakpoints.js +1 -1
  99. package/dist-cjs/lib/ui/context/events.js +1 -1
  100. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  101. package/dist-cjs/lib/ui/hooks/useEditorEvents.js +1 -1
  102. package/dist-cjs/lib/ui/hooks/useEditorEvents.js.map +1 -1
  103. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +1 -1
  104. package/dist-cjs/lib/ui/hooks/useLocalStorageState.js +1 -1
  105. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  106. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +4 -4
  107. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +1 -1
  108. package/dist-cjs/lib/ui/hooks/useTranslation/useTranslation.js +1 -1
  109. package/dist-cjs/lib/ui/version.js +3 -3
  110. package/dist-cjs/lib/ui/version.js.map +1 -1
  111. package/dist-cjs/lib/utils/text/richText.js +4 -4
  112. package/dist-esm/index.d.mts +46 -12
  113. package/dist-esm/index.mjs +12 -4
  114. package/dist-esm/index.mjs.map +2 -2
  115. package/dist-esm/lib/defaultEmbedDefinitions.mjs +25 -30
  116. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  117. package/dist-esm/lib/defaultExternalContentHandlers.mjs +10 -33
  118. package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
  119. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +3 -0
  120. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  121. package/dist-esm/lib/shapes/arrow/curved-arrow.mjs +8 -2
  122. package/dist-esm/lib/shapes/arrow/curved-arrow.mjs.map +2 -2
  123. package/dist-esm/lib/shapes/arrow/straight-arrow.mjs +4 -1
  124. package/dist-esm/lib/shapes/arrow/straight-arrow.mjs.map +2 -2
  125. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +46 -101
  126. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  127. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +124 -0
  128. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +7 -0
  129. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +26 -3
  130. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  131. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +3 -0
  132. package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
  133. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +1 -1
  134. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  135. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs +20 -4
  136. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Cropping.mjs.map +2 -2
  137. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs +1 -1
  138. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/Idle.mjs.map +2 -2
  139. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs +23 -11
  140. package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.mjs.map +2 -2
  141. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +29 -7
  142. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  143. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +1 -1
  144. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  145. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs +21 -9
  146. package/dist-esm/lib/tools/SelectTool/childStates/PointingArrowLabel.mjs.map +2 -2
  147. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs +24 -8
  148. package/dist-esm/lib/tools/SelectTool/childStates/PointingResizeHandle.mjs.map +2 -2
  149. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs +21 -9
  150. package/dist-esm/lib/tools/SelectTool/childStates/PointingRotateHandle.mjs.map +2 -2
  151. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +23 -8
  152. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  153. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +21 -9
  154. package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
  155. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +26 -11
  156. package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
  157. package/dist-esm/lib/ui/components/DebugMenu/DefaultDebugMenuContent.mjs +2 -2
  158. package/dist-esm/lib/ui/components/DebugMenu/DefaultDebugMenuContent.mjs.map +1 -1
  159. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +1 -1
  160. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
  161. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +5 -0
  162. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  163. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs +6 -2
  164. package/dist-esm/lib/ui/components/SharePanel/PeopleMenu.mjs.map +2 -2
  165. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +68 -57
  166. package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
  167. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +54 -47
  168. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +3 -3
  169. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs +63 -56
  170. package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +2 -2
  171. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs +12 -5
  172. package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +2 -2
  173. package/dist-esm/lib/ui/components/menu-items.mjs +2 -2
  174. package/dist-esm/lib/ui/components/menu-items.mjs.map +1 -1
  175. package/dist-esm/lib/ui/context/actions.mjs +43 -29
  176. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  177. package/dist-esm/lib/ui/hooks/useEditorEvents.mjs +1 -1
  178. package/dist-esm/lib/ui/hooks/useEditorEvents.mjs.map +1 -1
  179. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -4
  180. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +1 -1
  181. package/dist-esm/lib/ui/version.mjs +3 -3
  182. package/dist-esm/lib/ui/version.mjs.map +1 -1
  183. package/package.json +11 -11
  184. package/src/index.ts +4 -0
  185. package/src/lib/defaultEmbedDefinitions.ts +20 -24
  186. package/src/lib/defaultExternalContentHandlers.ts +12 -37
  187. package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +211 -1
  188. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +3 -0
  189. package/src/lib/shapes/arrow/curved-arrow.ts +8 -2
  190. package/src/lib/shapes/arrow/straight-arrow.ts +5 -1
  191. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +51 -135
  192. package/src/lib/shapes/bookmark/bookmarks.ts +170 -0
  193. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +28 -2
  194. package/src/lib/shapes/line/LineShapeUtil.tsx +3 -0
  195. package/src/lib/shapes/shared/RichTextLabel.tsx +1 -1
  196. package/src/lib/shapes/text/TextShapeTool.test.ts +74 -0
  197. package/src/lib/tools/SelectTool/childStates/Crop/children/Cropping.ts +23 -6
  198. package/src/lib/tools/SelectTool/childStates/Crop/children/Idle.ts +1 -1
  199. package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCropHandle.ts +24 -12
  200. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +34 -11
  201. package/src/lib/tools/SelectTool/childStates/Idle.ts +1 -1
  202. package/src/lib/tools/SelectTool/childStates/PointingArrowLabel.ts +23 -11
  203. package/src/lib/tools/SelectTool/childStates/PointingResizeHandle.ts +26 -9
  204. package/src/lib/tools/SelectTool/childStates/PointingRotateHandle.ts +23 -10
  205. package/src/lib/tools/SelectTool/childStates/Resizing.ts +24 -9
  206. package/src/lib/tools/SelectTool/childStates/Rotating.ts +27 -11
  207. package/src/lib/tools/SelectTool/childStates/Translating.ts +28 -12
  208. package/src/lib/ui/components/DebugMenu/DefaultDebugMenuContent.tsx +2 -2
  209. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +1 -1
  210. package/src/lib/ui/components/Minimap/MinimapManager.ts +6 -0
  211. package/src/lib/ui/components/SharePanel/PeopleMenu.tsx +6 -2
  212. package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +60 -49
  213. package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +70 -53
  214. package/src/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.tsx +105 -90
  215. package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +72 -51
  216. package/src/lib/ui/components/menu-items.tsx +2 -2
  217. package/src/lib/ui/context/actions.tsx +49 -31
  218. package/src/lib/ui/hooks/useEditorEvents.ts +1 -1
  219. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -4
  220. package/src/lib/ui/version.ts +3 -3
  221. package/src/lib/utils/embeds/embeds.test.ts +16 -34
  222. package/src/test/SelectTool.test.ts +251 -0
  223. package/src/test/bookmark-shapes.test.ts +129 -7
  224. package/src/test/customSnapping.test.tsx +55 -11
  225. package/tldraw.css +7 -2
@@ -19,14 +19,20 @@ export class Rotating extends StateNode {
19
19
 
20
20
  snapshot = {} as TLRotationSnapshot
21
21
 
22
- info = {} as Extract<TLPointerEventInfo, { target: 'selection' }> & { onInteractionEnd?: string }
22
+ info = {} as Extract<TLPointerEventInfo, { target: 'selection' }> & {
23
+ onInteractionEnd?: string | (() => void)
24
+ }
23
25
 
24
26
  markId = ''
25
27
 
26
- override onEnter(info: TLPointerEventInfo & { target: 'selection'; onInteractionEnd?: string }) {
28
+ override onEnter(
29
+ info: TLPointerEventInfo & { target: 'selection'; onInteractionEnd?: string | (() => void) }
30
+ ) {
27
31
  // Store the event information
28
32
  this.info = info
29
- this.parent.setCurrentToolIdMask(info.onInteractionEnd)
33
+ if (typeof info.onInteractionEnd === 'string') {
34
+ this.parent.setCurrentToolIdMask(info.onInteractionEnd)
35
+ }
30
36
 
31
37
  this.markId = this.editor.markHistoryStoppingPoint('rotate start')
32
38
 
@@ -121,11 +127,16 @@ export class Rotating extends StateNode {
121
127
  })
122
128
 
123
129
  this.editor.bailToMark(this.markId)
124
- if (this.info.onInteractionEnd) {
125
- this.editor.setCurrentTool(this.info.onInteractionEnd, this.info)
126
- } else {
127
- this.parent.transition('idle', this.info)
130
+ const { onInteractionEnd } = this.info
131
+ if (onInteractionEnd) {
132
+ if (typeof onInteractionEnd === 'string') {
133
+ this.editor.setCurrentTool(onInteractionEnd, this.info)
134
+ } else {
135
+ onInteractionEnd()
136
+ }
137
+ return
128
138
  }
139
+ this.parent.transition('idle', this.info)
129
140
  }
130
141
 
131
142
  private complete() {
@@ -139,11 +150,16 @@ export class Rotating extends StateNode {
139
150
  this.editor,
140
151
  this.snapshot.shapeSnapshots.map((s) => s.shape.id)
141
152
  )
142
- if (this.info.onInteractionEnd) {
143
- this.editor.setCurrentTool(this.info.onInteractionEnd, this.info)
144
- } else {
145
- this.parent.transition('idle', this.info)
153
+ const { onInteractionEnd } = this.info
154
+ if (onInteractionEnd) {
155
+ if (typeof onInteractionEnd === 'string') {
156
+ this.editor.setCurrentTool(onInteractionEnd, this.info)
157
+ } else {
158
+ onInteractionEnd()
159
+ }
160
+ return
146
161
  }
162
+ this.parent.transition('idle', this.info)
147
163
  }
148
164
 
149
165
  _getRotationFromPointerPosition({ snapToNearestDegree }: { snapToNearestDegree: boolean }) {
@@ -28,7 +28,7 @@ export type TranslatingInfo = TLPointerEventInfo & {
28
28
  isCreating?: boolean
29
29
  creatingMarkId?: string
30
30
  onCreate?(): void
31
- onInteractionEnd?: string
31
+ onInteractionEnd?: string | (() => void)
32
32
  }
33
33
 
34
34
  export class Translating extends StateNode {
@@ -59,7 +59,9 @@ export class Translating extends StateNode {
59
59
  }
60
60
 
61
61
  this.info = info
62
- this.parent.setCurrentToolIdMask(info.onInteractionEnd)
62
+ if (typeof info.onInteractionEnd === 'string') {
63
+ this.parent.setCurrentToolIdMask(info.onInteractionEnd)
64
+ }
63
65
  this.isCreating = isCreating
64
66
 
65
67
  this.markId = ''
@@ -190,15 +192,24 @@ export class Translating extends StateNode {
190
192
  this.snapshot.movingShapes.map((s) => s.id)
191
193
  )
192
194
 
193
- if (this.editor.getInstanceState().isToolLocked && this.info.onInteractionEnd) {
194
- this.editor.setCurrentTool(this.info.onInteractionEnd)
195
- } else {
196
- if (this.isCreating) {
197
- this.onCreate?.(this.editor.getOnlySelectedShape())
195
+ const { onInteractionEnd } = this.info
196
+ if (onInteractionEnd) {
197
+ if (typeof onInteractionEnd === 'string') {
198
+ if (this.editor.getInstanceState().isToolLocked) {
199
+ this.editor.setCurrentTool(onInteractionEnd)
200
+ return
201
+ }
198
202
  } else {
199
- this.parent.transition('idle')
203
+ onInteractionEnd()
204
+ return
200
205
  }
201
206
  }
207
+
208
+ if (this.isCreating) {
209
+ this.onCreate?.(this.editor.getOnlySelectedShape())
210
+ } else {
211
+ this.parent.transition('idle')
212
+ }
202
213
  }
203
214
 
204
215
  private cancel() {
@@ -214,11 +225,16 @@ export class Translating extends StateNode {
214
225
  })
215
226
 
216
227
  this.reset()
217
- if (this.info.onInteractionEnd) {
218
- this.editor.setCurrentTool(this.info.onInteractionEnd)
219
- } else {
220
- this.parent.transition('idle', this.info)
228
+ const { onInteractionEnd } = this.info
229
+ if (onInteractionEnd) {
230
+ if (typeof onInteractionEnd === 'string') {
231
+ this.editor.setCurrentTool(onInteractionEnd)
232
+ } else {
233
+ onInteractionEnd()
234
+ }
235
+ return
221
236
  }
237
+ this.parent.transition('idle', this.info)
222
238
  }
223
239
 
224
240
  protected handleStart() {
@@ -172,7 +172,7 @@ export function DebugFlags() {
172
172
  const items = Object.values(debugFlags)
173
173
  if (!items.length) return null
174
174
  return (
175
- <TldrawUiMenuSubmenu id="debug flags" label="Debug Flags">
175
+ <TldrawUiMenuSubmenu id="debug flags" label="Debug flags">
176
176
  <TldrawUiMenuGroup id="debug flags">
177
177
  {items.map((flag) => (
178
178
  <DebugFlagToggle key={flag.name} flag={flag} />
@@ -186,7 +186,7 @@ export function FeatureFlags() {
186
186
  const items = Object.values(featureFlags)
187
187
  if (!items.length) return null
188
188
  return (
189
- <TldrawUiMenuSubmenu id="feature flags" label="Feature Flags">
189
+ <TldrawUiMenuSubmenu id="feature flags" label="Feature flags">
190
190
  <TldrawUiMenuGroup id="feature flags">
191
191
  {items.map((flag) => (
192
192
  <DebugFlagToggle key={flag.name} flag={flag} />
@@ -165,7 +165,7 @@ export function DefaultKeyboardShortcutsDialogContent() {
165
165
  <TldrawUiMenuItem
166
166
  id="a11y-select-next-shape-container"
167
167
  label="a11y.enter-leave-container"
168
- kbd="cmd+shift+[[↑→]]"
168
+ kbd="cmd+shift+[[↑↓]]"
169
169
  onSelect={() => {
170
170
  /* do nothing */
171
171
  }}
@@ -249,6 +249,12 @@ export class MinimapManager {
249
249
 
250
250
  const len = geometry.length
251
251
 
252
+ const shape = this.editor.getShape(shapeId)
253
+ if (shape) {
254
+ const shapeUtil = this.editor.getShapeUtil(shape.type)
255
+ if (shapeUtil.hideInMinimap?.(shape)) continue
256
+ }
257
+
252
258
  if (selectedShapes.has(shapeId)) {
253
259
  appendVertices(this.gl.selectedShapes, selectedShapeOffset, geometry)
254
260
  selectedShapeOffset += len
@@ -1,6 +1,8 @@
1
1
  import { useContainer, useEditor, usePeerIds, useValue } from '@tldraw/editor'
2
2
  import { Popover as _Popover } from 'radix-ui'
3
3
  import { ReactNode } from 'react'
4
+ import { PORTRAIT_BREAKPOINT } from '../../constants'
5
+ import { useBreakpoint } from '../../context/breakpoints'
4
6
  import { useMenuIsOpen } from '../../hooks/useMenuIsOpen'
5
7
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
6
8
  import { PeopleMenuAvatar } from './PeopleMenuAvatar'
@@ -25,6 +27,8 @@ export function PeopleMenu({ children }: PeopleMenuProps) {
25
27
  const userName = useValue('user', () => editor.user.getName(), [editor])
26
28
 
27
29
  const [isOpen, onOpenChange] = useMenuIsOpen('people menu')
30
+ const breakpoint = useBreakpoint()
31
+ const maxAvatars = breakpoint <= PORTRAIT_BREAKPOINT.MOBILE_XS ? 1 : 5
28
32
 
29
33
  if (!userIds.length) return null
30
34
 
@@ -33,7 +37,7 @@ export function PeopleMenu({ children }: PeopleMenuProps) {
33
37
  <_Popover.Trigger dir="ltr" asChild>
34
38
  <button className="tlui-people-menu__avatars-button" title={msg('people-menu.title')}>
35
39
  <div className="tlui-people-menu__avatars">
36
- {userIds.slice(-5).map((userId) => (
40
+ {userIds.slice(-maxAvatars).map((userId) => (
37
41
  <PeopleMenuAvatar key={userId} userId={userId} />
38
42
  ))}
39
43
  {userIds.length > 0 && (
@@ -46,7 +50,7 @@ export function PeopleMenu({ children }: PeopleMenuProps) {
46
50
  {userName?.[0] ?? ''}
47
51
  </div>
48
52
  )}
49
- {userIds.length > 5 && <PeopleMenuMore count={userIds.length - 5} />}
53
+ {userIds.length > maxAvatars && <PeopleMenuMore count={userIds.length - maxAvatars} />}
50
54
  </div>
51
55
  </button>
52
56
  </_Popover.Trigger>
@@ -25,10 +25,13 @@ import { useTranslation } from '../../hooks/useTranslation/useTranslation'
25
25
  import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
26
26
  import { TldrawUiSlider } from '../primitives/TldrawUiSlider'
27
27
  import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
28
- import { StylePanelButtonPicker } from './StylePanelButtonPicker'
28
+ import { StylePanelButtonPicker, StylePanelButtonPickerInline } from './StylePanelButtonPicker'
29
29
  import { useStylePanelContext } from './StylePanelContext'
30
30
  import { StylePanelDoubleDropdownPicker } from './StylePanelDoubleDropdownPicker'
31
- import { StylePanelDropdownPicker } from './StylePanelDropdownPicker'
31
+ import {
32
+ StylePanelDropdownPicker,
33
+ StylePanelDropdownPickerInline,
34
+ } from './StylePanelDropdownPicker'
32
35
  import { StylePanelSubheading } from './StylePanelSubheading'
33
36
 
34
37
  /** @public @react */
@@ -225,70 +228,78 @@ export function StylePanelFontPicker() {
225
228
 
226
229
  /** @public @react */
227
230
  export function StylePanelTextAlignPicker() {
228
- const { styles } = useStylePanelContext()
231
+ const { styles, enhancedA11yMode } = useStylePanelContext()
229
232
  const msg = useTranslation()
230
233
  const textAlign = styles.get(DefaultTextAlignStyle)
231
234
  if (textAlign === undefined) return null
235
+ const title = msg('style-panel.align')
232
236
 
233
237
  return (
234
- <TldrawUiToolbar orientation="horizontal" label={msg('style-panel.align')}>
235
- <StylePanelButtonPicker
236
- title={msg('style-panel.align')}
237
- uiType="align"
238
- style={DefaultTextAlignStyle}
239
- items={STYLES.textAlign}
240
- value={textAlign}
241
- />
242
- <TldrawUiToolbarButton
243
- type="icon"
244
- title={msg('style-panel.vertical-align')}
245
- data-testid="vertical-align"
246
- disabled
247
- >
248
- <TldrawUiButtonIcon icon="vertical-align-middle" />
249
- </TldrawUiToolbarButton>
250
- </TldrawUiToolbar>
238
+ <>
239
+ {enhancedA11yMode && <StylePanelSubheading>{title}</StylePanelSubheading>}
240
+ <TldrawUiToolbar orientation="horizontal" label={title}>
241
+ <StylePanelButtonPickerInline
242
+ title={title}
243
+ uiType="align"
244
+ style={DefaultTextAlignStyle}
245
+ items={STYLES.textAlign}
246
+ value={textAlign}
247
+ />
248
+ <TldrawUiToolbarButton
249
+ type="icon"
250
+ title={msg('style-panel.vertical-align')}
251
+ data-testid="vertical-align"
252
+ disabled
253
+ >
254
+ <TldrawUiButtonIcon icon="vertical-align-middle" />
255
+ </TldrawUiToolbarButton>
256
+ </TldrawUiToolbar>
257
+ </>
251
258
  )
252
259
  }
253
260
 
254
261
  /** @public @react */
255
262
  export function StylePanelLabelAlignPicker() {
256
- const { styles } = useStylePanelContext()
263
+ const { styles, enhancedA11yMode } = useStylePanelContext()
257
264
  const msg = useTranslation()
258
265
  const labelAlign = styles.get(DefaultHorizontalAlignStyle)
259
266
  const verticalLabelAlign = styles.get(DefaultVerticalAlignStyle)
260
267
  if (labelAlign === undefined) return null
268
+ const title = msg('style-panel.label-align')
261
269
 
262
270
  return (
263
- <TldrawUiToolbar orientation="horizontal" label={msg('style-panel.label-align')}>
264
- <StylePanelButtonPicker
265
- title={msg('style-panel.label-align')}
266
- uiType="align"
267
- style={DefaultHorizontalAlignStyle}
268
- items={STYLES.horizontalAlign}
269
- value={labelAlign}
270
- />
271
- {verticalLabelAlign === undefined ? (
272
- <TldrawUiToolbarButton
273
- type="icon"
274
- title={msg('style-panel.vertical-align')}
275
- data-testid="vertical-align"
276
- disabled
277
- >
278
- <TldrawUiButtonIcon icon="vertical-align-middle" />
279
- </TldrawUiToolbarButton>
280
- ) : (
281
- <StylePanelDropdownPicker
282
- type="icon"
283
- id="geo-vertical-alignment"
284
- uiType="verticalAlign"
285
- stylePanelType="vertical-align"
286
- style={DefaultVerticalAlignStyle}
287
- items={STYLES.verticalAlign}
288
- value={verticalLabelAlign}
271
+ <>
272
+ {enhancedA11yMode && <StylePanelSubheading>{title}</StylePanelSubheading>}
273
+ <TldrawUiToolbar orientation="horizontal" label={title}>
274
+ <StylePanelButtonPickerInline
275
+ title={title}
276
+ uiType="align"
277
+ style={DefaultHorizontalAlignStyle}
278
+ items={STYLES.horizontalAlign}
279
+ value={labelAlign}
289
280
  />
290
- )}
291
- </TldrawUiToolbar>
281
+ {verticalLabelAlign === undefined ? (
282
+ <TldrawUiToolbarButton
283
+ type="icon"
284
+ title={msg('style-panel.vertical-align')}
285
+ data-testid="vertical-align"
286
+ disabled
287
+ >
288
+ <TldrawUiButtonIcon icon="vertical-align-middle" />
289
+ </TldrawUiToolbarButton>
290
+ ) : (
291
+ <StylePanelDropdownPickerInline
292
+ type="icon"
293
+ id="geo-vertical-alignment"
294
+ uiType="verticalAlign"
295
+ stylePanelType="vertical-align"
296
+ style={DefaultVerticalAlignStyle}
297
+ items={STYLES.verticalAlign}
298
+ value={verticalLabelAlign}
299
+ />
300
+ )}
301
+ </TldrawUiToolbar>
302
+ </>
292
303
  )
293
304
  }
294
305
 
@@ -6,7 +6,7 @@ import {
6
6
  TLDefaultColorStyle,
7
7
  useEditor,
8
8
  } from '@tldraw/editor'
9
- import { memo, ReactElement, useMemo, useRef } from 'react'
9
+ import { memo, useMemo, useRef } from 'react'
10
10
  import { useDefaultColorTheme } from '../../../shapes/shared/useDefaultColorTheme'
11
11
  import { StyleValuesForUi } from '../../../styles'
12
12
  import { PORTRAIT_BREAKPOINT } from '../../constants'
@@ -34,8 +34,19 @@ export interface StylePanelButtonPickerProps<T extends string> {
34
34
  onHistoryMark?(id: string): void
35
35
  }
36
36
 
37
- /** @public */
38
- export const StylePanelButtonPicker = memo(function StylePanelButtonPicker<T extends string>(
37
+ function StylePanelButtonPickerInner<T extends string>(props: StylePanelButtonPickerProps<T>) {
38
+ const { enhancedA11yMode } = useStylePanelContext()
39
+ return (
40
+ <>
41
+ {enhancedA11yMode && <StylePanelSubheading>{props.title}</StylePanelSubheading>}
42
+ <TldrawUiToolbar label={props.title}>
43
+ <StylePanelButtonPickerInline {...props} />
44
+ </TldrawUiToolbar>
45
+ </>
46
+ )
47
+ }
48
+
49
+ function StylePanelButtonPickerInlineInner<T extends string>(
39
50
  props: StylePanelButtonPickerProps<T>
40
51
  ) {
41
52
  const ctx = useStylePanelContext()
@@ -126,54 +137,60 @@ export const StylePanelButtonPicker = memo(function StylePanelButtonPicker<T ext
126
137
  const Layout = items.length > 4 ? TldrawUiGrid : TldrawUiRow
127
138
 
128
139
  return (
129
- <>
130
- {ctx.enhancedA11yMode && <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 isActive = value.type === 'shared' && value.value === item.value
141
- const label =
142
- title + ' — ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
143
- return (
144
- <TldrawUiToolbarToggleItem
145
- type="icon"
146
- key={item.value}
147
- data-id={item.value}
148
- data-testid={`style.${uiType}.${item.value}`}
149
- aria-label={label + (isActive ? ` (${msg('style-panel.selected')})` : '')}
150
- tooltip={
151
- <>
152
- <div>{label}</div>
153
- {isActive ? <div>({msg('style-panel.selected')})</div> : null}
154
- </>
155
- }
156
- value={item.value}
157
- data-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}
158
- data-isactive={isActive}
159
- title={label}
160
- style={
161
- style === (DefaultColorStyle as StyleProp<unknown>)
162
- ? { color: getColorValue(theme, item.value as TLDefaultColorStyle, 'solid') }
163
- : undefined
164
- }
165
- onPointerEnter={handleButtonPointerEnter}
166
- onPointerDown={handleButtonPointerDown}
167
- onPointerUp={handleButtonPointerUp}
168
- onClick={handleButtonClick}
169
- >
170
- <TldrawUiButtonIcon icon={item.icon} />
171
- </TldrawUiToolbarToggleItem>
172
- )
173
- })}
174
- </Layout>
175
- </TldrawUiToolbarToggleGroup>
176
- </TldrawUiToolbar>
177
- </>
140
+ <TldrawUiToolbarToggleGroup
141
+ data-testid={`style.${uiType}`}
142
+ type="single"
143
+ value={value.type === 'shared' ? value.value : null}
144
+ asChild
145
+ >
146
+ <Layout>
147
+ {items.map((item) => {
148
+ const isActive = value.type === 'shared' && value.value === item.value
149
+ const label = title + ' — ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
150
+ return (
151
+ <TldrawUiToolbarToggleItem
152
+ type="icon"
153
+ key={item.value}
154
+ data-id={item.value}
155
+ data-testid={`style.${uiType}.${item.value}`}
156
+ aria-label={label + (isActive ? ` (${msg('style-panel.selected')})` : '')}
157
+ tooltip={
158
+ <>
159
+ <div>{label}</div>
160
+ {isActive ? <div>({msg('style-panel.selected')})</div> : null}
161
+ </>
162
+ }
163
+ value={item.value}
164
+ data-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}
165
+ data-isactive={isActive}
166
+ title={label}
167
+ style={
168
+ style === (DefaultColorStyle as StyleProp<unknown>)
169
+ ? { color: getColorValue(theme, item.value as TLDefaultColorStyle, 'solid') }
170
+ : undefined
171
+ }
172
+ onPointerEnter={handleButtonPointerEnter}
173
+ onPointerDown={handleButtonPointerDown}
174
+ onPointerUp={handleButtonPointerUp}
175
+ onClick={handleButtonClick}
176
+ >
177
+ <TldrawUiButtonIcon icon={item.icon} />
178
+ </TldrawUiToolbarToggleItem>
179
+ )
180
+ })}
181
+ </Layout>
182
+ </TldrawUiToolbarToggleGroup>
178
183
  )
179
- }) as <T extends string>(props: StylePanelButtonPickerProps<T>) => ReactElement
184
+ }
185
+
186
+ /** @public @react */
187
+ export const StylePanelButtonPicker = memo(StylePanelButtonPickerInner) as <T extends string>(
188
+ props: StylePanelButtonPickerProps<T>
189
+ ) => React.JSX.Element
190
+
191
+ /** @public @react*/
192
+ export const StylePanelButtonPickerInline = memo(StylePanelButtonPickerInlineInner) as <
193
+ T extends string,
194
+ >(
195
+ props: StylePanelButtonPickerProps<T>
196
+ ) => React.JSX.Element