tldraw 3.16.0-canary.1efac4751756 → 3.16.0-canary.1f09406e5b86

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 (106) hide show
  1. package/dist-cjs/index.d.ts +86 -5
  2. package/dist-cjs/index.js +5 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/shapes/arrow/arrow-types.js.map +1 -1
  5. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +3 -2
  6. package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
  7. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +1 -1
  8. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  9. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +1 -1
  10. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  11. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js +8 -2
  12. package/dist-cjs/lib/shapes/frame/components/FrameLabelInput.js.map +2 -2
  13. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +1 -1
  14. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  15. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +2 -3
  16. package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
  17. package/dist-cjs/lib/shapes/text/PlainTextArea.js +2 -1
  18. package/dist-cjs/lib/shapes/text/PlainTextArea.js.map +2 -2
  19. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +3 -1
  20. package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
  21. package/dist-cjs/lib/ui/components/A11y.js +1 -1
  22. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  23. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +1 -1
  24. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  25. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +1 -1
  26. package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
  27. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +1 -1
  28. package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
  29. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +6 -2
  30. package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
  31. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
  32. package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
  33. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +2 -2
  34. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  35. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +3 -3
  36. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  37. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js +1 -1
  38. package/dist-cjs/lib/ui/hooks/useClipboardEvents.js.map +2 -2
  39. package/dist-cjs/lib/ui/version.js +3 -3
  40. package/dist-cjs/lib/ui/version.js.map +1 -1
  41. package/dist-esm/index.d.mts +86 -5
  42. package/dist-esm/index.mjs +9 -1
  43. package/dist-esm/index.mjs.map +2 -2
  44. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +3 -2
  45. package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
  46. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +1 -1
  47. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  48. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +1 -2
  49. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  50. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs +9 -3
  51. package/dist-esm/lib/shapes/frame/components/FrameLabelInput.mjs.map +2 -2
  52. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +2 -2
  53. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  54. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +2 -4
  55. package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
  56. package/dist-esm/lib/shapes/text/PlainTextArea.mjs +3 -2
  57. package/dist-esm/lib/shapes/text/PlainTextArea.mjs.map +2 -2
  58. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +3 -1
  59. package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
  60. package/dist-esm/lib/ui/components/A11y.mjs +1 -2
  61. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  62. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +1 -1
  63. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  64. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +1 -2
  65. package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
  66. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +1 -1
  67. package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
  68. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +6 -2
  69. package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
  70. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -2
  71. package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
  72. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +2 -2
  73. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  74. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +3 -3
  75. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  76. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs +1 -2
  77. package/dist-esm/lib/ui/hooks/useClipboardEvents.mjs.map +2 -2
  78. package/dist-esm/lib/ui/version.mjs +3 -3
  79. package/dist-esm/lib/ui/version.mjs.map +1 -1
  80. package/package.json +3 -3
  81. package/src/index.ts +7 -0
  82. package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +83 -13
  83. package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +97 -3
  84. package/src/lib/shapes/arrow/arrow-types.ts +3 -5
  85. package/src/lib/shapes/arrow/arrowTargetState.ts +34 -3
  86. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +1 -1
  87. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +1 -2
  88. package/src/lib/shapes/frame/components/FrameLabelInput.tsx +10 -3
  89. package/src/lib/shapes/shared/HyperlinkButton.tsx +2 -2
  90. package/src/lib/shapes/shared/useEditablePlainText.ts +2 -5
  91. package/src/lib/shapes/text/PlainTextArea.tsx +3 -2
  92. package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +6 -2
  93. package/src/lib/ui/components/A11y.tsx +1 -2
  94. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +1 -1
  95. package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +1 -2
  96. package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +1 -1
  97. package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +9 -2
  98. package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -2
  99. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +2 -2
  100. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +3 -3
  101. package/src/lib/ui/hooks/useClipboardEvents.ts +1 -2
  102. package/src/lib/ui/version.ts +3 -3
  103. package/src/lib/ui.css +14 -1
  104. package/src/test/TestEditor.ts +8 -2
  105. package/src/test/frames.test.ts +15 -0
  106. package/tldraw.css +14 -1
@@ -163,7 +163,7 @@ export class Pointing extends StateNode {
163
163
  const endHandle = handles.find((h) => h.id === 'end')!
164
164
  const change = util.onHandleDrag?.(this.editor.getShape(shape)!, {
165
165
  handle: { ...endHandle, x: point.x, y: point.y },
166
- isPrecise: false,
166
+ isPrecise: this.isPrecise,
167
167
  isCreatingShape: true,
168
168
  initial: initial,
169
169
  })
@@ -13,7 +13,6 @@ import {
13
13
  debounce,
14
14
  getHashForString,
15
15
  lerp,
16
- markEventAsHandled,
17
16
  tlenv,
18
17
  toDomPrecision,
19
18
  useEditor,
@@ -134,7 +133,7 @@ function BookmarkShapeComponent({ shape }: { shape: TLBookmarkShape }) {
134
133
 
135
134
  const markAsHandledOnShiftKey = useCallback<PointerEventHandler>(
136
135
  (e) => {
137
- if (!editor.inputs.shiftKey) markEventAsHandled(e)
136
+ if (!editor.inputs.shiftKey) editor.markEventAsHandled(e)
138
137
  },
139
138
  [editor]
140
139
  )
@@ -1,4 +1,4 @@
1
- import { TLFrameShape, TLShapeId, markEventAsHandled, useEditor } from '@tldraw/editor'
1
+ import { TLFrameShape, TLShapeId, useEditor } from '@tldraw/editor'
2
2
  import { forwardRef, useCallback } from 'react'
3
3
  import { defaultEmptyAs } from '../FrameShapeUtil'
4
4
 
@@ -8,12 +8,19 @@ export const FrameLabelInput = forwardRef<
8
8
  >(({ id, name, isEditing }, ref) => {
9
9
  const editor = useEditor()
10
10
 
11
+ const handlePointerDown = useCallback(
12
+ (e: React.PointerEvent) => {
13
+ if (isEditing) editor.markEventAsHandled(e)
14
+ },
15
+ [editor, isEditing]
16
+ )
17
+
11
18
  const handleKeyDown = useCallback(
12
19
  (e: React.KeyboardEvent<HTMLInputElement>) => {
13
20
  if (e.key === 'Enter' && !e.nativeEvent.isComposing) {
14
21
  // need to prevent the enter keydown making it's way up to the Idle state
15
22
  // and sending us back into edit mode
16
- markEventAsHandled(e)
23
+ editor.markEventAsHandled(e)
17
24
  e.currentTarget.blur()
18
25
  editor.setEditingShape(null)
19
26
  }
@@ -74,7 +81,7 @@ export const FrameLabelInput = forwardRef<
74
81
  onKeyDown={handleKeyDown}
75
82
  onBlur={handleBlur}
76
83
  onChange={handleChange}
77
- onPointerDown={isEditing ? markEventAsHandled : undefined}
84
+ onPointerDown={handlePointerDown}
78
85
  draggable={false}
79
86
  />
80
87
  {defaultEmptyAs(name, 'Frame') + String.fromCharCode(8203)}
@@ -1,4 +1,4 @@
1
- import { markEventAsHandled, useEditor, useValue } from '@tldraw/editor'
1
+ import { useEditor, useValue } from '@tldraw/editor'
2
2
  import classNames from 'classnames'
3
3
  import { PointerEventHandler, useCallback } from 'react'
4
4
 
@@ -10,7 +10,7 @@ export function HyperlinkButton({ url }: { url: string }) {
10
10
  const hideButton = useValue('zoomLevel', () => editor.getZoomLevel() < 0.32, [editor])
11
11
  const markAsHandledOnShiftKey = useCallback<PointerEventHandler>(
12
12
  (e) => {
13
- if (!editor.inputs.shiftKey) markEventAsHandled(e)
13
+ if (!editor.inputs.shiftKey) editor.markEventAsHandled(e)
14
14
  },
15
15
  [editor]
16
16
  )
@@ -3,7 +3,6 @@ import {
3
3
  TLShapeId,
4
4
  TLUnknownShape,
5
5
  getPointerInfo,
6
- markEventAsHandled,
7
6
  noop,
8
7
  preventDefault,
9
8
  tlenv,
@@ -129,7 +128,7 @@ export function useEditableTextCommon(shapeId: TLShapeId) {
129
128
  // partially if we didn't dispatch/stop below.
130
129
 
131
130
  editor.dispatch({
132
- ...getPointerInfo(e),
131
+ ...getPointerInfo(editor, e),
133
132
  type: 'pointer',
134
133
  name: 'pointer_down',
135
134
  target: 'shape',
@@ -157,13 +156,11 @@ export function useEditableTextCommon(shapeId: TLShapeId) {
157
156
  [editor, shapeId]
158
157
  )
159
158
 
160
- const handleDoubleClick: (e: React.MouseEvent) => void = markEventAsHandled
161
-
162
159
  return {
163
160
  handleFocus: noop,
164
161
  handleBlur: noop,
165
162
  handleInputPointerDown,
166
- handleDoubleClick,
163
+ handleDoubleClick: editor.markEventAsHandled,
167
164
  handlePaste,
168
165
  isEditing,
169
166
  isReadyForEditing,
@@ -1,4 +1,4 @@
1
- import { markEventAsHandled, preventDefault } from '@tldraw/editor'
1
+ import { preventDefault, useEditor } from '@tldraw/editor'
2
2
  import React from 'react'
3
3
  import { TextAreaProps } from './RichTextArea'
4
4
 
@@ -21,6 +21,7 @@ export const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps
21
21
  },
22
22
  ref
23
23
  ) {
24
+ const editor = useEditor()
24
25
  const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
25
26
  handleChange({ plaintext: e.target.value })
26
27
  }
@@ -46,7 +47,7 @@ export const PlainTextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps
46
47
  onChange={onChange}
47
48
  onKeyDown={(e) => handleKeyDown(e.nativeEvent)}
48
49
  onBlur={handleBlur}
49
- onTouchEnd={markEventAsHandled}
50
+ onTouchEnd={editor.markEventAsHandled}
50
51
  onContextMenu={isEditing ? (e) => e.stopPropagation() : undefined}
51
52
  onPointerDown={handleInputPointerDown}
52
53
  onPaste={handlePaste}
@@ -13,6 +13,7 @@ import {
13
13
  sortByIndex,
14
14
  structuredClone,
15
15
  } from '@tldraw/editor'
16
+ import { ArrowShapeUtil } from '../../../shapes/arrow/ArrowShapeUtil'
16
17
  import { clearArrowTargetState } from '../../../shapes/arrow/arrowTargetState'
17
18
  import { getArrowBindings } from '../../../shapes/arrow/shared'
18
19
 
@@ -135,10 +136,13 @@ export class DraggingHandle extends StateNode {
135
136
  }
136
137
 
137
138
  // Only relevant to arrows
138
- private exactTimeout = -1 as any
139
+ private exactTimeout = -1
139
140
 
140
141
  // Only relevant to arrows
141
142
  private resetExactTimeout() {
143
+ const arrowUtil = this.editor.getShapeUtil<ArrowShapeUtil>('arrow')
144
+ const timeoutValue = arrowUtil.options.pointingPreciseTimeout
145
+
142
146
  if (this.exactTimeout !== -1) {
143
147
  this.clearExactTimeout()
144
148
  }
@@ -150,7 +154,7 @@ export class DraggingHandle extends StateNode {
150
154
  this.update()
151
155
  }
152
156
  this.exactTimeout = -1
153
- }, 750)
157
+ }, timeoutValue)
154
158
  }
155
159
 
156
160
  // Only relevant to arrows
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  debugFlags,
3
3
  Editor,
4
- markEventAsHandled,
5
4
  TLGeoShape,
6
5
  TLShapeId,
7
6
  unsafe__withoutCapture,
@@ -23,7 +22,7 @@ export function SkipToMainContent() {
23
22
 
24
23
  const handleNavigateToFirstShape = useCallback(
25
24
  (e: MouseEvent | KeyboardEvent) => {
26
- markEventAsHandled(e)
25
+ editor.markEventAsHandled(e)
27
26
  button.current?.blur()
28
27
  const shapes = editor.getCurrentPageShapesInReadingOrder()
29
28
  if (!shapes.length) return
@@ -159,7 +159,7 @@ export function DefaultMinimap() {
159
159
  type: 'pointer',
160
160
  target: 'canvas',
161
161
  name: 'pointer_move',
162
- ...getPointerInfo(e),
162
+ ...getPointerInfo(editor, e),
163
163
  point: screenPoint,
164
164
  isPen: editor.getInstanceState().isPenMode,
165
165
  }
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  PageRecordType,
3
3
  TLPageId,
4
- markEventAsHandled,
5
4
  releasePointerCapture,
6
5
  setPointerCapture,
7
6
  tlenv,
@@ -451,7 +450,7 @@ export const DefaultPageMenu = memo(function DefaultPageMenu() {
451
450
  if (e.key === 'Enter') {
452
451
  if (page.id === currentPage.id) {
453
452
  toggleEditing()
454
- markEventAsHandled(e)
453
+ editor.markEventAsHandled(e)
455
454
  }
456
455
  }
457
456
  }}
@@ -101,7 +101,7 @@ export function OverflowingToolbar({
101
101
  items: collectItems(child.children),
102
102
  element: child as HTMLElement,
103
103
  })
104
- } else {
104
+ } else if (!child.hasAttribute('data-radix-popper-content-wrapper')) {
105
105
  items.push({ type: 'item', element: child as HTMLElement })
106
106
  }
107
107
  }
@@ -1,8 +1,10 @@
1
1
  import { useEditor, useValue } from '@tldraw/editor'
2
2
  import classNames from 'classnames'
3
3
  import { PORTRAIT_BREAKPOINT } from '../../constants'
4
+ import { useActions } from '../../context/actions'
4
5
  import { useBreakpoint } from '../../context/breakpoints'
5
6
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
7
+ import { kbdStr } from '../../kbd-utils'
6
8
  import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
7
9
  import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
8
10
  import { TldrawUiTooltip } from '../primitives/TldrawUiTooltip'
@@ -17,6 +19,7 @@ export function ToggleToolLockedButton({ activeToolId }: ToggleToolLockedButtonP
17
19
  const editor = useEditor()
18
20
  const breakpoint = useBreakpoint()
19
21
  const msg = useTranslation()
22
+ const actions = useActions()
20
23
 
21
24
  const isToolLocked = useValue('is tool locked', () => editor.getInstanceState().isToolLocked, [
22
25
  editor,
@@ -25,11 +28,15 @@ export function ToggleToolLockedButton({ activeToolId }: ToggleToolLockedButtonP
25
28
 
26
29
  if (!activeToolId || !tool.isLockable) return null
27
30
 
31
+ const toggleLockAction = actions['toggle-tool-lock']
32
+ const tooltipContent = toggleLockAction?.kbd
33
+ ? `${msg('action.toggle-tool-lock')} ${kbdStr(toggleLockAction.kbd)}`
34
+ : msg('action.toggle-tool-lock')
35
+
28
36
  return (
29
- <TldrawUiTooltip content={msg('action.toggle-tool-lock')}>
37
+ <TldrawUiTooltip content={tooltipContent}>
30
38
  <TldrawUiButton
31
39
  type="normal"
32
- title={msg('action.toggle-tool-lock')}
33
40
  data-testid="tool-lock"
34
41
  className={classNames('tlui-main-toolbar__lock-button', {
35
42
  'tlui-main-toolbar__lock-button__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,
@@ -3,7 +3,6 @@ import {
3
3
  Box,
4
4
  clamp,
5
5
  Editor,
6
- markEventAsHandled,
7
6
  react,
8
7
  useAtom,
9
8
  useEditor,
@@ -170,7 +169,7 @@ export const TldrawUiContextualToolbar = ({
170
169
  data-visible={false}
171
170
  data-testid="contextual-toolbar"
172
171
  className={classNames('tlui-contextual-toolbar', className)}
173
- onPointerDown={markEventAsHandled}
172
+ onPointerDown={editor.markEventAsHandled}
174
173
  >
175
174
  <TldrawUiToolbar
176
175
  orientation="horizontal"
@@ -307,9 +307,9 @@ export const TldrawUiTooltip = forwardRef<HTMLButtonElement, TldrawUiTooltipProp
307
307
  }
308
308
 
309
309
  // Fallback to old behavior if no provider
310
- if (!hasProvider) {
310
+ if (!hasProvider || showUiLabels) {
311
311
  return (
312
- <_Tooltip.Root delayDuration={delayDurationToUse} disableHoverableContent>
312
+ <_Tooltip.Root delayDuration={delayDurationToUse} disableHoverableContent={!showUiLabels}>
313
313
  <_Tooltip.Trigger asChild ref={ref}>
314
314
  {children}
315
315
  </_Tooltip.Trigger>
@@ -333,7 +333,7 @@ function useDraggableEvents(
333
333
  type: 'pointer',
334
334
  target: 'canvas',
335
335
  name: 'pointer_down',
336
- ...getPointerInfo(e),
336
+ ...getPointerInfo(editor, e),
337
337
  point: screenSpaceStart,
338
338
  })
339
339
 
@@ -345,7 +345,7 @@ function useDraggableEvents(
345
345
  type: 'pointer',
346
346
  target: 'canvas',
347
347
  name: 'pointer_move',
348
- ...getPointerInfo(e),
348
+ ...getPointerInfo(editor, e),
349
349
  point: screenSpaceStart,
350
350
  })
351
351
 
@@ -365,7 +365,7 @@ function useDraggableEvents(
365
365
  type: 'pointer',
366
366
  target: 'canvas',
367
367
  name: 'pointer_up',
368
- ...getPointerInfo(e),
368
+ ...getPointerInfo(editor, e),
369
369
  })
370
370
  }
371
371
 
@@ -7,7 +7,6 @@ import {
7
7
  assert,
8
8
  compact,
9
9
  isDefined,
10
- markEventAsHandled,
11
10
  preventDefault,
12
11
  uniq,
13
12
  useEditor,
@@ -763,7 +762,7 @@ export function useNativeClipboardEvents() {
763
762
 
764
763
  const paste = (e: ClipboardEvent) => {
765
764
  if (disablingMiddleClickPaste) {
766
- markEventAsHandled(e)
765
+ editor.markEventAsHandled(e)
767
766
  return
768
767
  }
769
768
 
@@ -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.1efac4751756'
4
+ export const version = '3.16.0-canary.1f09406e5b86'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-09-16T22:07:50.660Z',
8
- patch: '2025-09-16T22:07:50.660Z',
7
+ minor: '2025-09-18T13:28:56.456Z',
8
+ patch: '2025-09-18T13:28:56.456Z',
9
9
  }
package/src/lib/ui.css CHANGED
@@ -168,7 +168,7 @@
168
168
  min-height: 40px;
169
169
  width: 100%;
170
170
  gap: 8px;
171
- margin: -4px 0px;
171
+ margin-top: -4px;
172
172
  }
173
173
 
174
174
  .tlui-button__menu::after {
@@ -1039,6 +1039,19 @@ tldraw? probably.
1039
1039
  display: none;
1040
1040
  }
1041
1041
 
1042
+ /*
1043
+ * This is used in a couple places, like Align and Vertical Align.
1044
+ * It's because we have a toolbar with a Toggle Group but then an adjacent button
1045
+ * next to it that opens a popup.
1046
+ */
1047
+ .tlui-style-panel__section .tlui-toolbar:has(.tlui-toolbar) {
1048
+ flex-wrap: wrap;
1049
+ }
1050
+
1051
+ .tlui-style-panel__section .tlui-toolbar:has(.tlui-toolbar) .tlui-style-panel__subheading {
1052
+ margin-left: -2px;
1053
+ }
1054
+
1042
1055
  .tlui-style-panel__section__common:not(:only-child) {
1043
1056
  margin-bottom: 7px;
1044
1057
  border-bottom: 1px solid var(--tl-color-divider);
@@ -86,8 +86,14 @@ export class TestEditor extends Editor {
86
86
  elm.tabIndex = 0
87
87
  elm.getBoundingClientRect = () => bounds as DOMRect
88
88
 
89
- const shapeUtilsWithDefaults = [...defaultShapeUtils, ...(options.shapeUtils ?? [])]
90
- const bindingUtilsWithDefaults = [...defaultBindingUtils, ...(options.bindingUtils ?? [])]
89
+ const shapeUtilsWithDefaults = [
90
+ ...defaultShapeUtils.filter((s) => !options.shapeUtils?.some((su) => su.type === s.type)),
91
+ ...(options.shapeUtils ?? []),
92
+ ]
93
+ const bindingUtilsWithDefaults = [
94
+ ...defaultBindingUtils.filter((b) => !options.bindingUtils?.some((bu) => bu.type === b.type)),
95
+ ...(options.bindingUtils ?? []),
96
+ ]
91
97
 
92
98
  super({
93
99
  ...options,
@@ -1680,3 +1680,18 @@ it('drops into the top-most frame, if there is one', () => {
1680
1680
 
1681
1681
  expect(editor.getShape(rect)?.parentId).toBe(editor.getCurrentPageId())
1682
1682
  })
1683
+
1684
+ it('does not get drop children of nested frame if they are occluded from the outer frame', () => {
1685
+ const frame1Id = dragCreateFrame({ down: [100, 100], move: [300, 300], up: [300, 300] })
1686
+ const frame2Id = dragCreateFrame({ down: [150, 150], move: [290, 290], up: [290, 290] })
1687
+
1688
+ const rect1 = createRect({ pos: [280, 160], size: [10, 30] })
1689
+
1690
+ expect(editor.getShape(rect1)?.parentId).toBe(frame2Id)
1691
+ expect(editor.getShape(frame2Id)?.parentId).toBe(frame1Id)
1692
+
1693
+ editor.select(frame2Id)
1694
+ editor.translateSelection(30, 0)
1695
+
1696
+ expect(editor.getShape(rect1)?.parentId).toBe(frame2Id)
1697
+ })
package/tldraw.css CHANGED
@@ -1964,7 +1964,7 @@ it from receiving any pointer events or affecting the cursor. */
1964
1964
  min-height: 40px;
1965
1965
  width: 100%;
1966
1966
  gap: 8px;
1967
- margin: -4px 0px;
1967
+ margin-top: -4px;
1968
1968
  }
1969
1969
 
1970
1970
  .tlui-button__menu::after {
@@ -2835,6 +2835,19 @@ tldraw? probably.
2835
2835
  display: none;
2836
2836
  }
2837
2837
 
2838
+ /*
2839
+ * This is used in a couple places, like Align and Vertical Align.
2840
+ * It's because we have a toolbar with a Toggle Group but then an adjacent button
2841
+ * next to it that opens a popup.
2842
+ */
2843
+ .tlui-style-panel__section .tlui-toolbar:has(.tlui-toolbar) {
2844
+ flex-wrap: wrap;
2845
+ }
2846
+
2847
+ .tlui-style-panel__section .tlui-toolbar:has(.tlui-toolbar) .tlui-style-panel__subheading {
2848
+ margin-left: -2px;
2849
+ }
2850
+
2838
2851
  .tlui-style-panel__section__common:not(:only-child) {
2839
2852
  margin-bottom: 7px;
2840
2853
  border-bottom: 1px solid var(--tl-color-divider);