radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.79k stars 820 forks source link

[Select] Make the `hideOthers` feature optional (ie. add non-modal mode) #1927

Open frykten opened 1 year ago

frykten commented 1 year ago

Feature request

Overview

We started using Radix recently and we found something that is quite an issue on our side: when opening a simple Select or Menu "content", the page scrollbar disappears and there is a small lag.

Both stem from the same line of code (a feature):

    React.useEffect(() => {
      if (content) return hideOthers(content);
    }, [content]);

That "hideOthers" method/feature, though it has good intentions, breaks the UX for our mouse users as it hides the page scrollbar, and creates a lag in certain pages as it adds to all nodes the aria-hidden property (and we do not have a small website, but a rather big application with some heavy pages/documents and modifying the whole dom is just... not really something we want to do).

We understand that the intention was good and to trap the focus inside the element/popover and only that element/popover. Still, while we see the use for modals/dialogs, for Menus and Selects, we do not see the real plus-value---especially since it hinders our users' experience (page scroll difference, plus performance), and we would like to request a parameter to make that behavior optional via a param.

Personally, I'm inclined to make a PR, if you wish.

Examples in other libraries

It is mostly that other libraries do not use such behavior for elements like Menus/Selects. Just look at GitHub, the Google suite, Spotify, or any tool/app/website you use every day; this is way too brutal for such components that are used in forms, in navigation, and which do not break the flow (contrary to a modal, where it is advised in every specs/docs/tutorial to add such a behavior). In aria-hidden's documentation, they advise/enforce the use of the addon for modals/dialogs, not for smaller block items.

Whom does this impact? Who is this for?

This impacts Users---at least, ours. Making the property optional, with true as default, would not break the implementation of all those who use those components and are happy about it, but it would permit those who are not to fix it.

Additional context

Additionally, now, the repo aria-hidden has a "suppressOthers" method that turns everything into the new and better inert. Maybe you should turn to this method for the Modal/Dialog components?

Another thing/question: while implementing the component, we had to suppress an axe rule "Ensures aria-hidden elements are not focusable nor contain focusable elements"; when axe runs while the popover is opened (whether it is the selection list or the menu dropdown), the component's trigger is aria-hidden as well, even though it is tabbable/interactive and axe doesn't like that very much. Maybe it isn't supposed to be an issue, since the focus is trapped inside the popover, but it felt weird to our Product/QA teams and during User tests.

florianloechle commented 1 year ago

The disappearing scrollbar is causing problems in our company as well. Is there any solution to this atm?

frykten commented 1 year ago

@florianloechle I created a PR and, while scrounging through the code, I discovered what "created" the issues. Most of the other components have a "modal" mode (and therefore a "non-modal" mode) that make the scrollbar disappear and block the "outside events" (need to close the "modal" first, ofc).

For now, there is no solution (I'dn't advise to fork my PR :shrug: ). I have had no reviews from the Radix team yet, and, lastly, they told me they hadn't had much time for external reviews. I guess the only thing to do for us is to put lotsa "+1" on the PR and to ping them on Discord :sweat_smile: I hope it will help them understand the need (they have it for all other components, they also need it for this one :D !).

benoitgrelard commented 1 year ago

Still, while we see the use for modals/dialogs, for Menus and Selects, we do not see the real plus-value---especially since it hinders our users' experience (page scroll difference, plus performance)

Important to note that this is how the native select behaves, it is modal by default (and always modal AFAICT). That being said, supporting non-modal mode is something I always thought we'd add to Select too given the rest of the library.

Just look at GitHub, the Google suite, Spotify, or any tool/app/website you use every day; this is way too brutal for such components that are used in forms, in navigation, and which do not break the flow (contrary to a modal, where it is advised in every specs/docs/tutorial to add such a behavior).

What do you mean here? I'm confused given what I said above, on MacOS, any form that has a select will behave like this, you won't be able to scroll or click on something else whilst it's open, you'll have to close it first.

frykten commented 1 year ago

What do you mean here? I'm confused given what I said above, on MacOS, any form that has a select will behave like this, you won't be able to scroll or click on something else whilst it's open, you'll have to close it first.

Though it is the native behavior, many component libraries we've seen (we = my team, with our old stack being Ember.js) implement "Select" components with a non-modal mode :eyes: I'm sorry if my first message (edited many times, since I first thought it was the "hideOthers" which was creating this "modal mode") was opaque on this.

That being said, supporting non-modal mode is something I always thought we'd add to Select too given the rest of the library.

As I said, our UX team would love to recover that behavior (our users are used to being able to click from one form field to another, even if it opens a dropdown selection); I opened a PR, and I'm open to reviews if more work is needed :metal: (and I'd assume more work is needed as I don't now the codebase :D !)

benoitgrelard commented 1 year ago

I opened a PR, and I'm open to reviews if more work is needed

I have responded on there too btw!

dvartic commented 4 months ago

We really need this. As of now this makes Select unusable for us.

firxworx commented 3 months ago

@benoitgrelard I think you may be too focused on the behaviours of a modal "in theory" vs. in practice.

The radix select behaves absolutely nothing like the native selects that the vast majority of users experience.

What you say above simply isn't true (https://github.com/radix-ui/primitives/issues/1927#issuecomment-1556988494) and I'll explain some behaviours.

UI/UX principles in action

We serve the majority of users right?

I friendly bet $5 if you used Windows with Chrome or Edge for a week you'd be making some revisions to radix pretty quick and would go back on may of the things I've seen you push back on in various comments on various issues in this project!

Like many on the UI/UX side I figure you must use MacOS full-time and don't generally touch anything else outside that ecosystem. No judgement here -- I have a Macs myself and they are nice. However I also work a lot on PC/Win and linux too.

BTW while linux window managers / desktop environments can be all over the place, the vast majority of the ones I have used are more Windows-like in their behaviour vs. Mac-like (especially at default configuration).

What the majority experience

Gigantic fat scrollbars with no background behind them when they disappear in a jarring fashion

Big fat scrollbars that are very visually jarring to suddenly have disappear without a blur / backdrop. Its really bad.

Opening select menus is never jarring or janky except with radix UI.

If a site has a dark background on PC there's a big white gutter where it should be and a page's background does not extend to it.

Radix' use of the horrendous react-remove-scroll and the general insistence on a third party library over in-housing such an important feature and giving devs some control is a huge pain and makes half of any projects that uses radix + modals really jarring and janky feeling a lot of the time. Devs don't always have control of the global styles or the layout and many times we're just making a component or widget and can't have hardcoded opinionated things janking and breaking pages.

This is why you see many comments (so frequently related to radix + modal) where devs say its a showstopper or dealbreaker for them.

Describing select behaviour

Opening a select box does not jarringly disappear scrollbars. Never. Not like radix.

If I open a native HTML select element I can still use my mouse scroll wheel to scroll the page.

If I'm on a touchpad OR touchscreen if I tap outside the open select dropdown and start dragging the experience is seamless. There is no modal-like close and restore whatsoever, it's like the new interaction/gesture "takes over". You have to experience it.

Radix UI Select (and modals in general) are completely outlier in how the behave.

Radix does get the arrow keys and escape correct.

However it does not get other keyboard interactions correct. If I have a native select open on a given option and I hit tab as a keyboard user, the dropdown closes and I am focused on the select component. Radix fails to do this because tab is locked (they keypress is ignored).

Radix gets the press-a-letter-or-number key correct by cycling through the options that start with that character.

Anyway...

I doubt that certain native behaviours are even possible to implement in any web UI (for example: a native html select that is too large for a screen that is not full viewport height (i.e. so there's breathing room) will spill out of the page and even the browser window because there is enough room on-viewport).

The long and short of it is the modal-like behaviour of select is completely at odds of how select works, and while the non-modal behaviour is still far off when it comes to many things, at least its not jarring or janky and it is much closer UX-wise.

LeonLiu2020 commented 3 months ago

For the sticky header, clicking on the select located in the content causes the header to shift. The solutions mentioned in other issues or discussions are not working for me. It would be great if radix could provide a modal prop as easily as the dropdown menu. Otherwise, I'll have to use other unheadless select components, which is very inconvenient.

LeonLiu2020 commented 3 months ago

@benoitgrelard I think you may be too focused on the behaviours of a modal "in theory" vs. in practice.

The radix select behaves absolutely nothing like the native selects that the vast majority of users experience.

What you say above simply isn't true (#1927 (comment)) and I'll explain some behaviours.

UI/UX principles in action

We serve the majority of users right?

I friendly bet $5 if you used Windows with Chrome or Edge for a week you'd be making some revisions to radix pretty quick and would go back on may of the things I've seen you push back on in various comments on various issues in this project!

Like many on the UI/UX side I figure you must use MacOS full-time and don't generally touch anything else outside that ecosystem. No judgement here -- I have a Macs myself and they are nice. However I also work a lot on PC/Win and linux too.

BTW while linux window managers / desktop environments can be all over the place, the vast majority of the ones I have used are more Windows-like in their behaviour vs. Mac-like (especially at default configuration).

What the majority experience

Gigantic fat scrollbars with no background behind them when they disappear in a jarring fashion

Big fat scrollbars that are very visually jarring to suddenly have disappear without a blur / backdrop. Its really bad.

Opening select menus is never jarring or janky except with radix UI.

If a site has a dark background on PC there's a big white gutter where it should be and a page's background does not extend to it.

Radix' use of the horrendous react-remove-scroll and the general insistence on a third party library over in-housing such an important feature and giving devs some control is a huge pain and makes half of any projects that uses radix + modals really jarring and janky feeling a lot of the time. Devs don't always have control of the global styles or the layout and many times we're just making a component or widget and can't have hardcoded opinionated things janking and breaking pages.

This is why you see many comments (so frequently related to radix + modal) where devs say its a showstopper or dealbreaker for them.

Describing select behaviour

Opening a select box does not jarringly disappear scrollbars. Never. Not like radix.

If I open a native HTML select element I can still use my mouse scroll wheel to scroll the page.

If I'm on a touchpad OR touchscreen if I tap outside the open select dropdown and start dragging the experience is seamless. There is no modal-like close and restore whatsoever, it's like the new interaction/gesture "takes over". You have to experience it.

Radix UI Select (and modals in general) are completely outlier in how the behave.

Radix does get the arrow keys and escape correct.

However it does not get other keyboard interactions correct. If I have a native select open on a given option and I hit tab as a keyboard user, the dropdown closes and I am focused on the select component. Radix fails to do this because tab is locked (they keypress is ignored).

Radix gets the press-a-letter-or-number key correct by cycling through the options that start with that character.

Anyway...

I doubt that certain native behaviours are even possible to implement in any web UI (for example: a native html select that is too large for a screen that is not full viewport height (i.e. so there's breathing room) will spill out of the page and even the browser window because there is enough room on-viewport).

The long and short of it is the modal-like behaviour of select is completely at odds of how select works, and while the non-modal behaviour is still far off when it comes to many things, at least its not jarring or janky and it is much closer UX-wise.

@firxworx Thanks, your explanation is very comprehensive and I have benefited greatly from it. The other components in radix-primitive are very useful, but for Select, I should choose another headless library instead of foolishly trying to solve this silly shift.

joeyfigaro commented 1 week ago

The disappearing scrollbar is causing problems in our company as well. Is there any solution to this atm?

In addition to scrollbars missing on body/page content (which makes sense for modal content being opened) any content in a Select also has missing scrollbars. Even if overflow is styled explicitly, and even when using ScrollArea from radix. Right now the only way to see all of the options in a radix supplied Select that has a cut off options list and lives inside of a modal parent is to get a bigger screen. Which is less than ideal. 🤣

CleanShot 2024-10-28 at 17 11 25@2x

Scrolling over this select's options list does nothing.