tldraw 3.16.0-canary.cf24aedcd577 → 3.16.0-canary.d04b7fc312b4

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 (90) hide show
  1. package/dist-cjs/index.d.ts +2 -1
  2. package/dist-cjs/index.js +1 -1
  3. package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
  4. package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
  5. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
  6. package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
  7. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
  8. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
  9. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +4 -4
  10. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  11. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
  12. package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
  13. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
  14. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
  15. package/dist-cjs/lib/shapes/shared/ShapeFill.js +1 -1
  16. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  17. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
  18. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
  19. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
  20. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  21. package/dist-cjs/lib/ui/components/MobileStylePanel.js +1 -1
  22. package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
  23. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
  24. package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
  25. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +55 -89
  26. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  27. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
  28. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +0 -10
  29. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
  30. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +1 -18
  31. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  32. package/dist-cjs/lib/ui/hooks/useTools.js +21 -3
  33. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  34. package/dist-cjs/lib/ui/version.js +3 -3
  35. package/dist-cjs/lib/ui/version.js.map +1 -1
  36. package/dist-esm/index.d.mts +2 -1
  37. package/dist-esm/index.mjs +1 -1
  38. package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
  39. package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
  40. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
  41. package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
  42. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
  43. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
  44. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +4 -4
  45. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  46. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
  47. package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
  48. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
  49. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
  50. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +1 -1
  51. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  52. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
  53. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
  54. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
  55. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  56. package/dist-esm/lib/ui/components/MobileStylePanel.mjs +1 -1
  57. package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
  58. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
  59. package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
  60. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +64 -91
  61. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  62. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
  63. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +0 -10
  64. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
  65. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +1 -18
  66. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  67. package/dist-esm/lib/ui/hooks/useTools.mjs +22 -3
  68. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  69. package/dist-esm/lib/ui/version.mjs +3 -3
  70. package/dist-esm/lib/ui/version.mjs.map +1 -1
  71. package/package.json +3 -3
  72. package/src/lib/canvas/TldrawScribble.tsx +1 -1
  73. package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
  74. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
  75. package/src/lib/shapes/frame/FrameShapeUtil.tsx +12 -4
  76. package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
  77. package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
  78. package/src/lib/shapes/shared/ShapeFill.tsx +1 -1
  79. package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
  80. package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
  81. package/src/lib/ui/components/MobileStylePanel.tsx +1 -1
  82. package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
  83. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +77 -112
  84. package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
  85. package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +0 -10
  86. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +2 -16
  87. package/src/lib/ui/hooks/useTools.tsx +25 -3
  88. package/src/lib/ui/version.ts +3 -3
  89. package/src/lib/ui.css +227 -228
  90. package/tldraw.css +520 -518
@@ -1,7 +1,14 @@
1
- import { assert, Editor, uniqueId, useMaybeEditor, Vec } from '@tldraw/editor'
1
+ import { assert, Atom, atom, Editor, uniqueId, useMaybeEditor, useValue } from '@tldraw/editor'
2
2
  import { Tooltip as _Tooltip } from 'radix-ui'
3
- import React, { createContext, forwardRef, useContext, useEffect, useRef, useState } from 'react'
4
- import { usePrefersReducedMotion } from '../../../shapes/shared/usePrefersReducedMotion'
3
+ import React, {
4
+ createContext,
5
+ forwardRef,
6
+ ReactNode,
7
+ useContext,
8
+ useEffect,
9
+ useRef,
10
+ useState,
11
+ } from 'react'
5
12
  import { useTldrawUiOrientation } from './layout'
6
13
 
7
14
  const DEFAULT_TOOLTIP_DELAY_MS = 700
@@ -13,19 +20,21 @@ export interface TldrawUiTooltipProps {
13
20
  side?: 'top' | 'right' | 'bottom' | 'left'
14
21
  sideOffset?: number
15
22
  disabled?: boolean
23
+ showOnMobile?: boolean
16
24
  }
17
25
 
18
26
  // Singleton tooltip manager
19
27
  class TooltipManager {
20
28
  private static instance: TooltipManager | null = null
21
- private currentTooltipId: string | null = null
22
- private currentContent: string | React.ReactNode = ''
23
- private currentSide: 'top' | 'right' | 'bottom' | 'left' = 'bottom'
24
- private currentSideOffset: number = 5
29
+ private currentTooltip = atom<{
30
+ id: string
31
+ content: ReactNode
32
+ side: 'top' | 'right' | 'bottom' | 'left'
33
+ sideOffset: number
34
+ showOnMobile: boolean
35
+ targetElement: HTMLElement
36
+ } | null>('current tooltip', null)
25
37
  private destroyTimeoutId: number | null = null
26
- private subscribers: Set<() => void> = new Set()
27
- private activeElement: HTMLElement | null = null
28
- private editor: Editor | null = null
29
38
 
30
39
  static getInstance(): TooltipManager {
31
40
  if (!TooltipManager.instance) {
@@ -34,25 +43,13 @@ class TooltipManager {
34
43
  return TooltipManager.instance
35
44
  }
36
45
 
37
- setEditor(editor: Editor | null) {
38
- this.editor = editor
39
- }
40
-
41
- subscribe(callback: () => void): () => void {
42
- this.subscribers.add(callback)
43
- return () => this.subscribers.delete(callback)
44
- }
45
-
46
- private notify() {
47
- this.subscribers.forEach((callback) => callback())
48
- }
49
-
50
46
  showTooltip(
51
47
  tooltipId: string,
52
48
  content: string | React.ReactNode,
53
- element: HTMLElement,
54
- side: 'top' | 'right' | 'bottom' | 'left' = 'bottom',
55
- sideOffset: number = 5
49
+ targetElement: HTMLElement,
50
+ side: 'top' | 'right' | 'bottom' | 'left',
51
+ sideOffset: number,
52
+ showOnMobile: boolean
56
53
  ) {
57
54
  // Clear any existing destroy timeout
58
55
  if (this.destroyTimeoutId) {
@@ -61,51 +58,56 @@ class TooltipManager {
61
58
  }
62
59
 
63
60
  // Update current tooltip
64
- this.currentTooltipId = tooltipId
65
- this.currentContent = content
66
- this.currentSide = side
67
- this.currentSideOffset = sideOffset
68
- this.activeElement = element
69
-
70
- this.notify()
61
+ this.currentTooltip.set({
62
+ id: tooltipId,
63
+ content,
64
+ side,
65
+ sideOffset,
66
+ showOnMobile,
67
+ targetElement,
68
+ })
71
69
  }
72
70
 
73
- hideTooltip(tooltipId: string, instant: boolean = false) {
71
+ hideTooltip(editor: Editor | null, tooltipId: string, instant: boolean = false) {
74
72
  const hide = () => {
75
73
  // Only hide if this is the current tooltip
76
- if (this.currentTooltipId === tooltipId) {
77
- this.currentTooltipId = null
78
- this.currentContent = ''
79
- this.activeElement = null
74
+ if (this.currentTooltip.get()?.id === tooltipId) {
75
+ this.currentTooltip.set(null)
80
76
  this.destroyTimeoutId = null
81
- this.notify()
82
77
  }
83
78
  }
84
79
 
85
- if (instant) {
86
- hide()
87
- } else if (this.editor) {
80
+ if (editor && !instant) {
88
81
  // Start destroy timeout (1 second)
89
- this.destroyTimeoutId = this.editor.timers.setTimeout(hide, 300)
82
+ this.destroyTimeoutId = editor.timers.setTimeout(hide, 300)
83
+ } else {
84
+ hide()
90
85
  }
91
86
  }
92
87
 
93
88
  hideAllTooltips() {
94
- this.currentTooltipId = null
95
- this.currentContent = ''
96
- this.activeElement = null
89
+ this.currentTooltip.set(null)
97
90
  this.destroyTimeoutId = null
98
- this.notify()
99
91
  }
100
92
 
101
93
  getCurrentTooltipData() {
102
- return {
103
- id: this.currentTooltipId,
104
- content: this.currentContent,
105
- side: this.currentSide,
106
- sideOffset: this.currentSideOffset,
107
- element: this.activeElement,
94
+ const currentTooltip = this.currentTooltip.get()
95
+ if (!currentTooltip) return null
96
+ if (!this.supportsHover() && !currentTooltip.showOnMobile) return null
97
+ return currentTooltip
98
+ }
99
+
100
+ private supportsHoverAtom: Atom<boolean> | null = null
101
+ supportsHover() {
102
+ if (!this.supportsHoverAtom) {
103
+ const mediaQuery = window.matchMedia('(hover: hover)')
104
+ const supportsHover = atom('has hover', mediaQuery.matches)
105
+ this.supportsHoverAtom = supportsHover
106
+ mediaQuery.addEventListener('change', (e) => {
107
+ supportsHover.set(e.matches)
108
+ })
108
109
  }
110
+ return this.supportsHoverAtom.get()
109
111
  }
110
112
  }
111
113
 
@@ -134,65 +136,30 @@ export function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderPro
134
136
  // The singleton tooltip component that renders once
135
137
  function TooltipSingleton() {
136
138
  const editor = useMaybeEditor()
137
- const [, forceUpdate] = useState({})
138
139
  const [isOpen, setIsOpen] = useState(false)
139
140
  const triggerRef = useRef<HTMLDivElement>(null)
140
- const previousPositionRef = useRef<{ x: number; y: number } | null>(null)
141
- const prefersReducedMotion = usePrefersReducedMotion()
142
- const [shouldAnimate, setShouldAnimate] = useState(false)
143
141
  const isFirstShowRef = useRef(true)
144
142
  const showTimeoutRef = useRef<number | null>(null)
145
143
 
146
- // Set editor in tooltip manager
147
- useEffect(() => {
148
- tooltipManager.setEditor(editor)
149
- }, [editor])
150
-
151
- // Subscribe to tooltip manager updates
152
- useEffect(() => {
153
- const unsubscribe = tooltipManager.subscribe(() => {
154
- forceUpdate({})
155
- })
156
- return unsubscribe
157
- }, [])
158
-
159
- const tooltipData = tooltipManager.getCurrentTooltipData()
144
+ const currentTooltip = useValue(
145
+ 'current tooltip',
146
+ () => tooltipManager.getCurrentTooltipData(),
147
+ []
148
+ )
160
149
 
161
150
  // Update open state and trigger position
162
151
  useEffect(() => {
163
- const shouldBeOpen = Boolean(tooltipData.id && tooltipData.element)
164
-
165
152
  // Clear any existing show timeout
166
153
  if (showTimeoutRef.current) {
167
154
  clearTimeout(showTimeoutRef.current)
168
155
  showTimeoutRef.current = null
169
156
  }
170
157
 
171
- if (shouldBeOpen && tooltipData.element && triggerRef.current) {
158
+ if (currentTooltip && triggerRef.current) {
172
159
  // Position the invisible trigger element over the active element
173
- const activeRect = tooltipData.element.getBoundingClientRect()
160
+ const activeRect = currentTooltip.targetElement.getBoundingClientRect()
174
161
  const trigger = triggerRef.current
175
162
 
176
- const newPosition = {
177
- x: activeRect.left + activeRect.width / 2,
178
- y: activeRect.top + activeRect.height / 2,
179
- }
180
-
181
- // Determine if we should animate
182
- let shouldAnimateCheck = false
183
- if (previousPositionRef.current) {
184
- const isNearPrevious = Vec.DistMin(previousPositionRef.current, newPosition, 200)
185
- // Only animate if the distance is less than 200px (nearby tooltips)
186
- shouldAnimateCheck =
187
- !prefersReducedMotion &&
188
- isNearPrevious &&
189
- Math.abs(newPosition.y - previousPositionRef.current.y) < 50
190
- }
191
- // Don't animate on initial show (previousPositionRef.current is null)
192
-
193
- setShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck)
194
- previousPositionRef.current = newPosition
195
-
196
163
  trigger.style.position = 'fixed'
197
164
  trigger.style.left = `${activeRect.left}px`
198
165
  trigger.style.top = `${activeRect.top}px`
@@ -211,18 +178,15 @@ function TooltipSingleton() {
211
178
  // Subsequent tooltips show immediately
212
179
  setIsOpen(true)
213
180
  }
214
- } else if (!shouldBeOpen) {
181
+ } else {
215
182
  // Hide tooltip immediately
216
183
  setIsOpen(false)
217
- // Reset position tracking when tooltip closes
218
- previousPositionRef.current = null
219
- setShouldAnimate(false)
220
184
  // Reset first show state after tooltip is hidden
221
185
  isFirstShowRef.current = true
222
186
  }
223
- }, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion])
187
+ }, [editor, currentTooltip])
224
188
 
225
- if (!tooltipData.id) {
189
+ if (!currentTooltip) {
226
190
  return null
227
191
  }
228
192
 
@@ -233,14 +197,13 @@ function TooltipSingleton() {
233
197
  </_Tooltip.Trigger>
234
198
  <_Tooltip.Content
235
199
  className="tlui-tooltip"
236
- data-should-animate={shouldAnimate}
237
- side={tooltipData.side}
238
- sideOffset={tooltipData.sideOffset}
200
+ side={currentTooltip.side}
201
+ sideOffset={currentTooltip.sideOffset}
239
202
  avoidCollisions
240
203
  collisionPadding={8}
241
204
  dir="ltr"
242
205
  >
243
- {tooltipData.content}
206
+ {currentTooltip.content}
244
207
  <_Tooltip.Arrow className="tlui-tooltip__arrow" />
245
208
  </_Tooltip.Content>
246
209
  </_Tooltip.Root>
@@ -249,7 +212,7 @@ function TooltipSingleton() {
249
212
 
250
213
  /** @public @react */
251
214
  export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProps>(
252
- ({ children, content, side, sideOffset = 5, disabled = false }, ref) => {
215
+ ({ children, content, side, sideOffset = 5, disabled = false, showOnMobile = false }, ref) => {
253
216
  const editor = useMaybeEditor()
254
217
  const tooltipId = useRef<string>(uniqueId())
255
218
  const hasProvider = useContext(TooltipSingletonContext)
@@ -261,10 +224,10 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
261
224
  const currentTooltipId = tooltipId.current
262
225
  return () => {
263
226
  if (hasProvider) {
264
- tooltipManager.hideTooltip(currentTooltipId, true)
227
+ tooltipManager.hideTooltip(editor, currentTooltipId, true)
265
228
  }
266
229
  }
267
- }, [hasProvider])
230
+ }, [editor, hasProvider])
268
231
 
269
232
  // Don't show tooltip if disabled, no content, or UI labels are disabled
270
233
  if (disabled || !content) {
@@ -306,13 +269,14 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
306
269
  content,
307
270
  event.currentTarget as HTMLElement,
308
271
  sideToUse,
309
- sideOffset
272
+ sideOffset,
273
+ showOnMobile
310
274
  )
311
275
  }
312
276
 
313
277
  const handleMouseLeave = (event: React.MouseEvent<HTMLElement>) => {
314
278
  child.props.onMouseLeave?.(event)
315
- tooltipManager.hideTooltip(tooltipId.current)
279
+ tooltipManager.hideTooltip(editor, tooltipId.current)
316
280
  }
317
281
 
318
282
  const handleFocus = (event: React.FocusEvent<HTMLElement>) => {
@@ -322,13 +286,14 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
322
286
  content,
323
287
  event.currentTarget as HTMLElement,
324
288
  sideToUse,
325
- sideOffset
289
+ sideOffset,
290
+ showOnMobile
326
291
  )
327
292
  }
328
293
 
329
294
  const handleBlur = (event: React.FocusEvent<HTMLElement>) => {
330
295
  child.props.onBlur?.(event)
331
- tooltipManager.hideTooltip(tooltipId.current)
296
+ tooltipManager.hideTooltip(editor, tooltipId.current)
332
297
  }
333
298
 
334
299
  const childrenWithHandlers = React.cloneElement(children as React.ReactElement, {
@@ -3,7 +3,6 @@ import { TLUiEventSource } from '../../../context/events'
3
3
 
4
4
  /** @public */
5
5
  export type TLUiMenuContextType =
6
- | 'panel'
7
6
  | 'menu'
8
7
  | 'small-icons'
9
8
  | 'context-menu'
@@ -27,16 +27,6 @@ export function TldrawUiMenuGroup({ id, label, className, children }: TLUiMenuGr
27
27
  const labelStr = labelToUse ? msg(labelToUse as TLUiTranslationKey) : undefined
28
28
 
29
29
  switch (menu.type) {
30
- case 'panel': {
31
- return (
32
- <div
33
- className={classNames('tlui-menu__group', className)}
34
- data-testid={`${menu.sourceId}-group.${id}`}
35
- >
36
- {children}
37
- </div>
38
- )
39
- }
40
30
  case 'menu': {
41
31
  return (
42
32
  <TldrawUiDropdownMenuGroup
@@ -120,7 +120,6 @@ export function TldrawUiMenuItem<
120
120
  type="menu"
121
121
  data-testid={`${sourceId}.${id}`}
122
122
  disabled={disabled}
123
- title={titleStr}
124
123
  onClick={(e) => {
125
124
  if (noClose) {
126
125
  preventDefault(e)
@@ -146,7 +145,6 @@ export function TldrawUiMenuItem<
146
145
  return (
147
146
  <_ContextMenu.Item
148
147
  dir="ltr"
149
- title={titleStr}
150
148
  draggable={false}
151
149
  className="tlui-button tlui-button__menu"
152
150
  data-testid={`${sourceId}.${id}`}
@@ -168,20 +166,6 @@ export function TldrawUiMenuItem<
168
166
  </_ContextMenu.Item>
169
167
  )
170
168
  }
171
- case 'panel': {
172
- return (
173
- <TldrawUiButton
174
- data-testid={`${sourceId}.${id}`}
175
- type="menu"
176
- title={titleStr}
177
- disabled={disabled}
178
- onClick={() => onSelect(sourceId)}
179
- >
180
- <TldrawUiButtonLabel>{labelStr}</TldrawUiButtonLabel>
181
- {spinner ? <Spinner /> : icon && <TldrawUiButtonIcon icon={icon} />}
182
- </TldrawUiButton>
183
- )
184
- }
185
169
  case 'small-icons':
186
170
  case 'icons': {
187
171
  return (
@@ -342,6 +326,8 @@ function useDraggableEvents(
342
326
  }
343
327
 
344
328
  editor.run(() => {
329
+ editor.setCurrentTool('select')
330
+
345
331
  // Set origin point
346
332
  editor.dispatch({
347
333
  type: 'pointer',
@@ -3,6 +3,8 @@ import {
3
3
  createShapeId,
4
4
  Editor,
5
5
  GeoShapeGeoStyle,
6
+ getIndicesBetween,
7
+ TLLineShape,
6
8
  TLPointerEventInfo,
7
9
  TLShapeId,
8
10
  toRichText,
@@ -153,7 +155,8 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
153
155
  },
154
156
  onDragStart(source: TLUiEventSource, info: TLPointerEventInfo) {
155
157
  onDragFromToolbarToCreateShape(editor, info, {
156
- createShape: (id) => editor.createShape({ id, type: 'geo', props: { geo } }),
158
+ createShape: (id) =>
159
+ editor.createShape({ id, type: 'geo', props: { w: 200, h: 200, geo } }),
157
160
  })
158
161
  trackEvent('drag-tool', { source, id: 'geo' })
159
162
  },
@@ -188,6 +191,24 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
188
191
  editor.setCurrentTool('line')
189
192
  onToolSelect(source, this)
190
193
  },
194
+ onDragStart(source, info) {
195
+ onDragFromToolbarToCreateShape(editor, info, {
196
+ createShape: (id) => {
197
+ const [start, end] = getIndicesBetween(null, null, 2)
198
+ editor.createShape<TLLineShape>({
199
+ id,
200
+ type: 'line',
201
+ props: {
202
+ points: {
203
+ [start]: { id: start, index: start, x: 0, y: 200 },
204
+ [end]: { id: end, index: end, x: 200, y: 0 },
205
+ },
206
+ },
207
+ })
208
+ },
209
+ })
210
+ trackEvent('drag-tool', { source, id: 'line' })
211
+ },
191
212
  },
192
213
  {
193
214
  id: 'frame',
@@ -219,8 +240,8 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
219
240
  createShape: (id) =>
220
241
  editor.createShape({ id, type: 'text', props: { richText: toRichText('Text') } }),
221
242
  onDragEnd: (id) => {
222
- editor.emit('select-all-text', { shapeId: id })
223
243
  editor.setEditingShape(id)
244
+ editor.emit('select-all-text', { shapeId: id })
224
245
  },
225
246
  })
226
247
  trackEvent('drag-tool', { source, id: 'text' })
@@ -249,8 +270,8 @@ export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
249
270
  onDragFromToolbarToCreateShape(editor, info, {
250
271
  createShape: (id) => editor.createShape({ id, type: 'note' }),
251
272
  onDragEnd: (id) => {
252
- editor.emit('select-all-text', { shapeId: id })
253
273
  editor.setEditingShape(id)
274
+ editor.emit('select-all-text', { shapeId: id })
254
275
  },
255
276
  })
256
277
  trackEvent('drag-tool', { source, id: 'note' })
@@ -365,5 +386,6 @@ export function onDragFromToolbarToCreateShape(
365
386
  opts.onDragEnd?.(id)
366
387
  },
367
388
  })
389
+
368
390
  editor.getCurrentTool().setCurrentToolIdMask(shape.type)
369
391
  }
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.16.0-canary.cf24aedcd577'
4
+ export const version = '3.16.0-canary.d04b7fc312b4'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-08-11T15:30:09.531Z',
8
- patch: '2025-08-11T15:30:09.531Z',
7
+ minor: '2025-08-14T09:26:55.295Z',
8
+ patch: '2025-08-14T09:26:55.295Z',
9
9
  }