diff --git a/tldraw/packages/core/src/lib/TLBaseLineBindingState.ts b/tldraw/packages/core/src/lib/TLBaseLineBindingState.ts index 5e30bd254f..593927dede 100644 --- a/tldraw/packages/core/src/lib/TLBaseLineBindingState.ts +++ b/tldraw/packages/core/src/lib/TLBaseLineBindingState.ts @@ -49,11 +49,13 @@ export class TLBaseLineBindingState< const nextPoint = Vec.add(handles[handleId].point, delta) + const handleChanges = { [handleId]: { ...handles[handleId], // FIXME Snap not working properly - point: showGrid ? Vec.snap(nextPoint, currentGrid) : Vec.toFixed(nextPoint), + // point: showGrid ? Vec.snap(nextPoint, currentGrid) : Vec.toFixed(nextPoint) + point: Vec.toFixed(nextPoint), bindingId: undefined, }, } diff --git a/tldraw/packages/core/src/lib/TLHistory.ts b/tldraw/packages/core/src/lib/TLHistory.ts index fb1681c2ba..ddd7724d1b 100644 --- a/tldraw/packages/core/src/lib/TLHistory.ts +++ b/tldraw/packages/core/src/lib/TLHistory.ts @@ -1,4 +1,4 @@ -import { computed, makeObservable } from 'mobx' +import { computed, makeObservable, transaction } from 'mobx' import { TLApp, TLDocumentModel, TLPage, TLShape } from '~lib' import type { TLEventMap } from '~types' import { deepEqual } from '~utils' @@ -91,82 +91,86 @@ export class TLHistory { - const { currentPageId, selectedIds, pages } = snapshot - const wasPaused = this.isPaused - this.pause() + transaction(() => { + const { currentPageId, selectedIds, pages } = snapshot + const wasPaused = this.isPaused + this.pause() - const newSelectedIds = selectedIds.length === 0 ? Array.from(this.app.selectedIds) : selectedIds + const newSelectedIds = + selectedIds.length === 0 ? Array.from(this.app.selectedIds) : selectedIds - try { - const pagesMap = new Map(this.app.pages) - const pagesToAdd: TLPage[] = [] + try { + const pagesMap = new Map(this.app.pages) + const pagesToAdd: TLPage[] = [] - for (const serializedPage of pages) { - const page = pagesMap.get(serializedPage.id) - if (page !== undefined) { - // Update the page - const shapesMap = new Map(page.shapes.map(shape => [shape.props.id, shape])) - const shapesToAdd: S[] = [] - for (const serializedShape of serializedPage.shapes) { - const shape = shapesMap.get(serializedShape.id) - if (shape !== undefined) { - // Update the shape - if (shape.nonce !== serializedShape.nonce) { - shape.update(serializedShape, true) - shape.nonce = serializedShape.nonce! - shape.setLastSerialized(serializedShape) - } - shapesMap.delete(serializedShape.id) - } else { - // Create the shape - const ShapeClass = this.app.getShapeClass(serializedShape.type) - shapesToAdd.push(new ShapeClass(serializedShape)) - } - } - - // Do not remove any currently selected shapes - newSelectedIds.forEach(id => { - shapesMap.delete(id) - }) - - // Any shapes remaining in the shapes map need to be removed - if (shapesMap.size > 0) { - page.removeShapes(...shapesMap.values()) - } - // Add any new shapes - if (shapesToAdd.length > 0) page.addShapes(...shapesToAdd) - // Remove the page from the map - pagesMap.delete(serializedPage.id) - page.updateBindings(serializedPage.bindings) - } else { - // Create the page - const { id, name, shapes, bindings } = serializedPage - pagesToAdd.push( - new TLPage(this.app, { - id, - name, - bindings, - shapes: shapes.map(serializedShape => { + for (const serializedPage of pages) { + const page = pagesMap.get(serializedPage.id) + if (page !== undefined) { + // Update the page + const shapesMap = new Map(page.shapes.map(shape => [shape.props.id, shape])) + const shapesToAdd: S[] = [] + for (const serializedShape of serializedPage.shapes) { + const shape = shapesMap.get(serializedShape.id) + if (shape !== undefined) { + // Update the shape + if (shape.nonce !== serializedShape.nonce) { + shape.update(serializedShape, true) + shape.nonce = serializedShape.nonce! + shape.setLastSerialized(serializedShape) + } + shapesMap.delete(serializedShape.id) + } else { + // Create the shape const ShapeClass = this.app.getShapeClass(serializedShape.type) - return new ShapeClass(serializedShape) - }), + shapesToAdd.push(new ShapeClass(serializedShape)) + } + } + + // Do not remove any currently selected shapes + newSelectedIds.forEach(id => { + shapesMap.delete(id) }) - ) + + // Do not remove shapes if currently state is creating or editing + // Any shapes remaining in the shapes map need to be removed + if (shapesMap.size > 0 && !this.app.selectedTool.isInAny('creating', 'editingShape')) { + page.removeShapes(...shapesMap.values()) + } + // Add any new shapes + if (shapesToAdd.length > 0) page.addShapes(...shapesToAdd) + // Remove the page from the map + pagesMap.delete(serializedPage.id) + page.updateBindings(serializedPage.bindings) + } else { + // Create the page + const { id, name, shapes, bindings } = serializedPage + pagesToAdd.push( + new TLPage(this.app, { + id, + name, + bindings, + shapes: shapes.map(serializedShape => { + const ShapeClass = this.app.getShapeClass(serializedShape.type) + return new ShapeClass(serializedShape) + }), + }) + ) + } } + + // Add any new pages + if (pagesToAdd.length > 0) this.app.addPages(pagesToAdd) + + // Any pages remaining in the pages map need to be removed + if (pagesMap.size > 0) this.app.removePages(Array.from(pagesMap.values())) + + this.app.setSelectedShapes(newSelectedIds).setErasingShapes([]) + } catch (e) { + console.warn(e) } - // Add any new pages - if (pagesToAdd.length > 0) this.app.addPages(pagesToAdd) - - // Any pages remaining in the pages map need to be removed - if (pagesMap.size > 0) this.app.removePages(Array.from(pagesMap.values())) - - this.app.setSelectedShapes(newSelectedIds).setErasingShapes([]) - } catch (e) { - console.warn(e) - } - - // Resume the history if not originally paused - if (!wasPaused) this.resume() + // Resume the history if not originally paused + if (!wasPaused) this.resume() + }) } } diff --git a/tldraw/packages/react/src/components/ui/Grid/Grid.tsx b/tldraw/packages/react/src/components/ui/Grid/Grid.tsx index 66f2c0d56d..f2778d602f 100644 --- a/tldraw/packages/react/src/components/ui/Grid/Grid.tsx +++ b/tldraw/packages/react/src/components/ui/Grid/Grid.tsx @@ -1,7 +1,6 @@ -import * as React from 'react' -import { useRendererContext } from '~hooks' -import { observer } from 'mobx-react-lite' import { modulate } from '@tldraw/core' +import { observer } from 'mobx-react-lite' +import { useRendererContext } from '~hooks' import type { TLGridProps } from '~types/component-props' const STEPS = [ @@ -36,7 +35,7 @@ export const Grid = observer(function Grid({ size }: TLGridProps) { height={s} patternUnits="userSpaceOnUse" > - + ) })}