question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[v2] Custom Components, closeMenuOnSelect=false click outside do not close menu

See original GitHub issue

While implementing custom menu with option closeMenuOnSelect=false click outside do not close menu. Issue is probably cause lose of input focus.

  • Open menu and click outside, menu close as expected
  • Open menu, clear all items and click outside, menu close as expected
  • Open menu, select option and click outside menu is still open
  • Open menu, clear any option and click outside menu is still open
const props = {
           ...
           components: {
                Menu: ({options: renderedOptions, selectOption, selectProps, innerProps}) => (
                    <DropdownMenu className={`${classNamePrefix}__menu`} {...innerProps}>
                        {
                            renderedOptions && renderedOptions.length > 0
                                ? (renderedOptions.map((option) => (
                                    <DropdownItem
                                        key={option[VALUE_KEY]}
                                        tag="div"
                                        onClick={() => selectOption(option)}
                                        className={classnames(`${classNamePrefix}__menu-option`, {
                                            [`${classNamePrefix}__menu-option_is-selected`]: selectProps.value && (
                                                Array.isArray(selectProps.value)
                                                    ? selectProps.value.some((selectedValue) => selectedValue[VALUE_KEY] === option[VALUE_KEY])
                                                    : selectProps.value[VALUE_KEY] === option[VALUE_KEY]),
                                        })}
                                        role="option"
                                    >
                                        {option.name}
                                    </DropdownItem>
                                )))
                                : <span className={classnames(`${classNamePrefix}__no-options`)}>{msg.noOptions}</span>
                        }
                    </DropdownMenu>
                ),
                ValueContainer: ({children, ...restValueContainerProps}) => (
                    <DropdownToggle className={`${classNamePrefix}__flip-toggle`} tag="div">
                        <components.ValueContainer {...restValueContainerProps}>
                            {children}
                        </components.ValueContainer>
                    </DropdownToggle>
                ),
                MultiValueContainer: ({children, ...restValueContainerProps}) => (
                    <DropdownToggle className={`${classNamePrefix}__flip-toggle`} tag="div">
                        <components.MultiValueContainer {...restValueContainerProps}>
                            {children}
                        </components.MultiValueContainer>
                    </DropdownToggle>
                ),
                IndicatorSeparator: () => <span />,
            }
}

note: Im using reactstrap coponents becasuse their handle menu floping when its needed

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:12
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

35reactions
clickblipclickcommented, Dec 26, 2019

And I think I just figured out why. You can’t define your replacement component directly on the components prop object like this:

<Select
  options={options}
  value={selectValue}
  closeMenuOnSelect={false}
  onChange={value => setSelectValue(value)}
  components={{
    ValueContainer: props => <components.ValueContainer {...props} />
  }}
/>

You have to define the custom component elsewhere outside the render like so:

const CustomValueContainer: React.FC = props => (
  <components.ValueContainer {...props} />
);

const App = () => {
  const [selectValue, setSelectValue] = useState();
  return (
    <div className="App">
      <Select
        options={options}
        value={selectValue}
        closeMenuOnSelect={false}
        onChange={value => setSelectValue(value)}
        components={{
          ValueContainer: CustomValueContainer,
        }}
      />
    </div>
  );
};

Why? I assume because there is some side-effect event listener being added, on recreating the component on every render causes that not to work. (Just a guess).

11reactions
todesstosscommented, Feb 24, 2020

Faced the same issue.

You have to define the custom component elsewhere outside the render like so:

In this case it’s no possible to provide custom props to this custom component

UPD:

for someone else facing same issue, custom props can be passed on Select element and accessed via props.selectProps

Read more comments on GitHub >

github_iconTop Results From Across the Web

React closing a dropdown when click outside - Stack Overflow
Simple follow 5 steps to close menu/ change state of any element when clicked outside of that element using React Hook.
Read more >
How to detect click outside in a React component
In this tutorial, we will display a dropdown and close the dropdown when the user clicks outside it.
Read more >
React click outside to close - YouTube
Registering click outside event ( click - out ) using references (useRef) and useEffect. The event is registered on body and added and...
Read more >
Click Outside to Close - React Hook - YouTube
In this video I'll show you how to make a hook that runs whenever the user clicks outside of a DOM node.
Read more >
Dismissing a React Dropdown Menu by Clicking Outside its ...
That's the case even if there are no elements to be focused inside the dropdown menu. So, onBlur is not the answer. Attempt...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found