tldraw 3.16.0-canary.856874107ebd → 3.16.0-canary.887377ec7acc
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 +269 -106
- package/dist-cjs/index.js +36 -14
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/Tldraw.js +12 -2
- package/dist-cjs/lib/Tldraw.js.map +2 -2
- package/dist-cjs/lib/canvas/TldrawScribble.js +1 -1
- package/dist-cjs/lib/canvas/TldrawScribble.js.map +2 -2
- package/dist-cjs/lib/defaultExternalContentHandlers.js +5 -4
- package/dist-cjs/lib/defaultExternalContentHandlers.js.map +2 -2
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js +6 -0
- package/dist-cjs/lib/shapes/arrow/arrowLabel.js.map +3 -3
- package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js +3 -3
- package/dist-cjs/lib/shapes/arrow/elbow/ElbowArrowDebug.js.map +1 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +1 -1
- package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +1 -1
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +12 -5
- package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/frame/components/FrameHeading.js +1 -1
- package/dist-cjs/lib/shapes/frame/components/FrameHeading.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -0
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +6 -3
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +2 -1
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +1 -1
- package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +0 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +1 -1
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js +25 -1
- package/dist-cjs/lib/tools/EraserTool/childStates/Erasing.js.map +2 -2
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js +12 -0
- package/dist-cjs/lib/tools/EraserTool/childStates/Pointing.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +27 -12
- package/dist-cjs/lib/ui/TldrawUi.js.map +3 -3
- 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/ActionsMenu/DefaultActionsMenu.js +10 -2
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/{FollowingIndicator.js → DefaultFollowingIndicator.js} +6 -6
- package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +7 -0
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +6 -6
- package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +1 -1
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +4 -4
- package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
- package/dist-cjs/lib/ui/components/MobileStylePanel.js +4 -2
- package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +24 -21
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js +3 -2
- package/dist-cjs/lib/ui/components/Toolbar/AltTextEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +39 -10
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -22
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js +15 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultVideoToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/LinkEditor.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +188 -78
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +10 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +18 -5
- package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +17 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +176 -166
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/layout.js +30 -5
- package/dist-cjs/lib/ui/components/primitives/layout.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuContext.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js +25 -12
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuGroup.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +8 -24
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +23 -10
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/context/components.js +2 -0
- package/dist-cjs/lib/ui/context/components.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +1 -1
- package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +22 -4
- 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 +4 -2
- package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
- package/dist-cjs/lib/ui/kbd-utils.js +9 -3
- 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/export/copyAs.js +1 -2
- package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
- package/dist-cjs/lib/utils/export/export.js +0 -20
- package/dist-cjs/lib/utils/export/export.js.map +2 -2
- package/dist-cjs/lib/utils/export/exportAs.js +1 -2
- package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
- package/dist-esm/index.d.mts +269 -106
- package/dist-esm/index.mjs +68 -30
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/Tldraw.mjs +14 -4
- package/dist-esm/lib/Tldraw.mjs.map +2 -2
- package/dist-esm/lib/canvas/TldrawScribble.mjs +1 -1
- package/dist-esm/lib/canvas/TldrawScribble.mjs.map +2 -2
- package/dist-esm/lib/defaultExternalContentHandlers.mjs +5 -4
- package/dist-esm/lib/defaultExternalContentHandlers.mjs.map +2 -2
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs +6 -0
- package/dist-esm/lib/shapes/arrow/arrowLabel.mjs.map +3 -3
- package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs +3 -3
- package/dist-esm/lib/shapes/arrow/elbow/ElbowArrowDebug.mjs.map +1 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +1 -1
- package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +12 -5
- package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs +1 -1
- package/dist-esm/lib/shapes/frame/components/FrameHeading.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +1 -0
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +6 -3
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +2 -1
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs +1 -1
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +3 -3
- package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs +26 -1
- package/dist-esm/lib/tools/EraserTool/childStates/Erasing.mjs.map +2 -2
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs +13 -0
- package/dist-esm/lib/tools/EraserTool/childStates/Pointing.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +29 -14
- package/dist-esm/lib/ui/TldrawUi.mjs.map +3 -3
- 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/ActionsMenu/DefaultActionsMenu.mjs +10 -2
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/{FollowingIndicator.mjs → DefaultFollowingIndicator.mjs} +3 -3
- package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +7 -0
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +6 -6
- package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +1 -1
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +4 -4
- package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs +4 -2
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/{primitives/TldrawUiButtonPicker.mjs → StylePanel/StylePanelButtonPicker.mjs} +54 -43
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +21 -18
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs +3 -2
- package/dist-esm/lib/ui/components/Toolbar/AltTextEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +39 -10
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -22
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs +15 -3
- package/dist-esm/lib/ui/components/Toolbar/DefaultVideoToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs +3 -3
- package/dist-esm/lib/ui/components/Toolbar/LinkEditor.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -80
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +10 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +18 -5
- package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +18 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +186 -168
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/layout.mjs +31 -6
- package/dist-esm/lib/ui/components/primitives/layout.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuContext.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs +25 -12
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuGroup.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +8 -24
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +23 -10
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/context/components.mjs +2 -0
- package/dist-esm/lib/ui/context/components.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +1 -1
- package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
- package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +23 -4
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +4 -2
- package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
- package/dist-esm/lib/ui/kbd-utils.mjs +9 -3
- 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/export/copyAs.mjs +1 -2
- package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
- package/dist-esm/lib/utils/export/export.mjs +0 -20
- package/dist-esm/lib/utils/export/export.mjs.map +2 -2
- package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
- package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
- package/package.json +11 -34
- package/src/index.ts +49 -22
- package/src/lib/Tldraw.tsx +15 -2
- package/src/lib/canvas/TldrawScribble.tsx +1 -1
- package/src/lib/defaultExternalContentHandlers.ts +12 -4
- package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +6 -5
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +48 -6
- package/src/lib/shapes/arrow/arrowLabel.ts +8 -0
- package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
- package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -4
- package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +1 -0
- package/src/lib/shapes/image/ImageShapeUtil.tsx +6 -3
- package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
- package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +1 -0
- package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
- package/src/lib/shapes/shared/ShapeFill.tsx +1 -1
- package/src/lib/shapes/shared/freehand/svg.ts +2 -0
- package/src/lib/shapes/shared/useEditablePlainText.ts +0 -6
- package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
- package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
- package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
- package/src/lib/tools/EraserTool/childStates/Erasing.ts +34 -1
- package/src/lib/tools/EraserTool/childStates/Pointing.ts +20 -0
- package/src/lib/ui/TldrawUi.tsx +33 -12
- package/src/lib/ui/assetUrls.ts +13 -10
- package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +13 -2
- package/src/lib/ui/components/{FollowingIndicator.tsx → DefaultFollowingIndicator.tsx} +2 -1
- package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +6 -6
- package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
- package/src/lib/ui/components/MobileStylePanel.tsx +4 -3
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
- package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +63 -50
- package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
- package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
- package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
- package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
- package/src/lib/ui/components/Toolbar/AltTextEditor.tsx +4 -3
- package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +33 -16
- package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -24
- package/src/lib/ui/components/Toolbar/DefaultVideoToolbarContent.tsx +12 -4
- package/src/lib/ui/components/Toolbar/LinkEditor.tsx +5 -5
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +208 -56
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +6 -1
- package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +52 -32
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +25 -5
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +220 -187
- package/src/lib/ui/components/primitives/layout.tsx +79 -5
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuContext.tsx +0 -1
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuGroup.tsx +29 -16
- package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +11 -24
- package/src/lib/ui/context/actions.tsx +23 -10
- package/src/lib/ui/context/components.tsx +3 -0
- package/src/lib/ui/context/events.tsx +1 -1
- package/src/lib/ui/hooks/useExportAs.ts +3 -2
- package/src/lib/ui/hooks/useTools.tsx +26 -4
- package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
- package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +4 -2
- package/src/lib/ui/kbd-utils.ts +10 -3
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +365 -245
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
- package/src/lib/utils/export/copyAs.ts +1 -24
- package/src/lib/utils/export/export.ts +0 -36
- package/src/lib/utils/export/exportAs.ts +1 -32
- package/src/lib/utils/tldr/__snapshots__/buildFromV1Document.test.ts.snap +4 -4
- package/src/test/A11y.test.tsx +3 -2
- package/src/test/ClickManager.test.ts +7 -6
- package/src/test/Editor.test.tsx +20 -19
- package/src/test/EraserTool.test.ts +184 -13
- package/src/test/HandTool.test.ts +10 -9
- package/src/test/HighlightShape.test.ts +2 -1
- package/src/test/SelectTool.test.ts +3 -2
- package/src/test/TLUserPreferences.test.ts +4 -3
- package/src/test/TestEditor.ts +13 -15
- package/src/test/TldrawEditor.test.tsx +11 -10
- package/src/test/ZoomTool.test.ts +7 -6
- package/src/test/__snapshots__/drawing.test.ts.snap +2 -2
- package/src/test/__snapshots__/groups.test.tsx.snap +6 -6
- package/src/test/__snapshots__/resizing.test.ts.snap +2 -2
- package/src/test/arrows-megabus.test.tsx +5 -4
- package/src/test/bindings.test.tsx +24 -37
- package/src/test/bookmark-shapes.test.ts +1 -8
- package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +23 -7
- package/src/test/commands/__snapshots__/packShapes.test.ts.snap +8 -8
- package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
- package/src/test/commands/alignShapes.test.tsx +25 -24
- package/src/test/commands/animationSpeed.test.ts +2 -1
- package/src/test/commands/centerOnPoint.test.ts +3 -2
- package/src/test/commands/clipboard.test.ts +3 -2
- package/src/test/commands/createShapes.test.ts +2 -1
- package/src/test/commands/deleteShapes.test.ts +2 -1
- package/src/test/commands/distributeShapes.test.tsx +11 -10
- package/src/test/commands/getSvgString.test.ts +2 -1
- package/src/test/commands/packShapes.test.ts +5 -4
- package/src/test/commands/resizeShape.test.ts +2 -1
- package/src/test/commands/rotateShapes.test.ts +7 -6
- package/src/test/commands/setCamera.test.ts +4 -3
- package/src/test/commands/setCurrentPage.test.ts +3 -2
- package/src/test/commands/stackShapes.test.ts +11 -10
- package/src/test/commands/stretch.test.tsx +13 -12
- package/src/test/createDeepLink.test.tsx +2 -1
- package/src/test/cropping.test.ts +3 -2
- package/src/test/custom-clipping.test.ts +436 -0
- package/src/test/drawing.test.ts +2 -1
- package/src/test/flipShapes.test.ts +4 -3
- package/src/test/frames.test.ts +25 -24
- package/src/test/getCulledShapes.test.tsx +74 -4
- package/src/test/groups.test.tsx +1 -1
- package/src/test/handleDeepLink.test.tsx +2 -1
- package/src/test/maxShapes.test.ts +3 -2
- package/src/test/modifiers.test.ts +5 -4
- package/src/test/navigation.test.ts +12 -11
- package/src/test/panning.test.ts +2 -1
- package/src/test/perf/perf.test.ts +2 -1
- package/src/test/registerDeepLinkListener.test.tsx +10 -9
- package/src/test/resizing.test.ts +39 -38
- package/src/test/select.test.tsx +4 -3
- package/src/test/selection-omnibus.test.ts +11 -10
- package/src/test/shapeutils.test.ts +4 -3
- package/src/test/translating.test.ts +9 -8
- package/tldraw.css +673 -537
- package/dist-cjs/lib/ui/components/FollowingIndicator.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
- package/dist-esm/lib/ui/components/FollowingIndicator.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
- package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
|
@@ -5,6 +5,7 @@ import { useUiEvents } from '../../context/events'
|
|
|
5
5
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
6
6
|
import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
|
|
7
7
|
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
|
|
8
|
+
import { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
8
9
|
|
|
9
10
|
/** @public */
|
|
10
11
|
export interface DefaultVideoToolbarContentProps {
|
|
@@ -44,7 +45,12 @@ export const DefaultVideoToolbarContent = track(function DefaultVideoToolbarCont
|
|
|
44
45
|
return (
|
|
45
46
|
<>
|
|
46
47
|
{!isReadonly && (
|
|
47
|
-
<TldrawUiButton
|
|
48
|
+
<TldrawUiButton
|
|
49
|
+
type="icon"
|
|
50
|
+
title={msg('tool.replace-media')}
|
|
51
|
+
onClick={handleVideoReplace}
|
|
52
|
+
data-testid="tool.video-replace"
|
|
53
|
+
>
|
|
48
54
|
<TldrawUiButtonIcon small icon="tool-media" />
|
|
49
55
|
</TldrawUiButton>
|
|
50
56
|
)}
|
|
@@ -52,21 +58,23 @@ export const DefaultVideoToolbarContent = track(function DefaultVideoToolbarCont
|
|
|
52
58
|
type="icon"
|
|
53
59
|
title={msg('action.download-original')}
|
|
54
60
|
onClick={handleVideoDownload}
|
|
61
|
+
data-testid="tool.video-download"
|
|
55
62
|
>
|
|
56
63
|
<TldrawUiButtonIcon small icon="download" />
|
|
57
64
|
</TldrawUiButton>
|
|
58
65
|
{(altText || !isReadonly) && (
|
|
59
|
-
<
|
|
60
|
-
type="
|
|
66
|
+
<TldrawUiToolbarButton
|
|
67
|
+
type="icon"
|
|
61
68
|
isActive={!!altText}
|
|
62
69
|
title={msg('tool.media-alt-text')}
|
|
70
|
+
data-testid="tool.video-alt-text"
|
|
63
71
|
onClick={() => {
|
|
64
72
|
trackEvent('alt-text-start', { source })
|
|
65
73
|
onEditAltTextStart()
|
|
66
74
|
}}
|
|
67
75
|
>
|
|
68
76
|
<TldrawUiButtonIcon small icon="alt" />
|
|
69
|
-
</
|
|
77
|
+
</TldrawUiToolbarButton>
|
|
70
78
|
)}
|
|
71
79
|
</>
|
|
72
80
|
)
|
|
@@ -2,9 +2,9 @@ import { preventDefault, TiptapEditor, useEditor } from '@tldraw/editor'
|
|
|
2
2
|
import { useEffect, useRef, useState } from 'react'
|
|
3
3
|
import { useUiEvents } from '../../context/events'
|
|
4
4
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
5
|
-
import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
|
|
6
5
|
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
|
|
7
6
|
import { TldrawUiInput } from '../primitives/TldrawUiInput'
|
|
7
|
+
import { TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
8
8
|
|
|
9
9
|
/** @public */
|
|
10
10
|
export interface LinkEditorProps {
|
|
@@ -76,7 +76,7 @@ export function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEdi
|
|
|
76
76
|
onCancel={handleLinkCancel}
|
|
77
77
|
placeholder="example.com"
|
|
78
78
|
/>
|
|
79
|
-
<
|
|
79
|
+
<TldrawUiToolbarButton
|
|
80
80
|
className="tlui-rich-text__toolbar-link-visit"
|
|
81
81
|
title={msg('tool.rich-text-link-visit')}
|
|
82
82
|
type="icon"
|
|
@@ -85,8 +85,8 @@ export function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEdi
|
|
|
85
85
|
disabled={!value}
|
|
86
86
|
>
|
|
87
87
|
<TldrawUiButtonIcon small icon="external-link" />
|
|
88
|
-
</
|
|
89
|
-
<
|
|
88
|
+
</TldrawUiToolbarButton>
|
|
89
|
+
<TldrawUiToolbarButton
|
|
90
90
|
className="tlui-rich-text__toolbar-link-remove"
|
|
91
91
|
title={msg('tool.rich-text-link-remove')}
|
|
92
92
|
data-testid="rich-text.link-remove"
|
|
@@ -95,7 +95,7 @@ export function LinkEditor({ textEditor, value: initialValue, onClose }: LinkEdi
|
|
|
95
95
|
onClick={handleRemoveLink}
|
|
96
96
|
>
|
|
97
97
|
<TldrawUiButtonIcon small icon="trash" />
|
|
98
|
-
</
|
|
98
|
+
</TldrawUiToolbarButton>
|
|
99
99
|
</>
|
|
100
100
|
)
|
|
101
101
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
activeElementShouldCaptureKeys,
|
|
3
|
+
assert,
|
|
4
|
+
modulate,
|
|
3
5
|
preventDefault,
|
|
4
6
|
tlmenus,
|
|
5
7
|
useEditor,
|
|
@@ -7,7 +9,7 @@ import {
|
|
|
7
9
|
useUniqueSafeId,
|
|
8
10
|
} from '@tldraw/editor'
|
|
9
11
|
import classNames from 'classnames'
|
|
10
|
-
import { createContext, useEffect, useLayoutEffect,
|
|
12
|
+
import { createContext, useEffect, useLayoutEffect, useRef, useState } from 'react'
|
|
11
13
|
import { PORTRAIT_BREAKPOINT } from '../../constants'
|
|
12
14
|
import { useBreakpoint } from '../../context/breakpoints'
|
|
13
15
|
import { areShortcutsDisabled } from '../../hooks/useKeyboardShortcuts'
|
|
@@ -20,7 +22,7 @@ import {
|
|
|
20
22
|
TldrawUiPopoverTrigger,
|
|
21
23
|
} from '../primitives/TldrawUiPopover'
|
|
22
24
|
import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
23
|
-
import { TldrawUiRow } from '../primitives/layout'
|
|
25
|
+
import { TldrawUiColumn, TldrawUiRow } from '../primitives/layout'
|
|
24
26
|
import { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'
|
|
25
27
|
|
|
26
28
|
export const IsInOverflowContext = createContext(false)
|
|
@@ -41,10 +43,24 @@ const NUMBERED_SHORTCUT_KEYS: Record<string, number> = {
|
|
|
41
43
|
/** @public */
|
|
42
44
|
export interface OverflowingToolbarProps {
|
|
43
45
|
children: React.ReactNode
|
|
46
|
+
orientation: 'horizontal' | 'vertical'
|
|
47
|
+
sizingParentClassName: string
|
|
48
|
+
minItems: number
|
|
49
|
+
minSizePx: number
|
|
50
|
+
maxItems: number
|
|
51
|
+
maxSizePx: number
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
/** @public @react */
|
|
47
|
-
export function OverflowingToolbar({
|
|
55
|
+
export function OverflowingToolbar({
|
|
56
|
+
children,
|
|
57
|
+
orientation,
|
|
58
|
+
sizingParentClassName,
|
|
59
|
+
minItems,
|
|
60
|
+
minSizePx,
|
|
61
|
+
maxItems,
|
|
62
|
+
maxSizePx,
|
|
63
|
+
}: OverflowingToolbarProps) {
|
|
48
64
|
const editor = useEditor()
|
|
49
65
|
const id = useUniqueSafeId()
|
|
50
66
|
const breakpoint = useBreakpoint()
|
|
@@ -52,63 +68,165 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
52
68
|
const rButtons = useRef<HTMLElement[]>([])
|
|
53
69
|
const [isOpen, setIsOpen] = useState(false)
|
|
54
70
|
|
|
55
|
-
const overflowIndex = Math.min(8, 5 + breakpoint)
|
|
56
|
-
|
|
57
|
-
const [totalItems, setTotalItems] = useState(0)
|
|
58
71
|
const mainToolsRef = useRef<HTMLDivElement>(null)
|
|
59
|
-
const [lastActiveOverflowItem, setLastActiveOverflowItem] = useState<string | null>(null)
|
|
60
72
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
display: none;
|
|
67
|
-
}
|
|
68
|
-
#${id}_more > *:nth-of-type(-n + ${overflowIndex}):not([data-radix-popper-content-wrapper]) {
|
|
69
|
-
display: none;
|
|
70
|
-
}
|
|
71
|
-
`
|
|
72
|
-
}, [lastActiveOverflowItem, id, overflowIndex])
|
|
73
|
+
// we have to use state instead of a ref here so that we get
|
|
74
|
+
// an update when the overflow popover mounts / unmounts
|
|
75
|
+
const [overflowTools, setOverflowTools] = useState<HTMLDivElement | null>(null)
|
|
76
|
+
const [lastActiveOverflowItem, setLastActiveOverflowItem] = useState<string | null>(null)
|
|
77
|
+
const [shouldShowOverflow, setShouldShowOverflow] = useState(false)
|
|
73
78
|
|
|
74
79
|
const onDomUpdate = useEvent(() => {
|
|
75
80
|
if (!mainToolsRef.current) return
|
|
76
81
|
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
// whenever we get an update, we need to re-calculate the number of items to show and update
|
|
83
|
+
// the component accordingly.
|
|
84
|
+
const sizeProp = orientation === 'horizontal' ? 'offsetWidth' : 'offsetHeight'
|
|
79
85
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
// toolbars can contain both single items and groups. we need to keep track of both.
|
|
87
|
+
type Items = (
|
|
88
|
+
| { type: 'item'; element: HTMLElement }
|
|
89
|
+
| { type: 'group'; items: Items; element: HTMLElement }
|
|
90
|
+
)[]
|
|
91
|
+
|
|
92
|
+
// walk through the dom and collect items so we can calculate what to show/hide
|
|
93
|
+
const mainItems = collectItems(mainToolsRef.current.children)
|
|
94
|
+
const overflowItems = overflowTools ? collectItems(overflowTools.children) : null
|
|
95
|
+
function collectItems(collection: HTMLCollection) {
|
|
96
|
+
const items: Items = []
|
|
97
|
+
for (const child of collection) {
|
|
98
|
+
if (child.classList.contains('tlui-main-toolbar__group')) {
|
|
99
|
+
items.push({
|
|
100
|
+
type: 'group',
|
|
101
|
+
items: collectItems(child.children),
|
|
102
|
+
element: child as HTMLElement,
|
|
103
|
+
})
|
|
104
|
+
} else {
|
|
105
|
+
items.push({ type: 'item', element: child as HTMLElement })
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return items
|
|
86
110
|
}
|
|
87
111
|
|
|
88
|
-
//
|
|
89
|
-
const
|
|
90
|
-
|
|
112
|
+
// the number of items to show is based on the space available to the toolbar.
|
|
113
|
+
const sizingParent = findParentWithClassName(mainToolsRef.current, sizingParentClassName)
|
|
114
|
+
const size = sizingParent[sizeProp]
|
|
115
|
+
const itemsToShow = Math.floor(
|
|
116
|
+
modulate(size, [minSizePx, maxSizePx], [minItems, maxItems], true)
|
|
91
117
|
)
|
|
92
|
-
if (activeElementIdx === -1) return
|
|
93
118
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
119
|
+
// now we know how many items to show, we need to walk through the items we found and show /
|
|
120
|
+
// hide them accordingly. We need to keep track of:
|
|
121
|
+
// the number of item's we've shown in the main content so far
|
|
122
|
+
let mainItemCount = 0
|
|
123
|
+
// the item that is currently active in the overflow content (if any)
|
|
124
|
+
let newActiveOverflowItem: string | null = null
|
|
125
|
+
// whether the last active overflow item is actually still in the overflow content
|
|
126
|
+
let shouldInvalidateLastActiveOverflowItem = false
|
|
127
|
+
// the buttons visible in the main content
|
|
128
|
+
const numberedButtons: HTMLButtonElement[] = []
|
|
129
|
+
function visitItems(
|
|
130
|
+
mainItems: Items,
|
|
131
|
+
overflowItems: Items | null
|
|
132
|
+
): {
|
|
133
|
+
// for each group of items we visit, we need to know whether we showed anything in
|
|
134
|
+
// either section
|
|
135
|
+
didShowAnyInMain: boolean
|
|
136
|
+
didShowAnyInOverflow: boolean
|
|
137
|
+
} {
|
|
138
|
+
if (overflowItems) assert(mainItems.length === overflowItems.length)
|
|
139
|
+
|
|
140
|
+
let didShowAnyInMain = false
|
|
141
|
+
let didShowAnyInOverflow = false
|
|
142
|
+
|
|
143
|
+
for (let i = 0; i < mainItems.length; i++) {
|
|
144
|
+
const mainItem = mainItems[i]
|
|
145
|
+
const overflowItem = overflowItems?.[i]
|
|
146
|
+
|
|
147
|
+
if (mainItem.type === 'item') {
|
|
148
|
+
const isLastActiveOverflowItem =
|
|
149
|
+
mainItem.element.getAttribute('data-value') === lastActiveOverflowItem
|
|
150
|
+
|
|
151
|
+
// for single items, we show them in main if we have space, or if they're the
|
|
152
|
+
// last-used item from the overflow.
|
|
153
|
+
let shouldShowInMain
|
|
154
|
+
if (lastActiveOverflowItem) {
|
|
155
|
+
shouldShowInMain = mainItemCount < itemsToShow || isLastActiveOverflowItem
|
|
156
|
+
} else {
|
|
157
|
+
// we use <= here because if there is no last active overflow item, we want
|
|
158
|
+
// to show at least one item in the main toolbar.
|
|
159
|
+
shouldShowInMain = mainItemCount <= itemsToShow
|
|
160
|
+
}
|
|
161
|
+
const shouldShowInOverflow = mainItemCount >= itemsToShow
|
|
98
162
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
(el): el is HTMLElement => {
|
|
102
|
-
// only count html elements...
|
|
103
|
-
if (!(el instanceof HTMLElement)) return false
|
|
163
|
+
didShowAnyInMain ||= shouldShowInMain
|
|
164
|
+
didShowAnyInOverflow ||= shouldShowInOverflow
|
|
104
165
|
|
|
105
|
-
|
|
106
|
-
|
|
166
|
+
setAttribute(
|
|
167
|
+
mainItem.element,
|
|
168
|
+
'data-toolbar-visible',
|
|
169
|
+
shouldShowInMain ? 'true' : 'false'
|
|
170
|
+
)
|
|
171
|
+
if (overflowItem) {
|
|
172
|
+
assert(overflowItem.type === 'item')
|
|
173
|
+
setAttribute(
|
|
174
|
+
overflowItem.element,
|
|
175
|
+
'data-toolbar-visible',
|
|
176
|
+
shouldShowInOverflow ? 'true' : 'false'
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
if (shouldShowInOverflow && mainItem.element.getAttribute('aria-pressed') === 'true') {
|
|
180
|
+
newActiveOverflowItem = mainItem.element.getAttribute('data-value')
|
|
181
|
+
}
|
|
182
|
+
if (shouldShowInMain && mainItem.element.tagName === 'BUTTON') {
|
|
183
|
+
numberedButtons.push(mainItem.element as HTMLButtonElement)
|
|
184
|
+
}
|
|
185
|
+
if (!shouldShowInOverflow && isLastActiveOverflowItem) {
|
|
186
|
+
shouldInvalidateLastActiveOverflowItem = true
|
|
187
|
+
}
|
|
188
|
+
mainItemCount++
|
|
189
|
+
} else {
|
|
190
|
+
// for groups, we show them in main if we have space, or if they're the
|
|
191
|
+
// last-used item from the overflow.
|
|
192
|
+
let result, overflowGroup
|
|
193
|
+
if (overflowItem) {
|
|
194
|
+
assert(overflowItem.type === 'group')
|
|
195
|
+
overflowGroup = overflowItem
|
|
196
|
+
result = visitItems(mainItem.items, overflowGroup.items)
|
|
197
|
+
} else {
|
|
198
|
+
result = visitItems(mainItem.items, null)
|
|
199
|
+
}
|
|
107
200
|
|
|
108
|
-
|
|
109
|
-
|
|
201
|
+
didShowAnyInMain ||= result.didShowAnyInMain
|
|
202
|
+
didShowAnyInOverflow ||= result.didShowAnyInOverflow
|
|
203
|
+
|
|
204
|
+
setAttribute(
|
|
205
|
+
mainItem.element,
|
|
206
|
+
'data-toolbar-visible',
|
|
207
|
+
result.didShowAnyInMain ? 'true' : 'false'
|
|
208
|
+
)
|
|
209
|
+
if (overflowGroup) {
|
|
210
|
+
setAttribute(
|
|
211
|
+
overflowGroup.element,
|
|
212
|
+
'data-toolbar-visible',
|
|
213
|
+
result.didShowAnyInOverflow ? 'true' : 'false'
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
}
|
|
110
217
|
}
|
|
111
|
-
|
|
218
|
+
return { didShowAnyInMain, didShowAnyInOverflow }
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const { didShowAnyInOverflow } = visitItems(mainItems, overflowItems)
|
|
222
|
+
setShouldShowOverflow(didShowAnyInOverflow)
|
|
223
|
+
if (newActiveOverflowItem) {
|
|
224
|
+
setLastActiveOverflowItem(newActiveOverflowItem)
|
|
225
|
+
} else if (shouldInvalidateLastActiveOverflowItem) {
|
|
226
|
+
setLastActiveOverflowItem(null)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
rButtons.current = numberedButtons
|
|
112
230
|
})
|
|
113
231
|
|
|
114
232
|
useLayoutEffect(() => {
|
|
@@ -122,20 +240,31 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
122
240
|
mutationObserver.observe(mainToolsRef.current, {
|
|
123
241
|
childList: true,
|
|
124
242
|
subtree: true,
|
|
125
|
-
|
|
243
|
+
attributes: true,
|
|
244
|
+
characterData: true,
|
|
126
245
|
})
|
|
127
246
|
|
|
247
|
+
const sizingParent = findParentWithClassName(mainToolsRef.current, sizingParentClassName)
|
|
248
|
+
const resizeObserver = new ResizeObserver(onDomUpdate)
|
|
249
|
+
resizeObserver.observe(sizingParent)
|
|
250
|
+
|
|
128
251
|
return () => {
|
|
129
252
|
mutationObserver.disconnect()
|
|
253
|
+
resizeObserver.disconnect()
|
|
130
254
|
}
|
|
131
|
-
}, [onDomUpdate])
|
|
255
|
+
}, [onDomUpdate, sizingParentClassName])
|
|
132
256
|
|
|
133
257
|
useEffect(() => {
|
|
134
258
|
if (!editor.options.enableToolbarKeyboardShortcuts) return
|
|
135
259
|
|
|
136
260
|
function handleKeyDown(event: KeyboardEvent) {
|
|
137
|
-
if (
|
|
261
|
+
if (
|
|
262
|
+
areShortcutsDisabled(editor) ||
|
|
263
|
+
activeElementShouldCaptureKeys(true /* allow buttons */)
|
|
264
|
+
) {
|
|
138
265
|
return
|
|
266
|
+
}
|
|
267
|
+
|
|
139
268
|
// no accelerator keys
|
|
140
269
|
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) return
|
|
141
270
|
const index = NUMBERED_SHORTCUT_KEYS[event.key]
|
|
@@ -152,23 +281,23 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
152
281
|
}, [editor])
|
|
153
282
|
|
|
154
283
|
const popoverId = 'toolbar overflow'
|
|
284
|
+
|
|
285
|
+
const Layout = orientation === 'horizontal' ? TldrawUiRow : TldrawUiColumn
|
|
155
286
|
return (
|
|
156
287
|
<>
|
|
157
|
-
<style nonce={editor.options.nonce}>{css}</style>
|
|
158
288
|
<TldrawUiToolbar
|
|
159
|
-
orientation=
|
|
289
|
+
orientation={orientation}
|
|
160
290
|
className={classNames('tlui-main-toolbar__tools', {
|
|
161
291
|
'tlui-main-toolbar__tools__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,
|
|
162
292
|
})}
|
|
163
293
|
label={msg('tool-panel.title')}
|
|
164
294
|
>
|
|
165
|
-
<
|
|
295
|
+
<Layout id={`${id}_main`} ref={mainToolsRef}>
|
|
166
296
|
<TldrawUiMenuContextProvider type="toolbar" sourceId="toolbar">
|
|
167
297
|
{children}
|
|
168
298
|
</TldrawUiMenuContextProvider>
|
|
169
|
-
</
|
|
170
|
-
{
|
|
171
|
-
{totalItems > overflowIndex + 1 && (
|
|
299
|
+
</Layout>
|
|
300
|
+
{shouldShowOverflow && (
|
|
172
301
|
<IsInOverflowContext.Provider value={true}>
|
|
173
302
|
<TldrawUiPopover id={popoverId} open={isOpen} onOpenChange={setIsOpen}>
|
|
174
303
|
<TldrawUiPopoverTrigger>
|
|
@@ -178,12 +307,19 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
178
307
|
className="tlui-main-toolbar__overflow"
|
|
179
308
|
data-testid="tools.more-button"
|
|
180
309
|
>
|
|
181
|
-
<TldrawUiButtonIcon
|
|
310
|
+
<TldrawUiButtonIcon
|
|
311
|
+
icon={orientation === 'horizontal' ? 'chevron-up' : 'chevron-right'}
|
|
312
|
+
/>
|
|
182
313
|
</TldrawUiToolbarButton>
|
|
183
314
|
</TldrawUiPopoverTrigger>
|
|
184
|
-
<TldrawUiPopoverContent
|
|
315
|
+
<TldrawUiPopoverContent
|
|
316
|
+
side={orientation === 'horizontal' ? 'top' : 'right'}
|
|
317
|
+
align={orientation === 'horizontal' ? 'center' : 'end'}
|
|
318
|
+
>
|
|
185
319
|
<TldrawUiToolbar
|
|
186
320
|
orientation="grid"
|
|
321
|
+
className="tlui-main-toolbar__overflow-content"
|
|
322
|
+
ref={setOverflowTools}
|
|
187
323
|
data-testid="tools.more-content"
|
|
188
324
|
label={msg('tool-panel.more')}
|
|
189
325
|
id={`${id}_more`}
|
|
@@ -214,3 +350,19 @@ export const isActiveTLUiToolItem = (
|
|
|
214
350
|
? activeToolId === 'geo' && geoState === item.meta?.geo
|
|
215
351
|
: activeToolId === item.id
|
|
216
352
|
}
|
|
353
|
+
|
|
354
|
+
function findParentWithClassName(startingElement: HTMLElement, className: string): HTMLElement {
|
|
355
|
+
let element: HTMLElement | null = startingElement
|
|
356
|
+
while (element) {
|
|
357
|
+
if (element.classList.contains(className)) {
|
|
358
|
+
return element
|
|
359
|
+
}
|
|
360
|
+
element = element.parentElement
|
|
361
|
+
}
|
|
362
|
+
throw new Error('Could not find parent with class name ' + className)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function setAttribute(element: HTMLElement, name: string, value: string) {
|
|
366
|
+
if (element.getAttribute(name) === value) return
|
|
367
|
+
element.setAttribute(name, value)
|
|
368
|
+
}
|
|
@@ -172,7 +172,12 @@ export const TldrawUiContextualToolbar = ({
|
|
|
172
172
|
className={classNames('tlui-contextual-toolbar', className)}
|
|
173
173
|
onPointerDown={stopEventPropagation}
|
|
174
174
|
>
|
|
175
|
-
<TldrawUiToolbar
|
|
175
|
+
<TldrawUiToolbar
|
|
176
|
+
orientation="horizontal"
|
|
177
|
+
className="tlui-menu"
|
|
178
|
+
label={label}
|
|
179
|
+
tooltipSide="top"
|
|
180
|
+
>
|
|
176
181
|
{children}
|
|
177
182
|
</TldrawUiToolbar>
|
|
178
183
|
</div>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { tltime } from '@tldraw/editor'
|
|
1
2
|
import { Slider as _Slider } from 'radix-ui'
|
|
2
3
|
import React, { useCallback, useEffect, useState } from 'react'
|
|
3
4
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
|
4
5
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
6
|
+
import { TldrawUiTooltip, tooltipManager } from './TldrawUiTooltip'
|
|
5
7
|
|
|
6
8
|
/** @public */
|
|
7
9
|
export interface TLUiSliderProps {
|
|
@@ -11,7 +13,7 @@ export interface TLUiSliderProps {
|
|
|
11
13
|
label: string
|
|
12
14
|
title: string
|
|
13
15
|
onValueChange(value: number): void
|
|
14
|
-
onHistoryMark(id: string): void
|
|
16
|
+
onHistoryMark?(id: string): void
|
|
15
17
|
'data-testid'?: string
|
|
16
18
|
ariaValueModifier?: number
|
|
17
19
|
}
|
|
@@ -32,6 +34,7 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
|
|
|
32
34
|
ref
|
|
33
35
|
) {
|
|
34
36
|
const msg = useTranslation()
|
|
37
|
+
const [titleAndLabel, setTitleAndLabel] = useState('')
|
|
35
38
|
|
|
36
39
|
// XXX: Radix starts out our slider with a tabIndex of 0
|
|
37
40
|
// This causes some tab focusing issues, most prevelant in MobileStylePanel,
|
|
@@ -49,9 +52,25 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
|
|
|
49
52
|
)
|
|
50
53
|
|
|
51
54
|
const handlePointerDown = useCallback(() => {
|
|
52
|
-
|
|
55
|
+
tooltipManager.hideAllTooltips()
|
|
56
|
+
onHistoryMark?.('click slider')
|
|
53
57
|
}, [onHistoryMark])
|
|
54
58
|
|
|
59
|
+
// N.B. This is a bit silly. The Radix slider auto-focuses which
|
|
60
|
+
// triggers TldrawUiTooltip handleFocus when we dbl-click to edit an image,
|
|
61
|
+
// which in turn makes the tooltip display prematurely.
|
|
62
|
+
// This makes it wait until we've focused to show the tooltip.
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const timeout = tltime.setTimeout(
|
|
65
|
+
'set title and label',
|
|
66
|
+
() => {
|
|
67
|
+
setTitleAndLabel(title + ' — ' + msg(label as TLUiTranslationKey))
|
|
68
|
+
},
|
|
69
|
+
0
|
|
70
|
+
)
|
|
71
|
+
return () => clearTimeout(timeout)
|
|
72
|
+
}, [label, msg, title])
|
|
73
|
+
|
|
55
74
|
// N.B. Annoying. For a11y purposes, we need Tab to work.
|
|
56
75
|
// For some reason, Radix has some custom behavior here
|
|
57
76
|
// that interferes with tabbing past the slider and then
|
|
@@ -64,36 +83,37 @@ export const TldrawUiSlider = React.forwardRef<HTMLDivElement, TLUiSliderProps>(
|
|
|
64
83
|
|
|
65
84
|
return (
|
|
66
85
|
<div className="tlui-slider__container">
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
<TldrawUiTooltip content={titleAndLabel}>
|
|
87
|
+
<_Slider.Root
|
|
88
|
+
data-testid={testId}
|
|
89
|
+
className="tlui-slider"
|
|
90
|
+
dir="ltr"
|
|
91
|
+
min={min ?? 0}
|
|
92
|
+
max={steps}
|
|
93
|
+
step={1}
|
|
94
|
+
value={value !== null ? [value] : undefined}
|
|
95
|
+
onPointerDown={handlePointerDown}
|
|
96
|
+
onValueChange={handleValueChange}
|
|
97
|
+
onKeyDownCapture={handleKeyEvent}
|
|
98
|
+
onKeyUpCapture={handleKeyEvent}
|
|
99
|
+
>
|
|
100
|
+
<_Slider.Track className="tlui-slider__track" dir="ltr">
|
|
101
|
+
{value !== null && <_Slider.Range className="tlui-slider__range" dir="ltr" />}
|
|
102
|
+
</_Slider.Track>
|
|
103
|
+
{value !== null && (
|
|
104
|
+
<_Slider.Thumb
|
|
105
|
+
aria-valuemin={(min ?? 0) * ariaValueModifier}
|
|
106
|
+
aria-valuenow={value * ariaValueModifier}
|
|
107
|
+
aria-valuemax={steps * ariaValueModifier}
|
|
108
|
+
aria-label={titleAndLabel}
|
|
109
|
+
className="tlui-slider__thumb"
|
|
110
|
+
dir="ltr"
|
|
111
|
+
ref={ref}
|
|
112
|
+
tabIndex={tabIndex}
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
115
|
+
</_Slider.Root>
|
|
116
|
+
</TldrawUiTooltip>
|
|
97
117
|
</div>
|
|
98
118
|
)
|
|
99
119
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import classnames from 'classnames'
|
|
2
2
|
import { Toolbar as _Toolbar } from 'radix-ui'
|
|
3
3
|
import React from 'react'
|
|
4
|
-
import { TldrawUiGrid, TldrawUiRow } from './layout'
|
|
4
|
+
import { TldrawUiColumn, TldrawUiGrid, TldrawUiRow } from './layout'
|
|
5
5
|
import { TldrawUiTooltip } from './TldrawUiTooltip'
|
|
6
6
|
|
|
7
7
|
/** @public */
|
|
@@ -10,15 +10,32 @@ export interface TLUiToolbarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
10
10
|
className?: string
|
|
11
11
|
dir?: 'ltr' | 'rtl'
|
|
12
12
|
label: string
|
|
13
|
-
orientation?: 'horizontal' | 'grid'
|
|
13
|
+
orientation?: 'horizontal' | 'vertical' | 'grid'
|
|
14
|
+
tooltipSide?: 'top' | 'right' | 'bottom' | 'left'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const LayoutByOrientation = {
|
|
18
|
+
horizontal: TldrawUiRow,
|
|
19
|
+
vertical: TldrawUiColumn,
|
|
20
|
+
grid: TldrawUiGrid,
|
|
14
21
|
}
|
|
15
22
|
|
|
16
23
|
/** @public @react */
|
|
17
24
|
export const TldrawUiToolbar = React.forwardRef<HTMLDivElement, TLUiToolbarProps>(
|
|
18
|
-
(
|
|
19
|
-
|
|
25
|
+
(
|
|
26
|
+
{
|
|
27
|
+
children,
|
|
28
|
+
className,
|
|
29
|
+
label,
|
|
30
|
+
orientation = 'horizontal',
|
|
31
|
+
tooltipSide,
|
|
32
|
+
...props
|
|
33
|
+
}: TLUiToolbarProps,
|
|
34
|
+
ref
|
|
35
|
+
) => {
|
|
36
|
+
const Layout = LayoutByOrientation[orientation]
|
|
20
37
|
return (
|
|
21
|
-
<Layout asChild>
|
|
38
|
+
<Layout asChild tooltipSide={tooltipSide}>
|
|
22
39
|
<_Toolbar.Root
|
|
23
40
|
ref={ref}
|
|
24
41
|
{...props}
|
|
@@ -77,6 +94,7 @@ export interface TLUiToolbarToggleGroupProps extends React.HTMLAttributes<HTMLDi
|
|
|
77
94
|
// TODO: fix up this type later
|
|
78
95
|
defaultValue?: any
|
|
79
96
|
type: 'single' | 'multiple'
|
|
97
|
+
asChild?: boolean
|
|
80
98
|
}
|
|
81
99
|
|
|
82
100
|
/** @public @react */
|
|
@@ -84,10 +102,12 @@ export const TldrawUiToolbarToggleGroup = ({
|
|
|
84
102
|
children,
|
|
85
103
|
className,
|
|
86
104
|
type,
|
|
105
|
+
asChild,
|
|
87
106
|
...props
|
|
88
107
|
}: TLUiToolbarToggleGroupProps) => {
|
|
89
108
|
return (
|
|
90
109
|
<_Toolbar.ToggleGroup
|
|
110
|
+
asChild={asChild}
|
|
91
111
|
type={type}
|
|
92
112
|
{...props}
|
|
93
113
|
// TODO: this fixes a bug in Radix until they fix it.
|