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