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

Upgrade to material ui icons v5 broke react-select #4979

Closed
charneykaye opened this issue Jan 6, 2022 · 4 comments
Closed

Upgrade to material ui icons v5 broke react-select #4979

charneykaye opened this issue Jan 6, 2022 · 4 comments
Labels
issue/bug-unconfirmed Issues that describe a bug that hasn't been confirmed by a maintainer yet

Comments

@charneykaye
Copy link

charneykaye commented Jan 6, 2022

I have been upgrading from @material-ui/icons 4.11.2 to @mui/icons-material at 5.2.3

I realize that material UI is not directly used in react-select however as far as I can see there is some interaction.

The upgrade from Material UI Icons v4 to v5 seemed to be going fine. But then, I noticed all the react-select dropdowns explode the application (instant blank screen) with this error in the console:

TypeError: theme.transitions is undefined
./node_modules/@mui/material/SvgIcon/SvgIcon.js/SvgIconRoot<
node_modules/@mui/material/SvgIcon/SvgIcon.js:49

46 | display: 'inline-block',
47 | fill: 'currentColor',
48 | flexShrink: 0,
49 | transition: theme.transitions.create('fill', {
   | ^  50 |   duration: theme.transitions.duration.shorter
51 | }),
52 | fontSize: {

I've been pouring over the Material UI v4 -> v5 migration guide, have upgraded our react and react-dom libraries to 17.0.2 and react-select library to 5.2.1, but this issue persists.

Here's my function component that wraps all the dropdown selectors in question.

import React, {useState} from 'react';
import Select from 'react-select';
import {useSelector} from "react-redux";
import "./EntityChildDropdownSelector.scss"
import {selectStyles, selectTheme} from "./SelectorStyles";
import SearchIcon from '@mui/icons-material/Search';
import PropTypes from "prop-types";

/**
 EntityChildDropdownSelector for editing one attribute of an entity

 @return {*}
 @typedef EntitiesSelector{Selector} is a Redux selector that can be used to fetch the entities for this selector
 @typedef Entity{{ id:String }} is an entity having an id
 @typedef TextFormattingFunction{function} given an entity, returns it formatted as text
 @typedef ClassName{string} of attribute to edit
 @typedef ActivateFunction{function} to callback when a selection is made
 */
const EntityChildDropdownSelector = function (props) {
  const
    [isOpen, setIsOpen] = useState(false);

  // option object has id and text, must be translated back and forth value <> riek field
  const entities = useSelector(state => props.entitiesSelector(state)),
    options = entities
      .map((o) => ({value: o.id, label: props.format(o)})),
    active = !!props.active ? options.find((o) => (o.value === props.active.id)) : null;

  const
    toggleOpen = () => {
      setIsOpen(!isOpen);
    },
    onSelectChange = option => {
      toggleOpen();
      props.onActivate(option.value);
    };

  options?.length && !active && props.onActivate(options[0].value);

  return (
    <div>
      <Select
        autoFocus
        classNamePrefix="selector"
        options={options}
        value={active}
        backspaceRemovesValue={false}
        components={{DropdownIndicator: SearchIcon, IndicatorSeparator: null}}
        controlShouldRenderValue={false}
        hideSelectedOptions={false}
        isClearable={false}
        menuIsOpen
        onChange={onSelectChange}
        placeholder="Search..."
        styles={selectStyles(200)}
        theme={selectTheme}
        tabSelectsValue={false}/>
    </div>
  );
}

EntityChildDropdownSelector.propTypes = {
  entitiesSelector: PropTypes.func.isRequired,
  format: PropTypes.func,
  className: PropTypes.string,
  active: PropTypes.object,
  onActivate: PropTypes.func.isRequired,
};

export default EntityChildDropdownSelector;

Also posted this question on StackOverflow

@charneykaye charneykaye added the issue/bug-unconfirmed Issues that describe a bug that hasn't been confirmed by a maintainer yet label Jan 6, 2022
@Rall3n
Copy link
Collaborator

Rall3n commented Jan 6, 2022

Hello @charneykaye,

react-select uses its own theme prop for simple style customization which clashes with muis theme prop.

You should wrap SearchIcon with a function and an instance of the original DropdownIndicator to keep the props from spreading onto the icon component, but to also retain normal functionality:

const DropdownIndicator = (props) => (<components.DropdownIndicator {...props}>
  <SearchIcon />
</components.DropdownIndicator>);

<Select
  components={{
    DropdownIndicator
  }}
/>

@Rall3n Rall3n added the awaiting-author-response Issues or PRs waiting for more information from the author label Jan 6, 2022
@charneykaye
Copy link
Author

@Rall3n great catch on that interaction between the theme props.

To clarify, what is the source of <components.DropdownIndicator/> above?

It turns out, your fix does work, simply with:

const DropdownIndicator = (props) => (<div {...props}><SearchIcon /></div>);

Anyway, you nailed it. Go take credit with the correct answer on stack overflow :)

@Rall3n Rall3n removed the awaiting-author-response Issues or PRs waiting for more information from the author label Jan 6, 2022
@Rall3n Rall3n closed this as completed Jan 6, 2022
@Rall3n
Copy link
Collaborator

Rall3n commented Jan 6, 2022

@Rall3n great catch on that interaction between the theme props.

To clarify, what is the source of <components.DropdownIndicator/> above?

It turns out, your fix does work, simply with:

const DropdownIndicator = (props) => (<div {...props}><SearchIcon /></div>);

Anyway, you nailed it. Go take credit with the correct answer on stack overflow :)

@charneykaye

You should not directly spread props onto the div element, as it contains properties unknown to the HTML <div> element. Instead you should spread props.innerProps.

But I still recommend using components.DropdownIndicator to retain basic styles and classnames. It is the default DropdownIndicator component, but it accepts custom icons as child components.

@charneykaye
Copy link
Author

Thanks @Rall3n I will take your suggestion. I did not understand where components came from, but now I see you mean import { components } from "react-select";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue/bug-unconfirmed Issues that describe a bug that hasn't been confirmed by a maintainer yet
Projects
None yet
Development

No branches or pull requests

2 participants