Adds dev server
This commit is contained in:
parent
5998879e24
commit
4ac1b93f96
22 changed files with 1165 additions and 1896 deletions
18
.eslintrc.js
18
.eslintrc.js
|
@ -1,11 +1,15 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
||||
overrides: [
|
||||
{
|
||||
// enable the rule specifically for TypeScript files
|
||||
files: ['*.ts', '*.tsx'],
|
||||
rules: {
|
||||
'@typescript-eslint/explicit-module-boundary-types': [false],
|
||||
},
|
||||
},
|
||||
],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"packages": [
|
||||
"packages/core",
|
||||
"packages/tldraw",
|
||||
"packages/www"
|
||||
"packages/dev"
|
||||
]
|
||||
}
|
||||
}
|
21
package.json
21
package.json
|
@ -10,8 +10,18 @@
|
|||
"license": "MIT",
|
||||
"version": "0.0.36",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
"packages/core",
|
||||
"packages/tldraw",
|
||||
"packages/dev"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"lerna": "lerna",
|
||||
"start": "lerna run dev --stream --parallel",
|
||||
"start:www": "lerna run dev --stream --parallel & cd packages/www && yarn build",
|
||||
"build": "yarn build:packages && cd packages/www && yarn build",
|
||||
"build:packages": "cd packages/core && yarn build && cd ../tldraw && yarn build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
||||
"@babel/preset-react": "^7.14.5",
|
||||
|
@ -32,20 +42,13 @@
|
|||
"tslib": "^2.3.0",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"lerna": "lerna",
|
||||
"start": "lerna run dev --stream --parallel",
|
||||
"build": "yarn build:packages && cd packages/www && yarn build",
|
||||
"build:packages": "cd packages/core && yarn build && cd ../tldraw && yarn build"
|
||||
},
|
||||
"dependencies": {},
|
||||
"prettier": {
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"printWidth": 100
|
||||
},
|
||||
"dependencies": {},
|
||||
"jest": {
|
||||
"preset": "ts-jest",
|
||||
"transform": {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||
import * as React from 'react'
|
||||
|
||||
export function usePreventNavigation(rCanvas: React.RefObject<SVGGElement>) {
|
||||
export function usePreventNavigation(rCanvas: React.RefObject<SVGGElement>): void {
|
||||
React.useEffect(() => {
|
||||
const preventGestureNavigation = (event: TouchEvent) => {
|
||||
event.preventDefault()
|
||||
|
@ -27,7 +27,7 @@ export function usePreventNavigation(rCanvas: React.RefObject<SVGGElement>) {
|
|||
|
||||
const elm = rCanvas.current
|
||||
|
||||
if (!elm) return () => {}
|
||||
if (!elm) return () => void null
|
||||
|
||||
elm.addEventListener('touchstart', preventGestureNavigation)
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ function useTheme<T = AnyTheme>(prefix: string, theme: T, selector = ':root') {
|
|||
function useStyle(uid: string, rules: string) {
|
||||
React.useLayoutEffect(() => {
|
||||
if (styles.get(uid)) {
|
||||
return () => {}
|
||||
return () => void null
|
||||
}
|
||||
|
||||
const style = document.createElement('style')
|
||||
|
|
|
@ -15,6 +15,8 @@ export function useZoomEvents() {
|
|||
|
||||
useWheel(
|
||||
({ event: e, delta }) => {
|
||||
e.preventDefault()
|
||||
|
||||
if (Vec.isEqual(delta, [0, 0])) return
|
||||
|
||||
const info = inputs.pan(delta, e as WheelEvent)
|
||||
|
|
18
packages/dev/README.md
Normal file
18
packages/dev/README.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# react-esbuild-starter
|
||||
|
||||
Starter template for React and Typescript.
|
||||
Inspired by https://github.com/sikanhe/rescript-esbuild-starter
|
||||
|
||||
It provides minimal yet 🔥 blazing fast ™ development boilerplate for rapid React prototyping.
|
||||
|
||||
- `yarn start` Starts typescript typechecking and esbuild in watch mode, and serves web page at localhost:5000.
|
||||
- `yarn build` Builds production bundle for browser, outputs bundle to dist/bundle.js with source map.
|
||||
- `yarn clean` Clean up assets produced by esbuild.
|
||||
|
||||
All code bundling and transpilation is handled by esbuild. Its configuration is kept inside `esbuild.config.mjs`. Follow [esbuild docs](https://esbuild.github.io/getting-started/) to see all supported options.
|
||||
|
||||
### Caveats
|
||||
|
||||
- No output file hashing
|
||||
- No test runner
|
||||
- Importing CSS in JS file is not supported in esbuild yet. It is currently in development https://github.com/evanw/esbuild/issues/20. In meantime either opt-in for some CSS-in-JS solution, or include styles directly in `www/index.html`.
|
34
packages/dev/esbuild.config.mjs
Normal file
34
packages/dev/esbuild.config.mjs
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* eslint-disable no-undef */
|
||||
import esbuild from 'esbuild'
|
||||
import serve, { error, log } from 'create-serve'
|
||||
|
||||
const isDevServer = process.argv.includes('--dev')
|
||||
|
||||
esbuild
|
||||
.build({
|
||||
entryPoints: ['src/index.tsx'],
|
||||
bundle: true,
|
||||
outfile: 'dist/bundle.js',
|
||||
minify: false,
|
||||
sourcemap: true,
|
||||
incremental: isDevServer,
|
||||
target: ['chrome58', 'firefox57', 'safari11', 'edge18'],
|
||||
define: {
|
||||
'process.env.NODE_ENV': isDevServer ? '"development"' : '"production"',
|
||||
},
|
||||
watch: isDevServer && {
|
||||
onRebuild(err) {
|
||||
serve.update()
|
||||
err ? error('❌ Failed') : log('✅ Updated')
|
||||
},
|
||||
},
|
||||
})
|
||||
.catch(() => process.exit(1))
|
||||
|
||||
if (isDevServer) {
|
||||
serve.start({
|
||||
port: 5000,
|
||||
root: './dist',
|
||||
live: true,
|
||||
})
|
||||
}
|
34
packages/dev/package.json
Normal file
34
packages/dev/package.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "react-esbuild-starter",
|
||||
"version": "2.1.0",
|
||||
"private": true,
|
||||
"description": "Starter template for React + Typescript, powered by Esbuild",
|
||||
"repository": "https://github.com/belaczek/react-esbuild-starter.git",
|
||||
"author": "Tomas Belada <tomas@belada.net>",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"react",
|
||||
"typescript",
|
||||
"esbuild"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "node ./esbuild.config.mjs --dev tsc --watch",
|
||||
"test": "echo 'TODO'"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"@tldraw/tldraw": "*",
|
||||
"idb": "^6.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.14.35",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"concurrently": "6.0.1",
|
||||
"create-serve": "1.0.1",
|
||||
"esbuild": "0.11.5",
|
||||
"rimraf": "3.0.2",
|
||||
"typescript": "4.2.3"
|
||||
}
|
||||
}
|
6
packages/dev/src/app.tsx
Normal file
6
packages/dev/src/app.tsx
Normal file
|
@ -0,0 +1,6 @@
|
|||
import * as React from 'react'
|
||||
import Editor from './components/editor'
|
||||
|
||||
export default function App(): JSX.Element {
|
||||
return <Editor />
|
||||
}
|
99
packages/dev/src/components/editor.tsx
Normal file
99
packages/dev/src/components/editor.tsx
Normal file
|
@ -0,0 +1,99 @@
|
|||
import * as React from 'react'
|
||||
import { ColorStyle, DashStyle, SizeStyle, TLDrawShapeType, TLDrawState } from '@tldraw/tldraw'
|
||||
import { TLDraw, TLDrawDocument } from '@tldraw/tldraw'
|
||||
import { usePersistence } from '../hooks/usePersistence'
|
||||
|
||||
const initialDoc: TLDrawDocument = {
|
||||
id: 'doc',
|
||||
pages: {
|
||||
page1: {
|
||||
id: 'page1',
|
||||
shapes: {
|
||||
rect1: {
|
||||
id: 'rect1',
|
||||
parentId: 'page1',
|
||||
name: 'Rectangle',
|
||||
childIndex: 1,
|
||||
type: TLDrawShapeType.Rectangle,
|
||||
point: [32, 32],
|
||||
size: [100, 100],
|
||||
style: {
|
||||
dash: DashStyle.Draw,
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Blue,
|
||||
},
|
||||
},
|
||||
ellipse1: {
|
||||
id: 'ellipse1',
|
||||
parentId: 'page1',
|
||||
name: 'Ellipse',
|
||||
childIndex: 2,
|
||||
type: TLDrawShapeType.Ellipse,
|
||||
point: [132, 132],
|
||||
radius: [50, 50],
|
||||
style: {
|
||||
dash: DashStyle.Draw,
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Cyan,
|
||||
},
|
||||
},
|
||||
draw1: {
|
||||
id: 'draw1',
|
||||
parentId: 'page1',
|
||||
name: 'Draw',
|
||||
childIndex: 3,
|
||||
type: TLDrawShapeType.Draw,
|
||||
point: [232, 232],
|
||||
points: [
|
||||
[50, 0],
|
||||
[100, 100],
|
||||
[0, 100],
|
||||
[50, 0],
|
||||
[100, 100],
|
||||
[0, 100],
|
||||
[50, 0],
|
||||
[56, 5],
|
||||
],
|
||||
style: {
|
||||
dash: DashStyle.Draw,
|
||||
size: SizeStyle.Medium,
|
||||
color: ColorStyle.Green,
|
||||
},
|
||||
},
|
||||
},
|
||||
bindings: {},
|
||||
},
|
||||
},
|
||||
pageStates: {
|
||||
page1: {
|
||||
id: 'page1',
|
||||
selectedIds: [],
|
||||
currentParentId: 'page1',
|
||||
camera: {
|
||||
point: [0, 0],
|
||||
zoom: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default function Editor(): JSX.Element {
|
||||
const { value, setValue, status } = usePersistence('doc', initialDoc)
|
||||
|
||||
const handleChange = React.useCallback(
|
||||
(tlstate: TLDrawState, reason: string) => {
|
||||
if (reason.startsWith('session')) {
|
||||
return
|
||||
}
|
||||
|
||||
setValue(tlstate.document)
|
||||
},
|
||||
[setValue]
|
||||
)
|
||||
|
||||
if (status === 'loading' || value === null) {
|
||||
return <div />
|
||||
}
|
||||
|
||||
return <TLDraw document={value} onChange={handleChange} />
|
||||
}
|
93
packages/dev/src/hooks/usePersistence.tsx
Normal file
93
packages/dev/src/hooks/usePersistence.tsx
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import * as React from 'react'
|
||||
import { openDB, DBSchema } from 'idb'
|
||||
import type { TLDrawDocument } from '@tldraw/tldraw'
|
||||
|
||||
interface TLDatabase extends DBSchema {
|
||||
documents: {
|
||||
key: string
|
||||
value: TLDrawDocument
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist a value in indexdb. This hook is designed to be used primarily through
|
||||
* its methods, `setValue` and `forceUpdate`. The `setValue` method will update the
|
||||
* value in the database, howeever it will NOT cause the hook's component to update.
|
||||
* The `forceUpdate` method will cause the component to update with the latest value
|
||||
* in the database.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
*```ts
|
||||
* const {status, value, setValue, forceUpdate} = usePersistence()
|
||||
*```
|
||||
*/
|
||||
export function usePersistence(id: string, doc: TLDrawDocument) {
|
||||
const [status, setStatus] = React.useState<'loading' | 'ready'>('loading')
|
||||
const [value, _setValue] = React.useState<TLDrawDocument | null>(null)
|
||||
|
||||
// A function that other parts of the program can use to manually update
|
||||
// the state to the latest value in the database.
|
||||
const forceUpdate = React.useCallback(() => {
|
||||
_setValue(null)
|
||||
setStatus('loading')
|
||||
|
||||
openDB<TLDatabase>('db', 1).then((db) =>
|
||||
db.get('documents', id).then((v) => {
|
||||
if (!v) throw Error(`Could not find document with id: ${id}`)
|
||||
_setValue(v)
|
||||
setStatus('ready')
|
||||
})
|
||||
)
|
||||
}, [id])
|
||||
|
||||
// A function that other parts of the program can use to manually set the
|
||||
// value in the database.
|
||||
const setValue = React.useCallback(
|
||||
(doc: TLDrawDocument) => {
|
||||
openDB<TLDatabase>('db', 1).then((db) => db.put('documents', doc, id))
|
||||
},
|
||||
[id]
|
||||
)
|
||||
|
||||
// Whenever the id or doc changes, save the new value to the database and update
|
||||
// the state.
|
||||
React.useEffect(() => {
|
||||
async function handleLoad() {
|
||||
const db = await openDB<TLDatabase>('db', 1, {
|
||||
upgrade(db) {
|
||||
db.createObjectStore('documents')
|
||||
},
|
||||
})
|
||||
|
||||
let savedDoc: TLDrawDocument
|
||||
|
||||
try {
|
||||
const restoredDoc = await db.get('documents', id)
|
||||
if (!restoredDoc) throw Error('No document')
|
||||
savedDoc = restoredDoc
|
||||
restoredDoc.pageStates = Object.fromEntries(
|
||||
Object.entries(restoredDoc.pageStates).map(([pageId, pageState]) => [
|
||||
pageId,
|
||||
{
|
||||
...pageState,
|
||||
hoveredId: undefined,
|
||||
editingId: undefined,
|
||||
},
|
||||
])
|
||||
)
|
||||
} catch (e) {
|
||||
await db.put('documents', doc, id)
|
||||
savedDoc = doc
|
||||
}
|
||||
|
||||
_setValue(savedDoc)
|
||||
setStatus('ready')
|
||||
}
|
||||
|
||||
handleLoad()
|
||||
}, [id, doc])
|
||||
|
||||
return { value, status, setValue, forceUpdate }
|
||||
}
|
10
packages/dev/src/index.tsx
Normal file
10
packages/dev/src/index.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './app'
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
)
|
11
packages/dev/tsconfig.json
Normal file
11
packages/dev/tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "**/*.test.ts", "dist"],
|
||||
"compilerOptions": {
|
||||
"jsx": "preserve",
|
||||
"lib": ["dom", "esnext"],
|
||||
"module": "esnext",
|
||||
"outDir": "./dist/types"
|
||||
}
|
||||
}
|
559
packages/dev/yarn.lock
Normal file
559
packages/dev/yarn.lock
Normal file
|
@ -0,0 +1,559 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.0.0":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
|
||||
integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.12.13"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.12.11":
|
||||
version "7.12.11"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
|
||||
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
|
||||
|
||||
"@babel/highlight@^7.12.13":
|
||||
version "7.13.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1"
|
||||
integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.12.11"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@types/node@14.14.35":
|
||||
version "14.14.35"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.35.tgz#42c953a4e2b18ab931f72477e7012172f4ffa313"
|
||||
integrity sha512-Lt+wj8NVPx0zUmUwumiVXapmaLUcAk3yPuHCFVXras9k5VT9TdhJqKqGVUQCD60OTMCl0qxJ57OiTL0Mic3Iag==
|
||||
|
||||
"@types/normalize-package-data@^2.4.0":
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
|
||||
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
|
||||
|
||||
"@types/prop-types@*":
|
||||
version "15.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
|
||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||
|
||||
"@types/react-dom@17.0.2":
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.2.tgz#35654cf6c49ae162d5bc90843d5437dc38008d43"
|
||||
integrity sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@17.0.3":
|
||||
version "17.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
|
||||
integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
|
||||
integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==
|
||||
|
||||
ansi-regex@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
chalk@^2.0.0:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
dependencies:
|
||||
ansi-styles "^3.2.1"
|
||||
escape-string-regexp "^1.0.5"
|
||||
supports-color "^5.3.0"
|
||||
|
||||
chalk@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
|
||||
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
dependencies:
|
||||
color-name "1.1.3"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
concurrently@6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.0.1.tgz#b472efd9398bd9f5b117e22f72c3e50bf0a8a651"
|
||||
integrity sha512-YCF/Wf31a910hXu7eGN9/SyHKD/usw3Shw4IPYuqIsxxC39v92engYlIlOs/zXnBJtX/6aVuhgzfhZeGJkhU4w==
|
||||
dependencies:
|
||||
chalk "^4.1.0"
|
||||
date-fns "^2.16.1"
|
||||
lodash "^4.17.20"
|
||||
read-pkg "^5.2.0"
|
||||
rxjs "^6.6.3"
|
||||
spawn-command "^0.0.2-1"
|
||||
supports-color "^8.1.0"
|
||||
tree-kill "^1.2.2"
|
||||
yargs "^16.2.0"
|
||||
|
||||
create-serve@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/create-serve/-/create-serve-1.0.1.tgz#a52ec4cbd2d0f776d3e42338fa1f0dae69080c59"
|
||||
integrity sha512-cDAmBGhkwolS7ihq7SnPE8KwjYUZl5FaI9Pq5ZBwNelSKvFR9OoAA4/B5BfB/NC+eYaykBpX9RVMfuU4DHtrPw==
|
||||
|
||||
csstype@^3.0.2:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b"
|
||||
integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==
|
||||
|
||||
date-fns@^2.16.1:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
|
||||
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
error-ex@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
esbuild@0.11.5:
|
||||
version "0.11.5"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.11.5.tgz#25b18a2ff2fb9580683edce26a48f64c08c2f2df"
|
||||
integrity sha512-aRs6jAE+bVRp1tyfzUugAw1T/Y0Fwzp4Z2ROikF3h+UifoD5QlEbEYQGc6orNnnSIRhWR5VWBH7LozlAumaLHg==
|
||||
|
||||
escalade@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
glob@^7.1.3:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
has-flag@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
|
||||
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
|
||||
|
||||
is-core-module@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
|
||||
integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
json-parse-even-better-errors@^2.3.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
|
||||
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
|
||||
|
||||
lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
loose-envify@^1.1.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
normalize-package-data@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
|
||||
dependencies:
|
||||
hosted-git-info "^2.1.4"
|
||||
resolve "^1.10.0"
|
||||
semver "2 || 3 || 4 || 5"
|
||||
validate-npm-package-license "^3.0.1"
|
||||
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
parse-json@^5.0.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
|
||||
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.0.0"
|
||||
error-ex "^1.3.1"
|
||||
json-parse-even-better-errors "^2.3.0"
|
||||
lines-and-columns "^1.1.6"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
|
||||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
|
||||
react-dom@17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
|
||||
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react@17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
read-pkg@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
|
||||
integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
|
||||
dependencies:
|
||||
"@types/normalize-package-data" "^2.4.0"
|
||||
normalize-package-data "^2.5.0"
|
||||
parse-json "^5.0.0"
|
||||
type-fest "^0.6.0"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
resolve@^1.10.0:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||
dependencies:
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
rimraf@3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
rxjs@^6.6.3:
|
||||
version "6.6.6"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70"
|
||||
integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
scheduler@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
|
||||
integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
"semver@2 || 3 || 4 || 5":
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
spawn-command@^0.0.2-1:
|
||||
version "0.0.2-1"
|
||||
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
|
||||
integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=
|
||||
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||
integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
|
||||
dependencies:
|
||||
spdx-expression-parse "^3.0.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-exceptions@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
|
||||
integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
|
||||
|
||||
spdx-expression-parse@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
|
||||
integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
|
||||
dependencies:
|
||||
spdx-exceptions "^2.1.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-license-ids@^3.0.0:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65"
|
||||
integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
|
||||
integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
strip-ansi@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-color@^8.1.0:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
tree-kill@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
|
||||
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
|
||||
|
||||
tslib@^1.9.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
type-fest@^0.6.0:
|
||||
version "0.6.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b"
|
||||
integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
|
||||
|
||||
typescript@4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3"
|
||||
integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw==
|
||||
|
||||
validate-npm-package-license@^3.0.1:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
|
||||
integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
|
||||
dependencies:
|
||||
spdx-correct "^3.0.0"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
|
||||
integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.7"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
||||
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
||||
|
||||
yargs@^16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
|
@ -1,7 +1,7 @@
|
|||
import * as React from 'react'
|
||||
import { useTLDrawContext } from '../hooks'
|
||||
import type { Data } from '../state'
|
||||
import styled from '../styles'
|
||||
import { useTLDrawContext } from '../../hooks'
|
||||
import type { Data } from '../../state'
|
||||
import styled from '../../styles'
|
||||
|
||||
const activeToolSelector = (s: Data) => s.appState.activeTool
|
||||
|
|
@ -9,7 +9,7 @@ import {
|
|||
TextIcon,
|
||||
} from '@radix-ui/react-icons'
|
||||
import * as React from 'react'
|
||||
import { StatusBar } from '../status-bar'
|
||||
import { StatusBar } from './status-bar'
|
||||
import { FloatingContainer } from '../shared'
|
||||
import { PrimaryButton, SecondaryButton } from './shared'
|
||||
import styled from '../../styles'
|
||||
|
@ -24,118 +24,118 @@ const activeToolSelector = (s: Data) => s.appState.activeTool
|
|||
const isToolLockedSelector = (s: Data) => s.appState.isToolLocked
|
||||
const isDebugModeSelector = (s: Data) => s.settings.isDebugMode
|
||||
|
||||
export const ToolsPanel = React.memo(
|
||||
(): JSX.Element => {
|
||||
const { tlstate, useSelector } = useTLDrawContext()
|
||||
export const ToolsPanel = React.memo((): JSX.Element => {
|
||||
const { tlstate, useSelector } = useTLDrawContext()
|
||||
|
||||
const activeTool = useSelector(activeToolSelector)
|
||||
const activeTool = useSelector(activeToolSelector)
|
||||
|
||||
const isToolLocked = useSelector(isToolLockedSelector)
|
||||
const isToolLocked = useSelector(isToolLockedSelector)
|
||||
|
||||
const isDebugMode = useSelector(isDebugModeSelector)
|
||||
const isDebugMode = useSelector(isDebugModeSelector)
|
||||
|
||||
const selectSelectTool = React.useCallback(() => {
|
||||
tlstate.selectTool('select')
|
||||
}, [tlstate])
|
||||
const selectSelectTool = React.useCallback(() => {
|
||||
tlstate.selectTool('select')
|
||||
}, [tlstate])
|
||||
|
||||
const selectDrawTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Draw)
|
||||
}, [tlstate])
|
||||
const selectDrawTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Draw)
|
||||
}, [tlstate])
|
||||
|
||||
const selectRectangleTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Rectangle)
|
||||
}, [tlstate])
|
||||
const selectRectangleTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Rectangle)
|
||||
}, [tlstate])
|
||||
|
||||
const selectEllipseTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Ellipse)
|
||||
}, [tlstate])
|
||||
const selectEllipseTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Ellipse)
|
||||
}, [tlstate])
|
||||
|
||||
const selectArrowTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Arrow)
|
||||
}, [tlstate])
|
||||
const selectArrowTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Arrow)
|
||||
}, [tlstate])
|
||||
|
||||
const selectTextTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Text)
|
||||
}, [tlstate])
|
||||
const selectTextTool = React.useCallback(() => {
|
||||
tlstate.selectTool(TLDrawShapeType.Text)
|
||||
}, [tlstate])
|
||||
|
||||
return (
|
||||
<ToolsPanelContainer>
|
||||
<LeftWrap size={{ '@initial': 'mobile', '@sm': 'small' }}>
|
||||
<Zoom />
|
||||
<FloatingContainer>
|
||||
<SecondaryButton
|
||||
label={'Select'}
|
||||
kbd={'1'}
|
||||
onClick={selectSelectTool}
|
||||
isActive={activeTool === 'select'}
|
||||
>
|
||||
<CursorArrowIcon />
|
||||
</SecondaryButton>
|
||||
</FloatingContainer>
|
||||
</LeftWrap>
|
||||
<CenterWrap>
|
||||
<BackToContent />
|
||||
<FloatingContainer>
|
||||
<PrimaryButton
|
||||
kbd={'2'}
|
||||
label={TLDrawShapeType.Draw}
|
||||
onClick={selectDrawTool}
|
||||
isActive={activeTool === TLDrawShapeType.Draw}
|
||||
>
|
||||
<Pencil1Icon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'3'}
|
||||
label={TLDrawShapeType.Rectangle}
|
||||
onClick={selectRectangleTool}
|
||||
isActive={activeTool === TLDrawShapeType.Rectangle}
|
||||
>
|
||||
<SquareIcon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'4'}
|
||||
label={TLDrawShapeType.Draw}
|
||||
onClick={selectEllipseTool}
|
||||
isActive={activeTool === TLDrawShapeType.Ellipse}
|
||||
>
|
||||
<CircleIcon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'5'}
|
||||
label={TLDrawShapeType.Arrow}
|
||||
onClick={selectArrowTool}
|
||||
isActive={activeTool === TLDrawShapeType.Arrow}
|
||||
>
|
||||
<ArrowTopRightIcon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'6'}
|
||||
label={TLDrawShapeType.Text}
|
||||
onClick={selectTextTool}
|
||||
isActive={activeTool === TLDrawShapeType.Text}
|
||||
>
|
||||
<TextIcon />
|
||||
</PrimaryButton>
|
||||
</FloatingContainer>
|
||||
</CenterWrap>
|
||||
<RightWrap size={{ '@initial': 'mobile', '@sm': 'small' }}>
|
||||
<FloatingContainer>
|
||||
<SecondaryButton
|
||||
kbd={'7'}
|
||||
label={'Lock Tool'}
|
||||
onClick={tlstate.toggleToolLock}
|
||||
isActive={isToolLocked}
|
||||
>
|
||||
{isToolLocked ? <LockClosedIcon /> : <LockOpen1Icon />}
|
||||
</SecondaryButton>
|
||||
</FloatingContainer>
|
||||
<UndoRedo />
|
||||
</RightWrap>
|
||||
<StatusWrap>{isDebugMode && <StatusBar />}</StatusWrap>
|
||||
</ToolsPanelContainer>
|
||||
)
|
||||
}
|
||||
)
|
||||
return (
|
||||
<ToolsPanelContainer>
|
||||
<LeftWrap size={{ '@initial': 'mobile', '@sm': 'small' }}>
|
||||
<Zoom />
|
||||
<FloatingContainer>
|
||||
<SecondaryButton
|
||||
label={'Select'}
|
||||
kbd={'1'}
|
||||
onClick={selectSelectTool}
|
||||
isActive={activeTool === 'select'}
|
||||
>
|
||||
<CursorArrowIcon />
|
||||
</SecondaryButton>
|
||||
</FloatingContainer>
|
||||
</LeftWrap>
|
||||
<CenterWrap>
|
||||
<BackToContent />
|
||||
<FloatingContainer>
|
||||
<PrimaryButton
|
||||
kbd={'2'}
|
||||
label={TLDrawShapeType.Draw}
|
||||
onClick={selectDrawTool}
|
||||
isActive={activeTool === TLDrawShapeType.Draw}
|
||||
>
|
||||
<Pencil1Icon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'3'}
|
||||
label={TLDrawShapeType.Rectangle}
|
||||
onClick={selectRectangleTool}
|
||||
isActive={activeTool === TLDrawShapeType.Rectangle}
|
||||
>
|
||||
<SquareIcon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'4'}
|
||||
label={TLDrawShapeType.Draw}
|
||||
onClick={selectEllipseTool}
|
||||
isActive={activeTool === TLDrawShapeType.Ellipse}
|
||||
>
|
||||
<CircleIcon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'5'}
|
||||
label={TLDrawShapeType.Arrow}
|
||||
onClick={selectArrowTool}
|
||||
isActive={activeTool === TLDrawShapeType.Arrow}
|
||||
>
|
||||
<ArrowTopRightIcon />
|
||||
</PrimaryButton>
|
||||
<PrimaryButton
|
||||
kbd={'6'}
|
||||
label={TLDrawShapeType.Text}
|
||||
onClick={selectTextTool}
|
||||
isActive={activeTool === TLDrawShapeType.Text}
|
||||
>
|
||||
<TextIcon />
|
||||
</PrimaryButton>
|
||||
</FloatingContainer>
|
||||
</CenterWrap>
|
||||
<RightWrap size={{ '@initial': 'mobile', '@sm': 'small' }}>
|
||||
<FloatingContainer>
|
||||
<SecondaryButton
|
||||
kbd={'7'}
|
||||
label={'Lock Tool'}
|
||||
onClick={tlstate.toggleToolLock}
|
||||
isActive={isToolLocked}
|
||||
>
|
||||
{isToolLocked ? <LockClosedIcon /> : <LockOpen1Icon />}
|
||||
</SecondaryButton>
|
||||
</FloatingContainer>
|
||||
<UndoRedo />
|
||||
</RightWrap>
|
||||
<StatusWrap>
|
||||
<StatusBar />
|
||||
</StatusWrap>
|
||||
</ToolsPanelContainer>
|
||||
)
|
||||
})
|
||||
|
||||
const ToolsPanelContainer = styled('div', {
|
||||
position: 'fixed',
|
||||
|
|
|
@ -18,13 +18,7 @@ import {
|
|||
Vec,
|
||||
} from '@tldraw/core'
|
||||
import { brushUpdater } from '@tldraw/core'
|
||||
import {
|
||||
defaultStyle,
|
||||
ShapeStyles,
|
||||
TLDrawShape,
|
||||
TLDrawShapeType,
|
||||
TLDrawToolType,
|
||||
} from '../shape'
|
||||
import { defaultStyle, ShapeStyles, TLDrawShape, TLDrawShapeType, TLDrawToolType } from '../shape'
|
||||
import type {
|
||||
Data,
|
||||
Session,
|
||||
|
@ -45,19 +39,13 @@ import {
|
|||
TextSession,
|
||||
} from './session'
|
||||
import { TLDR } from './tldr'
|
||||
import {
|
||||
TLDrawDocument,
|
||||
MoveType,
|
||||
AlignType,
|
||||
StretchType,
|
||||
DistributeType,
|
||||
} from '../types'
|
||||
import { TLDrawDocument, MoveType, AlignType, StretchType, DistributeType } from '../types'
|
||||
|
||||
const initialData: Data = {
|
||||
settings: {
|
||||
isPenMode: false,
|
||||
isDarkMode: false,
|
||||
isDebugMode: false,
|
||||
isDebugMode: process.env.NODE_ENV === 'development',
|
||||
isReadonlyMode: false,
|
||||
nudgeDistanceLarge: 10,
|
||||
nudgeDistanceSmall: 1,
|
||||
|
@ -115,9 +103,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
// Low API
|
||||
getState = this.store.getState
|
||||
|
||||
setState = <T extends keyof Data>(
|
||||
data: Partial<Data> | ((data: Data) => Partial<Data>)
|
||||
) => {
|
||||
setState = <T extends keyof Data>(data: Partial<Data> | ((data: Data) => Partial<Data>)) => {
|
||||
const current = this.getState()
|
||||
|
||||
// Apply incoming change
|
||||
|
@ -130,11 +116,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
...next.page,
|
||||
shapes: Object.fromEntries(
|
||||
Object.entries(next.page.shapes).filter(([_, shape]) => {
|
||||
return (
|
||||
shape &&
|
||||
(shape.parentId === next.page.id ||
|
||||
next.page.shapes[shape.parentId])
|
||||
)
|
||||
return shape && (shape.parentId === next.page.id || next.page.shapes[shape.parentId])
|
||||
})
|
||||
),
|
||||
}
|
||||
|
@ -241,9 +223,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
...data.appState,
|
||||
activeTool: tool,
|
||||
activeToolType:
|
||||
tool === 'select'
|
||||
? 'select'
|
||||
: TLDR.getShapeUtils({ type: tool } as TLDrawShape).toolType,
|
||||
tool === 'select' ? 'select' : TLDR.getShapeUtils({ type: tool } as TLDrawShape).toolType,
|
||||
},
|
||||
}))
|
||||
return this
|
||||
|
@ -261,18 +241,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
|
||||
/* --------------------- Camera --------------------- */
|
||||
zoomIn = () => {
|
||||
const i = Math.round(
|
||||
(this.store.getState().pageState.camera.zoom * 100) / 25
|
||||
)
|
||||
const i = Math.round((this.store.getState().pageState.camera.zoom * 100) / 25)
|
||||
const nextZoom = TLDR.getCameraZoom((i + 1) * 0.25)
|
||||
this.zoomTo(nextZoom)
|
||||
return this
|
||||
}
|
||||
|
||||
zoomOut = () => {
|
||||
const i = Math.round(
|
||||
(this.store.getState().pageState.camera.zoom * 100) / 25
|
||||
)
|
||||
const i = Math.round((this.store.getState().pageState.camera.zoom * 100) / 25)
|
||||
const nextZoom = TLDR.getCameraZoom((i - 1) * 0.25)
|
||||
this.zoomTo(nextZoom)
|
||||
return this
|
||||
|
@ -284,9 +260,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
|
||||
if (shapes.length === 0) return { pageState: data.pageState }
|
||||
|
||||
const bounds = Utils.getCommonBounds(
|
||||
Object.values(shapes).map(TLDR.getBounds)
|
||||
)
|
||||
const bounds = Utils.getCommonBounds(Object.values(shapes).map(TLDR.getBounds))
|
||||
|
||||
const zoom = TLDR.getCameraZoom(
|
||||
bounds.width > bounds.height
|
||||
|
@ -313,8 +287,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
|
||||
zoomToSelection = () => {
|
||||
this.setState((data) => {
|
||||
if (TLDR.getSelectedIds(data).length === 0)
|
||||
return { pageState: data.pageState }
|
||||
if (TLDR.getSelectedIds(data).length === 0) return { pageState: data.pageState }
|
||||
|
||||
const bounds = TLDR.getSelectedBounds(data)
|
||||
|
||||
|
@ -360,9 +333,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
|
||||
if (shapes.length === 0) return { pageState: data.pageState }
|
||||
|
||||
const bounds = Utils.getCommonBounds(
|
||||
Object.values(shapes).map(TLDR.getBounds)
|
||||
)
|
||||
const bounds = Utils.getCommonBounds(Object.values(shapes).map(TLDR.getBounds))
|
||||
|
||||
const { zoom } = data.pageState.camera
|
||||
const mx = (window.innerWidth - bounds.width * zoom) / 2 / zoom
|
||||
|
@ -452,10 +423,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
|
||||
/* ---------------------- Document --------------------- */
|
||||
loadDocument = (
|
||||
document: TLDrawDocument,
|
||||
onChange?: TLDrawState['_onChange']
|
||||
) => {
|
||||
loadDocument = (document: TLDrawDocument, onChange?: TLDrawState['_onChange']) => {
|
||||
this._onChange = onChange
|
||||
this.currentDocumentId = document.id
|
||||
this.pages = Utils.deepClone(document.pages)
|
||||
|
@ -489,19 +457,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
|
||||
/* -------------------- Sessions -------------------- */
|
||||
startSession<T extends Session>(
|
||||
session: T,
|
||||
...args: ParametersExceptFirst<T['start']>
|
||||
) {
|
||||
startSession<T extends Session>(session: T, ...args: ParametersExceptFirst<T['start']>) {
|
||||
this.session = session
|
||||
this.setState((data) => session.start(data, ...args))
|
||||
this._onChange?.(this, `session:start_${session.id}`)
|
||||
return this
|
||||
}
|
||||
|
||||
updateSession<T extends Session>(
|
||||
...args: ParametersExceptFirst<T['update']>
|
||||
) {
|
||||
updateSession<T extends Session>(...args: ParametersExceptFirst<T['update']>) {
|
||||
const { session } = this
|
||||
if (!session) return this
|
||||
this.setState((data) => session.update(data, ...args))
|
||||
|
@ -509,9 +472,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
return this
|
||||
}
|
||||
|
||||
cancelSession<T extends Session>(
|
||||
...args: ParametersExceptFirst<T['cancel']>
|
||||
) {
|
||||
cancelSession<T extends Session>(...args: ParametersExceptFirst<T['cancel']>) {
|
||||
const { session } = this
|
||||
if (!session) return this
|
||||
|
||||
|
@ -522,9 +483,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
return this
|
||||
}
|
||||
|
||||
completeSession<T extends Session>(
|
||||
...args: ParametersExceptFirst<T['complete']>
|
||||
) {
|
||||
completeSession<T extends Session>(...args: ParametersExceptFirst<T['complete']>) {
|
||||
const { session } = this
|
||||
if (!session) return this
|
||||
|
||||
|
@ -560,9 +519,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
|
||||
history.pointer = history.stack.length - 1
|
||||
|
||||
this.setState((data) =>
|
||||
Utils.deepMerge<Data>(data, history.stack[history.pointer].after)
|
||||
)
|
||||
this.setState((data) => Utils.deepMerge<Data>(data, history.stack[history.pointer].after))
|
||||
|
||||
this._onChange?.(this, `command:${command.id}`)
|
||||
|
||||
|
@ -607,9 +564,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
return {
|
||||
pageState: {
|
||||
...data.pageState,
|
||||
selectedIds: push
|
||||
? [...data.pageState.selectedIds, ...ids]
|
||||
: [...ids],
|
||||
selectedIds: push ? [...data.pageState.selectedIds, ...ids] : [...ids],
|
||||
},
|
||||
}
|
||||
})
|
||||
|
@ -715,9 +670,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
nudge = (delta: number[], isMajor = false, ids?: string[]) => {
|
||||
const data = this.store.getState()
|
||||
const idsToMutate = ids ? ids : data.pageState.selectedIds
|
||||
this.do(
|
||||
commands.translate(data, idsToMutate, Vec.mul(delta, isMajor ? 10 : 1))
|
||||
)
|
||||
this.do(commands.translate(data, idsToMutate, Vec.mul(delta, isMajor ? 10 : 1)))
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -846,20 +799,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
} catch (e) {
|
||||
// Create a text shape from the given string
|
||||
const childIndex =
|
||||
Object.values(data.page.shapes).sort(
|
||||
(a, b) => b.childIndex - a.childIndex
|
||||
)[0].childIndex + 1
|
||||
Object.values(data.page.shapes).sort((a, b) => b.childIndex - a.childIndex)[0]
|
||||
.childIndex + 1
|
||||
|
||||
const shape = TLDR.getShapeUtils<TextShape>(
|
||||
TLDrawShapeType.Text
|
||||
).create({
|
||||
const shape = TLDR.getShapeUtils<TextShape>(TLDrawShapeType.Text).create({
|
||||
id: Utils.uniqueId(),
|
||||
parentId: data.page.id,
|
||||
childIndex,
|
||||
point: this.getPagePoint([
|
||||
window.innerWidth / 2,
|
||||
window.innerHeight / 2,
|
||||
]),
|
||||
point: this.getPagePoint([window.innerWidth / 2, window.innerHeight / 2]),
|
||||
style: { ...data.appState.currentStyle },
|
||||
})
|
||||
|
||||
|
@ -888,19 +835,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
})
|
||||
|
||||
const commonBounds = Utils.getCommonBounds(
|
||||
shapesToPaste.map(TLDR.getBounds)
|
||||
)
|
||||
const commonBounds = Utils.getCommonBounds(shapesToPaste.map(TLDR.getBounds))
|
||||
|
||||
const centeredBounds = Utils.centerBounds(
|
||||
commonBounds,
|
||||
this.getPagePoint([window.innerWidth / 2, window.innerHeight / 2])
|
||||
)
|
||||
|
||||
let delta = Vec.sub(
|
||||
Utils.getBoundsCenter(centeredBounds),
|
||||
Utils.getBoundsCenter(commonBounds)
|
||||
)
|
||||
let delta = Vec.sub(Utils.getBoundsCenter(centeredBounds), Utils.getBoundsCenter(commonBounds))
|
||||
|
||||
if (Vec.isEqual(delta, [0, 0])) {
|
||||
delta = [16, 16]
|
||||
|
@ -948,11 +890,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
return this
|
||||
}
|
||||
|
||||
updateTranslateSession = (
|
||||
point: number[],
|
||||
shiftKey = false,
|
||||
altKey = false
|
||||
) => {
|
||||
updateTranslateSession = (point: number[], shiftKey = false, altKey = false) => {
|
||||
this.updateSession<TranslateSession>(point, shiftKey, altKey)
|
||||
return this
|
||||
}
|
||||
|
@ -983,26 +921,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
)
|
||||
} else {
|
||||
this.startSession(
|
||||
new TransformSession(
|
||||
this.store.getState(),
|
||||
point,
|
||||
this.pointedBoundsHandle
|
||||
)
|
||||
new TransformSession(this.store.getState(), point, this.pointedBoundsHandle)
|
||||
)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
updateTransformSession = (
|
||||
point: number[],
|
||||
shiftKey = false,
|
||||
altKey = false
|
||||
) => {
|
||||
this.updateSession<TransformSingleSession | TransformSession>(
|
||||
point,
|
||||
shiftKey,
|
||||
altKey
|
||||
)
|
||||
updateTransformSession = (point: number[], shiftKey = false, altKey = false) => {
|
||||
this.updateSession<TransformSingleSession | TransformSession>(point, shiftKey, altKey)
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -1029,23 +955,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
return this
|
||||
}
|
||||
|
||||
startHandleSession = (
|
||||
point: number[],
|
||||
handleId: string,
|
||||
commandId?: string
|
||||
) => {
|
||||
startHandleSession = (point: number[], handleId: string, commandId?: string) => {
|
||||
this.startSession<HandleSession>(
|
||||
new HandleSession(this.store.getState(), handleId, point, commandId)
|
||||
)
|
||||
return this
|
||||
}
|
||||
|
||||
updateHandleSession = (
|
||||
point: number[],
|
||||
shiftKey = false,
|
||||
altKey = false,
|
||||
metaKey = false
|
||||
) => {
|
||||
updateHandleSession = (point: number[], shiftKey = false, altKey = false, metaKey = false) => {
|
||||
this.updateSession<HandleSession>(point, shiftKey, altKey, metaKey)
|
||||
return this
|
||||
}
|
||||
|
@ -1055,20 +972,14 @@ export class TLDrawState implements TLCallbacks {
|
|||
case 'pointingBoundsHandle': {
|
||||
if (Vec.dist(info.origin, info.point) > 4) {
|
||||
this.setStatus('transforming')
|
||||
this.startTransformSession(
|
||||
this.getPagePoint(info.origin),
|
||||
this.pointedBoundsHandle!
|
||||
)
|
||||
this.startTransformSession(this.getPagePoint(info.origin), this.pointedBoundsHandle!)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'pointingHandle': {
|
||||
if (Vec.dist(info.origin, info.point) > 4) {
|
||||
this.setStatus('translatingHandle')
|
||||
this.startHandleSession(
|
||||
this.getPagePoint(info.origin),
|
||||
this.pointedHandle!
|
||||
)
|
||||
this.startHandleSession(this.getPagePoint(info.origin), this.pointedHandle!)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -1084,52 +995,29 @@ export class TLDrawState implements TLCallbacks {
|
|||
break
|
||||
}
|
||||
case 'translating': {
|
||||
this.updateTranslateSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateTranslateSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
break
|
||||
}
|
||||
case 'transforming': {
|
||||
this.updateTransformSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateTransformSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
break
|
||||
}
|
||||
case 'translatingHandle': {
|
||||
this.updateHandleSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateHandleSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
break
|
||||
}
|
||||
case 'creating': {
|
||||
switch (this.appState.activeToolType) {
|
||||
case 'draw': {
|
||||
this.updateDrawSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.pressure,
|
||||
info.shiftKey
|
||||
)
|
||||
this.updateDrawSession(this.getPagePoint(info.point), info.pressure, info.shiftKey)
|
||||
break
|
||||
}
|
||||
case 'bounds': {
|
||||
this.updateTransformSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey
|
||||
)
|
||||
this.updateTransformSession(this.getPagePoint(info.point), info.shiftKey)
|
||||
break
|
||||
}
|
||||
case 'handle': {
|
||||
this.updateHandleSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateHandleSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
break
|
||||
}
|
||||
case 'point': {
|
||||
|
@ -1193,11 +1081,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
break
|
||||
}
|
||||
case TLDrawToolType.Bounds: {
|
||||
this.startTransformSession(
|
||||
pagePoint,
|
||||
TLBoundsCorner.BottomRight,
|
||||
`create_${activeTool}`
|
||||
)
|
||||
this.startTransformSession(pagePoint, TLBoundsCorner.BottomRight, `create_${activeTool}`)
|
||||
break
|
||||
}
|
||||
case TLDrawToolType.Handle: {
|
||||
|
@ -1242,11 +1126,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
|
||||
if (key === 'Shift' || key === 'Alt') {
|
||||
this.updateTranslateSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateTranslateSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -1256,11 +1136,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
|
||||
if (key === 'Shift' || key === 'Alt') {
|
||||
this.updateTransformSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateTransformSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -1277,21 +1153,13 @@ export class TLDrawState implements TLCallbacks {
|
|||
}
|
||||
case 'transforming': {
|
||||
if (key === 'Shift' || key === 'Alt') {
|
||||
this.updateTransformSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateTransformSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'translating': {
|
||||
if (key === 'Shift' || key === 'Alt') {
|
||||
this.updateTransformSession(
|
||||
this.getPagePoint(info.point),
|
||||
info.shiftKey,
|
||||
info.altKey
|
||||
)
|
||||
this.updateTransformSession(this.getPagePoint(info.point), info.shiftKey, info.altKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -1380,9 +1248,7 @@ export class TLDrawState implements TLCallbacks {
|
|||
if (info.shiftKey) {
|
||||
// Unless we just shift-selected the shape, remove it from the selected shapes
|
||||
if (this.pointedId !== info.target) {
|
||||
this.setSelectedIds(
|
||||
data.pageState.selectedIds.filter((id) => id !== info.target)
|
||||
)
|
||||
this.setSelectedIds(data.pageState.selectedIds.filter((id) => id !== info.target))
|
||||
}
|
||||
}
|
||||
} else if (this.pointedId === info.target) {
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
"jsx": "preserve",
|
||||
"lib": ["dom", "esnext"],
|
||||
"module": "esnext",
|
||||
"outDir": "./dist/types"
|
||||
"outDir": "./dist/types",
|
||||
"paths": {
|
||||
"@tldraw/core": ["packages/core/dist"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@stitches/react": "^0.2.3",
|
||||
"@tldraw/tldraw": "latest",
|
||||
"@tldraw/tldraw": "*",
|
||||
"idb": "^6.1.2",
|
||||
"next": "^11.0.1",
|
||||
"next-transpile-modules": "^8.0.0",
|
||||
|
@ -36,4 +36,4 @@
|
|||
"eslint-config-next": "11.0.1",
|
||||
"typescript": "^4.3.5"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@
|
|||
"strictFunctionTypes": true /* Enable strict checking of function types. */,
|
||||
"strictNullChecks": true /* Enable strict null checks. */,
|
||||
"target": "es5",
|
||||
"typeRoots": ["node_modules/@types"],
|
||||
"typeRoots": ["node_modules/@types", "node_modules/jest"],
|
||||
"types": ["node", "jest"],
|
||||
"paths": {
|
||||
"@tldraw/*": ["./packages/*"]
|
||||
|
|
Loading…
Reference in a new issue