Tweak dev server
This commit is contained in:
parent
44e1c7dfdc
commit
9194ee7522
13 changed files with 1903 additions and 118 deletions
|
@ -9,6 +9,7 @@ describe('bounds', () => {
|
|||
zoom={1}
|
||||
bounds={{ minX: 0, minY: 0, maxX: 100, maxY: 100, width: 100, height: 100 }}
|
||||
rotation={0}
|
||||
viewportWidth={1000}
|
||||
isLocked={false}
|
||||
/>
|
||||
)
|
||||
|
|
|
@ -119,9 +119,9 @@ const tlcss = css`
|
|||
margin: 0px;
|
||||
touch-action: none;
|
||||
overscroll-behavior: none;
|
||||
overscroll-behavior-x: none;
|
||||
background-color: var(--tl-background);
|
||||
}
|
||||
|
||||
.tl-container * {
|
||||
user-select: none;
|
||||
box-sizing: border-box;
|
||||
|
@ -130,70 +130,85 @@ const tlcss = css`
|
|||
.tl-counter-scaled {
|
||||
transform: scale(var(--tl-scale));
|
||||
}
|
||||
|
||||
.tl-dashed {
|
||||
stroke-dasharray: calc(2px * var(--tl-scale)), calc(2px * var(--tl-scale));
|
||||
}
|
||||
|
||||
.tl-transparent {
|
||||
fill: transparent;
|
||||
stroke: transparent;
|
||||
}
|
||||
|
||||
.tl-cursor-ns {
|
||||
cursor: ns-resize;
|
||||
}
|
||||
|
||||
.tl-cursor-ew {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.tl-cursor-nesw {
|
||||
cursor: nesw-resize;
|
||||
}
|
||||
|
||||
.tl-cursor-nwse {
|
||||
cursor: nwse-resize;
|
||||
}
|
||||
|
||||
.tl-corner-handle {
|
||||
stroke: var(--tl-selectStroke);
|
||||
fill: var(--tl-background);
|
||||
stroke-width: calc(1.5px * var(--tl-scale));
|
||||
}
|
||||
|
||||
.tl-rotate-handle {
|
||||
stroke: var(--tl-selectStroke);
|
||||
fill: var(--tl-background);
|
||||
stroke-width: calc(1.5px * var(--tl-scale));
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.tl-binding {
|
||||
fill: var(--tl-selectFill);
|
||||
stroke: var(--tl-selectStroke);
|
||||
stroke-width: calc(1px * var(--tl-scale));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tl-selected {
|
||||
fill: transparent;
|
||||
stroke: var(--tl-selectStroke);
|
||||
stroke-width: calc(1.5px * var(--tl-scale));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tl-hovered {
|
||||
fill: transparent;
|
||||
stroke: var(--tl-selectStroke);
|
||||
stroke-width: calc(1.5px * var(--tl-scale));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tl-bounds-center {
|
||||
fill: transparent;
|
||||
stroke: var(--tl-selectStroke);
|
||||
stroke-width: calc(1.5px * var(--tl-scale));
|
||||
}
|
||||
|
||||
.tl-bounds-bg {
|
||||
stroke: none;
|
||||
fill: var(--tl-selectFill);
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.tl-brush {
|
||||
fill: var(--tl-brushFill);
|
||||
stroke: var(--tl-brushStroke);
|
||||
stroke-width: calc(1px * var(--tl-scale));
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tl-canvas {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
|
@ -204,50 +219,63 @@ const tlcss = css`
|
|||
touch-action: none;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.tl-dot {
|
||||
fill: var(--tl-background);
|
||||
stroke: var(--tl-foreground);
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.tl-handles {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.tl-handles:hover > .tl-handle-bg {
|
||||
fill: var(--tl-selectFill);
|
||||
}
|
||||
|
||||
.tl-handles:hover > .tl-handle-bg > * {
|
||||
stroke: var(--tl-selectFill);
|
||||
}
|
||||
|
||||
.tl-handles:active > .tl-handle-bg {
|
||||
fill: var(--tl-selectFill);
|
||||
}
|
||||
|
||||
.tl-handles:active > .tl-handle-bg > * {
|
||||
stroke: var(--tl-selectFill);
|
||||
}
|
||||
|
||||
.tl-handle {
|
||||
fill: var(--tl-background);
|
||||
stroke: var(--tl-selectStroke);
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
.tl-handle-bg {
|
||||
fill: transparent;
|
||||
stroke: none;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.tl-binding-indicator {
|
||||
stroke-width: calc(3px * var(--tl-scale));
|
||||
fill: var(--tl-selectFill);
|
||||
stroke: var(--tl-selected);
|
||||
}
|
||||
|
||||
.tl-shape-group {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tl-shape-group > *[data-shy='true'] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.tl-shape-group:hover > *[data-shy='true'] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.tl-current-parent > *[data-shy='true'] {
|
||||
opacity: 1;
|
||||
}
|
||||
|
|
|
@ -5,21 +5,11 @@ import serve, { error, log } from 'create-serve'
|
|||
|
||||
const isDevServer = process.argv.includes('--dev')
|
||||
|
||||
if (!fs.existsSync('./dist')) {
|
||||
fs.mkdirSync('./dist')
|
||||
}
|
||||
|
||||
for (const file of ['styles.css', 'index.html']) {
|
||||
fs.copyFile(`./src/${file}`, './dist/${file}', (err) => {
|
||||
if (err) throw err
|
||||
})
|
||||
}
|
||||
|
||||
esbuild
|
||||
.build({
|
||||
entryPoints: ['src/index.tsx'],
|
||||
bundle: true,
|
||||
outfile: 'dist/bundle.js',
|
||||
outdir: 'dist',
|
||||
minify: false,
|
||||
sourcemap: true,
|
||||
incremental: isDevServer,
|
||||
|
@ -37,6 +27,11 @@ esbuild
|
|||
})
|
||||
.catch(() => process.exit(1))
|
||||
|
||||
for (const file of ['index.html']) {
|
||||
fs.copyFile(`./src/${file}`, `./dist/${file}`, (err) => {
|
||||
if (err) throw err
|
||||
})
|
||||
}
|
||||
if (isDevServer) {
|
||||
serve.start({
|
||||
port: 5000,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"esbuild"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "node ./esbuild.config.mjs --dev tsc --watch"
|
||||
"start": "node ./esbuild.config.mjs --dev & tsc --watch"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
|
@ -37,4 +37,4 @@
|
|||
"typescript": "4.2.3"
|
||||
},
|
||||
"gitHead": "a7dac0f83ad998e205c2aab58182cb4ba4e099a6"
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import Controlled from './controlled'
|
|||
import Imperative from './imperative'
|
||||
import Embedded from './embedded'
|
||||
import ChangingId from './changing-id'
|
||||
import './styles.css'
|
||||
|
||||
export default function App(): JSX.Element {
|
||||
return (
|
||||
|
|
|
@ -12,5 +12,9 @@ export default function Editor(props: TLDrawProps): JSX.Element {
|
|||
props.onMount?.(state)
|
||||
}, [])
|
||||
|
||||
return <TLDraw id="tldraw" {...props} onMount={handleMount} />
|
||||
return (
|
||||
<div className="tldraw">
|
||||
<TLDraw id="tldraw" {...props} onMount={handleMount} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import * as React from 'react'
|
||||
import { openDB, DBSchema } from 'idb'
|
||||
import type { TLDrawDocument } from '@tldraw/tldraw'
|
||||
|
||||
const VERSION = 5
|
||||
|
||||
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', VERSION).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', VERSION).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', VERSION, {
|
||||
upgrade(db, _oldVersion, newVersion) {
|
||||
if (newVersion) {
|
||||
if (db.objectStoreNames.contains('documents')) {
|
||||
db.deleteObjectStore('documents')
|
||||
}
|
||||
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 }
|
||||
}
|
|
@ -2,14 +2,14 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>tldraw</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script type="module" src="./bundle.js"></script>
|
||||
<script type="module" src="./index.js"></script>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
|
|
@ -5,4 +5,16 @@ html,
|
|||
|
||||
body {
|
||||
overscroll-behavior: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.tldraw {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
1800
packages/dev/tsconfig.tsbuildinfo
Normal file
1800
packages/dev/tsconfig.tsbuildinfo
Normal file
File diff suppressed because it is too large
Load diff
|
@ -230,7 +230,7 @@ const Layout = styled('div', {
|
|||
boxSizing: 'border-box',
|
||||
outline: 'none',
|
||||
pointerEvents: 'none',
|
||||
zIndex: 100,
|
||||
zIndex: 1,
|
||||
|
||||
'& > *': {
|
||||
pointerEvents: 'all',
|
||||
|
|
24
packages/tldraw/src/index.html
Normal file
24
packages/tldraw/src/index.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>tldraw</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script type="module" src="./bundle.js"></script>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
20
packages/tldraw/src/styles.css
Normal file
20
packages/tldraw/src/styles.css
Normal file
|
@ -0,0 +1,20 @@
|
|||
html,
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
overscroll-behavior: none;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.tldraw {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
Loading…
Reference in a new issue