base-ui icon indicating copy to clipboard operation
base-ui copied to clipboard

[Autocomplete] useAutocomplete hook disabled option can be clicked

Open phiter opened this issue 1 year ago • 4 comments

Duplicates

  • [X] I have searched the existing issues

Latest version

  • [X] I have tested the latest version

Steps to reproduce 🕹

Link to live example: https://codesandbox.io/s/compassionate-chatelet-qz92q4?file=/Demo.tsx

Steps:

  1. Have an autocomplete hook with the getOptionDisabled option working
  2. Pass some disabled option
  3. Click the disabled option

Current behavior 😯

The disabled option can be clicked, even though if inspected, it has aria-disabled="true" attribute.

Expected behavior 🤔

The option should not be clickable.

Context 🔦

I'm creating a custom Autocomplete input with the useAutocomplete hook, but this is failing on my tests.

Your environment 🌎

npx @mui/envinfo
  System:
    OS: macOS 13.5.1
  Binaries:
    Node: 18.12.1 - /usr/local/bin/node
    Yarn: 1.22.19 - ~/.npm-global/bin/yarn
    npm: 8.19.2 - /usr/local/bin/npm
  Browsers:
    Chrome: 116.0.5845.96 <-- tested here
    Edge: 114.0.1823.55
    Safari: 16.6

phiter avatar Aug 23 '23 19:08 phiter

@phiter Thanks for reporting this ~ I agree it's a little unintuitive 😅

When we use this hook to make the Material UI and Joy UI autocomplete components, we use pointer-events: none to prevent the click (here)

Here's an example with just Base UI: https://codesandbox.io/s/https-github-com-mui-material-ui-issues-38620-77j4gk?file=/Demo.tsx

@michaldudak Do you think preventing selecting a disabled option could be provided out of the box?

mj12albert avatar Aug 24 '23 11:08 mj12albert

@mj12albert I tried pointer-events: none at first but during unit testing, since I use @testing-library/user-events, it doesn't immediately perform clicks on elements with pointer-events: none. When I disabled this check, the click event triggered. I don't know if simply trusting CSS is a good option, because the user can disable pointer-events: none in the devtools and the function will execute if it isn't handled.

I ended up having to do this in my code 😬

{(groupedOptions as T[]).map((option, index) => {
    const optionProps = getOptionProps({ option, index });
    // Workaround until https://github.com/mui/base-ui/issues/44 is fixed
    const isDisabled = autoCompleteOptions.getOptionDisabled(option);

    return (
        <AutocompleteOption
            key={index}
            {...optionProps}
            onClick={isDisabled ? undefined : optionProps.onClick}
        >
            {option.name}
        </AutocompleteOption>
    );
})}

I suppose it could be an option for the hook, like enableDisabledOptionClickHandler or something like that.

There is no handling in the code:

https://github.com/mui/material-ui/blob/8f5ff618ba8ec5d25c82fb8c5f67f9325a41bb3b/packages/mui-base/src/useAutocomplete/useAutocomplete.js#L998-L1003

https://github.com/mui/material-ui/blob/8f5ff618ba8ec5d25c82fb8c5f67f9325a41bb3b/packages/mui-base/src/useAutocomplete/useAutocomplete.js#L1157-L1175

phiter avatar Aug 24 '23 13:08 phiter

Same

aelfannir avatar Aug 28 '23 14:08 aelfannir

Do you think preventing selecting a disabled option could be provided out of the box?

Yes, I think it should work similarly to how Base UI's Select works (likely using the same primitives).

michaldudak avatar Aug 30 '23 09:08 michaldudak