mantinedev / mantine

A fully featured React components library
https://mantine.dev
MIT License
26.79k stars 1.9k forks source link

MultiSelect - an unexpected behavior makes the component unusable when in a certain controlled state #2059

Closed Stouffi closed 2 years ago

Stouffi commented 2 years ago

What package has an issue

@mantine/core

Describe the bug

When MultiSelect is given a value prop and a data prop with the same value, and a true searchable prop, The following problems occur:

Here is an excerpt of the codesandbox (link below) :

import { MultiSelect, Text } from "@mantine/core";
import { useState } from "react";
import "./styles.css";

export default function App() {
  const [value, onChange] = useState(["foo"]);

  return (
    <div className="App">
      <Text>value is {value}</Text>
      <MultiSelect
        searchable
        data={["foo"]}
        value={value}
        onChange={onChange}
      />
    </div>
  );
}

What version of @mantine/hooks page do you have in package.json?

5.1.1

If possible, please include a link to a codesandbox with the reproduced problem

https://codesandbox.io/s/repro-multi-select-dropdown-ikmuxi?file=/src/App.tsx

Do you know how to fix the issue

No response

Are you willing to participate in fixing this issue and create a pull request with the fix

No response

Possible fix

After debugging with the help of onDropdownClose prop those lines of code are responsible of the dropdown close https://github.com/mantinedev/mantine/blob/4486a9b11f2e2817d26c88e1d3337c60ef7d1140/src/mantine-core/src/MultiSelect/MultiSelect.tsx#L314-L316

The lifecycle hooks used in MultiSelect ought to be where to investigate...

rtivital commented 2 years ago

Thanks for reporting, the issue will be fixed in one of the next patches

Aeriit commented 2 years ago

For what it's worth, I'm currently using patch-package to work around this issue - so the dropdown doesn't get closed in this specific case if the MultiSelect is marked as searchable - using the following patch and it seems to be working:

diff --git a/node_modules/@mantine/core/esm/MultiSelect/MultiSelect.js b/node_modules/@mantine/core/esm/MultiSelect/MultiSelect.js
index 54438b2..709cd65 100644
--- a/node_modules/@mantine/core/esm/MultiSelect/MultiSelect.js
+++ b/node_modules/@mantine/core/esm/MultiSelect/MultiSelect.js
@@ -299,7 +299,7 @@ const MultiSelect = forwardRef((props, ref) => {
     setHovered(-1);
   }, [searchValue]);
   useDidUpdate(() => {
-    if (!disabled && _value.length >= data.length) {
+    if (!disabled && !searchable && _value.length >= data.length) {
       setDropdownOpened(false);
     }
     if (!!maxSelectedValues && _value.length < maxSelectedValues) {

This particular fix could be seen as an issue though, as technically there shouldn't be anything to search if _value.length >= data.length, so it doesn't make sense for the MultiSelect to be searchable. For my particular use case though, I'm using onSearchChange to fetch results from an API, so I need the user to be able to input a search even when there aren't any results. Maybe a new prop could be a solution here, to signal that the search input shouldn't get hidden even if there's no data?

dipiash commented 2 years ago

Hello!

I have the same situation with MultiSelect.

In my case: I want to select all values and show dropdown with this value.

But this lines:

  useDidUpdate(() => {
    if (!disabled && _value.length >= data.length) {
       setDropdownOpened(false);
    }
    ...
  }, [_value]);

don't allow to open dropdown (after open dropdown close immediately)

Fuzkin commented 2 years ago

Same to me with creatable prop. Opens and closes immediately when typing to create new option.

dipiash commented 2 years ago

@rtivital, hi!

Tell us please, when the new version with fix will be release?

rtivital commented 2 years ago

When I have time to publish it, you can always downgrade Mantine packages to previous versions if you experience any issues

rtivital commented 2 years ago

Fixed in 5.1.7