I'm using React Select v2 in my project with Styled Components and I need to be able to turn the arrow indicator upside down when the menu is open, which was supported in v1.
I kinda managed to do it by doing this:
css`
&.react-select__control--is-focused {
& .react-select__indicators {
& .react-select__dropdown-indicator {
transform: rotate(180deg);
}
}
}
`;
Problem is that, if I press the arrow to open the menu and click on it again to close it, the arrow stays upside down because the select is still focused, which feels a bit weird in terms of UIX.
Is there a proper way to rotate it based on the state of the menu? I looked for something in the documentation but I couldn't find it.
Maybe I missed it, if someone could point me in the right direction, that'd be awesome!
Thanks!
Technically you can use the style-in-JS props of the v2. Like the following example:
dropdownIndicator: (base, state) => ({
...base,
transition: 'all .2s ease',
transform: state.isFocused ? 'rotate(180deg)' : null
})
It seems that the isFocused
state isn't bind with the isMenuOpen
state but with the real focus
state of the container.
A solution is to set closeMenuOnSelect={false}
so the user would have to click outside the select and your arrow will flip back.
Or you could change the className
props using onMenuOpen
and onMenuClose
by adding a specific suffix to target your animation.
UPDATE
You can directly access the menuOpen
props via the state
so no need to manually add class like the following:
dropdownIndicator: (base, state) => ({
...base,
transition: 'all .2s ease',
transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : null
})
PLEASE NOTE THAT
In react-select
v2.3 a control--menu-is-open
has been added directly in the code.
So, based on Laura's response, my solution was to use the onMenuClose
and onMenuOpen
to set the state of a property in my styled component.
const indicatorStyle = (props: StyledSelectProps & DropdownProps<{}>) => css`
& .react-select__indicators {
& .react-select__dropdown-indicator {
transition: all .2s ease;
transform: ${props.isOpen && "rotate(180deg)"};
}
}
`;
This function is called inside of my styled component's css.
And then in the component I call my styled component, I control the state:
export class Dropdown<TValue> extends React.Component<DropdownProps<TValue>> {
public state = { isOpen: false };
private onMenuOpen = () => this.setState({ isOpen: true });
private onMenuClose = () => this.setState({ isOpen: false });
public render() {
const { ...props } = this.props;
const { isOpen } = this.state;
return (
<StyledSelect {...props} isOpen={isOpen} onMenuOpen={this.onMenuOpen} onMenuClose={this.onMenuClose} />
);
}
}
A bit convoluted but it works for now.