No impure getters pt10 (#2235)
Follow up to #2189 ### Change Type - [x] `patch` — Bug fix
This commit is contained in:
parent
81f6fae070
commit
431ce73476
49 changed files with 751 additions and 171 deletions
|
@ -44,6 +44,11 @@ module.exports = {
|
|||
],
|
||||
'local/no-export-star': 'error',
|
||||
'no-only-tests/no-only-tests': 'error',
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{ selector: "MethodDefinition[kind='set']", message: 'Property setters are not allowed' },
|
||||
{ selector: "MethodDefinition[kind='get']", message: 'Property getters are not allowed' },
|
||||
],
|
||||
},
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
|
|
|
@ -1803,6 +1803,8 @@ export class SnapManager {
|
|||
// (undocumented)
|
||||
getCurrentCommonAncestor(): TLShapeId | undefined;
|
||||
// (undocumented)
|
||||
getLines(): SnapLine[];
|
||||
// (undocumented)
|
||||
getOutlinesInPageSpace(): Vec2d[][];
|
||||
// (undocumented)
|
||||
getSnappablePoints(): SnapPoint[];
|
||||
|
@ -1822,7 +1824,7 @@ export class SnapManager {
|
|||
horizontal: Gap[];
|
||||
vertical: Gap[];
|
||||
};
|
||||
// (undocumented)
|
||||
// @deprecated (undocumented)
|
||||
get lines(): SnapLine[];
|
||||
// @deprecated (undocumented)
|
||||
get outlinesInPageSpace(): Vec2d[][];
|
||||
|
@ -1897,7 +1899,7 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
static children?: () => TLStateNodeConstructor[];
|
||||
// (undocumented)
|
||||
children?: Record<string, StateNode>;
|
||||
// (undocumented)
|
||||
// @deprecated (undocumented)
|
||||
get currentToolIdMask(): string | undefined;
|
||||
set currentToolIdMask(id: string | undefined);
|
||||
_currentToolIdMask: Atom<string | undefined, unknown>;
|
||||
|
@ -1908,6 +1910,8 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
// (undocumented)
|
||||
exit: (info: any, from: string) => void;
|
||||
getCurrent(): StateNode | undefined;
|
||||
// (undocumented)
|
||||
getCurrentToolIdMask(): string | undefined;
|
||||
getIsActive(): boolean;
|
||||
getPath(): string;
|
||||
// (undocumented)
|
||||
|
@ -1959,6 +1963,8 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
// (undocumented)
|
||||
_path: Computed<string>;
|
||||
// (undocumented)
|
||||
setCurrentToolIdMask(id: string | undefined): void;
|
||||
// (undocumented)
|
||||
shapeType?: string;
|
||||
transition: (id: string, info?: any) => this;
|
||||
// (undocumented)
|
||||
|
|
|
@ -33889,6 +33889,42 @@
|
|||
"isAbstract": false,
|
||||
"name": "getCurrentCommonAncestor"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!SnapManager#getLines:member(1)",
|
||||
"docComment": "",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getLines(): "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "SnapLine",
|
||||
"canonicalReference": "@tldraw/editor!SnapLine:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "[]"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 3
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getLines"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!SnapManager#getOutlinesInPageSpace:member(1)",
|
||||
|
@ -34209,7 +34245,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!SnapManager#lines:member",
|
||||
"docComment": "",
|
||||
"docComment": "/**\n * @deprecated\n *\n * use `getLines` instead\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -35318,7 +35354,7 @@
|
|||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!StateNode#currentToolIdMask:member",
|
||||
"docComment": "",
|
||||
"docComment": "/**\n * @deprecated\n *\n * use `getCurrentToolIdMask()` instead\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -35472,6 +35508,37 @@
|
|||
"isAbstract": false,
|
||||
"name": "getCurrent"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!StateNode#getCurrentToolIdMask:member(1)",
|
||||
"docComment": "",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "getCurrentToolIdMask(): "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "string | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "getCurrentToolIdMask"
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!StateNode#getIsActive:member(1)",
|
||||
|
@ -36329,6 +36396,54 @@
|
|||
"isProtected": false,
|
||||
"isAbstract": false
|
||||
},
|
||||
{
|
||||
"kind": "Method",
|
||||
"canonicalReference": "@tldraw/editor!StateNode#setCurrentToolIdMask:member(1)",
|
||||
"docComment": "",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "setCurrentToolIdMask(id: "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "string | undefined"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "): "
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "void"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
}
|
||||
],
|
||||
"isStatic": false,
|
||||
"returnTypeTokenRange": {
|
||||
"startIndex": 3,
|
||||
"endIndex": 4
|
||||
},
|
||||
"releaseTag": "Public",
|
||||
"isProtected": false,
|
||||
"overloadIndex": 1,
|
||||
"parameters": [
|
||||
{
|
||||
"parameterName": "id",
|
||||
"parameterTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 2
|
||||
},
|
||||
"isOptional": false
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isAbstract": false,
|
||||
"name": "setCurrentToolIdMask"
|
||||
},
|
||||
{
|
||||
"kind": "Property",
|
||||
"canonicalReference": "@tldraw/editor!StateNode#shapeType:member",
|
||||
|
|
|
@ -189,7 +189,7 @@ function ZoomBrushWrapper() {
|
|||
|
||||
function SnapLinesWrapper() {
|
||||
const editor = useEditor()
|
||||
const lines = useValue('snapLines', () => editor.snaps.lines, [editor])
|
||||
const lines = useValue('snapLines', () => editor.snaps.getLines(), [editor])
|
||||
const zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])
|
||||
const { SnapLine } = useEditorComponents()
|
||||
|
||||
|
|
|
@ -799,12 +799,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @public
|
||||
*/
|
||||
@computed getCanUndo(): boolean {
|
||||
return this.history.numUndos > 0
|
||||
return this.history.getNumUndos() > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getCanUndo` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get canUndo(): boolean {
|
||||
return this.getCanUndo()
|
||||
}
|
||||
|
@ -830,12 +831,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @public
|
||||
*/
|
||||
@computed getCanRedo(): boolean {
|
||||
return this.history.numRedos > 0
|
||||
return this.history.getNumRedos() > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getCanRedo` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get canRedo(): boolean {
|
||||
return this.getCanRedo()
|
||||
}
|
||||
|
@ -1141,6 +1143,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @deprecated Use `getCurrentTool` instead.
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentTool() {
|
||||
return this.getCurrentTool()
|
||||
}
|
||||
|
@ -1153,12 +1156,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
@computed getCurrentToolId(): string {
|
||||
const currentTool = this.getCurrentTool()
|
||||
if (!currentTool) return ''
|
||||
return currentTool.currentToolIdMask ?? currentTool.id
|
||||
return currentTool.getCurrentToolIdMask() ?? currentTool.id
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getCurrentToolId` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentToolId() {
|
||||
return this.getCurrentToolId()
|
||||
}
|
||||
|
@ -1203,6 +1207,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getDocumentSettings` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get documentSettings() {
|
||||
return this.getDocumentSettings()
|
||||
}
|
||||
|
@ -1231,6 +1236,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getInstanceState` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get instanceState() {
|
||||
return this.getInstanceState()
|
||||
}
|
||||
|
@ -1315,6 +1321,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getOpenMenus` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get openMenus() {
|
||||
return this.getOpenMenus()
|
||||
}
|
||||
|
@ -1374,6 +1381,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getIsMenuOpen` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isMenuOpen() {
|
||||
return this.getIsMenuOpen()
|
||||
}
|
||||
|
@ -1410,6 +1418,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getPageStates` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get pageStates() {
|
||||
return this.getPageStates()
|
||||
}
|
||||
|
@ -1431,6 +1440,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCurrentPageState` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageState() {
|
||||
return this.getCurrentPageState()
|
||||
}
|
||||
|
@ -1496,6 +1506,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getSelectedShapeIds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get selectedShapeIds() {
|
||||
return this.getSelectedShapeIds()
|
||||
}
|
||||
|
@ -1514,6 +1525,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getSelectedShapes` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get selectedShapes() {
|
||||
return this.getSelectedShapes()
|
||||
}
|
||||
|
@ -1690,6 +1702,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getOnlySelectedShape` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get onlySelectedShape() {
|
||||
return this.getOnlySelectedShape()
|
||||
}
|
||||
|
@ -1713,6 +1726,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getSelectionPageBounds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get selectionPageBounds() {
|
||||
return this.getSelectionPageBounds()
|
||||
}
|
||||
|
@ -1743,6 +1757,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getSelectionRotation` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get selectionRotation() {
|
||||
return this.getSelectionRotation()
|
||||
}
|
||||
|
@ -1790,6 +1805,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getSelectionRotatedPageBounds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get selectionRotatedPageBounds() {
|
||||
return this.getSelectionRotatedPageBounds()
|
||||
}
|
||||
|
@ -1808,6 +1824,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getFocusedGroupId` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get focusedGroupId() {
|
||||
return this.getFocusedGroupId()
|
||||
}
|
||||
|
@ -1825,6 +1842,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getFocusedGroup` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get focusedGroup() {
|
||||
return this.getFocusedGroup()
|
||||
}
|
||||
|
@ -1922,6 +1940,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getEditingShapeId` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get editingShapeId() {
|
||||
return this.getEditingShapeId()
|
||||
}
|
||||
|
@ -1939,6 +1958,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getEditingShape` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get editingShape() {
|
||||
return this.getEditingShape()
|
||||
}
|
||||
|
@ -1988,6 +2008,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getHoveredShapeId` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get hoveredShapeId() {
|
||||
return this.getHoveredShapeId()
|
||||
}
|
||||
|
@ -2005,6 +2026,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getHoveredShape` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get hoveredShape() {
|
||||
return this.getHoveredShape()
|
||||
}
|
||||
|
@ -2043,6 +2065,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getHintingShapeIds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get hintingShapeIds() {
|
||||
return this.getHintingShapeIds()
|
||||
}
|
||||
|
@ -2060,6 +2083,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getHintingShape` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get hintingShape() {
|
||||
return this.getHintingShape()
|
||||
}
|
||||
|
@ -2101,6 +2125,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getErasingShapeIds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get erasingShapeIds() {
|
||||
return this.getErasingShapeIds()
|
||||
}
|
||||
|
@ -2118,6 +2143,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getErasingShapes` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get erasingShapes() {
|
||||
return this.getErasingShapes()
|
||||
}
|
||||
|
@ -2174,6 +2200,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCroppingShapeId` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get croppingShapeId() {
|
||||
return this.getCroppingShapeId()
|
||||
}
|
||||
|
@ -2237,6 +2264,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getZoomLevel` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get zoomLevel() {
|
||||
return this.getZoomLevel()
|
||||
}
|
||||
|
@ -2948,6 +2976,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getViewportScreenBounds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get viewportScreenBounds() {
|
||||
return this.getViewportScreenBounds()
|
||||
}
|
||||
|
@ -2964,6 +2993,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getViewportScreenCenter` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get viewportScreenCenter() {
|
||||
return this.getViewportScreenCenter()
|
||||
}
|
||||
|
@ -2982,6 +3012,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getViewportPageBounds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get viewportPageBounds() {
|
||||
return this.getViewportPageBounds()
|
||||
}
|
||||
|
@ -2998,6 +3029,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getViewportPageCenter` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get viewportPageCenter() {
|
||||
return this.getViewportPageCenter()
|
||||
}
|
||||
|
@ -3201,6 +3233,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCameraState` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get cameraState() {
|
||||
return this.getCameraState()
|
||||
}
|
||||
|
@ -3376,6 +3409,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getRenderingShapes` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get renderingShapes() {
|
||||
return this.getRenderingShapes()
|
||||
}
|
||||
|
@ -3393,6 +3427,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
* @deprecated Use `getRenderingBounds` instead.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get renderingBounds() {
|
||||
return this.getRenderingBounds()
|
||||
}
|
||||
|
@ -3413,6 +3448,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getRenderingBoundsExpanded` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get renderingBoundsExpanded() {
|
||||
return this.getRenderingBoundsExpanded()
|
||||
}
|
||||
|
@ -3473,6 +3509,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getPages` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get pages() {
|
||||
return this.getPages()
|
||||
}
|
||||
|
@ -3482,6 +3519,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPage(): TLPage {
|
||||
const page = this.getPage(this.currentPageId)!
|
||||
return page
|
||||
|
@ -3492,6 +3530,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageId(): TLPageId {
|
||||
return this.getInstanceState().currentPageId
|
||||
}
|
||||
|
@ -3521,6 +3560,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageShapeIds() {
|
||||
return this._currentPageShapeIds.get()
|
||||
}
|
||||
|
@ -3873,6 +3913,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getAssets` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get assets() {
|
||||
return this.getAssets()
|
||||
}
|
||||
|
@ -4493,6 +4534,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCurrentPageBounds` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageBounds() {
|
||||
return this.getCurrentPageBounds()
|
||||
}
|
||||
|
@ -4809,6 +4851,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCurrentPageShapes` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageShapes() {
|
||||
return this.getCurrentPageShapes()
|
||||
}
|
||||
|
@ -4850,6 +4893,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCurrentPageShapesSorted` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageShapesSorted() {
|
||||
return this.getCurrentPageShapesSorted()
|
||||
}
|
||||
|
@ -4870,6 +4914,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `getCurrentPageRenderingShapesSorted` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentPageRenderingShapesSorted() {
|
||||
return this.getCurrentPageRenderingShapesSorted()
|
||||
}
|
||||
|
@ -7566,6 +7611,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `editor.sharedStyles` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get sharedStyles() {
|
||||
return this.getSharedStyles()
|
||||
}
|
||||
|
@ -7615,6 +7661,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|||
/**
|
||||
* @deprecated Use `editor.sharedOpacity` instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get sharedOpacity() {
|
||||
return this.getSharedOpacity()
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ export class ClickManager {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get clickState() {
|
||||
return this._clickState
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ describe(HistoryManager, () => {
|
|||
|
||||
expect(editor.getCount()).toBe(5)
|
||||
|
||||
expect(editor.history.numUndos).toBe(3)
|
||||
expect(editor.history.getNumUndos()).toBe(3)
|
||||
})
|
||||
|
||||
it('allows ephemeral commands that do not affect the stack', () => {
|
||||
|
@ -250,11 +250,11 @@ describe(HistoryManager, () => {
|
|||
|
||||
it('does not allow new history entries to be pushed if a command invokes them while doing or undoing', () => {
|
||||
editor.incrementTwice()
|
||||
expect(editor.history.numUndos).toBe(1)
|
||||
expect(editor.history.getNumUndos()).toBe(1)
|
||||
expect(editor.getCount()).toBe(2)
|
||||
editor.history.undo()
|
||||
expect(editor.getCount()).toBe(0)
|
||||
expect(editor.history.numUndos).toBe(0)
|
||||
expect(editor.history.getNumUndos()).toBe(0)
|
||||
})
|
||||
|
||||
it('does not allow new history entries to be pushed if a command invokes them while bailing', () => {
|
||||
|
@ -263,13 +263,13 @@ describe(HistoryManager, () => {
|
|||
editor.history.mark('2')
|
||||
editor.incrementTwice()
|
||||
editor.incrementTwice()
|
||||
expect(editor.history.numUndos).toBe(5)
|
||||
expect(editor.history.getNumUndos()).toBe(5)
|
||||
expect(editor.getCount()).toBe(6)
|
||||
editor.history.bail()
|
||||
expect(editor.getCount()).toBe(2)
|
||||
expect(editor.history.numUndos).toBe(2)
|
||||
expect(editor.history.getNumUndos()).toBe(2)
|
||||
editor.history.bailToMark('0')
|
||||
expect(editor.history.numUndos).toBe(0)
|
||||
expect(editor.history.getNumUndos()).toBe(0)
|
||||
expect(editor.getCount()).toBe(0)
|
||||
})
|
||||
|
||||
|
|
|
@ -33,13 +33,27 @@ export class HistoryManager<
|
|||
|
||||
private _commands: Record<string, TLCommandHandler<any>> = {}
|
||||
|
||||
get numUndos() {
|
||||
getNumUndos() {
|
||||
return this._undos.get().length
|
||||
}
|
||||
/**
|
||||
* @deprecated use `getNumUndos` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get numUndos() {
|
||||
return this.getNumUndos()
|
||||
}
|
||||
|
||||
get numRedos() {
|
||||
getNumRedos() {
|
||||
return this._redos.get().length
|
||||
}
|
||||
/**
|
||||
* @deprecated use `getNumRedos` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get numRedos() {
|
||||
return this.getNumRedos()
|
||||
}
|
||||
|
||||
createCommand = <Name extends string, Constructor extends CommandFn<any>>(
|
||||
name: Name,
|
||||
|
|
|
@ -73,7 +73,7 @@ type NearestSnap =
|
|||
}
|
||||
| {
|
||||
// selection snaps to create a new gap of equal size to another gap
|
||||
// on the opposide side of some shape
|
||||
// on the opposite side of some shape
|
||||
type: 'gap_duplicate'
|
||||
gap: Gap
|
||||
protrusionDirection: 'left' | 'right' | 'top' | 'bottom'
|
||||
|
@ -212,12 +212,20 @@ function dedupeGapSnaps(snaps: Array<Extract<SnapLine, { type: 'gaps' }>>) {
|
|||
export class SnapManager {
|
||||
private _snapLines = atom<SnapLine[] | undefined>('snapLines', undefined)
|
||||
|
||||
get lines() {
|
||||
getLines() {
|
||||
return this._snapLines.get() ?? (EMPTY_ARRAY as SnapLine[])
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use `getLines` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get lines() {
|
||||
return this.getLines()
|
||||
}
|
||||
|
||||
clear() {
|
||||
if (this.lines.length) {
|
||||
if (this.getLines().length) {
|
||||
this._snapLines.set(undefined)
|
||||
}
|
||||
}
|
||||
|
@ -244,6 +252,7 @@ export class SnapManager {
|
|||
/**
|
||||
* @deprecated use `getSnapPointsCache` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get snapPointsCache() {
|
||||
return this.getSnapPointsCache()
|
||||
}
|
||||
|
@ -255,6 +264,7 @@ export class SnapManager {
|
|||
/**
|
||||
* @deprecated use `getSnapThreshold` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get snapThreshold() {
|
||||
return this.getSnapThreshold()
|
||||
}
|
||||
|
@ -302,6 +312,7 @@ export class SnapManager {
|
|||
* @deprecated use `getSnappableShapes` instead
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get snappableShapes() {
|
||||
return this.getSnappableShapes()
|
||||
}
|
||||
|
@ -314,6 +325,7 @@ export class SnapManager {
|
|||
/**
|
||||
* @deprecated use `getCurrentCommonAncestor` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentCommonAncestor() {
|
||||
return this.getCurrentCommonAncestor()
|
||||
}
|
||||
|
@ -337,6 +349,7 @@ export class SnapManager {
|
|||
/**
|
||||
* @deprecated use `getSnappablePoints` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get snappablePoints() {
|
||||
return this.getSnappablePoints()
|
||||
}
|
||||
|
@ -441,6 +454,7 @@ export class SnapManager {
|
|||
/**
|
||||
* @deprecated use `getVisibleGaps` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get visibleGaps() {
|
||||
return this.getVisibleGaps()
|
||||
}
|
||||
|
@ -551,6 +565,7 @@ export class SnapManager {
|
|||
/**
|
||||
* @deprecated use `getOutlinesInPageSpace` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get outlinesInPageSpace() {
|
||||
return this.getOutlinesInPageSpace()
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getUserPreferences` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get userPreferences() {
|
||||
return this.getUserPreferences()
|
||||
}
|
||||
|
@ -43,6 +44,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getIsDarkMode` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isDarkMode() {
|
||||
return this.getIsDarkMode()
|
||||
}
|
||||
|
@ -54,6 +56,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getAnimationSpeed` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get animationSpeed() {
|
||||
return this.getAnimationSpeed()
|
||||
}
|
||||
|
@ -65,6 +68,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getId` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get id() {
|
||||
return this.getId()
|
||||
}
|
||||
|
@ -76,6 +80,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getName` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get name() {
|
||||
return this.getName()
|
||||
}
|
||||
|
@ -87,6 +92,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getLocale` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get locale() {
|
||||
return this.getLocale()
|
||||
}
|
||||
|
@ -98,6 +104,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getColor` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get color() {
|
||||
return this.getColor()
|
||||
}
|
||||
|
@ -109,6 +116,7 @@ export class UserPreferencesManager {
|
|||
/**
|
||||
* @deprecated use `getIsSnapMode` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isSnapMode() {
|
||||
return this.getIsSnapMode()
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
@computed getPath() {
|
||||
getPath() {
|
||||
return this._path.get()
|
||||
}
|
||||
_path: Computed<string>
|
||||
|
@ -85,7 +85,7 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
@computed getCurrent() {
|
||||
getCurrent() {
|
||||
return this._current.get()
|
||||
}
|
||||
private _current: Atom<StateNode | undefined>
|
||||
|
@ -95,7 +95,7 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
@computed getIsActive() {
|
||||
getIsActive() {
|
||||
return this._isActive.get()
|
||||
}
|
||||
private _isActive: Atom<boolean>
|
||||
|
@ -182,11 +182,23 @@ export abstract class StateNode implements Partial<TLEventHandlers> {
|
|||
*/
|
||||
_currentToolIdMask = atom('curent tool id mask', undefined as string | undefined)
|
||||
|
||||
@computed get currentToolIdMask() {
|
||||
/**
|
||||
* @deprecated use `getCurrentToolIdMask()` instead
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentToolIdMask() {
|
||||
return this._currentToolIdMask.get()
|
||||
}
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set currentToolIdMask(id: string | undefined) {
|
||||
this._currentToolIdMask.set(id)
|
||||
}
|
||||
|
||||
getCurrentToolIdMask() {
|
||||
return this._currentToolIdMask.get()
|
||||
}
|
||||
|
||||
set currentToolIdMask(id: string | undefined) {
|
||||
setCurrentToolIdMask(id: string | undefined) {
|
||||
this._currentToolIdMask.set(id)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,76 +36,94 @@ export class Box2d {
|
|||
w = 0
|
||||
h = 0
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get point() {
|
||||
return new Vec2d(this.x, this.y)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set point(val: Vec2d) {
|
||||
this.x = val.x
|
||||
this.y = val.y
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get minX() {
|
||||
return this.x
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set minX(n: number) {
|
||||
this.x = n
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get midX() {
|
||||
return this.x + this.w / 2
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get maxX() {
|
||||
return this.x + this.w
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get minY() {
|
||||
return this.y
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set minY(n: number) {
|
||||
this.y = n
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get midY() {
|
||||
return this.y + this.h / 2
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get maxY() {
|
||||
return this.y + this.h
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get width() {
|
||||
return this.w
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set width(n: number) {
|
||||
this.w = n
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get height() {
|
||||
return this.h
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set height(n: number) {
|
||||
this.h = n
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get aspectRatio() {
|
||||
return this.width / this.height
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get center() {
|
||||
return new Vec2d(this.midX, this.midY)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
set center(v: Vec2d) {
|
||||
this.minX = v.x - this.width / 2
|
||||
this.minY = v.y - this.height / 2
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get corners() {
|
||||
return [
|
||||
new Vec2d(this.minX, this.minY),
|
||||
|
@ -115,6 +133,7 @@ export class Box2d {
|
|||
]
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get snapPoints() {
|
||||
return [
|
||||
new Vec2d(this.minX, this.minY),
|
||||
|
@ -125,6 +144,7 @@ export class Box2d {
|
|||
]
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get sides(): Array<[Vec2d, Vec2d]> {
|
||||
const { corners } = this
|
||||
return [
|
||||
|
@ -135,6 +155,7 @@ export class Box2d {
|
|||
]
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get size(): Vec2d {
|
||||
return new Vec2d(this.w, this.h)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ export type VecLike = Vec2d | Vec2dModel
|
|||
export class Vec2d {
|
||||
constructor(public x = 0, public y = 0, public z = 1) {}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get pressure() {
|
||||
return this.z
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ export class CubicSpline2d extends Geometry2d {
|
|||
|
||||
_segments?: CubicBezier2d[]
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get segments() {
|
||||
if (!this._segments) {
|
||||
this._segments = []
|
||||
|
@ -49,6 +50,7 @@ export class CubicSpline2d extends Geometry2d {
|
|||
|
||||
_length?: number
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get length() {
|
||||
if (!this._length) {
|
||||
this._length = this.segments.reduce((acc, segment) => acc + segment.length, 0)
|
||||
|
|
|
@ -24,6 +24,7 @@ export class Edge2d extends Geometry2d {
|
|||
|
||||
_length?: number
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get length() {
|
||||
if (!this._length) {
|
||||
return this.d.len()
|
||||
|
|
|
@ -24,6 +24,7 @@ export class Ellipse2d extends Geometry2d {
|
|||
|
||||
_edges?: Edge2d[]
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get edges() {
|
||||
if (!this._edges) {
|
||||
const { vertices } = this
|
||||
|
|
|
@ -78,6 +78,7 @@ export abstract class Geometry2d {
|
|||
|
||||
_vertices: Vec2d[] | undefined
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get vertices(): Vec2d[] {
|
||||
if (!this._vertices) {
|
||||
this._vertices = this.getVertices()
|
||||
|
@ -92,6 +93,7 @@ export abstract class Geometry2d {
|
|||
|
||||
_bounds: Box2d | undefined
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get bounds(): Box2d {
|
||||
if (!this._bounds) {
|
||||
this._bounds = this.getBounds()
|
||||
|
@ -101,6 +103,7 @@ export abstract class Geometry2d {
|
|||
|
||||
_snapPoints: Vec2d[] | undefined
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get snapPoints() {
|
||||
if (!this._snapPoints) {
|
||||
this._snapPoints = this.bounds.snapPoints
|
||||
|
@ -108,12 +111,14 @@ export abstract class Geometry2d {
|
|||
return this._snapPoints
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get center() {
|
||||
return this.bounds.center
|
||||
}
|
||||
|
||||
_area: number | undefined
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get area() {
|
||||
if (!this._area) {
|
||||
this._area = this.getArea()
|
||||
|
|
|
@ -14,6 +14,7 @@ export class Polyline2d extends Geometry2d {
|
|||
|
||||
_segments?: Edge2d[]
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get segments() {
|
||||
if (!this._segments) {
|
||||
this._segments = []
|
||||
|
@ -34,6 +35,7 @@ export class Polyline2d extends Geometry2d {
|
|||
|
||||
_length?: number
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get length() {
|
||||
if (!this._length) {
|
||||
this._length = this.segments.reduce((acc, segment) => acc + segment.length, 0)
|
||||
|
|
|
@ -16,7 +16,7 @@ class C extends StateNode {
|
|||
static override id = 'C'
|
||||
|
||||
override onEnter = () => {
|
||||
this.currentToolIdMask = 'A'
|
||||
this.setCurrentToolIdMask('A')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export class ReadonlySharedStyleMap {
|
|||
return value.value
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get size() {
|
||||
return this.map.size
|
||||
}
|
||||
|
|
|
@ -596,7 +596,7 @@
|
|||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/state!computed:function(1)",
|
||||
"docComment": "/**\n * Creates a computed signal.\n *\n * @param name - The name of the signal.\n *\n * @param compute - The function that computes the value of the signal.\n *\n * @param options - Options for the signal.\n *\n * @example\n * ```ts\n * const name = atom('name', 'John')\n * const greeting = computed('greeting', () => `Hello ${name.value}!`)\n * console.log(greeting.value) // 'Hello John!'\n * ```\n *\n * `computed` may also be used as a decorator for creating computed class properties.\n *\n * @example\n * ```ts\n * class Counter {\n * max = 100\n * count = atom<number>(0)\n *\n * @computed get remaining() {\n * return this.max - this.count.value\n * }\n * }\n * ```\n *\n * You may optionally pass in a [[ComputedOptions]] when used as a decorator:\n *\n * @example\n * ```ts\n * class Counter {\n * max = 100\n * count = atom<number>(0)\n *\n * @computed({isEqual: (a, b) => a === b})\n * get remaining() {\n * return this.max - this.count.value\n * }\n * }\n * ```\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * Creates a computed signal.\n *\n * @param name - The name of the signal.\n *\n * @param compute - The function that computes the value of the signal.\n *\n * @param options - Options for the signal.\n *\n * @example\n * ```ts\n * const name = atom('name', 'John')\n * const greeting = computed('greeting', () => `Hello ${name.value}!`)\n * console.log(greeting.value) // 'Hello John!'\n * ```\n *\n * `computed` may also be used as a decorator for creating computed getter methods.\n *\n * @example\n * ```ts\n * class Counter {\n * max = 100\n * count = atom<number>(0)\n *\n * @computed getRemaining() {\n * return this.max - this.count.value\n * }\n * }\n * ```\n *\n * You may optionally pass in a [[ComputedOptions]] when used as a decorator:\n *\n * @example\n * ```ts\n * class Counter {\n * max = 100\n * count = atom<number>(0)\n *\n * @computed({isEqual: (a, b) => a === b})\n * getRemaining() {\n * return this.max - this.count.value\n * }\n * }\n * ```\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
@ -1434,7 +1434,7 @@
|
|||
{
|
||||
"kind": "Function",
|
||||
"canonicalReference": "@tldraw/state!getComputedInstance:function(1)",
|
||||
"docComment": "/**\n * Retrieves the underlying computed instance for a given property created with the [[computed]] decorator.\n *\n * @param obj - The object\n *\n * @param propertyName - The property name\n *\n * @example\n * ```ts\n * class Counter {\n * max = 100\n * count = atom(0)\n *\n * @computed get remaining() {\n * return this.max - this.count.value\n * }\n * }\n *\n * const c = new Counter()\n * const remaining = getComputedInstance(c, 'remaining')\n * remaining.value === 100 // true\n * c.count.set(13)\n * remaining.value === 87 // true\n * ```\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * Retrieves the underlying computed instance for a given property created with the [[computed]] decorator.\n *\n * @param obj - The object\n *\n * @param propertyName - The property name\n *\n * @example\n * ```ts\n * class Counter {\n * max = 100\n * count = atom(0)\n *\n * @computed getRemaining() {\n * return this.max - this.count.value\n * }\n * }\n *\n * const c = new Counter()\n * const remaining = getComputedInstance(c, 'getRemaining')\n * remaining.value === 100 // true\n * c.count.set(13)\n * remaining.value === 87 // true\n * ```\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
|
|
|
@ -18,6 +18,7 @@ export class ArraySet<T> {
|
|||
*
|
||||
* @returns True if this ArraySet has any elements, false otherwise.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isEmpty() {
|
||||
if (this.array) {
|
||||
return this.arraySize === 0
|
||||
|
|
|
@ -108,6 +108,7 @@ export class _Atom<Value, Diff = unknown> implements Atom<Value, Diff> {
|
|||
/**
|
||||
* @deprecated Use [[Atom.get]] instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get value() {
|
||||
logDotValueWarning()
|
||||
return this.get()
|
||||
|
|
|
@ -135,6 +135,7 @@ export class _Computed<Value, Diff = unknown> implements Computed<Value, Diff> {
|
|||
|
||||
children = new ArraySet<Child>()
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isActivelyListening(): boolean {
|
||||
return !this.children.isEmpty
|
||||
}
|
||||
|
@ -212,6 +213,7 @@ export class _Computed<Value, Diff = unknown> implements Computed<Value, Diff> {
|
|||
/**
|
||||
* @deprecated Use [[get]] instead.
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get value() {
|
||||
logDotValueWarning()
|
||||
return this.get()
|
||||
|
@ -311,13 +313,13 @@ const isComputedMethodKey = '@@__isComputedMethod__@@'
|
|||
* max = 100
|
||||
* count = atom(0)
|
||||
*
|
||||
* @computed get remaining() {
|
||||
* @computed getRemaining() {
|
||||
* return this.max - this.count.value
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const c = new Counter()
|
||||
* const remaining = getComputedInstance(c, 'remaining')
|
||||
* const remaining = getComputedInstance(c, 'getRemaining')
|
||||
* remaining.value === 100 // true
|
||||
* c.count.set(13)
|
||||
* remaining.value === 87 // true
|
||||
|
@ -355,7 +357,7 @@ export function getComputedInstance<Obj extends object, Prop extends keyof Obj>(
|
|||
* console.log(greeting.value) // 'Hello John!'
|
||||
* ```
|
||||
*
|
||||
* `computed` may also be used as a decorator for creating computed class properties.
|
||||
* `computed` may also be used as a decorator for creating computed getter methods.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
|
@ -363,7 +365,7 @@ export function getComputedInstance<Obj extends object, Prop extends keyof Obj>(
|
|||
* max = 100
|
||||
* count = atom<number>(0)
|
||||
*
|
||||
* @computed get remaining() {
|
||||
* @computed getRemaining() {
|
||||
* return this.max - this.count.value
|
||||
* }
|
||||
* }
|
||||
|
@ -378,7 +380,7 @@ export function getComputedInstance<Obj extends object, Prop extends keyof Obj>(
|
|||
* count = atom<number>(0)
|
||||
*
|
||||
* @computed({isEqual: (a, b) => a === b})
|
||||
* get remaining() {
|
||||
* getRemaining() {
|
||||
* return this.max - this.count.value
|
||||
* }
|
||||
* }
|
||||
|
|
|
@ -60,6 +60,7 @@ export class EffectScheduler<Result> {
|
|||
* Whether this scheduler is attached and actively listening to its parents.
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isActivelyListening() {
|
||||
return this._isActivelyListening
|
||||
}
|
||||
|
@ -73,6 +74,7 @@ export class EffectScheduler<Result> {
|
|||
* The number of times this effect has been scheduled.
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get scheduleCount() {
|
||||
return this._scheduleCount
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ class Transaction {
|
|||
*
|
||||
* @public
|
||||
*/
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get isRoot() {
|
||||
return this.parent === null
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ export class StoreSchema<R extends UnknownRecord, P = unknown> {
|
|||
private readonly options: StoreSchemaOptions<R, P>
|
||||
) {}
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
get currentStoreVersion(): number {
|
||||
return this.options.snapshotMigrations?.currentVersion ?? 0
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ export class DraggingHandle extends StateNode {
|
|||
) => {
|
||||
const { shape, isCreating, handle } = info
|
||||
this.info = info
|
||||
this.parent.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
this.shapeId = shape.id
|
||||
this.markId = isCreating ? `creating:${shape.id}` : 'dragging handle'
|
||||
if (!isCreating) this.editor.mark(this.markId)
|
||||
|
@ -166,7 +166,7 @@ export class DraggingHandle extends StateNode {
|
|||
}
|
||||
|
||||
override onExit = () => {
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
this.editor.setHintingShapes([])
|
||||
this.editor.snaps.clear()
|
||||
this.editor.updateInstanceState(
|
||||
|
|
|
@ -22,7 +22,7 @@ export class Idle extends StateNode {
|
|||
static override id = 'idle'
|
||||
|
||||
override onEnter = () => {
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
updateHoveredId(this.editor)
|
||||
this.editor.updateInstanceState(
|
||||
{ cursor: { type: 'default', rotation: 0 } },
|
||||
|
|
|
@ -24,7 +24,7 @@ export class PointingCropHandle extends StateNode {
|
|||
|
||||
override onEnter = (info: TLPointingCropHandleInfo) => {
|
||||
this.info = info
|
||||
this.parent.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
const selectedShape = this.editor.getSelectedShapes()[0]
|
||||
if (!selectedShape) return
|
||||
|
||||
|
@ -37,7 +37,7 @@ export class PointingCropHandle extends StateNode {
|
|||
{ cursor: { type: 'default', rotation: 0 } },
|
||||
{ ephemeral: true }
|
||||
)
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
}
|
||||
|
||||
override onPointerMove: TLEventHandlers['onPointerMove'] = () => {
|
||||
|
|
|
@ -21,13 +21,13 @@ export class PointingRotateHandle extends StateNode {
|
|||
}
|
||||
|
||||
override onEnter = (info: PointingRotateHandleInfo) => {
|
||||
this.parent.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
this.info = info
|
||||
this.updateCursor()
|
||||
}
|
||||
|
||||
override onExit = () => {
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
this.editor.updateInstanceState(
|
||||
{ cursor: { type: 'default', rotation: 0 } },
|
||||
{ ephemeral: true }
|
||||
|
|
|
@ -51,7 +51,7 @@ export class Resizing extends StateNode {
|
|||
|
||||
this.info = info
|
||||
|
||||
this.parent.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
this.editAfterComplete = editAfterComplete
|
||||
this.creationCursorOffset = creationCursorOffset
|
||||
|
||||
|
@ -358,7 +358,7 @@ export class Resizing extends StateNode {
|
|||
}
|
||||
|
||||
override onExit = () => {
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
this.editor.updateInstanceState(
|
||||
{ cursor: { type: 'default', rotation: 0 } },
|
||||
{ ephemeral: true }
|
||||
|
|
|
@ -27,7 +27,7 @@ export class Rotating extends StateNode {
|
|||
) => {
|
||||
// Store the event information
|
||||
this.info = info
|
||||
this.parent.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
|
||||
this.markId = 'rotate start'
|
||||
this.editor.mark(this.markId)
|
||||
|
@ -42,7 +42,7 @@ export class Rotating extends StateNode {
|
|||
|
||||
override onExit = () => {
|
||||
this.editor.setCursor({ type: 'default', rotation: 0 })
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
|
||||
this.snapshot = {} as TLRotationSnapshot
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ export class Translating extends StateNode {
|
|||
const { isCreating = false, editAfterComplete = false } = info
|
||||
|
||||
this.info = info
|
||||
this.parent.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
this.isCreating = isCreating
|
||||
this.editAfterComplete = editAfterComplete
|
||||
|
||||
|
@ -76,7 +76,7 @@ export class Translating extends StateNode {
|
|||
}
|
||||
|
||||
override onExit = () => {
|
||||
this.parent.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
this.editor.off('tick', this.updateParent)
|
||||
this.selectionSnapshot = {} as any
|
||||
this.snapshot = {} as any
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
import {
|
||||
Matrix2d,
|
||||
StateNode,
|
||||
TLArrowShape,
|
||||
TLArrowShapeTerminal,
|
||||
TLCancelEvent,
|
||||
TLEnterEventHandler,
|
||||
TLEventHandlers,
|
||||
TLHandle,
|
||||
TLKeyboardEvent,
|
||||
TLPointerEventInfo,
|
||||
TLShapeId,
|
||||
TLShapePartial,
|
||||
Vec2d,
|
||||
deepCopy,
|
||||
snapAngle,
|
||||
sortByIndex,
|
||||
} from '@tldraw/editor'
|
||||
|
||||
export class DraggingHandle extends StateNode {
|
||||
static override id = 'dragging_handle'
|
||||
|
||||
shapeId = '' as TLShapeId
|
||||
initialHandle = {} as TLHandle
|
||||
initialAdjacentHandle = null as TLHandle | null
|
||||
initialPagePoint = {} as Vec2d
|
||||
|
||||
markId = ''
|
||||
initialPageTransform: any
|
||||
initialPageRotation: any
|
||||
|
||||
info = {} as TLPointerEventInfo & {
|
||||
shape: TLArrowShape
|
||||
target: 'handle'
|
||||
onInteractionEnd?: string
|
||||
isCreating: boolean
|
||||
}
|
||||
|
||||
isPrecise = false
|
||||
isPreciseId = null as TLShapeId | null
|
||||
pointingId = null as TLShapeId | null
|
||||
|
||||
override onEnter: TLEnterEventHandler = (
|
||||
info: TLPointerEventInfo & {
|
||||
shape: TLArrowShape
|
||||
target: 'handle'
|
||||
onInteractionEnd?: string
|
||||
isCreating: boolean
|
||||
}
|
||||
) => {
|
||||
const { shape, isCreating, handle } = info
|
||||
this.info = info
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
this.shapeId = shape.id
|
||||
this.markId = isCreating ? `creating:${shape.id}` : 'dragging handle'
|
||||
if (!isCreating) this.editor.mark(this.markId)
|
||||
this.initialHandle = deepCopy(handle)
|
||||
this.initialPageTransform = this.editor.getShapePageTransform(shape)!
|
||||
this.initialPageRotation = this.initialPageTransform.rotation()
|
||||
this.initialPagePoint = this.editor.inputs.originPagePoint.clone()
|
||||
|
||||
this.editor.updateInstanceState(
|
||||
{ cursor: { type: isCreating ? 'cross' : 'grabbing', rotation: 0 } },
|
||||
{ ephemeral: true }
|
||||
)
|
||||
|
||||
// <!-- Only relevant to arrows
|
||||
const handles = this.editor.getShapeHandles(shape)!.sort(sortByIndex)
|
||||
const index = handles.findIndex((h) => h.id === info.handle.id)
|
||||
|
||||
// Find the adjacent handle
|
||||
this.initialAdjacentHandle = null
|
||||
|
||||
// Start from the handle and work forward
|
||||
for (let i = index + 1; i < handles.length; i++) {
|
||||
const handle = handles[i]
|
||||
if (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {
|
||||
this.initialAdjacentHandle = handle
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If still no handle, start from the end and work backward
|
||||
if (!this.initialAdjacentHandle) {
|
||||
for (let i = handles.length - 1; i >= 0; i--) {
|
||||
const handle = handles[i]
|
||||
if (handle.type === 'vertex' && handle.id !== 'middle' && handle.id !== info.handle.id) {
|
||||
this.initialAdjacentHandle = handle
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const initialTerminal = shape.props[info.handle.id as 'start' | 'end']
|
||||
|
||||
this.isPrecise = false
|
||||
|
||||
if (initialTerminal?.type === 'binding') {
|
||||
this.editor.setHintingShapes([initialTerminal.boundShapeId])
|
||||
|
||||
this.isPrecise = !Vec2d.Equals(initialTerminal.normalizedAnchor, { x: 0.5, y: 0.5 })
|
||||
if (this.isPrecise) {
|
||||
this.isPreciseId = initialTerminal.boundShapeId
|
||||
} else {
|
||||
this.resetExactTimeout()
|
||||
}
|
||||
} else {
|
||||
this.editor.setHintingShapes([])
|
||||
}
|
||||
// -->
|
||||
|
||||
this.update()
|
||||
|
||||
this.editor.select(this.shapeId)
|
||||
}
|
||||
|
||||
// Only relevant to arrows
|
||||
private exactTimeout = -1 as any
|
||||
|
||||
// Only relevant to arrows
|
||||
private resetExactTimeout() {
|
||||
if (this.exactTimeout !== -1) {
|
||||
this.clearExactTimeout()
|
||||
}
|
||||
|
||||
this.exactTimeout = setTimeout(() => {
|
||||
if (this.getIsActive() && !this.isPrecise) {
|
||||
this.isPrecise = true
|
||||
this.isPreciseId = this.pointingId
|
||||
this.update()
|
||||
}
|
||||
this.exactTimeout = -1
|
||||
}, 750)
|
||||
}
|
||||
|
||||
// Only relevant to arrows
|
||||
private clearExactTimeout() {
|
||||
if (this.exactTimeout !== -1) {
|
||||
clearTimeout(this.exactTimeout)
|
||||
this.exactTimeout = -1
|
||||
}
|
||||
}
|
||||
|
||||
override onPointerMove: TLEventHandlers['onPointerMove'] = () => {
|
||||
this.update()
|
||||
}
|
||||
|
||||
override onKeyDown: TLKeyboardEvent | undefined = () => {
|
||||
this.update()
|
||||
}
|
||||
|
||||
override onKeyUp: TLKeyboardEvent | undefined = () => {
|
||||
this.update()
|
||||
}
|
||||
|
||||
override onPointerUp: TLEventHandlers['onPointerUp'] = () => {
|
||||
this.complete()
|
||||
}
|
||||
|
||||
override onComplete: TLEventHandlers['onComplete'] = () => {
|
||||
this.complete()
|
||||
}
|
||||
|
||||
override onCancel: TLCancelEvent = () => {
|
||||
this.cancel()
|
||||
}
|
||||
|
||||
override onExit = () => {
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
this.editor.setHintingShapes([])
|
||||
this.editor.snaps.clear()
|
||||
this.editor.updateInstanceState(
|
||||
{ cursor: { type: 'default', rotation: 0 } },
|
||||
{ ephemeral: true }
|
||||
)
|
||||
}
|
||||
|
||||
private complete() {
|
||||
this.editor.snaps.clear()
|
||||
|
||||
const { onInteractionEnd } = this.info
|
||||
if (this.editor.getInstanceState().isToolLocked && onInteractionEnd) {
|
||||
// Return to the tool that was active before this one,
|
||||
// but only if tool lock is turned on!
|
||||
this.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId })
|
||||
return
|
||||
}
|
||||
|
||||
this.parent.transition('idle')
|
||||
}
|
||||
|
||||
private cancel() {
|
||||
this.editor.bailToMark(this.markId)
|
||||
this.editor.snaps.clear()
|
||||
|
||||
const { onInteractionEnd } = this.info
|
||||
if (onInteractionEnd) {
|
||||
// Return to the tool that was active before this one,
|
||||
// whether tool lock is turned on or not!
|
||||
this.editor.setCurrentTool(onInteractionEnd, { shapeId: this.shapeId })
|
||||
return
|
||||
}
|
||||
|
||||
this.parent.transition('idle')
|
||||
}
|
||||
|
||||
private update() {
|
||||
const { editor, shapeId, initialPagePoint } = this
|
||||
const { initialHandle, initialPageRotation, initialAdjacentHandle } = this
|
||||
const hintingShapeIds = this.editor.getHintingShapeIds()
|
||||
const {
|
||||
user: { isSnapMode },
|
||||
snaps,
|
||||
inputs: { currentPagePoint, shiftKey, ctrlKey, altKey, pointerVelocity },
|
||||
} = editor
|
||||
|
||||
const initial = this.info.shape
|
||||
const shape = editor.getShape(shapeId)
|
||||
if (!shape) return
|
||||
const util = editor.getShapeUtil(shape)
|
||||
|
||||
let point = currentPagePoint
|
||||
.clone()
|
||||
.sub(initialPagePoint)
|
||||
.rot(-initialPageRotation)
|
||||
.add(initialHandle)
|
||||
|
||||
if (shiftKey && initialAdjacentHandle && initialHandle.id !== 'middle') {
|
||||
const angle = Vec2d.Angle(initialAdjacentHandle, point)
|
||||
const snappedAngle = snapAngle(angle, 24)
|
||||
const angleDifference = snappedAngle - angle
|
||||
point = Vec2d.RotWith(point, initialAdjacentHandle, angleDifference)
|
||||
}
|
||||
|
||||
// Clear any existing snaps
|
||||
editor.snaps.clear()
|
||||
|
||||
if (initialHandle.canSnap && (isSnapMode ? !ctrlKey : ctrlKey)) {
|
||||
// We're snapping
|
||||
const pageTransform = editor.getShapePageTransform(shape.id)
|
||||
if (!pageTransform) throw Error('Expected a page transform')
|
||||
|
||||
// We want to skip the segments that include the handle, so
|
||||
// find the index of the handle that shares the same index property
|
||||
// as the initial dragging handle; this catches a quirk of create handles
|
||||
const handleIndex = editor
|
||||
.getShapeHandles(shape)!
|
||||
.filter(({ type }) => type === 'vertex')
|
||||
.sort(sortByIndex)
|
||||
.findIndex(({ index }) => initialHandle.index === index)
|
||||
|
||||
// Get all the outline segments from the shape
|
||||
const additionalSegments = util
|
||||
.getOutlineSegments(shape)
|
||||
.map((segment) => Matrix2d.applyToPoints(pageTransform, segment))
|
||||
.filter((_segment, i) => i !== handleIndex - 1 && i !== handleIndex)
|
||||
|
||||
const snapDelta = snaps.getSnappingHandleDelta({
|
||||
additionalSegments,
|
||||
handlePoint: Matrix2d.applyToPoint(pageTransform, point),
|
||||
})
|
||||
|
||||
if (snapDelta) {
|
||||
snapDelta.rot(-editor.getShapeParentTransform(shape)!.rotation())
|
||||
point.add(snapDelta)
|
||||
}
|
||||
}
|
||||
|
||||
const changes = util.onHandleChange?.(shape, {
|
||||
handle: {
|
||||
...initialHandle,
|
||||
x: point.x,
|
||||
y: point.y,
|
||||
},
|
||||
isPrecise: this.isPrecise || altKey,
|
||||
initial: initial,
|
||||
})
|
||||
|
||||
const next: TLShapePartial<any> = { ...shape, ...changes }
|
||||
|
||||
// Arrows
|
||||
if (initialHandle.canBind) {
|
||||
const bindingAfter = (next.props as any)[initialHandle.id] as TLArrowShapeTerminal | undefined
|
||||
|
||||
if (bindingAfter?.type === 'binding') {
|
||||
if (hintingShapeIds[0] !== bindingAfter.boundShapeId) {
|
||||
editor.setHintingShapes([bindingAfter.boundShapeId])
|
||||
this.pointingId = bindingAfter.boundShapeId
|
||||
this.isPrecise = pointerVelocity.len() < 0.5 || altKey
|
||||
this.isPreciseId = this.isPrecise ? bindingAfter.boundShapeId : null
|
||||
this.resetExactTimeout()
|
||||
}
|
||||
} else {
|
||||
if (hintingShapeIds.length > 0) {
|
||||
editor.setHintingShapes([])
|
||||
this.pointingId = null
|
||||
this.isPrecise = false
|
||||
this.isPreciseId = null
|
||||
this.resetExactTimeout()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changes) {
|
||||
editor.updateShapes([next], { squashing: true })
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,17 +13,17 @@ export class ZoomTool extends StateNode {
|
|||
|
||||
override onEnter = (info: TLPointerEventInfo & { onInteractionEnd: string }) => {
|
||||
this.info = info
|
||||
this.currentToolIdMask = info.onInteractionEnd
|
||||
this.parent.setCurrentToolIdMask(info.onInteractionEnd)
|
||||
this.updateCursor()
|
||||
}
|
||||
|
||||
override onExit = () => {
|
||||
this.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
this.editor.updateInstanceState(
|
||||
{ zoomBrush: null, cursor: { type: 'default', rotation: 0 } },
|
||||
{ ephemeral: true }
|
||||
)
|
||||
this.currentToolIdMask = undefined
|
||||
this.parent.setCurrentToolIdMask(undefined)
|
||||
}
|
||||
|
||||
override onKeyDown: TLKeyboardEvent | undefined = () => {
|
||||
|
|
|
@ -477,7 +477,11 @@ export class TestEditor extends Editor {
|
|||
.clone()
|
||||
.rotWith(this.getSelectionRotatedPageBounds()!.point, this.getSelectionRotation())
|
||||
|
||||
const targetHandlePoint = Vec2d.RotWith(handlePoint, this.selectionPageCenter!, angleRadians)
|
||||
const targetHandlePoint = Vec2d.RotWith(
|
||||
handlePoint,
|
||||
this.getSelectionPageCenter()!,
|
||||
angleRadians
|
||||
)
|
||||
|
||||
this.pointerDown(handlePoint.x, handlePoint.y, { target: 'selection', handle })
|
||||
this.pointerMove(targetHandlePoint.x, targetHandlePoint.y, { shiftKey })
|
||||
|
@ -491,7 +495,7 @@ export class TestEditor extends Editor {
|
|||
* @readonly
|
||||
* @public
|
||||
*/
|
||||
get selectionPageCenter() {
|
||||
getSelectionPageCenter() {
|
||||
const selectionRotation = this.getSelectionRotation()
|
||||
const selectionBounds = this.getSelectionRotatedPageBounds()
|
||||
if (!selectionBounds) return null
|
||||
|
@ -504,7 +508,7 @@ export class TestEditor extends Editor {
|
|||
}
|
||||
this.setCurrentTool('select')
|
||||
|
||||
const center = this.selectionPageCenter!
|
||||
const center = this.getSelectionPageCenter()!
|
||||
|
||||
this.pointerDown(center.x, center.y, this.getSelectedShapeIds()[0])
|
||||
const numSteps = 10
|
||||
|
|
|
@ -61,25 +61,25 @@ describe('Editor.moveShapesToPage', () => {
|
|||
it('Adds undo items', () => {
|
||||
editor.history.clear()
|
||||
editor.moveShapesToPage([ids.box1], ids.page2)
|
||||
expect(editor.history.numUndos).toBeGreaterThan(1)
|
||||
expect(editor.history.getNumUndos()).toBeGreaterThan(1)
|
||||
})
|
||||
|
||||
it('Does nothing on an empty ids array', () => {
|
||||
editor.history.clear()
|
||||
editor.moveShapesToPage([], ids.page2)
|
||||
expect(editor.history.numUndos).toBe(0)
|
||||
expect(editor.history.getNumUndos()).toBe(0)
|
||||
})
|
||||
|
||||
it('Does nothing if the new page is not found or is deleted', () => {
|
||||
editor.history.clear()
|
||||
editor.moveShapesToPage([ids.box1], PageRecordType.createId('missing'))
|
||||
expect(editor.history.numUndos).toBe(0)
|
||||
expect(editor.history.getNumUndos()).toBe(0)
|
||||
})
|
||||
|
||||
it('Does not move shapes to the current page', () => {
|
||||
editor.history.clear()
|
||||
editor.moveShapesToPage([ids.box1], ids.page1)
|
||||
expect(editor.history.numUndos).toBe(0)
|
||||
expect(editor.history.getNumUndos()).toBe(0)
|
||||
})
|
||||
|
||||
it('Restores on undo / redo', () => {
|
||||
|
|
|
@ -24,13 +24,13 @@ describe('resizing a shape', () => {
|
|||
editor.createShapes([{ id: ids.boxA, type: 'geo', props: { w: 100, h: 100 } }])
|
||||
|
||||
editor.mark('start')
|
||||
const startHistoryLength = editor.history.numUndos
|
||||
const startHistoryLength = editor.history.getNumUndos()
|
||||
editor.resizeShape(ids.boxA, { x: 2, y: 2 })
|
||||
expect(editor.history.numUndos).toBe(startHistoryLength + 1)
|
||||
expect(editor.history.getNumUndos()).toBe(startHistoryLength + 1)
|
||||
editor.resizeShape(ids.boxA, { x: 2, y: 2 })
|
||||
expect(editor.history.numUndos).toBe(startHistoryLength + 1)
|
||||
expect(editor.history.getNumUndos()).toBe(startHistoryLength + 1)
|
||||
editor.resizeShape(ids.boxA, { x: 2, y: 2 })
|
||||
expect(editor.history.numUndos).toBe(startHistoryLength + 1)
|
||||
expect(editor.history.getNumUndos()).toBe(startHistoryLength + 1)
|
||||
|
||||
expect(editor.getShapePageBounds(ids.boxA)).toCloselyMatchObject({
|
||||
w: 800,
|
||||
|
|
|
@ -57,7 +57,7 @@ describe('editor.rotateShapes', () => {
|
|||
// Select the shape...
|
||||
editor.select(ids.box1, ids.box2)
|
||||
|
||||
const { selectionPageCenter } = editor
|
||||
const selectionPageCenter = editor.getSelectionPageCenter()
|
||||
|
||||
// Rotate the shape...
|
||||
editor.rotateShapesBy(editor.getSelectedShapeIds(), Math.PI)
|
||||
|
@ -77,6 +77,6 @@ describe('editor.rotateShapes', () => {
|
|||
.expectShapeToMatch({ id: ids.box2, rotation: Math.PI })
|
||||
|
||||
// Are the centers the same?
|
||||
expect(selectionPageCenter).toCloselyMatchObject(editor.selectionPageCenter!)
|
||||
expect(selectionPageCenter).toCloselyMatchObject(editor.getSelectionPageCenter()!)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -53,7 +53,7 @@ describe('setCurrentPage', () => {
|
|||
editor.setCurrentPage(editor.getPages()[1].id)
|
||||
editor.setCurrentPage(editor.getPages()[0].id)
|
||||
editor.setCurrentPage(editor.getPages()[0].id)
|
||||
expect(editor.history.numUndos).toBe(1)
|
||||
expect(editor.history.getNumUndos()).toBe(1)
|
||||
})
|
||||
|
||||
it('preserves the undo stack', () => {
|
||||
|
@ -68,7 +68,7 @@ describe('setCurrentPage', () => {
|
|||
editor.setCurrentPage(editor.getPages()[0].id)
|
||||
editor.setCurrentPage(editor.getPages()[0].id)
|
||||
expect(editor.getShape(boxId)).toBeUndefined()
|
||||
expect(editor.history.numUndos).toBe(1)
|
||||
expect(editor.history.getNumUndos()).toBe(1)
|
||||
editor.redo()
|
||||
expect(editor.getShape(boxId)).not.toBeUndefined()
|
||||
})
|
||||
|
|
|
@ -127,7 +127,7 @@ describe('creating frames', () => {
|
|||
|
||||
// x should snap
|
||||
editor.keyDown('Control')
|
||||
expect(editor.snaps.lines).toHaveLength(1)
|
||||
expect(editor.snaps.getLines()).toHaveLength(1)
|
||||
expect(editor.getShapePageBounds(editor.getOnlySelectedShape()!)).toMatchObject({
|
||||
x: 50,
|
||||
y: 100,
|
||||
|
@ -346,7 +346,7 @@ describe('frame shapes', () => {
|
|||
expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ y: 49 })
|
||||
editor.keyDown('Control')
|
||||
expect(editor.getShapePageBounds(ids.boxA)).toMatchObject({ y: 50 })
|
||||
expect(editor.snaps.lines).toHaveLength(1)
|
||||
expect(editor.snaps.getLines()).toHaveLength(1)
|
||||
})
|
||||
|
||||
it("does not allow outside shapes to snap to the frame's children", () => {
|
||||
|
@ -382,12 +382,12 @@ describe('frame shapes', () => {
|
|||
w: 5,
|
||||
h: 5,
|
||||
})
|
||||
expect(editor.snaps.lines).toHaveLength(0)
|
||||
expect(editor.snaps.getLines()).toHaveLength(0)
|
||||
// and if we unparent the box it should snap
|
||||
editor.reparentShapes([innerBoxId], editor.currentPageId)
|
||||
|
||||
editor.pointerMove(287.5, 126.5).pointerMove(277.5, 126.5)
|
||||
expect(editor.snaps.lines).toHaveLength(1)
|
||||
expect(editor.snaps.getLines()).toHaveLength(1)
|
||||
expect(editor.getShapePageBounds(editor.getOnlySelectedShape()!)).toMatchObject({
|
||||
x: 275,
|
||||
y: 125,
|
||||
|
@ -414,12 +414,12 @@ describe('frame shapes', () => {
|
|||
editor.setCurrentTool('select')
|
||||
editor.pointerDown(150, 150, innerBoxId).pointerMove(150, 50).pointerMove(150, 148)
|
||||
editor.keyDown('Control')
|
||||
expect(editor.snaps.lines).toHaveLength(0)
|
||||
expect(editor.snaps.getLines()).toHaveLength(0)
|
||||
|
||||
// move shape inside the frame to make sure it snaps in there
|
||||
editor.reparentShapes([outerBoxId], frameId).pointerMove(150, 149, { ctrlKey: true })
|
||||
|
||||
expect(editor.snaps.lines).toHaveLength(1)
|
||||
expect(editor.snaps.getLines()).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('masks its children', () => {
|
||||
|
|
|
@ -8,7 +8,7 @@ const simplifyNumber = (n: number) => {
|
|||
}
|
||||
export const getSnapLines = (scene: Editor) => {
|
||||
const result = []
|
||||
for (const snap of scene.snaps.lines) {
|
||||
for (const snap of scene.snaps.getLines()) {
|
||||
if (snap.type !== 'points') {
|
||||
throw new Error('Expected only points snap')
|
||||
}
|
||||
|
|
|
@ -1922,14 +1922,14 @@ describe('snapping', () => {
|
|||
editor.select(groupCId)
|
||||
editor.pointerDown(10, 5, groupCId)
|
||||
editor.pointerMove(80, 5, groupCId, { ctrlKey: true })
|
||||
expect(editor.snaps.lines.length).toBe(0)
|
||||
expect(editor.snaps.getLines().length).toBe(0)
|
||||
})
|
||||
|
||||
it('does not happen between children and thier group', () => {
|
||||
editor.select(ids.boxD)
|
||||
editor.pointerDown(65, 5, ids.boxD)
|
||||
editor.pointerMove(80, 105, ids.boxD, { ctrlKey: true })
|
||||
expect(editor.snaps.lines.length).toBe(0)
|
||||
expect(editor.snaps.getLines().length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ describe('When pasting', () => {
|
|||
|
||||
// Should put the pasted shapes centered in the frame
|
||||
editor.select(shapes.new.box1!.id, shapes.new.box1!.id)
|
||||
expect(editor.selectionPageCenter).toMatchObject(
|
||||
expect(editor.getSelectionPageCenter()).toMatchObject(
|
||||
editor.getPageCenter(editor.getShape(ids.frame1)!)!
|
||||
)
|
||||
})
|
||||
|
@ -317,7 +317,7 @@ describe('When pasting', () => {
|
|||
|
||||
// Should put the pasted shapes centered in the frame
|
||||
editor.select(shapes.new.box1!.id, shapes.new.box1!.id)
|
||||
expect(editor.selectionPageCenter).toMatchObject(editor.getPageCenter(shapes.old.frame1)!)
|
||||
expect(editor.getSelectionPageCenter()).toMatchObject(editor.getPageCenter(shapes.old.frame1)!)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -940,8 +940,10 @@ describe('When resizing a shape with children', () => {
|
|||
})
|
||||
|
||||
function getGapAndPointLines() {
|
||||
const gapLines = editor.snaps.lines.filter((snap) => snap.type === 'gaps') as GapsSnapLine[]
|
||||
const pointLines = editor.snaps.lines.filter((snap) => snap.type === 'points') as PointsSnapLine[]
|
||||
const gapLines = editor.snaps.getLines().filter((snap) => snap.type === 'gaps') as GapsSnapLine[]
|
||||
const pointLines = editor.snaps
|
||||
.getLines()
|
||||
.filter((snap) => snap.type === 'points') as PointsSnapLine[]
|
||||
return { gapLines, pointLines }
|
||||
}
|
||||
|
||||
|
@ -985,12 +987,12 @@ describe('snapping while resizing', () => {
|
|||
.pointerMove(115, 59, { ctrlKey: true })
|
||||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 60, props: { w: 60, h: 80 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
// moving the mouse horizontally should not change things
|
||||
editor.pointerMove(15, 65, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 60, props: { w: 60, h: 80 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(6)
|
||||
|
||||
|
@ -998,7 +1000,7 @@ describe('snapping while resizing', () => {
|
|||
editor.pointerMove(15, 43, { ctrlKey: true })
|
||||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 40, props: { w: 60, h: 100 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(4)
|
||||
})
|
||||
|
@ -1015,7 +1017,7 @@ describe('snapping while resizing', () => {
|
|||
.pointerMove(156, 115, { ctrlKey: true })
|
||||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 80, props: { w: 80, h: 60 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(6)
|
||||
|
||||
|
@ -1026,7 +1028,7 @@ describe('snapping while resizing', () => {
|
|||
// snap to left edge of B
|
||||
editor.pointerMove(173, 280, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 80, props: { w: 100, h: 60 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(4)
|
||||
})
|
||||
|
||||
|
@ -1041,19 +1043,19 @@ describe('snapping while resizing', () => {
|
|||
.pointerMove(115, 159, { ctrlKey: true })
|
||||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 80, props: { w: 60, h: 80 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(6)
|
||||
|
||||
// changing horzontal mouse position should not change things
|
||||
editor.pointerMove(315, 163, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 80, props: { w: 60, h: 80 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
// snap to top edge of C
|
||||
editor.pointerMove(115, 183, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 80, y: 80, props: { w: 60, h: 100 } })
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(4)
|
||||
})
|
||||
|
@ -1070,7 +1072,7 @@ describe('snapping while resizing', () => {
|
|||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 60, y: 80, props: { w: 80, h: 60 } })
|
||||
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(6)
|
||||
|
||||
// moving the mouse vertically should not change things
|
||||
|
@ -1081,7 +1083,7 @@ describe('snapping while resizing', () => {
|
|||
editor.pointerMove(39, 280, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 40, y: 80, props: { w: 100, h: 60 } })
|
||||
|
||||
expect(editor.snaps.lines.length).toBe(1)
|
||||
expect(editor.snaps.getLines().length).toBe(1)
|
||||
expect(getGapAndPointLines().pointLines[0].points).toHaveLength(4)
|
||||
})
|
||||
it('works for dragging the top left corner', () => {
|
||||
|
@ -3020,7 +3022,7 @@ describe('resizing a shape with a child', () => {
|
|||
.pointerDown(0, 0, { target: 'selection', handle: 'top_left' })
|
||||
.pointerMove(25, 25, { ctrlKey: true })
|
||||
|
||||
expect(editor.snaps.lines.length).toBe(0)
|
||||
expect(editor.snaps.getLines().length).toBe(0)
|
||||
expect(editor.getShape(ids.boxA)).toMatchObject({ x: 25, y: 25, props: { w: 25, h: 25 } })
|
||||
expect(editor.getShape(ids.boxB)).toMatchObject({ x: 0.5, y: 0.5, props: { w: 5, h: 5 } })
|
||||
expect(editor.getShapePageBounds(ids.boxB)).toMatchObject({
|
||||
|
|
|
@ -8,7 +8,7 @@ const simplifyNumber = (n: number) => {
|
|||
}
|
||||
export const getSnapLines = (scene: Editor) => {
|
||||
const result = []
|
||||
for (const snap of scene.snaps.lines) {
|
||||
for (const snap of scene.snaps.getLines()) {
|
||||
if (snap.type !== 'points') {
|
||||
throw new Error('Expected only points snap')
|
||||
}
|
||||
|
|
|
@ -117,8 +117,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘ x───────x
|
||||
editor.pointerDown(250, 250, ids.box1).pointerMove(250, 51, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 200, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should not snap to 100 on y axis
|
||||
// x───────┐
|
||||
|
@ -132,7 +132,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(250, 151, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 200, y: 101 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
|
||||
// should not snap to 50 on y axis
|
||||
// x───────┐
|
||||
|
@ -144,7 +144,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(250, 101, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 200, y: 51 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
|
||||
// should snap to 0 on x axis
|
||||
// x x───────┐
|
||||
|
@ -160,8 +160,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x x───────x
|
||||
editor.pointerMove(51, 250, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 0, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should not snap to 100 on x axis
|
||||
// x───────┐
|
||||
|
@ -177,7 +177,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(151, 250, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 101, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
|
||||
// should not snap to 50 on x axis
|
||||
// x───────┐
|
||||
|
@ -193,7 +193,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(101, 250, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 51, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
})
|
||||
|
||||
it('allows shapes with custom points to snap to other shapes', () => {
|
||||
|
@ -206,8 +206,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘ x───────x
|
||||
editor.pointerDown(50, 50, ids.boxT).pointerMove(50, 251, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 0, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should snap to 250 on y axis
|
||||
// x─────────────────x
|
||||
|
@ -220,8 +220,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘
|
||||
editor.pointerMove(50, 301, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 0, y: 250 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(2)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(2)
|
||||
|
||||
// should snap to 300 on y axis
|
||||
// x─────────────x───────x
|
||||
|
@ -236,8 +236,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘
|
||||
editor.pointerMove(50, 351, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 0, y: 300 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should snap to 200 on x axis
|
||||
// x x───────┐
|
||||
|
@ -253,8 +253,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x x───────x
|
||||
editor.pointerMove(251, 50, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 200, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should snap to 250 on x axis
|
||||
// x x───────┐
|
||||
|
@ -270,8 +270,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(301, 50, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 250, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(2)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(2)
|
||||
|
||||
// should snap to 300 on x axis
|
||||
// x x───────┐
|
||||
|
@ -287,8 +287,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x x───────x
|
||||
editor.pointerMove(351, 50, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 300, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
})
|
||||
|
||||
it('becomes part of the selection bounding box if there is more than one shape in the selection', () => {
|
||||
|
@ -315,9 +315,9 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.select(ids.boxT, ids.box1)
|
||||
editor.pointerDown(50, 50, ids.boxT).pointerMove(351, 50, { ctrlKey: true })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(2)
|
||||
expect(getSnapPoints(editor.snaps.lines![0])?.map(({ x }) => x)).toEqual([450, 450])
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(2)
|
||||
expect(getSnapPoints(editor.snaps.getLines()![0])?.map(({ x }) => x)).toEqual([450, 450])
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -379,8 +379,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘ x───────x
|
||||
editor.pointerDown(250, 250, ids.box1).pointerMove(250, 51, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 200, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should not snap to 100 on y axis
|
||||
// x───────┐
|
||||
|
@ -394,7 +394,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(250, 151, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 200, y: 101 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
|
||||
// should not snap to 50 on y axis
|
||||
// x───────┐
|
||||
|
@ -406,7 +406,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(250, 101, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 200, y: 51 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
|
||||
// should snap to 0 on x axis
|
||||
// x x───────┐
|
||||
|
@ -422,8 +422,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x x───────x
|
||||
editor.pointerMove(51, 250, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 0, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should not snap to 100 on x axis
|
||||
// x───────┐
|
||||
|
@ -439,7 +439,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(151, 250, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 101, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
|
||||
// should not snap to 50 on x axis
|
||||
// x───────┐
|
||||
|
@ -455,7 +455,7 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(101, 250, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({ x: 51, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
})
|
||||
|
||||
it('allows shapes with custom points to snap to other shapes', () => {
|
||||
|
@ -468,8 +468,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘ x───────x
|
||||
editor.pointerDown(50, 50, ids.boxT).pointerMove(50, 251, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 0, y: 200 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should snap to 250 on y axis
|
||||
// x─────────────────x
|
||||
|
@ -482,8 +482,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘
|
||||
editor.pointerMove(50, 301, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 0, y: 250 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(2)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(2)
|
||||
|
||||
// should snap to 300 on y axis
|
||||
// x─────────────x───────x
|
||||
|
@ -498,8 +498,8 @@ describe.skip('custom snapping points', () => {
|
|||
// └───────┘
|
||||
editor.pointerMove(50, 351, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 0, y: 300 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should snap to 200 on x axis
|
||||
// x x───────┐
|
||||
|
@ -515,8 +515,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x x───────x
|
||||
editor.pointerMove(251, 50, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 200, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
|
||||
// should snap to 250 on x axis
|
||||
// x x───────┐
|
||||
|
@ -532,8 +532,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.pointerMove(301, 50, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 250, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(2)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(2)
|
||||
|
||||
// should snap to 300 on x axis
|
||||
// x x───────┐
|
||||
|
@ -549,8 +549,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x x───────x
|
||||
editor.pointerMove(351, 50, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxT)).toMatchObject({ x: 300, y: 0 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(3)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(3)
|
||||
})
|
||||
|
||||
it('becomes part of the selection bounding box if there is more than one shape in the selection', () => {
|
||||
|
@ -577,8 +577,8 @@ describe.skip('custom snapping points', () => {
|
|||
// x───────x
|
||||
editor.select(ids.boxT, ids.box1)
|
||||
editor.pointerDown(50, 50, ids.boxT).pointerMove(351, 50, { ctrlKey: true })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(2)
|
||||
expect(getSnapPoints(editor.snaps.lines![0])?.map(({ x }) => x)).toEqual([450, 450])
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(2)
|
||||
expect(getSnapPoints(editor.snaps.getLines()![0])?.map(({ x }) => x)).toEqual([450, 450])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -510,9 +510,9 @@ describe('snapping with single shapes', () => {
|
|||
// ┼ └──────┘
|
||||
|
||||
editor.pointerDown(25, 5, ids.box2).pointerMove(16, 35, { ctrlKey: true })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
|
||||
expect(getNumSnapPoints(editor.snaps.lines![0])).toBe(4)
|
||||
expect(getNumSnapPoints(editor.snaps.getLines()![0])).toBe(4)
|
||||
})
|
||||
|
||||
it('shows all the horizonal lines + points where the bounding boxes align', () => {
|
||||
|
@ -523,7 +523,7 @@ describe('snapping with single shapes', () => {
|
|||
// x─────x────────────────────x─────x
|
||||
editor.pointerDown(25, 5, ids.box2).pointerMove(36, 5, { ctrlKey: true })
|
||||
|
||||
const snaps = editor.snaps.lines!.sort((a, b) => getNumSnapPoints(a) - getNumSnapPoints(b))
|
||||
const snaps = editor.snaps.getLines()!.sort((a, b) => getNumSnapPoints(a) - getNumSnapPoints(b))
|
||||
expect(snaps.length).toBe(3)
|
||||
|
||||
// center snap line
|
||||
|
@ -544,7 +544,7 @@ describe('snapping with single shapes', () => {
|
|||
// x └─────┘ x
|
||||
editor.pointerDown(25, 5, ids.box2).pointerMove(5, 45, { ctrlKey: true })
|
||||
|
||||
const snaps = editor.snaps.lines!.sort((a, b) => getNumSnapPoints(a) - getNumSnapPoints(b))
|
||||
const snaps = editor.snaps.getLines()!.sort((a, b) => getNumSnapPoints(a) - getNumSnapPoints(b))
|
||||
expect(snaps.length).toBe(3)
|
||||
|
||||
// center snap line
|
||||
|
@ -560,23 +560,23 @@ describe('snapping with single shapes', () => {
|
|||
editor.updateShapes([{ id: ids.box1, type: 'geo', x: -20 }])
|
||||
|
||||
editor.pointerDown(25, 5, ids.box2).pointerMove(36, 5, { ctrlKey: true })
|
||||
expect(editor.snaps.lines!.length).toBe(0)
|
||||
expect(editor.snaps.getLines()!.length).toBe(0)
|
||||
|
||||
editor.updateShapes([{ id: ids.box1, type: 'geo', x: editor.getViewportScreenBounds().w + 10 }])
|
||||
editor.pointerMove(33, 5, { ctrlKey: true })
|
||||
|
||||
expect(editor.snaps.lines!.length).toBe(0)
|
||||
expect(editor.snaps.getLines()!.length).toBe(0)
|
||||
editor.updateShapes([{ id: ids.box1, type: 'geo', y: -20 }])
|
||||
|
||||
editor.pointerMove(5, 5, { ctrlKey: true })
|
||||
expect(editor.snaps.lines!.length).toBe(0)
|
||||
expect(editor.snaps.getLines()!.length).toBe(0)
|
||||
|
||||
editor.updateShapes([
|
||||
{ id: ids.box1, type: 'geo', x: 0, y: editor.getViewportScreenBounds().h + 10 },
|
||||
])
|
||||
|
||||
editor.pointerMove(5, 5, { ctrlKey: true })
|
||||
expect(editor.snaps.lines!.length).toBe(0)
|
||||
expect(editor.snaps.getLines()!.length).toBe(0)
|
||||
})
|
||||
|
||||
it('does not snap on the Y axis if the shift key is pressed', () => {
|
||||
|
@ -740,9 +740,10 @@ describe('Snap-between behavior', () => {
|
|||
// the midpoint is 125 and c is 10 wide so it should snap to 120 if we put it at 121
|
||||
editor.pointerDown(55, 5, ids.line1).pointerMove(126, 67, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 120, y: 62 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
assertGaps(editor.snaps.lines![0])
|
||||
expect(editor.snaps.lines![0].gaps.length).toBe(2)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
const line = editor.snaps.getLines()![0]
|
||||
assertGaps(line)
|
||||
expect(line.gaps.length).toBe(2)
|
||||
})
|
||||
it('shows horizontal point snaps at the same time as horizontal gap snaps', () => {
|
||||
// ┌─────┐ ┌─────┐
|
||||
|
@ -763,7 +764,7 @@ describe('Snap-between behavior', () => {
|
|||
|
||||
editor.pointerDown(55, 5, ids.line1).pointerMove(126, 94, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 120, y: 90 })
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(pointLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps.length).toBe(2)
|
||||
|
@ -793,7 +794,7 @@ describe('Snap-between behavior', () => {
|
|||
// the midpoint is 125 and c is 10 wide so it should snap to 120 if we put it at 121
|
||||
editor.pointerDown(55, 5, ids.line1).pointerMove(126, 67, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 120, y: 62 })
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(pointLines).toHaveLength(1)
|
||||
|
||||
|
@ -828,9 +829,9 @@ describe('Snap-between behavior', () => {
|
|||
// the midpoint is 125 and c is 10 wide so it should snap to 120 if we put it at 121
|
||||
editor.pointerDown(55, 155, ids.line1).pointerMove(27, 126, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 22, y: 120 })
|
||||
expect(editor.snaps.lines?.length).toBe(1)
|
||||
assertGaps(editor.snaps.lines![0])
|
||||
const { gapLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
expect(editor.snaps.getLines()?.length).toBe(1)
|
||||
assertGaps(editor.snaps.getLines()![0])
|
||||
const { gapLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines[0].gaps.length).toBe(2)
|
||||
})
|
||||
it('shows vertical snap points at the same time as vertical gaps', () => {
|
||||
|
@ -862,7 +863,7 @@ describe('Snap-between behavior', () => {
|
|||
editor.pointerDown(55, 155, ids.line1).pointerMove(6, 126, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 0, y: 120 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(pointLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps.length).toBe(2)
|
||||
|
@ -898,7 +899,7 @@ describe('Snap-between behavior', () => {
|
|||
editor.pointerDown(55, 155, ids.line1).pointerMove(27, 126, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 22, y: 120 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(pointLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(2)
|
||||
|
@ -933,10 +934,10 @@ describe('Snap-between behavior', () => {
|
|||
])
|
||||
editor.pointerDown(5, 5, ids.boxE).pointerMove(101, 126, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxE)).toMatchObject({ x: 95, y: 120 })
|
||||
expect(editor.snaps.lines?.length).toBe(2)
|
||||
assertGaps(editor.snaps.lines![0])
|
||||
assertGaps(editor.snaps.lines![1])
|
||||
const { gapLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
expect(editor.snaps.getLines()?.length).toBe(2)
|
||||
assertGaps(editor.snaps.getLines()![0])
|
||||
assertGaps(editor.snaps.getLines()![1])
|
||||
const { gapLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines[0].gaps.length).toBe(2)
|
||||
expect(gapLines[1].gaps.length).toBe(2)
|
||||
})
|
||||
|
@ -978,7 +979,7 @@ describe('Snap-between behavior', () => {
|
|||
editor.pointerDown(5, 5, ids.boxX).pointerMove(46, 46, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 40, y: 40 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines).toHaveLength(2)
|
||||
expect(gapLines[0].gaps).toHaveLength(4)
|
||||
expect(gapLines[1].gaps).toHaveLength(4)
|
||||
|
@ -1011,7 +1012,7 @@ describe('Snap-between behavior', () => {
|
|||
editor.pointerDown(65, 25, ids.boxX).pointerMove(16, 25, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 0, y: 20 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
expect(gapLines).toHaveLength(2)
|
||||
expect(gapLines[0].gaps).toHaveLength(2)
|
||||
expect(gapLines[1].gaps).toHaveLength(2)
|
||||
|
@ -1048,7 +1049,7 @@ describe('Snap-between behavior', () => {
|
|||
editor.pointerDown(50, 55, ids.boxX).pointerMove(51, 66, { ctrlKey: true })
|
||||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 1, y: 61 })
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
})
|
||||
|
||||
it('should work if the thing being dragged is a selection', () => {
|
||||
|
@ -1076,7 +1077,7 @@ describe('Snap-between behavior', () => {
|
|||
|
||||
expect(editor.getShape(ids.line1)).toMatchObject({ x: 200, y: 21 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(pointLines).toHaveLength(0)
|
||||
|
@ -1115,7 +1116,7 @@ describe('Snap-next-to behavior', () => {
|
|||
editor.pointerDown(5, 5, ids.boxX).pointerMove(6, 16, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 0, y: 10 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(2)
|
||||
|
@ -1151,7 +1152,7 @@ describe('Snap-next-to behavior', () => {
|
|||
editor.pointerDown(5, 5, ids.boxX).pointerMove(6, 16, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 0, y: 10 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(4)
|
||||
|
@ -1178,7 +1179,7 @@ describe('Snap-next-to behavior', () => {
|
|||
editor.pointerDown(105, 5, ids.boxX).pointerMove(106, 16, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 100, y: 10 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(2)
|
||||
|
@ -1212,7 +1213,7 @@ describe('Snap-next-to behavior', () => {
|
|||
editor.pointerDown(205, 5, ids.boxX).pointerMove(206, 16, { ctrlKey: true })
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 200, y: 10 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(4)
|
||||
|
@ -1238,7 +1239,7 @@ describe('Snap-next-to behavior', () => {
|
|||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 10, y: 0 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(2)
|
||||
|
@ -1280,7 +1281,7 @@ describe('Snap-next-to behavior', () => {
|
|||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 10, y: 0 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(4)
|
||||
|
@ -1307,7 +1308,7 @@ describe('Snap-next-to behavior', () => {
|
|||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 10, y: 40 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(2)
|
||||
|
@ -1348,7 +1349,7 @@ describe('Snap-next-to behavior', () => {
|
|||
|
||||
expect(editor.getShape(ids.boxX)).toMatchObject({ x: 10, y: 80 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(gapLines[0].gaps).toHaveLength(4)
|
||||
|
@ -1382,7 +1383,7 @@ describe('Snap-next-to behavior', () => {
|
|||
|
||||
expect(editor.getShape(ids.boxD)).toMatchObject({ x: 200, y: 131 })
|
||||
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.lines!)
|
||||
const { gapLines, pointLines } = getGapAndPointLines(editor.snaps.getLines()!)
|
||||
|
||||
expect(gapLines).toHaveLength(1)
|
||||
expect(pointLines).toHaveLength(0)
|
||||
|
@ -1533,7 +1534,7 @@ describe('translating a shape with a child', () => {
|
|||
|
||||
editor.pointerDown(25, 25, ids.box1).pointerMove(50, 25, { ctrlKey: true })
|
||||
|
||||
expect(editor.snaps.lines?.length).toBe(0)
|
||||
expect(editor.snaps.getLines()?.length).toBe(0)
|
||||
expect(editor.getShape(ids.box1)).toMatchObject({
|
||||
x: 25,
|
||||
y: 0,
|
||||
|
@ -1575,7 +1576,7 @@ describe('translating a shape with a bound shape', () => {
|
|||
|
||||
editor.pointerDown(50, 50, ids.box1).pointerMove(84, 110, { ctrlKey: true })
|
||||
|
||||
expect(editor.snaps.lines.length).toBe(0)
|
||||
expect(editor.snaps.getLines().length).toBe(0)
|
||||
})
|
||||
|
||||
it('should preserve arrow bindings', () => {
|
||||
|
|
Loading…
Reference in a new issue