Material-ui: [Select] Improve categories support

Created on 5 Nov 2019  路  12Comments  路  Source: mui-org/material-ui

Edit @oliviertassinari

bug 1

bug 2

bug 馃悰 Select

Most helpful comment

Any progress on bug 1 here? Anything I can do to help? This is a bit of a dealbreaker for the Select component as I obviously don't want my headers being selected. The native Select option seems to handle this properly.

My current workaround is to add the following to my CSS stylesheet, but I know it's an ugly hack:

.MuiListSubheader-root {
    pointer-events: none;
}

Perhaps putting a boolean prop on the ListSubheader that conditionally adds pointer-events: none would be good enough?

All 12 comments

@nicks78 Please provide a full reproduction test case. This would help a lot 馃懛 .
A live example would be perfect. This codesandbox.io template _may_ be a good starting point. Thank you!

https://codesandbox.io/s/create-react-app-5z42i?fontsize=14

This is the reproduction with the error

@nicks78 Thank you for the reproduction. You can't do that, the Select requires a flat array. See #14943 for the issue that prevents it.

@oliviertassinari , I take the same exemple like it is in the library and there is still the same error :
https://material-ui.com/components/selects/
https://codesandbox.io/s/create-react-app-5z42i?fontsize=14

@nicks78 Thank you for the codesandbox.

Any progress on bug 1 here? Anything I can do to help? This is a bit of a dealbreaker for the Select component as I obviously don't want my headers being selected. The native Select option seems to handle this properly.

My current workaround is to add the following to my CSS stylesheet, but I know it's an ugly hack:

.MuiListSubheader-root {
    pointer-events: none;
}

Perhaps putting a boolean prop on the ListSubheader that conditionally adds pointer-events: none would be good enough?

For a future iteration, let's not forget about the learnings of #19574.

As mentioned in #20448:

There is an accessibility bug when using ListSubheader in a Select. When the first child of a Select component is ListSubheader, you must press tab before up/down arrow key functionality works. Codesandbox repo.

Are there any workarounds for issue #2?

@wseagar I'm not sure if adding position: sticky to a ListSubheader would work or not; you could give that a shot.

Thanks @embeddedt

For the moment I've used the native prop on the select with the native elements for the options

This solves the above 2 issues for my use case

(this example from the docs)

<Select native defaultValue="" id="grouped-native-select">
          <option aria-label="None" value="" />
          <optgroup label="Category 1">
            <option value={1}>Option 1</option>
            <option value={2}>Option 2</option>
          </optgroup>
          <optgroup label="Category 2">
            <option value={3}>Option 3</option>
            <option value={4}>Option 4</option>
          </optgroup>
        </Select>

I found a better solution to this problem (It only solves if you have just one ListSubheader). In the select component, you can pass the MenuProps object, and inside this object, you can pass the MenuListProps object which is the one that renders the List component that has a prop called subheader (which is the "right way" to render a ListSubHeader component).

So, you just have to do this:

import * as React from 'react'
import MenuItem from '@material-ui/core/MenuItem'
import ListSubheader from '@material-ui/core/ListSubheader'
import Select, { SelectProps } from '@material-ui/core/Select'

interface Props {
  subheaderText: string
}

function MySelect(props: Props) {
  const { subheaderText } = props

  const menuProps: SelectProps['MenuProps'] = React.useMemo(
    () => ({
      TransitionProps: { timeout: 0 },
      MenuListProps: {
        subheader: <ListSubheader component="div">{subheaderText}</ListSubheader>,
      },
    }),
    [subheaderText]
  )

  return (
    <Select MenuProps={menuProps}>
      <MenuItem>0</MenuItem>
      <MenuItem>1</MenuItem>
      <MenuItem>2</MenuItem>
    </Select>
  )
}

This way nothing will happen if the user clicks in the subheader and also the Select will position the Popover in the right position

Was this page helpful?
0 / 5 - 0 ratings