@tldraw/editor 4.6.0-next.30b99cd52fc8 → 4.6.0-next.35cf541abcf9
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 +758 -96
- package/dist-cjs/index.js +18 -3
- package/dist-cjs/index.js.map +3 -3
- package/dist-cjs/lib/TldrawEditor.js +55 -12
- package/dist-cjs/lib/TldrawEditor.js.map +3 -3
- package/dist-cjs/lib/components/LiveCollaborators.js +1 -0
- package/dist-cjs/lib/components/LiveCollaborators.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +99 -38
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +10 -3
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +3 -3
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +5 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +1 -0
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +2 -2
- package/dist-cjs/lib/config/createTLStore.js +7 -0
- package/dist-cjs/lib/config/createTLStore.js.map +2 -2
- package/dist-cjs/lib/config/defaultAssets.js +36 -0
- package/dist-cjs/lib/config/defaultAssets.js.map +7 -0
- package/dist-cjs/lib/editor/Editor.js +279 -10
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/assets/AssetUtil.js +67 -0
- package/dist-cjs/lib/editor/assets/AssetUtil.js.map +7 -0
- package/dist-cjs/lib/editor/bindings/BindingUtil.js +1 -0
- package/dist-cjs/lib/editor/bindings/BindingUtil.js.map +1 -1
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js +1 -0
- package/dist-cjs/lib/editor/managers/ClickManager/ClickManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js +1 -0
- package/dist-cjs/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js +1 -0
- package/dist-cjs/lib/editor/managers/FocusManager/FocusManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js +2 -0
- package/dist-cjs/lib/editor/managers/FontManager/FontManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js +2 -0
- package/dist-cjs/lib/editor/managers/HistoryManager/HistoryManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js +12 -0
- package/dist-cjs/lib/editor/managers/InputsManager/InputsManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js +80 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.js.map +7 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js +466 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/PerformanceManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js +17 -0
- package/dist-cjs/lib/editor/managers/PerformanceManager/perf-types.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js +1 -0
- package/dist-cjs/lib/editor/managers/ScribbleManager/ScribbleManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js +1 -0
- package/dist-cjs/lib/editor/managers/SnapManager/BoundsSnaps.js.map +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js +1 -0
- package/dist-cjs/lib/editor/managers/SnapManager/HandleSnaps.js.map +1 -1
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js +2 -1
- package/dist-cjs/lib/editor/managers/SnapManager/SnapManager.js.map +2 -2
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js +1 -0
- package/dist-cjs/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js +1 -0
- package/dist-cjs/lib/editor/managers/TextManager/TextManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js +107 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/ThemeManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +586 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +7 -0
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js +1 -0
- package/dist-cjs/lib/editor/managers/TickManager/TickManager.js.map +1 -1
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +8 -4
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +76 -0
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +7 -0
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +22 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +1 -1
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js +6 -0
- package/dist-cjs/lib/editor/shapes/shared/getPerfectDashProps.js.map +2 -2
- package/dist-cjs/lib/editor/tools/StateNode.js +15 -17
- package/dist-cjs/lib/editor/tools/StateNode.js.map +2 -2
- package/dist-cjs/lib/editor/types/SvgExportContext.js.map +2 -2
- package/dist-cjs/lib/editor/types/external-content.js.map +1 -1
- package/dist-cjs/lib/exports/ExportDelay.js +1 -0
- package/dist-cjs/lib/exports/ExportDelay.js.map +1 -1
- package/dist-cjs/lib/exports/StyleEmbedder.js +1 -0
- package/dist-cjs/lib/exports/StyleEmbedder.js.map +1 -1
- package/dist-cjs/lib/exports/getSvgJsx.js +14 -8
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/globals/environment.js +18 -1
- package/dist-cjs/lib/globals/environment.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +25 -4
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/{useIsDarkMode.js → useColorMode.js} +14 -10
- package/dist-cjs/lib/hooks/useColorMode.js.map +7 -0
- package/dist-cjs/lib/hooks/useCursor.js +3 -7
- package/dist-cjs/lib/hooks/useCursor.js.map +2 -2
- package/dist-cjs/lib/hooks/useDarkMode.js +4 -4
- package/dist-cjs/lib/hooks/useDarkMode.js.map +2 -2
- package/dist-cjs/lib/options.js +2 -0
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/primitives/Vec.js +3 -0
- package/dist-cjs/lib/primitives/Vec.js.map +1 -1
- package/dist-cjs/lib/primitives/geometry/Circle2d.js +1 -0
- package/dist-cjs/lib/primitives/geometry/Circle2d.js.map +1 -1
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js +1 -0
- package/dist-cjs/lib/primitives/geometry/Ellipse2d.js.map +1 -1
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js +2 -0
- package/dist-cjs/lib/primitives/geometry/Geometry2d.js.map +1 -1
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js +1 -0
- package/dist-cjs/lib/primitives/geometry/Stadium2d.js.map +1 -1
- package/dist-cjs/lib/utils/EditorAtom.js +2 -0
- package/dist-cjs/lib/utils/EditorAtom.js.map +1 -1
- package/dist-cjs/lib/utils/reparenting.js +2 -1
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/richText.js.map +2 -2
- package/dist-cjs/lib/utils/runtime.js +2 -1
- package/dist-cjs/lib/utils/runtime.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +2 -0
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +1 -1
- package/dist-cjs/lib/utils/sync/hardReset.js +0 -8
- package/dist-cjs/lib/utils/sync/hardReset.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +758 -96
- package/dist-esm/index.mjs +19 -6
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +58 -12
- package/dist-esm/lib/TldrawEditor.mjs.map +3 -3
- package/dist-esm/lib/components/LiveCollaborators.mjs +1 -0
- package/dist-esm/lib/components/LiveCollaborators.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +100 -39
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +10 -3
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +3 -3
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +5 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +1 -0
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +2 -2
- package/dist-esm/lib/config/createTLStore.mjs +10 -1
- package/dist-esm/lib/config/createTLStore.mjs.map +2 -2
- package/dist-esm/lib/config/defaultAssets.mjs +16 -0
- package/dist-esm/lib/config/defaultAssets.mjs.map +7 -0
- package/dist-esm/lib/editor/Editor.mjs +279 -10
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/assets/AssetUtil.mjs +47 -0
- package/dist-esm/lib/editor/assets/AssetUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs +1 -0
- package/dist-esm/lib/editor/bindings/BindingUtil.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/ClickManager/ClickManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/FocusManager/FocusManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs +2 -0
- package/dist-esm/lib/editor/managers/FontManager/FontManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs +2 -0
- package/dist-esm/lib/editor/managers/HistoryManager/HistoryManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs +12 -0
- package/dist-esm/lib/editor/managers/InputsManager/InputsManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs +60 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs +438 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/PerformanceManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs +1 -0
- package/dist-esm/lib/editor/managers/PerformanceManager/perf-types.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/ScribbleManager/ScribbleManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs +1 -0
- package/dist-esm/lib/editor/managers/SnapManager/BoundsSnaps.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs +1 -0
- package/dist-esm/lib/editor/managers/SnapManager/HandleSnaps.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs +2 -1
- package/dist-esm/lib/editor/managers/SnapManager/SnapManager.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/SpatialIndexManager/SpatialIndexManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/TextManager/TextManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs +89 -0
- package/dist-esm/lib/editor/managers/ThemeManager/ThemeManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +568 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs +1 -0
- package/dist-esm/lib/editor/managers/TickManager/TickManager.mjs.map +1 -1
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +8 -4
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +56 -0
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +22 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +1 -1
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs +6 -0
- package/dist-esm/lib/editor/shapes/shared/getPerfectDashProps.mjs.map +2 -2
- package/dist-esm/lib/editor/tools/StateNode.mjs +15 -17
- package/dist-esm/lib/editor/tools/StateNode.mjs.map +2 -2
- package/dist-esm/lib/editor/types/SvgExportContext.mjs.map +2 -2
- package/dist-esm/lib/exports/ExportDelay.mjs +1 -0
- package/dist-esm/lib/exports/ExportDelay.mjs.map +1 -1
- package/dist-esm/lib/exports/StyleEmbedder.mjs +1 -0
- package/dist-esm/lib/exports/StyleEmbedder.mjs.map +1 -1
- package/dist-esm/lib/exports/getSvgJsx.mjs +14 -11
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/globals/environment.mjs +18 -1
- package/dist-esm/lib/globals/environment.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -4
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useColorMode.mjs +19 -0
- package/dist-esm/lib/hooks/useColorMode.mjs.map +7 -0
- package/dist-esm/lib/hooks/useCursor.mjs +3 -7
- package/dist-esm/lib/hooks/useCursor.mjs.map +2 -2
- package/dist-esm/lib/hooks/useDarkMode.mjs +4 -4
- package/dist-esm/lib/hooks/useDarkMode.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +2 -0
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/primitives/Vec.mjs +3 -0
- package/dist-esm/lib/primitives/Vec.mjs.map +1 -1
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs +1 -0
- package/dist-esm/lib/primitives/geometry/Circle2d.mjs.map +1 -1
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs +1 -0
- package/dist-esm/lib/primitives/geometry/Ellipse2d.mjs.map +1 -1
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs +2 -0
- package/dist-esm/lib/primitives/geometry/Geometry2d.mjs.map +1 -1
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs +1 -0
- package/dist-esm/lib/primitives/geometry/Stadium2d.mjs.map +1 -1
- package/dist-esm/lib/utils/EditorAtom.mjs +2 -0
- package/dist-esm/lib/utils/EditorAtom.mjs.map +1 -1
- package/dist-esm/lib/utils/reparenting.mjs +2 -1
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/richText.mjs.map +2 -2
- package/dist-esm/lib/utils/runtime.mjs +2 -1
- package/dist-esm/lib/utils/runtime.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +2 -0
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +1 -1
- package/dist-esm/lib/utils/sync/hardReset.mjs +0 -8
- package/dist-esm/lib/utils/sync/hardReset.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +0 -37
- package/package.json +7 -7
- package/src/index.ts +24 -6
- package/src/lib/TldrawEditor.tsx +90 -13
- package/src/lib/components/LiveCollaborators.tsx +8 -2
- package/src/lib/components/MenuClickCapture.tsx +129 -49
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +14 -3
- package/src/lib/components/default-components/DefaultCanvas.tsx +6 -2
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +2 -2
- package/src/lib/components/default-components/DefaultShapeIndicators.tsx +2 -0
- package/src/lib/config/createTLStore.ts +22 -1
- package/src/lib/config/defaultAssets.ts +19 -0
- package/src/lib/editor/Editor.ts +387 -40
- package/src/lib/editor/assets/AssetUtil.ts +85 -0
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +9 -2
- package/src/lib/editor/managers/FontManager/FontManager.ts +1 -67
- package/src/lib/editor/managers/InputsManager/InputsManager.ts +12 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceApiAdapter.ts +82 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.test.ts +522 -0
- package/src/lib/editor/managers/PerformanceManager/PerformanceManager.ts +583 -0
- package/src/lib/editor/managers/PerformanceManager/perf-types.ts +196 -0
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +13 -2
- package/src/lib/editor/managers/SnapManager/SnapManager.ts +1 -1
- package/src/lib/editor/managers/ThemeManager/ThemeManager.ts +116 -0
- package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +605 -0
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +23 -29
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +5 -3
- package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +121 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +39 -3
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +1 -1
- package/src/lib/editor/shapes/shared/getPerfectDashProps.ts +7 -0
- package/src/lib/editor/tools/StateNode.ts +16 -18
- package/src/lib/editor/types/SvgExportContext.tsx +5 -0
- package/src/lib/editor/types/external-content.ts +1 -0
- package/src/lib/exports/getSvgJsx.tsx +23 -16
- package/src/lib/globals/environment.ts +18 -0
- package/src/lib/hooks/useCanvasEvents.ts +40 -3
- package/src/lib/hooks/{useIsDarkMode.ts → useColorMode.ts} +9 -5
- package/src/lib/hooks/useCursor.ts +3 -7
- package/src/lib/hooks/useDarkMode.ts +4 -4
- package/src/lib/options.ts +14 -0
- package/src/lib/utils/reparenting.ts +6 -2
- package/src/lib/utils/richText.ts +1 -1
- package/src/lib/utils/runtime.ts +3 -1
- package/src/lib/utils/sync/hardReset.ts +0 -8
- package/src/version.ts +3 -3
- package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
- package/dist-esm/lib/hooks/useIsDarkMode.mjs +0 -15
- package/dist-esm/lib/hooks/useIsDarkMode.mjs.map +0 -7
package/src/lib/TldrawEditor.tsx
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { MigrationSequence, Store } from '@tldraw/store'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
TLShape,
|
|
4
|
+
TLStore,
|
|
5
|
+
TLStoreSnapshot,
|
|
6
|
+
TLTheme,
|
|
7
|
+
TLThemeId,
|
|
8
|
+
TLThemes,
|
|
9
|
+
registerColorsFromThemes,
|
|
10
|
+
registerFontsFromThemes,
|
|
11
|
+
} from '@tldraw/tlschema'
|
|
3
12
|
import { annotateError, Required } from '@tldraw/utils'
|
|
4
13
|
import classNames from 'classnames'
|
|
5
14
|
import React, {
|
|
@@ -18,10 +27,12 @@ import { DefaultErrorFallback } from './components/default-components/DefaultErr
|
|
|
18
27
|
import { OptionalErrorBoundary } from './components/ErrorBoundary'
|
|
19
28
|
import { createTLCurrentUser, TLCurrentUser } from './config/createTLCurrentUser'
|
|
20
29
|
import { TLStoreBaseOptions } from './config/createTLStore'
|
|
30
|
+
import { TLAnyAssetUtilConstructor } from './config/defaultAssets'
|
|
21
31
|
import { TLAnyBindingUtilConstructor } from './config/defaultBindings'
|
|
22
32
|
import { TLAnyShapeUtilConstructor } from './config/defaultShapes'
|
|
23
33
|
import { TLEditorSnapshot } from './config/TLEditorSnapshot'
|
|
24
34
|
import { Editor } from './editor/Editor'
|
|
35
|
+
import { resolveThemes } from './editor/managers/ThemeManager/ThemeManager'
|
|
25
36
|
import { TLStateNodeConstructor } from './editor/tools/StateNode'
|
|
26
37
|
import { TLCameraOptions } from './editor/types/misc-types'
|
|
27
38
|
import { useEditorComponents } from './hooks/EditorComponentsContext'
|
|
@@ -121,6 +132,11 @@ export interface TldrawEditorBaseProps {
|
|
|
121
132
|
*/
|
|
122
133
|
bindingUtils?: readonly TLAnyBindingUtilConstructor[]
|
|
123
134
|
|
|
135
|
+
/**
|
|
136
|
+
* An array of asset utils to use in the editor.
|
|
137
|
+
*/
|
|
138
|
+
assetUtils?: readonly TLAnyAssetUtilConstructor[]
|
|
139
|
+
|
|
124
140
|
/**
|
|
125
141
|
* An array of tools to add to the editor's state chart.
|
|
126
142
|
*/
|
|
@@ -157,9 +173,23 @@ export interface TldrawEditorBaseProps {
|
|
|
157
173
|
user?: TLCurrentUser
|
|
158
174
|
|
|
159
175
|
/**
|
|
160
|
-
*
|
|
176
|
+
* The editor's color scheme. Defaults to `'light'`.
|
|
177
|
+
*
|
|
178
|
+
* - `'light'` - Always use light mode.
|
|
179
|
+
* - `'dark'` - Always use dark mode.
|
|
180
|
+
* - `'system'` - Follow the OS color scheme preference.
|
|
161
181
|
*/
|
|
162
|
-
|
|
182
|
+
colorScheme?: 'light' | 'dark' | 'system'
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Named themes for the editor.
|
|
186
|
+
*/
|
|
187
|
+
themes?: Partial<TLThemes>
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The id of the initially active theme. Defaults to `'default'`.
|
|
191
|
+
*/
|
|
192
|
+
initialTheme?: TLThemeId
|
|
163
193
|
|
|
164
194
|
/**
|
|
165
195
|
* Camera options for the editor.
|
|
@@ -242,6 +272,7 @@ declare global {
|
|
|
242
272
|
|
|
243
273
|
const EMPTY_SHAPE_UTILS_ARRAY = [] as const
|
|
244
274
|
const EMPTY_BINDING_UTILS_ARRAY = [] as const
|
|
275
|
+
const EMPTY_ASSET_UTILS_ARRAY = [] as const
|
|
245
276
|
const EMPTY_TOOLS_ARRAY = [] as const
|
|
246
277
|
/** @internal */
|
|
247
278
|
export const TL_CONTAINER_CLASS = 'tl-container'
|
|
@@ -259,6 +290,13 @@ export const TldrawEditor = memo(function TldrawEditor({
|
|
|
259
290
|
deepLinks: _deepLinks,
|
|
260
291
|
...rest
|
|
261
292
|
}: TldrawEditorProps) {
|
|
293
|
+
// Register custom colors and fonts before effects run. For external stores,
|
|
294
|
+
// users should also pass themes to createTLStore so they are
|
|
295
|
+
// registered before data is loaded into the store.
|
|
296
|
+
const resolvedThemes = resolveThemes(rest.themes)
|
|
297
|
+
registerColorsFromThemes(resolvedThemes)
|
|
298
|
+
registerFontsFromThemes(resolvedThemes)
|
|
299
|
+
|
|
262
300
|
const [container, setContainer] = useState<HTMLElement | null>(null)
|
|
263
301
|
const user = useMemo(() => _user ?? createTLCurrentUser(), [_user])
|
|
264
302
|
|
|
@@ -285,6 +323,7 @@ export const TldrawEditor = memo(function TldrawEditor({
|
|
|
285
323
|
...rest,
|
|
286
324
|
shapeUtils: rest.shapeUtils ?? EMPTY_SHAPE_UTILS_ARRAY,
|
|
287
325
|
bindingUtils: rest.bindingUtils ?? EMPTY_BINDING_UTILS_ARRAY,
|
|
326
|
+
assetUtils: rest.assetUtils ?? EMPTY_ASSET_UTILS_ARRAY,
|
|
288
327
|
tools: rest.tools ?? EMPTY_TOOLS_ARRAY,
|
|
289
328
|
components,
|
|
290
329
|
options: useShallowObjectIdentity(mergedOptions),
|
|
@@ -332,7 +371,7 @@ export const TldrawEditor = memo(function TldrawEditor({
|
|
|
332
371
|
function TldrawEditorWithOwnStore(
|
|
333
372
|
props: Required<
|
|
334
373
|
TldrawEditorProps & { store: undefined; user: TLCurrentUser },
|
|
335
|
-
'shapeUtils' | 'bindingUtils' | 'tools'
|
|
374
|
+
'shapeUtils' | 'bindingUtils' | 'assetUtils' | 'tools'
|
|
336
375
|
>
|
|
337
376
|
) {
|
|
338
377
|
const {
|
|
@@ -341,17 +380,20 @@ function TldrawEditorWithOwnStore(
|
|
|
341
380
|
initialData,
|
|
342
381
|
shapeUtils,
|
|
343
382
|
bindingUtils,
|
|
383
|
+
assetUtils,
|
|
344
384
|
persistenceKey,
|
|
345
385
|
sessionId,
|
|
346
386
|
user,
|
|
347
387
|
assets,
|
|
348
388
|
users,
|
|
349
389
|
migrations,
|
|
390
|
+
themes,
|
|
350
391
|
} = props
|
|
351
392
|
|
|
352
393
|
const syncedStore = useLocalStore({
|
|
353
394
|
shapeUtils,
|
|
354
395
|
bindingUtils,
|
|
396
|
+
assetUtils,
|
|
355
397
|
initialData,
|
|
356
398
|
persistenceKey,
|
|
357
399
|
sessionId,
|
|
@@ -360,6 +402,7 @@ function TldrawEditorWithOwnStore(
|
|
|
360
402
|
assets,
|
|
361
403
|
users,
|
|
362
404
|
migrations,
|
|
405
|
+
themes,
|
|
363
406
|
})
|
|
364
407
|
|
|
365
408
|
return <TldrawEditorWithLoadingStore {...props} store={syncedStore} user={user} />
|
|
@@ -371,7 +414,7 @@ const TldrawEditorWithLoadingStore = memo(function TldrawEditorBeforeLoading({
|
|
|
371
414
|
...rest
|
|
372
415
|
}: Required<
|
|
373
416
|
TldrawEditorProps & { store: TLStoreWithStatus; user: TLCurrentUser },
|
|
374
|
-
'shapeUtils' | 'bindingUtils' | 'tools'
|
|
417
|
+
'shapeUtils' | 'bindingUtils' | 'assetUtils' | 'tools'
|
|
375
418
|
>) {
|
|
376
419
|
const container = useContainer()
|
|
377
420
|
|
|
@@ -417,22 +460,25 @@ function TldrawEditorWithReadyStore({
|
|
|
417
460
|
tools,
|
|
418
461
|
shapeUtils,
|
|
419
462
|
bindingUtils,
|
|
463
|
+
assetUtils,
|
|
420
464
|
user,
|
|
421
465
|
initialState,
|
|
422
466
|
autoFocus = true,
|
|
423
|
-
inferDarkMode,
|
|
424
467
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
425
468
|
cameraOptions,
|
|
426
469
|
options,
|
|
427
470
|
licenseKey,
|
|
428
471
|
getShapeVisibility,
|
|
472
|
+
colorScheme,
|
|
429
473
|
assetUrls,
|
|
474
|
+
themes,
|
|
475
|
+
initialTheme,
|
|
430
476
|
}: Required<
|
|
431
477
|
TldrawEditorProps & {
|
|
432
478
|
store: TLStore
|
|
433
479
|
user: TLCurrentUser
|
|
434
480
|
},
|
|
435
|
-
'shapeUtils' | 'bindingUtils' | 'tools'
|
|
481
|
+
'shapeUtils' | 'bindingUtils' | 'assetUtils' | 'tools'
|
|
436
482
|
>) {
|
|
437
483
|
const { ErrorFallback } = useEditorComponents()
|
|
438
484
|
const container = useContainer()
|
|
@@ -448,44 +494,58 @@ function TldrawEditorWithReadyStore({
|
|
|
448
494
|
const editorOptionsRef = useRef({
|
|
449
495
|
// for these, it's because they're only used when the editor first mounts:
|
|
450
496
|
autoFocus: autoFocus && !noAutoFocus(),
|
|
451
|
-
inferDarkMode,
|
|
452
497
|
initialState,
|
|
498
|
+
colorScheme,
|
|
453
499
|
|
|
454
500
|
// for these, it's because we keep them up to date in a separate effect:
|
|
455
501
|
cameraOptions,
|
|
456
502
|
deepLinks,
|
|
503
|
+
themes,
|
|
504
|
+
initialTheme,
|
|
457
505
|
})
|
|
458
506
|
|
|
459
507
|
useLayoutEffect(() => {
|
|
460
508
|
editorOptionsRef.current = {
|
|
461
509
|
autoFocus: autoFocus && !noAutoFocus(),
|
|
462
|
-
inferDarkMode,
|
|
463
510
|
initialState,
|
|
511
|
+
colorScheme,
|
|
464
512
|
cameraOptions,
|
|
465
513
|
deepLinks,
|
|
514
|
+
themes,
|
|
515
|
+
initialTheme,
|
|
466
516
|
}
|
|
467
|
-
}, [autoFocus,
|
|
517
|
+
}, [autoFocus, initialState, colorScheme, cameraOptions, deepLinks, themes, initialTheme])
|
|
468
518
|
|
|
469
519
|
useLayoutEffect(
|
|
470
520
|
() => {
|
|
471
|
-
const {
|
|
472
|
-
|
|
521
|
+
const {
|
|
522
|
+
autoFocus,
|
|
523
|
+
initialState,
|
|
524
|
+
colorScheme: initColorScheme,
|
|
525
|
+
cameraOptions,
|
|
526
|
+
deepLinks,
|
|
527
|
+
themes,
|
|
528
|
+
initialTheme,
|
|
529
|
+
} = editorOptionsRef.current
|
|
473
530
|
const editor = new Editor({
|
|
474
531
|
store,
|
|
475
532
|
shapeUtils,
|
|
476
533
|
bindingUtils,
|
|
534
|
+
assetUtils,
|
|
477
535
|
tools,
|
|
478
536
|
getContainer: () => container,
|
|
479
537
|
user,
|
|
480
538
|
initialState,
|
|
481
539
|
// we should check for some kind of query parameter that turns off autofocus
|
|
482
540
|
autoFocus,
|
|
483
|
-
inferDarkMode,
|
|
484
541
|
cameraOptions,
|
|
485
542
|
options,
|
|
486
543
|
licenseKey,
|
|
487
544
|
getShapeVisibility,
|
|
545
|
+
colorScheme: initColorScheme,
|
|
488
546
|
fontAssetUrls: assetUrls?.fonts,
|
|
547
|
+
themes: themes,
|
|
548
|
+
initialTheme: initialTheme,
|
|
489
549
|
})
|
|
490
550
|
|
|
491
551
|
editor.updateViewportScreenBounds(canvasRef.current ?? container)
|
|
@@ -510,7 +570,9 @@ function TldrawEditorWithReadyStore({
|
|
|
510
570
|
},
|
|
511
571
|
// if any of these change, we need to recreate the editor.
|
|
512
572
|
[
|
|
573
|
+
assetUtils,
|
|
513
574
|
bindingUtils,
|
|
575
|
+
colorScheme,
|
|
514
576
|
container,
|
|
515
577
|
options,
|
|
516
578
|
shapeUtils,
|
|
@@ -539,6 +601,21 @@ function TldrawEditorWithReadyStore({
|
|
|
539
601
|
}
|
|
540
602
|
}, [editor, cameraOptions, options?.camera])
|
|
541
603
|
|
|
604
|
+
// keep the editor up to date with the latest theme definitions
|
|
605
|
+
useLayoutEffect(() => {
|
|
606
|
+
if (editor && themes) {
|
|
607
|
+
for (const def of Object.values(themes) as TLTheme[]) {
|
|
608
|
+
editor.updateTheme(def)
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}, [editor, themes])
|
|
612
|
+
|
|
613
|
+
useLayoutEffect(() => {
|
|
614
|
+
if (editor && initialTheme) {
|
|
615
|
+
editor.setCurrentTheme(initialTheme)
|
|
616
|
+
}
|
|
617
|
+
}, [editor, initialTheme])
|
|
618
|
+
|
|
542
619
|
const crashingError = useSyncExternalStore(
|
|
543
620
|
useCallback(
|
|
544
621
|
(onStoreChange) => {
|
|
@@ -123,8 +123,14 @@ const Collaborator = track(function Collaborator({
|
|
|
123
123
|
.filter((id) => {
|
|
124
124
|
// Skip hidden shapes
|
|
125
125
|
if (editor.isShapeHidden(id)) return false
|
|
126
|
-
//
|
|
127
|
-
//
|
|
126
|
+
// When canvas indicators are disabled, render SVG indicators for
|
|
127
|
+
// every selected shape. Otherwise shapes that opt into the canvas
|
|
128
|
+
// path via useLegacyIndicator() === false would never get a
|
|
129
|
+
// collaborator indicator drawn.
|
|
130
|
+
if (!editor.options.useCanvasIndicators) return true
|
|
131
|
+
// Otherwise, only render SVG indicators for shapes that opt in to
|
|
132
|
+
// the legacy path — canvas-based indicators are handled by
|
|
133
|
+
// CanvasShapeIndicators.
|
|
128
134
|
const shape = editor.getShape(id)
|
|
129
135
|
if (!shape) return false
|
|
130
136
|
const util = editor.getShapeUtil(shape)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { useValue } from '@tldraw/state-react'
|
|
2
|
-
import { PointerEvent, useCallback, useRef, useState } from 'react'
|
|
2
|
+
import { type PointerEvent, useCallback, useEffect, useRef, useState } from 'react'
|
|
3
|
+
import { flushSync } from 'react-dom'
|
|
3
4
|
import { useCanvasEvents } from '../hooks/useCanvasEvents'
|
|
4
5
|
import { useEditor } from '../hooks/useEditor'
|
|
5
6
|
import { Vec } from '../primitives/Vec'
|
|
7
|
+
import { releasePointerCapture, setPointerCapture } from '../utils/dom'
|
|
6
8
|
import { getPointerInfo } from '../utils/getPointerInfo'
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -13,99 +15,173 @@ import { getPointerInfo } from '../utils/getPointerInfo'
|
|
|
13
15
|
export function MenuClickCapture() {
|
|
14
16
|
const editor = useEditor()
|
|
15
17
|
|
|
16
|
-
// Whether any menus are open
|
|
17
18
|
const isMenuOpen = useValue('is menu open', () => editor.menus.hasAnyOpenMenus(), [editor])
|
|
18
19
|
|
|
19
|
-
//
|
|
20
|
+
// Keep this component mounted while the pointer is down so pointerup/move still
|
|
21
|
+
// land here after a synchronous clearOpenMenus() flips isMenuOpen to false.
|
|
20
22
|
const [isPointing, setIsPointing] = useState(false)
|
|
21
|
-
|
|
22
23
|
const showElement = isMenuOpen || isPointing
|
|
23
24
|
|
|
24
|
-
// Get the same events that we use on the canvas
|
|
25
25
|
const canvasEvents = useCanvasEvents()
|
|
26
26
|
|
|
27
|
-
// Keep track of the pointer state
|
|
28
27
|
const rPointerState = useRef({
|
|
29
28
|
isDown: false,
|
|
30
29
|
isDragging: false,
|
|
30
|
+
button: 0,
|
|
31
31
|
start: new Vec(),
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
+
// Swallow the native contextmenu that follows a right-click pointerdown. Without
|
|
35
|
+
// this, Radix's trigger catches the native event and opens a menu at the pointer-
|
|
36
|
+
// DOWN position — then our own synthetic contextmenu (fired on pointerup) opens it
|
|
37
|
+
// again at the release position, producing a visible flash.
|
|
38
|
+
const rCancelContextMenuSwallow = useRef<null | (() => void)>(null)
|
|
39
|
+
useEffect(
|
|
40
|
+
() => () => {
|
|
41
|
+
rCancelContextMenuSwallow.current?.()
|
|
42
|
+
rCancelContextMenuSwallow.current = null
|
|
43
|
+
},
|
|
44
|
+
[]
|
|
45
|
+
)
|
|
46
|
+
const swallowNextNativeContextMenu = useCallback(() => {
|
|
47
|
+
rCancelContextMenuSwallow.current?.()
|
|
48
|
+
const doc = editor.getContainerDocument()
|
|
49
|
+
const onContextMenu = (event: MouseEvent) => {
|
|
50
|
+
// Skip our own synthetic contextmenu — only swallow the real browser one
|
|
51
|
+
if (!event.isTrusted) return
|
|
52
|
+
rCancelContextMenuSwallow.current?.()
|
|
53
|
+
rCancelContextMenuSwallow.current = null
|
|
54
|
+
event.preventDefault()
|
|
55
|
+
event.stopImmediatePropagation()
|
|
56
|
+
}
|
|
57
|
+
const cancel = () => doc.removeEventListener('contextmenu', onContextMenu, true)
|
|
58
|
+
rCancelContextMenuSwallow.current = cancel
|
|
59
|
+
doc.addEventListener('contextmenu', onContextMenu, true)
|
|
60
|
+
// Drop the listener on the next tick if it never fires (e.g. pointer moved off-screen)
|
|
61
|
+
doc.defaultView?.setTimeout(() => {
|
|
62
|
+
if (rCancelContextMenuSwallow.current === cancel) {
|
|
63
|
+
cancel()
|
|
64
|
+
rCancelContextMenuSwallow.current = null
|
|
65
|
+
}
|
|
66
|
+
}, 0)
|
|
67
|
+
}, [editor])
|
|
68
|
+
|
|
34
69
|
const handlePointerDown = useCallback(
|
|
35
70
|
(e: PointerEvent) => {
|
|
36
|
-
if (e.button
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
71
|
+
if (e.button !== 0 && e.button !== 2) return
|
|
72
|
+
|
|
73
|
+
flushSync(() => setIsPointing(true))
|
|
74
|
+
setPointerCapture(e.currentTarget, e)
|
|
75
|
+
rPointerState.current = {
|
|
76
|
+
isDown: true,
|
|
77
|
+
isDragging: false,
|
|
78
|
+
button: e.button,
|
|
79
|
+
start: new Vec(e.clientX, e.clientY),
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (e.button === 2) {
|
|
83
|
+
if (!editor.options.rightClickPanning) {
|
|
84
|
+
// Right-click panning off: close the open menu and swallow the native
|
|
85
|
+
// contextmenu that would otherwise briefly open a new one (causing a flash).
|
|
86
|
+
swallowNextNativeContextMenu()
|
|
87
|
+
editor.menus.clearOpenMenus()
|
|
88
|
+
return
|
|
42
89
|
}
|
|
43
|
-
|
|
90
|
+
// Forward right-click pointerdown through the canvas's own handler so
|
|
91
|
+
// pointer capture is also set on the canvas (load-bearing: without this
|
|
92
|
+
// the context menu briefly flashes closed during consecutive right-clicks).
|
|
93
|
+
// We don't clearOpenMenus() — Radix's DismissableLayer closes the menu
|
|
94
|
+
// via outside-click detection, keeping its internal state in sync.
|
|
95
|
+
const canvas =
|
|
96
|
+
editor.getContainer().querySelector<HTMLDivElement>('.tl-canvas') ?? e.currentTarget
|
|
97
|
+
canvasEvents.onPointerDown?.({ ...e, currentTarget: canvas })
|
|
98
|
+
swallowNextNativeContextMenu()
|
|
99
|
+
return
|
|
44
100
|
}
|
|
101
|
+
|
|
45
102
|
editor.menus.clearOpenMenus()
|
|
46
103
|
},
|
|
47
|
-
[editor]
|
|
104
|
+
[canvasEvents, editor, swallowNextNativeContextMenu]
|
|
48
105
|
)
|
|
49
106
|
|
|
50
|
-
const rDidAPointerDownAndDragWhileMenuWasOpen = useRef(false)
|
|
51
|
-
|
|
52
107
|
const handlePointerMove = useCallback(
|
|
53
108
|
(e: PointerEvent) => {
|
|
54
|
-
|
|
55
|
-
if (!
|
|
56
|
-
|
|
57
|
-
// call the onPointerDown with the original pointer position
|
|
58
|
-
const { x, y } = rPointerState.current.start
|
|
109
|
+
const state = rPointerState.current
|
|
110
|
+
if (!state.isDown) return
|
|
59
111
|
|
|
60
|
-
|
|
112
|
+
// Left-click: wait for the drag threshold before forwarding anything, then
|
|
113
|
+
// replay pointerdown at the original start so the editor records the
|
|
114
|
+
// correct drag origin. Right-click forwards moves immediately (pointerdown
|
|
115
|
+
// was already dispatched in handlePointerDown).
|
|
116
|
+
if (state.button !== 2 && !state.isDragging) {
|
|
61
117
|
if (
|
|
62
|
-
|
|
63
|
-
Vec.Dist2(rPointerState.current.start, new Vec(e.clientX, e.clientY)) >
|
|
118
|
+
Vec.Dist2(state.start, new Vec(e.clientX, e.clientY)) <=
|
|
64
119
|
editor.options.dragDistanceSquared
|
|
65
120
|
) {
|
|
66
|
-
|
|
67
|
-
// Wehaddaeventitsadrag
|
|
68
|
-
rPointerState.current = {
|
|
69
|
-
...rPointerState.current,
|
|
70
|
-
isDown: true,
|
|
71
|
-
isDragging: true,
|
|
72
|
-
}
|
|
73
|
-
canvasEvents.onPointerDown?.({
|
|
74
|
-
...e,
|
|
75
|
-
clientX: x,
|
|
76
|
-
clientY: y,
|
|
77
|
-
button: 0,
|
|
78
|
-
})
|
|
121
|
+
return
|
|
79
122
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (rDidAPointerDownAndDragWhileMenuWasOpen.current) {
|
|
123
|
+
state.isDragging = true
|
|
83
124
|
editor.dispatch({
|
|
84
125
|
type: 'pointer',
|
|
85
126
|
target: 'canvas',
|
|
86
|
-
name: '
|
|
87
|
-
...getPointerInfo(editor, e),
|
|
127
|
+
name: 'pointer_down',
|
|
128
|
+
...getPointerInfo(editor, { ...e, clientX: state.start.x, clientY: state.start.y }),
|
|
88
129
|
})
|
|
89
130
|
}
|
|
131
|
+
|
|
132
|
+
editor.dispatch({
|
|
133
|
+
type: 'pointer',
|
|
134
|
+
target: 'canvas',
|
|
135
|
+
name: 'pointer_move',
|
|
136
|
+
...getPointerInfo(editor, e),
|
|
137
|
+
})
|
|
90
138
|
},
|
|
91
|
-
[
|
|
139
|
+
[editor]
|
|
92
140
|
)
|
|
93
141
|
|
|
94
142
|
const handlePointerUp = useCallback(
|
|
95
143
|
(e: PointerEvent) => {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
144
|
+
const isStaticRightClick = e.button === 2 && !rPointerState.current.isDragging
|
|
145
|
+
|
|
146
|
+
editor.dispatch({
|
|
147
|
+
type: 'pointer',
|
|
148
|
+
target: 'canvas',
|
|
149
|
+
name: 'pointer_up',
|
|
150
|
+
...getPointerInfo(editor, e),
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
if (isStaticRightClick && editor.options.rightClickPanning) {
|
|
154
|
+
// Dispatch contextmenu on the canvas's parent (Radix's trigger) so the
|
|
155
|
+
// menu opens at the release position. Bypassing the canvas avoids its
|
|
156
|
+
// own onContextMenu handler, which preventDefaults non-synthesized events.
|
|
157
|
+
const canvas = editor.getContainer().querySelector<HTMLDivElement>('.tl-canvas')
|
|
158
|
+
const trigger = canvas?.parentElement ?? e.currentTarget
|
|
159
|
+
editor.timers.requestAnimationFrame(() => {
|
|
160
|
+
trigger.dispatchEvent(
|
|
161
|
+
new PointerEvent('contextmenu', {
|
|
162
|
+
bubbles: true,
|
|
163
|
+
clientX: e.clientX,
|
|
164
|
+
clientY: e.clientY,
|
|
165
|
+
button: 2,
|
|
166
|
+
buttons: 0,
|
|
167
|
+
pointerId: e.pointerId,
|
|
168
|
+
pointerType: e.pointerType,
|
|
169
|
+
isPrimary: e.isPrimary,
|
|
170
|
+
})
|
|
171
|
+
)
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
releasePointerCapture(e.currentTarget, e)
|
|
99
176
|
setIsPointing(false)
|
|
100
|
-
// Reset the pointer state
|
|
101
177
|
rPointerState.current = {
|
|
102
178
|
isDown: false,
|
|
103
179
|
isDragging: false,
|
|
180
|
+
button: 0,
|
|
104
181
|
start: new Vec(e.clientX, e.clientY),
|
|
105
182
|
}
|
|
106
|
-
rDidAPointerDownAndDragWhileMenuWasOpen.current = false
|
|
107
183
|
},
|
|
108
|
-
[
|
|
184
|
+
[editor]
|
|
109
185
|
)
|
|
110
186
|
|
|
111
187
|
return (
|
|
@@ -117,6 +193,10 @@ export function MenuClickCapture() {
|
|
|
117
193
|
onPointerDown={handlePointerDown}
|
|
118
194
|
onPointerMove={handlePointerMove}
|
|
119
195
|
onPointerUp={handlePointerUp}
|
|
196
|
+
onContextMenu={(e) => {
|
|
197
|
+
e.preventDefault()
|
|
198
|
+
e.stopPropagation()
|
|
199
|
+
}}
|
|
120
200
|
/>
|
|
121
201
|
)
|
|
122
202
|
)
|
|
@@ -6,8 +6,8 @@ import { memo, useEffect, useRef } from 'react'
|
|
|
6
6
|
import { Editor } from '../../editor/Editor'
|
|
7
7
|
import { TLIndicatorPath } from '../../editor/shapes/ShapeUtil'
|
|
8
8
|
import { getComputedStyle } from '../../exports/domUtils'
|
|
9
|
+
import { useColorMode } from '../../hooks/useColorMode'
|
|
9
10
|
import { useEditor } from '../../hooks/useEditor'
|
|
10
|
-
import { useIsDarkMode } from '../../hooks/useIsDarkMode'
|
|
11
11
|
import { useActivePeerIds$ } from '../../hooks/usePeerIds'
|
|
12
12
|
|
|
13
13
|
interface CollaboratorIndicatorData {
|
|
@@ -129,18 +129,29 @@ function renderIndicatorPath(ctx: CanvasRenderingContext2D, indicatorPath: TLInd
|
|
|
129
129
|
/** @internal @react */
|
|
130
130
|
export const CanvasShapeIndicators = memo(function CanvasShapeIndicators() {
|
|
131
131
|
const editor = useEditor()
|
|
132
|
+
|
|
133
|
+
// Skip canvas indicator rendering when the option is disabled (e.g. A/B test)
|
|
134
|
+
if (!editor.options.useCanvasIndicators) {
|
|
135
|
+
return null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return <CanvasShapeIndicatorsInner />
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const CanvasShapeIndicatorsInner = memo(function CanvasShapeIndicatorsInner() {
|
|
142
|
+
const editor = useEditor()
|
|
132
143
|
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
133
144
|
|
|
134
145
|
// Cache the selected color to avoid getComputedStyle on every render
|
|
135
146
|
const rSelectedColor = useRef<string | null>(null)
|
|
136
|
-
const
|
|
147
|
+
const colorMode = useColorMode()
|
|
137
148
|
|
|
138
149
|
useEffect(() => {
|
|
139
150
|
const timer = editor.timers.setTimeout(() => {
|
|
140
151
|
rSelectedColor.current = null
|
|
141
152
|
}, 0)
|
|
142
153
|
return () => clearTimeout(timer)
|
|
143
|
-
}, [
|
|
154
|
+
}, [colorMode, editor])
|
|
144
155
|
|
|
145
156
|
// Get active peer IDs (already handles time-based state transitions)
|
|
146
157
|
const activePeerIds$ = useActivePeerIds$()
|
|
@@ -465,8 +465,11 @@ function HintedShapeIndicator() {
|
|
|
465
465
|
const ids = useValue(
|
|
466
466
|
'hinting shape ids without canvas indicator',
|
|
467
467
|
() => {
|
|
468
|
+
const hintingIds = dedupe(editor.getHintingShapeIds())
|
|
469
|
+
// When canvas indicators are disabled, render all hints via SVG
|
|
470
|
+
if (!editor.options.useCanvasIndicators) return hintingIds
|
|
468
471
|
// Filter to only shapes that use legacy SVG indicators
|
|
469
|
-
return
|
|
472
|
+
return hintingIds.filter((id) => {
|
|
470
473
|
const shape = editor.getShape(id)
|
|
471
474
|
if (!shape) return false
|
|
472
475
|
const util = editor.getShapeUtil(shape)
|
|
@@ -530,7 +533,8 @@ function DebugSvgCopy({ id, mode }: { id: TLShapeId; mode: 'img' | 'iframe' }) {
|
|
|
530
533
|
const renderId = Math.random()
|
|
531
534
|
latest = renderId
|
|
532
535
|
|
|
533
|
-
const
|
|
536
|
+
const shape = editor.getShape(id)
|
|
537
|
+
const isSingleFrame = !!shape && editor.isShapeFrameLike(shape)
|
|
534
538
|
const padding = isSingleFrame ? 0 : 10
|
|
535
539
|
let bounds = editor.getShapePageBounds(id)
|
|
536
540
|
if (!bounds) return
|
|
@@ -34,8 +34,8 @@ const InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId })
|
|
|
34
34
|
|
|
35
35
|
const util = editor.getShapeUtil(shape)
|
|
36
36
|
|
|
37
|
-
// If the shape uses
|
|
38
|
-
if (!util.useLegacyIndicator()) return null
|
|
37
|
+
// If canvas indicators are enabled and the shape uses them, it will be rendered by CanvasShapeIndicators
|
|
38
|
+
if (editor.options.useCanvasIndicators && !util.useLegacyIndicator()) return null
|
|
39
39
|
|
|
40
40
|
return (
|
|
41
41
|
<OptionalErrorBoundary
|
|
@@ -91,9 +91,11 @@ export const DefaultShapeIndicators = memo(function DefaultShapeIndicators({
|
|
|
91
91
|
const { ShapeIndicator } = useEditorComponents()
|
|
92
92
|
|
|
93
93
|
// Filter out shapes that have canvas indicator support - only render shapes that use legacy SVG indicators
|
|
94
|
+
// When useCanvasIndicators is disabled, render all shapes via SVG
|
|
94
95
|
const shapesToRender = useValue(
|
|
95
96
|
'shapes to render for svg indicators',
|
|
96
97
|
() => {
|
|
98
|
+
if (!editor.options.useCanvasIndicators) return renderingShapes
|
|
97
99
|
return renderingShapes.filter(({ id }) => {
|
|
98
100
|
const shape = editor.getShape(id)
|
|
99
101
|
if (!shape) return false
|
|
@@ -8,15 +8,20 @@ import {
|
|
|
8
8
|
TLStore,
|
|
9
9
|
TLStoreProps,
|
|
10
10
|
TLStoreSnapshot,
|
|
11
|
+
TLThemes,
|
|
11
12
|
TLUser,
|
|
12
13
|
TLUserStore,
|
|
13
14
|
UserRecordType,
|
|
14
15
|
createCachedUserResolve,
|
|
15
16
|
createTLSchema,
|
|
16
17
|
createUserId,
|
|
18
|
+
registerColorsFromThemes,
|
|
19
|
+
registerFontsFromThemes,
|
|
17
20
|
} from '@tldraw/tlschema'
|
|
18
21
|
import { FileHelpers, assert } from '@tldraw/utils'
|
|
19
22
|
import { Editor } from '../editor/Editor'
|
|
23
|
+
import { resolveThemes } from '../editor/managers/ThemeManager/ThemeManager'
|
|
24
|
+
import { TLAnyAssetUtilConstructor, checkAssets } from './defaultAssets'
|
|
20
25
|
import { TLAnyBindingUtilConstructor, checkBindings } from './defaultBindings'
|
|
21
26
|
import { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from './defaultShapes'
|
|
22
27
|
import { TLEditorSnapshot, loadSnapshot } from './TLEditorSnapshot'
|
|
@@ -36,6 +41,13 @@ export interface TLStoreBaseOptions {
|
|
|
36
41
|
/** How should this store upload & resolve assets? */
|
|
37
42
|
assets?: TLAssetStore
|
|
38
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Named theme definitions. When provided, custom color names are automatically
|
|
46
|
+
* registered before the store is constructed so persisted data with those
|
|
47
|
+
* colors passes validation on load.
|
|
48
|
+
*/
|
|
49
|
+
themes?: Partial<TLThemes>
|
|
50
|
+
|
|
39
51
|
/** How should this store resolve users for attribution? */
|
|
40
52
|
users?: TLUserStore
|
|
41
53
|
|
|
@@ -50,8 +62,9 @@ export type TLStoreSchemaOptions =
|
|
|
50
62
|
}
|
|
51
63
|
| {
|
|
52
64
|
shapeUtils?: readonly TLAnyShapeUtilConstructor[]
|
|
53
|
-
migrations?: readonly MigrationSequence[]
|
|
54
65
|
bindingUtils?: readonly TLAnyBindingUtilConstructor[]
|
|
66
|
+
assetUtils?: readonly TLAnyAssetUtilConstructor[]
|
|
67
|
+
migrations?: readonly MigrationSequence[]
|
|
55
68
|
records?: Record<string, CustomRecordInfo>
|
|
56
69
|
}
|
|
57
70
|
|
|
@@ -114,6 +127,10 @@ export function createTLSchemaFromUtils(
|
|
|
114
127
|
'bindingUtils' in opts && opts.bindingUtils
|
|
115
128
|
? utilsToMap(checkBindings(opts.bindingUtils))
|
|
116
129
|
: undefined,
|
|
130
|
+
assets:
|
|
131
|
+
'assetUtils' in opts && opts.assetUtils
|
|
132
|
+
? utilsToMap(checkAssets(opts.assetUtils))
|
|
133
|
+
: undefined,
|
|
117
134
|
records: 'records' in opts ? opts.records : undefined,
|
|
118
135
|
migrations: 'migrations' in opts ? opts.migrations : undefined,
|
|
119
136
|
})
|
|
@@ -134,8 +151,12 @@ export function createTLStore({
|
|
|
134
151
|
users = defaultUserStore,
|
|
135
152
|
onMount,
|
|
136
153
|
collaboration,
|
|
154
|
+
themes,
|
|
137
155
|
...rest
|
|
138
156
|
}: TLStoreOptions = {}): TLStore {
|
|
157
|
+
const resolvedThemes = resolveThemes(themes)
|
|
158
|
+
registerColorsFromThemes(resolvedThemes)
|
|
159
|
+
registerFontsFromThemes(resolvedThemes)
|
|
139
160
|
const schema = createTLSchemaFromUtils(rest)
|
|
140
161
|
|
|
141
162
|
const store = new Store({
|