Reach-ui: [Listbox] Wait for mousemove before allowing mouseup to trigger an option select

Created on 2 Apr 2020  路  8Comments  路  Source: reach/reach-ui

鉂換uestion

Is there specific reason for Listbox component to select am item on museUp?
I'm trying to implement a design where selected ListboxOption is displayed on top of the ListboxButton, similar how https://material-ui.com/components/selects/ does it.

Or like chrome does it with native select tag.

Screen Shot 2020-04-01 at 7 07 52 PM

I'm passing a custom position prop to ListboxPopover component that calculates the position - and that seems to work, but when clicking on the ListboxButton happens it immediately closes and does not stay open. Was looking at the Listbox code and it seemed like item selection get's triggered on mouseUp...


Is there a way to do what I'm trying to do? Or is this not possible...?

Enhancement

All 8 comments

There is this code that handles the mouseUp on ListboxOption component
https://github.com/reach/reach-ui/blob/d4bcfc73f27e6e618ec2eb2b0154a58bc17496f0/packages/listbox/src/index.tsx#L1004-L1016

to do what I'm trying to do this code will need to be updated so that when a user does not move their mouse after the mouseDown on ListboxButton component mouseUp in ListboxOption does not get triggered. So basically when it's a click on ListboxButton it opens the popup, but when user mouseDown on ListboxButton and move their mouse mouseUp on ListboxOption gets triggered.

One other way I've managed to get it to work is to update the following code
https://github.com/reach/reach-ui/blob/d4bcfc73f27e6e618ec2eb2b0154a58bc17496f0/packages/listbox/src/index.tsx#L523-L532

To something like this

function handleMouseDown(event: React.MouseEvent) {
  if (!isRightClick(event.nativeEvent)) {

    mouseEventStartedRef.current = false;
    setTimeout(() => {
      mouseEventStartedRef.current = true;
    }, 500);

    event.preventDefault();
    send({
      type: ListboxEvents.ButtonMouseDown,
      disabled,
    });
  }
}

I can try making a PR to Reach UI with this but was not sure if something like this will be accepted... 馃

I don't think a timer is the right approach. Looks like the native HTML select will wait for the mouse to move before allowing mouseup to select the options. Will put this one on the burner.

@marexandre Would you mind sharing your code for the positioning logic so I can test against it?

@chancestrickland

Here's an simplified version of the code https://codesandbox.io/s/loving-mountain-56dfc

If you click the right side of the ListboxButton the popup will open and stay open, but when clicked on the left side it closes immediately. With CSS it's easy to make the button and popup be same width, but in this example I'm not doing that so it's easier to test both cases.

@marexandre Can you try testing your implementation against the master branch? I added an example showing how we can do this a little better with the popover's position prop, so it may need some adjustments. Using querySelector could potentially be a bit fragile if we update something internally that interferes with mount/paint timing.

@chancestrickland just tried out the master branch and code from listbox/examples/position-over-active.example.tsx - and it worked great out the box and managed to get the design to look like we wanted 馃槃 Thank you so much for all the changes!

Using querySelector could potentially be a bit fragile if we update something internally that interferes with mount/paint timing.

Could not agree more - as there was no way to get access to the selected option before your updates that was the easier way to prototype on.

Addressed in 0.10.1

Was this page helpful?
0 / 5 - 0 ratings