Move state to rko
This commit is contained in:
parent
c3e6c55a68
commit
9e8e99cb6f
22 changed files with 4105 additions and 1482 deletions
27
package.json
27
package.json
|
@ -17,6 +17,7 @@
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
|
"test:watch": "jest --watchAll",
|
||||||
"lerna": "lerna",
|
"lerna": "lerna",
|
||||||
"start": "lerna run start --stream --parallel",
|
"start": "lerna run start --stream --parallel",
|
||||||
"start:www": "lerna run start --stream --parallel & cd packages/www && yarn dev",
|
"start:www": "lerna run start --stream --parallel & cd packages/www && yarn dev",
|
||||||
|
@ -26,25 +27,27 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
||||||
|
"@babel/preset-env": "^7.15.0",
|
||||||
"@babel/preset-react": "^7.14.5",
|
"@babel/preset-react": "^7.14.5",
|
||||||
"@babel/preset-typescript": "^7.15.0",
|
"@babel/preset-typescript": "^7.15.0",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
"@testing-library/react": "^12.0.0",
|
"@testing-library/react": "^12.0.0",
|
||||||
"@types/jest": "^26.0.24",
|
"@types/jest": "^27.0.1",
|
||||||
"@types/node": "^15.0.1",
|
"@types/node": "^15.0.1",
|
||||||
"@types/react": "^17.0.16",
|
"@types/react": "^17.0.19",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.19.0",
|
"@typescript-eslint/eslint-plugin": "^4.19.0",
|
||||||
"@typescript-eslint/parser": "^4.19.0",
|
"@typescript-eslint/parser": "^4.19.0",
|
||||||
"babel-jest": "^27.0.6",
|
"babel-jest": "^27.1.0",
|
||||||
"esbuild": "^0.11.11",
|
"esbuild": "^0.11.11",
|
||||||
"jest": "^27.0.6",
|
"fake-indexeddb": "^3.1.3",
|
||||||
|
"jest": "^27.1.0",
|
||||||
"lerna": "^3.15.0",
|
"lerna": "^3.15.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"ts-jest": "^27.0.4",
|
"ts-jest": "^27.0.5",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"typescript": "^4.3.5"
|
"typescript": "^4.4.2"
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
|
@ -59,7 +62,7 @@
|
||||||
"<rootDir>/setupTests.ts"
|
"<rootDir>/setupTests.ts"
|
||||||
],
|
],
|
||||||
"transform": {
|
"transform": {
|
||||||
"^.+\\.(tsx|jsx|ts|js)?$": "ts-jest"
|
"^.+\\.(tsx|jsx|ts|js|mjs)?$": "ts-jest"
|
||||||
},
|
},
|
||||||
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
|
@ -72,9 +75,17 @@
|
||||||
],
|
],
|
||||||
"globals": {
|
"globals": {
|
||||||
"ts-jest": {
|
"ts-jest": {
|
||||||
"tsConfig": "tsconfig.json",
|
"tsconfig": "tsconfig.json",
|
||||||
"babelConfig": {
|
"babelConfig": {
|
||||||
"presets": [
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"esmodules": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"@babel/preset-react"
|
"@babel/preset-react"
|
||||||
],
|
],
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
"ismobilejs": "^1.1.1",
|
"ismobilejs": "^1.1.1",
|
||||||
"perfect-freehand": "^0.5.2",
|
"perfect-freehand": "^0.5.2",
|
||||||
"react-hotkeys-hook": "^3.4.0",
|
"react-hotkeys-hook": "^3.4.0",
|
||||||
"zustand": "^3.5.7"
|
"rko": "^0.5.18"
|
||||||
},
|
},
|
||||||
"gitHead": "4a7439ddf81b615ee49fddbe00802699975f9375"
|
"gitHead": "4a7439ddf81b615ee49fddbe00802699975f9375"
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ async function main() {
|
||||||
esbuild.buildSync({
|
esbuild.buildSync({
|
||||||
entryPoints: ['./src/index.ts'],
|
entryPoints: ['./src/index.ts'],
|
||||||
outdir: 'dist/esm',
|
outdir: 'dist/esm',
|
||||||
minify: true,
|
minify: false,
|
||||||
bundle: true,
|
bundle: true,
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
target: 'es6',
|
target: 'es6',
|
||||||
|
|
|
@ -32,7 +32,7 @@ const isDarkModeSelector = (s: Data) => s.settings.isDarkMode
|
||||||
export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }: TLDrawProps) {
|
export function TLDraw({ document, currentPageId, onMount, onChange: _onChange }: TLDrawProps) {
|
||||||
const [tlstate] = React.useState(() => new TLDrawState())
|
const [tlstate] = React.useState(() => new TLDrawState())
|
||||||
const [context] = React.useState(() => {
|
const [context] = React.useState(() => {
|
||||||
return { tlstate, useSelector: tlstate.store }
|
return { tlstate, useSelector: tlstate.useStore }
|
||||||
})
|
})
|
||||||
|
|
||||||
useKeyboardShortcuts(tlstate)
|
useKeyboardShortcuts(tlstate)
|
||||||
|
|
|
@ -26,67 +26,56 @@ export function useKeyboardShortcuts(tlstate: TLDrawState) {
|
||||||
|
|
||||||
/* ---------------------- Tools --------------------- */
|
/* ---------------------- Tools --------------------- */
|
||||||
|
|
||||||
useHotkeys('v,1', (e) => {
|
useHotkeys('v,1', () => {
|
||||||
tlstate.selectTool('select')
|
tlstate.selectTool('select')
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('d,2', (e) => {
|
useHotkeys('d,2', () => {
|
||||||
tlstate.selectTool(TLDrawShapeType.Draw)
|
tlstate.selectTool(TLDrawShapeType.Draw)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('r,3', (e) => {
|
useHotkeys('r,3', () => {
|
||||||
tlstate.selectTool(TLDrawShapeType.Rectangle)
|
tlstate.selectTool(TLDrawShapeType.Rectangle)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('e,4', (e) => {
|
useHotkeys('e,4', () => {
|
||||||
tlstate.selectTool(TLDrawShapeType.Ellipse)
|
tlstate.selectTool(TLDrawShapeType.Ellipse)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('a,5', (e) => {
|
useHotkeys('a,5', () => {
|
||||||
tlstate.selectTool(TLDrawShapeType.Arrow)
|
tlstate.selectTool(TLDrawShapeType.Arrow)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('t,6', (e) => {
|
useHotkeys('t,6', () => {
|
||||||
tlstate.selectTool(TLDrawShapeType.Text)
|
tlstate.selectTool(TLDrawShapeType.Text)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/* ---------------------- Misc ---------------------- */
|
/* ---------------------- Misc ---------------------- */
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
|
|
||||||
useHotkeys('ctrl+s,command+s', (e) => {
|
useHotkeys('ctrl+s,command+s', () => {
|
||||||
tlstate.save()
|
tlstate.saveProject()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Undo Redo
|
// Undo Redo
|
||||||
|
|
||||||
useHotkeys('command+z,ctrl+z', (e) => {
|
useHotkeys('command+z,ctrl+z', () => {
|
||||||
tlstate.undo()
|
tlstate.undo()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('ctrl+shift-z,command+shift+z', (e) => {
|
useHotkeys('ctrl+shift-z,command+shift+z', () => {
|
||||||
tlstate.redo()
|
tlstate.redo()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Undo Redo
|
// Undo Redo
|
||||||
|
|
||||||
useHotkeys('command+u,ctrl+u', (e) => {
|
useHotkeys('command+u,ctrl+u', () => {
|
||||||
tlstate.undoSelect()
|
tlstate.undoSelect()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('ctrl+shift-u,command+shift+u', (e) => {
|
useHotkeys('ctrl+shift-u,command+shift+u', () => {
|
||||||
tlstate.redoSelect()
|
tlstate.redoSelect()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/* -------------------- Commands -------------------- */
|
/* -------------------- Commands -------------------- */
|
||||||
|
@ -103,139 +92,115 @@ export function useKeyboardShortcuts(tlstate: TLDrawState) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+1', (e) => {
|
useHotkeys('shift+1', () => {
|
||||||
tlstate.zoomToFit()
|
tlstate.zoomToFit()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+2', (e) => {
|
useHotkeys('shift+2', () => {
|
||||||
tlstate.zoomToSelection()
|
tlstate.zoomToSelection()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+0', (e) => {
|
useHotkeys('shift+0', () => {
|
||||||
tlstate.zoomToActual()
|
tlstate.zoomToActual()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Duplicate
|
// Duplicate
|
||||||
|
|
||||||
useHotkeys('ctrl+d,command+d', (e) => {
|
useHotkeys('ctrl+d,command+d', () => {
|
||||||
tlstate.duplicate()
|
tlstate.duplicate()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Flip
|
// Flip
|
||||||
|
|
||||||
useHotkeys('shift+h', (e) => {
|
useHotkeys('shift+h', () => {
|
||||||
tlstate.flipHorizontal()
|
tlstate.flipHorizontal()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+v', (e) => {
|
useHotkeys('shift+v', () => {
|
||||||
tlstate.flipVertical()
|
tlstate.flipVertical()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Cancel
|
// Cancel
|
||||||
|
|
||||||
useHotkeys('escape', (e) => {
|
useHotkeys('escape', () => {
|
||||||
tlstate.cancel()
|
tlstate.cancel()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
|
|
||||||
useHotkeys('backspace', (e) => {
|
useHotkeys('backspace', () => {
|
||||||
tlstate.delete()
|
tlstate.delete()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Select All
|
// Select All
|
||||||
|
|
||||||
useHotkeys('command+a,ctrl+a', (e) => {
|
useHotkeys('command+a,ctrl+a', () => {
|
||||||
tlstate.selectAll()
|
tlstate.selectAll()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Nudge
|
// Nudge
|
||||||
|
|
||||||
useHotkeys('up', (e) => {
|
useHotkeys('up', () => {
|
||||||
tlstate.nudge([0, -1], false)
|
tlstate.nudge([0, -1], false)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('right', (e) => {
|
useHotkeys('right', () => {
|
||||||
tlstate.nudge([1, 0], false)
|
tlstate.nudge([1, 0], false)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('down', (e) => {
|
useHotkeys('down', () => {
|
||||||
tlstate.nudge([0, 1], false)
|
tlstate.nudge([0, 1], false)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('left', (e) => {
|
useHotkeys('left', () => {
|
||||||
tlstate.nudge([-1, 0], false)
|
tlstate.nudge([-1, 0], false)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+up', (e) => {
|
useHotkeys('shift+up', () => {
|
||||||
tlstate.nudge([0, -1], true)
|
tlstate.nudge([0, -1], true)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+right', (e) => {
|
useHotkeys('shift+right', () => {
|
||||||
tlstate.nudge([1, 0], true)
|
tlstate.nudge([1, 0], true)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+down', (e) => {
|
useHotkeys('shift+down', () => {
|
||||||
tlstate.nudge([0, 1], true)
|
tlstate.nudge([0, 1], true)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+left', (e) => {
|
useHotkeys('shift+left', () => {
|
||||||
tlstate.nudge([-1, 0], true)
|
tlstate.nudge([-1, 0], true)
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Copy & Paste
|
// Copy & Paste
|
||||||
|
|
||||||
useHotkeys('command+c,ctrl+c', (e) => {
|
useHotkeys('command+c,ctrl+c', () => {
|
||||||
tlstate.copy()
|
tlstate.copy()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('command+v,ctrl+v', (e) => {
|
useHotkeys('command+v,ctrl+v', () => {
|
||||||
tlstate.paste()
|
tlstate.paste()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Move
|
// Move
|
||||||
|
|
||||||
useHotkeys('[', (e) => {
|
useHotkeys('[', () => {
|
||||||
tlstate.moveBackward()
|
tlstate.moveBackward()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys(']', (e) => {
|
useHotkeys(']', () => {
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+[', (e) => {
|
useHotkeys('shift+[', () => {
|
||||||
tlstate.moveToBack()
|
tlstate.moveToBack()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('shift+]', (e) => {
|
useHotkeys('shift+]', () => {
|
||||||
tlstate.moveToFront()
|
tlstate.moveToFront()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
useHotkeys('command+shift+backspace', (e) => {
|
useHotkeys('command+shift+backspace', () => {
|
||||||
tlstate.reset()
|
tlstate.reset()
|
||||||
e.preventDefault()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
2134
packages/tldraw/src/state/__tlstate.ts
Normal file
2134
packages/tldraw/src/state/__tlstate.ts
Normal file
File diff suppressed because it is too large
Load diff
|
@ -46,11 +46,11 @@ describe('Move command', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['b'])
|
tlstate.setSelectedIds(['b'])
|
||||||
tlstate.moveToBack()
|
tlstate.moveToBack()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('bacd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||||
tlstate.undo()
|
tlstate.undo()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('abcd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||||
tlstate.redo()
|
tlstate.redo()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('bacd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('to back', () => {
|
describe('to back', () => {
|
||||||
|
@ -58,21 +58,21 @@ describe('Move command', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['b'])
|
tlstate.setSelectedIds(['b'])
|
||||||
tlstate.moveToBack()
|
tlstate.moveToBack()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('bacd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two adjacent siblings to back', () => {
|
it('moves two adjacent siblings to back', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['b', 'c'])
|
tlstate.setSelectedIds(['b', 'c'])
|
||||||
tlstate.moveToBack()
|
tlstate.moveToBack()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('bcad')
|
expect(getSortedShapeIds(tlstate.state)).toBe('bcad')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two non-adjacent siblings to back', () => {
|
it('moves two non-adjacent siblings to back', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['b', 'd'])
|
tlstate.setSelectedIds(['b', 'd'])
|
||||||
tlstate.moveToBack()
|
tlstate.moveToBack()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('bdac')
|
expect(getSortedShapeIds(tlstate.state)).toBe('bdac')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -81,35 +81,35 @@ describe('Move command', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['c'])
|
tlstate.setSelectedIds(['c'])
|
||||||
tlstate.moveBackward()
|
tlstate.moveBackward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('acbd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('acbd')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves a shape at first index backward', () => {
|
it('moves a shape at first index backward', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['a'])
|
tlstate.setSelectedIds(['a'])
|
||||||
tlstate.moveBackward()
|
tlstate.moveBackward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('abcd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two adjacent siblings backward', () => {
|
it('moves two adjacent siblings backward', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['c', 'd'])
|
tlstate.setSelectedIds(['c', 'd'])
|
||||||
tlstate.moveBackward()
|
tlstate.moveBackward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('acdb')
|
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two non-adjacent siblings backward', () => {
|
it('moves two non-adjacent siblings backward', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['b', 'd'])
|
tlstate.setSelectedIds(['b', 'd'])
|
||||||
tlstate.moveBackward()
|
tlstate.moveBackward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('badc')
|
expect(getSortedShapeIds(tlstate.state)).toBe('badc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two adjacent siblings backward at zero index', () => {
|
it('moves two adjacent siblings backward at zero index', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['a', 'b'])
|
tlstate.setSelectedIds(['a', 'b'])
|
||||||
tlstate.moveBackward()
|
tlstate.moveBackward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('abcd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ describe('Move command', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['c'])
|
tlstate.setSelectedIds(['c'])
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('abdc')
|
expect(getSortedShapeIds(tlstate.state)).toBe('abdc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves a shape forward at the top index', () => {
|
it('moves a shape forward at the top index', () => {
|
||||||
|
@ -127,28 +127,28 @@ describe('Move command', () => {
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('acdb')
|
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two adjacent siblings forward', () => {
|
it('moves two adjacent siblings forward', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['a', 'b'])
|
tlstate.setSelectedIds(['a', 'b'])
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('cabd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('cabd')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two non-adjacent siblings forward', () => {
|
it('moves two non-adjacent siblings forward', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['a', 'c'])
|
tlstate.setSelectedIds(['a', 'c'])
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('badc')
|
expect(getSortedShapeIds(tlstate.state)).toBe('badc')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two adjacent siblings forward at top index', () => {
|
it('moves two adjacent siblings forward at top index', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['c', 'd'])
|
tlstate.setSelectedIds(['c', 'd'])
|
||||||
tlstate.moveForward()
|
tlstate.moveForward()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('abcd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -157,28 +157,28 @@ describe('Move command', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['b'])
|
tlstate.setSelectedIds(['b'])
|
||||||
tlstate.moveToFront()
|
tlstate.moveToFront()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('acdb')
|
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two adjacent siblings to front', () => {
|
it('moves two adjacent siblings to front', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['a', 'b'])
|
tlstate.setSelectedIds(['a', 'b'])
|
||||||
tlstate.moveToFront()
|
tlstate.moveToFront()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('cdab')
|
expect(getSortedShapeIds(tlstate.state)).toBe('cdab')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves two non-adjacent siblings to front', () => {
|
it('moves two non-adjacent siblings to front', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['a', 'c'])
|
tlstate.setSelectedIds(['a', 'c'])
|
||||||
tlstate.moveToFront()
|
tlstate.moveToFront()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('bdac')
|
expect(getSortedShapeIds(tlstate.state)).toBe('bdac')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('moves siblings already at front to front', () => {
|
it('moves siblings already at front to front', () => {
|
||||||
tlstate.loadDocument(doc)
|
tlstate.loadDocument(doc)
|
||||||
tlstate.setSelectedIds(['c', 'd'])
|
tlstate.setSelectedIds(['c', 'd'])
|
||||||
tlstate.moveToFront()
|
tlstate.moveToFront()
|
||||||
expect(getSortedShapeIds(tlstate.data)).toBe('abcd')
|
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -41,7 +41,7 @@ describe('Arrow session', () => {
|
||||||
expect(binding.fromId).toBe('arrow1')
|
expect(binding.fromId).toBe('arrow1')
|
||||||
expect(binding.toId).toBe('target1')
|
expect(binding.toId).toBe('target1')
|
||||||
expect(binding.handleId).toBe('start')
|
expect(binding.handleId).toBe('start')
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
expect(tlstate.getShape('arrow1').handles?.start.bindingId).toBe(binding.id)
|
expect(tlstate.getShape('arrow1').handles?.start.bindingId).toBe(binding.id)
|
||||||
|
|
||||||
tlstate.undo()
|
tlstate.undo()
|
||||||
|
|
|
@ -11,7 +11,7 @@ describe('Brush session', () => {
|
||||||
tlstate.startBrushSession([-10, -10])
|
tlstate.startBrushSession([-10, -10])
|
||||||
tlstate.updateBrushSession([10, 10])
|
tlstate.updateBrushSession([10, 10])
|
||||||
tlstate.completeSession()
|
tlstate.completeSession()
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
expect(tlstate.selectedIds.length).toBe(1)
|
expect(tlstate.selectedIds.length).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe('Transform session', () => {
|
||||||
.updateDrawSession([10, 10], 0.5)
|
.updateDrawSession([10, 10], 0.5)
|
||||||
.completeSession()
|
.completeSession()
|
||||||
|
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('does, undoes and redoes', () => {
|
it('does, undoes and redoes', () => {
|
||||||
|
|
|
@ -20,7 +20,7 @@ describe('Handle session', () => {
|
||||||
.updateHandleSession([10, 10])
|
.updateHandleSession([10, 10])
|
||||||
.completeSession()
|
.completeSession()
|
||||||
|
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
|
|
||||||
tlstate.undo().redo()
|
tlstate.undo().redo()
|
||||||
})
|
})
|
||||||
|
|
|
@ -35,7 +35,7 @@ describe('Brush session', () => {
|
||||||
|
|
||||||
tlstate.completeSession()
|
tlstate.completeSession()
|
||||||
|
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
|
|
||||||
tlstate.undo()
|
tlstate.undo()
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe('Transform single session', () => {
|
||||||
.updateTransformSession([10, 10])
|
.updateTransformSession([10, 10])
|
||||||
.completeSession()
|
.completeSession()
|
||||||
|
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
|
|
||||||
tlstate.undo().redo()
|
tlstate.undo().redo()
|
||||||
})
|
})
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe('Transform session', () => {
|
||||||
.updateTransformSession([10, 10])
|
.updateTransformSession([10, 10])
|
||||||
.completeSession()
|
.completeSession()
|
||||||
|
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
|
|
||||||
expect(getShapeBounds(tlstate, 'rect1')).toMatchObject({
|
expect(getShapeBounds(tlstate, 'rect1')).toMatchObject({
|
||||||
minX: 10,
|
minX: 10,
|
||||||
|
|
|
@ -17,7 +17,7 @@ describe('Brush session', () => {
|
||||||
|
|
||||||
tlstate.completeSession()
|
tlstate.completeSession()
|
||||||
|
|
||||||
expect(tlstate.status.current).toBe(TLDrawStatus.Idle)
|
expect(tlstate.appState.status.current).toBe(TLDrawStatus.Idle)
|
||||||
|
|
||||||
expect(tlstate.getShape('rect1').point).toStrictEqual([5, 5])
|
expect(tlstate.getShape('rect1').point).toStrictEqual([5, 5])
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { TLDrawState } from './tlstate'
|
import { TLDrawState } from './tlstate'
|
||||||
import { mockDocument, TLStateUtils } from '~test'
|
import { mockDocument, TLStateUtils } from '~test'
|
||||||
import { Utils } from '@tldraw/core'
|
|
||||||
|
|
||||||
describe('TLDrawState', () => {
|
describe('TLDrawState', () => {
|
||||||
const tlstate = new TLDrawState()
|
const tlstate = new TLDrawState()
|
||||||
|
@ -52,7 +51,7 @@ describe('TLDrawState', () => {
|
||||||
tlstate.loadDocument(mockDocument).deselectAll()
|
tlstate.loadDocument(mockDocument).deselectAll()
|
||||||
tlu.clickShape('rect1')
|
tlu.clickShape('rect1')
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect1'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect1'])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('selects and deselects a shape', () => {
|
it('selects and deselects a shape', () => {
|
||||||
|
@ -60,7 +59,7 @@ describe('TLDrawState', () => {
|
||||||
tlu.clickShape('rect1')
|
tlu.clickShape('rect1')
|
||||||
tlu.clickCanvas()
|
tlu.clickCanvas()
|
||||||
expect(tlstate.selectedIds).toStrictEqual([])
|
expect(tlstate.selectedIds).toStrictEqual([])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('selects multiple shapes', () => {
|
it('selects multiple shapes', () => {
|
||||||
|
@ -68,7 +67,7 @@ describe('TLDrawState', () => {
|
||||||
tlu.clickShape('rect1')
|
tlu.clickShape('rect1')
|
||||||
tlu.clickShape('rect2', { shiftKey: true })
|
tlu.clickShape('rect2', { shiftKey: true })
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect1', 'rect2'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect1', 'rect2'])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('shift-selects to deselect shapes', () => {
|
it('shift-selects to deselect shapes', () => {
|
||||||
|
@ -78,7 +77,7 @@ describe('TLDrawState', () => {
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect1', 'rect2'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect1', 'rect2'])
|
||||||
tlu.clickShape('rect2', { shiftKey: true })
|
tlu.clickShape('rect2', { shiftKey: true })
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect1'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect1'])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('clears selection when clicking bounds', () => {
|
it('clears selection when clicking bounds', () => {
|
||||||
|
@ -105,14 +104,14 @@ describe('TLDrawState', () => {
|
||||||
tlstate.loadDocument(mockDocument).deselectAll()
|
tlstate.loadDocument(mockDocument).deselectAll()
|
||||||
tlu.clickShape('rect1', { ctrlKey: true })
|
tlu.clickShape('rect1', { ctrlKey: true })
|
||||||
expect(tlstate.selectedIds).toStrictEqual([])
|
expect(tlstate.selectedIds).toStrictEqual([])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('does not select on meta-shift-click', () => {
|
it('does not select on meta-shift-click', () => {
|
||||||
tlstate.loadDocument(mockDocument).deselectAll()
|
tlstate.loadDocument(mockDocument).deselectAll()
|
||||||
tlu.clickShape('rect1', { ctrlKey: true, shiftKey: true })
|
tlu.clickShape('rect1', { ctrlKey: true, shiftKey: true })
|
||||||
expect(tlstate.selectedIds).toStrictEqual([])
|
expect(tlstate.selectedIds).toStrictEqual([])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('deletes shapes if cancelled during creating', () => {
|
it('deletes shapes if cancelled during creating', () => {
|
||||||
|
@ -139,7 +138,7 @@ describe('TLDrawState', () => {
|
||||||
tlu.clickShape('rect2', { shiftKey: true })
|
tlu.clickShape('rect2', { shiftKey: true })
|
||||||
tlu.clickShape('rect2')
|
tlu.clickShape('rect2')
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect2'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect2'])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('single-selects shape in selection on pointerup only', () => {
|
it('single-selects shape in selection on pointerup only', () => {
|
||||||
|
@ -150,17 +149,17 @@ describe('TLDrawState', () => {
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect1', 'rect2'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect1', 'rect2'])
|
||||||
tlu.stopPointing('rect2')
|
tlu.stopPointing('rect2')
|
||||||
expect(tlstate.selectedIds).toStrictEqual(['rect2'])
|
expect(tlstate.selectedIds).toStrictEqual(['rect2'])
|
||||||
expect(tlstate.status.current).toBe('idle')
|
expect(tlstate.appState.status.current).toBe('idle')
|
||||||
})
|
})
|
||||||
|
|
||||||
// it('selects shapes if shift key is lifted before pointerup', () => {
|
// it('selects shapes if shift key is lifted before pointerup', () => {
|
||||||
// tlstate.deselectAll()
|
// tlstate.deselectAll()
|
||||||
// tlu.clickShape('rect1')
|
// tlu.clickShape('rect1')
|
||||||
// tlu.pointShape('rect2', { shiftKey: true })
|
// tlu.pointShape('rect2', { shiftKey: true })
|
||||||
// expect(tlstate.status.current).toBe('pointingBounds')
|
// expect(tlstate.appState.status.current).toBe('pointingBounds')
|
||||||
// tlu.stopPointing('rect2')
|
// tlu.stopPointing('rect2')
|
||||||
// expect(tlstate.selectedIds).toStrictEqual(['rect2'])
|
// expect(tlstate.selectedIds).toStrictEqual(['rect2'])
|
||||||
// expect(tlstate.status.current).toBe('idle')
|
// expect(tlstate.appState.status.current).toBe('idle')
|
||||||
// })
|
// })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,7 +8,7 @@ import { render } from '@testing-library/react'
|
||||||
export const Wrapper: React.FC = ({ children }) => {
|
export const Wrapper: React.FC = ({ children }) => {
|
||||||
const [tlstate] = React.useState(() => new TLDrawState())
|
const [tlstate] = React.useState(() => new TLDrawState())
|
||||||
const [context] = React.useState(() => {
|
const [context] = React.useState(() => {
|
||||||
return { tlstate, useSelector: tlstate.store }
|
return { tlstate, useSelector: tlstate.useStore }
|
||||||
})
|
})
|
||||||
|
|
||||||
useKeyboardShortcuts(tlstate)
|
useKeyboardShortcuts(tlstate)
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
import '@testing-library/jest-dom/extend-expect'
|
import '@testing-library/jest-dom/extend-expect'
|
||||||
|
import "fake-indexeddb/auto"
|
|
@ -20,7 +20,7 @@
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"strictFunctionTypes": true /* Enable strict checking of function types. */,
|
"strictFunctionTypes": true /* Enable strict checking of function types. */,
|
||||||
"strictNullChecks": true /* Enable strict null checks. */,
|
"strictNullChecks": true /* Enable strict null checks. */,
|
||||||
"target": "es5",
|
"target": "es6",
|
||||||
"typeRoots": ["node_modules/@types", "node_modules/jest"],
|
"typeRoots": ["node_modules/@types", "node_modules/jest"],
|
||||||
"types": ["node", "jest"],
|
"types": ["node", "jest"],
|
||||||
"jsx": "preserve",
|
"jsx": "preserve",
|
||||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue