tldraw 3.16.0-next.34fddf633325 → 3.16.0-next.b88d494af370
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 +102 -5
- package/dist-cjs/index.js +8 -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/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/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/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 +153 -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 +102 -5
- package/dist-esm/index.mjs +15 -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/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/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/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 +161 -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 +3 -3
- package/src/index.ts +12 -0
- package/src/lib/canvas/TldrawScribble.tsx +1 -1
- package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +4 -3
- package/src/lib/shapes/arrow/elbow/ElbowArrowDebug.tsx +3 -3
- 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.tsx +6 -1
- package/src/lib/shapes/note/NoteShapeUtil.tsx +9 -4
- package/src/lib/shapes/shared/ShapeFill.tsx +5 -4
- package/src/lib/shapes/text/TextShapeUtil.tsx +3 -2
- package/src/lib/shapes/video/VideoShapeUtil.tsx +3 -3
- package/src/lib/tools/SelectTool/childStates/Translating.ts +0 -1
- package/src/lib/ui/TldrawUi.tsx +17 -2
- 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 +220 -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/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
|
)
|