[fix] copy and paste (again) (#685)

* fix copy

* remove console logs

* update types
This commit is contained in:
Steve Ruiz 2022-05-14 14:15:55 +01:00 committed by GitHub
parent 61cf4e6290
commit c3050db968
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
85 changed files with 145 additions and 762 deletions

View file

@ -29,8 +29,8 @@
"electron-util": "^0.17.2", "electron-util": "^0.17.2",
"esbuild": "^0.14.18", "esbuild": "^0.14.18",
"esbuild-serve": "^1.0.1", "esbuild-serve": "^1.0.1",
"react": ">=16.8", "react": "^17.0",
"react-dom": "^16.8 || ^17.0", "react-dom": "^17.0",
"rimraf": "3.0.2", "rimraf": "3.0.2",
"typescript": "4.5.5" "typescript": "4.5.5"
}, },

View file

@ -4,7 +4,7 @@ import type { Message, TldrawBridgeApi } from 'src/types'
declare const window: Window & { TldrawBridgeApi: TldrawBridgeApi } declare const window: Window & { TldrawBridgeApi: TldrawBridgeApi }
export default function App(): JSX.Element { export default function App() {
const rTldrawApp = React.useRef<TldrawApp>() const rTldrawApp = React.useRef<TldrawApp>()
// When the editor mounts, save the state instance in a ref. // When the editor mounts, save the state instance in a ref.

View file

@ -25,8 +25,8 @@
"create-serve": "1.0.1", "create-serve": "1.0.1",
"esbuild": "^0.14.38", "esbuild": "^0.14.38",
"esbuild-serve": "^1.0.1", "esbuild-serve": "^1.0.1",
"react": ">=16.8", "react": "^17.0",
"react-dom": "^16.8 || ^17.0", "react-dom": "^17.0",
"rimraf": "3.0.2", "rimraf": "3.0.2",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "4.5.5" "typescript": "4.5.5"

View file

@ -120,7 +120,6 @@
"devDependencies": { "devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.10.2", "@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2", "@typescript-eslint/parser": "^5.10.2",
"@vscode/test-web": "^0.0.22",
"assert": "^2.0.0", "assert": "^2.0.0",
"eslint": "^8.8.0", "eslint": "^8.8.0",
"mocha": "^9.1.1", "mocha": "^9.1.1",

View file

@ -1,14 +0,0 @@
// This file isn't doing much; however it cannot be removed, or else
// the build will fail due to the fact that we're targeting ES6.
{
"presets": [
[
"next/babel",
{
"preset-env": { "targets": { "node": true } }
}
]
],
"plugins": []
}

View file

@ -33,13 +33,11 @@
"next-auth": "^4.0.5", "next-auth": "^4.0.5",
"next-pwa": "^5.4.4", "next-pwa": "^5.4.4",
"next-themes": "^0.0.15", "next-themes": "^0.0.15",
"react": "17.0.2", "react": "^17.0",
"react-dom": "17.0.2" "react-dom": "^17.0"
}, },
"devDependencies": { "devDependencies": {
"@sentry/webpack-plugin": "^1.17.1", "@sentry/webpack-plugin": "^1.17.1",
"@tldraw/core": "*",
"@tldraw/tldraw": "*",
"@types/react": "^17.0.19", "@types/react": "^17.0.19",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"eslint": "^8.8.0", "eslint": "^8.8.0",

View file

@ -2,7 +2,6 @@ import '../styles/globals.css'
import Head from 'next/head' import Head from 'next/head'
import useGtag from 'utils/useGtag' import useGtag from 'utils/useGtag'
import { init } from 'utils/sentry' import { init } from 'utils/sentry'
import type { AppProps } from 'next/app'
import type React from 'react' import type React from 'react'
init() init()
@ -12,7 +11,7 @@ const APP_DESCRIPTION = 'A tiny little drawing app.'
const APP_URL = 'https://tldraw.com' const APP_URL = 'https://tldraw.com'
const IMAGE = 'https://tldraw.com/social-image.png' const IMAGE = 'https://tldraw.com/social-image.png'
function MyApp({ Component, pageProps }: AppProps) { function MyApp({ Component, pageProps }: any) {
useGtag() useGtag()
return ( return (

View file

@ -3,7 +3,7 @@ import { getCssText } from 'styles'
import { GA_TRACKING_ID } from 'utils/gtag' import { GA_TRACKING_ID } from 'utils/gtag'
class MyDocument extends NextDocument { class MyDocument extends NextDocument {
static async getInitialProps(ctx: DocumentContext) { static async getInitialProps(ctx: DocumentContext): Promise<any> {
const initialProps = await NextDocument.getInitialProps(ctx) const initialProps = await NextDocument.getInitialProps(ctx)
return { return {
@ -17,7 +17,7 @@ class MyDocument extends NextDocument {
} }
} }
render(): JSX.Element { render() {
return ( return (
<Html lang="en"> <Html lang="en">
<Head> <Head>

View file

@ -5,7 +5,7 @@ import Head from 'next/head'
import { useRouter } from 'next/router' import { useRouter } from 'next/router'
import { FC, useMemo } from 'react' import { FC, useMemo } from 'react'
const Editor = dynamic(() => import('components/Editor'), { ssr: false }) const Editor = dynamic(() => import('components/Editor'), { ssr: false }) as any
interface PageProps { interface PageProps {
isUser: boolean isUser: boolean

View file

@ -2,7 +2,9 @@ import * as React from 'react'
import type { GetServerSideProps } from 'next' import type { GetServerSideProps } from 'next'
import { getSession } from 'next-auth/react' import { getSession } from 'next-auth/react'
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
const MultiplayerEditor = dynamic(() => import('components/MultiplayerEditor'), { ssr: false }) const MultiplayerEditor = dynamic(() => import('components/MultiplayerEditor'), {
ssr: false,
}) as any
interface RoomProps { interface RoomProps {
id: string id: string
@ -10,7 +12,7 @@ interface RoomProps {
isUser: boolean isUser: boolean
} }
export default function Room({ id, isUser, isSponsor }: RoomProps): JSX.Element { export default function Room({ id, isUser, isSponsor }: RoomProps) {
return <MultiplayerEditor isUser={isUser} isSponsor={isSponsor} roomId={id} /> return <MultiplayerEditor isUser={isUser} isSponsor={isSponsor} roomId={id} />
} }

View file

@ -2,7 +2,7 @@ import * as React from 'react'
import type { GetServerSideProps } from 'next' import type { GetServerSideProps } from 'next'
import Head from 'next/head' import Head from 'next/head'
export default function RandomRoomPage(): JSX.Element { export default function RandomRoomPage() {
return ( return (
<> <>
<Head> <Head>

View file

@ -18,9 +18,9 @@
"devDependencies": { "devDependencies": {
"@state-designer/react": "^3.0.0", "@state-designer/react": "^3.0.0",
"@stitches/react": "^1.2.6", "@stitches/react": "^1.2.6",
"@tldraw/core": "^1.6.1", "@tldraw/core": "*",
"@tldraw/intersect": "^1.6.1", "@tldraw/intersect": "*",
"@tldraw/vec": "^1.6.1", "@tldraw/vec": "*",
"@types/node": "^17.0.14", "@types/node": "^17.0.14",
"@types/react": "^17.0.38", "@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11", "@types/react-dom": "^17.0.11",

View file

@ -177,7 +177,7 @@ interface AppProps {
onMount?: (api: Api) => void onMount?: (api: Api) => void
} }
export default function App({ onMount }: AppProps): JSX.Element { export default function App({ onMount }: AppProps) {
const appState = useStateDesigner(machine) const appState = useStateDesigner(machine)
React.useEffect(() => { React.useEffect(() => {

View file

@ -15,8 +15,8 @@
}, },
"files": [], "files": [],
"devDependencies": { "devDependencies": {
"@tldraw/core": "^1.6.1", "@tldraw/core": "*",
"@tldraw/vec": "^1.6.1", "@tldraw/vec": "*",
"@types/node": "^17.0.14", "@types/node": "^17.0.14",
"@types/react": "^17.0.38", "@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11", "@types/react-dom": "^17.0.11",

View file

@ -27,7 +27,7 @@ const shapeUtils: TLShapeUtilsMap<Shape> = {
rect: new RectUtil(), rect: new RectUtil(),
} }
export default observer(function App(): JSX.Element { export default observer(function App() {
const onHoverShape: TLPointerEventHandler = (e) => { const onHoverShape: TLPointerEventHandler = (e) => {
pageState.setHoveredId(e.target) pageState.setHoveredId(e.target)
} }

View file

@ -2,7 +2,7 @@
import * as React from 'react' import * as React from 'react'
import { ColorStyle, Tldraw, TDShapeType, TldrawApp } from '@tldraw/tldraw' import { ColorStyle, Tldraw, TDShapeType, TldrawApp } from '@tldraw/tldraw'
export default function Imperative(): JSX.Element { export default function Imperative() {
const rTldrawApp = React.useRef<TldrawApp>() const rTldrawApp = React.useRef<TldrawApp>()
const handleMount = React.useCallback((app: TldrawApp) => { const handleMount = React.useCallback((app: TldrawApp) => {

View file

@ -3,7 +3,7 @@ import { Tldraw, TldrawApp, TDShapeType, ColorStyle } from '@tldraw/tldraw'
declare const window: Window & { app: TldrawApp } declare const window: Window & { app: TldrawApp }
export default function Api(): JSX.Element { export default function Api() {
const rTldrawApp = React.useRef<TldrawApp>() const rTldrawApp = React.useRef<TldrawApp>()
const handleMount = React.useCallback((app: TldrawApp) => { const handleMount = React.useCallback((app: TldrawApp) => {

View file

@ -19,7 +19,7 @@ import { Multiplayer as MultiplayerWithImages } from './multiplayer-with-images'
import './styles.css' import './styles.css'
import Export from '~export' import Export from '~export'
export default function App(): JSX.Element { export default function App() {
return ( return (
<main> <main>
<Routes> <Routes>

View file

@ -1,7 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { Tldraw } from '@tldraw/tldraw' import { Tldraw } from '@tldraw/tldraw'
export default function Basic(): JSX.Element { export default function Basic() {
return ( return (
<div className="tldraw"> <div className="tldraw">
<Tldraw /> <Tldraw />

View file

@ -1,7 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { Tldraw } from '@tldraw/tldraw' import { Tldraw } from '@tldraw/tldraw'
export default function DarkMode(): JSX.Element { export default function DarkMode() {
return ( return (
<div className="tldraw"> <div className="tldraw">
<Tldraw darkMode /> <Tldraw darkMode />

View file

@ -4,7 +4,7 @@ import { TDShapeType, Tldraw, TldrawApp, useFileSystem } from '@tldraw/tldraw'
declare const window: Window & { app: TldrawApp } declare const window: Window & { app: TldrawApp }
export default function Develop(): JSX.Element { export default function Develop() {
const rTldrawApp = React.useRef<TldrawApp>() const rTldrawApp = React.useRef<TldrawApp>()
const fileSystemEvents = useFileSystem() const fileSystemEvents = useFileSystem()

View file

@ -1,7 +1,7 @@
import { Tldraw } from '@tldraw/tldraw' import { Tldraw } from '@tldraw/tldraw'
import * as React from 'react' import * as React from 'react'
export default function Embedded(): JSX.Element { export default function Embedded() {
return ( return (
<div style={{ padding: '2% 10%', width: 'calc(100% - 100px)' }}> <div style={{ padding: '2% 10%', width: 'calc(100% - 100px)' }}>
<div <div

View file

@ -13,7 +13,7 @@ import {
import Vec from '@tldraw/vec' import Vec from '@tldraw/vec'
import { Utils } from '@tldraw/core' import { Utils } from '@tldraw/core'
export default function Export(): JSX.Element { export default function Export() {
const handleExport = React.useCallback(async (app: TldrawApp) => { const handleExport = React.useCallback(async (app: TldrawApp) => {
exportViaServer(app, TDExportType.PNG) exportViaServer(app, TDExportType.PNG)
}, []) }, [])

View file

@ -3,7 +3,7 @@ import { TldrawApp, TDExport, TDExportType, Tldraw } from '@tldraw/tldraw'
const ACTION = 'download' as 'download' | 'open' const ACTION = 'download' as 'download' | 'open'
export default function Export(): JSX.Element { export default function Export() {
const handleExport = React.useCallback(async (app: TldrawApp, info: TDExport) => { const handleExport = React.useCallback(async (app: TldrawApp, info: TDExport) => {
// When a user exports, the default behavior is to download // When a user exports, the default behavior is to download
// the exported data as a file. If the onExport callback is // the exported data as a file. If the onExport callback is

View file

@ -1,7 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { Tldraw, useFileSystem } from '@tldraw/tldraw' import { Tldraw, useFileSystem } from '@tldraw/tldraw'
export default function FileSystem(): JSX.Element { export default function FileSystem() {
const fileSystemEvents = useFileSystem() const fileSystemEvents = useFileSystem()
// Use the Menu > File to create, open, and save .tldr files. // Use the Menu > File to create, open, and save .tldr files.

View file

@ -1,7 +1,7 @@
import { Tldraw, TDFile } from '@tldraw/tldraw' import { Tldraw, TDFile } from '@tldraw/tldraw'
import * as React from 'react' import * as React from 'react'
export default function LoadingFiles(): JSX.Element { export default function LoadingFiles() {
const [file, setFile] = React.useState<TDFile>() const [file, setFile] = React.useState<TDFile>()
React.useEffect(() => { React.useEffect(() => {

View file

@ -1,6 +1,6 @@
import { Tldraw } from '@tldraw/tldraw' import { Tldraw } from '@tldraw/tldraw'
import * as React from 'react' import * as React from 'react'
export default function NoSizeEmbedded(): JSX.Element { export default function NoSizeEmbedded() {
return <Tldraw /> return <Tldraw />
} }

View file

@ -1,7 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { Tldraw } from '@tldraw/tldraw' import { Tldraw } from '@tldraw/tldraw'
export default function Persisted(): JSX.Element { export default function Persisted() {
return ( return (
<div className="tldraw"> <div className="tldraw">
<Tldraw id="Tldraw-persisted-id" /> <Tldraw id="Tldraw-persisted-id" />

View file

@ -1,7 +1,7 @@
import { Tldraw, TDFile } from '@tldraw/tldraw' import { Tldraw, TDFile } from '@tldraw/tldraw'
import * as React from 'react' import * as React from 'react'
export default function ReadOnly(): JSX.Element { export default function ReadOnly() {
const [file, setFile] = React.useState<TDFile>() const [file, setFile] = React.useState<TDFile>()
React.useEffect(() => { React.useEffect(() => {

View file

@ -1,7 +1,7 @@
import * as React from 'react' import * as React from 'react'
import { Tldraw } from '@tldraw/tldraw' import { Tldraw } from '@tldraw/tldraw'
export default function UIOptions(): JSX.Element { export default function UIOptions() {
return ( return (
<div className="tldraw"> <div className="tldraw">
<Tldraw <Tldraw

View file

@ -61,8 +61,8 @@
"mobx": "^6.3.8", "mobx": "^6.3.8",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"pretty-quick": "^3.1.3", "pretty-quick": "^3.1.3",
"react": ">=16.8", "react": "^17.0",
"react-dom": "^16.8 || ^17.0", "react-dom": "^17.0",
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"source-map-loader": "^3.0.1", "source-map-loader": "^3.0.1",
"tslib": "^2.3.1", "tslib": "^2.3.1",

View file

@ -54,7 +54,7 @@ export abstract class TLShapeUtil<T extends TLShape, E extends Element = any, M
/* --------------------- Static --------------------- */ /* --------------------- Static --------------------- */
static Component = <T extends TLShape, E extends Element = any, M = any>( static Component = <T extends TLShape, E extends Element = any, M = any>(
component: (props: TLComponentProps<T, E, M>, ref: TLForwardedRef<E>) => JSX.Element component: (props: TLComponentProps<T, E, M>, ref: TLForwardedRef<E>) => React.ReactElement
) => { ) => {
return React.forwardRef(component) return React.forwardRef(component)
} }
@ -66,6 +66,6 @@ export abstract class TLShapeUtil<T extends TLShape, E extends Element = any, M
isHovered: boolean isHovered: boolean
isSelected: boolean isSelected: boolean
bounds: TLBounds bounds: TLBounds
}) => JSX.Element }) => React.ReactElement
) => component ) => component
} }

View file

@ -5,7 +5,7 @@ interface BindingProps {
type: string type: string
} }
export function Binding({ point: [x, y], type }: BindingProps): JSX.Element { export function Binding({ point: [x, y], type }: BindingProps) {
return ( return (
<g pointerEvents="none"> <g pointerEvents="none">
{type === 'center' && ( {type === 'center' && (

View file

@ -22,7 +22,7 @@ interface BoundsProps {
hideBindingHandles: boolean hideBindingHandles: boolean
hideResizeHandles: boolean hideResizeHandles: boolean
viewportWidth: number viewportWidth: number
children?: React.ReactNode children?: React.ReactElement
} }
export const Bounds = observer<BoundsProps>(function Bounds({ export const Bounds = observer<BoundsProps>(function Bounds({
@ -36,7 +36,7 @@ export const Bounds = observer<BoundsProps>(function Bounds({
hideResizeHandles, hideResizeHandles,
hideRotateHandle, hideRotateHandle,
hideBindingHandles, hideBindingHandles,
}: BoundsProps): JSX.Element { }: BoundsProps) {
// Touch target size // Touch target size
const targetSize = (viewportWidth < 768 ? 16 : 8) / zoom const targetSize = (viewportWidth < 768 ? 16 : 8) / zoom
// Handle size // Handle size
@ -58,7 +58,7 @@ export const Bounds = observer<BoundsProps>(function Bounds({
<Container bounds={bounds} rotation={rotation}> <Container bounds={bounds} rotation={rotation}>
<SVGContainer> <SVGContainer>
<CenterHandle bounds={bounds} isLocked={isLocked} isHidden={isHidden} /> <CenterHandle bounds={bounds} isLocked={isLocked} isHidden={isHidden} />
{showResizeHandles && ( {showResizeHandles ? (
<> <>
<EdgeHandle <EdgeHandle
targetSize={targetSize} targetSize={targetSize}
@ -117,7 +117,7 @@ export const Bounds = observer<BoundsProps>(function Bounds({
corner={TLBoundsCorner.BottomLeft} corner={TLBoundsCorner.BottomLeft}
/> />
</> </>
)} ) : null}
{showRotateHandle && ( {showRotateHandle && (
<RotateHandle <RotateHandle
targetSize={targetSize} targetSize={targetSize}

View file

@ -12,11 +12,7 @@ interface BoundsBgProps {
isHidden: boolean isHidden: boolean
} }
export const BoundsBg = observer<BoundsBgProps>(function BoundsBg({ export const BoundsBg = observer<BoundsBgProps>(function BoundsBg({ bounds, rotation, isHidden }) {
bounds,
rotation,
isHidden,
}): JSX.Element {
const events = useBoundsEvents() const events = useBoundsEvents()
return ( return (

View file

@ -12,7 +12,7 @@ export const CenterHandle = observer<CenterHandleProps>(function CenterHandle({
bounds, bounds,
isLocked, isLocked,
isHidden, isHidden,
}): JSX.Element { }) {
return ( return (
<rect <rect
className={['tl-bounds-center', isLocked ? 'tl-dashed' : ''].join(' ')} className={['tl-bounds-center', isLocked ? 'tl-dashed' : ''].join(' ')}

View file

@ -24,7 +24,7 @@ export const CornerHandle = observer(function CornerHandle({
isHidden, isHidden,
corner, corner,
bounds, bounds,
}: CornerHandleProps): JSX.Element { }: CornerHandleProps) {
const events = useBoundsHandleEvents(corner) const events = useBoundsHandleEvents(corner)
const isTop = corner === TLBoundsCorner.TopLeft || corner === TLBoundsCorner.TopRight const isTop = corner === TLBoundsCorner.TopLeft || corner === TLBoundsCorner.TopRight

View file

@ -23,7 +23,7 @@ export const EdgeHandle = observer<EdgeHandleProps>(function EdgeHandle({
isHidden, isHidden,
bounds, bounds,
edge, edge,
}: EdgeHandleProps): JSX.Element { }: EdgeHandleProps) {
const events = useBoundsHandleEvents(edge) const events = useBoundsHandleEvents(edge)
const isHorizontal = edge === TLBoundsEdge.Top || edge === TLBoundsEdge.Bottom const isHorizontal = edge === TLBoundsEdge.Top || edge === TLBoundsEdge.Bottom

View file

@ -15,7 +15,7 @@ export const RotateHandle = observer<RotateHandleProps>(function RotateHandle({
targetSize, targetSize,
size, size,
isHidden, isHidden,
}): JSX.Element { }) {
const events = useBoundsHandleEvents('rotate') const events = useBoundsHandleEvents('rotate')
return ( return (

View file

@ -9,7 +9,7 @@ export const Brush = observer<{
brush: TLBounds brush: TLBounds
zoom: number zoom: number
dashed: boolean | null | undefined dashed: boolean | null | undefined
}>(function Brush({ brush, zoom, dashed }): JSX.Element | null { }>(function Brush({ brush, zoom, dashed }) {
return ( return (
<Container bounds={brush} rotation={0}> <Container bounds={brush} rotation={0}>
<SVGContainer> <SVGContainer>

View file

@ -80,7 +80,7 @@ export const Canvas = observer(function _Canvas<
hideRotateHandle, hideRotateHandle,
hideGrid, hideGrid,
onBoundsChange, onBoundsChange,
}: CanvasProps<T, M>): JSX.Element { }: CanvasProps<T, M>) {
const rCanvas = React.useRef<HTMLDivElement>(null) const rCanvas = React.useRef<HTMLDivElement>(null)
const rContainer = React.useRef<HTMLDivElement>(null) const rContainer = React.useRef<HTMLDivElement>(null)
const rLayer = React.useRef<HTMLDivElement>(null) const rLayer = React.useRef<HTMLDivElement>(null)
@ -107,14 +107,7 @@ export const Canvas = observer(function _Canvas<
<div id={id} className="tl-container" ref={rContainer}> <div id={id} className="tl-container" ref={rContainer}>
<div id="canvas" className="tl-absolute tl-canvas" ref={rCanvas} {...events}> <div id="canvas" className="tl-absolute tl-canvas" ref={rCanvas} {...events}>
{!hideGrid && grid && <Grid grid={grid} camera={pageState.camera} />} {!hideGrid && grid && <Grid grid={grid} camera={pageState.camera} />}
<div <div ref={rLayer} className="tl-absolute tl-layer" data-testid="layer">
ref={rLayer}
className="tl-absolute tl-layer"
data-testid="layer"
onCopy={stopPropagation}
onPaste={stopPropagation}
onCut={stopPropagation}
>
<Page <Page
page={page} page={page}
pageState={pageState} pageState={pageState}

View file

@ -9,10 +9,7 @@ interface HandlesProps {
zoom: number zoom: number
} }
export const Handles = observer(function Handles({ export const Handles = observer(function Handles({ shape, zoom }: HandlesProps) {
shape,
zoom,
}: HandlesProps): JSX.Element | null {
if (shape.handles === undefined) { if (shape.handles === undefined) {
return null return null
} }

View file

@ -39,7 +39,7 @@ export const Page = observer(function _Page<T extends TLShape, M extends Record<
hideRotateHandle, hideRotateHandle,
hideResizeHandles, hideResizeHandles,
meta, meta,
}: PageProps<T, M>): JSX.Element { }: PageProps<T, M>) {
const { bounds: rendererBounds, shapeUtils } = useTLContext() const { bounds: rendererBounds, shapeUtils } = useTLContext()
const shapeTree = useShapeTree(page, pageState, assets, meta) const shapeTree = useShapeTree(page, pageState, assets, meta)

View file

@ -154,7 +154,7 @@ export const Renderer = observer(function _Renderer<
hideGrid = true, hideGrid = true,
showDashedBrush = false, showDashedBrush = false,
...rest ...rest
}: RendererProps<T, M>): JSX.Element { }: RendererProps<T, M>) {
useTLTheme(theme, '#' + id) useTLTheme(theme, '#' + id)
const rSelectionBounds = React.useRef<TLBounds>(null) const rSelectionBounds = React.useRef<TLBounds>(null)

View file

@ -45,7 +45,7 @@ export function useZoomEvents<T extends HTMLElement>(zoom: number, ref: React.Re
} }
// otherwise pan // otherwise pan
const delta = Vec.mul( const delta = Vec.mul(
(e.shiftKey && !Utils.isDarwin) e.shiftKey && !Utils.isDarwin
? // shift+scroll = pan horizontally ? // shift+scroll = pan horizontally
[offset[1], 0] [offset[1], 0]
: // scroll = pan vertically (or in any direction on a trackpad) : // scroll = pan vertically (or in any direction on a trackpad)
@ -126,7 +126,7 @@ export function useZoomEvents<T extends HTMLElement>(zoom: number, ref: React.Re
target: ref, target: ref,
eventOptions: { passive: false }, eventOptions: { passive: false },
pinch: { pinch: {
from: zoom, from: [0, zoom],
scaleBounds: () => ({ from: inputs.zoom, max: 5, min: 0.1 }), scaleBounds: () => ({ from: inputs.zoom, max: 5, min: 0.1 }),
}, },
} }

View file

@ -2,6 +2,6 @@ import * as React from 'react'
import { render } from '@testing-library/react' import { render } from '@testing-library/react'
import { ContextWrapper } from './ContextWrapper' import { ContextWrapper } from './ContextWrapper'
export const renderWithContext = (children: JSX.Element) => { export const renderWithContext = (children: React.ReactNode) => {
return render(<ContextWrapper>{children}</ContextWrapper>) return render(<ContextWrapper>{children}</ContextWrapper>)
} }

View file

@ -2,7 +2,7 @@ import * as React from 'react'
import { render } from '@testing-library/react' import { render } from '@testing-library/react'
import { ContextWrapper } from './ContextWrapper' import { ContextWrapper } from './ContextWrapper'
export const renderWithSvg = (children: JSX.Element) => { export const renderWithSvg = (children: React.ReactNode) => {
return render( return render(
<ContextWrapper> <ContextWrapper>
<svg>{children}</svg> <svg>{children}</svg>

View file

@ -75,8 +75,8 @@
"eslint": "^8.8.0", "eslint": "^8.8.0",
"lask": "^0.0.29", "lask": "^0.0.29",
"mobx": "^6.3.8", "mobx": "^6.3.8",
"react": ">=16.8", "react": "^17.0",
"react-dom": "^16.8 || ^17.0", "react-dom": "^17.0",
"typescript": "^4.6.4" "typescript": "^4.6.4"
}, },
"jest": { "jest": {

View file

@ -41,7 +41,7 @@ interface ContextMenuProps {
children: React.ReactNode children: React.ReactNode
} }
export const ContextMenu = ({ onBlur, children }: ContextMenuProps): JSX.Element => { export const ContextMenu = ({ onBlur, children }: ContextMenuProps) => {
return ( return (
<RadixContextMenu.Root dir="ltr"> <RadixContextMenu.Root dir="ltr">
<RadixContextMenu.Trigger dir="ltr">{children}</RadixContextMenu.Trigger> <RadixContextMenu.Trigger dir="ltr">{children}</RadixContextMenu.Trigger>
@ -417,7 +417,7 @@ const StyledGridContent = styled(MenuContent, {
const currentPageIdSelector = (s: TDSnapshot) => s.appState.currentPageId const currentPageIdSelector = (s: TDSnapshot) => s.appState.currentPageId
const documentPagesSelector = (s: TDSnapshot) => s.document.pages const documentPagesSelector = (s: TDSnapshot) => s.document.pages
function MoveToPageMenu(): JSX.Element | null { function MoveToPageMenu() {
const app = useTldrawApp() const app = useTldrawApp()
const currentPageId = app.useStore(currentPageIdSelector) const currentPageId = app.useStore(currentPageIdSelector)
const documentPages = app.useStore(documentPagesSelector) const documentPages = app.useStore(documentPagesSelector)
@ -458,12 +458,7 @@ export interface ContextMenuSubMenuProps {
id?: string id?: string
} }
export function ContextMenuSubMenu({ export function ContextMenuSubMenu({ children, label, size, id }: ContextMenuSubMenuProps) {
children,
label,
size,
id,
}: ContextMenuSubMenuProps): JSX.Element {
return ( return (
<span id={id}> <span id={id}>
<RadixContextMenu.Root dir="ltr"> <RadixContextMenu.Root dir="ltr">
@ -487,7 +482,7 @@ const CMArrow = styled(RadixContextMenu.ContextMenuArrow, {
/* ------------------- IconButton ------------------- */ /* ------------------- IconButton ------------------- */
function CMIconButton({ onSelect, ...rest }: ToolButtonProps): JSX.Element { function CMIconButton({ onSelect, ...rest }: ToolButtonProps) {
return ( return (
<RadixContextMenu.ContextMenuItem dir="ltr" onSelect={onSelect} asChild> <RadixContextMenu.ContextMenuItem dir="ltr" onSelect={onSelect} asChild>
<ToolButton {...rest} /> <ToolButton {...rest} />

View file

@ -21,7 +21,7 @@ export function DMCheckboxItem({
kbd, kbd,
id, id,
children, children,
}: DMCheckboxItemProps): JSX.Element { }: DMCheckboxItemProps) {
return ( return (
<CheckboxItem <CheckboxItem
dir="ltr" dir="ltr"

View file

@ -12,13 +12,7 @@ export interface DMContentProps {
id?: string id?: string
} }
export function DMContent({ export function DMContent({ sideOffset = 8, children, align, variant, id }: DMContentProps) {
sideOffset = 8,
children,
align,
variant,
id,
}: DMContentProps): JSX.Element {
return ( return (
<Content <Content
dir="ltr" dir="ltr"

View file

@ -6,7 +6,7 @@ export function DMItem({
onSelect, onSelect,
id, id,
...rest ...rest
}: RowButtonProps & { onSelect?: (event: Event) => void; id?: string }): JSX.Element { }: RowButtonProps & { onSelect?: (event: Event) => void; id?: string }) {
return ( return (
<Item dir="ltr" asChild onSelect={onSelect} id={id}> <Item dir="ltr" asChild onSelect={onSelect} id={id}>
<RowButton {...rest} /> <RowButton {...rest} />

View file

@ -11,13 +11,7 @@ export interface DMSubMenuProps {
id?: string id?: string
} }
export function DMSubMenu({ export function DMSubMenu({ children, size, disabled = false, label, id }: DMSubMenuProps) {
children,
size,
disabled = false,
label,
id,
}: DMSubMenuProps): JSX.Element {
return ( return (
<span id={id}> <span id={id}>
<Root dir="ltr"> <Root dir="ltr">

View file

@ -8,13 +8,7 @@ import { Utils } from '@tldraw/core'
const commandKey = () => (Utils.isDarwin() ? '⌘' : 'Ctrl') const commandKey = () => (Utils.isDarwin() ? '⌘' : 'Ctrl')
export function Kbd({ export function Kbd({ variant, children }: { variant: 'tooltip' | 'menu'; children: string }) {
variant,
children,
}: {
variant: 'tooltip' | 'menu'
children: string
}): JSX.Element | null {
return ( return (
<StyledKbd variant={variant}> <StyledKbd variant={variant}>
{children.split('').map((k, i) => { {children.split('').map((k, i) => {

View file

@ -15,13 +15,7 @@ interface TooltipProps {
side?: 'bottom' | 'left' | 'right' | 'top' side?: 'bottom' | 'left' | 'right' | 'top'
} }
export function Tooltip({ export function Tooltip({ children, label, kbd: kbdProp, id, side = 'top' }: TooltipProps) {
children,
label,
kbd: kbdProp,
id,
side = 'top',
}: TooltipProps): JSX.Element {
return ( return (
<span id={id}> <span id={id}>
<RadixTooltip.Root> <RadixTooltip.Root>

View file

@ -8,7 +8,7 @@ export function BoxIcon({
fill?: string fill?: string
stroke?: string stroke?: string
strokeWidth?: number strokeWidth?: number
}): JSX.Element { }) {
return ( return (
<svg <svg
width="24" width="24"

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function DashDashedIcon(): JSX.Element { export function DashDashedIcon() {
return ( return (
<svg width="24" height="24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
<circle <circle

View file

@ -2,7 +2,7 @@ import * as React from 'react'
const dottedDasharray = `${50.26548 * 0.025} ${50.26548 * 0.1}` const dottedDasharray = `${50.26548 * 0.025} ${50.26548 * 0.1}`
export function DashDottedIcon(): JSX.Element { export function DashDottedIcon() {
return ( return (
<svg width="24" height="24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
<circle <circle

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function DashDrawIcon(): JSX.Element { export function DashDrawIcon() {
return ( return (
<svg <svg
width="24" width="24"

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function DashSolidIcon(): JSX.Element { export function DashSolidIcon() {
return ( return (
<svg width="24" height="24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" stroke="currentColor" xmlns="http://www.w3.org/2000/svg">
<circle cx={12} cy={12} r={8} fill="none" strokeWidth={2} strokeLinecap="round" /> <circle cx={12} cy={12} r={8} fill="none" strokeWidth={2} strokeLinecap="round" />

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function EraserIcon(): JSX.Element { export function EraserIcon() {
return ( return (
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function IsFilledIcon(): JSX.Element { export function IsFilledIcon() {
return ( return (
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<rect <rect

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function MultiplayerIcon(): JSX.Element { export function MultiplayerIcon() {
return ( return (
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path <path

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function RedoIcon(props: React.SVGProps<SVGSVGElement>): JSX.Element { export function RedoIcon(props: React.SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
width={32} width={32}

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function SizeLargeIcon(props: React.SVGProps<SVGSVGElement>): JSX.Element { export function SizeLargeIcon(props: React.SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
width={24} width={24}

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function SizeMediumIcon(props: React.SVGProps<SVGSVGElement>): JSX.Element { export function SizeMediumIcon(props: React.SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
width={24} width={24}

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function SizeSmallIcon(props: React.SVGProps<SVGSVGElement>): JSX.Element { export function SizeSmallIcon(props: React.SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
width={24} width={24}

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function TrashIcon(props: React.SVGProps<SVGSVGElement>): JSX.Element { export function TrashIcon(props: React.SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
width={18} width={18}

View file

@ -1,6 +1,6 @@
import * as React from 'react' import * as React from 'react'
export function UndoIcon(props: React.SVGProps<SVGSVGElement>): JSX.Element { export function UndoIcon(props: React.SVGProps<SVGSVGElement>) {
return ( return (
<svg <svg
width={32} width={32}

View file

@ -72,7 +72,7 @@ const hasMultipleSelectionSelector = (s: TDSnapshot) => {
return selectedIds.length > 1 return selectedIds.length > 1
} }
export function ActionButton(): JSX.Element { export function ActionButton() {
const app = useTldrawApp() const app = useTldrawApp()
const isAllLocked = app.useStore(isAllLockedSelector) const isAllLocked = app.useStore(isAllLockedSelector)

View file

@ -4,7 +4,7 @@ import { useTldrawApp } from '~hooks'
import { ToolButton } from '~components/Primitives/ToolButton' import { ToolButton } from '~components/Primitives/ToolButton'
import { TrashIcon } from '~components/Primitives/icons' import { TrashIcon } from '~components/Primitives/icons'
export function DeleteButton(): JSX.Element { export function DeleteButton() {
const app = useTldrawApp() const app = useTldrawApp()
const handleDelete = React.useCallback(() => { const handleDelete = React.useCallback(() => {

View file

@ -7,7 +7,7 @@ import type { TDSnapshot } from '~types'
const isToolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked const isToolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked
export function LockButton(): JSX.Element { export function LockButton() {
const app = useTldrawApp() const app = useTldrawApp()
const isToolLocked = app.useStore(isToolLockedSelector) const isToolLocked = app.useStore(isToolLockedSelector)

View file

@ -16,7 +16,7 @@ import { EraserIcon } from '~components/Primitives/icons'
const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool
const toolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked const toolLockedSelector = (s: TDSnapshot) => s.appState.isToolLocked
export const PrimaryTools = React.memo(function PrimaryTools(): JSX.Element { export const PrimaryTools = React.memo(function PrimaryTools() {
const app = useTldrawApp() const app = useTldrawApp()
const activeTool = app.useStore(activeToolSelector) const activeTool = app.useStore(activeToolSelector)

View file

@ -7,7 +7,7 @@ import { breakpoints } from '~components/breakpoints'
const statusSelector = (s: TDSnapshot) => s.appState.status const statusSelector = (s: TDSnapshot) => s.appState.status
const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool const activeToolSelector = (s: TDSnapshot) => s.appState.activeTool
export function StatusBar(): JSX.Element | null { export function StatusBar() {
const app = useTldrawApp() const app = useTldrawApp()
const status = app.useStore(statusSelector) const status = app.useStore(statusSelector)
const activeTool = app.useStore(activeToolSelector) const activeTool = app.useStore(activeToolSelector)

View file

@ -14,7 +14,7 @@ interface ToolsPanelProps {
onBlur?: React.FocusEventHandler onBlur?: React.FocusEventHandler
} }
export const ToolsPanel = React.memo(function ToolsPanel({ onBlur }: ToolsPanelProps): JSX.Element { export const ToolsPanel = React.memo(function ToolsPanel({ onBlur }: ToolsPanelProps) {
const app = useTldrawApp() const app = useTldrawApp()
const isDebugMode = app.useStore(isDebugModeSelector) const isDebugMode = app.useStore(isDebugModeSelector)

View file

@ -17,7 +17,7 @@ const currentPageNameSelector = (s: TDSnapshot) => s.document.pages[s.appState.c
const currentPageIdSelector = (s: TDSnapshot) => s.document.pages[s.appState.currentPageId].id const currentPageIdSelector = (s: TDSnapshot) => s.document.pages[s.appState.currentPageId].id
export function PageMenu(): JSX.Element { export function PageMenu() {
const app = useTldrawApp() const app = useTldrawApp()
const rIsOpen = React.useRef(false) const rIsOpen = React.useRef(false)

View file

@ -21,7 +21,7 @@ interface PageOptionsDialogProps {
onClose?: () => void onClose?: () => void
} }
export function PageOptionsDialog({ page, onOpen, onClose }: PageOptionsDialogProps): JSX.Element { export function PageOptionsDialog({ page, onOpen, onClose }: PageOptionsDialogProps) {
const app = useTldrawApp() const app = useTldrawApp()
const [isOpen, setIsOpen] = React.useState(false) const [isOpen, setIsOpen] = React.useState(false)

View file

@ -99,7 +99,7 @@ const optionsSelector = (s: TDSnapshot) => {
return false return false
} }
export const StyleMenu = React.memo(function ColorMenu(): JSX.Element { export const StyleMenu = React.memo(function ColorMenu() {
const app = useTldrawApp() const app = useTldrawApp()
const theme = app.useStore(themeSelector) const theme = app.useStore(themeSelector)

View file

@ -1771,11 +1771,13 @@ export class TldrawApp extends StateManager<TDSnapshot> {
this.clipboard = this.getClipboard(ids, pageId) this.clipboard = this.getClipboard(ids, pageId)
const tldrawString = JSON.stringify({ const jsonString = JSON.stringify({
type: 'tldr/clipboard', type: 'tldr/clipboard',
...this.clipboard, ...this.clipboard,
}) })
const tldrawString = `<tldraw>${jsonString}</tldraw>`
if (e) { if (e) {
e.clipboardData?.setData('text/html', tldrawString) e.clipboardData?.setData('text/html', tldrawString)
} }
@ -1929,7 +1931,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
const pasteAsHTML = (html: string) => { const pasteAsHTML = (html: string) => {
try { try {
const maybeJson = html.startsWith('<') ? html.match(/({".*})$|</g)?.[1] : html const maybeJson = html.match(/<tldraw>(.*)<\/tldraw>/)?.[1]
if (!maybeJson) return if (!maybeJson) return
@ -2004,7 +2006,6 @@ export class TldrawApp extends StateManager<TDSnapshot> {
if (htmlData) { if (htmlData) {
let html = await htmlData.text() let html = await htmlData.text()
pasteAsHTML(html) pasteAsHTML(html)
} }

View file

@ -222,6 +222,9 @@ export class StickyUtil extends TDShapeUtil<T, E> {
spellCheck={true} spellCheck={true}
alignment={shape.style.textAlign} alignment={shape.style.textAlign}
onContextMenu={stopPropagation} onContextMenu={stopPropagation}
onCopy={stopPropagation}
onPaste={stopPropagation}
onCut={stopPropagation}
/> />
)} )}
</StyledStickyContainer> </StyledStickyContainer>

View file

@ -220,6 +220,9 @@ export class TextUtil extends TDShapeUtil<T, E> {
onBlur={handleBlur} onBlur={handleBlur}
onPointerDown={handlePointerDown} onPointerDown={handlePointerDown}
onContextMenu={stopPropagation} onContextMenu={stopPropagation}
onCopy={stopPropagation}
onPaste={stopPropagation}
onCut={stopPropagation}
/> />
) : ( ) : (
text text

View file

@ -167,6 +167,9 @@ export const TextLabel = React.memo(function TextLabel({
onBlur={handleBlur} onBlur={handleBlur}
onPointerDown={handlePointerDown} onPointerDown={handlePointerDown}
onContextMenu={stopPropagation} onContextMenu={stopPropagation}
onCopy={stopPropagation}
onPaste={stopPropagation}
onCut={stopPropagation}
/> />
) : ( ) : (
text text

View file

@ -26,6 +26,6 @@ export const Wrapper: React.FC = ({ children }) => {
) )
} }
export const renderWithContext = (children: JSX.Element) => { export const renderWithContext = (children: React.ReactNode) => {
return render(<Wrapper>{children}</Wrapper>) return render(<Wrapper>{children}</Wrapper>)
} }

File diff suppressed because one or more lines are too long

628
yarn.lock

File diff suppressed because it is too large Load diff