Раскрывающийся список пользовательского интерфейса материала, показывающий несоответствующую высоту - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь использовать Раскрывающийся пользовательский интерфейс на моем веб-сайте, используя библиотеку Reaction-select . Проблема в том, что когда я использую опцию длиннее, чем ширина раскрывающегося меню, это ставит под угрозу пользовательский интерфейс.

Может кто-нибудь, пожалуйста, помогите мне здесь.

Вот мой код реагирования :

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

1 Ответ

1 голос
/ 12 марта 2020

Полагаю, вам лучше использовать 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

Дайте мне знать, если это поможет.

...