From 16fda2fddfa83a1ec0499578969e41e9d14c0718 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Wed, 1 Sep 2021 09:37:07 +0100 Subject: [PATCH] Adds manual create and update, more jsdoc --- packages/dev/src/components/editor.tsx | 9 +- .../src/shape/shapes/rectangle/rectangle.tsx | 2 +- .../tldraw/src/shape/shapes/text/text.tsx | 8 +- packages/tldraw/src/state/command/index.ts | 1 + .../state/command/move/move.command.spec.ts | 36 +-- .../command/toggle/toggle.command.spec.ts | 2 +- .../tldraw/src/state/command/update/index.ts | 1 + .../command/update/update.command.spec.ts | 19 ++ .../state/command/update/update.command.ts | 47 ++++ .../session/sessions/text/text.session.ts | 2 +- .../sessions/transform/transform.session.ts | 3 +- packages/tldraw/src/state/tldr.ts | 2 - packages/tldraw/src/state/tlstate.ts | 233 +++++++++++++++--- 13 files changed, 304 insertions(+), 61 deletions(-) create mode 100644 packages/tldraw/src/state/command/update/index.ts create mode 100644 packages/tldraw/src/state/command/update/update.command.spec.ts create mode 100644 packages/tldraw/src/state/command/update/update.command.ts diff --git a/packages/dev/src/components/editor.tsx b/packages/dev/src/components/editor.tsx index c242be516..06eb17a12 100644 --- a/packages/dev/src/components/editor.tsx +++ b/packages/dev/src/components/editor.tsx @@ -1,6 +1,11 @@ import * as React from 'react' -import { TLDraw } from '@tldraw/tldraw' +import { TLDraw, TLDrawState } from '@tldraw/tldraw' export default function Editor(): JSX.Element { - return + const handleMount = React.useCallback((tlstate: TLDrawState) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + window.tlstate = tlstate + }, []) + return } diff --git a/packages/tldraw/src/shape/shapes/rectangle/rectangle.tsx b/packages/tldraw/src/shape/shapes/rectangle/rectangle.tsx index 44ff944f8..e6d43842b 100644 --- a/packages/tldraw/src/shape/shapes/rectangle/rectangle.tsx +++ b/packages/tldraw/src/shape/shapes/rectangle/rectangle.tsx @@ -312,7 +312,7 @@ export class Rectangle extends TLDrawShapeUtil { } } - transformSingle(shape: RectangleShape, bounds: TLBounds) { + transformSingle(_shape: RectangleShape, bounds: TLBounds) { return { size: Vec.round([bounds.width, bounds.height]), point: Vec.round([bounds.minX, bounds.minY]), diff --git a/packages/tldraw/src/shape/shapes/text/text.tsx b/packages/tldraw/src/shape/shapes/text/text.tsx index 3b402f7b0..f1e122559 100644 --- a/packages/tldraw/src/shape/shapes/text/text.tsx +++ b/packages/tldraw/src/shape/shapes/text/text.tsx @@ -56,7 +56,7 @@ if (typeof window !== 'undefined') { export class Text extends TLDrawShapeUtil { type = TLDrawShapeType.Text as const toolType = TLDrawToolType.Text - canChangeAspectRatio = false + isAspectRatioLocked = true isEditableText = true canBind = true @@ -325,7 +325,7 @@ export class Text extends TLDrawShapeUtil { transformSingle( _shape: TextShape, bounds: TLBounds, - { initialShape, scaleX }: TLTransformInfo + { initialShape, scaleX, scaleY }: TLTransformInfo ): Partial { const { style: { scale = 1 }, @@ -335,7 +335,7 @@ export class Text extends TLDrawShapeUtil { point: Vec.round([bounds.minX, bounds.minY]), style: { ...initialShape.style, - scale: scale * Math.abs(scaleX), + scale: scale * Math.max(Math.abs(scaleY), Math.abs(scaleX)), }, } } @@ -369,7 +369,7 @@ export class Text extends TLDrawShapeUtil { } shouldDelete(shape: TextShape): boolean { - return shape.text.length === 0 + return shape.text.trim().length === 0 } // getBindingPoint(shape, point, origin, direction, expandDistance) { diff --git a/packages/tldraw/src/state/command/index.ts b/packages/tldraw/src/state/command/index.ts index ae1c567fd..df155f897 100644 --- a/packages/tldraw/src/state/command/index.ts +++ b/packages/tldraw/src/state/command/index.ts @@ -16,3 +16,4 @@ export * from './delete-page' export * from './rename-page' export * from './duplicate-page' export * from './change-page' +export * from './update' diff --git a/packages/tldraw/src/state/command/move/move.command.spec.ts b/packages/tldraw/src/state/command/move/move.command.spec.ts index ab66ea81e..9afff6b97 100644 --- a/packages/tldraw/src/state/command/move/move.command.spec.ts +++ b/packages/tldraw/src/state/command/move/move.command.spec.ts @@ -44,7 +44,7 @@ describe('Move command', () => { it('does, undoes and redoes command', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b']) + tlstate.select('b') tlstate.moveToBack() expect(getSortedShapeIds(tlstate.state)).toBe('bacd') tlstate.undo() @@ -56,21 +56,21 @@ describe('Move command', () => { describe('to back', () => { it('moves a shape to back', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b']) + tlstate.select('b') tlstate.moveToBack() expect(getSortedShapeIds(tlstate.state)).toBe('bacd') }) it('moves two adjacent siblings to back', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b', 'c']) + tlstate.select('b', 'c') tlstate.moveToBack() expect(getSortedShapeIds(tlstate.state)).toBe('bcad') }) it('moves two non-adjacent siblings to back', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b', 'd']) + tlstate.select('b', 'd') tlstate.moveToBack() expect(getSortedShapeIds(tlstate.state)).toBe('bdac') }) @@ -79,35 +79,35 @@ describe('Move command', () => { describe('backward', () => { it('moves a shape backward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['c']) + tlstate.select('c') tlstate.moveBackward() expect(getSortedShapeIds(tlstate.state)).toBe('acbd') }) it('moves a shape at first index backward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['a']) + tlstate.select('a') tlstate.moveBackward() expect(getSortedShapeIds(tlstate.state)).toBe('abcd') }) it('moves two adjacent siblings backward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['c', 'd']) + tlstate.select('c', 'd') tlstate.moveBackward() expect(getSortedShapeIds(tlstate.state)).toBe('acdb') }) it('moves two non-adjacent siblings backward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b', 'd']) + tlstate.select('b', 'd') tlstate.moveBackward() expect(getSortedShapeIds(tlstate.state)).toBe('badc') }) it('moves two adjacent siblings backward at zero index', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['a', 'b']) + tlstate.select('a', 'b') tlstate.moveBackward() expect(getSortedShapeIds(tlstate.state)).toBe('abcd') }) @@ -116,14 +116,14 @@ describe('Move command', () => { describe('forward', () => { it('moves a shape forward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['c']) + tlstate.select('c') tlstate.moveForward() expect(getSortedShapeIds(tlstate.state)).toBe('abdc') }) it('moves a shape forward at the top index', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b']) + tlstate.select('b') tlstate.moveForward() tlstate.moveForward() tlstate.moveForward() @@ -132,21 +132,21 @@ describe('Move command', () => { it('moves two adjacent siblings forward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['a', 'b']) + tlstate.select('a', 'b') tlstate.moveForward() expect(getSortedShapeIds(tlstate.state)).toBe('cabd') }) it('moves two non-adjacent siblings forward', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['a', 'c']) + tlstate.select('a', 'c') tlstate.moveForward() expect(getSortedShapeIds(tlstate.state)).toBe('badc') }) it('moves two adjacent siblings forward at top index', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['c', 'd']) + tlstate.select('c', 'd') tlstate.moveForward() expect(getSortedShapeIds(tlstate.state)).toBe('abcd') }) @@ -155,28 +155,28 @@ describe('Move command', () => { describe('to front', () => { it('moves a shape to front', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['b']) + tlstate.select('b') tlstate.moveToFront() expect(getSortedShapeIds(tlstate.state)).toBe('acdb') }) it('moves two adjacent siblings to front', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['a', 'b']) + tlstate.select('a', 'b') tlstate.moveToFront() expect(getSortedShapeIds(tlstate.state)).toBe('cdab') }) it('moves two non-adjacent siblings to front', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['a', 'c']) + tlstate.select('a', 'c') tlstate.moveToFront() expect(getSortedShapeIds(tlstate.state)).toBe('bdac') }) it('moves siblings already at front to front', () => { tlstate.loadDocument(doc) - tlstate.setSelectedIds(['c', 'd']) + tlstate.select('c', 'd') tlstate.moveToFront() expect(getSortedShapeIds(tlstate.state)).toBe('abcd') }) diff --git a/packages/tldraw/src/state/command/toggle/toggle.command.spec.ts b/packages/tldraw/src/state/command/toggle/toggle.command.spec.ts index 85a2d4b1e..c545bbd84 100644 --- a/packages/tldraw/src/state/command/toggle/toggle.command.spec.ts +++ b/packages/tldraw/src/state/command/toggle/toggle.command.spec.ts @@ -26,7 +26,7 @@ describe('Toggle command', () => { it('toggles on before off when mixed values', () => { tlstate.loadDocument(mockDocument) - tlstate.setSelectedIds(['rect2']) + tlstate.select('rect2') expect(tlstate.getShape('rect1').isAspectRatioLocked).toBe(undefined) expect(tlstate.getShape('rect2').isAspectRatioLocked).toBe(undefined) tlstate.toggleAspectRatioLocked() diff --git a/packages/tldraw/src/state/command/update/index.ts b/packages/tldraw/src/state/command/update/index.ts new file mode 100644 index 000000000..cc22385b2 --- /dev/null +++ b/packages/tldraw/src/state/command/update/index.ts @@ -0,0 +1 @@ +export * from './update.command' diff --git a/packages/tldraw/src/state/command/update/update.command.spec.ts b/packages/tldraw/src/state/command/update/update.command.spec.ts new file mode 100644 index 000000000..568971e88 --- /dev/null +++ b/packages/tldraw/src/state/command/update/update.command.spec.ts @@ -0,0 +1,19 @@ +import { TLDrawState } from '~state' +import { mockDocument } from '~test' +import { Utils } from '@tldraw/core' + +const doc = Utils.deepClone(mockDocument) + +describe('Move command', () => { + const tlstate = new TLDrawState() + + it('does, undoes and redoes command', () => { + tlstate.loadDocument(doc) + tlstate.updateShapes({ id: 'rect1', point: [100, 100] }) + expect(tlstate.getShape('rect1').point).toStrictEqual([100, 100]) + tlstate.undo() + expect(tlstate.getShape('rect1').point).toStrictEqual([0, 0]) + tlstate.redo() + expect(tlstate.getShape('rect1').point).toStrictEqual([100, 100]) + }) +}) diff --git a/packages/tldraw/src/state/command/update/update.command.ts b/packages/tldraw/src/state/command/update/update.command.ts new file mode 100644 index 000000000..4e2b43cda --- /dev/null +++ b/packages/tldraw/src/state/command/update/update.command.ts @@ -0,0 +1,47 @@ +import type { Data, TLDrawCommand, PagePartial, TLDrawShape } from '~types' +import { TLDR } from '~state/tldr' + +export function update( + data: Data, + updates: ({ id: string } & Partial)[] +): TLDrawCommand { + const ids = updates.map((update) => update.id) + + const before: PagePartial = { + shapes: {}, + bindings: {}, + } + + const after: PagePartial = { + shapes: {}, + bindings: {}, + } + + const change = TLDR.mutateShapes( + data, + ids, + (_shape, i) => updates[i], + data.appState.currentPageId + ) + + before.shapes = change.before + after.shapes = change.after + + return { + id: 'translate_shapes', + before: { + document: { + pages: { + [data.appState.currentPageId]: before, + }, + }, + }, + after: { + document: { + pages: { + [data.appState.currentPageId]: after, + }, + }, + }, + } +} diff --git a/packages/tldraw/src/state/session/sessions/text/text.session.ts b/packages/tldraw/src/state/session/sessions/text/text.session.ts index 9f2487a49..3c24eed69 100644 --- a/packages/tldraw/src/state/session/sessions/text/text.session.ts +++ b/packages/tldraw/src/state/session/sessions/text/text.session.ts @@ -1,4 +1,4 @@ -import { TextShape, TLDrawShape, TLDrawStatus } from '~types' +import { TextShape, TLDrawStatus } from '~types' import type { Session } from '~types' import type { Data } from '~types' import { TLDR } from '~state/tldr' diff --git a/packages/tldraw/src/state/session/sessions/transform/transform.session.ts b/packages/tldraw/src/state/session/sessions/transform/transform.session.ts index ccf2067f1..d68fc2216 100644 --- a/packages/tldraw/src/state/session/sessions/transform/transform.session.ts +++ b/packages/tldraw/src/state/session/sessions/transform/transform.session.ts @@ -24,6 +24,7 @@ export class TransformSession implements Session { start = () => void null + // eslint-disable-next-line @typescript-eslint/no-unused-vars update = (data: Data, point: number[], isAspectRatioLocked = false, _altKey = false) => { const { transformType, @@ -37,7 +38,7 @@ export class TransformSession implements Session { const newBoundingBox = Utils.getTransformedBoundingBox( initialBounds, transformType, - Vec.vec(this.origin, point), + Vec.sub(point, this.origin), pageState.boundsRotation, isAspectRatioLocked || isAllAspectRatioLocked ) diff --git a/packages/tldraw/src/state/tldr.ts b/packages/tldraw/src/state/tldr.ts index 93abbb977..331d70517 100644 --- a/packages/tldraw/src/state/tldr.ts +++ b/packages/tldraw/src/state/tldr.ts @@ -668,8 +668,6 @@ export class TLDR { next = this.onChildrenChange(data, next, pageId) || next } - // data.page.shapes[next.id] = next - return next } diff --git a/packages/tldraw/src/state/tlstate.ts b/packages/tldraw/src/state/tlstate.ts index b8c1af4d5..c772e25dd 100644 --- a/packages/tldraw/src/state/tlstate.ts +++ b/packages/tldraw/src/state/tlstate.ts @@ -135,14 +135,14 @@ export class TLDrawState extends StateManager { } /* -------------------- Internal -------------------- */ - protected onStateWillChange = (_state: Data, id: string): void => { - if (!id.startsWith('patch')) { - this.selectHistory.stack = [[]] - this.selectHistory.pointer = 0 - } - } + // protected onStateWillChange = (_state: Data, id: string): void => { + // } protected onStateDidChange = (state: Data, id: string): void => { + if (!id.startsWith('patch')) { + this.clearSelectHistory() + } + this._onChange?.(this, state, id) } @@ -531,7 +531,9 @@ export class TLDrawState extends StateManager { loadDocument = (document: TLDrawDocument, onChange?: TLDrawState['_onChange']): this => { this._onChange = onChange + this.deselectAll() this.resetHistory() + this.clearSelectHistory() // this.selectHistory.pointer = 0 // this.selectHistory.stack = [[]] @@ -942,7 +944,13 @@ export class TLDrawState extends StateManager { this.selectHistory.stack.push(ids) } - setSelectedIds(ids: string[], push = false): this { + /** + * Set the current selection. + * @param ids The ids to select + * @param push Whether to add the ids to the current selection instead. + * @returns this + */ + private setSelectedIds(ids: string[], push = false): this { return this.patchState( { appState: { @@ -961,6 +969,10 @@ export class TLDrawState extends StateManager { ) } + /** + * Undo the most recent selection. + * @returns this + */ undoSelect(): this { if (this.selectHistory.pointer > 0) { this.selectHistory.pointer-- @@ -969,6 +981,10 @@ export class TLDrawState extends StateManager { return this } + /** + * Redo the previous selection. + * @returns this + */ redoSelect(): this { if (this.selectHistory.pointer < this.selectHistory.stack.length - 1) { this.selectHistory.pointer++ @@ -977,12 +993,21 @@ export class TLDrawState extends StateManager { return this } + /** + * Select one or more shapes. + * @param ids The shape ids to select. + * @returns this + */ select = (...ids: string[]): this => { this.setSelectedIds(ids) this.addToSelectHistory(ids) return this } + /** + * Select all shapes on the page. + * @returns this + */ selectAll = (): this => { if (this.session) return this this.setSelectedIds(Object.keys(this.page.shapes)) @@ -993,6 +1018,10 @@ export class TLDrawState extends StateManager { return this } + /** + * Deselect any selected shapes. + * @returns this + */ deselectAll = (): this => { this.setSelectedIds([]) this.addToSelectHistory(this.selectedIds) @@ -1003,66 +1032,213 @@ export class TLDrawState extends StateManager { /* Shape Functions */ /* -------------------------------------------------- */ + /** + * Manually create shapes on the page. + * @param shapes An array of shape partials, containing the initial props for the shapes. + * @command + * @returns this + */ + createShapes = ( + ...shapes: ({ id: string; type: TLDrawShapeType } & Partial)[] + ): this => { + if (shapes.length === 0) return this + return this.create( + ...shapes.map((shape) => { + return TLDR.getShapeUtils(shape as TLDrawShape).create(shape) + }) + ) + } + + /** + * Manually update a set of shapes. + * @param shapes An array of shape partials, containing the changes to be made to each shape. + * @command + * @returns this + */ + updateShapes = (...shapes: ({ id: string } & Partial)[]): this => { + if (shapes.length === 0) return this + return this.setState(Commands.update(this.state, shapes), 'updated_shape') + } + + /** + * Create one or more shapes. + * @param shapes An array of shapes. + * @command + * @returns this + */ + create = (...shapes: TLDrawShape[]): this => { + if (shapes.length === 0) return this + return this.setState(Commands.create(this.state, shapes)) + } + + /** + * Delete one or more shapes. + * @param ids The ids of the shapes to delete. + * @command + * @returns this + */ + delete = (ids = this.selectedIds): this => { + if (ids.length === 0) return this + return this.setState(Commands.deleteShapes(this.state, ids)) + } + + /** + * Delete all shapes on the page. + * @returns this + */ + clear = (): this => { + this.selectAll() + this.delete() + return this + } + + /** + * Change the style for one or more shapes. + * @param style A style partial to apply to the shapes. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ style = (style: Partial, ids = this.selectedIds) => { return this.setState(Commands.style(this.state, ids, style)) } + /** + * Align one or more shapes. + * @param direction Whether to align horizontally or vertically. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ align = (type: AlignType, ids = this.selectedIds) => { return this.setState(Commands.align(this.state, ids, type)) } - distribute = (type: DistributeType, ids = this.selectedIds) => { - return this.setState(Commands.distribute(this.state, ids, type)) + /** + * Distribute one or more shapes. + * @param direction Whether to distribute horizontally or vertically.. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ + distribute = (direction: DistributeType, ids = this.selectedIds) => { + return this.setState(Commands.distribute(this.state, ids, direction)) } - stretch = (type: StretchType, ids = this.selectedIds) => { - return this.setState(Commands.stretch(this.state, ids, type)) + /** + * Stretch one or more shapes to their common bounds. + * @param direction Whether to stretch horizontally or vertically. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ + stretch = (direction: StretchType, ids = this.selectedIds) => { + return this.setState(Commands.stretch(this.state, ids, direction)) } + /** + * Flip one or more shapes horizontally. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ flipHorizontal = (ids = this.selectedIds) => { return this.setState(Commands.flip(this.state, ids, FlipType.Horizontal)) } + /** + * Flip one or more shapes vertically. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ flipVertical = (ids = this.selectedIds) => { return this.setState(Commands.flip(this.state, ids, FlipType.Vertical)) } + /** + * Move one or more shapes to the back of the page. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ moveToBack = (ids = this.selectedIds) => { return this.setState(Commands.move(this.state, ids, MoveType.ToBack)) } + /** + * Move one or more shapes backward on of the page. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ moveBackward = (ids = this.selectedIds) => { return this.setState(Commands.move(this.state, ids, MoveType.Backward)) } + /** + * Move one or more shapes forward on the page. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ moveForward = (ids = this.selectedIds) => { return this.setState(Commands.move(this.state, ids, MoveType.Forward)) } + /** + * Move one or more shapes to the front of the page. + * @param ids The ids of the shapes to change (defaults to selection). + * @returns this + */ moveToFront = (ids = this.selectedIds) => { return this.setState(Commands.move(this.state, ids, MoveType.ToFront)) } + /** + * Nudge one or more shapes in a direction. + * @param delta The direction to nudge the shapes. + * @param isMajor Whether this is a major (i.e. shift) nudge. + * @param ids The ids to change (defaults to selection). + * @returns this + */ nudge = (delta: number[], isMajor = false, ids = this.selectedIds): this => { return this.setState(Commands.translate(this.state, ids, Vec.mul(delta, isMajor ? 10 : 1))) } + /** + * Duplicate one or more shapes. + * @param ids The ids to duplicate (defaults to selection). + * @returns this + */ duplicate = (ids = this.selectedIds): this => { return this.setState(Commands.duplicate(this.state, ids)) } + /** + * Toggle the hidden property of one or more shapes. + * @param ids The ids to change (defaults to selection). + * @returns this + */ toggleHidden = (ids = this.selectedIds): this => { return this.setState(Commands.toggle(this.state, ids, 'isHidden')) } + /** + * Toggle the locked property of one or more shapes. + * @param ids The ids to change (defaults to selection). + * @returns this + */ toggleLocked = (ids = this.selectedIds): this => { return this.setState(Commands.toggle(this.state, ids, 'isLocked')) } + /** + * Toggle the fixed-aspect-ratio property of one or more shapes. + * @param ids The ids to change (defaults to selection). + * @returns this + */ toggleAspectRatioLocked = (ids = this.selectedIds): this => { return this.setState(Commands.toggle(this.state, ids, 'isAspectRatioLocked')) } + /** + * Toggle the decoration at a handle of one or more shapes. + * @param handleId The handle to toggle. + * @param ids The ids of the shapes to toggle the decoration on. + * @returns this + */ toggleDecoration = (handleId: string, ids = this.selectedIds): this => { if (handleId === 'start' || handleId === 'end') { return this.setState(Commands.toggleDecoration(this.state, ids, handleId)) @@ -1071,34 +1247,29 @@ export class TLDrawState extends StateManager { return this } + /** + * Rotate one or more shapes by a delta. + * @param delta The delta in radians. + * @param ids The ids to rotate (defaults to selection). + * @returns this + */ rotate = (delta = Math.PI * -0.5, ids = this.selectedIds): this => { return this.setState(Commands.rotate(this.state, ids, delta)) } + /** + * Group one or more shapes. + * @returns this + * @todo + */ group = (): this => { - // TODO - // - // - // this.setState(Commands.toggle(this.state, ids, 'isAspectRatioLocked')) - return this - } - - create = (...shapes: TLDrawShape[]): this => { - return this.setState(Commands.create(this.state, shapes)) - } - - delete = (ids = this.selectedIds): this => { - if (ids.length === 0) return this - - return this.setState(Commands.deleteShapes(this.state, ids)) - } - - clear = (): this => { - this.selectAll() - this.delete() return this } + /** + * Cancel the current session. + * @returns this + */ cancel = (): this => { switch (this.state.appState.status.current) { case TLDrawStatus.Idle: {