tldraw 3.16.0-canary.ffdf566dd0a8 → 3.16.0-internal.51e99e128bd4
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 +173 -5
- package/dist-cjs/index.js +12 -1
- package/dist-cjs/index.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/shapes/arrow/ArrowShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
- 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/draw/DrawShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
- 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 -12
- 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 +2 -2
- package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js +2 -1
- package/dist-cjs/lib/shapes/geo/components/GeoShapeBody.js.map +2 -2
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +5 -1
- package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -3
- package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +1 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js +5 -1
- package/dist-cjs/lib/shapes/line/LineShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -4
- package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/ShapeFill.js +4 -4
- 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/text/TextShapeUtil.js +2 -2
- package/dist-cjs/lib/shapes/text/TextShapeUtil.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/tools/SelectTool/childStates/Translating.js.map +2 -2
- package/dist-cjs/lib/ui/TldrawUi.js +14 -0
- 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 +12 -3
- package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/DefaultMenuPanel.js +3 -2
- package/dist-cjs/lib/ui/components/DefaultMenuPanel.js.map +2 -2
- 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 +5 -3
- package/dist-cjs/lib/ui/components/MobileStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js +1 -1
- package/dist-cjs/lib/ui/components/NavigationPanel/DefaultNavigationPanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js +2 -1
- package/dist-cjs/lib/ui/components/PageMenu/DefaultPageMenu.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js +3 -2
- package/dist-cjs/lib/ui/components/SharePanel/PeopleMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js +2 -2
- package/dist-cjs/lib/ui/components/SharePanel/UserPresenceColorPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +14 -14
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js +3 -3
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js +26 -25
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js +1 -1
- package/dist-cjs/lib/ui/components/Toolbar/DefaultImageToolbarContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js +66 -21
- package/dist-cjs/lib/ui/components/Toolbar/DefaultToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js +189 -80
- package/dist-cjs/lib/ui/components/Toolbar/OverflowingToolbar.js.map +3 -3
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js +2 -2
- package/dist-cjs/lib/ui/components/Toolbar/ToggleToolLockedButton.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js +5 -16
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +3 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js +1 -1
- package/dist-cjs/lib/ui/components/primitives/TldrawUiContextualToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +3 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +3 -3
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +19 -4
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +153 -152
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/layout.js +76 -0
- package/dist-cjs/lib/ui/components/primitives/layout.js.map +7 -0
- 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 +154 -20
- package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
- package/dist-cjs/lib/ui/context/events.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useTools.js +94 -9
- package/dist-cjs/lib/ui/hooks/useTools.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-esm/index.d.mts +173 -5
- package/dist-esm/index.mjs +19 -1
- package/dist-esm/index.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/shapes/arrow/ArrowShapeUtil.mjs +4 -3
- package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
- 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/draw/DrawShapeUtil.mjs +4 -3
- package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
- 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 +13 -12
- 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 +3 -2
- package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs +2 -1
- package/dist-esm/lib/shapes/geo/components/GeoShapeBody.mjs.map +2 -2
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +6 -1
- package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -3
- package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +1 -1
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs +6 -1
- package/dist-esm/lib/shapes/line/LineShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +5 -4
- package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/ShapeFill.mjs +5 -4
- 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/text/TextShapeUtil.mjs +3 -2
- package/dist-esm/lib/shapes/text/TextShapeUtil.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/tools/SelectTool/childStates/Translating.mjs.map +2 -2
- package/dist-esm/lib/ui/TldrawUi.mjs +16 -2
- 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 +12 -3
- package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs +3 -2
- package/dist-esm/lib/ui/components/DefaultMenuPanel.mjs.map +2 -2
- 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 +6 -3
- package/dist-esm/lib/ui/components/MobileStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs +1 -1
- package/dist-esm/lib/ui/components/NavigationPanel/DefaultNavigationPanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs +2 -1
- package/dist-esm/lib/ui/components/PageMenu/DefaultPageMenu.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs +3 -2
- package/dist-esm/lib/ui/components/SharePanel/PeopleMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs +2 -2
- package/dist-esm/lib/ui/components/SharePanel/UserPresenceColorPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +14 -14
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs +3 -3
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs +26 -25
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs +1 -1
- package/dist-esm/lib/ui/components/Toolbar/DefaultImageToolbarContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs +56 -21
- package/dist-esm/lib/ui/components/Toolbar/DefaultToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs +192 -81
- package/dist-esm/lib/ui/components/Toolbar/OverflowingToolbar.mjs.map +3 -3
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs +2 -2
- package/dist-esm/lib/ui/components/Toolbar/ToggleToolLockedButton.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs +6 -6
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs +1 -1
- package/dist-esm/lib/ui/components/primitives/TldrawUiContextualToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +3 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +19 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +162 -154
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/layout.mjs +46 -0
- package/dist-esm/lib/ui/components/primitives/layout.mjs.map +7 -0
- 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 +162 -22
- package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
- package/dist-esm/lib/ui/context/events.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useTools.mjs +102 -10
- package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/package.json +11 -34
- package/src/index.ts +15 -0
- package/src/lib/canvas/TldrawScribble.tsx +1 -1
- package/src/lib/shapes/arrow/ArrowShapeOptions.test.ts +2 -1
- package/src/lib/shapes/arrow/ArrowShapeTool.test.ts +4 -3
- package/src/lib/shapes/arrow/ArrowShapeUtil.test.ts +7 -6
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
- package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
- package/src/lib/shapes/draw/DrawShapeTool.test.ts +0 -5
- package/src/lib/shapes/draw/DrawShapeUtil.tsx +4 -3
- package/src/lib/shapes/embed/EmbedShapeUtil.tsx +1 -1
- package/src/lib/shapes/frame/FrameShapeUtil.tsx +21 -14
- package/src/lib/shapes/frame/components/FrameHeading.tsx +1 -1
- package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -2
- package/src/lib/shapes/geo/components/GeoShapeBody.tsx +2 -2
- package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +7 -1
- package/src/lib/shapes/image/ImageShapeUtil.tsx +3 -3
- package/src/lib/shapes/line/LineShapeUtil.test.tsx +4 -3
- package/src/lib/shapes/line/LineShapeUtil.tsx +6 -1
- package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.tsx.snap +2 -2
- package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
- package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
- package/src/lib/shapes/shared/freehand/svg.ts +2 -0
- package/src/lib/shapes/text/TextShapeTool.test.ts +6 -5
- package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
- 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/tools/SelectTool/childStates/Translating.ts +0 -1
- package/src/lib/ui/TldrawUi.tsx +17 -2
- package/src/lib/ui/assetUrls.ts +13 -10
- package/src/lib/ui/components/ActionsMenu/DefaultActionsMenu.tsx +15 -3
- package/src/lib/ui/components/DefaultMenuPanel.tsx +4 -3
- package/src/lib/ui/components/Minimap/MinimapManager.ts +4 -4
- package/src/lib/ui/components/MobileStylePanel.tsx +9 -6
- package/src/lib/ui/components/NavigationPanel/DefaultNavigationPanel.tsx +1 -1
- package/src/lib/ui/components/PageMenu/DefaultPageMenu.tsx +3 -2
- package/src/lib/ui/components/SharePanel/PeopleMenuItem.tsx +4 -3
- package/src/lib/ui/components/SharePanel/UserPresenceColorPicker.tsx +3 -3
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +39 -43
- package/src/lib/ui/components/StylePanel/DoubleDropdownPicker.tsx +3 -3
- package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +7 -6
- package/src/lib/ui/components/Toolbar/DefaultImageToolbarContent.tsx +1 -1
- package/src/lib/ui/components/Toolbar/DefaultToolbar.tsx +55 -23
- package/src/lib/ui/components/Toolbar/OverflowingToolbar.tsx +212 -61
- package/src/lib/ui/components/Toolbar/ToggleToolLockedButton.tsx +2 -2
- package/src/lib/ui/components/primitives/TldrawUiButtonPicker.tsx +40 -37
- package/src/lib/ui/components/primitives/TldrawUiContextualToolbar.tsx +1 -1
- package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +4 -2
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +32 -9
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +186 -172
- package/src/lib/ui/components/primitives/layout.tsx +107 -0
- 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 +221 -19
- package/src/lib/ui/context/events.tsx +1 -0
- package/src/lib/ui/hooks/useTools.tsx +140 -10
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +363 -305
- package/src/lib/utils/excalidraw/__snapshots__/putExcalidrawContent.test.tsx.snap +5 -5
- 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/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 +3 -2
- 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 +656 -595
|
@@ -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,6 +22,7 @@ import {
|
|
|
20
22
|
TldrawUiPopoverTrigger,
|
|
21
23
|
} from '../primitives/TldrawUiPopover'
|
|
22
24
|
import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
25
|
+
import { TldrawUiColumn, TldrawUiRow } from '../primitives/layout'
|
|
23
26
|
import { TldrawUiMenuContextProvider } from '../primitives/menus/TldrawUiMenuContext'
|
|
24
27
|
|
|
25
28
|
export const IsInOverflowContext = createContext(false)
|
|
@@ -40,10 +43,24 @@ const NUMBERED_SHORTCUT_KEYS: Record<string, number> = {
|
|
|
40
43
|
/** @public */
|
|
41
44
|
export interface OverflowingToolbarProps {
|
|
42
45
|
children: React.ReactNode
|
|
46
|
+
orientation: 'horizontal' | 'vertical'
|
|
47
|
+
sizingParentClassName: string
|
|
48
|
+
minItems: number
|
|
49
|
+
minSizePx: number
|
|
50
|
+
maxItems: number
|
|
51
|
+
maxSizePx: number
|
|
43
52
|
}
|
|
44
53
|
|
|
45
54
|
/** @public @react */
|
|
46
|
-
export function OverflowingToolbar({
|
|
55
|
+
export function OverflowingToolbar({
|
|
56
|
+
children,
|
|
57
|
+
orientation,
|
|
58
|
+
sizingParentClassName,
|
|
59
|
+
minItems,
|
|
60
|
+
minSizePx,
|
|
61
|
+
maxItems,
|
|
62
|
+
maxSizePx,
|
|
63
|
+
}: OverflowingToolbarProps) {
|
|
47
64
|
const editor = useEditor()
|
|
48
65
|
const id = useUniqueSafeId()
|
|
49
66
|
const breakpoint = useBreakpoint()
|
|
@@ -51,66 +68,165 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
51
68
|
const rButtons = useRef<HTMLElement[]>([])
|
|
52
69
|
const [isOpen, setIsOpen] = useState(false)
|
|
53
70
|
|
|
54
|
-
const overflowIndex = Math.min(8, 5 + breakpoint)
|
|
55
|
-
|
|
56
|
-
const [totalItems, setTotalItems] = useState(0)
|
|
57
71
|
const mainToolsRef = useRef<HTMLDivElement>(null)
|
|
58
|
-
const [lastActiveOverflowItem, setLastActiveOverflowItem] = useState<string | null>(null)
|
|
59
|
-
|
|
60
|
-
const css = useMemo(() => {
|
|
61
|
-
const activeCss = lastActiveOverflowItem ? `:not([data-value="${lastActiveOverflowItem}"])` : ''
|
|
62
72
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
display: none;
|
|
69
|
-
}
|
|
70
|
-
#${id}_more > *:nth-of-type(-n + ${overflowIndex + 4}):not([data-radix-popper-content-wrapper]) {
|
|
71
|
-
margin-top: 0;
|
|
72
|
-
}
|
|
73
|
-
`
|
|
74
|
-
}, [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)
|
|
75
78
|
|
|
76
79
|
const onDomUpdate = useEvent(() => {
|
|
77
80
|
if (!mainToolsRef.current) return
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
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'
|
|
81
85
|
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
88
110
|
}
|
|
89
111
|
|
|
90
|
-
//
|
|
91
|
-
const
|
|
92
|
-
|
|
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)
|
|
93
117
|
)
|
|
94
|
-
if (activeElementIdx === -1) return
|
|
95
118
|
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
|
100
162
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
(el): el is HTMLElement => {
|
|
104
|
-
// only count html elements...
|
|
105
|
-
if (!(el instanceof HTMLElement)) return false
|
|
163
|
+
didShowAnyInMain ||= shouldShowInMain
|
|
164
|
+
didShowAnyInOverflow ||= shouldShowInOverflow
|
|
106
165
|
|
|
107
|
-
|
|
108
|
-
|
|
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
|
+
}
|
|
109
200
|
|
|
110
|
-
|
|
111
|
-
|
|
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
|
+
}
|
|
112
217
|
}
|
|
113
|
-
|
|
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
|
|
114
230
|
})
|
|
115
231
|
|
|
116
232
|
useLayoutEffect(() => {
|
|
@@ -124,20 +240,31 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
124
240
|
mutationObserver.observe(mainToolsRef.current, {
|
|
125
241
|
childList: true,
|
|
126
242
|
subtree: true,
|
|
127
|
-
|
|
243
|
+
attributes: true,
|
|
244
|
+
characterData: true,
|
|
128
245
|
})
|
|
129
246
|
|
|
247
|
+
const sizingParent = findParentWithClassName(mainToolsRef.current, sizingParentClassName)
|
|
248
|
+
const resizeObserver = new ResizeObserver(onDomUpdate)
|
|
249
|
+
resizeObserver.observe(sizingParent)
|
|
250
|
+
|
|
130
251
|
return () => {
|
|
131
252
|
mutationObserver.disconnect()
|
|
253
|
+
resizeObserver.disconnect()
|
|
132
254
|
}
|
|
133
|
-
}, [onDomUpdate])
|
|
255
|
+
}, [onDomUpdate, sizingParentClassName])
|
|
134
256
|
|
|
135
257
|
useEffect(() => {
|
|
136
258
|
if (!editor.options.enableToolbarKeyboardShortcuts) return
|
|
137
259
|
|
|
138
260
|
function handleKeyDown(event: KeyboardEvent) {
|
|
139
|
-
if (
|
|
261
|
+
if (
|
|
262
|
+
areShortcutsDisabled(editor) ||
|
|
263
|
+
activeElementShouldCaptureKeys(true /* allow buttons */)
|
|
264
|
+
) {
|
|
140
265
|
return
|
|
266
|
+
}
|
|
267
|
+
|
|
141
268
|
// no accelerator keys
|
|
142
269
|
if (event.ctrlKey || event.metaKey || event.altKey || event.shiftKey) return
|
|
143
270
|
const index = NUMBERED_SHORTCUT_KEYS[event.key]
|
|
@@ -154,37 +281,45 @@ export function OverflowingToolbar({ children }: OverflowingToolbarProps) {
|
|
|
154
281
|
}, [editor])
|
|
155
282
|
|
|
156
283
|
const popoverId = 'toolbar overflow'
|
|
284
|
+
|
|
285
|
+
const Layout = orientation === 'horizontal' ? TldrawUiRow : TldrawUiColumn
|
|
157
286
|
return (
|
|
158
287
|
<>
|
|
159
|
-
<style nonce={editor.options.nonce}>{css}</style>
|
|
160
288
|
<TldrawUiToolbar
|
|
161
|
-
|
|
162
|
-
|
|
289
|
+
orientation={orientation}
|
|
290
|
+
className={classNames('tlui-main-toolbar__tools', {
|
|
291
|
+
'tlui-main-toolbar__tools__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,
|
|
163
292
|
})}
|
|
164
293
|
label={msg('tool-panel.title')}
|
|
165
294
|
>
|
|
166
|
-
<
|
|
295
|
+
<Layout id={`${id}_main`} ref={mainToolsRef}>
|
|
167
296
|
<TldrawUiMenuContextProvider type="toolbar" sourceId="toolbar">
|
|
168
297
|
{children}
|
|
169
298
|
</TldrawUiMenuContextProvider>
|
|
170
|
-
</
|
|
171
|
-
{
|
|
172
|
-
{totalItems > overflowIndex + 1 && (
|
|
299
|
+
</Layout>
|
|
300
|
+
{shouldShowOverflow && (
|
|
173
301
|
<IsInOverflowContext.Provider value={true}>
|
|
174
302
|
<TldrawUiPopover id={popoverId} open={isOpen} onOpenChange={setIsOpen}>
|
|
175
303
|
<TldrawUiPopoverTrigger>
|
|
176
304
|
<TldrawUiToolbarButton
|
|
177
305
|
title={msg('tool-panel.more')}
|
|
178
306
|
type="tool"
|
|
179
|
-
className="tlui-toolbar__overflow"
|
|
307
|
+
className="tlui-main-toolbar__overflow"
|
|
180
308
|
data-testid="tools.more-button"
|
|
181
309
|
>
|
|
182
|
-
<TldrawUiButtonIcon
|
|
310
|
+
<TldrawUiButtonIcon
|
|
311
|
+
icon={orientation === 'horizontal' ? 'chevron-up' : 'chevron-right'}
|
|
312
|
+
/>
|
|
183
313
|
</TldrawUiToolbarButton>
|
|
184
314
|
</TldrawUiPopoverTrigger>
|
|
185
|
-
<TldrawUiPopoverContent
|
|
315
|
+
<TldrawUiPopoverContent
|
|
316
|
+
side={orientation === 'horizontal' ? 'top' : 'right'}
|
|
317
|
+
align={orientation === 'horizontal' ? 'center' : 'end'}
|
|
318
|
+
>
|
|
186
319
|
<TldrawUiToolbar
|
|
187
|
-
|
|
320
|
+
orientation="grid"
|
|
321
|
+
className="tlui-main-toolbar__overflow-content"
|
|
322
|
+
ref={setOverflowTools}
|
|
188
323
|
data-testid="tools.more-content"
|
|
189
324
|
label={msg('tool-panel.more')}
|
|
190
325
|
id={`${id}_more`}
|
|
@@ -215,3 +350,19 @@ export const isActiveTLUiToolItem = (
|
|
|
215
350
|
? activeToolId === 'geo' && geoState === item.meta?.geo
|
|
216
351
|
: activeToolId === item.id
|
|
217
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
|
+
}
|
|
@@ -31,8 +31,8 @@ export function ToggleToolLockedButton({ activeToolId }: ToggleToolLockedButtonP
|
|
|
31
31
|
type="normal"
|
|
32
32
|
title={msg('action.toggle-tool-lock')}
|
|
33
33
|
data-testid="tool-lock"
|
|
34
|
-
className={classNames('tlui-toolbar__lock-button', {
|
|
35
|
-
'tlui-toolbar__lock-button__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,
|
|
34
|
+
className={classNames('tlui-main-toolbar__lock-button', {
|
|
35
|
+
'tlui-main-toolbar__lock-button__mobile': breakpoint < PORTRAIT_BREAKPOINT.TABLET_SM,
|
|
36
36
|
})}
|
|
37
37
|
onClick={() => editor.updateInstanceState({ isToolLocked: !isToolLocked })}
|
|
38
38
|
>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DefaultColorStyle,
|
|
3
|
+
getColorValue,
|
|
3
4
|
SharedStyle,
|
|
4
5
|
StyleProp,
|
|
5
6
|
TLDefaultColorStyle,
|
|
6
7
|
TLDefaultColorTheme,
|
|
7
8
|
useEditor,
|
|
8
9
|
} from '@tldraw/editor'
|
|
9
|
-
import
|
|
10
|
-
import { ReactElement, memo, useMemo, useRef } from 'react'
|
|
10
|
+
import { memo, ReactElement, useMemo, useRef } from 'react'
|
|
11
11
|
import { StyleValuesForUi } from '../../../styles'
|
|
12
12
|
import { PORTRAIT_BREAKPOINT } from '../../constants'
|
|
13
13
|
import { useBreakpoint } from '../../context/breakpoints'
|
|
@@ -15,6 +15,7 @@ import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKe
|
|
|
15
15
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
16
16
|
import { TldrawUiButtonIcon } from './Button/TldrawUiButtonIcon'
|
|
17
17
|
import { TldrawUiToolbarToggleGroup, TldrawUiToolbarToggleItem } from './TldrawUiToolbar'
|
|
18
|
+
import { TldrawUiGrid, TldrawUiRow } from './layout'
|
|
18
19
|
|
|
19
20
|
/** @public */
|
|
20
21
|
export interface TLUiButtonPickerProps<T extends string> {
|
|
@@ -116,41 +117,43 @@ export const TldrawUiButtonPicker = memo(function TldrawUiButtonPicker<T extends
|
|
|
116
117
|
}
|
|
117
118
|
}, [editor, breakpoint, value, onHistoryMark, onValueChange, style])
|
|
118
119
|
|
|
120
|
+
const Wrapper = items.length > 4 ? TldrawUiGrid : TldrawUiRow
|
|
121
|
+
|
|
119
122
|
return (
|
|
120
|
-
<
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
</
|
|
123
|
+
<Wrapper asChild>
|
|
124
|
+
<TldrawUiToolbarToggleGroup
|
|
125
|
+
data-testid={`style.${uiType}`}
|
|
126
|
+
type="single"
|
|
127
|
+
value={value.type === 'shared' ? value.value : undefined}
|
|
128
|
+
>
|
|
129
|
+
{items.map((item) => {
|
|
130
|
+
const label = title + ' — ' + msg(`${uiType}-style.${item.value}` as TLUiTranslationKey)
|
|
131
|
+
return (
|
|
132
|
+
<TldrawUiToolbarToggleItem
|
|
133
|
+
type="icon"
|
|
134
|
+
key={item.value}
|
|
135
|
+
data-id={item.value}
|
|
136
|
+
data-testid={`style.${uiType}.${item.value}`}
|
|
137
|
+
aria-label={label}
|
|
138
|
+
value={item.value}
|
|
139
|
+
data-state={value.type === 'shared' && value.value === item.value ? 'on' : 'off'}
|
|
140
|
+
data-isactive={value.type === 'shared' && value.value === item.value}
|
|
141
|
+
title={label}
|
|
142
|
+
style={
|
|
143
|
+
style === (DefaultColorStyle as StyleProp<unknown>)
|
|
144
|
+
? { color: getColorValue(theme, item.value as TLDefaultColorStyle, 'solid') }
|
|
145
|
+
: undefined
|
|
146
|
+
}
|
|
147
|
+
onPointerEnter={handleButtonPointerEnter}
|
|
148
|
+
onPointerDown={handleButtonPointerDown}
|
|
149
|
+
onPointerUp={handleButtonPointerUp}
|
|
150
|
+
onClick={handleButtonClick}
|
|
151
|
+
>
|
|
152
|
+
<TldrawUiButtonIcon icon={item.icon} />
|
|
153
|
+
</TldrawUiToolbarToggleItem>
|
|
154
|
+
)
|
|
155
|
+
})}
|
|
156
|
+
</TldrawUiToolbarToggleGroup>
|
|
157
|
+
</Wrapper>
|
|
155
158
|
)
|
|
156
159
|
}) as <T extends string>(props: TLUiButtonPickerProps<T>) => ReactElement
|
|
@@ -172,7 +172,7 @@ export const TldrawUiContextualToolbar = ({
|
|
|
172
172
|
className={classNames('tlui-contextual-toolbar', className)}
|
|
173
173
|
onPointerDown={stopEventPropagation}
|
|
174
174
|
>
|
|
175
|
-
<TldrawUiToolbar className="tlui-menu
|
|
175
|
+
<TldrawUiToolbar orientation="horizontal" className="tlui-menu" label={label}>
|
|
176
176
|
{children}
|
|
177
177
|
</TldrawUiToolbar>
|
|
178
178
|
</div>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useContainer } from '@tldraw/editor'
|
|
2
|
+
import classNames from 'classnames'
|
|
2
3
|
import { Popover as _Popover } from 'radix-ui'
|
|
3
4
|
import React from 'react'
|
|
4
5
|
import { useMenuIsOpen } from '../../hooks/useMenuIsOpen'
|
|
@@ -9,15 +10,16 @@ export interface TLUiPopoverProps {
|
|
|
9
10
|
open?: boolean
|
|
10
11
|
children: React.ReactNode
|
|
11
12
|
onOpenChange?(isOpen: boolean): void
|
|
13
|
+
className?: string
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
/** @public @react */
|
|
15
|
-
export function TldrawUiPopover({ id, children, onOpenChange, open }: TLUiPopoverProps) {
|
|
17
|
+
export function TldrawUiPopover({ id, children, onOpenChange, open, className }: TLUiPopoverProps) {
|
|
16
18
|
const [isOpen, handleOpenChange] = useMenuIsOpen(id, onOpenChange)
|
|
17
19
|
|
|
18
20
|
return (
|
|
19
21
|
<_Popover.Root onOpenChange={handleOpenChange} open={open || isOpen /* allow debugging */}>
|
|
20
|
-
<div className=
|
|
22
|
+
<div className={classNames('tlui-popover', className)}>{children}</div>
|
|
21
23
|
</_Popover.Root>
|
|
22
24
|
)
|
|
23
25
|
}
|
|
@@ -1,6 +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 { TldrawUiColumn, TldrawUiGrid, TldrawUiRow } from './layout'
|
|
4
5
|
import { TldrawUiTooltip } from './TldrawUiTooltip'
|
|
5
6
|
|
|
6
7
|
/** @public */
|
|
@@ -9,20 +10,42 @@ export interface TLUiToolbarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
9
10
|
className?: string
|
|
10
11
|
dir?: 'ltr' | 'rtl'
|
|
11
12
|
label: string
|
|
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,
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
/** @public @react */
|
|
15
24
|
export const TldrawUiToolbar = React.forwardRef<HTMLDivElement, TLUiToolbarProps>(
|
|
16
|
-
(
|
|
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]
|
|
17
37
|
return (
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
38
|
+
<Layout asChild tooltipSide={tooltipSide}>
|
|
39
|
+
<_Toolbar.Root
|
|
40
|
+
ref={ref}
|
|
41
|
+
{...props}
|
|
42
|
+
className={classnames('tlui-toolbar', className)}
|
|
43
|
+
aria-label={label}
|
|
44
|
+
orientation={orientation === 'grid' ? 'horizontal' : orientation}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
</_Toolbar.Root>
|
|
48
|
+
</Layout>
|
|
26
49
|
)
|
|
27
50
|
}
|
|
28
51
|
)
|