Select locked shapes on long press (#1529)

Fixes https://github.com/tldraw/tldraw/issues/1534

### Change Type

- [x] `patch` — Bug Fix

### Test Plan

1. On a touch device, create a locked shape
2. Long press on the locked shape to select it and open the context menu

### Release Notes
This commit is contained in:
Steve Ruiz 2023-06-06 12:23:53 +01:00 committed by GitHub
parent d9548556cb
commit 9e1b679e3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,7 +1,7 @@
import * as _ContextMenu from '@radix-ui/react-context-menu' import * as _ContextMenu from '@radix-ui/react-context-menu'
import { Editor, preventDefault, useContainer, useEditor } from '@tldraw/editor' import { Editor, preventDefault, useContainer, useEditor } from '@tldraw/editor'
import classNames from 'classnames' import classNames from 'classnames'
import * as React from 'react' import { useCallback, useState } from 'react'
import { useValue } from 'signia-react' import { useValue } from 'signia-react'
import { TLUiMenuChild } from '../hooks/menuHelpers' import { TLUiMenuChild } from '../hooks/menuHelpers'
import { useBreakpoint } from '../hooks/useBreakpoint' import { useBreakpoint } from '../hooks/useBreakpoint'
@ -24,12 +24,45 @@ export const ContextMenu = function ContextMenu({ children }: { children: any })
const editor = useEditor() const editor = useEditor()
const contextTLUiMenuSchema = useContextMenuSchema() const contextTLUiMenuSchema = useContextMenuSchema()
const cb = (isOpen: boolean) => {
if (isOpen) return const cb = useCallback(
if (shouldDeselect(editor)) { (isOpen: boolean) => {
editor.setSelectedIds([]) if (!isOpen) {
} const { onlySelectedShape } = editor
}
if (onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)) {
editor.setSelectedIds([])
}
} else {
// Weird route: selecting locked shapes on long press
if (editor.isCoarsePointer) {
const {
selectedShapes,
inputs: { currentPagePoint },
} = editor
// get all of the shapes under the current pointer
const shapesAtPoint = editor.getShapesAtPoint(currentPagePoint)
if (
// if there are no selected shapes
!editor.selectedShapes.length ||
// OR if none of the shapes at the point include the selected shape
!shapesAtPoint.some((s) => selectedShapes.includes(s))
) {
// then are there any locked shapes under the current pointer?
const lockedShapes = shapesAtPoint.filter((s) => editor.isShapeOrAncestorLocked(s))
if (lockedShapes.length) {
// nice, let's select them
editor.select(...lockedShapes.map((s) => s.id))
}
}
}
}
},
[editor]
)
const [_, handleOpenChange] = useMenuIsOpen('context menu', cb) const [_, handleOpenChange] = useMenuIsOpen('context menu', cb)
@ -60,12 +93,6 @@ export const ContextMenu = function ContextMenu({ children }: { children: any })
) )
} }
function shouldDeselect(editor: Editor) {
const { onlySelectedShape } = editor
if (!onlySelectedShape) return false
return editor.isShapeOrAncestorLocked(onlySelectedShape)
}
function ContextMenuContent() { function ContextMenuContent() {
const editor = useEditor() const editor = useEditor()
const msg = useTranslation() const msg = useTranslation()
@ -76,7 +103,7 @@ function ContextMenuContent() {
const breakpoint = useBreakpoint() const breakpoint = useBreakpoint()
const container = useContainer() const container = useContainer()
const [disableClicks, setDisableClicks] = React.useState(false) const [disableClicks, setDisableClicks] = useState(false)
function getContextMenuItem( function getContextMenuItem(
editor: Editor, editor: Editor,