@tldraw/editor 3.15.0 → 3.16.0-canary.0e0fb8bde89d

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 (59) hide show
  1. package/dist-cjs/index.d.ts +101 -0
  2. package/dist-cjs/index.js +3 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/TldrawEditor.js +3 -1
  5. package/dist-cjs/lib/TldrawEditor.js.map +2 -2
  6. package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
  7. package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
  8. package/dist-cjs/lib/components/Shape.js +4 -26
  9. package/dist-cjs/lib/components/Shape.js.map +2 -2
  10. package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +53 -0
  11. package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +7 -0
  12. package/dist-cjs/lib/editor/Editor.js +64 -35
  13. package/dist-cjs/lib/editor/Editor.js.map +2 -2
  14. package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
  15. package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
  16. package/dist-cjs/lib/hooks/useCanvasEvents.js +24 -20
  17. package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
  18. package/dist-cjs/lib/hooks/useEditorComponents.js +2 -0
  19. package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
  20. package/dist-cjs/lib/hooks/useStateAttribute.js +35 -0
  21. package/dist-cjs/lib/hooks/useStateAttribute.js.map +7 -0
  22. package/dist-cjs/version.js +3 -3
  23. package/dist-cjs/version.js.map +1 -1
  24. package/dist-esm/index.d.mts +101 -0
  25. package/dist-esm/index.mjs +5 -1
  26. package/dist-esm/index.mjs.map +2 -2
  27. package/dist-esm/lib/TldrawEditor.mjs +3 -1
  28. package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
  29. package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
  30. package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
  31. package/dist-esm/lib/components/Shape.mjs +4 -26
  32. package/dist-esm/lib/components/Shape.mjs.map +2 -2
  33. package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +23 -0
  34. package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +7 -0
  35. package/dist-esm/lib/editor/Editor.mjs +64 -35
  36. package/dist-esm/lib/editor/Editor.mjs.map +2 -2
  37. package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
  38. package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -21
  39. package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
  40. package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -0
  41. package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
  42. package/dist-esm/lib/hooks/useStateAttribute.mjs +15 -0
  43. package/dist-esm/lib/hooks/useStateAttribute.mjs.map +7 -0
  44. package/dist-esm/version.mjs +3 -3
  45. package/dist-esm/version.mjs.map +1 -1
  46. package/editor.css +4 -23
  47. package/package.json +7 -7
  48. package/src/index.ts +5 -0
  49. package/src/lib/TldrawEditor.tsx +7 -5
  50. package/src/lib/components/MenuClickCapture.tsx +0 -8
  51. package/src/lib/components/Shape.tsx +6 -21
  52. package/src/lib/components/default-components/DefaultShapeWrapper.tsx +35 -0
  53. package/src/lib/editor/Editor.ts +71 -35
  54. package/src/lib/editor/shapes/ShapeUtil.ts +57 -0
  55. package/src/lib/editor/types/misc-types.ts +19 -0
  56. package/src/lib/hooks/useCanvasEvents.ts +39 -32
  57. package/src/lib/hooks/useEditorComponents.tsx +7 -1
  58. package/src/lib/hooks/useStateAttribute.ts +15 -0
  59. package/src/version.ts +3 -3
@@ -0,0 +1,35 @@
1
+ import { TLShape } from '@tldraw/tlschema'
2
+ import classNames from 'classnames'
3
+ import { forwardRef, ReactNode } from 'react'
4
+
5
+ /** @public */
6
+ export interface TLShapeWrapperProps extends React.HTMLAttributes<HTMLDivElement> {
7
+ /** The shape being rendered. */
8
+ shape: TLShape
9
+ /** Whether this is the shapes regular, or background component. */
10
+ isBackground: boolean
11
+ /** The shape's rendered component. */
12
+ children: ReactNode
13
+ }
14
+
15
+ /** @public @react */
16
+ export const DefaultShapeWrapper = forwardRef(function DefaultShapeWrapper(
17
+ { children, shape, isBackground, ...props }: TLShapeWrapperProps,
18
+ ref: React.Ref<HTMLDivElement>
19
+ ) {
20
+ const isFilledShape = 'fill' in shape.props && shape.props.fill !== 'none'
21
+
22
+ return (
23
+ <div
24
+ ref={ref}
25
+ data-shape-type={shape.type}
26
+ data-shape-is-filled={isBackground ? undefined : isFilledShape}
27
+ data-shape-id={shape.id}
28
+ draggable={false}
29
+ {...props}
30
+ className={classNames('tl-shape', isBackground && 'tl-shape-background', props.className)}
31
+ >
32
+ {children}
33
+ </div>
34
+ )
35
+ })
@@ -178,6 +178,7 @@ import {
178
178
  TLCameraOptions,
179
179
  TLImageExportOptions,
180
180
  TLSvgExportOptions,
181
+ TLUpdatePointerOptions,
181
182
  } from './types/misc-types'
182
183
  import { TLAdjacentDirection, TLResizeHandle } from './types/selection-types'
183
184
 
@@ -3072,7 +3073,6 @@ export class Editor extends EventEmitter<TLEventMap> {
3072
3073
  // Dispatch a new pointer move because the pointer's page will have changed
3073
3074
  // (its screen position will compute to a new page position given the new camera position)
3074
3075
  const { currentScreenPoint, currentPagePoint } = this.inputs
3075
- const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
3076
3076
 
3077
3077
  // compare the next page point (derived from the current camera) to the current page point
3078
3078
  if (
@@ -3080,27 +3080,10 @@ export class Editor extends EventEmitter<TLEventMap> {
3080
3080
  currentScreenPoint.y / z - y !== currentPagePoint.y
3081
3081
  ) {
3082
3082
  // If it's changed, dispatch a pointer event
3083
- const event: TLPointerEventInfo = {
3084
- type: 'pointer',
3085
- target: 'canvas',
3086
- name: 'pointer_move',
3087
- // weird but true: we need to put the screen point back into client space
3088
- point: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),
3083
+ this.updatePointer({
3084
+ immediate: opts?.immediate,
3089
3085
  pointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,
3090
- ctrlKey: this.inputs.ctrlKey,
3091
- altKey: this.inputs.altKey,
3092
- shiftKey: this.inputs.shiftKey,
3093
- metaKey: this.inputs.metaKey,
3094
- accelKey: isAccelKey(this.inputs),
3095
- button: 0,
3096
- isPen: this.getInstanceState().isPenMode ?? false,
3097
- }
3098
-
3099
- if (opts?.immediate) {
3100
- this._flushEventForTick(event)
3101
- } else {
3102
- this.dispatch(event)
3103
- }
3086
+ })
3104
3087
  }
3105
3088
 
3106
3089
  this._tickCameraState()
@@ -4421,21 +4404,28 @@ export class Editor extends EventEmitter<TLEventMap> {
4421
4404
  */
4422
4405
  deletePage(page: TLPageId | TLPage): this {
4423
4406
  const id = typeof page === 'string' ? page : page.id
4424
- this.run(() => {
4425
- if (this.getIsReadonly()) return
4426
- const pages = this.getPages()
4427
- if (pages.length === 1) return
4407
+ this.run(
4408
+ () => {
4409
+ if (this.getIsReadonly()) return
4410
+ const pages = this.getPages()
4411
+ if (pages.length === 1) return
4428
4412
 
4429
- const deletedPage = this.getPage(id)
4430
- if (!deletedPage) return
4413
+ const deletedPage = this.getPage(id)
4414
+ if (!deletedPage) return
4431
4415
 
4432
- if (id === this.getCurrentPageId()) {
4433
- const index = pages.findIndex((page) => page.id === id)
4434
- const next = pages[index - 1] ?? pages[index + 1]
4435
- this.setCurrentPage(next.id)
4436
- }
4437
- this.store.remove([deletedPage.id])
4438
- })
4416
+ if (id === this.getCurrentPageId()) {
4417
+ const index = pages.findIndex((page) => page.id === id)
4418
+ const next = pages[index - 1] ?? pages[index + 1]
4419
+ this.setCurrentPage(next.id)
4420
+ }
4421
+
4422
+ const shapes = this.getSortedChildIdsForParent(deletedPage.id)
4423
+ this.deleteShapes(shapes)
4424
+
4425
+ this.store.remove([deletedPage.id])
4426
+ },
4427
+ { ignoreShapeLock: true }
4428
+ )
4439
4429
  return this
4440
4430
  }
4441
4431
 
@@ -5222,8 +5212,8 @@ export class Editor extends EventEmitter<TLEventMap> {
5222
5212
  // Check labels first
5223
5213
  if (
5224
5214
  this.isShapeOfType<TLFrameShape>(shape, 'frame') ||
5225
- (this.isShapeOfType<TLArrowShape>(shape, 'arrow') && shape.props.text.trim()) ||
5226
5215
  ((this.isShapeOfType<TLNoteShape>(shape, 'note') ||
5216
+ this.isShapeOfType<TLArrowShape>(shape, 'arrow') ||
5227
5217
  (this.isShapeOfType<TLGeoShape>(shape, 'geo') && shape.props.fill === 'none')) &&
5228
5218
  this.getShapeUtil(shape).getText(shape)?.trim())
5229
5219
  ) {
@@ -9673,6 +9663,52 @@ export class Editor extends EventEmitter<TLEventMap> {
9673
9663
  return this
9674
9664
  }
9675
9665
 
9666
+ /**
9667
+ * Dispatch a pointer move event in the current position of the pointer. This is useful when
9668
+ * external circumstances have changed (e.g. the camera moved or a shape was moved) and you want
9669
+ * the current interaction to respond to that change.
9670
+ *
9671
+ * @example
9672
+ * ```ts
9673
+ * editor.updatePointer()
9674
+ * ```
9675
+ *
9676
+ * @param options - The options for updating the pointer.
9677
+ * @returns The editor instance.
9678
+ * @public
9679
+ */
9680
+ updatePointer(options?: TLUpdatePointerOptions): this {
9681
+ const event: TLPointerEventInfo = {
9682
+ type: 'pointer',
9683
+ target: 'canvas',
9684
+ name: 'pointer_move',
9685
+ point:
9686
+ options?.point ??
9687
+ // weird but true: what `inputs` calls screen-space is actually viewport space. so
9688
+ // we need to convert back into true screen space first. we should fix this...
9689
+ Vec.Add(
9690
+ this.inputs.currentScreenPoint,
9691
+ this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!.screenBounds
9692
+ ),
9693
+ pointerId: options?.pointerId ?? 0,
9694
+ button: options?.button ?? 0,
9695
+ isPen: options?.isPen ?? this.inputs.isPen,
9696
+ shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
9697
+ altKey: options?.altKey ?? this.inputs.altKey,
9698
+ ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
9699
+ metaKey: options?.metaKey ?? this.inputs.metaKey,
9700
+ accelKey: options?.accelKey ?? isAccelKey(this.inputs),
9701
+ }
9702
+
9703
+ if (options?.immediate) {
9704
+ this._flushEventForTick(event)
9705
+ } else {
9706
+ this.dispatch(event)
9707
+ }
9708
+
9709
+ return this
9710
+ }
9711
+
9676
9712
  /**
9677
9713
  * Puts the editor into focused mode.
9678
9714
  *
@@ -584,6 +584,15 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
584
584
  */
585
585
  onResizeEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void
586
586
 
587
+ /**
588
+ * A callback called when a shape resize is cancelled.
589
+ *
590
+ * @param initial - The shape at the start of the resize.
591
+ * @param current - The current shape.
592
+ * @public
593
+ */
594
+ onResizeCancel?(initial: Shape, current: Shape): void
595
+
587
596
  /**
588
597
  * A callback called when a shape starts being translated.
589
598
  *
@@ -613,6 +622,25 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
613
622
  */
614
623
  onTranslateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void
615
624
 
625
+ /**
626
+ * A callback called when a shape translation is cancelled.
627
+ *
628
+ * @param initial - The shape at the start of the translation.
629
+ * @param current - The current shape.
630
+ * @public
631
+ */
632
+ onTranslateCancel?(initial: Shape, current: Shape): void
633
+
634
+ /**
635
+ * A callback called when a shape's handle starts being dragged.
636
+ *
637
+ * @param shape - The shape.
638
+ * @param info - An object containing the handle and whether the handle is 'precise' or not.
639
+ * @returns A change to apply to the shape, or void.
640
+ * @public
641
+ */
642
+ onHandleDragStart?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void
643
+
616
644
  /**
617
645
  * A callback called when a shape's handle changes.
618
646
  *
@@ -623,6 +651,25 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
623
651
  */
624
652
  onHandleDrag?(shape: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void
625
653
 
654
+ /**
655
+ * A callback called when a shape's handle finishes being dragged.
656
+ *
657
+ * @param current - The current shape.
658
+ * @param info - An object containing the handle and whether the handle is 'precise' or not.
659
+ * @returns A change to apply to the shape, or void.
660
+ * @public
661
+ */
662
+ onHandleDragEnd?(current: Shape, info: TLHandleDragInfo<Shape>): TLShapePartial<Shape> | void
663
+
664
+ /**
665
+ * A callback called when a shape's handle drag is cancelled.
666
+ *
667
+ * @param current - The current shape.
668
+ * @param info - An object containing the handle and whether the handle is 'precise' or not.
669
+ * @public
670
+ */
671
+ onHandleDragCancel?(current: Shape, info: TLHandleDragInfo<Shape>): void
672
+
626
673
  /**
627
674
  * A callback called when a shape starts being rotated.
628
675
  *
@@ -652,6 +699,15 @@ export abstract class ShapeUtil<Shape extends TLUnknownShape = TLUnknownShape> {
652
699
  */
653
700
  onRotateEnd?(initial: Shape, current: Shape): TLShapePartial<Shape> | void
654
701
 
702
+ /**
703
+ * A callback called when a shape rotation is cancelled.
704
+ *
705
+ * @param initial - The shape at the start of the rotation.
706
+ * @param current - The current shape.
707
+ * @public
708
+ */
709
+ onRotateCancel?(initial: Shape, current: Shape): void
710
+
655
711
  /**
656
712
  * Not currently used.
657
713
  *
@@ -819,5 +875,6 @@ export interface TLResizeInfo<T extends TLShape> {
819
875
  export interface TLHandleDragInfo<T extends TLShape> {
820
876
  handle: TLHandle
821
877
  isPrecise: boolean
878
+ isCreatingShape: boolean
822
879
  initial?: T | undefined
823
880
  }
@@ -187,3 +187,22 @@ export interface TLCameraConstraints {
187
187
  y: 'free' | 'fixed' | 'inside' | 'outside' | 'contain'
188
188
  }
189
189
  }
190
+
191
+ /** @public */
192
+ export interface TLUpdatePointerOptions {
193
+ /** Whether to update the pointer immediately, rather than on the next tick. */
194
+ immediate?: boolean
195
+ /**
196
+ * The point, in screen-space, to update the pointer to. Defaults to the position of the last
197
+ * pointer event.
198
+ */
199
+ point?: VecLike
200
+ pointerId?: number
201
+ ctrlKey?: boolean
202
+ altKey?: boolean
203
+ shiftKey?: boolean
204
+ metaKey?: boolean
205
+ accelKey?: boolean
206
+ isPen?: boolean
207
+ button?: number
208
+ }
@@ -1,5 +1,5 @@
1
1
  import { useValue } from '@tldraw/state-react'
2
- import React, { useMemo } from 'react'
2
+ import React, { useEffect, useMemo } from 'react'
3
3
  import { RIGHT_MOUSE_BUTTON } from '../constants'
4
4
  import {
5
5
  preventDefault,
@@ -16,9 +16,6 @@ export function useCanvasEvents() {
16
16
 
17
17
  const events = useMemo(
18
18
  function canvasEvents() {
19
- // Track the last screen point
20
- let lastX: number, lastY: number
21
-
22
19
  function onPointerDown(e: React.PointerEvent) {
23
20
  if ((e as any).isKilled) return
24
21
 
@@ -44,35 +41,9 @@ export function useCanvasEvents() {
44
41
  })
45
42
  }
46
43
 
47
- function onPointerMove(e: React.PointerEvent) {
48
- if ((e as any).isKilled) return
49
-
50
- if (e.clientX === lastX && e.clientY === lastY) return
51
- lastX = e.clientX
52
- lastY = e.clientY
53
-
54
- // For tools that benefit from a higher fidelity of events,
55
- // we dispatch the coalesced events.
56
- // N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.
57
- const events =
58
- currentTool.useCoalescedEvents && e.nativeEvent.getCoalescedEvents
59
- ? e.nativeEvent.getCoalescedEvents()
60
- : [e]
61
- for (const singleEvent of events) {
62
- editor.dispatch({
63
- type: 'pointer',
64
- target: 'canvas',
65
- name: 'pointer_move',
66
- ...getPointerInfo(singleEvent),
67
- })
68
- }
69
- }
70
-
71
44
  function onPointerUp(e: React.PointerEvent) {
72
45
  if ((e as any).isKilled) return
73
46
  if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return
74
- lastX = e.clientX
75
- lastY = e.clientY
76
47
 
77
48
  releasePointerCapture(e.currentTarget, e)
78
49
 
@@ -158,7 +129,6 @@ export function useCanvasEvents() {
158
129
 
159
130
  return {
160
131
  onPointerDown,
161
- onPointerMove,
162
132
  onPointerUp,
163
133
  onPointerEnter,
164
134
  onPointerLeave,
@@ -169,8 +139,45 @@ export function useCanvasEvents() {
169
139
  onClick,
170
140
  }
171
141
  },
172
- [editor, currentTool]
142
+ [editor]
173
143
  )
174
144
 
145
+ // onPointerMove is special: where we're only interested in the other events when they're
146
+ // happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want
147
+ // the pointer position to be up to date regardless of whether it's over the tldraw canvas or
148
+ // not. So instead of returning a listener to be attached to the canvas, we directly attach a
149
+ // listener to the whole document instead.
150
+ useEffect(() => {
151
+ let lastX: number, lastY: number
152
+
153
+ function onPointerMove(e: PointerEvent) {
154
+ if ((e as any).isKilled) return
155
+ ;(e as any).isKilled = true
156
+
157
+ if (e.clientX === lastX && e.clientY === lastY) return
158
+ lastX = e.clientX
159
+ lastY = e.clientY
160
+
161
+ // For tools that benefit from a higher fidelity of events,
162
+ // we dispatch the coalesced events.
163
+ // N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.
164
+ const events =
165
+ currentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]
166
+ for (const singleEvent of events) {
167
+ editor.dispatch({
168
+ type: 'pointer',
169
+ target: 'canvas',
170
+ name: 'pointer_move',
171
+ ...getPointerInfo(singleEvent),
172
+ })
173
+ }
174
+ }
175
+
176
+ document.body.addEventListener('pointermove', onPointerMove)
177
+ return () => {
178
+ document.body.removeEventListener('pointermove', onPointerMove)
179
+ }
180
+ }, [editor, currentTool])
181
+
175
182
  return events
176
183
  }
@@ -1,4 +1,4 @@
1
- import { ComponentType, ReactNode, createContext, useContext, useMemo } from 'react'
1
+ import { ComponentType, ReactNode, RefAttributes, createContext, useContext, useMemo } from 'react'
2
2
  import { DefaultBackground } from '../components/default-components/DefaultBackground'
3
3
  import { DefaultBrush, TLBrushProps } from '../components/default-components/DefaultBrush'
4
4
  import {
@@ -37,6 +37,10 @@ import {
37
37
  TLShapeIndicatorErrorFallbackComponent,
38
38
  } from '../components/default-components/DefaultShapeIndicatorErrorFallback'
39
39
  import { DefaultShapeIndicators } from '../components/default-components/DefaultShapeIndicators'
40
+ import {
41
+ DefaultShapeWrapper,
42
+ TLShapeWrapperProps,
43
+ } from '../components/default-components/DefaultShapeWrapper'
40
44
  import {
41
45
  DefaultSnapIndicator,
42
46
  TLSnapIndicatorProps,
@@ -68,6 +72,7 @@ export interface TLEditorComponents {
68
72
  SelectionForeground?: ComponentType<TLSelectionForegroundProps> | null
69
73
  ShapeIndicator?: ComponentType<TLShapeIndicatorProps> | null
70
74
  ShapeIndicators?: ComponentType | null
75
+ ShapeWrapper?: ComponentType<TLShapeWrapperProps & RefAttributes<HTMLDivElement>> | null
71
76
  SnapIndicator?: ComponentType<TLSnapIndicatorProps> | null
72
77
  Spinner?: ComponentType<React.SVGProps<SVGSVGElement>> | null
73
78
  SvgDefs?: ComponentType | null
@@ -114,6 +119,7 @@ export function EditorComponentsProvider({
114
119
  SelectionForeground: DefaultSelectionForeground,
115
120
  ShapeIndicator: DefaultShapeIndicator,
116
121
  ShapeIndicators: DefaultShapeIndicators,
122
+ ShapeWrapper: DefaultShapeWrapper,
117
123
  SnapIndicator: DefaultSnapIndicator,
118
124
  Spinner: DefaultSpinner,
119
125
  SvgDefs: DefaultSvgDefs,
@@ -0,0 +1,15 @@
1
+ import { react } from '@tldraw/state'
2
+ import { useLayoutEffect } from 'react'
3
+ import { useEditor } from './useEditor'
4
+
5
+ export function useStateAttribute() {
6
+ const editor = useEditor()
7
+
8
+ // we use a layout effect because we don't want there to be any perceptible delay between the
9
+ // editor mounting and this attribute being applied, because styles may depend on it:
10
+ useLayoutEffect(() => {
11
+ return react('stateAttribute', () => {
12
+ editor.getContainer().setAttribute('data-state', editor.getPath())
13
+ })
14
+ }, [editor])
15
+ }
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 = '3.15.0'
4
+ export const version = '3.16.0-canary.0e0fb8bde89d'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-07-30T09:07:27.887Z',
8
- patch: '2025-07-30T09:07:27.887Z',
7
+ minor: '2025-07-31T14:45:19.563Z',
8
+ patch: '2025-07-31T14:45:19.563Z',
9
9
  }