@tldraw/editor 3.16.0-internal.51e99e128bd4 → 3.16.0-internal.a478398270c6
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.
- package/dist-cjs/index.d.ts +16 -217
- package/dist-cjs/index.js +1 -8
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +1 -3
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +5 -0
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/SVGContainer.js +1 -1
- package/dist-cjs/lib/components/SVGContainer.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +26 -4
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultBrush.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCursor.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultGrid.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultGrid.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultHandles.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -9
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js +15 -27
- package/dist-cjs/lib/components/default-components/DefaultSpinner.js.map +3 -3
- package/dist-cjs/lib/config/TLUserPreferences.js +3 -15
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +67 -134
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +4 -14
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/tools/StateNode.js +1 -20
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +2 -1
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +20 -24
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditor.js +4 -1
- package/dist-cjs/lib/hooks/useEditor.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +0 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +8 -8
- package/dist-cjs/lib/license/Watermark.js.map +2 -2
- package/dist-cjs/lib/options.js +0 -7
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Arc2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Arc2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js +1 -3
- package/dist-cjs/lib/primitives/geometry/CubicBezier2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -1
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +2 -2
- package/dist-cjs/lib/primitives/geometry/geometry-constants.js +2 -2
- package/dist-cjs/lib/primitives/geometry/geometry-constants.js.map +2 -2
- package/dist-cjs/lib/primitives/intersect.js +4 -4
- package/dist-cjs/lib/primitives/intersect.js.map +2 -2
- package/dist-cjs/lib/primitives/utils.js +0 -4
- package/dist-cjs/lib/primitives/utils.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +1 -0
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +16 -217
- package/dist-esm/index.mjs +2 -16
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +1 -3
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +5 -0
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/SVGContainer.mjs +1 -1
- package/dist-esm/lib/components/SVGContainer.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +26 -4
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultGrid.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultGrid.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -9
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs +15 -17
- package/dist-esm/lib/components/default-components/DefaultSpinner.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +3 -15
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +67 -134
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +4 -14
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs +1 -20
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +21 -25
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditor.mjs +4 -1
- package/dist-esm/lib/hooks/useEditor.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +0 -4
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +8 -8
- package/dist-esm/lib/license/Watermark.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +0 -7
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Arc2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs +1 -3
- package/dist-esm/lib/primitives/geometry/CubicBezier2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +2 -2
- package/dist-esm/lib/primitives/geometry/geometry-constants.mjs +2 -2
- package/dist-esm/lib/primitives/geometry/geometry-constants.mjs.map +2 -2
- package/dist-esm/lib/primitives/intersect.mjs +5 -5
- package/dist-esm/lib/primitives/intersect.mjs.map +2 -2
- package/dist-esm/lib/primitives/utils.mjs +0 -4
- package/dist-esm/lib/primitives/utils.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +1 -0
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +313 -312
- package/package.json +38 -16
- package/src/index.ts +1 -15
- package/src/lib/TldrawEditor.tsx +5 -7
- package/src/lib/components/MenuClickCapture.tsx +8 -0
- package/src/lib/components/SVGContainer.tsx +1 -1
- package/src/lib/components/Shape.tsx +21 -6
- package/src/lib/components/default-components/DefaultBrush.tsx +1 -1
- package/src/lib/components/default-components/DefaultCanvas.tsx +1 -1
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +2 -2
- package/src/lib/components/default-components/DefaultCursor.tsx +1 -1
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
- package/src/lib/components/default-components/DefaultGrid.tsx +1 -1
- package/src/lib/components/default-components/DefaultHandles.tsx +1 -5
- package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +2 -6
- package/src/lib/components/default-components/DefaultSnapIndictor.tsx +1 -1
- package/src/lib/components/default-components/DefaultSpinner.tsx +12 -12
- package/src/lib/config/TLUserPreferences.ts +1 -15
- package/src/lib/editor/Editor.test.ts +8 -416
- package/src/lib/editor/Editor.ts +92 -177
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +14 -15
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +15 -16
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +48 -49
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +23 -24
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +6 -7
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +11 -12
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +50 -57
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +26 -51
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +13 -14
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +26 -55
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +1 -14
- package/src/lib/editor/shapes/ShapeUtil.ts +0 -57
- package/src/lib/editor/tools/StateNode.ts +1 -27
- package/src/lib/editor/types/misc-types.ts +1 -73
- package/src/lib/exports/getSvgJsx.tsx +2 -2
- package/src/lib/hooks/useCanvasEvents.ts +32 -39
- package/src/lib/hooks/useEditor.tsx +5 -6
- package/src/lib/hooks/useEditorComponents.tsx +2 -8
- package/src/lib/license/LicenseManager.test.ts +1 -3
- package/src/lib/license/Watermark.test.tsx +1 -2
- package/src/lib/license/Watermark.tsx +8 -8
- package/src/lib/options.ts +0 -8
- package/src/lib/primitives/geometry/Arc2d.ts +2 -2
- package/src/lib/primitives/geometry/Circle2d.ts +2 -2
- package/src/lib/primitives/geometry/CubicBezier2d.ts +1 -4
- package/src/lib/primitives/geometry/Ellipse2d.ts +2 -2
- package/src/lib/primitives/geometry/geometry-constants.ts +1 -2
- package/src/lib/primitives/intersect.ts +5 -12
- package/src/lib/primitives/utils.ts +0 -11
- package/src/lib/test/currentToolIdMask.test.ts +49 -0
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +1 -2
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
- package/src/lib/utils/sync/TLLocalSyncClient.ts +1 -0
- package/src/version.ts +3 -3
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +0 -53
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +0 -7
- package/dist-cjs/lib/hooks/useStateAttribute.js +0 -35
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +0 -7
- package/dist-cjs/lib/utils/EditorAtom.js +0 -45
- package/dist-cjs/lib/utils/EditorAtom.js.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +0 -23
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +0 -7
- package/dist-esm/lib/hooks/useStateAttribute.mjs +0 -15
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +0 -7
- package/dist-esm/lib/utils/EditorAtom.mjs +0 -25
- package/dist-esm/lib/utils/EditorAtom.mjs.map +0 -7
- package/src/lib/components/default-components/DefaultShapeWrapper.tsx +0 -35
- package/src/lib/editor/tools/StateNode.test.ts +0 -285
- package/src/lib/hooks/useStateAttribute.ts +0 -15
- package/src/lib/primitives/intersect.test.ts +0 -946
- package/src/lib/utils/EditorAtom.ts +0 -37
package/src/lib/editor/Editor.ts
CHANGED
|
@@ -176,10 +176,8 @@ import {
|
|
|
176
176
|
RequiredKeys,
|
|
177
177
|
TLCameraMoveOptions,
|
|
178
178
|
TLCameraOptions,
|
|
179
|
-
TLGetShapeAtPointOptions,
|
|
180
179
|
TLImageExportOptions,
|
|
181
180
|
TLSvgExportOptions,
|
|
182
|
-
TLUpdatePointerOptions,
|
|
183
181
|
} from './types/misc-types'
|
|
184
182
|
import { TLAdjacentDirection, TLResizeHandle } from './types/selection-types'
|
|
185
183
|
|
|
@@ -1805,9 +1803,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1805
1803
|
}
|
|
1806
1804
|
|
|
1807
1805
|
/**
|
|
1808
|
-
* Select all
|
|
1809
|
-
* select all shapes within that parent. If the user has not selected any shapes,
|
|
1810
|
-
* or if the shapes shapes are only on select all shapes on the current page.
|
|
1806
|
+
* Select all direct children of the current page.
|
|
1811
1807
|
*
|
|
1812
1808
|
* @example
|
|
1813
1809
|
* ```ts
|
|
@@ -1817,34 +1813,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1817
1813
|
* @public
|
|
1818
1814
|
*/
|
|
1819
1815
|
selectAll(): this {
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
const selectedShapeIds = this.getSelectedShapeIds()
|
|
1823
|
-
|
|
1824
|
-
// If we have selected shapes, try to find a parent to select within
|
|
1825
|
-
if (selectedShapeIds.length > 0) {
|
|
1826
|
-
for (const id of selectedShapeIds) {
|
|
1827
|
-
const shape = this.getShape(id)
|
|
1828
|
-
if (!shape) continue
|
|
1829
|
-
if (parentToSelectWithinId === null) {
|
|
1830
|
-
// If we haven't found a parent yet, set this parent as the parent to select within
|
|
1831
|
-
parentToSelectWithinId = shape.parentId
|
|
1832
|
-
} else if (parentToSelectWithinId !== shape.parentId) {
|
|
1833
|
-
// If we've found two different parents, we can't select all, do nothing
|
|
1834
|
-
return this
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
|
-
}
|
|
1838
|
-
|
|
1839
|
-
// If we haven't found a parent from our selected shapes, select the current page
|
|
1840
|
-
if (!parentToSelectWithinId) {
|
|
1841
|
-
parentToSelectWithinId = this.getCurrentPageId()
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
// Select all the unlocked shapes within the parent
|
|
1845
|
-
const ids = this.getSortedChildIdsForParent(parentToSelectWithinId)
|
|
1816
|
+
const ids = this.getSortedChildIdsForParent(this.getCurrentPageId())
|
|
1817
|
+
// page might have no shapes
|
|
1846
1818
|
if (ids.length <= 0) return this
|
|
1847
1819
|
this.setSelectedShapes(this._getUnlockedShapeIds(ids))
|
|
1820
|
+
|
|
1848
1821
|
return this
|
|
1849
1822
|
}
|
|
1850
1823
|
|
|
@@ -1865,11 +1838,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1865
1838
|
firstParentId &&
|
|
1866
1839
|
selectedShapeIds.every((shapeId) => this.getShape(shapeId)?.parentId === firstParentId) &&
|
|
1867
1840
|
!isPageId(firstParentId)
|
|
1868
|
-
const filteredShapes = isSelectedWithinContainer
|
|
1869
|
-
? this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)
|
|
1870
|
-
: this.getCurrentPageShapes().filter((shape) => isPageId(shape.parentId))
|
|
1871
1841
|
const readingOrderShapes = isSelectedWithinContainer
|
|
1872
|
-
? this._getShapesInReadingOrder(
|
|
1842
|
+
? this._getShapesInReadingOrder(
|
|
1843
|
+
this.getCurrentPageShapes().filter((shape) => shape.parentId === firstParentId)
|
|
1844
|
+
)
|
|
1873
1845
|
: this.getCurrentPageShapesInReadingOrder()
|
|
1874
1846
|
const currentShapeId: TLShapeId | undefined =
|
|
1875
1847
|
selectedShapeIds.length === 1
|
|
@@ -1886,7 +1858,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1886
1858
|
adjacentShapeId = shapeIds[adjacentIndex]
|
|
1887
1859
|
} else {
|
|
1888
1860
|
if (!currentShapeId) return
|
|
1889
|
-
adjacentShapeId = this.getNearestAdjacentShape(
|
|
1861
|
+
adjacentShapeId = this.getNearestAdjacentShape(currentShapeId, direction)
|
|
1890
1862
|
}
|
|
1891
1863
|
|
|
1892
1864
|
const shape = this.getShape(adjacentShapeId)
|
|
@@ -1985,7 +1957,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1985
1957
|
* @public
|
|
1986
1958
|
*/
|
|
1987
1959
|
getNearestAdjacentShape(
|
|
1988
|
-
shapes: TLShape[],
|
|
1989
1960
|
currentShapeId: TLShapeId,
|
|
1990
1961
|
direction: 'left' | 'right' | 'up' | 'down'
|
|
1991
1962
|
): TLShapeId {
|
|
@@ -1993,6 +1964,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1993
1964
|
const currentShape = this.getShape(currentShapeId)
|
|
1994
1965
|
if (!currentShape) return currentShapeId
|
|
1995
1966
|
|
|
1967
|
+
const shapes = this.getCurrentPageShapes()
|
|
1996
1968
|
const tabbableShapes = shapes.filter(
|
|
1997
1969
|
(shape) => this.getShapeUtil(shape).canTabTo(shape) && shape.id !== currentShapeId
|
|
1998
1970
|
)
|
|
@@ -3074,6 +3046,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3074
3046
|
// Dispatch a new pointer move because the pointer's page will have changed
|
|
3075
3047
|
// (its screen position will compute to a new page position given the new camera position)
|
|
3076
3048
|
const { currentScreenPoint, currentPagePoint } = this.inputs
|
|
3049
|
+
const { screenBounds } = this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!
|
|
3077
3050
|
|
|
3078
3051
|
// compare the next page point (derived from the current camera) to the current page point
|
|
3079
3052
|
if (
|
|
@@ -3081,10 +3054,27 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3081
3054
|
currentScreenPoint.y / z - y !== currentPagePoint.y
|
|
3082
3055
|
) {
|
|
3083
3056
|
// If it's changed, dispatch a pointer event
|
|
3084
|
-
|
|
3085
|
-
|
|
3057
|
+
const event: TLPointerEventInfo = {
|
|
3058
|
+
type: 'pointer',
|
|
3059
|
+
target: 'canvas',
|
|
3060
|
+
name: 'pointer_move',
|
|
3061
|
+
// weird but true: we need to put the screen point back into client space
|
|
3062
|
+
point: Vec.AddXY(currentScreenPoint, screenBounds.x, screenBounds.y),
|
|
3086
3063
|
pointerId: INTERNAL_POINTER_IDS.CAMERA_MOVE,
|
|
3087
|
-
|
|
3064
|
+
ctrlKey: this.inputs.ctrlKey,
|
|
3065
|
+
altKey: this.inputs.altKey,
|
|
3066
|
+
shiftKey: this.inputs.shiftKey,
|
|
3067
|
+
metaKey: this.inputs.metaKey,
|
|
3068
|
+
accelKey: isAccelKey(this.inputs),
|
|
3069
|
+
button: 0,
|
|
3070
|
+
isPen: this.getInstanceState().isPenMode ?? false,
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
if (opts?.immediate) {
|
|
3074
|
+
this._flushEventForTick(event)
|
|
3075
|
+
} else {
|
|
3076
|
+
this.dispatch(event)
|
|
3077
|
+
}
|
|
3088
3078
|
}
|
|
3089
3079
|
|
|
3090
3080
|
this._tickCameraState()
|
|
@@ -4405,28 +4395,21 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
4405
4395
|
*/
|
|
4406
4396
|
deletePage(page: TLPageId | TLPage): this {
|
|
4407
4397
|
const id = typeof page === 'string' ? page : page.id
|
|
4408
|
-
this.run(
|
|
4409
|
-
()
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
if (pages.length === 1) return
|
|
4413
|
-
|
|
4414
|
-
const deletedPage = this.getPage(id)
|
|
4415
|
-
if (!deletedPage) return
|
|
4416
|
-
|
|
4417
|
-
if (id === this.getCurrentPageId()) {
|
|
4418
|
-
const index = pages.findIndex((page) => page.id === id)
|
|
4419
|
-
const next = pages[index - 1] ?? pages[index + 1]
|
|
4420
|
-
this.setCurrentPage(next.id)
|
|
4421
|
-
}
|
|
4398
|
+
this.run(() => {
|
|
4399
|
+
if (this.getIsReadonly()) return
|
|
4400
|
+
const pages = this.getPages()
|
|
4401
|
+
if (pages.length === 1) return
|
|
4422
4402
|
|
|
4423
|
-
|
|
4424
|
-
|
|
4403
|
+
const deletedPage = this.getPage(id)
|
|
4404
|
+
if (!deletedPage) return
|
|
4425
4405
|
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4406
|
+
if (id === this.getCurrentPageId()) {
|
|
4407
|
+
const index = pages.findIndex((page) => page.id === id)
|
|
4408
|
+
const next = pages[index - 1] ?? pages[index + 1]
|
|
4409
|
+
this.setCurrentPage(next.id)
|
|
4410
|
+
}
|
|
4411
|
+
this.store.remove([deletedPage.id])
|
|
4412
|
+
})
|
|
4430
4413
|
return this
|
|
4431
4414
|
}
|
|
4432
4415
|
|
|
@@ -5155,7 +5138,20 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5155
5138
|
*
|
|
5156
5139
|
* @returns The shape at the given point, or undefined if there is no shape at the point.
|
|
5157
5140
|
*/
|
|
5158
|
-
getShapeAtPoint(
|
|
5141
|
+
getShapeAtPoint(
|
|
5142
|
+
point: VecLike,
|
|
5143
|
+
opts = {} as {
|
|
5144
|
+
renderingOnly?: boolean
|
|
5145
|
+
margin?: number
|
|
5146
|
+
hitInside?: boolean
|
|
5147
|
+
hitLocked?: boolean
|
|
5148
|
+
// TODO: we probably need to rename this, we don't quite _always_
|
|
5149
|
+
// respect this esp. in the part below that does "Check labels first"
|
|
5150
|
+
hitLabels?: boolean
|
|
5151
|
+
hitFrameInside?: boolean
|
|
5152
|
+
filter?(shape: TLShape): boolean
|
|
5153
|
+
}
|
|
5154
|
+
): TLShape | undefined {
|
|
5159
5155
|
const zoomLevel = this.getZoomLevel()
|
|
5160
5156
|
const viewportPageBounds = this.getViewportPageBounds()
|
|
5161
5157
|
const {
|
|
@@ -5167,8 +5163,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5167
5163
|
hitFrameInside = false,
|
|
5168
5164
|
} = opts
|
|
5169
5165
|
|
|
5170
|
-
const [innerMargin, outerMargin] = Array.isArray(margin) ? margin : [margin, margin]
|
|
5171
|
-
|
|
5172
5166
|
let inHollowSmallestArea = Infinity
|
|
5173
5167
|
let inHollowSmallestAreaHit: TLShape | null = null
|
|
5174
5168
|
|
|
@@ -5188,7 +5182,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5188
5182
|
return false
|
|
5189
5183
|
const pageMask = this.getShapeMask(shape)
|
|
5190
5184
|
if (pageMask && !pointInPolygon(point, pageMask)) return false
|
|
5191
|
-
if (filter
|
|
5185
|
+
if (filter) return filter(shape)
|
|
5192
5186
|
return true
|
|
5193
5187
|
})
|
|
5194
5188
|
|
|
@@ -5202,8 +5196,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5202
5196
|
// Check labels first
|
|
5203
5197
|
if (
|
|
5204
5198
|
this.isShapeOfType<TLFrameShape>(shape, 'frame') ||
|
|
5199
|
+
(this.isShapeOfType<TLArrowShape>(shape, 'arrow') && shape.props.text.trim()) ||
|
|
5205
5200
|
((this.isShapeOfType<TLNoteShape>(shape, 'note') ||
|
|
5206
|
-
this.isShapeOfType<TLArrowShape>(shape, 'arrow') ||
|
|
5207
5201
|
(this.isShapeOfType<TLGeoShape>(shape, 'geo') && shape.props.fill === 'none')) &&
|
|
5208
5202
|
this.getShapeUtil(shape).getText(shape)?.trim())
|
|
5209
5203
|
) {
|
|
@@ -5214,18 +5208,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5214
5208
|
}
|
|
5215
5209
|
}
|
|
5216
5210
|
|
|
5217
|
-
if (this.isShapeOfType
|
|
5211
|
+
if (this.isShapeOfType(shape, 'frame')) {
|
|
5218
5212
|
// On the rare case that we've hit a frame (not its label), test again hitInside to be forced true;
|
|
5219
5213
|
// this prevents clicks from passing through the body of a frame to shapes behind it.
|
|
5220
5214
|
|
|
5221
5215
|
// If the hit is within the frame's outer margin, then select the frame
|
|
5222
|
-
const distance = geometry.distanceToPoint(pointInShapeSpace,
|
|
5223
|
-
if (
|
|
5224
|
-
hitFrameInside
|
|
5225
|
-
? (distance > 0 && distance <= outerMargin) ||
|
|
5226
|
-
(distance <= 0 && distance > -innerMargin)
|
|
5227
|
-
: distance > 0 && distance <= outerMargin
|
|
5228
|
-
) {
|
|
5216
|
+
const distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
|
5217
|
+
if (Math.abs(distance) <= margin) {
|
|
5229
5218
|
return inMarginClosestToEdgeHit || shape
|
|
5230
5219
|
}
|
|
5231
5220
|
|
|
@@ -5264,11 +5253,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5264
5253
|
// If the margin is zero and the geometry has a very small width or height,
|
|
5265
5254
|
// then check the actual distance. This is to prevent a bug where straight
|
|
5266
5255
|
// lines would never pass the broad phase (point-in-bounds) check.
|
|
5267
|
-
if (
|
|
5256
|
+
if (margin === 0 && (geometry.bounds.w < 1 || geometry.bounds.h < 1)) {
|
|
5268
5257
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
|
5269
5258
|
} else {
|
|
5270
5259
|
// Broad phase
|
|
5271
|
-
if (geometry.bounds.containsPoint(pointInShapeSpace,
|
|
5260
|
+
if (geometry.bounds.containsPoint(pointInShapeSpace, margin)) {
|
|
5272
5261
|
// Narrow phase (actual distance)
|
|
5273
5262
|
distance = geometry.distanceToPoint(pointInShapeSpace, hitInside)
|
|
5274
5263
|
} else {
|
|
@@ -5283,8 +5272,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5283
5272
|
// the shape or negative if inside of the shape. If the distance
|
|
5284
5273
|
// is greater than the margin, then it's a miss. Otherwise...
|
|
5285
5274
|
|
|
5286
|
-
|
|
5287
|
-
if (distance <= outerMargin || (hitInside && distance <= 0 && distance > -innerMargin)) {
|
|
5275
|
+
if (distance <= margin) {
|
|
5288
5276
|
if (geometry.isFilled || (isGroup && geometry.children[0].isFilled)) {
|
|
5289
5277
|
// If the shape is filled, then it's a hit. Remember, we're
|
|
5290
5278
|
// starting from the TOP-MOST shape in z-index order, so any
|
|
@@ -5294,21 +5282,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5294
5282
|
// If the shape is bigger than the viewport, then skip it.
|
|
5295
5283
|
if (this.getShapePageBounds(shape)!.contains(viewportPageBounds)) continue
|
|
5296
5284
|
|
|
5297
|
-
//
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
? // On hitInside, the distance will be negative for hits inside
|
|
5303
|
-
// If the distance is positive, check against the outer margin
|
|
5304
|
-
(distance > 0 && distance <= outerMargin) ||
|
|
5305
|
-
// If the distance is negative, check against the inner margin
|
|
5306
|
-
(distance <= 0 && distance > -innerMargin)
|
|
5307
|
-
: // If hitInside is false, then sadly _we do not know_ whether the
|
|
5308
|
-
// point is inside or outside of the shape, so we check against
|
|
5309
|
-
// the max of the two margins
|
|
5310
|
-
Math.abs(distance) <= Math.max(innerMargin, outerMargin)
|
|
5311
|
-
) {
|
|
5285
|
+
// For hollow shapes...
|
|
5286
|
+
if (Math.abs(distance) < margin) {
|
|
5287
|
+
// We want to preference shapes where we're inside of the
|
|
5288
|
+
// shape margin; and we would want to hit the shape with the
|
|
5289
|
+
// edge closest to the point.
|
|
5312
5290
|
if (Math.abs(distance) < inMarginClosestToEdgeDistance) {
|
|
5313
5291
|
inMarginClosestToEdgeDistance = Math.abs(distance)
|
|
5314
5292
|
inMarginClosestToEdgeHit = shape
|
|
@@ -5330,7 +5308,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5330
5308
|
} else {
|
|
5331
5309
|
// For open shapes (e.g. lines or draw shapes) always use the margin.
|
|
5332
5310
|
// If the distance is less than the margin, return the shape as the hit.
|
|
5333
|
-
// Use the editor's configurable hit test margin.
|
|
5334
5311
|
if (distance < this.options.hitTestMargin / zoomLevel) {
|
|
5335
5312
|
return shape
|
|
5336
5313
|
}
|
|
@@ -6333,17 +6310,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
6333
6310
|
|
|
6334
6311
|
this.createShapes(shapesToCreate)
|
|
6335
6312
|
this.createBindings(bindingsToCreate)
|
|
6336
|
-
|
|
6337
|
-
this.setSelectedShapes(
|
|
6338
|
-
compact(
|
|
6339
|
-
ids.map((oldId) => {
|
|
6340
|
-
const newId = shapeIds.get(oldId)
|
|
6341
|
-
if (!newId) return null
|
|
6342
|
-
if (!this.getShape(newId)) return null
|
|
6343
|
-
return newId
|
|
6344
|
-
})
|
|
6345
|
-
)
|
|
6346
|
-
)
|
|
6313
|
+
this.setSelectedShapes(compact(ids.map((id) => shapeIds.get(id))))
|
|
6347
6314
|
|
|
6348
6315
|
if (offset !== undefined) {
|
|
6349
6316
|
// If we've offset the duplicated shapes, check to see whether their new bounds is entirely
|
|
@@ -7397,6 +7364,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7397
7364
|
if (
|
|
7398
7365
|
!this.getShapeUtil(shape).canBeLaidOut?.(shape, {
|
|
7399
7366
|
type: 'stretch',
|
|
7367
|
+
shapes: shapesToStretchFirstPass,
|
|
7400
7368
|
})
|
|
7401
7369
|
) {
|
|
7402
7370
|
continue
|
|
@@ -7867,38 +7835,31 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
7867
7835
|
) {
|
|
7868
7836
|
let parentId: TLParentId = this.getFocusedGroupId()
|
|
7869
7837
|
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
hitInside: true,
|
|
7890
|
-
}
|
|
7891
|
-
)
|
|
7892
|
-
) {
|
|
7893
|
-
parentId = parent.id
|
|
7894
|
-
break
|
|
7895
|
-
}
|
|
7838
|
+
for (let i = currentPageShapesSorted.length - 1; i >= 0; i--) {
|
|
7839
|
+
const parent = currentPageShapesSorted[i]
|
|
7840
|
+
const util = this.getShapeUtil(parent)
|
|
7841
|
+
if (
|
|
7842
|
+
util.canReceiveNewChildrenOfType(parent, partial.type) &&
|
|
7843
|
+
!this.isShapeHidden(parent) &&
|
|
7844
|
+
this.isPointInShape(
|
|
7845
|
+
parent,
|
|
7846
|
+
// If no parent is provided, then we can treat the
|
|
7847
|
+
// shape's provided x/y as being in the page's space.
|
|
7848
|
+
{ x: partial.x ?? 0, y: partial.y ?? 0 },
|
|
7849
|
+
{
|
|
7850
|
+
margin: 0,
|
|
7851
|
+
hitInside: true,
|
|
7852
|
+
}
|
|
7853
|
+
)
|
|
7854
|
+
) {
|
|
7855
|
+
parentId = parent.id
|
|
7856
|
+
break
|
|
7896
7857
|
}
|
|
7897
7858
|
}
|
|
7898
7859
|
|
|
7899
7860
|
const prevParentId = partial.parentId
|
|
7900
7861
|
|
|
7901
|
-
// a shape cannot be
|
|
7862
|
+
// a shape cannot be it's own parent. This was a rare issue with frames/groups in the syncFuzz tests.
|
|
7902
7863
|
if (parentId === partial.id) {
|
|
7903
7864
|
parentId = focusedGroupId
|
|
7904
7865
|
}
|
|
@@ -9686,52 +9647,6 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9686
9647
|
return this
|
|
9687
9648
|
}
|
|
9688
9649
|
|
|
9689
|
-
/**
|
|
9690
|
-
* Dispatch a pointer move event in the current position of the pointer. This is useful when
|
|
9691
|
-
* external circumstances have changed (e.g. the camera moved or a shape was moved) and you want
|
|
9692
|
-
* the current interaction to respond to that change.
|
|
9693
|
-
*
|
|
9694
|
-
* @example
|
|
9695
|
-
* ```ts
|
|
9696
|
-
* editor.updatePointer()
|
|
9697
|
-
* ```
|
|
9698
|
-
*
|
|
9699
|
-
* @param options - The options for updating the pointer.
|
|
9700
|
-
* @returns The editor instance.
|
|
9701
|
-
* @public
|
|
9702
|
-
*/
|
|
9703
|
-
updatePointer(options?: TLUpdatePointerOptions): this {
|
|
9704
|
-
const event: TLPointerEventInfo = {
|
|
9705
|
-
type: 'pointer',
|
|
9706
|
-
target: 'canvas',
|
|
9707
|
-
name: 'pointer_move',
|
|
9708
|
-
point:
|
|
9709
|
-
options?.point ??
|
|
9710
|
-
// weird but true: what `inputs` calls screen-space is actually viewport space. so
|
|
9711
|
-
// we need to convert back into true screen space first. we should fix this...
|
|
9712
|
-
Vec.Add(
|
|
9713
|
-
this.inputs.currentScreenPoint,
|
|
9714
|
-
this.store.unsafeGetWithoutCapture(TLINSTANCE_ID)!.screenBounds
|
|
9715
|
-
),
|
|
9716
|
-
pointerId: options?.pointerId ?? 0,
|
|
9717
|
-
button: options?.button ?? 0,
|
|
9718
|
-
isPen: options?.isPen ?? this.inputs.isPen,
|
|
9719
|
-
shiftKey: options?.shiftKey ?? this.inputs.shiftKey,
|
|
9720
|
-
altKey: options?.altKey ?? this.inputs.altKey,
|
|
9721
|
-
ctrlKey: options?.ctrlKey ?? this.inputs.ctrlKey,
|
|
9722
|
-
metaKey: options?.metaKey ?? this.inputs.metaKey,
|
|
9723
|
-
accelKey: options?.accelKey ?? isAccelKey(this.inputs),
|
|
9724
|
-
}
|
|
9725
|
-
|
|
9726
|
-
if (options?.immediate) {
|
|
9727
|
-
this._flushEventForTick(event)
|
|
9728
|
-
} else {
|
|
9729
|
-
this.dispatch(event)
|
|
9730
|
-
}
|
|
9731
|
-
|
|
9732
|
-
return this
|
|
9733
|
-
}
|
|
9734
|
-
|
|
9735
9650
|
/**
|
|
9736
9651
|
* Puts the editor into focused mode.
|
|
9737
9652
|
*
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { Mocked, vi } from 'vitest'
|
|
2
1
|
import { Editor } from '../../Editor'
|
|
3
2
|
import { TLClickEventInfo, TLPointerEventInfo } from '../../types/event-types'
|
|
4
3
|
import { ClickManager } from './ClickManager'
|
|
5
4
|
|
|
6
5
|
// Mock the Editor class
|
|
7
|
-
|
|
6
|
+
jest.mock('../../Editor')
|
|
8
7
|
|
|
9
8
|
describe('ClickManager', () => {
|
|
10
|
-
let editor: Mocked<Editor>
|
|
9
|
+
let editor: jest.Mocked<Editor>
|
|
11
10
|
let clickManager: ClickManager
|
|
12
11
|
let mockTimers: any
|
|
13
12
|
|
|
@@ -30,14 +29,14 @@ describe('ClickManager', () => {
|
|
|
30
29
|
})
|
|
31
30
|
|
|
32
31
|
beforeEach(() => {
|
|
33
|
-
|
|
32
|
+
jest.useFakeTimers()
|
|
34
33
|
mockTimers = {
|
|
35
|
-
setTimeout:
|
|
34
|
+
setTimeout: jest.fn((fn, delay) => setTimeout(fn, delay)),
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
editor = {
|
|
39
38
|
timers: mockTimers,
|
|
40
|
-
dispatch:
|
|
39
|
+
dispatch: jest.fn(),
|
|
41
40
|
options: {
|
|
42
41
|
doubleClickDurationMs: 300,
|
|
43
42
|
multiClickDurationMs: 300,
|
|
@@ -47,7 +46,7 @@ describe('ClickManager', () => {
|
|
|
47
46
|
inputs: {
|
|
48
47
|
currentScreenPoint: { x: 0, y: 0 },
|
|
49
48
|
},
|
|
50
|
-
getInstanceState:
|
|
49
|
+
getInstanceState: jest.fn(() => ({
|
|
51
50
|
isCoarsePointer: false,
|
|
52
51
|
})),
|
|
53
52
|
} as any
|
|
@@ -56,8 +55,8 @@ describe('ClickManager', () => {
|
|
|
56
55
|
})
|
|
57
56
|
|
|
58
57
|
afterEach(() => {
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
jest.useRealTimers()
|
|
59
|
+
jest.clearAllMocks()
|
|
61
60
|
})
|
|
62
61
|
|
|
63
62
|
describe('constructor and initial state', () => {
|
|
@@ -101,7 +100,7 @@ describe('ClickManager', () => {
|
|
|
101
100
|
clickManager.handlePointerEvent(pointerEvent)
|
|
102
101
|
expect(clickManager.clickState).toBe('pendingDouble')
|
|
103
102
|
|
|
104
|
-
|
|
103
|
+
jest.advanceTimersByTime(350)
|
|
105
104
|
|
|
106
105
|
expect(clickManager.clickState).toBe('idle')
|
|
107
106
|
})
|
|
@@ -142,7 +141,7 @@ describe('ClickManager', () => {
|
|
|
142
141
|
clickManager.handlePointerEvent(firstDown)
|
|
143
142
|
clickManager.handlePointerEvent(secondDown)
|
|
144
143
|
|
|
145
|
-
|
|
144
|
+
jest.advanceTimersByTime(350)
|
|
146
145
|
|
|
147
146
|
expect(editor.dispatch).toHaveBeenCalledWith(
|
|
148
147
|
expect.objectContaining({
|
|
@@ -236,7 +235,7 @@ describe('ClickManager', () => {
|
|
|
236
235
|
clickManager.handlePointerEvent(pointerDown) // second
|
|
237
236
|
clickManager.handlePointerEvent(pointerDown) // third
|
|
238
237
|
|
|
239
|
-
|
|
238
|
+
jest.advanceTimersByTime(350)
|
|
240
239
|
|
|
241
240
|
expect(editor.dispatch).toHaveBeenCalledWith(
|
|
242
241
|
expect.objectContaining({
|
|
@@ -256,7 +255,7 @@ describe('ClickManager', () => {
|
|
|
256
255
|
clickManager.handlePointerEvent(pointerDown) // third
|
|
257
256
|
clickManager.handlePointerEvent(pointerDown) // fourth
|
|
258
257
|
|
|
259
|
-
|
|
258
|
+
jest.advanceTimersByTime(350)
|
|
260
259
|
|
|
261
260
|
expect(editor.dispatch).toHaveBeenCalledWith(
|
|
262
261
|
expect.objectContaining({
|
|
@@ -278,7 +277,7 @@ describe('ClickManager', () => {
|
|
|
278
277
|
editor.options.doubleClickDurationMs
|
|
279
278
|
)
|
|
280
279
|
|
|
281
|
-
|
|
280
|
+
jest.clearAllMocks()
|
|
282
281
|
|
|
283
282
|
// Second click - should use multiClickDurationMs
|
|
284
283
|
clickManager.handlePointerEvent(pointerDown)
|
|
@@ -393,7 +392,7 @@ describe('ClickManager', () => {
|
|
|
393
392
|
clickManager.cancelDoubleClickTimeout()
|
|
394
393
|
|
|
395
394
|
// Advance time - should not dispatch settle event
|
|
396
|
-
|
|
395
|
+
jest.advanceTimersByTime(350)
|
|
397
396
|
|
|
398
397
|
expect(editor.dispatch).not.toHaveBeenCalled()
|
|
399
398
|
expect(clickManager.clickState).toBe('idle')
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
import { Mock, Mocked, vi } from 'vitest'
|
|
2
1
|
import { Box } from '../../../primitives/Box'
|
|
3
2
|
import { Vec } from '../../../primitives/Vec'
|
|
4
3
|
import { Editor } from '../../Editor'
|
|
5
4
|
import { EdgeScrollManager } from './EdgeScrollManager'
|
|
6
5
|
|
|
7
6
|
// Mock the Editor class
|
|
8
|
-
|
|
7
|
+
jest.mock('../../Editor')
|
|
9
8
|
|
|
10
9
|
describe('EdgeScrollManager', () => {
|
|
11
|
-
let editor: Mocked<
|
|
10
|
+
let editor: jest.Mocked<
|
|
12
11
|
Editor & {
|
|
13
|
-
user: { getEdgeScrollSpeed: Mock }
|
|
14
|
-
getCamera: Mock
|
|
15
|
-
getCameraOptions: Mock
|
|
16
|
-
getZoomLevel: Mock
|
|
17
|
-
getViewportScreenBounds: Mock
|
|
12
|
+
user: { getEdgeScrollSpeed: jest.Mock }
|
|
13
|
+
getCamera: jest.Mock
|
|
14
|
+
getCameraOptions: jest.Mock
|
|
15
|
+
getZoomLevel: jest.Mock
|
|
16
|
+
getViewportScreenBounds: jest.Mock
|
|
18
17
|
}
|
|
19
18
|
>
|
|
20
19
|
let edgeScrollManager: EdgeScrollManager
|
|
@@ -34,33 +33,33 @@ describe('EdgeScrollManager', () => {
|
|
|
34
33
|
isPanning: false,
|
|
35
34
|
},
|
|
36
35
|
user: {
|
|
37
|
-
getEdgeScrollSpeed:
|
|
36
|
+
getEdgeScrollSpeed: jest.fn(() => 1),
|
|
38
37
|
},
|
|
39
|
-
getViewportScreenBounds:
|
|
40
|
-
getInstanceState:
|
|
38
|
+
getViewportScreenBounds: jest.fn(() => new Box(0, 0, 1000, 600)),
|
|
39
|
+
getInstanceState: jest.fn(
|
|
41
40
|
() =>
|
|
42
41
|
({
|
|
43
42
|
isCoarsePointer: false,
|
|
44
43
|
insets: [false, false, false, false], // [top, right, bottom, left]
|
|
45
44
|
}) as any
|
|
46
45
|
),
|
|
47
|
-
getCameraOptions:
|
|
46
|
+
getCameraOptions: jest.fn(() => ({
|
|
48
47
|
isLocked: false,
|
|
49
48
|
panSpeed: 1,
|
|
50
49
|
zoomSpeed: 1,
|
|
51
50
|
zoomSteps: [1],
|
|
52
51
|
wheelBehavior: 'pan' as const,
|
|
53
52
|
})),
|
|
54
|
-
getZoomLevel:
|
|
55
|
-
getCamera:
|
|
56
|
-
setCamera:
|
|
53
|
+
getZoomLevel: jest.fn(() => 1),
|
|
54
|
+
getCamera: jest.fn(() => new Vec(0, 0, 1)),
|
|
55
|
+
setCamera: jest.fn(),
|
|
57
56
|
} as any
|
|
58
57
|
|
|
59
58
|
edgeScrollManager = new EdgeScrollManager(editor as any)
|
|
60
59
|
})
|
|
61
60
|
|
|
62
61
|
afterEach(() => {
|
|
63
|
-
|
|
62
|
+
jest.clearAllMocks()
|
|
64
63
|
})
|
|
65
64
|
|
|
66
65
|
describe('constructor and initialization', () => {
|