Как установить ширину реакции-выбора в зависимости от самой большой ширины параметра?

Как установить ширину ввода с реактивным выбором в зависимости от самой большой ширины параметра? Положение опций является абсолютным, поэтому их размер не влияет на ширину родительского div.

Это пример: https://codesandbox.io/s/9o4rkklz14

Мне нужно выбрать ширину, чтобы была самая длинная ширина варианта.


person Yarikhp    schedule 12.12.2018    source источник
comment
Добро пожаловать в StackOverflow, я бы порекомендовал вам прочитать это руководство по минимальному, полному и проверяемому примеру и показать нам, что вы уже пробовали. чтобы решить вашу проблему.   -  person Laura    schedule 12.12.2018
comment
Я добавил минимальный пример.   -  person Yarikhp    schedule 12.12.2018
comment
Но в вашем примере есть только один вариант с коротким вводом и самым длинным значением, что вы действительно хотите сделать? В «Выбранном варианте» отображается только метка.   -  person only_one    schedule 13.12.2018
comment
Мне нужно автоматизировать размер элемента управления в зависимости от самых длинных вариантов. Теперь контроль расширяется по ширине родительского элемента.   -  person Yarikhp    schedule 13.12.2018


Ответы (1)


Я ответил на это в нескольких темах, здесь и здесь для получения дополнительной информации о сложностях и предостережениях, но вот суть подхода.

  1. Вам нужно установить автоматическую ширину меню, чтобы оно растягивалось, чтобы соответствовать его содержимому.

  2. onMount, задайте стиль меню (высота: 0, видимость: скрыта) и откройте меню с помощью метода внутренней ссылки

  3. С опорой onMenuOpen используйте функцию, которая ждет 1 мс, получите ширину listMenuRef и закройте / сбросьте menuIsOpen.

  4. С рассчитанной шириной теперь вы можете установить ширину ValueContainer.

Результат можно увидеть здесь на этот кодовый ящик

Код размещен ниже ...

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;
person BornReady    schedule 09.12.2020