@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
|
@@ -25,8 +25,10 @@ import {
|
|
|
25
25
|
PageRecordType,
|
|
26
26
|
TLDOCUMENT_ID,
|
|
27
27
|
TLINSTANCE_ID,
|
|
28
|
+
UserRecordType,
|
|
28
29
|
createBindingId,
|
|
29
30
|
createShapeId,
|
|
31
|
+
createUserId,
|
|
30
32
|
getShapePropKeysByStyle,
|
|
31
33
|
isPageId,
|
|
32
34
|
isShapeId
|
|
@@ -62,7 +64,8 @@ import {
|
|
|
62
64
|
uniqueId
|
|
63
65
|
} from "@tldraw/utils";
|
|
64
66
|
import EventEmitter from "eventemitter3";
|
|
65
|
-
import {
|
|
67
|
+
import { createTLCurrentUser } from "../config/createTLCurrentUser.mjs";
|
|
68
|
+
import { checkAssets } from "../config/defaultAssets.mjs";
|
|
66
69
|
import { checkBindings } from "../config/defaultBindings.mjs";
|
|
67
70
|
import { checkShapesAndAddCore } from "../config/defaultShapes.mjs";
|
|
68
71
|
import {
|
|
@@ -113,10 +116,12 @@ import { FocusManager } from "./managers/FocusManager/FocusManager.mjs";
|
|
|
113
116
|
import { FontManager } from "./managers/FontManager/FontManager.mjs";
|
|
114
117
|
import { HistoryManager } from "./managers/HistoryManager/HistoryManager.mjs";
|
|
115
118
|
import { InputsManager } from "./managers/InputsManager/InputsManager.mjs";
|
|
119
|
+
import { PerformanceManager } from "./managers/PerformanceManager/PerformanceManager.mjs";
|
|
116
120
|
import { ScribbleManager } from "./managers/ScribbleManager/ScribbleManager.mjs";
|
|
117
121
|
import { SnapManager } from "./managers/SnapManager/SnapManager.mjs";
|
|
118
122
|
import { SpatialIndexManager } from "./managers/SpatialIndexManager/SpatialIndexManager.mjs";
|
|
119
123
|
import { TextManager } from "./managers/TextManager/TextManager.mjs";
|
|
124
|
+
import { ThemeManager, resolveThemes } from "./managers/ThemeManager/ThemeManager.mjs";
|
|
120
125
|
import { TickManager } from "./managers/TickManager/TickManager.mjs";
|
|
121
126
|
import { UserPreferencesManager } from "./managers/UserPreferencesManager/UserPreferencesManager.mjs";
|
|
122
127
|
import { RootState } from "./tools/RootState.mjs";
|
|
@@ -127,6 +132,7 @@ class Editor extends EventEmitter {
|
|
|
127
132
|
user,
|
|
128
133
|
shapeUtils,
|
|
129
134
|
bindingUtils,
|
|
135
|
+
assetUtils: assetUtilConstructors,
|
|
130
136
|
tools,
|
|
131
137
|
getContainer,
|
|
132
138
|
// needs to be here for backwards compatibility with TldrawEditor
|
|
@@ -134,13 +140,15 @@ class Editor extends EventEmitter {
|
|
|
134
140
|
cameraOptions,
|
|
135
141
|
initialState,
|
|
136
142
|
autoFocus,
|
|
137
|
-
inferDarkMode,
|
|
138
143
|
options: _options,
|
|
139
144
|
// needs to be here for backwards compatibility with TldrawEditor
|
|
140
145
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
141
146
|
textOptions: _textOptions,
|
|
142
147
|
getShapeVisibility,
|
|
143
|
-
|
|
148
|
+
colorScheme,
|
|
149
|
+
fontAssetUrls,
|
|
150
|
+
themes,
|
|
151
|
+
initialTheme
|
|
144
152
|
}) {
|
|
145
153
|
super();
|
|
146
154
|
this._getShapeVisibility = getShapeVisibility;
|
|
@@ -163,15 +171,27 @@ class Editor extends EventEmitter {
|
|
|
163
171
|
...cameraOptions,
|
|
164
172
|
...options?.camera
|
|
165
173
|
});
|
|
174
|
+
this.getContainer = getContainer;
|
|
166
175
|
this._textOptions = atom("text options", options?.text ?? null);
|
|
167
|
-
this.user = new UserPreferencesManager(user ??
|
|
176
|
+
this.user = new UserPreferencesManager(user ?? createTLCurrentUser(), colorScheme ?? "light");
|
|
168
177
|
this.disposables.add(() => this.user.dispose());
|
|
169
|
-
this.getContainer = getContainer;
|
|
170
178
|
this.textMeasure = new TextManager(this);
|
|
171
179
|
this.disposables.add(() => this.textMeasure.dispose());
|
|
172
|
-
this.
|
|
180
|
+
this._themeManager = new ThemeManager(this, {
|
|
181
|
+
themes: resolveThemes(themes),
|
|
182
|
+
initial: initialTheme ?? "default"
|
|
183
|
+
});
|
|
184
|
+
this.disposables.add(() => this._themeManager.dispose());
|
|
173
185
|
this._tickManager = new TickManager(this);
|
|
186
|
+
this.disposables.add(() => this._tickManager.dispose());
|
|
187
|
+
this.disposables.add(() => {
|
|
188
|
+
this.off("tick", this._decayCameraStateTimeout);
|
|
189
|
+
this._setCameraState("idle");
|
|
190
|
+
});
|
|
191
|
+
this.fonts = new FontManager(this, fontAssetUrls);
|
|
174
192
|
this.inputs = new InputsManager(this);
|
|
193
|
+
this.performance = new PerformanceManager(this);
|
|
194
|
+
this.disposables.add(() => this.performance.dispose());
|
|
175
195
|
class NewRoot extends RootState {
|
|
176
196
|
static initial = initialState ?? "";
|
|
177
197
|
}
|
|
@@ -199,6 +219,16 @@ class Editor extends EventEmitter {
|
|
|
199
219
|
}
|
|
200
220
|
this.shapeUtils = _shapeUtils;
|
|
201
221
|
this.styleProps = _styleProps;
|
|
222
|
+
const _shapeUtilsByAssetType = {};
|
|
223
|
+
for (const Util of allShapeUtils) {
|
|
224
|
+
const assetTypes = Util.handledAssetTypes;
|
|
225
|
+
if (assetTypes) {
|
|
226
|
+
for (const assetType of assetTypes) {
|
|
227
|
+
_shapeUtilsByAssetType[assetType] = _shapeUtils[Util.type];
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
this._shapeUtilsByAssetType = _shapeUtilsByAssetType;
|
|
202
232
|
const allBindingUtils = checkBindings(bindingUtils);
|
|
203
233
|
const _bindingUtils = {};
|
|
204
234
|
for (const Util of allBindingUtils) {
|
|
@@ -206,6 +236,15 @@ class Editor extends EventEmitter {
|
|
|
206
236
|
_bindingUtils[Util.type] = util;
|
|
207
237
|
}
|
|
208
238
|
this.bindingUtils = _bindingUtils;
|
|
239
|
+
if (assetUtilConstructors) {
|
|
240
|
+
const allAssetUtils = checkAssets(assetUtilConstructors);
|
|
241
|
+
const _assetUtils = {};
|
|
242
|
+
for (const Util of allAssetUtils) {
|
|
243
|
+
const util = new Util(this);
|
|
244
|
+
_assetUtils[Util.type] = util;
|
|
245
|
+
}
|
|
246
|
+
this.assetUtils = _assetUtils;
|
|
247
|
+
}
|
|
209
248
|
for (const Tool of [...tools]) {
|
|
210
249
|
if (hasOwnProperty(this.root.children, Tool.id)) {
|
|
211
250
|
throw Error(`Can't override tool with id "${Tool.id}"`);
|
|
@@ -547,6 +586,14 @@ class Editor extends EventEmitter {
|
|
|
547
586
|
})
|
|
548
587
|
);
|
|
549
588
|
}
|
|
589
|
+
this.disposables.add(
|
|
590
|
+
react("sync current user record", () => {
|
|
591
|
+
const user2 = this.store.props.users.currentUser.get();
|
|
592
|
+
if (user2) {
|
|
593
|
+
this._ensureUserRecord(user2);
|
|
594
|
+
}
|
|
595
|
+
})
|
|
596
|
+
);
|
|
550
597
|
}
|
|
551
598
|
_getShapeVisibility;
|
|
552
599
|
getIsShapeHiddenCache() {
|
|
@@ -638,6 +685,17 @@ class Editor extends EventEmitter {
|
|
|
638
685
|
* @public
|
|
639
686
|
*/
|
|
640
687
|
snaps;
|
|
688
|
+
/**
|
|
689
|
+
* A manager for performance measurement hooks.
|
|
690
|
+
*
|
|
691
|
+
* @public
|
|
692
|
+
*/
|
|
693
|
+
performance;
|
|
694
|
+
/**
|
|
695
|
+
* A manager for the spatial index, tracking where shapes exist on the canvas.
|
|
696
|
+
*
|
|
697
|
+
* @internal
|
|
698
|
+
*/
|
|
641
699
|
_spatialIndex;
|
|
642
700
|
/**
|
|
643
701
|
* A manager for the any asynchronous events and making sure they're
|
|
@@ -652,6 +710,12 @@ class Editor extends EventEmitter {
|
|
|
652
710
|
* @public
|
|
653
711
|
*/
|
|
654
712
|
user;
|
|
713
|
+
/**
|
|
714
|
+
* A manager for the editor's themes.
|
|
715
|
+
*
|
|
716
|
+
* @internal
|
|
717
|
+
*/
|
|
718
|
+
_themeManager;
|
|
655
719
|
/**
|
|
656
720
|
* A helper for measuring text.
|
|
657
721
|
*
|
|
@@ -723,12 +787,117 @@ class Editor extends EventEmitter {
|
|
|
723
787
|
* @public
|
|
724
788
|
*/
|
|
725
789
|
dispose() {
|
|
790
|
+
this.stopCameraAnimation();
|
|
791
|
+
if (this.getInstanceState().followingUserId) {
|
|
792
|
+
this.stopFollowingUser();
|
|
793
|
+
}
|
|
726
794
|
this.disposables.forEach((dispose) => dispose());
|
|
727
795
|
this.disposables.clear();
|
|
796
|
+
this.menus.clearOpenMenus();
|
|
728
797
|
this.store.dispose();
|
|
729
798
|
this.isDisposed = true;
|
|
730
799
|
this.emit("dispose");
|
|
731
800
|
}
|
|
801
|
+
/* ------------------ Themes (shadowing the theme manager) ------------------ */
|
|
802
|
+
/**
|
|
803
|
+
* Get the current color mode (`'light'` or `'dark'`), based on the user's dark mode preference.
|
|
804
|
+
*
|
|
805
|
+
* @public
|
|
806
|
+
*/
|
|
807
|
+
getColorMode() {
|
|
808
|
+
return this._themeManager.getColorMode();
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Set the color mode. Note that this is a convenience method that passes the mode to
|
|
812
|
+
* `user.updateUserPreferences`, which is the source of truth for the user's color mode preference.
|
|
813
|
+
*
|
|
814
|
+
* @public
|
|
815
|
+
*/
|
|
816
|
+
setColorMode(mode) {
|
|
817
|
+
this.user.updateUserPreferences({ colorScheme: mode });
|
|
818
|
+
return this;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Get the id of the current theme.
|
|
822
|
+
*
|
|
823
|
+
* @public
|
|
824
|
+
*/
|
|
825
|
+
getCurrentThemeId() {
|
|
826
|
+
return this._themeManager.getCurrentThemeId();
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Get the current theme definition.
|
|
830
|
+
*
|
|
831
|
+
* @public
|
|
832
|
+
*/
|
|
833
|
+
getCurrentTheme() {
|
|
834
|
+
return this._themeManager.getCurrentTheme();
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Set the current theme by id.
|
|
838
|
+
*
|
|
839
|
+
* @public
|
|
840
|
+
*/
|
|
841
|
+
setCurrentTheme(id) {
|
|
842
|
+
this._themeManager.setCurrentTheme(id);
|
|
843
|
+
return this;
|
|
844
|
+
}
|
|
845
|
+
/**
|
|
846
|
+
* Get all registered theme definitions.
|
|
847
|
+
*
|
|
848
|
+
* @public
|
|
849
|
+
*/
|
|
850
|
+
getThemes() {
|
|
851
|
+
return this._themeManager.getThemes();
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Get a single theme definition by id.
|
|
855
|
+
*
|
|
856
|
+
* @public
|
|
857
|
+
*/
|
|
858
|
+
getTheme(id) {
|
|
859
|
+
return this._themeManager.getTheme(id);
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Replace all theme definitions, or update them via a callback that receives a deep copy.
|
|
863
|
+
* The `'default'` theme must always be present in the result.
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```ts
|
|
867
|
+
* // Replace all themes
|
|
868
|
+
* editor.updateThemes({ default: myDefaultTheme, ocean: myOceanTheme })
|
|
869
|
+
*
|
|
870
|
+
* // Update via callback
|
|
871
|
+
* editor.updateThemes((themes) => {
|
|
872
|
+
* delete themes.ocean
|
|
873
|
+
* return themes
|
|
874
|
+
* })
|
|
875
|
+
* ```
|
|
876
|
+
*
|
|
877
|
+
* @public
|
|
878
|
+
*/
|
|
879
|
+
updateThemes(themes) {
|
|
880
|
+
this._themeManager.updateThemes(themes);
|
|
881
|
+
return this;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Register or update a single theme definition. The theme is keyed by its `id` property.
|
|
885
|
+
*
|
|
886
|
+
* @example
|
|
887
|
+
* ```ts
|
|
888
|
+
* // Override a property on the default theme
|
|
889
|
+
* editor.updateTheme({ ...editor.getTheme('default')!, fontSize: 24 })
|
|
890
|
+
*
|
|
891
|
+
* // Register a new theme
|
|
892
|
+
* editor.updateTheme({ id: 'ocean', ...myOceanTheme })
|
|
893
|
+
* ```
|
|
894
|
+
*
|
|
895
|
+
* @public
|
|
896
|
+
*/
|
|
897
|
+
updateTheme(theme) {
|
|
898
|
+
this._themeManager.updateTheme(theme);
|
|
899
|
+
return this;
|
|
900
|
+
}
|
|
732
901
|
/* ------------------- Shape Utils ------------------ */
|
|
733
902
|
/**
|
|
734
903
|
* A map of shape utility classes (TLShapeUtils) by shape type.
|
|
@@ -736,6 +905,8 @@ class Editor extends EventEmitter {
|
|
|
736
905
|
* @public
|
|
737
906
|
*/
|
|
738
907
|
shapeUtils;
|
|
908
|
+
/** @internal */
|
|
909
|
+
_shapeUtilsByAssetType = {};
|
|
739
910
|
styleProps;
|
|
740
911
|
getShapeUtil(arg) {
|
|
741
912
|
const type = typeof arg === "string" ? arg : arg.type;
|
|
@@ -747,6 +918,17 @@ class Editor extends EventEmitter {
|
|
|
747
918
|
const type = typeof arg === "string" ? arg : arg.type;
|
|
748
919
|
return hasOwnProperty(this.shapeUtils, type);
|
|
749
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* Get the shape util that handles the given asset type.
|
|
923
|
+
* Returns the shape util whose {@link ShapeUtil.handledAssetTypes} includes
|
|
924
|
+
* the given asset type, or undefined if none matches.
|
|
925
|
+
*
|
|
926
|
+
* @param assetType - The asset type string.
|
|
927
|
+
* @public
|
|
928
|
+
*/
|
|
929
|
+
getShapeUtilForAssetType(assetType) {
|
|
930
|
+
return getOwnProperty(this._shapeUtilsByAssetType, assetType);
|
|
931
|
+
}
|
|
750
932
|
/* ------------------- Binding Utils ------------------ */
|
|
751
933
|
/**
|
|
752
934
|
* A map of shape utility classes (TLShapeUtils) by shape type.
|
|
@@ -760,6 +942,42 @@ class Editor extends EventEmitter {
|
|
|
760
942
|
assert(bindingUtil, `No binding util found for type "${type}"`);
|
|
761
943
|
return bindingUtil;
|
|
762
944
|
}
|
|
945
|
+
/* ------------------- Asset Utils ------------------ */
|
|
946
|
+
/**
|
|
947
|
+
* A map of asset utility classes by asset type.
|
|
948
|
+
*
|
|
949
|
+
* @public
|
|
950
|
+
*/
|
|
951
|
+
assetUtils = {};
|
|
952
|
+
getAssetUtil(arg) {
|
|
953
|
+
const type = typeof arg === "string" ? arg : arg.type;
|
|
954
|
+
const assetUtil = getOwnProperty(this.assetUtils, type);
|
|
955
|
+
assert(assetUtil, `No asset util found for type "${type}"`);
|
|
956
|
+
return assetUtil;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Returns true if the editor has an asset util for the given asset type.
|
|
960
|
+
*
|
|
961
|
+
* @public
|
|
962
|
+
*/
|
|
963
|
+
hasAssetUtil(arg) {
|
|
964
|
+
const type = typeof arg === "string" ? arg : arg.type;
|
|
965
|
+
return hasOwnProperty(this.assetUtils, type);
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Get the asset util that accepts the given MIME type.
|
|
969
|
+
* Returns null if no registered asset util accepts the MIME type.
|
|
970
|
+
*
|
|
971
|
+
* @public
|
|
972
|
+
*/
|
|
973
|
+
getAssetUtilForMimeType(mimeType) {
|
|
974
|
+
for (const util of Object.values(this.assetUtils)) {
|
|
975
|
+
if (util && util.acceptsMimeType(mimeType)) {
|
|
976
|
+
return util;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return null;
|
|
980
|
+
}
|
|
763
981
|
/* --------------------- History -------------------- */
|
|
764
982
|
/**
|
|
765
983
|
* A manager for the editor's history.
|
|
@@ -781,6 +999,7 @@ class Editor extends EventEmitter {
|
|
|
781
999
|
this._flushEventsForTick(0);
|
|
782
1000
|
this.complete();
|
|
783
1001
|
this.history.undo();
|
|
1002
|
+
this.performance._notifyUndoRedo("undo", this.history.getNumUndos(), this.history.getNumRedos());
|
|
784
1003
|
return this;
|
|
785
1004
|
}
|
|
786
1005
|
canUndo() {
|
|
@@ -803,6 +1022,7 @@ class Editor extends EventEmitter {
|
|
|
803
1022
|
this._flushEventsForTick(0);
|
|
804
1023
|
this.complete();
|
|
805
1024
|
this.history.redo();
|
|
1025
|
+
this.performance._notifyUndoRedo("redo", this.history.getNumUndos(), this.history.getNumRedos());
|
|
806
1026
|
return this;
|
|
807
1027
|
}
|
|
808
1028
|
canRedo() {
|
|
@@ -2853,6 +3073,76 @@ class Editor extends EventEmitter {
|
|
|
2853
3073
|
const currentPageId = this.getCurrentPageId();
|
|
2854
3074
|
return this.getCollaborators().filter((c) => c.currentPageId === currentPageId);
|
|
2855
3075
|
}
|
|
3076
|
+
// Attribution
|
|
3077
|
+
/**
|
|
3078
|
+
* Get the current user's ID for attribution purposes.
|
|
3079
|
+
* Also ensures a `user:` record exists in the store for the current user.
|
|
3080
|
+
* Returns `null` when the user store has no current user.
|
|
3081
|
+
*
|
|
3082
|
+
* @public
|
|
3083
|
+
*/
|
|
3084
|
+
getAttributionUserId() {
|
|
3085
|
+
const user = this.store.props.users.currentUser.get();
|
|
3086
|
+
if (!user) return null;
|
|
3087
|
+
this._ensureUserRecord(user);
|
|
3088
|
+
return UserRecordType.parseId(user.id);
|
|
3089
|
+
}
|
|
3090
|
+
/**
|
|
3091
|
+
* Ensure a user record exists in the store for the given user,
|
|
3092
|
+
* updating it if the data has changed.
|
|
3093
|
+
*
|
|
3094
|
+
* @internal
|
|
3095
|
+
*/
|
|
3096
|
+
_ensureUserRecord(user) {
|
|
3097
|
+
const existing = this.store.get(user.id);
|
|
3098
|
+
if (existing && existing.name === user.name && existing.color === user.color && existing.imageUrl === user.imageUrl && existing.meta === user.meta) {
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
this.run(
|
|
3102
|
+
() => {
|
|
3103
|
+
this.store.put([user]);
|
|
3104
|
+
},
|
|
3105
|
+
{ history: "ignore" }
|
|
3106
|
+
);
|
|
3107
|
+
}
|
|
3108
|
+
/**
|
|
3109
|
+
* Resolve a display name for a user ID. Asks the
|
|
3110
|
+
* {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
|
|
3111
|
+
* falling back to the `user:` record in the store.
|
|
3112
|
+
*
|
|
3113
|
+
* @public
|
|
3114
|
+
*/
|
|
3115
|
+
getAttributionDisplayName(userId) {
|
|
3116
|
+
if (!userId) return null;
|
|
3117
|
+
return this.store.props.users.resolve(userId).get()?.name ?? this.store.get(createUserId(userId))?.name ?? null;
|
|
3118
|
+
}
|
|
3119
|
+
/**
|
|
3120
|
+
* Resolve a user record by ID. Asks the
|
|
3121
|
+
* {@link @tldraw/tlschema#TLUserStore} first (the app's source of truth),
|
|
3122
|
+
* falling back to the `user:` record in the store.
|
|
3123
|
+
*
|
|
3124
|
+
* @public
|
|
3125
|
+
*/
|
|
3126
|
+
getAttributionUser(userId) {
|
|
3127
|
+
if (!userId) return null;
|
|
3128
|
+
return this.store.props.users.resolve(userId).get() ?? this.store.get(createUserId(userId)) ?? null;
|
|
3129
|
+
}
|
|
3130
|
+
/**
|
|
3131
|
+
* Collect user IDs referenced by a set of shapes via shape-specific props
|
|
3132
|
+
* (e.g. `textFirstEditedBy` on notes).
|
|
3133
|
+
*
|
|
3134
|
+
* @internal
|
|
3135
|
+
*/
|
|
3136
|
+
_getReferencedUserIds(shapes) {
|
|
3137
|
+
const userIds = /* @__PURE__ */ new Set();
|
|
3138
|
+
for (const shape of shapes) {
|
|
3139
|
+
const util = this.getShapeUtil(shape);
|
|
3140
|
+
for (const id of util.getReferencedUserIds(shape)) {
|
|
3141
|
+
userIds.add(id);
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
return userIds;
|
|
3145
|
+
}
|
|
2856
3146
|
// Following
|
|
2857
3147
|
// When we are 'locked on' to a user, our camera is derived from their camera.
|
|
2858
3148
|
_isLockedOnFollowingUser = atom("isLockedOnFollowingUser", false);
|
|
@@ -3887,7 +4177,7 @@ class Editor extends EventEmitter {
|
|
|
3887
4177
|
const searchMargin = Math.max(innerMargin, outerMargin, this.options.hitTestMargin / zoomLevel);
|
|
3888
4178
|
const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, searchMargin);
|
|
3889
4179
|
const shapesToCheck = (opts.renderingOnly ? this.getCurrentPageRenderingShapesSorted() : this.getCurrentPageShapesSorted()).filter((shape) => {
|
|
3890
|
-
if (!candidateIds.has(shape.id) && !this.
|
|
4180
|
+
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
|
|
3891
4181
|
if (shape.isLocked && !hitLocked || this.isShapeHidden(shape) || this.isShapeOfType(shape, "group"))
|
|
3892
4182
|
return false;
|
|
3893
4183
|
const pageMask = this.getShapeMask(shape);
|
|
@@ -3900,14 +4190,16 @@ class Editor extends EventEmitter {
|
|
|
3900
4190
|
const geometry = this.getShapeGeometry(shape);
|
|
3901
4191
|
const isGroup = geometry instanceof Group2d;
|
|
3902
4192
|
const pointInShapeSpace = this.getPointInShapeSpace(shape, point);
|
|
3903
|
-
|
|
4193
|
+
const shapeUtil = this.getShapeUtil(shape);
|
|
4194
|
+
const isShapeFrameLike = this.isShapeFrameLike(shape);
|
|
4195
|
+
if (isShapeFrameLike || (this.isShapeOfType(shape, "note") || this.isShapeOfType(shape, "arrow") || this.isShapeOfType(shape, "geo") && shape.props.fill === "none") && shapeUtil.getText(shape)?.trim()) {
|
|
3904
4196
|
for (const childGeometry of geometry.children) {
|
|
3905
4197
|
if (childGeometry.isLabel && childGeometry.isPointInBounds(pointInShapeSpace)) {
|
|
3906
4198
|
return shape;
|
|
3907
4199
|
}
|
|
3908
4200
|
}
|
|
3909
4201
|
}
|
|
3910
|
-
if (
|
|
4202
|
+
if (isShapeFrameLike) {
|
|
3911
4203
|
const distance2 = geometry.distanceToPoint(pointInShapeSpace, hitFrameInside);
|
|
3912
4204
|
if (hitFrameInside ? distance2 > 0 && distance2 <= outerMargin || distance2 <= 0 && distance2 > -innerMargin : distance2 > 0 && distance2 <= outerMargin) {
|
|
3913
4205
|
return inMarginClosestToEdgeHit || shape;
|
|
@@ -4001,7 +4293,7 @@ class Editor extends EventEmitter {
|
|
|
4001
4293
|
const candidateIds = this._spatialIndex.getShapeIdsAtPoint(point, margin);
|
|
4002
4294
|
return this.getCurrentPageShapesSorted().filter((shape) => {
|
|
4003
4295
|
if (this.isShapeHidden(shape)) return false;
|
|
4004
|
-
if (!candidateIds.has(shape.id) && !this.
|
|
4296
|
+
if (!candidateIds.has(shape.id) && !this.isShapeFrameLike(shape)) return false;
|
|
4005
4297
|
return this.isPointInShape(shape, point, opts);
|
|
4006
4298
|
}).reverse();
|
|
4007
4299
|
}
|
|
@@ -4114,6 +4406,24 @@ class Editor extends EventEmitter {
|
|
|
4114
4406
|
if (!shape) return false;
|
|
4115
4407
|
return shape.type === type;
|
|
4116
4408
|
}
|
|
4409
|
+
/**
|
|
4410
|
+
* Get whether a shape behaves like a frame — a container that has child
|
|
4411
|
+
* shapes, requires full-brush selection, blocks erasure from inside, etc.
|
|
4412
|
+
*
|
|
4413
|
+
* @example
|
|
4414
|
+
* ```ts
|
|
4415
|
+
* const isFrameLike = editor.isShapeFrameLike(someShape)
|
|
4416
|
+
* ```
|
|
4417
|
+
*
|
|
4418
|
+
* @param shape - The shape (or shape id) to test.
|
|
4419
|
+
*
|
|
4420
|
+
* @public
|
|
4421
|
+
*/
|
|
4422
|
+
isShapeFrameLike(shape) {
|
|
4423
|
+
const _shape = typeof shape === "string" ? this.getShape(shape) : shape;
|
|
4424
|
+
if (!_shape) return false;
|
|
4425
|
+
return this.getShapeUtil(_shape).isFrameLike(_shape);
|
|
4426
|
+
}
|
|
4117
4427
|
/**
|
|
4118
4428
|
* Get a shape by its id.
|
|
4119
4429
|
*
|
|
@@ -6566,12 +6876,22 @@ class Editor extends EventEmitter {
|
|
|
6566
6876
|
if (!asset) continue;
|
|
6567
6877
|
assets.push(asset);
|
|
6568
6878
|
}
|
|
6879
|
+
const users = [];
|
|
6880
|
+
const seenUserIds = /* @__PURE__ */ new Set();
|
|
6881
|
+
for (const userId of this._getReferencedUserIds(shapes2)) {
|
|
6882
|
+
const recordId = createUserId(userId);
|
|
6883
|
+
if (seenUserIds.has(recordId)) continue;
|
|
6884
|
+
seenUserIds.add(recordId);
|
|
6885
|
+
const user = this.store.get(recordId);
|
|
6886
|
+
if (user) users.push(user);
|
|
6887
|
+
}
|
|
6569
6888
|
return {
|
|
6570
6889
|
schema: this.store.schema.serialize(),
|
|
6571
6890
|
shapes: shapes2,
|
|
6572
6891
|
rootShapeIds,
|
|
6573
6892
|
bindings,
|
|
6574
|
-
assets
|
|
6893
|
+
assets,
|
|
6894
|
+
users
|
|
6575
6895
|
};
|
|
6576
6896
|
});
|
|
6577
6897
|
}
|
|
@@ -6621,13 +6941,15 @@ class Editor extends EventEmitter {
|
|
|
6621
6941
|
const assets = [];
|
|
6622
6942
|
const shapes = [];
|
|
6623
6943
|
const bindings = [];
|
|
6944
|
+
const users = [];
|
|
6624
6945
|
const store = {
|
|
6625
6946
|
store: {
|
|
6626
6947
|
...Object.fromEntries(content.assets.map((asset) => [asset.id, asset])),
|
|
6627
6948
|
...Object.fromEntries(content.shapes.map((shape) => [shape.id, shape])),
|
|
6628
6949
|
...Object.fromEntries(
|
|
6629
6950
|
content.bindings?.map((bindings2) => [bindings2.id, bindings2]) ?? []
|
|
6630
|
-
)
|
|
6951
|
+
),
|
|
6952
|
+
...Object.fromEntries(content.users?.map((user) => [user.id, user]) ?? [])
|
|
6631
6953
|
},
|
|
6632
6954
|
schema: content.schema
|
|
6633
6955
|
};
|
|
@@ -6649,6 +6971,19 @@ class Editor extends EventEmitter {
|
|
|
6649
6971
|
bindings.push(record);
|
|
6650
6972
|
break;
|
|
6651
6973
|
}
|
|
6974
|
+
case "user": {
|
|
6975
|
+
users.push(record);
|
|
6976
|
+
break;
|
|
6977
|
+
}
|
|
6978
|
+
}
|
|
6979
|
+
}
|
|
6980
|
+
if (users.length > 0) {
|
|
6981
|
+
const existingUserIds = new Set(
|
|
6982
|
+
this.store.allRecords().filter((r) => r.typeName === "user").map((r) => r.id)
|
|
6983
|
+
);
|
|
6984
|
+
const usersToCreate = users.filter((u) => !existingUserIds.has(u.id));
|
|
6985
|
+
if (usersToCreate.length > 0) {
|
|
6986
|
+
this.store.put(usersToCreate);
|
|
6652
6987
|
}
|
|
6653
6988
|
}
|
|
6654
6989
|
const shapeIdMap = new Map(
|
|
@@ -7614,6 +7949,7 @@ class Editor extends EventEmitter {
|
|
|
7614
7949
|
),
|
|
7615
7950
|
{ immediate: true }
|
|
7616
7951
|
);
|
|
7952
|
+
this.performance._notifyCameraOperation("zooming");
|
|
7617
7953
|
this.emit("event", info);
|
|
7618
7954
|
return;
|
|
7619
7955
|
}
|
|
@@ -7675,6 +8011,7 @@ class Editor extends EventEmitter {
|
|
|
7675
8011
|
immediate: true
|
|
7676
8012
|
});
|
|
7677
8013
|
this.maybeTrackPerformance("Zooming");
|
|
8014
|
+
this.performance._notifyCameraOperation("zooming");
|
|
7678
8015
|
this.root.handleEvent(info);
|
|
7679
8016
|
this.emit("event", info);
|
|
7680
8017
|
return;
|
|
@@ -7684,6 +8021,7 @@ class Editor extends EventEmitter {
|
|
|
7684
8021
|
immediate: true
|
|
7685
8022
|
});
|
|
7686
8023
|
this.maybeTrackPerformance("Panning");
|
|
8024
|
+
this.performance._notifyCameraOperation("panning");
|
|
7687
8025
|
this.root.handleEvent(info);
|
|
7688
8026
|
this.emit("event", info);
|
|
7689
8027
|
return;
|
|
@@ -7730,6 +8068,10 @@ class Editor extends EventEmitter {
|
|
|
7730
8068
|
}
|
|
7731
8069
|
this.inputs.setIsPanning(true);
|
|
7732
8070
|
clearTimeout(this._longPressTimeout);
|
|
8071
|
+
} else if (info.button === RIGHT_MOUSE_BUTTON && this.options.rightClickPanning) {
|
|
8072
|
+
this.inputs.setIsRightPointing(true);
|
|
8073
|
+
clearTimeout(this._longPressTimeout);
|
|
8074
|
+
return this;
|
|
7733
8075
|
}
|
|
7734
8076
|
if (this.inputs.getIsPanning()) {
|
|
7735
8077
|
this.stopCameraAnimation();
|
|
@@ -7741,6 +8083,22 @@ class Editor extends EventEmitter {
|
|
|
7741
8083
|
case "pointer_move": {
|
|
7742
8084
|
if (!isPen && isPenMode) return;
|
|
7743
8085
|
const { x: cx, y: cy, z: cz } = unsafe__withoutCapture(() => this.getCamera());
|
|
8086
|
+
if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
|
|
8087
|
+
const currentScreenPoint = this.inputs.getCurrentScreenPoint();
|
|
8088
|
+
const originScreenPoint = this.inputs.getOriginScreenPoint();
|
|
8089
|
+
if (Vec.Dist2(originScreenPoint, currentScreenPoint) > this.options.dragDistanceSquared) {
|
|
8090
|
+
this._prevCursor = this.getInstanceState().cursor.type;
|
|
8091
|
+
this.inputs.setIsPanning(true);
|
|
8092
|
+
this.setCursor({ type: "grabbing", rotation: 0 });
|
|
8093
|
+
this.stopCameraAnimation();
|
|
8094
|
+
const offset = Vec.Sub(currentScreenPoint, originScreenPoint);
|
|
8095
|
+
this.setCamera(new Vec(cx + offset.x / cz, cy + offset.y / cz, cz), {
|
|
8096
|
+
immediate: true
|
|
8097
|
+
});
|
|
8098
|
+
this.maybeTrackPerformance("Panning");
|
|
8099
|
+
}
|
|
8100
|
+
return;
|
|
8101
|
+
}
|
|
7744
8102
|
if (this.inputs.getIsPanning() && this.inputs.getIsPointing()) {
|
|
7745
8103
|
const currentScreenPoint = this.inputs.getCurrentScreenPoint();
|
|
7746
8104
|
const previousScreenPoint = this.inputs.getPreviousScreenPoint();
|
|
@@ -7749,6 +8107,7 @@ class Editor extends EventEmitter {
|
|
|
7749
8107
|
immediate: true
|
|
7750
8108
|
});
|
|
7751
8109
|
this.maybeTrackPerformance("Panning");
|
|
8110
|
+
this.performance._notifyCameraOperation("panning");
|
|
7752
8111
|
return;
|
|
7753
8112
|
}
|
|
7754
8113
|
if (inputs.getIsPointing() && !inputs.getIsDragging() && Vec.Dist2(inputs.getOriginPagePoint(), inputs.getCurrentPagePoint()) * this.getZoomLevel() > (instanceState.isCoarsePointer ? this.options.coarseDragDistanceSquared : this.options.dragDistanceSquared) / cz) {
|
|
@@ -7763,6 +8122,12 @@ class Editor extends EventEmitter {
|
|
|
7763
8122
|
clearTimeout(this._longPressTimeout);
|
|
7764
8123
|
inputs.buttons.delete(info.button);
|
|
7765
8124
|
if (instanceState.isPenMode && !isPen) return;
|
|
8125
|
+
if (this.inputs.getIsRightPointing() && !this.inputs.getIsPanning()) {
|
|
8126
|
+
this.inputs.setIsRightPointing(false);
|
|
8127
|
+
this._selectedShapeIdsAtPointerDown = [];
|
|
8128
|
+
break;
|
|
8129
|
+
}
|
|
8130
|
+
this.inputs.setIsRightPointing(false);
|
|
7766
8131
|
if (this.capturedPointerId === info.pointerId) {
|
|
7767
8132
|
this.capturedPointerId = null;
|
|
7768
8133
|
info.button = 0;
|
|
@@ -7780,11 +8145,24 @@ class Editor extends EventEmitter {
|
|
|
7780
8145
|
break;
|
|
7781
8146
|
}
|
|
7782
8147
|
case MIDDLE_MOUSE_BUTTON: {
|
|
7783
|
-
if (this.inputs.keys.has("
|
|
8148
|
+
if (this.inputs.keys.has("Space")) {
|
|
7784
8149
|
this.setCursor({ type: "grab", rotation: 0 });
|
|
7785
8150
|
} else {
|
|
7786
8151
|
this.setCursor({ type: this._prevCursor, rotation: 0 });
|
|
7787
8152
|
}
|
|
8153
|
+
break;
|
|
8154
|
+
}
|
|
8155
|
+
case RIGHT_MOUSE_BUTTON: {
|
|
8156
|
+
if (this.inputs.keys.has("Space")) {
|
|
8157
|
+
this.setCursor({ type: "grab", rotation: 0 });
|
|
8158
|
+
} else {
|
|
8159
|
+
this.setCursor({ type: this._prevCursor, rotation: 0 });
|
|
8160
|
+
}
|
|
8161
|
+
if (slideSpeed > 0) {
|
|
8162
|
+
this.slideCamera({ speed: slideSpeed, direction: slideDirection });
|
|
8163
|
+
}
|
|
8164
|
+
this._selectedShapeIdsAtPointerDown = [];
|
|
8165
|
+
return this;
|
|
7788
8166
|
}
|
|
7789
8167
|
}
|
|
7790
8168
|
if (slideSpeed > 0) {
|