toolbar: disable items that dont work when not in select mode (#3819)

When switching to a non-Select tool, it should disable the Duplicate and
Trash button (and others). They don't do anything when clicking on them!
(drive-by tiny tweak to a `focus()` call)

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [x] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know

### Release Notes

- Toolbar: disable menu items that don't work when not in select mode.
This commit is contained in:
Mime Čuvalo 2024-05-28 10:49:42 +01:00 committed by GitHub
parent 93cfd250e9
commit 19f8d4248c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 54 additions and 51 deletions

View file

@ -270,7 +270,7 @@ const DocumentNameEditor = track(function DocumentNameEditor({
// trigger a save with the new one
setState((prev) => ({ ...prev, name: null }))
inputRef.current?.blur()
editor.getContainer().focus()
editor.focus()
}
},
[setState, editor]

View file

@ -6,6 +6,7 @@ import {
useAllowGroup,
useAllowUngroup,
useHasLinkShapeSelected,
useIsInSelectState,
useThreeStackableItems,
useUnlockedSelectedShapesCount,
} from '../../hooks/menu-hooks'
@ -31,17 +32,19 @@ export function DefaultActionsMenuContent() {
export function AlignMenuItems() {
const actions = useActions()
const twoSelected = useUnlockedSelectedShapesCount(2)
const isInSelectState = useIsInSelectState()
const enabled = twoSelected && isInSelectState
return (
<>
<TldrawUiMenuItem {...actions['align-left']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['align-center-horizontal']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['align-right']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['stretch-horizontal']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['align-top']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['align-center-vertical']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['align-bottom']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['stretch-vertical']} disabled={!twoSelected} />
<TldrawUiMenuItem {...actions['align-left']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['align-center-horizontal']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['align-right']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['stretch-horizontal']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['align-top']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['align-center-vertical']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['align-bottom']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['stretch-vertical']} disabled={!enabled} />
</>
)
}
@ -50,11 +53,13 @@ export function AlignMenuItems() {
export function DistributeMenuItems() {
const actions = useActions()
const threeSelected = useUnlockedSelectedShapesCount(3)
const isInSelectState = useIsInSelectState()
const enabled = threeSelected && isInSelectState
return (
<>
<TldrawUiMenuItem {...actions['distribute-horizontal']} disabled={!threeSelected} />
<TldrawUiMenuItem {...actions['distribute-vertical']} disabled={!threeSelected} />
<TldrawUiMenuItem {...actions['distribute-horizontal']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['distribute-vertical']} disabled={!enabled} />
</>
)
}
@ -63,11 +68,13 @@ export function DistributeMenuItems() {
export function StackMenuItems() {
const actions = useActions()
const threeStackableItems = useThreeStackableItems()
const isInSelectState = useIsInSelectState()
const enabled = threeStackableItems && isInSelectState
return (
<>
<TldrawUiMenuItem {...actions['stack-horizontal']} disabled={!threeStackableItems} />
<TldrawUiMenuItem {...actions['stack-vertical']} disabled={!threeStackableItems} />
<TldrawUiMenuItem {...actions['stack-horizontal']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['stack-vertical']} disabled={!enabled} />
</>
)
}
@ -76,13 +83,15 @@ export function StackMenuItems() {
export function ReorderMenuItems() {
const actions = useActions()
const oneSelected = useUnlockedSelectedShapesCount(1)
const isInSelectState = useIsInSelectState()
const enabled = oneSelected && isInSelectState
return (
<>
<TldrawUiMenuItem {...actions['send-to-back']} disabled={!oneSelected} />
<TldrawUiMenuItem {...actions['send-backward']} disabled={!oneSelected} />
<TldrawUiMenuItem {...actions['bring-forward']} disabled={!oneSelected} />
<TldrawUiMenuItem {...actions['bring-to-front']} disabled={!oneSelected} />
<TldrawUiMenuItem {...actions['send-to-back']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['send-backward']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['bring-forward']} disabled={!enabled} />
<TldrawUiMenuItem {...actions['bring-to-front']} disabled={!enabled} />
</>
)
}
@ -107,24 +116,30 @@ export function ZoomTo100MenuItem() {
export function RotateCCWMenuItem() {
const actions = useActions()
const oneSelected = useUnlockedSelectedShapesCount(1)
const isInSelectState = useIsInSelectState()
const enabled = oneSelected && isInSelectState
return <TldrawUiMenuItem {...actions['rotate-ccw']} disabled={!oneSelected} />
return <TldrawUiMenuItem {...actions['rotate-ccw']} disabled={!enabled} />
}
/** @public */
export function RotateCWMenuItem() {
const actions = useActions()
const oneSelected = useUnlockedSelectedShapesCount(1)
const isInSelectState = useIsInSelectState()
const enabled = oneSelected && isInSelectState
return <TldrawUiMenuItem {...actions['rotate-cw']} disabled={!oneSelected} />
return <TldrawUiMenuItem {...actions['rotate-cw']} disabled={!enabled} />
}
/** @public */
export function EditLinkMenuItem() {
const actions = useActions()
const showEditLink = useHasLinkShapeSelected()
const isInSelectState = useIsInSelectState()
const enabled = showEditLink && isInSelectState
return <TldrawUiMenuItem {...actions['edit-link']} disabled={!showEditLink} />
return <TldrawUiMenuItem {...actions['edit-link']} disabled={!enabled} />
}
/** @public */
@ -138,8 +153,10 @@ export function GroupOrUngroupMenuItem() {
export function GroupMenuItem() {
const actions = useActions()
const twoSelected = useUnlockedSelectedShapesCount(2)
const isInSelectState = useIsInSelectState()
const enabled = twoSelected && isInSelectState
return <TldrawUiMenuItem {...actions['group']} disabled={!twoSelected} />
return <TldrawUiMenuItem {...actions['group']} disabled={!enabled} />
}
/** @public */

View file

@ -1,27 +0,0 @@
import { memo } from 'react'
import { PORTRAIT_BREAKPOINT } from '../constants'
import { useBreakpoint } from '../context/breakpoints'
import { useTldrawUiComponents } from '../context/components'
export const MenuZone = memo(function MenuZone() {
const breakpoint = useBreakpoint()
const { MainMenu, QuickActions, ActionsMenu, PageMenu } = useTldrawUiComponents()
if (!MainMenu && !PageMenu && breakpoint < PORTRAIT_BREAKPOINT.TABLET) return null
return (
<div className="tlui-menu-zone">
<div className="tlui-buttons__horizontal">
{MainMenu && <MainMenu />}
{PageMenu && <PageMenu />}
{breakpoint < PORTRAIT_BREAKPOINT.TABLET ? null : (
<>
{QuickActions && <QuickActions />}
{ActionsMenu && <ActionsMenu />}
</>
)}
</div>
</div>
)
})

View file

@ -1,6 +1,11 @@
import { useEditor, useValue } from '@tldraw/editor'
import { useActions } from '../../context/actions'
import { useCanRedo, useCanUndo, useUnlockedSelectedShapesCount } from '../../hooks/menu-hooks'
import {
useCanRedo,
useCanUndo,
useIsInSelectState,
useUnlockedSelectedShapesCount,
} from '../../hooks/menu-hooks'
import { useReadonly } from '../../hooks/useReadonly'
import { TldrawUiMenuItem } from '../primitives/menus/TldrawUiMenuItem'
@ -21,6 +26,8 @@ export function DefaultQuickActionsContent() {
() => editor.isInAny('select', 'hand', 'zoom'),
[editor]
)
const isInSelectState = useIsInSelectState()
const selectDependentActionsEnabled = oneSelected && isInSelectState
if (isReadonlyMode && !isInAcceptableReadonlyState) return
@ -28,8 +35,8 @@ export function DefaultQuickActionsContent() {
<>
<TldrawUiMenuItem {...actions['undo']} disabled={!canUndo} />
<TldrawUiMenuItem {...actions['redo']} disabled={!canRedo} />
<TldrawUiMenuItem {...actions['delete']} disabled={!oneSelected} />
<TldrawUiMenuItem {...actions['duplicate']} disabled={!oneSelected} />
<TldrawUiMenuItem {...actions['delete']} disabled={!selectDependentActionsEnabled} />
<TldrawUiMenuItem {...actions['duplicate']} disabled={!selectDependentActionsEnabled} />
</>
)
}

View file

@ -32,6 +32,12 @@ export const useThreeStackableItems = () => {
return useValue('threeStackableItems', () => shapesWithUnboundArrows(editor).length > 2, [editor])
}
/** @internal */
export const useIsInSelectState = () => {
const editor = useEditor()
return useValue('isInSelectState', () => editor.isIn('select'), [editor])
}
/** @internal */
export const useAllowGroup = () => {
const editor = useEditor()