tldraw 3.16.0-canary.ffdf566dd0a8 → 3.16.0-internal.a478398270c6
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 +19 -125
- package/dist-cjs/index.js +2 -19
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawImage.js +2 -5
- package/dist-cjs/lib/TldrawImage.js.map +3 -3
- package/dist-cjs/lib/canvas/TldrawCropHandles.js +1 -1
- package/dist-cjs/lib/canvas/TldrawCropHandles.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawHandles.js +1 -1
- package/dist-cjs/lib/canvas/TldrawHandles.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawOverlays.js +1 -1
- package/dist-cjs/lib/canvas/TldrawOverlays.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +271 -279
- package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +0 -1
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +41 -24
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js +4 -16
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js +1 -1
- package/dist-cjs/lib/shapes/arrow/arrowTargetState.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +0 -3
- package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +5 -5
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +3 -0
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +4 -15
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +1 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PathBuilder.js +3 -21
- package/dist-cjs/lib/shapes/shared/PathBuilder.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +0 -1
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js +2 -5
- package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/SvgTextLabel.js +3 -4
- package/dist-cjs/lib/shapes/shared/SvgTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js +1 -10
- package/dist-cjs/lib/shapes/shared/usePrefersReducedMotion.js.map +2 -2
- package/dist-cjs/lib/shapes/text/TextShapeUtil.js +11 -5
- package/dist-cjs/lib/shapes/text/TextShapeUtil.js.map +2 -2
- package/dist-cjs/lib/styles.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js +1 -7
- package/dist-cjs/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js +22 -43
- package/dist-cjs/lib/tools/SelectTool/childStates/DraggingHandle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +15 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +0 -5
- package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +0 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js +0 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/Rotating.js.map +2 -2
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js +0 -8
- package/dist-cjs/lib/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.js.map +2 -2
- package/dist-cjs/lib/ui/assetUrls.js +13 -10
- package/dist-cjs/lib/ui/assetUrls.js.map +2 -2
- package/dist-cjs/lib/ui/components/A11y.js +12 -14
- package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +1 -51
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js +2 -3
- package/dist-cjs/lib/ui/components/MainMenu/DefaultMainMenuContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +4 -3
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/Spinner.js +25 -2
- package/dist-cjs/lib/ui/components/Spinner.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +0 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +136 -168
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js +7 -21
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +2 -3
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/menu-items.js +0 -22
- package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/Button/TldrawUiButtonIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +0 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiDialog.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +1 -35
- package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +2 -6
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +3 -12
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js +2 -3
- package/dist-cjs/lib/ui/context/TldrawUiContextProvider.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +8 -57
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/menu-hooks.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +2 -2
- package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +0 -11
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/kbd-utils.js +1 -2
- package/dist-cjs/lib/ui/kbd-utils.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js +1 -1
- package/dist-cjs/lib/utils/excalidraw/putExcalidrawContent.js.map +2 -2
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js +2 -3
- package/dist-cjs/lib/utils/tldr/buildFromV1Document.js.map +2 -2
- package/dist-esm/index.d.mts +19 -125
- package/dist-esm/index.mjs +4 -33
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawImage.mjs +2 -5
- package/dist-esm/lib/TldrawImage.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawCropHandles.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawCropHandles.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawHandles.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawHandles.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawOverlays.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawOverlays.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +271 -279
- package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +0 -1
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +41 -26
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +5 -19
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs +1 -1
- package/dist-esm/lib/shapes/arrow/arrowTargetState.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +0 -3
- package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +5 -5
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +3 -0
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +4 -15
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +1 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PathBuilder.mjs +3 -22
- package/dist-esm/lib/shapes/shared/PathBuilder.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +0 -1
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +2 -5
- package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/SvgTextLabel.mjs +3 -4
- package/dist-esm/lib/shapes/shared/SvgTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs +1 -10
- package/dist-esm/lib/shapes/shared/usePrefersReducedMotion.mjs.map +2 -2
- package/dist-esm/lib/shapes/text/TextShapeUtil.mjs +11 -5
- package/dist-esm/lib/shapes/text/TextShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/styles.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs +1 -7
- package/dist-esm/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs +22 -43
- package/dist-esm/lib/tools/SelectTool/childStates/DraggingHandle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +15 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +0 -5
- package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +0 -8
- package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs +0 -8
- package/dist-esm/lib/tools/SelectTool/childStates/Rotating.mjs.map +2 -2
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs +0 -8
- package/dist-esm/lib/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.mjs.map +2 -2
- package/dist-esm/lib/ui/assetUrls.mjs +13 -10
- package/dist-esm/lib/ui/assetUrls.mjs.map +2 -2
- package/dist-esm/lib/ui/components/A11y.mjs +12 -14
- package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +1 -51
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs +3 -3
- package/dist-esm/lib/ui/components/MainMenu/DefaultMainMenuContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +4 -3
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Spinner.mjs +26 -3
- package/dist-esm/lib/ui/components/Spinner.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +1 -3
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +136 -168
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs +9 -23
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbar.mjs.map +3 -3
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +3 -3
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +2 -3
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/menu-items.mjs +0 -22
- package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/Button/TldrawUiButtonIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +0 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiDialog.mjs +1 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiDialog.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +2 -36
- package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -6
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +3 -12
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs +2 -3
- package/dist-esm/lib/ui/context/TldrawUiContextProvider.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +8 -57
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/menu-hooks.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +2 -2
- package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +0 -11
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/kbd-utils.mjs +1 -2
- package/dist-esm/lib/ui/kbd-utils.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs +1 -1
- package/dist-esm/lib/utils/excalidraw/putExcalidrawContent.mjs.map +2 -2
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs +2 -3
- package/dist-esm/lib/utils/tldr/buildFromV1Document.mjs.map +2 -2
- package/package.json +3 -4
- package/src/index.ts +2 -24
- package/src/lib/TldrawImage.tsx +2 -6
- package/src/lib/canvas/TldrawCropHandles.tsx +1 -3
- package/src/lib/canvas/TldrawHandles.tsx +1 -5
- package/src/lib/canvas/TldrawOverlays.tsx +1 -1
- package/src/lib/canvas/TldrawSelectionForeground.tsx +1 -5
- package/src/lib/defaultExternalContentHandlers.ts +1 -2
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +5 -5
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +43 -26
- package/src/lib/shapes/arrow/arrowLabel.ts +3 -23
- package/src/lib/shapes/arrow/arrowTargetState.ts +1 -2
- package/src/lib/shapes/arrow/toolStates/Pointing.tsx +0 -3
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -0
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +7 -5
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +3 -0
- package/src/lib/shapes/line/LineShapeUtil.tsx +5 -19
- package/src/lib/shapes/note/NoteShapeUtil.tsx +0 -1
- package/src/lib/shapes/shared/PathBuilder.test.tsx +1 -1
- package/src/lib/shapes/shared/PathBuilder.tsx +1 -35
- package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -1
- package/src/lib/shapes/shared/RichTextLabel.tsx +0 -4
- package/src/lib/shapes/shared/SvgTextLabel.tsx +2 -4
- package/src/lib/shapes/shared/usePrefersReducedMotion.tsx +1 -11
- package/src/lib/shapes/text/TextShapeUtil.tsx +12 -5
- package/src/lib/styles.tsx +1 -3
- package/src/lib/tools/SelectTool/childStates/Crop/children/PointingCrop.ts +1 -8
- package/src/lib/tools/SelectTool/childStates/DraggingHandle.tsx +30 -54
- package/src/lib/tools/SelectTool/childStates/Idle.ts +24 -2
- package/src/lib/tools/SelectTool/childStates/PointingShape.ts +0 -7
- package/src/lib/tools/SelectTool/childStates/Resizing.ts +1 -12
- package/src/lib/tools/SelectTool/childStates/Rotating.ts +0 -11
- package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -11
- package/src/lib/tools/selection-logic/getHitShapeOnCanvasPointerDown.ts +0 -1
- package/src/lib/ui/assetUrls.ts +13 -10
- package/src/lib/ui/components/A11y.tsx +13 -15
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +0 -40
- package/src/lib/ui/components/MainMenu/DefaultMainMenuContent.tsx +2 -4
- package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +4 -3
- package/src/lib/ui/components/Spinner.tsx +24 -2
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +1 -3
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +127 -171
- package/src/lib/ui/components/Toolbar/DefaultImageToolbar.tsx +9 -25
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +3 -3
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +12 -17
- package/src/lib/ui/components/menu-items.tsx +0 -25
- package/src/lib/ui/components/primitives/Button/TldrawUiButtonIcon.tsx +2 -2
- package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +0 -2
- package/src/lib/ui/components/primitives/TldrawUiDialog.tsx +1 -1
- package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +3 -41
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +1 -6
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +3 -24
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +2 -2
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +4 -3
- package/src/lib/ui/context/TldrawUiContextProvider.tsx +20 -23
- package/src/lib/ui/context/actions.tsx +9 -59
- package/src/lib/ui/context/events.tsx +2 -5
- package/src/lib/ui/hooks/menu-hooks.ts +0 -1
- package/src/lib/ui/hooks/useKeyboardShortcuts.ts +2 -3
- package/src/lib/ui/hooks/useTools.tsx +1 -2
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +0 -11
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +0 -11
- package/src/lib/ui/kbd-utils.ts +1 -2
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +23 -65
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +2 -16
- package/src/lib/utils/excalidraw/putExcalidrawContent.ts +1 -1
- package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +3 -24
- package/src/lib/utils/tldr/buildFromV1Document.ts +1 -2
- package/src/test/Editor.test.tsx +1 -1
- package/src/test/SelectTool.test.ts +11 -37
- package/src/test/arrows-megabus.test.tsx +6 -12
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
- package/src/test/commands/deletePage.test.ts +1 -84
- package/src/test/groups.test.tsx +1 -1
- package/src/test/navigation.test.ts +0 -254
- package/src/test/shapeutils.test.ts +45 -394
- package/src/test/translating.test.ts +1 -1
- package/tldraw.css +50 -88
- package/dist-cjs/lib/ui/components/AccessibilityMenu.js +0 -35
- package/dist-cjs/lib/ui/components/AccessibilityMenu.js.map +0 -7
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +0 -267
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +0 -7
- package/dist-esm/lib/ui/components/AccessibilityMenu.mjs +0 -19
- package/dist-esm/lib/ui/components/AccessibilityMenu.mjs.map +0 -7
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +0 -237
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +0 -7
- package/src/lib/ui/components/AccessibilityMenu.tsx +0 -20
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +0 -313
- package/src/test/inner-outer-margin.test.ts +0 -315
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { uniqueId, useMaybeEditor, Vec } from "@tldraw/editor";
|
|
3
|
-
import { Tooltip as _Tooltip } from "radix-ui";
|
|
4
|
-
import React, { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
5
|
-
import { usePrefersReducedMotion } from "../../../shapes/shared/usePrefersReducedMotion.mjs";
|
|
6
|
-
const DEFAULT_TOOLTIP_DELAY_MS = 700;
|
|
7
|
-
class TooltipManager {
|
|
8
|
-
static instance = null;
|
|
9
|
-
currentTooltipId = null;
|
|
10
|
-
currentContent = "";
|
|
11
|
-
currentSide = "bottom";
|
|
12
|
-
currentSideOffset = 5;
|
|
13
|
-
destroyTimeoutId = null;
|
|
14
|
-
subscribers = /* @__PURE__ */ new Set();
|
|
15
|
-
activeElement = null;
|
|
16
|
-
editor = null;
|
|
17
|
-
static getInstance() {
|
|
18
|
-
if (!TooltipManager.instance) {
|
|
19
|
-
TooltipManager.instance = new TooltipManager();
|
|
20
|
-
}
|
|
21
|
-
return TooltipManager.instance;
|
|
22
|
-
}
|
|
23
|
-
setEditor(editor) {
|
|
24
|
-
this.editor = editor;
|
|
25
|
-
}
|
|
26
|
-
subscribe(callback) {
|
|
27
|
-
this.subscribers.add(callback);
|
|
28
|
-
return () => this.subscribers.delete(callback);
|
|
29
|
-
}
|
|
30
|
-
notify() {
|
|
31
|
-
this.subscribers.forEach((callback) => callback());
|
|
32
|
-
}
|
|
33
|
-
showTooltip(tooltipId, content, element, side = "bottom", sideOffset = 5) {
|
|
34
|
-
if (this.destroyTimeoutId) {
|
|
35
|
-
clearTimeout(this.destroyTimeoutId);
|
|
36
|
-
this.destroyTimeoutId = null;
|
|
37
|
-
}
|
|
38
|
-
this.currentTooltipId = tooltipId;
|
|
39
|
-
this.currentContent = content;
|
|
40
|
-
this.currentSide = side;
|
|
41
|
-
this.currentSideOffset = sideOffset;
|
|
42
|
-
this.activeElement = element;
|
|
43
|
-
this.notify();
|
|
44
|
-
}
|
|
45
|
-
hideTooltip(tooltipId) {
|
|
46
|
-
if (this.currentTooltipId === tooltipId) {
|
|
47
|
-
if (this.editor) {
|
|
48
|
-
this.destroyTimeoutId = this.editor.timers.setTimeout(() => {
|
|
49
|
-
this.currentTooltipId = null;
|
|
50
|
-
this.currentContent = "";
|
|
51
|
-
this.activeElement = null;
|
|
52
|
-
this.destroyTimeoutId = null;
|
|
53
|
-
this.notify();
|
|
54
|
-
}, 300);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
getCurrentTooltipData() {
|
|
59
|
-
return {
|
|
60
|
-
id: this.currentTooltipId,
|
|
61
|
-
content: this.currentContent,
|
|
62
|
-
side: this.currentSide,
|
|
63
|
-
sideOffset: this.currentSideOffset,
|
|
64
|
-
element: this.activeElement
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
const tooltipManager = TooltipManager.getInstance();
|
|
69
|
-
const TooltipSingletonContext = createContext(false);
|
|
70
|
-
function TldrawUiTooltipProvider({ children }) {
|
|
71
|
-
return /* @__PURE__ */ jsx(_Tooltip.Provider, { skipDelayDuration: 700, children: /* @__PURE__ */ jsxs(TooltipSingletonContext.Provider, { value: true, children: [
|
|
72
|
-
children,
|
|
73
|
-
/* @__PURE__ */ jsx(TooltipSingleton, {})
|
|
74
|
-
] }) });
|
|
75
|
-
}
|
|
76
|
-
function TooltipSingleton() {
|
|
77
|
-
const editor = useMaybeEditor();
|
|
78
|
-
const [, forceUpdate] = useState({});
|
|
79
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
80
|
-
const triggerRef = useRef(null);
|
|
81
|
-
const previousPositionRef = useRef(null);
|
|
82
|
-
const prefersReducedMotion = usePrefersReducedMotion();
|
|
83
|
-
const [shouldAnimate, setShouldAnimate] = useState(false);
|
|
84
|
-
const isFirstShowRef = useRef(true);
|
|
85
|
-
const showTimeoutRef = useRef(null);
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
tooltipManager.setEditor(editor);
|
|
88
|
-
}, [editor]);
|
|
89
|
-
useEffect(() => {
|
|
90
|
-
const unsubscribe = tooltipManager.subscribe(() => {
|
|
91
|
-
forceUpdate({});
|
|
92
|
-
});
|
|
93
|
-
return unsubscribe;
|
|
94
|
-
}, []);
|
|
95
|
-
const tooltipData = tooltipManager.getCurrentTooltipData();
|
|
96
|
-
useEffect(() => {
|
|
97
|
-
const shouldBeOpen = Boolean(tooltipData.id && tooltipData.element);
|
|
98
|
-
if (showTimeoutRef.current) {
|
|
99
|
-
clearTimeout(showTimeoutRef.current);
|
|
100
|
-
showTimeoutRef.current = null;
|
|
101
|
-
}
|
|
102
|
-
if (shouldBeOpen && tooltipData.element && triggerRef.current) {
|
|
103
|
-
const activeRect = tooltipData.element.getBoundingClientRect();
|
|
104
|
-
const trigger = triggerRef.current;
|
|
105
|
-
const newPosition = {
|
|
106
|
-
x: activeRect.left + activeRect.width / 2,
|
|
107
|
-
y: activeRect.top + activeRect.height / 2
|
|
108
|
-
};
|
|
109
|
-
let shouldAnimateCheck = false;
|
|
110
|
-
if (previousPositionRef.current) {
|
|
111
|
-
const isNearPrevious = Vec.DistMin(previousPositionRef.current, newPosition, 200);
|
|
112
|
-
shouldAnimateCheck = !prefersReducedMotion && isNearPrevious && Math.abs(newPosition.y - previousPositionRef.current.y) < 50;
|
|
113
|
-
}
|
|
114
|
-
setShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck);
|
|
115
|
-
previousPositionRef.current = newPosition;
|
|
116
|
-
trigger.style.position = "fixed";
|
|
117
|
-
trigger.style.left = `${activeRect.left}px`;
|
|
118
|
-
trigger.style.top = `${activeRect.top}px`;
|
|
119
|
-
trigger.style.width = `${activeRect.width}px`;
|
|
120
|
-
trigger.style.height = `${activeRect.height}px`;
|
|
121
|
-
trigger.style.pointerEvents = "none";
|
|
122
|
-
trigger.style.zIndex = "9999";
|
|
123
|
-
if (isFirstShowRef.current && editor) {
|
|
124
|
-
showTimeoutRef.current = editor.timers.setTimeout(() => {
|
|
125
|
-
setIsOpen(true);
|
|
126
|
-
isFirstShowRef.current = false;
|
|
127
|
-
}, editor.options.tooltipDelayMs);
|
|
128
|
-
} else {
|
|
129
|
-
setIsOpen(true);
|
|
130
|
-
}
|
|
131
|
-
} else if (!shouldBeOpen) {
|
|
132
|
-
setIsOpen(false);
|
|
133
|
-
previousPositionRef.current = null;
|
|
134
|
-
setShouldAnimate(false);
|
|
135
|
-
isFirstShowRef.current = true;
|
|
136
|
-
}
|
|
137
|
-
}, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion]);
|
|
138
|
-
if (!tooltipData.id) {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
return /* @__PURE__ */ jsxs(_Tooltip.Root, { open: isOpen, delayDuration: 0, children: [
|
|
142
|
-
/* @__PURE__ */ jsx(_Tooltip.Trigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { ref: triggerRef }) }),
|
|
143
|
-
/* @__PURE__ */ jsxs(
|
|
144
|
-
_Tooltip.Content,
|
|
145
|
-
{
|
|
146
|
-
className: "tlui-tooltip",
|
|
147
|
-
"data-should-animate": shouldAnimate,
|
|
148
|
-
side: tooltipData.side,
|
|
149
|
-
sideOffset: tooltipData.sideOffset,
|
|
150
|
-
avoidCollisions: true,
|
|
151
|
-
collisionPadding: 8,
|
|
152
|
-
dir: "ltr",
|
|
153
|
-
children: [
|
|
154
|
-
tooltipData.content,
|
|
155
|
-
/* @__PURE__ */ jsx(_Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
)
|
|
159
|
-
] });
|
|
160
|
-
}
|
|
161
|
-
function TldrawUiTooltip({
|
|
162
|
-
children,
|
|
163
|
-
content,
|
|
164
|
-
side = "bottom",
|
|
165
|
-
sideOffset = 5,
|
|
166
|
-
disabled = false
|
|
167
|
-
}) {
|
|
168
|
-
const editor = useMaybeEditor();
|
|
169
|
-
const tooltipId = useRef(uniqueId());
|
|
170
|
-
const hasProvider = useContext(TooltipSingletonContext);
|
|
171
|
-
if (disabled || !content) {
|
|
172
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
173
|
-
}
|
|
174
|
-
if (!hasProvider) {
|
|
175
|
-
return /* @__PURE__ */ jsxs(
|
|
176
|
-
_Tooltip.Root,
|
|
177
|
-
{
|
|
178
|
-
delayDuration: editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS,
|
|
179
|
-
disableHoverableContent: true,
|
|
180
|
-
children: [
|
|
181
|
-
/* @__PURE__ */ jsx(_Tooltip.Trigger, { asChild: true, children }),
|
|
182
|
-
/* @__PURE__ */ jsxs(
|
|
183
|
-
_Tooltip.Content,
|
|
184
|
-
{
|
|
185
|
-
className: "tlui-tooltip",
|
|
186
|
-
side,
|
|
187
|
-
sideOffset,
|
|
188
|
-
avoidCollisions: true,
|
|
189
|
-
collisionPadding: 8,
|
|
190
|
-
dir: "ltr",
|
|
191
|
-
children: [
|
|
192
|
-
content,
|
|
193
|
-
/* @__PURE__ */ jsx(_Tooltip.Arrow, { className: "tlui-tooltip__arrow" })
|
|
194
|
-
]
|
|
195
|
-
}
|
|
196
|
-
)
|
|
197
|
-
]
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
const handleMouseEnter = (event) => {
|
|
202
|
-
tooltipManager.showTooltip(
|
|
203
|
-
tooltipId.current,
|
|
204
|
-
content,
|
|
205
|
-
event.currentTarget,
|
|
206
|
-
side,
|
|
207
|
-
sideOffset
|
|
208
|
-
);
|
|
209
|
-
};
|
|
210
|
-
const handleMouseLeave = () => {
|
|
211
|
-
tooltipManager.hideTooltip(tooltipId.current);
|
|
212
|
-
};
|
|
213
|
-
const handleFocus = (event) => {
|
|
214
|
-
tooltipManager.showTooltip(
|
|
215
|
-
tooltipId.current,
|
|
216
|
-
content,
|
|
217
|
-
event.currentTarget,
|
|
218
|
-
side,
|
|
219
|
-
sideOffset
|
|
220
|
-
);
|
|
221
|
-
};
|
|
222
|
-
const handleBlur = () => {
|
|
223
|
-
tooltipManager.hideTooltip(tooltipId.current);
|
|
224
|
-
};
|
|
225
|
-
const childrenWithHandlers = React.cloneElement(children, {
|
|
226
|
-
onMouseEnter: handleMouseEnter,
|
|
227
|
-
onMouseLeave: handleMouseLeave,
|
|
228
|
-
onFocus: handleFocus,
|
|
229
|
-
onBlur: handleBlur
|
|
230
|
-
});
|
|
231
|
-
return childrenWithHandlers;
|
|
232
|
-
}
|
|
233
|
-
export {
|
|
234
|
-
TldrawUiTooltip,
|
|
235
|
-
TldrawUiTooltipProvider
|
|
236
|
-
};
|
|
237
|
-
//# sourceMappingURL=TldrawUiTooltip.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../../src/lib/ui/components/primitives/TldrawUiTooltip.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Editor, uniqueId, useMaybeEditor, Vec } from '@tldraw/editor'\nimport { Tooltip as _Tooltip } from 'radix-ui'\nimport React, { createContext, useContext, useEffect, useRef, useState } from 'react'\nimport { usePrefersReducedMotion } from '../../../shapes/shared/usePrefersReducedMotion'\n\nconst DEFAULT_TOOLTIP_DELAY_MS = 700\n\n/** @public */\nexport interface TldrawUiTooltipProps {\n\tchildren: React.ReactNode\n\tcontent?: string | React.ReactNode\n\tside?: 'top' | 'right' | 'bottom' | 'left'\n\tsideOffset?: number\n\tdisabled?: boolean\n}\n\n// Singleton tooltip manager\nclass TooltipManager {\n\tprivate static instance: TooltipManager | null = null\n\tprivate currentTooltipId: string | null = null\n\tprivate currentContent: string | React.ReactNode = ''\n\tprivate currentSide: 'top' | 'right' | 'bottom' | 'left' = 'bottom'\n\tprivate currentSideOffset: number = 5\n\tprivate destroyTimeoutId: number | null = null\n\tprivate subscribers: Set<() => void> = new Set()\n\tprivate activeElement: HTMLElement | null = null\n\tprivate editor: Editor | null = null\n\n\tstatic getInstance(): TooltipManager {\n\t\tif (!TooltipManager.instance) {\n\t\t\tTooltipManager.instance = new TooltipManager()\n\t\t}\n\t\treturn TooltipManager.instance\n\t}\n\n\tsetEditor(editor: Editor | null) {\n\t\tthis.editor = editor\n\t}\n\n\tsubscribe(callback: () => void): () => void {\n\t\tthis.subscribers.add(callback)\n\t\treturn () => this.subscribers.delete(callback)\n\t}\n\n\tprivate notify() {\n\t\tthis.subscribers.forEach((callback) => callback())\n\t}\n\n\tshowTooltip(\n\t\ttooltipId: string,\n\t\tcontent: string | React.ReactNode,\n\t\telement: HTMLElement,\n\t\tside: 'top' | 'right' | 'bottom' | 'left' = 'bottom',\n\t\tsideOffset: number = 5\n\t) {\n\t\t// Clear any existing destroy timeout\n\t\tif (this.destroyTimeoutId) {\n\t\t\tclearTimeout(this.destroyTimeoutId)\n\t\t\tthis.destroyTimeoutId = null\n\t\t}\n\n\t\t// Update current tooltip\n\t\tthis.currentTooltipId = tooltipId\n\t\tthis.currentContent = content\n\t\tthis.currentSide = side\n\t\tthis.currentSideOffset = sideOffset\n\t\tthis.activeElement = element\n\n\t\tthis.notify()\n\t}\n\n\thideTooltip(tooltipId: string) {\n\t\t// Only hide if this is the current tooltip\n\t\tif (this.currentTooltipId === tooltipId) {\n\t\t\t// Start destroy timeout (1 second)\n\t\t\tif (this.editor) {\n\t\t\t\tthis.destroyTimeoutId = this.editor.timers.setTimeout(() => {\n\t\t\t\t\tthis.currentTooltipId = null\n\t\t\t\t\tthis.currentContent = ''\n\t\t\t\t\tthis.activeElement = null\n\t\t\t\t\tthis.destroyTimeoutId = null\n\t\t\t\t\tthis.notify()\n\t\t\t\t}, 300)\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCurrentTooltipData() {\n\t\treturn {\n\t\t\tid: this.currentTooltipId,\n\t\t\tcontent: this.currentContent,\n\t\t\tside: this.currentSide,\n\t\t\tsideOffset: this.currentSideOffset,\n\t\t\telement: this.activeElement,\n\t\t}\n\t}\n}\n\nconst tooltipManager = TooltipManager.getInstance()\n\n// Context for the tooltip singleton\nconst TooltipSingletonContext = createContext<boolean>(false)\n\n/** @public */\nexport interface TldrawUiTooltipProviderProps {\n\tchildren: React.ReactNode\n}\n\n/** @public @react */\nexport function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderProps) {\n\treturn (\n\t\t<_Tooltip.Provider skipDelayDuration={700}>\n\t\t\t<TooltipSingletonContext.Provider value={true}>\n\t\t\t\t{children}\n\t\t\t\t<TooltipSingleton />\n\t\t\t</TooltipSingletonContext.Provider>\n\t\t</_Tooltip.Provider>\n\t)\n}\n\n// The singleton tooltip component that renders once\nfunction TooltipSingleton() {\n\tconst editor = useMaybeEditor()\n\tconst [, forceUpdate] = useState({})\n\tconst [isOpen, setIsOpen] = useState(false)\n\tconst triggerRef = useRef<HTMLDivElement>(null)\n\tconst previousPositionRef = useRef<{ x: number; y: number } | null>(null)\n\tconst prefersReducedMotion = usePrefersReducedMotion()\n\tconst [shouldAnimate, setShouldAnimate] = useState(false)\n\tconst isFirstShowRef = useRef(true)\n\tconst showTimeoutRef = useRef<number | null>(null)\n\n\t// Set editor in tooltip manager\n\tuseEffect(() => {\n\t\ttooltipManager.setEditor(editor)\n\t}, [editor])\n\n\t// Subscribe to tooltip manager updates\n\tuseEffect(() => {\n\t\tconst unsubscribe = tooltipManager.subscribe(() => {\n\t\t\tforceUpdate({})\n\t\t})\n\t\treturn unsubscribe\n\t}, [])\n\n\tconst tooltipData = tooltipManager.getCurrentTooltipData()\n\n\t// Update open state and trigger position\n\tuseEffect(() => {\n\t\tconst shouldBeOpen = Boolean(tooltipData.id && tooltipData.element)\n\n\t\t// Clear any existing show timeout\n\t\tif (showTimeoutRef.current) {\n\t\t\tclearTimeout(showTimeoutRef.current)\n\t\t\tshowTimeoutRef.current = null\n\t\t}\n\n\t\tif (shouldBeOpen && tooltipData.element && triggerRef.current) {\n\t\t\t// Position the invisible trigger element over the active element\n\t\t\tconst activeRect = tooltipData.element.getBoundingClientRect()\n\t\t\tconst trigger = triggerRef.current\n\n\t\t\tconst newPosition = {\n\t\t\t\tx: activeRect.left + activeRect.width / 2,\n\t\t\t\ty: activeRect.top + activeRect.height / 2,\n\t\t\t}\n\n\t\t\t// Determine if we should animate\n\t\t\tlet shouldAnimateCheck = false\n\t\t\tif (previousPositionRef.current) {\n\t\t\t\tconst isNearPrevious = Vec.DistMin(previousPositionRef.current, newPosition, 200)\n\t\t\t\t// Only animate if the distance is less than 200px (nearby tooltips)\n\t\t\t\tshouldAnimateCheck =\n\t\t\t\t\t!prefersReducedMotion &&\n\t\t\t\t\tisNearPrevious &&\n\t\t\t\t\tMath.abs(newPosition.y - previousPositionRef.current.y) < 50\n\t\t\t}\n\t\t\t// Don't animate on initial show (previousPositionRef.current is null)\n\n\t\t\tsetShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck)\n\t\t\tpreviousPositionRef.current = newPosition\n\n\t\t\ttrigger.style.position = 'fixed'\n\t\t\ttrigger.style.left = `${activeRect.left}px`\n\t\t\ttrigger.style.top = `${activeRect.top}px`\n\t\t\ttrigger.style.width = `${activeRect.width}px`\n\t\t\ttrigger.style.height = `${activeRect.height}px`\n\t\t\ttrigger.style.pointerEvents = 'none'\n\t\t\ttrigger.style.zIndex = '9999'\n\n\t\t\t// Handle delay for first show\n\t\t\tif (isFirstShowRef.current && editor) {\n\t\t\t\tshowTimeoutRef.current = editor.timers.setTimeout(() => {\n\t\t\t\t\tsetIsOpen(true)\n\t\t\t\t\tisFirstShowRef.current = false\n\t\t\t\t}, editor.options.tooltipDelayMs)\n\t\t\t} else {\n\t\t\t\t// Subsequent tooltips show immediately\n\t\t\t\tsetIsOpen(true)\n\t\t\t}\n\t\t} else if (!shouldBeOpen) {\n\t\t\t// Hide tooltip immediately\n\t\t\tsetIsOpen(false)\n\t\t\t// Reset position tracking when tooltip closes\n\t\t\tpreviousPositionRef.current = null\n\t\t\tsetShouldAnimate(false)\n\t\t\t// Reset first show state after tooltip is hidden\n\t\t\tisFirstShowRef.current = true\n\t\t}\n\t}, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion])\n\n\tif (!tooltipData.id) {\n\t\treturn null\n\t}\n\n\treturn (\n\t\t<_Tooltip.Root open={isOpen} delayDuration={0}>\n\t\t\t<_Tooltip.Trigger asChild>\n\t\t\t\t<div ref={triggerRef} />\n\t\t\t</_Tooltip.Trigger>\n\t\t\t<_Tooltip.Content\n\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\tdata-should-animate={shouldAnimate}\n\t\t\t\tside={tooltipData.side}\n\t\t\t\tsideOffset={tooltipData.sideOffset}\n\t\t\t\tavoidCollisions\n\t\t\t\tcollisionPadding={8}\n\t\t\t\tdir=\"ltr\"\n\t\t\t>\n\t\t\t\t{tooltipData.content}\n\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t</_Tooltip.Content>\n\t\t</_Tooltip.Root>\n\t)\n}\n\n/** @public @react */\nexport function TldrawUiTooltip({\n\tchildren,\n\tcontent,\n\tside = 'bottom',\n\tsideOffset = 5,\n\tdisabled = false,\n}: TldrawUiTooltipProps) {\n\tconst editor = useMaybeEditor()\n\tconst tooltipId = useRef<string>(uniqueId())\n\tconst hasProvider = useContext(TooltipSingletonContext)\n\n\t// Don't show tooltip if disabled, no content, or UI labels are disabled\n\tif (disabled || !content) {\n\t\treturn <>{children}</>\n\t}\n\n\t// Fallback to old behavior if no provider\n\tif (!hasProvider) {\n\t\treturn (\n\t\t\t<_Tooltip.Root\n\t\t\t\tdelayDuration={editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS}\n\t\t\t\tdisableHoverableContent\n\t\t\t>\n\t\t\t\t<_Tooltip.Trigger asChild>{children}</_Tooltip.Trigger>\n\t\t\t\t<_Tooltip.Content\n\t\t\t\t\tclassName=\"tlui-tooltip\"\n\t\t\t\t\tside={side}\n\t\t\t\t\tsideOffset={sideOffset}\n\t\t\t\t\tavoidCollisions\n\t\t\t\t\tcollisionPadding={8}\n\t\t\t\t\tdir=\"ltr\"\n\t\t\t\t>\n\t\t\t\t\t{content}\n\t\t\t\t\t<_Tooltip.Arrow className=\"tlui-tooltip__arrow\" />\n\t\t\t\t</_Tooltip.Content>\n\t\t\t</_Tooltip.Root>\n\t\t)\n\t}\n\n\tconst handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {\n\t\ttooltipManager.showTooltip(\n\t\t\ttooltipId.current,\n\t\t\tcontent,\n\t\t\tevent.currentTarget as HTMLElement,\n\t\t\tside,\n\t\t\tsideOffset\n\t\t)\n\t}\n\n\tconst handleMouseLeave = () => {\n\t\ttooltipManager.hideTooltip(tooltipId.current)\n\t}\n\n\tconst handleFocus = (event: React.FocusEvent<HTMLElement>) => {\n\t\ttooltipManager.showTooltip(\n\t\t\ttooltipId.current,\n\t\t\tcontent,\n\t\t\tevent.currentTarget as HTMLElement,\n\t\t\tside,\n\t\t\tsideOffset\n\t\t)\n\t}\n\n\tconst handleBlur = () => {\n\t\ttooltipManager.hideTooltip(tooltipId.current)\n\t}\n\n\tconst childrenWithHandlers = React.cloneElement(children as React.ReactElement, {\n\t\tonMouseEnter: handleMouseEnter,\n\t\tonMouseLeave: handleMouseLeave,\n\t\tonFocus: handleFocus,\n\t\tonBlur: handleBlur,\n\t})\n\n\treturn childrenWithHandlers\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ToggleKeyboardShortcutsItem,
|
|
3
|
-
ToggleReduceMotionItem,
|
|
4
|
-
ToggleUiLabelsItem,
|
|
5
|
-
} from './menu-items'
|
|
6
|
-
import { TldrawUiMenuGroup } from './primitives/menus/TldrawUiMenuGroup'
|
|
7
|
-
import { TldrawUiMenuSubmenu } from './primitives/menus/TldrawUiMenuSubmenu'
|
|
8
|
-
|
|
9
|
-
/** @public @react */
|
|
10
|
-
export function AccessibilityMenu() {
|
|
11
|
-
return (
|
|
12
|
-
<TldrawUiMenuSubmenu id="help menu accessibility" label="menu.accessibility">
|
|
13
|
-
<TldrawUiMenuGroup id="accessibility">
|
|
14
|
-
<ToggleReduceMotionItem />
|
|
15
|
-
<ToggleKeyboardShortcutsItem />
|
|
16
|
-
<ToggleUiLabelsItem />
|
|
17
|
-
</TldrawUiMenuGroup>
|
|
18
|
-
</TldrawUiMenuSubmenu>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
import { Editor, uniqueId, useMaybeEditor, Vec } from '@tldraw/editor'
|
|
2
|
-
import { Tooltip as _Tooltip } from 'radix-ui'
|
|
3
|
-
import React, { createContext, useContext, useEffect, useRef, useState } from 'react'
|
|
4
|
-
import { usePrefersReducedMotion } from '../../../shapes/shared/usePrefersReducedMotion'
|
|
5
|
-
|
|
6
|
-
const DEFAULT_TOOLTIP_DELAY_MS = 700
|
|
7
|
-
|
|
8
|
-
/** @public */
|
|
9
|
-
export interface TldrawUiTooltipProps {
|
|
10
|
-
children: React.ReactNode
|
|
11
|
-
content?: string | React.ReactNode
|
|
12
|
-
side?: 'top' | 'right' | 'bottom' | 'left'
|
|
13
|
-
sideOffset?: number
|
|
14
|
-
disabled?: boolean
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Singleton tooltip manager
|
|
18
|
-
class TooltipManager {
|
|
19
|
-
private static instance: TooltipManager | null = null
|
|
20
|
-
private currentTooltipId: string | null = null
|
|
21
|
-
private currentContent: string | React.ReactNode = ''
|
|
22
|
-
private currentSide: 'top' | 'right' | 'bottom' | 'left' = 'bottom'
|
|
23
|
-
private currentSideOffset: number = 5
|
|
24
|
-
private destroyTimeoutId: number | null = null
|
|
25
|
-
private subscribers: Set<() => void> = new Set()
|
|
26
|
-
private activeElement: HTMLElement | null = null
|
|
27
|
-
private editor: Editor | null = null
|
|
28
|
-
|
|
29
|
-
static getInstance(): TooltipManager {
|
|
30
|
-
if (!TooltipManager.instance) {
|
|
31
|
-
TooltipManager.instance = new TooltipManager()
|
|
32
|
-
}
|
|
33
|
-
return TooltipManager.instance
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
setEditor(editor: Editor | null) {
|
|
37
|
-
this.editor = editor
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
subscribe(callback: () => void): () => void {
|
|
41
|
-
this.subscribers.add(callback)
|
|
42
|
-
return () => this.subscribers.delete(callback)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private notify() {
|
|
46
|
-
this.subscribers.forEach((callback) => callback())
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
showTooltip(
|
|
50
|
-
tooltipId: string,
|
|
51
|
-
content: string | React.ReactNode,
|
|
52
|
-
element: HTMLElement,
|
|
53
|
-
side: 'top' | 'right' | 'bottom' | 'left' = 'bottom',
|
|
54
|
-
sideOffset: number = 5
|
|
55
|
-
) {
|
|
56
|
-
// Clear any existing destroy timeout
|
|
57
|
-
if (this.destroyTimeoutId) {
|
|
58
|
-
clearTimeout(this.destroyTimeoutId)
|
|
59
|
-
this.destroyTimeoutId = null
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Update current tooltip
|
|
63
|
-
this.currentTooltipId = tooltipId
|
|
64
|
-
this.currentContent = content
|
|
65
|
-
this.currentSide = side
|
|
66
|
-
this.currentSideOffset = sideOffset
|
|
67
|
-
this.activeElement = element
|
|
68
|
-
|
|
69
|
-
this.notify()
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
hideTooltip(tooltipId: string) {
|
|
73
|
-
// Only hide if this is the current tooltip
|
|
74
|
-
if (this.currentTooltipId === tooltipId) {
|
|
75
|
-
// Start destroy timeout (1 second)
|
|
76
|
-
if (this.editor) {
|
|
77
|
-
this.destroyTimeoutId = this.editor.timers.setTimeout(() => {
|
|
78
|
-
this.currentTooltipId = null
|
|
79
|
-
this.currentContent = ''
|
|
80
|
-
this.activeElement = null
|
|
81
|
-
this.destroyTimeoutId = null
|
|
82
|
-
this.notify()
|
|
83
|
-
}, 300)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
getCurrentTooltipData() {
|
|
89
|
-
return {
|
|
90
|
-
id: this.currentTooltipId,
|
|
91
|
-
content: this.currentContent,
|
|
92
|
-
side: this.currentSide,
|
|
93
|
-
sideOffset: this.currentSideOffset,
|
|
94
|
-
element: this.activeElement,
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const tooltipManager = TooltipManager.getInstance()
|
|
100
|
-
|
|
101
|
-
// Context for the tooltip singleton
|
|
102
|
-
const TooltipSingletonContext = createContext<boolean>(false)
|
|
103
|
-
|
|
104
|
-
/** @public */
|
|
105
|
-
export interface TldrawUiTooltipProviderProps {
|
|
106
|
-
children: React.ReactNode
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/** @public @react */
|
|
110
|
-
export function TldrawUiTooltipProvider({ children }: TldrawUiTooltipProviderProps) {
|
|
111
|
-
return (
|
|
112
|
-
<_Tooltip.Provider skipDelayDuration={700}>
|
|
113
|
-
<TooltipSingletonContext.Provider value={true}>
|
|
114
|
-
{children}
|
|
115
|
-
<TooltipSingleton />
|
|
116
|
-
</TooltipSingletonContext.Provider>
|
|
117
|
-
</_Tooltip.Provider>
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// The singleton tooltip component that renders once
|
|
122
|
-
function TooltipSingleton() {
|
|
123
|
-
const editor = useMaybeEditor()
|
|
124
|
-
const [, forceUpdate] = useState({})
|
|
125
|
-
const [isOpen, setIsOpen] = useState(false)
|
|
126
|
-
const triggerRef = useRef<HTMLDivElement>(null)
|
|
127
|
-
const previousPositionRef = useRef<{ x: number; y: number } | null>(null)
|
|
128
|
-
const prefersReducedMotion = usePrefersReducedMotion()
|
|
129
|
-
const [shouldAnimate, setShouldAnimate] = useState(false)
|
|
130
|
-
const isFirstShowRef = useRef(true)
|
|
131
|
-
const showTimeoutRef = useRef<number | null>(null)
|
|
132
|
-
|
|
133
|
-
// Set editor in tooltip manager
|
|
134
|
-
useEffect(() => {
|
|
135
|
-
tooltipManager.setEditor(editor)
|
|
136
|
-
}, [editor])
|
|
137
|
-
|
|
138
|
-
// Subscribe to tooltip manager updates
|
|
139
|
-
useEffect(() => {
|
|
140
|
-
const unsubscribe = tooltipManager.subscribe(() => {
|
|
141
|
-
forceUpdate({})
|
|
142
|
-
})
|
|
143
|
-
return unsubscribe
|
|
144
|
-
}, [])
|
|
145
|
-
|
|
146
|
-
const tooltipData = tooltipManager.getCurrentTooltipData()
|
|
147
|
-
|
|
148
|
-
// Update open state and trigger position
|
|
149
|
-
useEffect(() => {
|
|
150
|
-
const shouldBeOpen = Boolean(tooltipData.id && tooltipData.element)
|
|
151
|
-
|
|
152
|
-
// Clear any existing show timeout
|
|
153
|
-
if (showTimeoutRef.current) {
|
|
154
|
-
clearTimeout(showTimeoutRef.current)
|
|
155
|
-
showTimeoutRef.current = null
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (shouldBeOpen && tooltipData.element && triggerRef.current) {
|
|
159
|
-
// Position the invisible trigger element over the active element
|
|
160
|
-
const activeRect = tooltipData.element.getBoundingClientRect()
|
|
161
|
-
const trigger = triggerRef.current
|
|
162
|
-
|
|
163
|
-
const newPosition = {
|
|
164
|
-
x: activeRect.left + activeRect.width / 2,
|
|
165
|
-
y: activeRect.top + activeRect.height / 2,
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Determine if we should animate
|
|
169
|
-
let shouldAnimateCheck = false
|
|
170
|
-
if (previousPositionRef.current) {
|
|
171
|
-
const isNearPrevious = Vec.DistMin(previousPositionRef.current, newPosition, 200)
|
|
172
|
-
// Only animate if the distance is less than 200px (nearby tooltips)
|
|
173
|
-
shouldAnimateCheck =
|
|
174
|
-
!prefersReducedMotion &&
|
|
175
|
-
isNearPrevious &&
|
|
176
|
-
Math.abs(newPosition.y - previousPositionRef.current.y) < 50
|
|
177
|
-
}
|
|
178
|
-
// Don't animate on initial show (previousPositionRef.current is null)
|
|
179
|
-
|
|
180
|
-
setShouldAnimate(isFirstShowRef.current ? false : shouldAnimateCheck)
|
|
181
|
-
previousPositionRef.current = newPosition
|
|
182
|
-
|
|
183
|
-
trigger.style.position = 'fixed'
|
|
184
|
-
trigger.style.left = `${activeRect.left}px`
|
|
185
|
-
trigger.style.top = `${activeRect.top}px`
|
|
186
|
-
trigger.style.width = `${activeRect.width}px`
|
|
187
|
-
trigger.style.height = `${activeRect.height}px`
|
|
188
|
-
trigger.style.pointerEvents = 'none'
|
|
189
|
-
trigger.style.zIndex = '9999'
|
|
190
|
-
|
|
191
|
-
// Handle delay for first show
|
|
192
|
-
if (isFirstShowRef.current && editor) {
|
|
193
|
-
showTimeoutRef.current = editor.timers.setTimeout(() => {
|
|
194
|
-
setIsOpen(true)
|
|
195
|
-
isFirstShowRef.current = false
|
|
196
|
-
}, editor.options.tooltipDelayMs)
|
|
197
|
-
} else {
|
|
198
|
-
// Subsequent tooltips show immediately
|
|
199
|
-
setIsOpen(true)
|
|
200
|
-
}
|
|
201
|
-
} else if (!shouldBeOpen) {
|
|
202
|
-
// Hide tooltip immediately
|
|
203
|
-
setIsOpen(false)
|
|
204
|
-
// Reset position tracking when tooltip closes
|
|
205
|
-
previousPositionRef.current = null
|
|
206
|
-
setShouldAnimate(false)
|
|
207
|
-
// Reset first show state after tooltip is hidden
|
|
208
|
-
isFirstShowRef.current = true
|
|
209
|
-
}
|
|
210
|
-
}, [tooltipData.id, tooltipData.element, editor, prefersReducedMotion])
|
|
211
|
-
|
|
212
|
-
if (!tooltipData.id) {
|
|
213
|
-
return null
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return (
|
|
217
|
-
<_Tooltip.Root open={isOpen} delayDuration={0}>
|
|
218
|
-
<_Tooltip.Trigger asChild>
|
|
219
|
-
<div ref={triggerRef} />
|
|
220
|
-
</_Tooltip.Trigger>
|
|
221
|
-
<_Tooltip.Content
|
|
222
|
-
className="tlui-tooltip"
|
|
223
|
-
data-should-animate={shouldAnimate}
|
|
224
|
-
side={tooltipData.side}
|
|
225
|
-
sideOffset={tooltipData.sideOffset}
|
|
226
|
-
avoidCollisions
|
|
227
|
-
collisionPadding={8}
|
|
228
|
-
dir="ltr"
|
|
229
|
-
>
|
|
230
|
-
{tooltipData.content}
|
|
231
|
-
<_Tooltip.Arrow className="tlui-tooltip__arrow" />
|
|
232
|
-
</_Tooltip.Content>
|
|
233
|
-
</_Tooltip.Root>
|
|
234
|
-
)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/** @public @react */
|
|
238
|
-
export function TldrawUiTooltip({
|
|
239
|
-
children,
|
|
240
|
-
content,
|
|
241
|
-
side = 'bottom',
|
|
242
|
-
sideOffset = 5,
|
|
243
|
-
disabled = false,
|
|
244
|
-
}: TldrawUiTooltipProps) {
|
|
245
|
-
const editor = useMaybeEditor()
|
|
246
|
-
const tooltipId = useRef<string>(uniqueId())
|
|
247
|
-
const hasProvider = useContext(TooltipSingletonContext)
|
|
248
|
-
|
|
249
|
-
// Don't show tooltip if disabled, no content, or UI labels are disabled
|
|
250
|
-
if (disabled || !content) {
|
|
251
|
-
return <>{children}</>
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Fallback to old behavior if no provider
|
|
255
|
-
if (!hasProvider) {
|
|
256
|
-
return (
|
|
257
|
-
<_Tooltip.Root
|
|
258
|
-
delayDuration={editor?.options.tooltipDelayMs || DEFAULT_TOOLTIP_DELAY_MS}
|
|
259
|
-
disableHoverableContent
|
|
260
|
-
>
|
|
261
|
-
<_Tooltip.Trigger asChild>{children}</_Tooltip.Trigger>
|
|
262
|
-
<_Tooltip.Content
|
|
263
|
-
className="tlui-tooltip"
|
|
264
|
-
side={side}
|
|
265
|
-
sideOffset={sideOffset}
|
|
266
|
-
avoidCollisions
|
|
267
|
-
collisionPadding={8}
|
|
268
|
-
dir="ltr"
|
|
269
|
-
>
|
|
270
|
-
{content}
|
|
271
|
-
<_Tooltip.Arrow className="tlui-tooltip__arrow" />
|
|
272
|
-
</_Tooltip.Content>
|
|
273
|
-
</_Tooltip.Root>
|
|
274
|
-
)
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const handleMouseEnter = (event: React.MouseEvent<HTMLElement>) => {
|
|
278
|
-
tooltipManager.showTooltip(
|
|
279
|
-
tooltipId.current,
|
|
280
|
-
content,
|
|
281
|
-
event.currentTarget as HTMLElement,
|
|
282
|
-
side,
|
|
283
|
-
sideOffset
|
|
284
|
-
)
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const handleMouseLeave = () => {
|
|
288
|
-
tooltipManager.hideTooltip(tooltipId.current)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
const handleFocus = (event: React.FocusEvent<HTMLElement>) => {
|
|
292
|
-
tooltipManager.showTooltip(
|
|
293
|
-
tooltipId.current,
|
|
294
|
-
content,
|
|
295
|
-
event.currentTarget as HTMLElement,
|
|
296
|
-
side,
|
|
297
|
-
sideOffset
|
|
298
|
-
)
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const handleBlur = () => {
|
|
302
|
-
tooltipManager.hideTooltip(tooltipId.current)
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const childrenWithHandlers = React.cloneElement(children as React.ReactElement, {
|
|
306
|
-
onMouseEnter: handleMouseEnter,
|
|
307
|
-
onMouseLeave: handleMouseLeave,
|
|
308
|
-
onFocus: handleFocus,
|
|
309
|
-
onBlur: handleBlur,
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
return childrenWithHandlers
|
|
313
|
-
}
|