如何根据最大选项宽度设置反应选择宽度?

时间:2018-12-12 11:44:08

标签: css reactjs styles react-select

如何根据最大选项宽度设置反应选择输入宽度?选项的位置是绝对的,因此它们的大小不会影响父div的宽度。

例如:https://codesandbox.io/s/9o4rkklz14

我需要选择宽度为最长的选项宽度。

1 个答案:

答案 0 :(得分:0)

我已经在几个问题线程herehere中对此进行了回答,以获取有关复杂性和警告的更多背景信息,但这是该方法的要旨。

  1. 您需要将菜单的宽度设置为自动,以便其拉伸以适合其内容。

  2. onMount,设置菜单样式(高度:0,可见性:隐藏),并使用内部ref方法打开菜单

  3. 使用onMenuOpen道具,使用一个等待1毫秒的函数,获取listMenuRef的宽度,然后关闭/重置menuIsOpen。​​

  4. 使用计算出的宽度,您现在可以设置ValueContainer的宽度。

可以看到结果here at this codesandbox

下面发布的代码...

import React, { useState, useRef, useEffect } from "react";
import Select from "react-select";

const App = (props) => {
  const selectRef = useRef();

  const [menuIsOpen, setMenuIsOpen] = useState();
  const [menuWidth, setMenuWidth] = useState();
  const [isCalculatingWidth, setIsCalculatingWidth] = useState(false);

  useEffect(() => {
    if (!menuWidth && !isCalculatingWidth) {
      setTimeout(() => {
        setIsCalculatingWidth(true);
        // setIsOpen doesn't trigger onOpenMenu, so calling internal method
        selectRef.current.select.openMenu("first");
        setMenuIsOpen(true);
      }, 1);
    }
  }, [menuWidth, isCalculatingWidth]);

  const onMenuOpen = () => {
    if (!menuWidth && isCalculatingWidth) {
      setTimeout(() => {
        const width = selectRef.current.select.menuListRef.getBoundingClientRect()
          .width;
        setMenuWidth(width);
        setIsCalculatingWidth(false);

        // setting isMenuOpen to undefined and closing menu
        selectRef.current.select.onMenuClose();
        setMenuIsOpen(undefined);
      }, 1);
    }
  };

  const styles = {
    menu: (css) => ({
      ...css,
      width: "auto",
      ...(isCalculatingWidth && { height: 0, visibility: "hidden" })
    }),
    control: (css) => ({ ...css, display: "inline-flex " }),
    valueContainer: (css) => ({
      ...css,
      ...(menuWidth && { width: menuWidth })
    })
  };

  const options = [
    { label: "Option 1", value: 1 },
    { label: "Option 2", value: 2 },
    { label: "Option 3 is a reallly realllly long boi", value: 3 }
  ];

  return (
    <div>
      <div> Width of menu is {menuWidth}</div>
      <Select
        ref={selectRef}
        onMenuOpen={onMenuOpen}
        options={options}
        styles={styles}
        menuIsOpen={menuIsOpen}
      />
    </div>
  );
};

export default App;