@tldraw/editor 4.6.0-next.0eb36d65eec3 → 4.6.0-next.1a05e8ec7833
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 +816 -112
- package/dist-cjs/index.js +22 -6
- package/dist-cjs/index.js.map +3 -3
- package/dist-cjs/lib/TldrawEditor.js +59 -14
- 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/{createTLUser.js → createTLCurrentUser.js} +9 -9
- package/dist-cjs/lib/config/createTLCurrentUser.js.map +7 -0
- package/dist-cjs/lib/config/createTLStore.js +30 -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 +389 -13
- package/dist-cjs/lib/editor/Editor.js.map +3 -3
- 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 +32 -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/clipboard-types.js.map +1 -1
- 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/hooks/useGestureEvents.js +171 -127
- package/dist-cjs/lib/hooks/useGestureEvents.js.map +3 -3
- 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 +816 -112
- package/dist-esm/index.mjs +27 -9
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +62 -14
- 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/{createTLUser.mjs → createTLCurrentUser.mjs} +6 -6
- package/dist-esm/lib/config/createTLCurrentUser.mjs.map +7 -0
- package/dist-esm/lib/config/createTLStore.mjs +36 -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 +391 -13
- package/dist-esm/lib/editor/Editor.mjs.map +3 -3
- 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 +32 -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/hooks/useGestureEvents.mjs +171 -127
- package/dist-esm/lib/hooks/useGestureEvents.mjs.map +3 -3
- 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 +13 -37
- package/package.json +8 -9
- package/src/index.ts +30 -7
- package/src/lib/TldrawEditor.tsx +98 -19
- 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/{createTLUser.ts → createTLCurrentUser.ts} +6 -6
- package/src/lib/config/createTLStore.ts +57 -2
- package/src/lib/config/defaultAssets.ts +19 -0
- package/src/lib/editor/Editor.ts +526 -42
- 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 +25 -31
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +7 -5
- package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +121 -0
- package/src/lib/editor/shapes/ShapeUtil.ts +50 -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/clipboard-types.ts +2 -1
- 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/hooks/useGestureEvents.ts +240 -168
- package/src/lib/options.ts +14 -0
- package/src/lib/primitives/Box.test.ts +30 -0
- package/src/lib/primitives/geometry/Geometry2d.test.ts +21 -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/config/createTLUser.js.map +0 -7
- package/dist-cjs/lib/hooks/useIsDarkMode.js.map +0 -7
- package/dist-esm/lib/config/createTLUser.mjs.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/editor/Editor.ts
CHANGED
|
@@ -10,10 +10,10 @@ import {
|
|
|
10
10
|
import {
|
|
11
11
|
ComputedCache,
|
|
12
12
|
RecordType,
|
|
13
|
+
StoreSideEffects,
|
|
14
|
+
StoreSnapshot,
|
|
13
15
|
UnknownRecord,
|
|
14
16
|
reverseRecordsDiff,
|
|
15
|
-
StoreSnapshot,
|
|
16
|
-
StoreSideEffects,
|
|
17
17
|
} from '@tldraw/store'
|
|
18
18
|
import {
|
|
19
19
|
CameraRecordType,
|
|
@@ -50,9 +50,16 @@ import {
|
|
|
50
50
|
TLShapePartial,
|
|
51
51
|
TLStore,
|
|
52
52
|
TLStoreSnapshot,
|
|
53
|
+
TLTheme,
|
|
54
|
+
TLThemeId,
|
|
55
|
+
TLThemes,
|
|
56
|
+
TLUser,
|
|
57
|
+
TLUserId,
|
|
53
58
|
TLVideoAsset,
|
|
59
|
+
UserRecordType,
|
|
54
60
|
createBindingId,
|
|
55
61
|
createShapeId,
|
|
62
|
+
createUserId,
|
|
56
63
|
getShapePropKeysByStyle,
|
|
57
64
|
isPageId,
|
|
58
65
|
isShapeId,
|
|
@@ -90,7 +97,8 @@ import {
|
|
|
90
97
|
uniqueId,
|
|
91
98
|
} from '@tldraw/utils'
|
|
92
99
|
import EventEmitter from 'eventemitter3'
|
|
93
|
-
import {
|
|
100
|
+
import { TLCurrentUser, createTLCurrentUser } from '../config/createTLCurrentUser'
|
|
101
|
+
import { TLAnyAssetUtilConstructor, checkAssets } from '../config/defaultAssets'
|
|
94
102
|
import { TLAnyBindingUtilConstructor, checkBindings } from '../config/defaultBindings'
|
|
95
103
|
import { TLAnyShapeUtilConstructor, checkShapesAndAddCore } from '../config/defaultShapes'
|
|
96
104
|
import {
|
|
@@ -137,6 +145,7 @@ import { getDroppedShapesToNewParents, kickoutOccludedShapes } from '../utils/re
|
|
|
137
145
|
import { TLTextOptions, TiptapEditor } from '../utils/richText'
|
|
138
146
|
import { applyRotationToSnapshotShapes, getRotationSnapshot } from '../utils/rotation'
|
|
139
147
|
import { ReadonlySharedStyleMap, SharedStyle, SharedStyleMap } from '../utils/SharedStylesMap'
|
|
148
|
+
import { AssetUtil } from './assets/AssetUtil'
|
|
140
149
|
import { BindingOnDeleteOptions, BindingUtil } from './bindings/BindingUtil'
|
|
141
150
|
import { bindingsIndex } from './derivations/bindingsIndex'
|
|
142
151
|
import { notVisibleShapes } from './derivations/notVisibleShapes'
|
|
@@ -148,10 +157,12 @@ import { FocusManager } from './managers/FocusManager/FocusManager'
|
|
|
148
157
|
import { FontManager } from './managers/FontManager/FontManager'
|
|
149
158
|
import { HistoryManager } from './managers/HistoryManager/HistoryManager'
|
|
150
159
|
import { InputsManager } from './managers/InputsManager/InputsManager'
|
|
160
|
+
import { PerformanceManager } from './managers/PerformanceManager/PerformanceManager'
|
|
151
161
|
import { ScribbleManager } from './managers/ScribbleManager/ScribbleManager'
|
|
152
162
|
import { SnapManager } from './managers/SnapManager/SnapManager'
|
|
153
163
|
import { SpatialIndexManager } from './managers/SpatialIndexManager/SpatialIndexManager'
|
|
154
164
|
import { TextManager } from './managers/TextManager/TextManager'
|
|
165
|
+
import { ThemeManager, resolveThemes } from './managers/ThemeManager/ThemeManager'
|
|
155
166
|
import { TickManager } from './managers/TickManager/TickManager'
|
|
156
167
|
import { UserPreferencesManager } from './managers/UserPreferencesManager/UserPreferencesManager'
|
|
157
168
|
import {
|
|
@@ -210,18 +221,17 @@ export interface TLEditorOptions {
|
|
|
210
221
|
*/
|
|
211
222
|
bindingUtils: readonly TLAnyBindingUtilConstructor[]
|
|
212
223
|
/**
|
|
213
|
-
* An array of
|
|
224
|
+
* An array of asset utils to use in the editor. These will be used to handle asset-type-specific behavior.
|
|
214
225
|
*/
|
|
215
|
-
|
|
226
|
+
assetUtils?: readonly TLAnyAssetUtilConstructor[]
|
|
216
227
|
/**
|
|
217
|
-
*
|
|
218
|
-
* given, the body element will be used.
|
|
228
|
+
* An array of tools to use in the editor. These will be used to handle events and manage user interactions in the editor.
|
|
219
229
|
*/
|
|
220
|
-
|
|
230
|
+
tools: readonly TLStateNodeConstructor[]
|
|
221
231
|
/**
|
|
222
232
|
* A user defined externally to replace the default user.
|
|
223
233
|
*/
|
|
224
|
-
user?:
|
|
234
|
+
user?: TLCurrentUser
|
|
225
235
|
/**
|
|
226
236
|
* The editor's initial active tool (or other state node id).
|
|
227
237
|
*/
|
|
@@ -230,25 +240,13 @@ export interface TLEditorOptions {
|
|
|
230
240
|
* Whether to automatically focus the editor when it mounts.
|
|
231
241
|
*/
|
|
232
242
|
autoFocus?: boolean
|
|
233
|
-
/**
|
|
234
|
-
* Whether to infer dark mode from the user's system preferences. Defaults to false.
|
|
235
|
-
*/
|
|
236
|
-
inferDarkMode?: boolean
|
|
237
|
-
/**
|
|
238
|
-
* Options for the editor's camera.
|
|
239
|
-
*
|
|
240
|
-
* @deprecated Use `options.cameraOptions` instead. This will be removed in a future release.
|
|
241
|
-
*/
|
|
242
|
-
cameraOptions?: Partial<TLCameraOptions>
|
|
243
|
-
options?: Partial<TldrawOptions>
|
|
244
|
-
/**
|
|
245
|
-
* Text options for the editor.
|
|
246
|
-
*
|
|
247
|
-
* @deprecated Use `options.text` instead. This prop will be removed in a future release.
|
|
248
|
-
*/
|
|
249
|
-
textOptions?: TLTextOptions
|
|
250
243
|
licenseKey?: string
|
|
251
244
|
fontAssetUrls?: { [key: string]: string | undefined }
|
|
245
|
+
/**
|
|
246
|
+
* Should return a containing html element which has all the styles applied to the editor. If not
|
|
247
|
+
* given, the body element will be used.
|
|
248
|
+
*/
|
|
249
|
+
getContainer(): HTMLElement
|
|
252
250
|
/**
|
|
253
251
|
* Provides a way to hide shapes.
|
|
254
252
|
*
|
|
@@ -268,6 +266,41 @@ export interface TLEditorOptions {
|
|
|
268
266
|
shape: TLShape,
|
|
269
267
|
editor: Editor
|
|
270
268
|
): 'visible' | 'hidden' | 'inherit' | null | undefined
|
|
269
|
+
/**
|
|
270
|
+
* Named theme definitions for the editor. Each theme contains shared
|
|
271
|
+
* properties (font size, line height, stroke width) and color palettes
|
|
272
|
+
* for both light and dark modes.
|
|
273
|
+
*/
|
|
274
|
+
themes?: Partial<TLThemes>
|
|
275
|
+
/**
|
|
276
|
+
* The id of the initially active theme. Defaults to `'default'`.
|
|
277
|
+
*/
|
|
278
|
+
initialTheme?: TLThemeId
|
|
279
|
+
/**
|
|
280
|
+
* The editor's color scheme preference, controls the default color mode. Defaults to `'light'`.
|
|
281
|
+
*
|
|
282
|
+
* - `'light'` - Always use light mode.
|
|
283
|
+
* - `'dark'` - Always use dark mode.
|
|
284
|
+
* - `'system'` - Follow the OS color scheme preference.
|
|
285
|
+
*/
|
|
286
|
+
colorScheme?: 'light' | 'dark' | 'system'
|
|
287
|
+
/**
|
|
288
|
+
* Additional configuration options for the tldraw editor.
|
|
289
|
+
*/
|
|
290
|
+
options?: Partial<TldrawOptions>
|
|
291
|
+
// --- Deprecated ----
|
|
292
|
+
/**
|
|
293
|
+
* Options for the editor's camera.
|
|
294
|
+
*
|
|
295
|
+
* @deprecated Use `options.cameraOptions` instead. This will be removed in a future release.
|
|
296
|
+
*/
|
|
297
|
+
cameraOptions?: Partial<TLCameraOptions>
|
|
298
|
+
/**
|
|
299
|
+
* Text options for the editor.
|
|
300
|
+
*
|
|
301
|
+
* @deprecated Use `options.text` instead. This prop will be removed in a future release.
|
|
302
|
+
*/
|
|
303
|
+
textOptions?: TLTextOptions
|
|
271
304
|
}
|
|
272
305
|
|
|
273
306
|
/**
|
|
@@ -296,6 +329,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
296
329
|
user,
|
|
297
330
|
shapeUtils,
|
|
298
331
|
bindingUtils,
|
|
332
|
+
assetUtils: assetUtilConstructors,
|
|
299
333
|
tools,
|
|
300
334
|
getContainer,
|
|
301
335
|
// needs to be here for backwards compatibility with TldrawEditor
|
|
@@ -303,13 +337,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
303
337
|
cameraOptions,
|
|
304
338
|
initialState,
|
|
305
339
|
autoFocus,
|
|
306
|
-
inferDarkMode,
|
|
307
340
|
options: _options,
|
|
308
341
|
// needs to be here for backwards compatibility with TldrawEditor
|
|
309
342
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
310
343
|
textOptions: _textOptions,
|
|
311
344
|
getShapeVisibility,
|
|
345
|
+
colorScheme,
|
|
312
346
|
fontAssetUrls,
|
|
347
|
+
themes,
|
|
348
|
+
initialTheme,
|
|
313
349
|
}: TLEditorOptions) {
|
|
314
350
|
super()
|
|
315
351
|
|
|
@@ -344,21 +380,36 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
344
380
|
...options?.camera,
|
|
345
381
|
})
|
|
346
382
|
|
|
383
|
+
this.getContainer = getContainer
|
|
384
|
+
|
|
347
385
|
this._textOptions = atom('text options', options?.text ?? null)
|
|
348
386
|
|
|
349
|
-
this.user = new UserPreferencesManager(user ??
|
|
387
|
+
this.user = new UserPreferencesManager(user ?? createTLCurrentUser(), colorScheme ?? 'light')
|
|
350
388
|
this.disposables.add(() => this.user.dispose())
|
|
351
389
|
|
|
352
|
-
this.getContainer = getContainer
|
|
353
|
-
|
|
354
390
|
this.textMeasure = new TextManager(this)
|
|
355
391
|
this.disposables.add(() => this.textMeasure.dispose())
|
|
356
392
|
|
|
357
|
-
this.
|
|
393
|
+
this._themeManager = new ThemeManager(this, {
|
|
394
|
+
themes: resolveThemes(themes),
|
|
395
|
+
initial: initialTheme ?? 'default',
|
|
396
|
+
})
|
|
397
|
+
this.disposables.add(() => this._themeManager.dispose())
|
|
358
398
|
|
|
359
399
|
this._tickManager = new TickManager(this)
|
|
400
|
+
this.disposables.add(() => this._tickManager.dispose())
|
|
401
|
+
this.disposables.add(() => {
|
|
402
|
+
// Reset camera state to 'idle' so the store isn't left stuck at 'moving'
|
|
403
|
+
// when tick events stop (e.g. React strict mode disposes while camera is moving)
|
|
404
|
+
this.off('tick', this._decayCameraStateTimeout)
|
|
405
|
+
this._setCameraState('idle')
|
|
406
|
+
})
|
|
407
|
+
|
|
408
|
+
this.fonts = new FontManager(this, fontAssetUrls)
|
|
360
409
|
|
|
361
410
|
this.inputs = new InputsManager(this)
|
|
411
|
+
this.performance = new PerformanceManager(this)
|
|
412
|
+
this.disposables.add(() => this.performance.dispose())
|
|
362
413
|
|
|
363
414
|
class NewRoot extends RootState {
|
|
364
415
|
static override initial = initialState ?? ''
|
|
@@ -396,6 +447,17 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
396
447
|
this.shapeUtils = _shapeUtils
|
|
397
448
|
this.styleProps = _styleProps
|
|
398
449
|
|
|
450
|
+
const _shapeUtilsByAssetType = {} as Record<string, ShapeUtil<any>>
|
|
451
|
+
for (const Util of allShapeUtils) {
|
|
452
|
+
const assetTypes = Util.handledAssetTypes
|
|
453
|
+
if (assetTypes) {
|
|
454
|
+
for (const assetType of assetTypes) {
|
|
455
|
+
_shapeUtilsByAssetType[assetType] = _shapeUtils[Util.type]
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
this._shapeUtilsByAssetType = _shapeUtilsByAssetType
|
|
460
|
+
|
|
399
461
|
const allBindingUtils = checkBindings(bindingUtils)
|
|
400
462
|
const _bindingUtils = {} as Record<string, BindingUtil<any>>
|
|
401
463
|
for (const Util of allBindingUtils) {
|
|
@@ -404,6 +466,17 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
404
466
|
}
|
|
405
467
|
this.bindingUtils = _bindingUtils
|
|
406
468
|
|
|
469
|
+
// Asset utils
|
|
470
|
+
if (assetUtilConstructors) {
|
|
471
|
+
const allAssetUtils = checkAssets(assetUtilConstructors)
|
|
472
|
+
const _assetUtils = {} as Record<string, AssetUtil<any>>
|
|
473
|
+
for (const Util of allAssetUtils) {
|
|
474
|
+
const util = new Util(this)
|
|
475
|
+
_assetUtils[Util.type] = util
|
|
476
|
+
}
|
|
477
|
+
this.assetUtils = _assetUtils
|
|
478
|
+
}
|
|
479
|
+
|
|
407
480
|
// Tools.
|
|
408
481
|
// Accept tools from constructor parameters which may not conflict with the root note's default or
|
|
409
482
|
// "baked in" tools, select and zoom.
|
|
@@ -820,6 +893,15 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
820
893
|
})
|
|
821
894
|
)
|
|
822
895
|
}
|
|
896
|
+
|
|
897
|
+
this.disposables.add(
|
|
898
|
+
react('sync current user record', () => {
|
|
899
|
+
const user = this.store.props.users.currentUser.get()
|
|
900
|
+
if (user) {
|
|
901
|
+
this._ensureUserRecord(user)
|
|
902
|
+
}
|
|
903
|
+
})
|
|
904
|
+
)
|
|
823
905
|
}
|
|
824
906
|
|
|
825
907
|
private readonly _getShapeVisibility?: TLEditorOptions['getShapeVisibility']
|
|
@@ -929,6 +1011,18 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
929
1011
|
*/
|
|
930
1012
|
readonly snaps: SnapManager
|
|
931
1013
|
|
|
1014
|
+
/**
|
|
1015
|
+
* A manager for performance measurement hooks.
|
|
1016
|
+
*
|
|
1017
|
+
* @public
|
|
1018
|
+
*/
|
|
1019
|
+
readonly performance: PerformanceManager
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* A manager for the spatial index, tracking where shapes exist on the canvas.
|
|
1023
|
+
*
|
|
1024
|
+
* @internal
|
|
1025
|
+
*/
|
|
932
1026
|
private readonly _spatialIndex: SpatialIndexManager
|
|
933
1027
|
|
|
934
1028
|
/**
|
|
@@ -946,6 +1040,13 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
946
1040
|
*/
|
|
947
1041
|
readonly user: UserPreferencesManager
|
|
948
1042
|
|
|
1043
|
+
/**
|
|
1044
|
+
* A manager for the editor's themes.
|
|
1045
|
+
*
|
|
1046
|
+
* @internal
|
|
1047
|
+
*/
|
|
1048
|
+
private readonly _themeManager: ThemeManager
|
|
1049
|
+
|
|
949
1050
|
/**
|
|
950
1051
|
* A helper for measuring text.
|
|
951
1052
|
*
|
|
@@ -1026,13 +1127,134 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1026
1127
|
* @public
|
|
1027
1128
|
*/
|
|
1028
1129
|
dispose() {
|
|
1130
|
+
// Stop any in-progress camera animations and following before
|
|
1131
|
+
// running disposables, so their cleanup listeners fire first
|
|
1132
|
+
this.stopCameraAnimation()
|
|
1133
|
+
if (this.getInstanceState().followingUserId) {
|
|
1134
|
+
this.stopFollowingUser()
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1029
1137
|
this.disposables.forEach((dispose) => dispose())
|
|
1030
1138
|
this.disposables.clear()
|
|
1139
|
+
|
|
1140
|
+
// Clear any open menus for this editor's context
|
|
1141
|
+
this.menus.clearOpenMenus()
|
|
1142
|
+
|
|
1031
1143
|
this.store.dispose()
|
|
1032
1144
|
this.isDisposed = true
|
|
1033
1145
|
this.emit('dispose')
|
|
1034
1146
|
}
|
|
1035
1147
|
|
|
1148
|
+
/* ------------------ Themes (shadowing the theme manager) ------------------ */
|
|
1149
|
+
|
|
1150
|
+
/**
|
|
1151
|
+
* Get the current color mode (`'light'` or `'dark'`), based on the user's dark mode preference.
|
|
1152
|
+
*
|
|
1153
|
+
* @public
|
|
1154
|
+
*/
|
|
1155
|
+
getColorMode(): 'light' | 'dark' {
|
|
1156
|
+
return this._themeManager.getColorMode()
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Set the color mode. Note that this is a convenience method that passes the mode to
|
|
1161
|
+
* `user.updateUserPreferences`, which is the source of truth for the user's color mode preference.
|
|
1162
|
+
*
|
|
1163
|
+
* @public
|
|
1164
|
+
*/
|
|
1165
|
+
setColorMode(mode: 'light' | 'dark') {
|
|
1166
|
+
this.user.updateUserPreferences({ colorScheme: mode })
|
|
1167
|
+
return this
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* Get the id of the current theme.
|
|
1172
|
+
*
|
|
1173
|
+
* @public
|
|
1174
|
+
*/
|
|
1175
|
+
getCurrentThemeId(): TLThemeId {
|
|
1176
|
+
return this._themeManager.getCurrentThemeId()
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* Get the current theme definition.
|
|
1181
|
+
*
|
|
1182
|
+
* @public
|
|
1183
|
+
*/
|
|
1184
|
+
getCurrentTheme(): TLTheme {
|
|
1185
|
+
return this._themeManager.getCurrentTheme()
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/**
|
|
1189
|
+
* Set the current theme by id.
|
|
1190
|
+
*
|
|
1191
|
+
* @public
|
|
1192
|
+
*/
|
|
1193
|
+
setCurrentTheme(id: TLThemeId) {
|
|
1194
|
+
this._themeManager.setCurrentTheme(id)
|
|
1195
|
+
return this
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Get all registered theme definitions.
|
|
1200
|
+
*
|
|
1201
|
+
* @public
|
|
1202
|
+
*/
|
|
1203
|
+
getThemes(): TLThemes {
|
|
1204
|
+
return this._themeManager.getThemes()
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/**
|
|
1208
|
+
* Get a single theme definition by id.
|
|
1209
|
+
*
|
|
1210
|
+
* @public
|
|
1211
|
+
*/
|
|
1212
|
+
getTheme(id: TLThemeId): TLTheme | undefined {
|
|
1213
|
+
return this._themeManager.getTheme(id)
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* Replace all theme definitions, or update them via a callback that receives a deep copy.
|
|
1218
|
+
* The `'default'` theme must always be present in the result.
|
|
1219
|
+
*
|
|
1220
|
+
* @example
|
|
1221
|
+
* ```ts
|
|
1222
|
+
* // Replace all themes
|
|
1223
|
+
* editor.updateThemes({ default: myDefaultTheme, ocean: myOceanTheme })
|
|
1224
|
+
*
|
|
1225
|
+
* // Update via callback
|
|
1226
|
+
* editor.updateThemes((themes) => {
|
|
1227
|
+
* delete themes.ocean
|
|
1228
|
+
* return themes
|
|
1229
|
+
* })
|
|
1230
|
+
* ```
|
|
1231
|
+
*
|
|
1232
|
+
* @public
|
|
1233
|
+
*/
|
|
1234
|
+
updateThemes(themes: TLThemes | ((themes: TLThemes) => TLThemes)) {
|
|
1235
|
+
this._themeManager.updateThemes(themes)
|
|
1236
|
+
return this
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
/**
|
|
1240
|
+
* Register or update a single theme definition. The theme is keyed by its `id` property.
|
|
1241
|
+
*
|
|
1242
|
+
* @example
|
|
1243
|
+
* ```ts
|
|
1244
|
+
* // Override a property on the default theme
|
|
1245
|
+
* editor.updateTheme({ ...editor.getTheme('default')!, fontSize: 24 })
|
|
1246
|
+
*
|
|
1247
|
+
* // Register a new theme
|
|
1248
|
+
* editor.updateTheme({ id: 'ocean', ...myOceanTheme })
|
|
1249
|
+
* ```
|
|
1250
|
+
*
|
|
1251
|
+
* @public
|
|
1252
|
+
*/
|
|
1253
|
+
updateTheme(theme: TLTheme) {
|
|
1254
|
+
this._themeManager.updateTheme(theme)
|
|
1255
|
+
return this
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1036
1258
|
/* ------------------- Shape Utils ------------------ */
|
|
1037
1259
|
|
|
1038
1260
|
/**
|
|
@@ -1042,6 +1264,9 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1042
1264
|
*/
|
|
1043
1265
|
shapeUtils: { readonly [K in string]?: ShapeUtil<TLShape> }
|
|
1044
1266
|
|
|
1267
|
+
/** @internal */
|
|
1268
|
+
private _shapeUtilsByAssetType: { readonly [K in string]?: ShapeUtil<TLShape> } = {}
|
|
1269
|
+
|
|
1045
1270
|
styleProps: { [key: string]: Map<StyleProp<any>, string> }
|
|
1046
1271
|
|
|
1047
1272
|
/**
|
|
@@ -1084,6 +1309,18 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1084
1309
|
return hasOwnProperty(this.shapeUtils, type)
|
|
1085
1310
|
}
|
|
1086
1311
|
|
|
1312
|
+
/**
|
|
1313
|
+
* Get the shape util that handles the given asset type.
|
|
1314
|
+
* Returns the shape util whose {@link ShapeUtil.handledAssetTypes} includes
|
|
1315
|
+
* the given asset type, or undefined if none matches.
|
|
1316
|
+
*
|
|
1317
|
+
* @param assetType - The asset type string.
|
|
1318
|
+
* @public
|
|
1319
|
+
*/
|
|
1320
|
+
getShapeUtilForAssetType(assetType: string): ShapeUtil | undefined {
|
|
1321
|
+
return getOwnProperty(this._shapeUtilsByAssetType, assetType)
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1087
1324
|
/* ------------------- Binding Utils ------------------ */
|
|
1088
1325
|
/**
|
|
1089
1326
|
* A map of shape utility classes (TLShapeUtils) by shape type.
|
|
@@ -1119,6 +1356,56 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1119
1356
|
return bindingUtil
|
|
1120
1357
|
}
|
|
1121
1358
|
|
|
1359
|
+
/* ------------------- Asset Utils ------------------ */
|
|
1360
|
+
|
|
1361
|
+
/**
|
|
1362
|
+
* A map of asset utility classes by asset type.
|
|
1363
|
+
*
|
|
1364
|
+
* @public
|
|
1365
|
+
*/
|
|
1366
|
+
assetUtils: { readonly [K in string]?: AssetUtil<TLAsset> } = {}
|
|
1367
|
+
|
|
1368
|
+
/**
|
|
1369
|
+
* Get an asset util from an asset or asset type.
|
|
1370
|
+
*
|
|
1371
|
+
* @param arg - An asset, asset type string, or object with type.
|
|
1372
|
+
*
|
|
1373
|
+
* @public
|
|
1374
|
+
*/
|
|
1375
|
+
getAssetUtil<S extends TLAsset>(asset: S | { type: S['type'] }): AssetUtil<S>
|
|
1376
|
+
getAssetUtil(type: string): AssetUtil
|
|
1377
|
+
getAssetUtil(arg: string | { type: string }) {
|
|
1378
|
+
const type = typeof arg === 'string' ? arg : arg.type
|
|
1379
|
+
const assetUtil = getOwnProperty(this.assetUtils, type)
|
|
1380
|
+
assert(assetUtil, `No asset util found for type "${type}"`)
|
|
1381
|
+
return assetUtil
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
/**
|
|
1385
|
+
* Returns true if the editor has an asset util for the given asset type.
|
|
1386
|
+
*
|
|
1387
|
+
* @public
|
|
1388
|
+
*/
|
|
1389
|
+
hasAssetUtil(arg: string | { type: string }): boolean {
|
|
1390
|
+
const type = typeof arg === 'string' ? arg : arg.type
|
|
1391
|
+
return hasOwnProperty(this.assetUtils, type)
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
/**
|
|
1395
|
+
* Get the asset util that accepts the given MIME type.
|
|
1396
|
+
* Returns null if no registered asset util accepts the MIME type.
|
|
1397
|
+
*
|
|
1398
|
+
* @public
|
|
1399
|
+
*/
|
|
1400
|
+
getAssetUtilForMimeType(mimeType: string): AssetUtil | null {
|
|
1401
|
+
for (const util of Object.values(this.assetUtils)) {
|
|
1402
|
+
if (util && util.acceptsMimeType(mimeType)) {
|
|
1403
|
+
return util
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
return null
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1122
1409
|
/* --------------------- History -------------------- */
|
|
1123
1410
|
|
|
1124
1411
|
/**
|
|
@@ -1142,6 +1429,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1142
1429
|
this._flushEventsForTick(0)
|
|
1143
1430
|
this.complete()
|
|
1144
1431
|
this.history.undo()
|
|
1432
|
+
this.performance._notifyUndoRedo('undo', this.history.getNumUndos(), this.history.getNumRedos())
|
|
1145
1433
|
return this
|
|
1146
1434
|
}
|
|
1147
1435
|
|
|
@@ -1172,6 +1460,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
1172
1460
|
this._flushEventsForTick(0)
|
|
1173
1461
|
this.complete()
|
|
1174
1462
|
this.history.redo()
|
|
1463
|
+
this.performance._notifyUndoRedo('redo', this.history.getNumUndos(), this.history.getNumRedos())
|
|
1175
1464
|
return this
|
|
1176
1465
|
}
|
|
1177
1466
|
|
|
@@ -3972,6 +4261,94 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
3972
4261
|
return this.getCollaborators().filter((c) => c.currentPageId === currentPageId)
|
|
3973
4262
|
}
|
|
3974
4263
|
|
|
4264
|
+
// Attribution
|
|
4265
|
+
|
|
4266
|
+
/**
|
|
4267
|
+
* Get the current user's ID for attribution purposes.
|
|
4268
|
+
* Also ensures a `user:` record exists in the store for the current user.
|
|
4269
|
+
* Returns `null` when the user store has no current user.
|
|
4270
|
+
*
|
|
4271
|
+
* @public
|
|
4272
|
+
*/
|
|
4273
|
+
getAttributionUserId(): string | null {
|
|
4274
|
+
const user = this.store.props.users.currentUser.get()
|
|
4275
|
+
if (!user) return null
|
|
4276
|
+
this._ensureUserRecord(user)
|
|
4277
|
+
return UserRecordType.parseId(user.id)
|
|
4278
|
+
}
|
|
4279
|
+
|
|
4280
|
+
/**
|
|
4281
|
+
* Ensure a user record exists in the store for the given user,
|
|
4282
|
+
* updating it if the data has changed.
|
|
4283
|
+
*
|
|
4284
|
+
* @internal
|
|
4285
|
+
*/
|
|
4286
|
+
_ensureUserRecord(user: TLUser): void {
|
|
4287
|
+
const existing = this.store.get(user.id)
|
|
4288
|
+
if (
|
|
4289
|
+
existing &&
|
|
4290
|
+
existing.name === user.name &&
|
|
4291
|
+
existing.color === user.color &&
|
|
4292
|
+
existing.imageUrl === user.imageUrl &&
|
|
4293
|
+
existing.meta === user.meta
|
|
4294
|
+
) {
|
|
4295
|
+
return
|
|
4296
|
+
}
|
|
4297
|
+
this.run(
|
|
4298
|
+
() => {
|
|
4299
|
+
this.store.put([user])
|
|
4300
|
+
},
|
|
4301
|
+
{ history: 'ignore' }
|
|
4302
|
+
)
|
|
4303
|
+
}
|
|
4304
|
+
|
|
4305
|
+
/**
|
|
4306
|
+
* Resolve a display name for a user ID. Asks the
|
|
4307
|
+
* {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
|
|
4308
|
+
* falling back to the `user:` record in the store.
|
|
4309
|
+
*
|
|
4310
|
+
* @public
|
|
4311
|
+
*/
|
|
4312
|
+
getAttributionDisplayName(userId: string | null): string | null {
|
|
4313
|
+
if (!userId) return null
|
|
4314
|
+
return (
|
|
4315
|
+
this.store.props.users.resolve(userId).get()?.name ??
|
|
4316
|
+
this.store.get(createUserId(userId))?.name ??
|
|
4317
|
+
null
|
|
4318
|
+
)
|
|
4319
|
+
}
|
|
4320
|
+
|
|
4321
|
+
/**
|
|
4322
|
+
* Resolve a user record by ID. Asks the
|
|
4323
|
+
* {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
|
|
4324
|
+
* falling back to the `user:` record in the store.
|
|
4325
|
+
*
|
|
4326
|
+
* @public
|
|
4327
|
+
*/
|
|
4328
|
+
getAttributionUser(userId: string | null): TLUser | null {
|
|
4329
|
+
if (!userId) return null
|
|
4330
|
+
return (
|
|
4331
|
+
this.store.props.users.resolve(userId).get() ?? this.store.get(createUserId(userId)) ?? null
|
|
4332
|
+
)
|
|
4333
|
+
}
|
|
4334
|
+
|
|
4335
|
+
/**
|
|
4336
|
+
* Collect user IDs referenced by a set of shapes via shape-specific props
|
|
4337
|
+
* (e.g. `textFirstEditedBy` on notes).
|
|
4338
|
+
*
|
|
4339
|
+
* @internal
|
|
4340
|
+
*/
|
|
4341
|
+
_getReferencedUserIds(shapes: TLShape[]): Set<string> {
|
|
4342
|
+
const userIds = new Set<string>()
|
|
4343
|
+
for (const shape of shapes) {
|
|
4344
|
+
const util = this.getShapeUtil(shape)
|
|
4345
|
+
for (const id of util.getReferencedUserIds(shape)) {
|
|
4346
|
+
userIds.add(id)
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
return userIds
|
|
4350
|
+
}
|
|
4351
|
+
|
|
3975
4352
|
// Following
|
|
3976
4353
|
|
|
3977
4354
|
// When we are 'locked on' to a user, our camera is derived from their camera.
|
|
@@ -5326,8 +5703,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5326
5703
|
? this.getCurrentPageRenderingShapesSorted()
|
|
5327
5704
|
: this.getCurrentPageShapesSorted()
|
|
5328
5705
|
).filter((shape) => {
|
|
5329
|
-
//
|
|
5330
|
-
if (!candidateIds.has(shape.id) && !this.
|
|
5706
|
+
// Frame-like shapes have labels positioned above the shape (outside bounds), so always include them
|
|
5707
|
+
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false
|
|
5331
5708
|
|
|
5332
5709
|
if (
|
|
5333
5710
|
(shape.isLocked && !hitLocked) ||
|
|
@@ -5349,12 +5726,14 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5349
5726
|
const pointInShapeSpace = this.getPointInShapeSpace(shape, point)
|
|
5350
5727
|
|
|
5351
5728
|
// Check labels first
|
|
5729
|
+
const shapeUtil = this.getShapeUtil(shape)
|
|
5730
|
+
const isShapeFrameLike = this.isShapeFrameLike(shape)
|
|
5352
5731
|
if (
|
|
5353
|
-
|
|
5732
|
+
isShapeFrameLike ||
|
|
5354
5733
|
((this.isShapeOfType(shape, 'note') ||
|
|
5355
5734
|
this.isShapeOfType(shape, 'arrow') ||
|
|
5356
5735
|
(this.isShapeOfType(shape, 'geo') && shape.props.fill === 'none')) &&
|
|
5357
|
-
|
|
5736
|
+
shapeUtil.getText(shape)?.trim())
|
|
5358
5737
|
) {
|
|
5359
5738
|
for (const childGeometry of (geometry as Group2d).children) {
|
|
5360
5739
|
if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
|
|
@@ -5363,8 +5742,8 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5363
5742
|
}
|
|
5364
5743
|
}
|
|
5365
5744
|
|
|
5366
|
-
if (
|
|
5367
|
-
// On the rare case that we've hit a frame (not its label), test again hitInside to be forced true;
|
|
5745
|
+
if (isShapeFrameLike) {
|
|
5746
|
+
// On the rare case that we've hit a frame-like shape (not its label), test again hitInside to be forced true;
|
|
5368
5747
|
// this prevents clicks from passing through the body of a frame to shapes behind it.
|
|
5369
5748
|
|
|
5370
5749
|
// If the hit is within the frame's outer margin, then select the frame
|
|
@@ -5523,11 +5902,11 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5523
5902
|
const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, margin)
|
|
5524
5903
|
|
|
5525
5904
|
// Get all page shapes in z-index order and filter to candidates that pass isPointInShape
|
|
5526
|
-
//
|
|
5905
|
+
// Frame-like shapes are always checked because their labels can be outside their bounds
|
|
5527
5906
|
return this.getCurrentPageShapesSorted()
|
|
5528
5907
|
.filter((shape) => {
|
|
5529
5908
|
if (this.isShapeHidden(shape)) return false
|
|
5530
|
-
if (!candidateIds.has(shape.id) && !this.
|
|
5909
|
+
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false
|
|
5531
5910
|
return this.isPointInShape(shape, point, opts)
|
|
5532
5911
|
})
|
|
5533
5912
|
.reverse()
|
|
@@ -5702,6 +6081,25 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
5702
6081
|
return shape.type === type
|
|
5703
6082
|
}
|
|
5704
6083
|
|
|
6084
|
+
/**
|
|
6085
|
+
* Get whether a shape behaves like a frame — a container that has child
|
|
6086
|
+
* shapes, requires full-brush selection, blocks erasure from inside, etc.
|
|
6087
|
+
*
|
|
6088
|
+
* @example
|
|
6089
|
+
* ```ts
|
|
6090
|
+
* const isFrameLike = editor.isShapeFrameLike(someShape)
|
|
6091
|
+
* ```
|
|
6092
|
+
*
|
|
6093
|
+
* @param shape - The shape (or shape id) to test.
|
|
6094
|
+
*
|
|
6095
|
+
* @public
|
|
6096
|
+
*/
|
|
6097
|
+
isShapeFrameLike(shape: TLShape | TLShapeId): boolean {
|
|
6098
|
+
const _shape = typeof shape === 'string' ? this.getShape(shape) : shape
|
|
6099
|
+
if (!_shape) return false
|
|
6100
|
+
return this.getShapeUtil(_shape).isFrameLike(_shape)
|
|
6101
|
+
}
|
|
6102
|
+
|
|
5705
6103
|
/**
|
|
5706
6104
|
* Get a shape by its id.
|
|
5707
6105
|
*
|
|
@@ -9157,12 +9555,23 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9157
9555
|
assets.push(asset)
|
|
9158
9556
|
}
|
|
9159
9557
|
|
|
9558
|
+
const users: TLUser[] = []
|
|
9559
|
+
const seenUserIds = new Set<TLUserId>()
|
|
9560
|
+
for (const userId of this._getReferencedUserIds(shapes)) {
|
|
9561
|
+
const recordId = createUserId(userId)
|
|
9562
|
+
if (seenUserIds.has(recordId)) continue
|
|
9563
|
+
seenUserIds.add(recordId)
|
|
9564
|
+
const user = this.store.get(recordId)
|
|
9565
|
+
if (user) users.push(user)
|
|
9566
|
+
}
|
|
9567
|
+
|
|
9160
9568
|
return {
|
|
9161
9569
|
schema: this.store.schema.serialize(),
|
|
9162
9570
|
shapes,
|
|
9163
9571
|
rootShapeIds,
|
|
9164
9572
|
bindings,
|
|
9165
9573
|
assets,
|
|
9574
|
+
users,
|
|
9166
9575
|
}
|
|
9167
9576
|
})
|
|
9168
9577
|
}
|
|
@@ -9238,6 +9647,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9238
9647
|
const assets: TLAsset[] = []
|
|
9239
9648
|
const shapes: TLShape[] = []
|
|
9240
9649
|
const bindings: TLBinding[] = []
|
|
9650
|
+
const users: TLUser[] = []
|
|
9241
9651
|
|
|
9242
9652
|
// Let's treat the content as a store, and then migrate that store.
|
|
9243
9653
|
const store: StoreSnapshot<TLRecord> = {
|
|
@@ -9247,6 +9657,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9247
9657
|
...Object.fromEntries(
|
|
9248
9658
|
content.bindings?.map((bindings) => [bindings.id, bindings] as const) ?? []
|
|
9249
9659
|
),
|
|
9660
|
+
...Object.fromEntries(content.users?.map((user) => [user.id, user] as const) ?? []),
|
|
9250
9661
|
},
|
|
9251
9662
|
schema: content.schema,
|
|
9252
9663
|
}
|
|
@@ -9268,6 +9679,23 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
9268
9679
|
bindings.push(record)
|
|
9269
9680
|
break
|
|
9270
9681
|
}
|
|
9682
|
+
case 'user': {
|
|
9683
|
+
users.push(record)
|
|
9684
|
+
break
|
|
9685
|
+
}
|
|
9686
|
+
}
|
|
9687
|
+
}
|
|
9688
|
+
|
|
9689
|
+
if (users.length > 0) {
|
|
9690
|
+
const existingUserIds = new Set(
|
|
9691
|
+
this.store
|
|
9692
|
+
.allRecords()
|
|
9693
|
+
.filter((r): r is TLUser => r.typeName === 'user')
|
|
9694
|
+
.map((r) => r.id)
|
|
9695
|
+
)
|
|
9696
|
+
const usersToCreate = users.filter((u) => !existingUserIds.has(u.id))
|
|
9697
|
+
if (usersToCreate.length > 0) {
|
|
9698
|
+
this.store.put(usersToCreate)
|
|
9271
9699
|
}
|
|
9272
9700
|
}
|
|
9273
9701
|
|
|
@@ -10458,6 +10886,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10458
10886
|
{ immediate: true }
|
|
10459
10887
|
)
|
|
10460
10888
|
|
|
10889
|
+
this.performance._notifyCameraOperation('zooming')
|
|
10461
10890
|
this.emit('event', info)
|
|
10462
10891
|
return // Stop here!
|
|
10463
10892
|
}
|
|
@@ -10550,6 +10979,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10550
10979
|
immediate: true,
|
|
10551
10980
|
})
|
|
10552
10981
|
this.maybeTrackPerformance('Zooming')
|
|
10982
|
+
this.performance._notifyCameraOperation('zooming')
|
|
10553
10983
|
this.root.handleEvent(info)
|
|
10554
10984
|
this.emit('event', info)
|
|
10555
10985
|
return
|
|
@@ -10560,6 +10990,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10560
10990
|
immediate: true,
|
|
10561
10991
|
})
|
|
10562
10992
|
this.maybeTrackPerformance('Panning')
|
|
10993
|
+
this.performance._notifyCameraOperation('panning')
|
|
10563
10994
|
this.root.handleEvent(info)
|
|
10564
10995
|
this.emit('event', info)
|
|
10565
10996
|
return
|
|
@@ -10626,6 +11057,10 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10626
11057
|
}
|
|
10627
11058
|
this.inputs.setIsPanning(true)
|
|
10628
11059
|
clearTimeout(this._longPressTimeout)
|
|
11060
|
+
} else if (info.button === RIGHT_MOUSE_BUTTON && this.options.rightClickPanning) {
|
|
11061
|
+
this.inputs.setIsRightPointing(true)
|
|
11062
|
+
clearTimeout(this._longPressTimeout)
|
|
11063
|
+
return this
|
|
10629
11064
|
}
|
|
10630
11065
|
|
|
10631
11066
|
// We might be panning because we did a middle mouse click, or because we're holding spacebar and started a regular click
|
|
@@ -10644,9 +11079,31 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10644
11079
|
|
|
10645
11080
|
const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera())
|
|
10646
11081
|
|
|
11082
|
+
// Right-click pointing: waiting to see if this becomes a drag
|
|
11083
|
+
if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
|
|
11084
|
+
const currentScreenPoint = this.inputs.getCurrentScreenPoint()
|
|
11085
|
+
const originScreenPoint = this.inputs.getOriginScreenPoint()
|
|
11086
|
+
if (
|
|
11087
|
+
Vec.Dist2(originScreenPoint, currentScreenPoint) > this.options.dragDistanceSquared
|
|
11088
|
+
) {
|
|
11089
|
+
// Passed the drag threshold—transition to panning
|
|
11090
|
+
this._prevCursor = this.getInstanceState().cursor.type
|
|
11091
|
+
this.inputs.setIsPanning(true)
|
|
11092
|
+
this.setCursor({ type: 'grabbing', rotation: 0 })
|
|
11093
|
+
this.stopCameraAnimation()
|
|
11094
|
+
// Apply the initial delta from the pointer down origin
|
|
11095
|
+
const offset = Vec.Sub(currentScreenPoint, originScreenPoint)
|
|
11096
|
+
this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
|
|
11097
|
+
immediate: true,
|
|
11098
|
+
})
|
|
11099
|
+
this.maybeTrackPerformance('Panning')
|
|
11100
|
+
}
|
|
11101
|
+
return
|
|
11102
|
+
}
|
|
11103
|
+
|
|
10647
11104
|
// If we've started panning, then clear any long press timeout
|
|
10648
11105
|
if (this.inputs.getIsPanning() && this.inputs.getIsPointing()) {
|
|
10649
|
-
// Handle spacebar / middle mouse button panning
|
|
11106
|
+
// Handle spacebar / middle mouse button / right-click panning
|
|
10650
11107
|
const currentScreenPoint = this.inputs.getCurrentScreenPoint()
|
|
10651
11108
|
const previousScreenPoint = this.inputs.getPreviousScreenPoint()
|
|
10652
11109
|
const offset = Vec.Sub(currentScreenPoint, previousScreenPoint)
|
|
@@ -10654,6 +11111,7 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10654
11111
|
immediate: true,
|
|
10655
11112
|
})
|
|
10656
11113
|
this.maybeTrackPerformance('Panning')
|
|
11114
|
+
this.performance._notifyCameraOperation('panning')
|
|
10657
11115
|
return
|
|
10658
11116
|
}
|
|
10659
11117
|
|
|
@@ -10678,13 +11136,24 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10678
11136
|
inputs.setIsDragging(false)
|
|
10679
11137
|
inputs.setIsPointing(false)
|
|
10680
11138
|
clearTimeout(this._longPressTimeout)
|
|
10681
|
-
|
|
10682
11139
|
// Remove the button from the buttons set
|
|
10683
11140
|
inputs.buttons.delete(info.button)
|
|
10684
11141
|
|
|
10685
11142
|
// If we're in pen mode and we're not using a pen, stop here
|
|
10686
11143
|
if (instanceState.isPenMode && !isPen) return
|
|
10687
11144
|
|
|
11145
|
+
// Right-click pointing ended without dragging—this is a static
|
|
11146
|
+
// right-click, so let it through to the state chart as right_click.
|
|
11147
|
+
// Check isPanning first: if we transitioned to panning, isRightPointing
|
|
11148
|
+
// is still true but we want the panning cleanup path instead.
|
|
11149
|
+
if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
|
|
11150
|
+
this.inputs.setIsRightPointing(false)
|
|
11151
|
+
this._selectedShapeIdsAtPointerDown = []
|
|
11152
|
+
break // fall through to state chart dispatch as right_click
|
|
11153
|
+
}
|
|
11154
|
+
|
|
11155
|
+
this.inputs.setIsRightPointing(false)
|
|
11156
|
+
|
|
10688
11157
|
// Firefox bug fix...
|
|
10689
11158
|
// If it's the same pointer that we stored earlier...
|
|
10690
11159
|
// ... then it's probably still a left-mouse-click!
|
|
@@ -10707,11 +11176,26 @@ export class Editor extends EventEmitter<TLEventMap> {
|
|
|
10707
11176
|
break
|
|
10708
11177
|
}
|
|
10709
11178
|
case MIDDLE_MOUSE_BUTTON: {
|
|
10710
|
-
if (this.inputs.keys.has('
|
|
11179
|
+
if (this.inputs.keys.has('Space')) {
|
|
10711
11180
|
this.setCursor({ type: 'grab', rotation: 0 })
|
|
10712
11181
|
} else {
|
|
10713
11182
|
this.setCursor({ type: this._prevCursor, rotation: 0 })
|
|
10714
11183
|
}
|
|
11184
|
+
break
|
|
11185
|
+
}
|
|
11186
|
+
case RIGHT_MOUSE_BUTTON: {
|
|
11187
|
+
if (this.inputs.keys.has('Space')) {
|
|
11188
|
+
this.setCursor({ type: 'grab', rotation: 0 })
|
|
11189
|
+
} else {
|
|
11190
|
+
this.setCursor({ type: this._prevCursor, rotation: 0 })
|
|
11191
|
+
}
|
|
11192
|
+
// Don't pass right-click panning events to the state chart
|
|
11193
|
+
// as it causes unintended shape selection on release
|
|
11194
|
+
if (slideSpeed > 0) {
|
|
11195
|
+
this.slideCamera({ speed: slideSpeed, direction: slideDirection })
|
|
11196
|
+
}
|
|
11197
|
+
this._selectedShapeIdsAtPointerDown = []
|
|
11198
|
+
return this
|
|
10715
11199
|
}
|
|
10716
11200
|
}
|
|
10717
11201
|
|