01bc73e750
This PR: - creates `Editor.run` (previously `Editor.batch`) - deprecates `Editor.batch` - introduces a `ignoreShapeLock` option top the `Editor.run` method that allows the editor to update and delete locked shapes - fixes a bug with `updateShapes` that allowed updating locked shapes - fixes a bug with `ungroupShapes` that allowed ungrouping locked shapes - makes `Editor.history` private - adds `Editor.squashToMark` - adds `Editor.clearHistory` - removes `History.ignore` - removes `History.onBatchComplete` - makes `_updateCurrentPageState` private ```ts editor.run(() => { editor.updateShape({ ...myLockedShape }) editor.deleteShape(myLockedShape) }, { ignoreShapeLock: true }) ``` It also: ## How it works Normally `updateShape`/`updateShapes` and `deleteShape`/`deleteShapes` do not effect locked shapes. ```ts const myLockedShape = editor.getShape(myShapeId)! // no change from update editor.updateShape({ ...myLockedShape, x: 100 }) expect(editor.getShape(myShapeId)).toMatchObject(myLockedShape) // no change from delete editor.deleteShapes([myLockedShape]) expect(editor.getShape(myShapeId)).toMatchObject(myLockedShape) ``` The new `run` method adds the option to ignore shape lock. ```ts const myLockedShape = editor.getShape(myShapeId)! // update works editor.run(() => { editor.updateShape({ ...myLockedShape, x: 100 }) }, { ignoreShapeLock: true }) expect(editor.getShape(myShapeId)).toMatchObject({ ...myLockedShape, x: 100 }) // delete works editor.run(() => { editor.deleteShapes([myLockedShape]), { ignoreShapeLock: true }) expect(editor.getShape(myShapeId)).toBeUndefined() ``` ## History changes This is a related but not entirely related change in this PR. Previously, we had a few ways to run code that ignored the history. - `editor.history.ignore(() => { ... })` - `editor.batch(() => { ... }, { history: "ignore" })` - `editor.history.batch(() => { ... }, { history: "ignore" })` - `editor.updateCurrentPageState(() => { ... }, { history: "ignore" })` We now have one way to run code that ignores history: - `editor.run(() => { ... }, { history: "ignore" })` ## Design notes We want a user to be able to update or delete locked shapes programmatically. ### Callback vs. method options? We could have added a `{ force: boolean }` property to the `updateShapes` / `deleteShapes` methods, however there are places where those methods are called from other methods (such as `distributeShapes`). If we wanted to make these work, we would have also had to provide a `force` option / bag to those methods. Using a wrapper callback allows for "regular" tldraw editor code to work while allowing for updates and deletes. ### Interaction logic? We don't want this change to effect any of our interaction logic. A lot of our interaction logic depends on identifying which shapes are locked and which shapes aren't. For example, clicking on a locked shape will go to the `pointing_canvas` state rather than the `pointing_shape`. This PR has no effect on that part of the library. It only effects the updateShapes and deleteShapes methods. As an example of this, when `_force` is set to true by default, the only tests that should fail are in `lockedShapes.test.ts`. The "user land" experience of locked shapes is identical to what it is now. ### Change type - [x] `bugfix` - [ ] `improvement` - [x] `feature` - [x] `api` - [ ] `other` ### Test plan 1. Create a shape 2. Lock it 3. From the console, update it 4. From the console, delete it - [x] Unit tests ### Release notes - SDK: Adds `Editor.force()` to permit updating / deleting locked shapes - Fixed a bug that would allow locked shapes to be updated programmatically - Fixed a bug that would allow locked group shapes to be ungrouped programmatically --------- Co-authored-by: alex <alex@dytry.ch> |
||
---|---|---|
.. | ||
assets/watermarks | ||
src | ||
api-extractor.json | ||
api-report.md | ||
CHANGELOG.md | ||
editor.css | ||
LICENSE.md | ||
modules.d.ts | ||
package.json | ||
README.md | ||
setupTests.js | ||
tsconfig.json |
tldraw/tldraw
Distributions
You can find tldraw on npm here.
Contribution
Please see our contributing guide. Found a bug? Please submit an issue.
License
The tldraw source code and its distributions are provided under the tldraw license. This license does not permit commercial use. To purchase a commercial license or learn more, please fill out this form.
Trademarks
Copyright (c) 2023-present tldraw Inc. The tldraw name and logo are trademarks of tldraw. Please see our trademark guidelines for info on acceptable usage.
Contact
Find us on Twitter/X at @tldraw.
Community
Have questions, comments or feedback? Join our discord or start a discussion. For the latest news and release notes, check out our Substack.