[improvement] More selection logic (#1806)

This PR includes further UX improvements to selection.

- clicking inside of a hollow shape will no longer select it on pointer
up
- clicking a shape's filled label will select it on pointer down
- clicking a shape's empty label will select it on pointer up
- clicking and dragging a selected arrow is now better limited to its
body, not its bounds
- arrows will no longer bind to labels

### Text labels

A big change here relates to text labels. Previously, we had listeners
set on the text label elements; I've removed these and we now check the
actual label bounds geometry for a hit. For geo shapes, this geometry is
now placed correctly based on the alignment / vertical alignment of the
label.

- Clicking on a label with text in it will select the shape on pointer
down.
- Clicking on an empty text label will select the shape on pointer up.

## Hollow shapes

Previously, shapes with `fill: none` were also being selected on pointer
up. I've removed that logic because it was producing wrong-feeling
selections too often. We now select these shapes only when clicking on
the label (as mentioned above) or when clicking on the edges of the
shape. This is in line with the original behavior (currently on
tldraw.com, prior to the earlier PR that updated selection logic).

## Arrows

Arrows still hit the inside of hollow shapes, using the "smallest
hovered" logic previously used for pointer-up selection on hollow
shapes. They also now correctly do so while ignoring text labels.

### Change Type

- [x] `minor` — New feature

### Test Plan

1. try selecting geo shapes, nested geo shapes, arrows and shapes with
labels or without labels

- [x] Unit Tests
This commit is contained in:
Steve Ruiz 2023-08-13 16:55:24 +01:00 committed by GitHub
parent eaba3c8f2a
commit 22329c51fc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
58 changed files with 1173 additions and 1137 deletions

View file

@ -25,7 +25,6 @@ export const ArrowTextLabel = React.memo(function ArrowTextLabel({
handleChange,
isEmpty,
handleInputPointerDown,
handleContentPointerDown,
} = useEditableText(id, 'arrow', text)
if (!isEditing && isEmpty) {
@ -48,7 +47,7 @@ export const ArrowTextLabel = React.memo(function ArrowTextLabel({
}}
>
<div className="tl-arrow-label__inner">
<p style={{ width: width ? width : '9px' }} onPointerDown={handleContentPointerDown}>
<p style={{ width: width ? width : '9px' }}>
{text ? TextHelpers.normalizeTextForDom(text) : ' '}
</p>
{isEditing && (