@tldraw/editor 4.3.0-canary.da35795ba8e2 → 4.3.0-canary.e52fa5385f86

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 (71) hide show
  1. package/dist-cjs/index.d.ts +70 -35
  2. package/dist-cjs/index.js +2 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
  5. package/dist-cjs/lib/editor/Editor.js +24 -12
  6. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  7. package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +2 -2
  8. package/dist-cjs/lib/editor/derivations/bindingsIndex.js.map +2 -2
  9. package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
  10. package/dist-cjs/lib/editor/shapes/BaseBoxShapeUtil.js.map +1 -1
  11. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
  13. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.js.map +2 -2
  14. package/dist-cjs/lib/editor/tools/BaseBoxShapeTool/children/Pointing.js.map +2 -2
  15. package/dist-cjs/lib/editor/types/emit-types.js.map +1 -1
  16. package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
  17. package/dist-cjs/lib/globals/environment.js +45 -9
  18. package/dist-cjs/lib/globals/environment.js.map +2 -2
  19. package/dist-cjs/lib/globals/menus.js +1 -1
  20. package/dist-cjs/lib/globals/menus.js.map +2 -2
  21. package/dist-cjs/lib/hooks/useCoarsePointer.js +14 -29
  22. package/dist-cjs/lib/hooks/useCoarsePointer.js.map +2 -2
  23. package/dist-cjs/lib/utils/reparenting.js.map +2 -2
  24. package/dist-cjs/version.js +3 -3
  25. package/dist-cjs/version.js.map +1 -1
  26. package/dist-esm/index.d.mts +70 -35
  27. package/dist-esm/index.mjs +3 -2
  28. package/dist-esm/index.mjs.map +2 -2
  29. package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
  30. package/dist-esm/lib/editor/Editor.mjs +24 -12
  31. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  32. package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +2 -2
  33. package/dist-esm/lib/editor/derivations/bindingsIndex.mjs.map +2 -2
  34. package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
  35. package/dist-esm/lib/editor/shapes/BaseBoxShapeUtil.mjs.map +1 -1
  36. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  37. package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
  38. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.mjs.map +2 -2
  39. package/dist-esm/lib/editor/tools/BaseBoxShapeTool/children/Pointing.mjs.map +2 -2
  40. package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
  41. package/dist-esm/lib/globals/environment.mjs +45 -9
  42. package/dist-esm/lib/globals/environment.mjs.map +2 -2
  43. package/dist-esm/lib/globals/menus.mjs +1 -1
  44. package/dist-esm/lib/globals/menus.mjs.map +2 -2
  45. package/dist-esm/lib/hooks/useCoarsePointer.mjs +15 -30
  46. package/dist-esm/lib/hooks/useCoarsePointer.mjs.map +2 -2
  47. package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
  48. package/dist-esm/version.mjs +3 -3
  49. package/dist-esm/version.mjs.map +1 -1
  50. package/package.json +10 -10
  51. package/src/index.ts +1 -1
  52. package/src/lib/components/default-components/DefaultCanvas.tsx +1 -0
  53. package/src/lib/editor/Editor.test.ts +10 -10
  54. package/src/lib/editor/Editor.ts +110 -59
  55. package/src/lib/editor/bindings/BindingUtil.ts +15 -9
  56. package/src/lib/editor/derivations/bindingsIndex.ts +2 -2
  57. package/src/lib/editor/managers/FontManager/FontManager.test.ts +14 -4
  58. package/src/lib/editor/managers/SnapManager/SnapManager.ts +3 -3
  59. package/src/lib/editor/shapes/BaseBoxShapeUtil.tsx +2 -2
  60. package/src/lib/editor/shapes/ShapeUtil.ts +5 -8
  61. package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -3
  62. package/src/lib/editor/tools/BaseBoxShapeTool/BaseBoxShapeTool.ts +2 -1
  63. package/src/lib/editor/tools/BaseBoxShapeTool/children/Pointing.ts +3 -3
  64. package/src/lib/editor/types/emit-types.ts +3 -1
  65. package/src/lib/exports/getSvgJsx.test.ts +10 -19
  66. package/src/lib/exports/getSvgJsx.tsx +2 -5
  67. package/src/lib/globals/environment.ts +65 -10
  68. package/src/lib/globals/menus.ts +1 -1
  69. package/src/lib/hooks/useCoarsePointer.ts +16 -59
  70. package/src/lib/utils/reparenting.ts +5 -5
  71. package/src/version.ts +3 -3
@@ -26,10 +26,7 @@ import { TLClickEventInfo } from '../types/event-types'
26
26
  import { TLResizeHandle } from '../types/selection-types'
27
27
 
28
28
  /** @public */
29
- export interface TLShapeUtilConstructor<
30
- T extends TLUnknownShape,
31
- U extends ShapeUtil<T> = ShapeUtil<T>,
32
- > {
29
+ export interface TLShapeUtilConstructor<T extends TLShape, U extends ShapeUtil<T> = ShapeUtil<T>> {
33
30
  new (editor: Editor): U
34
31
  type: T['type']
35
32
  props?: RecordProps<T>
@@ -42,11 +39,11 @@ export interface TLShapeUtilConstructor<
42
39
  *
43
40
  * @public
44
41
  */
45
- export interface TLShapeUtilCanBindOpts<Shape extends TLUnknownShape = TLUnknownShape> {
42
+ export interface TLShapeUtilCanBindOpts<Shape extends TLShape = TLShape> {
46
43
  /** The type of shape referenced by the `fromId` of the binding. */
47
- fromShapeType: string
44
+ fromShapeType: TLShape['type']
48
45
  /** The type of shape referenced by the `toId` of the binding. */
49
- toShapeType: string
46
+ toShapeType: TLShape['type']
50
47
  /** The type of binding. */
51
48
  bindingType: string
52
49
  }
@@ -79,7 +76,7 @@ export interface TLShapeUtilCanvasSvgDef {
79
76
  }
80
77
 
81
78
  /** @public */
82
- export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
79
+ export abstract class ShapeUtil<Shape extends TLShape = TLShape> {
83
80
  /** Configure this shape utils {@link ShapeUtil.options | `options`}. */
84
81
  static configure<T extends TLShapeUtilConstructor<any, any>>(
85
82
  this: T,
@@ -55,9 +55,7 @@ export class GroupShapeUtil extends ShapeUtil<TLGroupShape> {
55
55
  const isHintingOtherGroup =
56
56
  hintingShapeIds.length > 0 &&
57
57
  hintingShapeIds.some(
58
- (id) =>
59
- id !== shape.id &&
60
- this.editor.isShapeOfType<TLGroupShape>(this.editor.getShape(id)!, 'group')
58
+ (id) => id !== shape.id && this.editor.isShapeOfType(this.editor.getShape(id)!, 'group')
61
59
  )
62
60
 
63
61
  const isFocused = this.editor.getCurrentPageState().focusedGroupId !== shape.id
@@ -1,4 +1,5 @@
1
1
  import { TLShape } from '@tldraw/tlschema'
2
+ import { TLBaseBoxShape } from '../../shapes/BaseBoxShapeUtil'
2
3
  import { StateNode, TLStateNodeConstructor } from '../StateNode'
3
4
  import { Idle } from './children/Idle'
4
5
  import { Pointing } from './children/Pointing'
@@ -11,7 +12,7 @@ export abstract class BaseBoxShapeTool extends StateNode {
11
12
  return [Idle, Pointing]
12
13
  }
13
14
 
14
- abstract override shapeType: string
15
+ abstract override shapeType: TLBaseBoxShape['type']
15
16
 
16
17
  onCreate?(_shape: TLShape | null): void | null
17
18
  }
@@ -23,7 +23,7 @@ export class Pointing extends StateNode {
23
23
  const newPoint = maybeSnapToGrid(originPagePoint, editor)
24
24
 
25
25
  // Allow this to trigger the max shapes reached alert
26
- this.editor.createShapes<TLBaseBoxShape>([
26
+ this.editor.createShapes([
27
27
  {
28
28
  id,
29
29
  type: shapeType,
@@ -88,7 +88,7 @@ export class Pointing extends StateNode {
88
88
 
89
89
  // Allow this to trigger the max shapes reached alert
90
90
  // todo: add scale here when dynamic size is enabled (is this still needed?)
91
- this.editor.createShapes<TLBaseBoxShape>([
91
+ this.editor.createShapes([
92
92
  {
93
93
  id,
94
94
  type: shapeType,
@@ -127,7 +127,7 @@ export class Pointing extends StateNode {
127
127
  ;(next as TLBaseBoxShape & { props: { scale: number } }).props.scale = scale
128
128
  }
129
129
 
130
- this.editor.updateShape<TLBaseBoxShape>(next)
130
+ this.editor.updateShape(next)
131
131
 
132
132
  this.editor.setSelectedShapes([id])
133
133
 
@@ -1,5 +1,5 @@
1
1
  import { HistoryEntry } from '@tldraw/store'
2
- import { TLPageId, TLRecord, TLShapeId } from '@tldraw/tlschema'
2
+ import { BoxModel, TLPageId, TLRecord, TLShapeId } from '@tldraw/tlschema'
3
3
  import { TLEventInfo } from './event-types'
4
4
 
5
5
  /** @public */
@@ -16,12 +16,14 @@ export interface TLEventMap {
16
16
  event: [TLEventInfo]
17
17
  tick: [number]
18
18
  frame: [number]
19
+ resize: [BoxModel]
19
20
  'select-all-text': [{ shapeId: TLShapeId }]
20
21
  'place-caret': [{ shapeId: TLShapeId; point: { x: number; y: number } }]
21
22
  'created-shapes': [TLRecord[]]
22
23
  'edited-shapes': [TLRecord[]]
23
24
  'deleted-shapes': [TLShapeId[]]
24
25
  edit: []
26
+ dispose: []
25
27
  }
26
28
 
27
29
  /** @public */
@@ -1,30 +1,21 @@
1
- import {
2
- Geometry2d,
3
- RecordProps,
4
- Rectangle2d,
5
- ShapeUtil,
6
- T,
7
- TLBaseShape,
8
- createShapeId,
9
- } from '../..'
1
+ import { Geometry2d, RecordProps, Rectangle2d, ShapeUtil, T, TLShape, createShapeId } from '../..'
10
2
  import { createTLStore } from '../config/createTLStore'
11
3
  import { Editor } from '../editor/Editor'
12
4
  import { Box } from '../primitives/Box'
13
5
  import { getExportDefaultBounds } from './getSvgJsx'
14
6
 
15
- type ITestShape = TLBaseShape<
16
- 'test-shape',
17
- {
18
- w: number
19
- h: number
20
- x: number
21
- y: number
22
- isContainer?: boolean
7
+ const TEST_SHAPE_TYPE = 'test-shape'
8
+
9
+ declare module '@tldraw/tlschema' {
10
+ export interface TLGlobalShapePropsMap {
11
+ [TEST_SHAPE_TYPE]: { w: number; h: number; x: number; y: number; isContainer?: boolean }
23
12
  }
24
- >
13
+ }
14
+
15
+ type ITestShape = TLShape<typeof TEST_SHAPE_TYPE>
25
16
 
26
17
  class TestShape extends ShapeUtil<ITestShape> {
27
- static override type = 'test-shape' as const
18
+ static override type = TEST_SHAPE_TYPE
28
19
  static override props: RecordProps<ITestShape> = {
29
20
  w: T.number,
30
21
  h: T.number,
@@ -1,7 +1,6 @@
1
1
  import { useAtom, useValue } from '@tldraw/state-react'
2
2
  import {
3
3
  TLFrameShape,
4
- TLGroupShape,
5
4
  TLShape,
6
5
  TLShapeId,
7
6
  getColorValue,
@@ -58,9 +57,7 @@ export function getSvgJsx(editor: Editor, ids: TLShapeId[], opts: TLImageExportO
58
57
 
59
58
  // --- Common bounding box of all shapes
60
59
  const singleFrameShapeId =
61
- ids.length === 1 && editor.isShapeOfType<TLFrameShape>(editor.getShape(ids[0])!, 'frame')
62
- ? ids[0]
63
- : null
60
+ ids.length === 1 && editor.isShapeOfType(editor.getShape(ids[0])!, 'frame') ? ids[0] : null
64
61
 
65
62
  let bbox: null | Box = null
66
63
  if (opts.bounds) {
@@ -272,7 +269,7 @@ function SvgExport({
272
269
 
273
270
  const shape = editor.getShape(id)!
274
271
 
275
- if (editor.isShapeOfType<TLGroupShape>(shape, 'group')) return []
272
+ if (editor.isShapeOfType(shape, 'group')) return []
276
273
 
277
274
  const elements = []
278
275
  const util = editor.getShapeUtil(shape)
@@ -1,5 +1,9 @@
1
+ import { atom } from '@tldraw/state'
2
+
1
3
  /**
2
4
  * An object that contains information about the current device and environment.
5
+ * This object is not reactive and will not update automatically when the environment changes,
6
+ * so only include values that are fixed, such as the user's browser and operating system.
3
7
  *
4
8
  * @public
5
9
  */
@@ -14,15 +18,66 @@ const tlenv = {
14
18
  hasCanvasSupport: false,
15
19
  }
16
20
 
17
- if (typeof window !== 'undefined' && 'navigator' in window) {
18
- tlenv.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
19
- tlenv.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i)
20
- tlenv.isChromeForIos = /crios.*safari/i.test(navigator.userAgent)
21
- tlenv.isFirefox = /firefox/i.test(navigator.userAgent)
22
- tlenv.isAndroid = /android/i.test(navigator.userAgent)
23
- tlenv.isDarwin = window.navigator.userAgent.toLowerCase().indexOf('mac') > -1
24
- tlenv.hasCanvasSupport =
25
- typeof window !== 'undefined' && 'Promise' in window && 'HTMLCanvasElement' in window
21
+ let isForcedFinePointer = false
22
+
23
+ if (typeof window !== 'undefined') {
24
+ if ('navigator' in window) {
25
+ tlenv.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
26
+ tlenv.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i)
27
+ tlenv.isChromeForIos = /crios.*safari/i.test(navigator.userAgent)
28
+ tlenv.isFirefox = /firefox/i.test(navigator.userAgent)
29
+ tlenv.isAndroid = /android/i.test(navigator.userAgent)
30
+ tlenv.isDarwin = window.navigator.userAgent.toLowerCase().indexOf('mac') > -1
31
+ }
32
+ tlenv.hasCanvasSupport = 'Promise' in window && 'HTMLCanvasElement' in window
33
+ isForcedFinePointer = tlenv.isFirefox && !tlenv.isAndroid && !tlenv.isIos
34
+ }
35
+
36
+ /**
37
+ * An atom that contains information about the current device and environment.
38
+ * This object is reactive and will update automatically when the environment changes.
39
+ * Use it for values that may change over time, such as the pointer type.
40
+ *
41
+ * @public
42
+ */
43
+ const tlenvReactive = atom('tlenvReactive', {
44
+ // Whether the user's device has a coarse pointer. This is dynamic on many systems, especially
45
+ // on touch-screen laptops, which will become "coarse" if the user touches the screen.
46
+ // See https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer#coarse
47
+ isCoarsePointer: false,
48
+ })
49
+
50
+ if (typeof window !== 'undefined' && !isForcedFinePointer) {
51
+ const mql = window.matchMedia && window.matchMedia('(any-pointer: coarse)')
52
+
53
+ const isCurrentCoarsePointer = () => tlenvReactive.__unsafe__getWithoutCapture().isCoarsePointer
54
+
55
+ if (mql) {
56
+ // 1. Update the coarse pointer automatically when the media query changes
57
+ const updateIsCoarsePointer = () => {
58
+ const isCoarsePointer = mql.matches
59
+ if (isCoarsePointer !== isCurrentCoarsePointer()) {
60
+ tlenvReactive.update((prev) => ({ ...prev, isCoarsePointer: isCoarsePointer }))
61
+ }
62
+ }
63
+ updateIsCoarsePointer()
64
+ mql.addEventListener('change', updateIsCoarsePointer)
65
+ }
66
+
67
+ // 2. Also update the coarse pointer state when a pointer down event occurs. We need `capture: true`
68
+ // here because the tldraw component itself stops propagation on pointer events it receives.
69
+ window.addEventListener(
70
+ 'pointerdown',
71
+ (e: PointerEvent) => {
72
+ // when the user interacts with a mouse, we assume they have a fine pointer.
73
+ // otherwise, we assume they have a coarse pointer.
74
+ const isCoarseEvent = e.pointerType !== 'mouse'
75
+ if (isCoarseEvent !== isCurrentCoarsePointer()) {
76
+ tlenvReactive.update((prev) => ({ ...prev, isCoarsePointer: isCoarseEvent }))
77
+ }
78
+ },
79
+ { capture: true }
80
+ )
26
81
  }
27
82
 
28
- export { tlenv }
83
+ export { tlenv, tlenvReactive }
@@ -148,7 +148,7 @@ export const tlmenus = {
148
148
  * @public
149
149
  */
150
150
  isMenuOpen(id: string, contextId?: string): boolean {
151
- return this.getOpenMenus(contextId).includes(id)
151
+ return this.getOpenMenus(contextId).includes(`${id}-${contextId}`)
152
152
  },
153
153
 
154
154
  /**
@@ -1,66 +1,23 @@
1
- import { useEffect } from 'react'
2
- import { tlenv } from '../globals/environment'
1
+ import { unsafe__withoutCapture } from '@tldraw/state'
2
+ import { useReactor } from '@tldraw/state-react'
3
+ import { tlenvReactive } from '../globals/environment'
3
4
  import { useEditor } from './useEditor'
4
5
 
5
6
  /** @internal */
6
7
  export function useCoarsePointer() {
7
8
  const editor = useEditor()
8
9
 
9
- useEffect(() => {
10
- // We'll track our own state for the pointer type
11
- let isCoarse = editor.getInstanceState().isCoarsePointer
12
-
13
- // 1.
14
- // We'll use pointer events to detect coarse pointer.
15
-
16
- const handlePointerDown = (e: PointerEvent) => {
17
- // when the user interacts with a mouse, we assume they have a fine pointer.
18
- // otherwise, we assume they have a coarse pointer.
19
- const isCoarseEvent = e.pointerType !== 'mouse'
20
- if (isCoarse === isCoarseEvent) return
21
- isCoarse = isCoarseEvent
22
- editor.updateInstanceState({ isCoarsePointer: isCoarseEvent })
23
- }
24
-
25
- // we need `capture: true` here because the tldraw component itself stops propagation on
26
- // pointer events it receives.
27
- window.addEventListener('pointerdown', handlePointerDown, { capture: true })
28
-
29
- // 2.
30
- // We can also use the media query to detect / set the initial pointer type
31
- // and update the state if the pointer type changes.
32
-
33
- // We want the touch / mouse events to run even if the browser does not
34
- // support matchMedia. We'll have to handle the media query changes
35
- // conditionally in the code below.
36
- const mql = window.matchMedia && window.matchMedia('(any-pointer: coarse)')
37
-
38
- // This is a workaround for a Firefox bug where we don't correctly
39
- // detect coarse VS fine pointer. For now, let's assume that you have a fine
40
- // pointer if you're on Firefox on desktop.
41
- const isForcedFinePointer = tlenv.isFirefox && !tlenv.isAndroid && !tlenv.isIos
42
-
43
- const handleMediaQueryChange = () => {
44
- const next = isForcedFinePointer ? false : mql.matches // get the value from the media query
45
- if (isCoarse !== next) return // bail if the value hasn't changed
46
- isCoarse = next // update the local value
47
- editor.updateInstanceState({ isCoarsePointer: next }) // update the value in state
48
- }
49
-
50
- if (mql) {
51
- // set up the listener
52
- mql.addEventListener('change', handleMediaQueryChange)
53
-
54
- // and run the handler once to set the initial value
55
- handleMediaQueryChange()
56
- }
57
-
58
- return () => {
59
- window.removeEventListener('pointerdown', handlePointerDown, { capture: true })
60
-
61
- if (mql) {
62
- mql.removeEventListener('change', handleMediaQueryChange)
63
- }
64
- }
65
- }, [editor])
10
+ // When the coarse pointer state changes, update the instance state
11
+ useReactor(
12
+ 'coarse pointer change',
13
+ () => {
14
+ const isCoarsePointer = tlenvReactive.get().isCoarsePointer
15
+ const isInstanceStateCoarsePointer = unsafe__withoutCapture(
16
+ () => editor.getInstanceState().isCoarsePointer
17
+ )
18
+ if (isCoarsePointer === isInstanceStateCoarsePointer) return
19
+ editor.updateInstanceState({ isCoarsePointer: isCoarsePointer })
20
+ },
21
+ [editor]
22
+ )
66
23
  }
@@ -95,8 +95,8 @@ export function kickoutOccludedShapes(
95
95
  if (remainingShapesToReparent.size > 0) {
96
96
  // The remaining shapes are going to be reparented to the old parent's containing group, if there was one, or else to the page
97
97
  const newParentId =
98
- editor.findShapeAncestor(prevParent, (s) => editor.isShapeOfType<TLGroupShape>(s, 'group'))
99
- ?.id ?? editor.getCurrentPageId()
98
+ editor.findShapeAncestor(prevParent, (s) => editor.isShapeOfType(s, 'group'))?.id ??
99
+ editor.getCurrentPageId()
100
100
 
101
101
  remainingShapesToReparent.forEach((shape) => {
102
102
  if (!parentsToNewChildren[newParentId]) {
@@ -211,7 +211,7 @@ export function getDroppedShapesToNewParents(
211
211
 
212
212
  for (const shape of shapes) {
213
213
  const parent = editor.getShapeParent(shape)
214
- if (parent && editor.isShapeOfType<TLGroupShape>(parent, 'group')) {
214
+ if (parent && editor.isShapeOfType(parent, 'group')) {
215
215
  if (!movingGroups.has(parent)) {
216
216
  movingGroups.add(parent)
217
217
  }
@@ -248,7 +248,7 @@ export function getDroppedShapesToNewParents(
248
248
  parentCheck: for (let i = potentialParentShapes.length - 1; i >= 0; i--) {
249
249
  const parentShape = potentialParentShapes[i]
250
250
  const parentShapeContainingGroupId = editor.findShapeAncestor(parentShape, (s) =>
251
- editor.isShapeOfType<TLGroupShape>(s, 'group')
251
+ editor.isShapeOfType(s, 'group')
252
252
  )?.id
253
253
 
254
254
  const parentGeometry = editor.getShapeGeometry(parentShape)
@@ -274,7 +274,7 @@ export function getDroppedShapesToNewParents(
274
274
  if (!shapeGroupIds.has(shape.id)) {
275
275
  shapeGroupIds.set(
276
276
  shape.id,
277
- editor.findShapeAncestor(shape, (s) => editor.isShapeOfType<TLGroupShape>(s, 'group'))?.id
277
+ editor.findShapeAncestor(shape, (s) => editor.isShapeOfType(s, 'group'))?.id
278
278
  )
279
279
  }
280
280
 
package/src/version.ts CHANGED
@@ -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 = '4.3.0-canary.da35795ba8e2'
4
+ export const version = '4.3.0-canary.e52fa5385f86'
5
5
  export const publishDates = {
6
6
  major: '2025-09-18T14:39:22.803Z',
7
- minor: '2025-11-19T15:43:54.030Z',
8
- patch: '2025-11-19T15:43:54.030Z',
7
+ minor: '2025-12-05T21:53:17.454Z',
8
+ patch: '2025-12-05T21:53:17.454Z',
9
9
  }