在 React-select v2 中旋转箭头指示器

IT技术 reactjs react-select
2021-05-08 19:37:36

我在我的带有样式组件的项目中使用 React Select v2,我需要能够在菜单打开时将箭头指示器倒置,这在 v1 中受支持。

我有点设法通过这样做来做到这一点:

   css`
     &.react-select__control--is-focused {
       & .react-select__indicators {
         & .react-select__dropdown-indicator {
           transform: rotate(180deg);
         }
       }
     }
   `;

问题是,如果我按下箭头打开菜单并再次单击它关闭它,箭头保持倒置,因为选择仍然是焦点,这在 UIX 方面感觉有点奇怪。

是否有根据菜单状态旋转它的正确方法?我在文档中寻找了一些东西,但找不到。

也许我错过了,如果有人能指出我正确的方向,那就太棒了!

谢谢!

4个回答

从技术上讲,您可以使用 v2 的 style-in-JS props。像下面的例子:

dropdownIndicator: (base, state) => ({
    ...base,
    transition: 'all .2s ease',
    transform: state.isFocused ? 'rotate(180deg)' : null
  })

isFocused状态似乎不是与isMenuOpen状态绑定,而是与focus容器的真实状态绑定

一种解决方案是进行设置,closeMenuOnSelect={false}以便用户必须在选择之外单击并且您的箭​​头将向后翻转。

或者您可以className使用onMenuOpenonMenuClose添加特定后缀来更改props以定位您的动画。

更新

您可以menuOpen通过直接访问props,state因此无需手动添加类,如下所示:

dropdownIndicator: (base, state) => ({
  ...base,
  transition: 'all .2s ease',
  transform: state.selectProps.menuIsOpen ? 'rotate(180deg)' : null
})

请注意

react-selectv2.3control--menu-is-open中已经直接在代码中添加了。

这对我有用

<select styles={{
            dropdownIndicator: (provided, state) => ({
              ...provided,
              transform: state.selectProps.menuIsOpen && "rotate(180deg)"
            })
          }}
/>

因此,根据 Laura 的回应,我的解决方案是在我的样式化组件中使用onMenuCloseonMenuOpen设置属性的状态。

const indicatorStyle = (props: StyledSelectProps & DropdownProps<{}>) => css`
  & .react-select__indicators {
      & .react-select__dropdown-indicator {
        transition: all .2s ease;
        transform: ${props.isOpen && "rotate(180deg)"};
      }
    }
`;

这个函数在我的样式组件的 css 内部调用。

然后在我调用样式化组件的组件中,我控制状态:

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} />
    );
  }
}

有点令人费解,但它现在有效。

这对我有用。

  dropdownIndicator: (base, state) => ({
    ...base,
    transform: state.selectProps.menuIsOpen ? 'rotate(-90deg)' : 'rotate(0)',
    transition: '250ms',
  }),