【问题标题】:Material UI dropdown showing inappropriate heightMaterial UI 下拉菜单显示不合适的高度
【发布时间】:2020-06-23 10:45:09
【问题描述】:

我正在尝试使用 react-select 库在我的网站中使用 Material UI 下拉菜单。问题是,当我使用比下拉列表宽度更长的选项时,它会影响 UI。

谁能帮帮我。

这是我的反应代码:

import React, { useState } from "react";
import "./styles.css";
import SelectDropdown from "./EditableDropdown";

export default function App() {
  const [description, setDesc] = useState("");

  const options = [
    {
      label: "a11 b33 c88 o99 t66 j44 z99",
      value: "a11 b33 c88 o99 t66 j44 z99"
    },
    {
      label: "Switches",
      value: "Switches"
    }
  ];

  return (
    <div style={{ width: "25%" }}>
      <SelectDropdown
        label="Description"
        value={description}
        onChange={setDesc}
        options={options}
      />
    </div>
  );
}

这是可编辑组件的代码

import React from "react";
import {
  MuiThemeProvider,
  createMuiTheme,
  MenuItem,
  Paper,
  withStyles,
  TextField
} from "@material-ui/core";
import Select from "react-select";

const styles = {
  input: {
    padding: 0,
    marginSides: "8px",
    minHeight: "inherit",
    lineHeight: "22px",
    fontWeight: 200
  },
  valueContainer: {
    alignItems: "center",
    fontFamily: "Helvetica Neue,Arial,Helvetica,sans-serif",
    fontWeight: 400,
    fontSize: "14px !important"
  }
};

function inputComponent({ inputRef, ...props }) {
  return <div ref={inputRef} {...props} />;
}

function Control(props) {
  return (
    <TextField
      fullWidth
      InputProps={{
        inputComponent,
        inputProps: {
          className: props.selectProps.classes.input,
          children: props.children,
          ...props.innerProps
        }
      }}
      {...props.selectProps.textFieldProps}
    />
  );
}

function Option(props) {
  return (
    <MenuItem
      buttonRef={props.innerRef}
      selected={props.isFocused}
      component="div"
      style={{
        fontWeight: props.isSelected ? 500 : 400,
        backgroundColor: props.isSelected
          ? "rgba(59,234,31,0.2)"
          : props.isFocused
          ? "#F0F0F0"
          : null,
        fontFamily: "Helvetica Neue,Arial,Helvetica,sans-serif",
        height: "34px",
        color: "#343434"
      }}
      {...props.innerProps}
    >
      {props.children}
    </MenuItem>
  );
}

function SingleValue(props) {
  return (
    <div
      className={props.selectProps.classes.singleValue}
      {...props.innerProps}
    >
      {typeof props.children !== "object" ? props.children : ""}
    </div>
  );
}

function ValueContainer(props) {
  let valueContainerClass = props.selectProps.classes.valueContainer;
  return (
    <div className={valueContainerClass} ref={props.inputRef}>
      {props.children}
    </div>
  );
}

function Menu(props) {
  return (
    <Paper square {...props.innerProps}>
      {props.children}
    </Paper>
  );
}

const dropDownStyle = {
  overrides: {
    MuiOutlinedInput: {
      root: {
        padding: "12px 12px 12px 16px !important"
      }
    },
    MuiInputBase: {
      root: {
        cursor: "pointer"
      }
    }
  }
};

class SelectDropdown extends React.Component {
  state = {
    focused: false
  };

  handleTextFieldChange = ({ target: { value } }) => {
    this.props.onChange({
      label: value,
      value
    });
  };

  components = {
    Control,
    Menu,
    Option,
    SingleValue,
    ValueContainer,
    IndicatorSeparator: () => null,
    DropdownIndicator: () => null
  };

  render() {
    const { classes, options, onChange, value } = this.props;

    const selectStyles = {
      clearIndicator: () => ({
        display: "none"
      }),
      noOptionsMessage: () => ({
        display: "none"
      })
    };
    return (
      <MuiThemeProvider theme={createMuiTheme(dropDownStyle)}>
        <Select
          styles={selectStyles}
          isClearable={true}
          classes={classes}
          onChange={onChange}
          backspaceRemovesValue={true}
          textFieldProps={{
            label: this.props.label,
            variant: "outlined",
            InputLabelProps: value ? { shrink: true } : {},
            onChange: this.handleTextFieldChange
          }}
          value={value}
          components={this.components}
          isSearchable={true}
          placeholder=""
          options={options}
        />
      </MuiThemeProvider>
    );
  }
}

export default withStyles(styles, { withTheme: true })(SelectDropdown);

这里是沙箱中相同代码的链接:https://codesandbox.io/s/editable-dropdown-ckf1r

【问题讨论】:

  • 我相信这是因为你有&lt;div style={{ width: "25%" }}&gt; 限制了长度。你可能想增加宽度。或者你的意思是说,当它被选中并且溢出时,你不希望它显示这种方式?
  • 那是前一段时间了.. 我可能已经尝试过了,但没有运气.. 无论如何,请随时在您的最后尝试.. 使用沙盒。让我知道这是否适合您。非常感谢您的关注。
  • 而且我不需要那里的全宽。我需要在那里显示一个较小的输入字段。
  • 我建议你直接使用 Material-UI Select 组件,而不是你现在实现的反弹
  • EditableDropdown组件是你自己写的吗?

标签: css reactjs user-interface material-ui react-select


【解决方案1】:

我相信你最好直接使用material-ui 而不是EditableDropdown。由于后者有局限性。

另外,您最好使用更新版本的 Material-UI。

这是 Material-UI (V4.9.5) 中的代码,可以按照您的意愿工作。如果你想给它添加样式,你总是可以使用 CSS 来

import React from 'react';
import TextField from '@material-ui/core/TextField';
import Autocomplete, { createFilterOptions } from '@material-ui/lab/Autocomplete';

const filter = createFilterOptions();

export default function FreeSoloCreateOption() {
  const [value, setValue] = React.useState(null);

  return (
    <Autocomplete
      value={value}
      onChange={(event, newValue) => {
        if (newValue && newValue.inputValue) {
          setValue({
            title: newValue.inputValue,
          });

          return;
        }

        setValue(newValue);
      }}
      filterOptions={(options, params) => {
        const filtered = filter(options, params);

        if (params.inputValue !== '') {
          filtered.push({
            inputValue: params.inputValue,
            title: `Add "${params.inputValue}"`,
          });
        }

        return filtered;
      }}
      id="free-solo-with-text-demo"
      options={top100Films}
      getOptionLabel={option => {
        // e.g value selected with enter, right from the input
        if (typeof option === 'string') {
          return option;
        }
        if (option.inputValue) {
          return option.inputValue;
        }
        return option.title;
      }}
      renderOption={option => option.title}
      style={{ width: 300 }}
      freeSolo
      renderInput={params => (
        <TextField {...params} label="Free solo with text demo" variant="outlined" />
      )}
    />
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
  { title: 'Raiders of the Lost Ark', year: 1981 },
  { title: 'Rear Window', year: 1954 },
  { title: 'The Pianist', year: 2002 },
  { title: 'The Departed', year: 2006 },
  { title: 'Terminator 2: Judgment Day', year: 1991 },
  { title: 'Back to the Future', year: 1985 },
  { title: 'Whiplash', year: 2014 },
  { title: 'Gladiator', year: 2000 },
  { title: 'Memento', year: 2000 },
  { title: 'The Prestige', year: 2006 },
  { title: 'The Lion King', year: 1994 },
  { title: 'Apocalypse Now', year: 1979 },
  { title: 'Alien', year: 1979 },
  { title: 'Sunset Boulevard', year: 1950 },
  {
    title: 'Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb',
    year: 1964,
  },
];

参考:https://material-ui.com/components/autocomplete/ 代码链接:https://codesandbox.io/s/gbljf

如果这有帮助,请告诉我。

【讨论】:

  • 我最初考虑过使用自动完成组件,但它显示了一些限制。(下拉没有自定义滚动条,当没有找到选项时,它显示一个新选项“添加***”和等等..)。另外,我之前已经使用过 react-selct,所以我必须坚持下去。不过,我确实很感谢您的努力..
  • 所以我真的想知道,如果我们可以用 CSS 做点什么,以避免溢出并显示省略号
  • 我不确定添加选项和滚动因为我使用它,所有这些都完美地工作。你应该看看并尝试。您正在使用的 react-select 使用的是过时版本的 Material UI。老实说,您最好直接使用 Material-UI 并使用周围的样式。我发送给您的示例无需太多工作即可按您的意愿工作。试试我发给你的东西,看看我的意思。
  • 再次感谢......我正在做更多的功能,我的项目中的 UI 样式比我在问题中显示的要多得多。我也严格要求在我的应用程序中使用旧的 MUI。请参阅.. 我在这里使用的是旧版应用程序,因此在任何情况下都没有新库或更改现有库的范围。
  • 对!我明白。我时不时面临着类似的挑战。让我看看能不能帮你破解一些东西。
猜你喜欢
相关资源
最近更新 更多
热门标签