Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Select] Create new Select component #541

Open
wants to merge 98 commits into
base: master
Choose a base branch
from

Conversation

atomiks
Copy link
Contributor

@atomiks atomiks commented Aug 15, 2024

Preview: https://deploy-preview-541--base-ui.netlify.app/components/react-select/

TODO:

  • Integrate with useField
  • Renamed alignMethod prop to alignOptionToTrigger

Olivier's edit: the v2 of mui/material-ui#8023 😄

@atomiks atomiks added the component: select This is the name of the generic UI component, not the React module! label Aug 15, 2024
@atomiks atomiks marked this pull request as draft August 15, 2024 02:37
@mui-bot
Copy link

mui-bot commented Aug 15, 2024

Netlify deploy preview

https://deploy-preview-541--base-ui.netlify.app/

Generated by 🚫 dangerJS against cccd3b2

@atomiks atomiks force-pushed the feat/Select branch 2 times, most recently from 2384edd to c32adfc Compare August 23, 2024 06:17
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Sep 2, 2024
ownerState,
propGetter: (externalProps) => getTriggerProps(getRootTriggerProps(externalProps)),
customStyleHookMapping: commonStyleHooks,
extraProps: otherProps,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if the Trigger had a CSS variable with the width of the popup, so it can match it (as in native OS controls)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the inverse? --anchor-width for popup is available. The trigger can't know the width of the popup when it's not mounted

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I didn't mean the inverse. Native OS selects adapt their width to the longest option. Perhaps this could be an option when keepMounted=true.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, but I'm hesitant to add something that doesn't work by default. Furthermore, it's likely very performance intensive with longer lists to calculate as you'll need to measure every option with getBoundingClientRect to calculate the largest one. It also doesn't work during SSR, so will cause layout shift. It's likely something that should be hardcoded by the user if necessary.

packages/mui-base/src/Select/Root/SelectRoot.tsx Outdated Show resolved Hide resolved
@github-actions github-actions bot added PR: out-of-date The pull request has merge conflicts and can't be merged and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Sep 5, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Sep 6, 2024
@michaldudak
Copy link
Member

Could you please review the list of reported Select bugs and set this PR to close the ones that will be fixed by it?

@github-actions github-actions bot added PR: out-of-date The pull request has merge conflicts and can't be merged and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Sep 11, 2024
@flaviendelangle
Copy link
Member

When you open the select, the page scrollbar disappears causing a layout shift on the right navbar in the doc (https://deploy-preview-541--base-ui.netlify.app/components/react-select/)

The @mui/material select also removes the scrollbar but there is no layout shift (https://mui.com/material-ui/react-select/)

@atomiks
Copy link
Contributor Author

atomiks commented Sep 11, 2024

@flaviendelangle interesting. The padding-right: 15px for the scrollbar width offset once it disappears prevents the main content from shifting but not the right navbar content (and end of the top navbar)

@michaldudak
Copy link
Member

michaldudak commented Sep 18, 2024

I'm wondering if we should prevent scrolling by default at all. I find it annoying when I open a select and something else changes appearance (=the scrollbar disappears). Native implementations differ in this matter - iOS prevents scrolling but doesn't hide the scrollbar, while Windows closes the popup when the page scrolls.
IMO locking the scroll is more important in modal windows.

I found an issue that's likely related to scroll locking: https://codesandbox.io/p/sandbox/q7qfjg - when you open the select, there's a small layout shift and you're able to scroll the page horizontally until the whole trigger disappears.

@atomiks
Copy link
Contributor Author

atomiks commented Sep 18, 2024

I'm wondering if we should prevent scrolling by default at all. I find it annoying when I open a select and something else changes appearance (=the scrollbar disappears).

The scroll locking changes we made in #604 prevents layout shift issues from disappearing scrollbars. The scroll lock is necessary with the item align anchoring because you can wheel the popup to reveal more items, but this can cause the page to scroll. It's not locked for the trigger align method.

I found an issue that's likely related to scroll locking: https://codesandbox.io/p/sandbox/q7qfjg - when you open the select, there's a small layout shift and you're able to scroll the page horizontally until the whole trigger disappears.

This looks like a bug with the .SelectPopup min-width style that doesn't limit itself by the --available-width.

This solves it:

  min-width: min(var(--available-width), calc(var(--anchor-width) + 20px));

There's a thread discussing default "functional styles" to apply to these elements and an API to override them in a thread in the base-ui channel. This could help prevent certain issues like this, including:

  • Making the popup scrollable by default
  • Limiting the popup's size to the available space (but the above calculation requires the user to use their own custom padding value)

@michaldudak
Copy link
Member

This looks like a bug with the .SelectPopup min-width style that doesn't limit itself by the --available-width.

This solves it:

The repro was taken directly from the demos, so they'll need to have the styles updated.

docs/data/components/select/select.mdx Outdated Show resolved Hide resolved
docs/src/styles/reset.css Outdated Show resolved Hide resolved
packages/mui-base/src/Field/Root/FieldRoot.test.tsx Outdated Show resolved Hide resolved
packages/mui-base/src/Select/Icon/SelectIcon.tsx Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous implementation supported multiple selection. Do you plan to add it here as well or in a separate component?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the potential complexity, a separate component + we'd need to discuss such an API first

packages/mui-base/src/Select/Root/useSelectRoot.tsx Outdated Show resolved Hide resolved
packages/mui-base/src/Select/Separator/SelectSeparator.tsx Outdated Show resolved Hide resolved
packages/mui-base/src/Select/Separator/SelectSeparator.tsx Outdated Show resolved Hide resolved
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Sep 24, 2024
@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 2, 2024

I imagine we won't support mui/material-ui#20402 (comment) just yet:

Screen.Recording.2024-10-03.at.00.50.04.mov

https://codesandbox.io/p/sandbox/magical-sara-zqhf6x. I think we should open a new issue for it, e.g. https://x.com/devongovett/status/1248306411508916224. One mistake I did there back in the days is I think to not compare values with autocompelte on toLowerCase() mode, like Chrome native select seems to do.

@atomiks
Copy link
Contributor Author

atomiks commented Oct 3, 2024

@oliviertassinari actually I did try to add support for it but I couldn't seem to get even the native select to autofill in my browser. I'll try to work off this demo instead.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 3, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 3, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 4, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 9, 2024
Copy link
Member

@michaldudak michaldudak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an issue when using objects as options - the component complains the selected option is not present among the available options: https://codesandbox.io/p/sandbox/upbeat-sun-v7yx2k (this fails in both controlled and uncontrolled mode).

Additionally, FYI, we briefly discussed rendering a native select on mobile devices by default. This could be done in a separate PR once we flesh out the details, but it's good to keep it in mind.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 14, 2024
Signed-off-by: atomiks <cc.glows@gmail.com>
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Oct 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: select This is the name of the generic UI component, not the React module!
Projects
None yet
5 participants