@tldraw/editor 3.15.1 → 3.16.0-canary.01f62b6d4455
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +185 -9
- package/dist-cjs/index.js +5 -1
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +3 -1
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +4 -26
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js +53 -0
- package/dist-cjs/lib/components/default-components/DefaultShapeWrapper.js.map +7 -0
- package/dist-cjs/lib/config/TLUserPreferences.js +9 -3
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +110 -59
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +9 -4
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/types/misc-types.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +1 -2
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +24 -20
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +2 -0
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/hooks/useStateAttribute.js +35 -0
- package/dist-cjs/lib/hooks/useStateAttribute.js.map +7 -0
- package/dist-cjs/lib/license/Watermark.js +6 -6
- package/dist-cjs/lib/license/Watermark.js.map +1 -1
- package/dist-cjs/lib/options.js +7 -0
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/EditorAtom.js +45 -0
- package/dist-cjs/lib/utils/EditorAtom.js.map +7 -0
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +185 -9
- package/dist-esm/index.mjs +7 -1
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +3 -1
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +4 -26
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs +23 -0
- package/dist-esm/lib/components/default-components/DefaultShapeWrapper.mjs.map +7 -0
- package/dist-esm/lib/config/TLUserPreferences.mjs +9 -3
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +110 -59
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +9 -4
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -21
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +4 -0
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useStateAttribute.mjs +15 -0
- package/dist-esm/lib/hooks/useStateAttribute.mjs.map +7 -0
- package/dist-esm/lib/license/Watermark.mjs +6 -6
- package/dist-esm/lib/license/Watermark.mjs.map +1 -1
- package/dist-esm/lib/options.mjs +7 -0
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/EditorAtom.mjs +25 -0
- package/dist-esm/lib/utils/EditorAtom.mjs.map +7 -0
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +297 -311
- package/package.json +12 -36
- package/src/index.ts +7 -0
- package/src/lib/TldrawEditor.tsx +7 -5
- package/src/lib/components/MenuClickCapture.tsx +0 -8
- package/src/lib/components/Shape.tsx +6 -21
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
- package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +5 -1
- package/src/lib/components/default-components/DefaultShapeWrapper.tsx +35 -0
- package/src/lib/config/TLUserPreferences.ts +8 -1
- package/src/lib/editor/Editor.test.ts +12 -11
- package/src/lib/editor/Editor.ts +141 -82
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +24 -23
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +34 -26
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +6 -1
- package/src/lib/editor/shapes/ShapeUtil.ts +57 -0
- package/src/lib/editor/types/misc-types.ts +73 -1
- package/src/lib/exports/getSvgJsx.tsx +2 -2
- package/src/lib/hooks/useCanvasEvents.ts +39 -32
- package/src/lib/hooks/useEditorComponents.tsx +7 -1
- package/src/lib/hooks/useStateAttribute.ts +15 -0
- package/src/lib/license/LicenseManager.test.ts +3 -1
- package/src/lib/license/Watermark.test.tsx +2 -1
- package/src/lib/license/Watermark.tsx +6 -6
- package/src/lib/options.ts +8 -0
- package/src/lib/utils/EditorAtom.ts +37 -0
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
- package/src/version.ts +3 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tldraw/editor",
|
|
3
3
|
"description": "tldraw infinite canvas SDK (editor).",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.16.0-canary.01f62b6d4455",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "tldraw Inc.",
|
|
7
7
|
"email": "hello@tldraw.com"
|
|
@@ -34,10 +34,10 @@
|
|
|
34
34
|
"src"
|
|
35
35
|
],
|
|
36
36
|
"scripts": {
|
|
37
|
-
"test-ci": "
|
|
38
|
-
"test": "yarn run -T
|
|
37
|
+
"test-ci": "yarn run -T vitest run --passWithNoTests",
|
|
38
|
+
"test": "yarn run -T vitest --passWithNoTests",
|
|
39
39
|
"benchmark": "yarn run -T tsx ./internal/scripts/benchmark.ts",
|
|
40
|
-
"test-coverage": "
|
|
40
|
+
"test-coverage": "yarn run -T vitest run --coverage --passWithNoTests",
|
|
41
41
|
"build": "yarn run -T tsx ../../internal/scripts/build-package.ts",
|
|
42
42
|
"build-api": "yarn run -T tsx ../../internal/scripts/build-api.ts",
|
|
43
43
|
"prepack": "yarn run -T tsx ../../internal/scripts/prepack.ts",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"@tiptap/core": "^2.9.1",
|
|
50
50
|
"@tiptap/pm": "^2.9.1",
|
|
51
51
|
"@tiptap/react": "^2.9.1",
|
|
52
|
-
"@tldraw/state": "3.
|
|
53
|
-
"@tldraw/state-react": "3.
|
|
54
|
-
"@tldraw/store": "3.
|
|
55
|
-
"@tldraw/tlschema": "3.
|
|
56
|
-
"@tldraw/utils": "3.
|
|
57
|
-
"@tldraw/validate": "3.
|
|
52
|
+
"@tldraw/state": "3.16.0-canary.01f62b6d4455",
|
|
53
|
+
"@tldraw/state-react": "3.16.0-canary.01f62b6d4455",
|
|
54
|
+
"@tldraw/store": "3.16.0-canary.01f62b6d4455",
|
|
55
|
+
"@tldraw/tlschema": "3.16.0-canary.01f62b6d4455",
|
|
56
|
+
"@tldraw/utils": "3.16.0-canary.01f62b6d4455",
|
|
57
|
+
"@tldraw/validate": "3.16.0-canary.01f62b6d4455",
|
|
58
58
|
"@types/core-js": "^2.5.8",
|
|
59
59
|
"@use-gesture/react": "^10.3.1",
|
|
60
60
|
"classnames": "^2.5.1",
|
|
@@ -69,41 +69,17 @@
|
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@peculiar/webcrypto": "^1.5.0",
|
|
72
|
-
"@testing-library/jest-dom": "^5.17.0",
|
|
73
72
|
"@testing-library/react": "^15.0.7",
|
|
74
73
|
"@types/benchmark": "^2.1.5",
|
|
75
74
|
"@types/react": "^18.3.18",
|
|
76
75
|
"@types/wicg-file-system-access": "^2020.9.8",
|
|
77
76
|
"benchmark": "^2.1.4",
|
|
78
77
|
"fake-indexeddb": "^4.0.2",
|
|
79
|
-
"jest-canvas-mock": "^2.5.2",
|
|
80
|
-
"jest-environment-jsdom": "^29.7.0",
|
|
81
78
|
"lazyrepo": "0.0.0-alpha.27",
|
|
82
79
|
"react": "^18.3.1",
|
|
83
80
|
"react-dom": "^18.3.1",
|
|
84
|
-
"resize-observer-polyfill": "^1.5.1"
|
|
85
|
-
|
|
86
|
-
"jest": {
|
|
87
|
-
"preset": "../../internal/config/jest/node/jest-preset.js",
|
|
88
|
-
"testEnvironment": "../../../packages/utils/patchedJestJsDom.js",
|
|
89
|
-
"fakeTimers": {
|
|
90
|
-
"enableGlobally": true
|
|
91
|
-
},
|
|
92
|
-
"testPathIgnorePatterns": [
|
|
93
|
-
"^.+\\.*.css$"
|
|
94
|
-
],
|
|
95
|
-
"moduleNameMapper": {
|
|
96
|
-
"^~(.*)": "<rootDir>/src/$1",
|
|
97
|
-
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
|
|
98
|
-
},
|
|
99
|
-
"setupFiles": [
|
|
100
|
-
"raf/polyfill",
|
|
101
|
-
"jest-canvas-mock",
|
|
102
|
-
"<rootDir>/setupTests.js"
|
|
103
|
-
],
|
|
104
|
-
"setupFilesAfterEnv": [
|
|
105
|
-
"../../internal/config/setupJest.ts"
|
|
106
|
-
]
|
|
81
|
+
"resize-observer-polyfill": "^1.5.1",
|
|
82
|
+
"vitest": "^3.2.4"
|
|
107
83
|
},
|
|
108
84
|
"module": "dist-esm/index.mjs",
|
|
109
85
|
"source": "src/index.ts",
|
package/src/index.ts
CHANGED
|
@@ -67,6 +67,10 @@ export {
|
|
|
67
67
|
DefaultShapeIndicators,
|
|
68
68
|
type TLShapeIndicatorsProps,
|
|
69
69
|
} from './lib/components/default-components/DefaultShapeIndicators'
|
|
70
|
+
export {
|
|
71
|
+
DefaultShapeWrapper,
|
|
72
|
+
type TLShapeWrapperProps,
|
|
73
|
+
} from './lib/components/default-components/DefaultShapeWrapper'
|
|
70
74
|
export {
|
|
71
75
|
DefaultSnapIndicator,
|
|
72
76
|
type TLSnapIndicatorProps,
|
|
@@ -261,9 +265,11 @@ export {
|
|
|
261
265
|
type TLCameraMoveOptions,
|
|
262
266
|
type TLCameraOptions,
|
|
263
267
|
type TLExportType,
|
|
268
|
+
type TLGetShapeAtPointOptions,
|
|
264
269
|
type TLImageExportOptions,
|
|
265
270
|
type TLSvgExportOptions,
|
|
266
271
|
type TLSvgOptions,
|
|
272
|
+
type TLUpdatePointerOptions,
|
|
267
273
|
} from './lib/editor/types/misc-types'
|
|
268
274
|
export {
|
|
269
275
|
type TLAdjacentDirection,
|
|
@@ -445,6 +451,7 @@ export {
|
|
|
445
451
|
setPointerCapture,
|
|
446
452
|
stopEventPropagation,
|
|
447
453
|
} from './lib/utils/dom'
|
|
454
|
+
export { EditorAtom } from './lib/utils/EditorAtom'
|
|
448
455
|
export { getIncrementedName } from './lib/utils/getIncrementedName'
|
|
449
456
|
export { getPointerInfo } from './lib/utils/getPointerInfo'
|
|
450
457
|
export { getSvgPathFromPoints } from './lib/utils/getSvgPathFromPoints'
|
package/src/lib/TldrawEditor.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { MigrationSequence, Store } from '@tldraw/store'
|
|
2
2
|
import { TLShape, TLStore, TLStoreSnapshot } from '@tldraw/tlschema'
|
|
3
|
-
import {
|
|
3
|
+
import { annotateError, Required } from '@tldraw/utils'
|
|
4
4
|
import React, {
|
|
5
|
-
ReactNode,
|
|
6
5
|
memo,
|
|
6
|
+
ReactNode,
|
|
7
7
|
useCallback,
|
|
8
8
|
useEffect,
|
|
9
9
|
useLayoutEffect,
|
|
@@ -15,13 +15,13 @@ import React, {
|
|
|
15
15
|
|
|
16
16
|
import classNames from 'classnames'
|
|
17
17
|
import { version } from '../version'
|
|
18
|
-
import { OptionalErrorBoundary } from './components/ErrorBoundary'
|
|
19
18
|
import { DefaultErrorFallback } from './components/default-components/DefaultErrorFallback'
|
|
20
|
-
import {
|
|
19
|
+
import { OptionalErrorBoundary } from './components/ErrorBoundary'
|
|
21
20
|
import { TLStoreBaseOptions } from './config/createTLStore'
|
|
22
|
-
import {
|
|
21
|
+
import { createTLUser, TLUser } from './config/createTLUser'
|
|
23
22
|
import { TLAnyBindingUtilConstructor } from './config/defaultBindings'
|
|
24
23
|
import { TLAnyShapeUtilConstructor } from './config/defaultShapes'
|
|
24
|
+
import { TLEditorSnapshot } from './config/TLEditorSnapshot'
|
|
25
25
|
import { Editor } from './editor/Editor'
|
|
26
26
|
import { TLStateNodeConstructor } from './editor/tools/StateNode'
|
|
27
27
|
import { TLCameraOptions } from './editor/types/misc-types'
|
|
@@ -39,6 +39,7 @@ import { useForceUpdate } from './hooks/useForceUpdate'
|
|
|
39
39
|
import { useShallowObjectIdentity } from './hooks/useIdentity'
|
|
40
40
|
import { useLocalStore } from './hooks/useLocalStore'
|
|
41
41
|
import { useRefState } from './hooks/useRefState'
|
|
42
|
+
import { useStateAttribute } from './hooks/useStateAttribute'
|
|
42
43
|
import { useZoomCss } from './hooks/useZoomCss'
|
|
43
44
|
import { LicenseProvider } from './license/LicenseProvider'
|
|
44
45
|
import { Watermark } from './license/Watermark'
|
|
@@ -646,6 +647,7 @@ function Layout({ children, onMount }: { children: ReactNode; onMount?: TLOnMoun
|
|
|
646
647
|
useCursor()
|
|
647
648
|
useDarkMode()
|
|
648
649
|
useForceUpdate()
|
|
650
|
+
useStateAttribute()
|
|
649
651
|
useOnMount((editor) => {
|
|
650
652
|
const teardownStore = editor.store.props.onMount(editor)
|
|
651
653
|
const teardownCallback = onMount?.(editor)
|
|
@@ -50,12 +50,6 @@ export function MenuClickCapture() {
|
|
|
50
50
|
// Do nothing unless we're pointing
|
|
51
51
|
if (!rPointerState.current.isDown) return
|
|
52
52
|
|
|
53
|
-
// If we're already dragging, pass on the event as it is
|
|
54
|
-
if (rPointerState.current.isDragging) {
|
|
55
|
-
canvasEvents.onPointerMove?.(e)
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
|
|
59
53
|
if (
|
|
60
54
|
// We're pointing, but are we dragging?
|
|
61
55
|
Vec.Dist2(rPointerState.current.start, new Vec(e.clientX, e.clientY)) >
|
|
@@ -75,8 +69,6 @@ export function MenuClickCapture() {
|
|
|
75
69
|
clientY: y,
|
|
76
70
|
button: 0,
|
|
77
71
|
})
|
|
78
|
-
// call the pointer move with the current pointer position
|
|
79
|
-
canvasEvents.onPointerMove?.(e)
|
|
80
72
|
}
|
|
81
73
|
},
|
|
82
74
|
[canvasEvents, editor]
|
|
@@ -40,7 +40,7 @@ export const Shape = memo(function Shape({
|
|
|
40
40
|
}) {
|
|
41
41
|
const editor = useEditor()
|
|
42
42
|
|
|
43
|
-
const { ShapeErrorFallback } = useEditorComponents()
|
|
43
|
+
const { ShapeErrorFallback, ShapeWrapper } = useEditorComponents()
|
|
44
44
|
|
|
45
45
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
46
46
|
const bgContainerRef = useRef<HTMLDivElement>(null)
|
|
@@ -145,37 +145,22 @@ export const Shape = memo(function Shape({
|
|
|
145
145
|
[editor]
|
|
146
146
|
)
|
|
147
147
|
|
|
148
|
-
if (!shape) return null
|
|
149
|
-
|
|
150
|
-
const isFilledShape = 'fill' in shape.props && shape.props.fill !== 'none'
|
|
148
|
+
if (!shape || !ShapeWrapper) return null
|
|
151
149
|
|
|
152
150
|
return (
|
|
153
151
|
<>
|
|
154
152
|
{util.backgroundComponent && (
|
|
155
|
-
<
|
|
156
|
-
ref={bgContainerRef}
|
|
157
|
-
className="tl-shape tl-shape-background"
|
|
158
|
-
data-shape-type={shape.type}
|
|
159
|
-
data-shape-id={shape.id}
|
|
160
|
-
draggable={false}
|
|
161
|
-
>
|
|
153
|
+
<ShapeWrapper ref={bgContainerRef} shape={shape} isBackground={true}>
|
|
162
154
|
<OptionalErrorBoundary fallback={ShapeErrorFallback} onError={annotateError}>
|
|
163
155
|
<InnerShapeBackground shape={shape} util={util} />
|
|
164
156
|
</OptionalErrorBoundary>
|
|
165
|
-
</
|
|
157
|
+
</ShapeWrapper>
|
|
166
158
|
)}
|
|
167
|
-
<
|
|
168
|
-
ref={containerRef}
|
|
169
|
-
className="tl-shape"
|
|
170
|
-
data-shape-type={shape.type}
|
|
171
|
-
data-shape-is-filled={isFilledShape}
|
|
172
|
-
data-shape-id={shape.id}
|
|
173
|
-
draggable={false}
|
|
174
|
-
>
|
|
159
|
+
<ShapeWrapper ref={containerRef} shape={shape} isBackground={false}>
|
|
175
160
|
<OptionalErrorBoundary fallback={ShapeErrorFallback as any} onError={annotateError}>
|
|
176
161
|
<InnerShape shape={shape} util={util} />
|
|
177
162
|
</OptionalErrorBoundary>
|
|
178
|
-
</
|
|
163
|
+
</ShapeWrapper>
|
|
179
164
|
</>
|
|
180
165
|
)
|
|
181
166
|
})
|
|
@@ -44,7 +44,7 @@ export function DefaultCollaboratorHint({
|
|
|
44
44
|
href={`#${cursorHintId}`}
|
|
45
45
|
color={color}
|
|
46
46
|
strokeWidth={3}
|
|
47
|
-
stroke="var(--color-background)"
|
|
47
|
+
stroke="var(--tl-color-background)"
|
|
48
48
|
/>
|
|
49
49
|
<use href={`#${cursorHintId}`} color={color} opacity={opacity} />
|
|
50
50
|
</svg>
|
|
@@ -75,7 +75,7 @@ export const DefaultErrorFallback: TLErrorFallbackComponent = ({ error, editor }
|
|
|
75
75
|
|
|
76
76
|
// if we can't find a theme class from the app or from a parent, we have
|
|
77
77
|
// to fall back on using a media query:
|
|
78
|
-
if (typeof window !== 'undefined' &&
|
|
78
|
+
if (typeof window !== 'undefined' && window.matchMedia) {
|
|
79
79
|
setIsDarkMode(window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
80
80
|
}
|
|
81
81
|
}, [isDarkModeFromApp])
|
|
@@ -21,7 +21,7 @@ export function DefaultScribble({ scribble, zoom, color, opacity, className }: T
|
|
|
21
21
|
<path
|
|
22
22
|
className="tl-scribble"
|
|
23
23
|
d={getSvgPathFromPoints(scribble.points, false)}
|
|
24
|
-
stroke={color ?? `var(--color-${scribble.color})`}
|
|
24
|
+
stroke={color ?? `var(--tl-color-${scribble.color})`}
|
|
25
25
|
fill="none"
|
|
26
26
|
strokeWidth={8 / zoom}
|
|
27
27
|
opacity={opacity ?? scribble.opacity}
|
|
@@ -87,7 +87,11 @@ export const DefaultShapeIndicator = memo(function DefaultShapeIndicator({
|
|
|
87
87
|
|
|
88
88
|
return (
|
|
89
89
|
<svg ref={rIndicator} className={classNames('tl-overlays__item', className)} aria-hidden="true">
|
|
90
|
-
<g
|
|
90
|
+
<g
|
|
91
|
+
className="tl-shape-indicator"
|
|
92
|
+
stroke={color ?? 'var(--tl-color-selected)'}
|
|
93
|
+
opacity={opacity}
|
|
94
|
+
>
|
|
91
95
|
<InnerIndicator editor={editor} id={shapeId} />
|
|
92
96
|
</g>
|
|
93
97
|
</svg>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { TLShape } from '@tldraw/tlschema'
|
|
2
|
+
import classNames from 'classnames'
|
|
3
|
+
import { forwardRef, ReactNode } from 'react'
|
|
4
|
+
|
|
5
|
+
/** @public */
|
|
6
|
+
export interface TLShapeWrapperProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
|
+
/** The shape being rendered. */
|
|
8
|
+
shape: TLShape
|
|
9
|
+
/** Whether this is the shapes regular, or background component. */
|
|
10
|
+
isBackground: boolean
|
|
11
|
+
/** The shape's rendered component. */
|
|
12
|
+
children: ReactNode
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** @public @react */
|
|
16
|
+
export const DefaultShapeWrapper = forwardRef(function DefaultShapeWrapper(
|
|
17
|
+
{ children, shape, isBackground, ...props }: TLShapeWrapperProps,
|
|
18
|
+
ref: React.Ref<HTMLDivElement>
|
|
19
|
+
) {
|
|
20
|
+
const isFilledShape = 'fill' in shape.props && shape.props.fill !== 'none'
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<div
|
|
24
|
+
ref={ref}
|
|
25
|
+
data-shape-type={shape.type}
|
|
26
|
+
data-shape-is-filled={isBackground ? undefined : isFilledShape}
|
|
27
|
+
data-shape-id={shape.id}
|
|
28
|
+
draggable={false}
|
|
29
|
+
{...props}
|
|
30
|
+
className={classNames('tl-shape', isBackground && 'tl-shape-background', props.className)}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
</div>
|
|
34
|
+
)
|
|
35
|
+
})
|
|
@@ -24,6 +24,7 @@ export interface TLUserPreferences {
|
|
|
24
24
|
isWrapMode?: boolean | null
|
|
25
25
|
isDynamicSizeMode?: boolean | null
|
|
26
26
|
isPasteAtCursorMode?: boolean | null
|
|
27
|
+
showUiLabels?: boolean | null
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
interface UserDataSnapshot {
|
|
@@ -52,6 +53,7 @@ export const userTypeValidator: T.Validator<TLUserPreferences> = T.object<TLUser
|
|
|
52
53
|
isWrapMode: T.boolean.nullable().optional(),
|
|
53
54
|
isDynamicSizeMode: T.boolean.nullable().optional(),
|
|
54
55
|
isPasteAtCursorMode: T.boolean.nullable().optional(),
|
|
56
|
+
showUiLabels: T.boolean.nullable().optional(),
|
|
55
57
|
})
|
|
56
58
|
|
|
57
59
|
const Versions = {
|
|
@@ -64,6 +66,7 @@ const Versions = {
|
|
|
64
66
|
AllowSystemColorScheme: 7,
|
|
65
67
|
AddPasteAtCursor: 8,
|
|
66
68
|
AddKeyboardShortcuts: 9,
|
|
69
|
+
AddShowUiLabels: 10,
|
|
67
70
|
} as const
|
|
68
71
|
|
|
69
72
|
const CURRENT_VERSION = Math.max(...Object.values(Versions))
|
|
@@ -102,6 +105,9 @@ function migrateSnapshot(data: { version: number; user: any }) {
|
|
|
102
105
|
if (data.version < Versions.AddKeyboardShortcuts) {
|
|
103
106
|
data.user.areKeyboardShortcutsEnabled = true
|
|
104
107
|
}
|
|
108
|
+
if (data.version < Versions.AddShowUiLabels) {
|
|
109
|
+
data.user.showUiLabels = false
|
|
110
|
+
}
|
|
105
111
|
|
|
106
112
|
// finally
|
|
107
113
|
data.version = CURRENT_VERSION
|
|
@@ -129,7 +135,7 @@ function getRandomColor() {
|
|
|
129
135
|
|
|
130
136
|
/** @internal */
|
|
131
137
|
export function userPrefersReducedMotion() {
|
|
132
|
-
if (typeof window !== 'undefined' &&
|
|
138
|
+
if (typeof window !== 'undefined' && window.matchMedia) {
|
|
133
139
|
return window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ?? false
|
|
134
140
|
}
|
|
135
141
|
|
|
@@ -150,6 +156,7 @@ export const defaultUserPreferences = Object.freeze({
|
|
|
150
156
|
isWrapMode: false,
|
|
151
157
|
isDynamicSizeMode: false,
|
|
152
158
|
isPasteAtCursorMode: false,
|
|
159
|
+
showUiLabels: false,
|
|
153
160
|
colorScheme: 'light',
|
|
154
161
|
}) satisfies Readonly<Omit<TLUserPreferences, 'id'>>
|
|
155
162
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { vi } from 'vitest'
|
|
1
2
|
import {
|
|
2
3
|
Box,
|
|
3
4
|
Geometry2d,
|
|
@@ -59,8 +60,8 @@ beforeEach(() => {
|
|
|
59
60
|
getContainer: () => document.body,
|
|
60
61
|
})
|
|
61
62
|
editor.setCameraOptions({ isLocked: true })
|
|
62
|
-
editor.setCamera =
|
|
63
|
-
editor.user.getAnimationSpeed =
|
|
63
|
+
editor.setCamera = vi.fn()
|
|
64
|
+
editor.user.getAnimationSpeed = vi.fn()
|
|
64
65
|
})
|
|
65
66
|
|
|
66
67
|
describe('centerOnPoint', () => {
|
|
@@ -94,13 +95,13 @@ describe('updateShape', () => {
|
|
|
94
95
|
|
|
95
96
|
describe('zoomToFit', () => {
|
|
96
97
|
it('no-op when isLocked is set', () => {
|
|
97
|
-
editor.getCurrentPageShapeIds =
|
|
98
|
+
editor.getCurrentPageShapeIds = vi.fn(() => new Set([createShapeId('box1')]))
|
|
98
99
|
editor.zoomToFit()
|
|
99
100
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
100
101
|
})
|
|
101
102
|
|
|
102
103
|
it('sets camera when isLocked is set and force flag is set', () => {
|
|
103
|
-
editor.getCurrentPageShapeIds =
|
|
104
|
+
editor.getCurrentPageShapeIds = vi.fn(() => new Set([createShapeId('box1')]))
|
|
104
105
|
editor.zoomToFit({ force: true })
|
|
105
106
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
106
107
|
})
|
|
@@ -144,13 +145,13 @@ describe('zoomOut', () => {
|
|
|
144
145
|
|
|
145
146
|
describe('zoomToSelection', () => {
|
|
146
147
|
it('no-op when isLocked is set', () => {
|
|
147
|
-
editor.getSelectionPageBounds =
|
|
148
|
+
editor.getSelectionPageBounds = vi.fn(() => Box.From({ x: 0, y: 0, w: 100, h: 100 }))
|
|
148
149
|
editor.zoomToSelection()
|
|
149
150
|
expect(editor.setCamera).not.toHaveBeenCalled()
|
|
150
151
|
})
|
|
151
152
|
|
|
152
153
|
it('sets camera when isLocked is set and force flag is set', () => {
|
|
153
|
-
editor.getSelectionPageBounds =
|
|
154
|
+
editor.getSelectionPageBounds = vi.fn(() => Box.From({ x: 0, y: 0, w: 100, h: 100 }))
|
|
154
155
|
editor.zoomToSelection({ force: true })
|
|
155
156
|
expect(editor.setCamera).toHaveBeenCalled()
|
|
156
157
|
})
|
|
@@ -286,7 +287,7 @@ describe('getShapesAtPoint', () => {
|
|
|
286
287
|
|
|
287
288
|
it('filters out hidden shapes', () => {
|
|
288
289
|
// Create a spy to mock isShapeHidden
|
|
289
|
-
const isShapeHiddenSpy =
|
|
290
|
+
const isShapeHiddenSpy = vi.spyOn(editor, 'isShapeHidden')
|
|
290
291
|
isShapeHiddenSpy.mockImplementation((shape) => {
|
|
291
292
|
return typeof shape === 'string' ? shape === ids.shape3 : shape.id === ids.shape3
|
|
292
293
|
})
|
|
@@ -352,7 +353,7 @@ describe('getShapesAtPoint', () => {
|
|
|
352
353
|
|
|
353
354
|
it('returns empty array when all shapes are hidden', () => {
|
|
354
355
|
// Mock all shapes as hidden
|
|
355
|
-
const isShapeHiddenSpy =
|
|
356
|
+
const isShapeHiddenSpy = vi.spyOn(editor, 'isShapeHidden')
|
|
356
357
|
isShapeHiddenSpy.mockReturnValue(true)
|
|
357
358
|
|
|
358
359
|
const shapes = editor.getShapesAtPoint({ x: 50, y: 50 })
|
|
@@ -692,7 +693,7 @@ describe('selectAll', () => {
|
|
|
692
693
|
const initialSelectedIds = editor.getSelectedShapeIds()
|
|
693
694
|
|
|
694
695
|
// Spy on setSelectedShapes to verify it's not called
|
|
695
|
-
const setSelectedShapesSpy =
|
|
696
|
+
const setSelectedShapesSpy = vi.spyOn(editor, 'setSelectedShapes')
|
|
696
697
|
|
|
697
698
|
// Call selectAll
|
|
698
699
|
editor.selectAll()
|
|
@@ -713,7 +714,7 @@ describe('selectAll', () => {
|
|
|
713
714
|
const initialSelectedIds = editor.getSelectedShapeIds()
|
|
714
715
|
|
|
715
716
|
// Spy on setSelectedShapes to verify it's not called
|
|
716
|
-
const setSelectedShapesSpy =
|
|
717
|
+
const setSelectedShapesSpy = vi.spyOn(editor, 'setSelectedShapes')
|
|
717
718
|
|
|
718
719
|
// Call selectAll
|
|
719
720
|
editor.selectAll()
|
|
@@ -818,7 +819,7 @@ describe('selectAll', () => {
|
|
|
818
819
|
const initialSelectedIds = Array.from(editor.getSelectedShapeIds())
|
|
819
820
|
|
|
820
821
|
// Spy on setSelectedShapes to verify it's not called
|
|
821
|
-
const setSelectedShapesSpy =
|
|
822
|
+
const setSelectedShapesSpy = vi.spyOn(editor, 'setSelectedShapes')
|
|
822
823
|
|
|
823
824
|
// Call selectAll
|
|
824
825
|
editor.selectAll()
|