Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
552 views
in Technique[技术] by (71.8m points)

javascript - Select is not working onClick IconComponent(dropdown-arrow) in react material ui

Below is my code snippet. I am facing an issue, when I click on IconComponent(dropdown-arrow), Select component is not opening.

<Select
  IconComponent={() => (
    <ExpandMore className="dropdown-arrow" />
  )}
  onChange={this.handleSelectUpdate.bind(this)}
  value={this.state.somestate}
  inputProps={{
    name: "someprops1",
    id: "someprops1"
  }}
  disabled={this.props.someprops1.length === 1}
  className="dropdown"
>
  >
  {_.map(this.props.someprops2, (item, id) => {
    return (
      <MenuItem value={item.somekey} key={id}>
        {item.somekey}
      </MenuItem>
    );
  })}
</Select>

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In SelectInput.js(which Select leverages) the icon is rendered as follows:

<IconComponent className={classes.icon} />

With the manner that you were customizing the icon, you were ignoring the className property that SelectInput passes which prevented it from behaving correctly.

Below are a couple examples of customizing the icon. The first case uses the icon directly (IconComponent={ExpandMoreIcon}) without wrapping it in another function. The second case shows something closer to what you are trying to do (supporting specifying your own class on it). Though className is the only property that SelectInput tries to specify currently, I think you would be best off to pass through all the props:

const iconStyles = {
  selectIcon: {
    color: "green"
  }
};
const CustomExpandMore = withStyles(iconStyles)(
  ({ className, classes, ...rest }) => {
    return (
      <ExpandMoreIcon
        {...rest}
        className={classNames(className, classes.selectIcon)}
      />
    );
  }
);

Here's the full example:

import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "@material-ui/core/styles";
import InputLabel from "@material-ui/core/InputLabel";
import MenuItem from "@material-ui/core/MenuItem";
import FormControl from "@material-ui/core/FormControl";
import Select from "@material-ui/core/Select";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import clsx from "clsx";

const styles = (theme) => ({
  root: {
    display: "flex",
    flexWrap: "wrap"
  },
  formControl: {
    margin: theme.spacing.unit,
    minWidth: 120
  },
  selectEmpty: {
    marginTop: theme.spacing.unit * 2
  }
});
const iconStyles = {
  selectIcon: {
    color: "green"
  }
};
const CustomExpandMore = withStyles(iconStyles)(
  ({ className, classes, ...rest }) => {
    return (
      <ExpandMoreIcon
        {...rest}
        className={clsx(className, classes.selectIcon)}
      />
    );
  }
);

class SimpleSelect extends React.Component {
  state = {
    age: "",
    name: "hai"
  };

  handleChange = (event) => {
    this.setState({ [event.target.name]: event.target.value });
  };

  render() {
    const { classes } = this.props;

    return (
      <form className={classes.root} autoComplete="off">
        <FormControl className={classes.formControl}>
          <InputLabel htmlFor="age-simple">Age</InputLabel>
          <Select
            value={this.state.age}
            onChange={this.handleChange}
            inputProps={{
              name: "age",
              id: "age-simple"
            }}
            IconComponent={ExpandMoreIcon}
          >
            <MenuItem value="">
              <em>None</em>
            </MenuItem>
            <MenuItem value={10}>Ten</MenuItem>
            <MenuItem value={20}>Twenty</MenuItem>
            <MenuItem value={30}>Thirty</MenuItem>
          </Select>
        </FormControl>
        <FormControl className={classes.formControl}>
          <InputLabel htmlFor="age-simple">Age</InputLabel>
          <Select
            value={this.state.age}
            onChange={this.handleChange}
            inputProps={{
              name: "age",
              id: "age-simple"
            }}
            IconComponent={CustomExpandMore}
          >
            <MenuItem value="">
              <em>None</em>
            </MenuItem>
            <MenuItem value={10}>Ten</MenuItem>
            <MenuItem value={20}>Twenty</MenuItem>
            <MenuItem value={30}>Thirty</MenuItem>
          </Select>
        </FormControl>
      </form>
    );
  }
}

SimpleSelect.propTypes = {
  classes: PropTypes.object.isRequired
};

export default withStyles(styles)(SimpleSelect);

Edit Select custom icon

Here is the styling that Material-UI adds to the icon (found in NativeSelect.js which exports its styles so that Select.js can reuse them):

  icon: {
    // We use a position absolute over a flexbox in order to forward the pointer events
    // to the input and to support wrapping tags..
    position: 'absolute',
    right: 0,
    top: 'calc(50% - 12px)', // Center vertically
    pointerEvents: 'none', // Don't block pointer events on the select under the icon.
    color: theme.palette.action.active,
    '&$disabled': {
      color: theme.palette.action.disabled,
    },
  },
  /* Styles applied to the icon component if the popup is open. */
  iconOpen: {
    transform: 'rotate(180deg)',
  },
  /* Styles applied to the icon component if `variant="filled"`. */
  iconFilled: {
    right: 7,
  },
  /* Styles applied to the icon component if `variant="outlined"`. */
  iconOutlined: {
    right: 7,
  },

The absolute positioning keeps the icon within the clickable area of the Select. Without the absolute positioning, the icon will cause the different elements making up the Select to shift. Clicking in the place where the icon should be continues to work, but the way elements get shifted causes the overall layout of the Select to no longer make sense.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...