首页 > 解决方案 > 材质-UI

问题描述

使用Material-UI,有没有办法为<Radio />具有某种<Button />外观的对象设置样式?如果没有,最简单的选择是什么?

在过去几天阅读文档和试验之后,我觉得离解决方案没有任何距离。感谢任何可以提供一些指导的人。

这是我的起点(没有<Button />实验),以防有人想使用我正在使用的东西:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import RadioGroup from '@material-ui/core/RadioGroup';
import Radio from '@material-ui/core/Radio';
import Button from '@material-ui/core/Button';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import FormControl from '@material-ui/core/FormControl';

const styles = theme => ({
  textField: {
    marginLeft: theme.spacing.unit,
    marginRight: theme.spacing.unit,
    width: '100%',
  },
  formControl: {
    display: 'flex',
    flexBasis: '100%',
    alignItems: 'center',
  }
});

class QRadios extends React.PureComponent {
  constructor(props, context) {
    super(props, context);
    this.state = {
      value: this.props.value,
    };
  }

  handleChange = event => {
    this.setState({
      value: event.target.value,
    },
      this.props.onChange(event)); 
  };

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

    return (
      <FormControl component="ul" className={classes.formControl} required>
        <RadioGroup
          row={true}
          id={this.props.id}
          name={this.props.name}
          value={this.state.value}
          onChange={this.handleChange}
        >
          <FormControlLabel
            htmlFor={this.props.id}
            value="good"
            control={<Radio />} 
          />
          <FormControlLabel
            htmlFor={this.props.id}
            value="okay"
            control={<Radio />}
          />
          <FormControlLabel
            htmlFor={this.props.id}
            value="bad"
            control={<Radio />} 
          />
          <FormControlLabel
            htmlFor={this.props.id}
            value="na"
            control={<Radio />} 
          />
        </RadioGroup>
      </FormControl>
    );
  }
}

QRadios.propTypes = {
  classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(QRadios);

更新:

对于使用旧版 Material-UI 且缺少以下答案的内置解决方案的任何人,您必须为按钮创建自己的 CSS。如果您需要帮助,这就是我实现它的方式:

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import green from '@material-ui/core/colors/green';
import yellow from '@material-ui/core/colors/yellow';
import red from '@material-ui/core/colors/red';
import grey from '@material-ui/core/colors/grey';
import RadioGroup from '@material-ui/core/RadioGroup';
import Radio from '@material-ui/core/Radio';
import FormControl from '@material-ui/core/FormControl';
import InputLabel from '@material-ui/core/InputLabel';

const styles = theme => ({
  formControl: {
    display: 'flex',
    flexBasis: '100%',
    alignItems: 'stretch',
    margin: theme.spacing.unit * 3 / 2
  },
  formGroup: {
    alignItems: 'stretch',
    justifyContent: 'space-around',
    flexWrap: 'nowrap'
  },
  radioFlex: {
    flex: '1 1 auto',
    margin: '0 5px'
  },
  greenButtonRoot: {
    backgroundColor: '#00000004',
    borderRadius: 5,
    border: '1px solid',
    color: green.A700,
    fontFamily: 'monospace',
    fontSize: '180%',
    height: 32,
    '&$checked': {
      backgroundColor: green.A700,
      color: 'white'
    },
    '&:not($checked):hover': {
      backgroundColor: green['50']
    },
    transition: 'background-color 250ms'
  },
  yellowButtonRoot: {
    backgroundColor: '#00000004',
    borderRadius: 5,
    border: '1px solid',
    color: yellow['700'],
    fontFamily: 'monospace',
    fontSize: '200%',
    height: 32,
    '&$checked': {
      backgroundColor: yellow.A700,
      color: 'white'
    },
    '&:not($checked):hover': {
      backgroundColor: yellow['100']
    },
    transition: 'background-color 250ms'
  },
  redButtonRoot: {
    backgroundColor: '#00000004',
    borderRadius: 5,
    border: '1px solid',
    color: red.A700,
    fontFamily: 'monospace',
    fontSize: '160%',
    height: 32,
    '&$checked': {
      backgroundColor: red.A700,
      color: 'white'
    },
    '&:not($checked):hover': {
      backgroundColor: red['50']
    },
    transition: 'background-color 250ms'
  },
  greyButtonRoot: {
    backgroundColor: '#00000004',
    borderRadius: 5,
    border: '1px solid',
    color: grey['700'],
    fontFamily: 'monospace',
    fontSize: '180%',
    height: 32,
    '&$checked': {
      backgroundColor: grey['700'],
      color: 'white'
    },
    '&:not($checked):hover': {
      backgroundColor: grey['200']
    },
    transition: 'background-color 250ms'
  },
  disabled: {
    backgroundColor: '#00000004'
  },
  checked: {}
});

function QRadios(props) {
  const {
    classes,
    error,
    required,
    id,
    label,
    name,
    binaryChoice,
    value,
    onChange,
    onBlur
  } = props;

  return (
    <FormControl className={classes.formControl} required={required}>
      <InputLabel
        error={error}
        required={required}
        shrink
        style={{
          position: 'relative',
          marginBottom: '10px'
        }}
      >
        {label}
      </InputLabel>
      <RadioGroup
        className={classes.formGroup}
        row

        id={id}
        name={name}

        value={value}
        onChange={onChange}
        onBlur={onBlur}
      >
        <Radio
          htmlFor={id}
          className={classes.radioFlex}

          value="good"
          classes={{
            root: classes.greenButtonRoot,
            checked: classes.checked
          }}
          icon="〇&quot;
          checkedIcon="〇&quot;
        />
        <Radio
          htmlFor={id}
          className={classes.radioFlex}

          value="okay"
          classes={{
            root: classes.yellowButtonRoot,
            checked: classes.checked,
            disabled: classes.disabled
          }}
          icon="△&quot;
          checkedIcon="△&quot;
          disabled={binaryChoice}
        />
        <Radio
          htmlFor={id}
          className={classes.radioFlex}

          value="bad"
          classes={{
            root: classes.redButtonRoot,
            checked: classes.checked
          }}
          icon="✕&quot;
          checkedIcon="✕&quot;
        />
        <Radio
          htmlFor={id}
          className={classes.radioFlex}

          value="na"
          classes={{
            root: classes.greyButtonRoot,
            checked: classes.checked
          }}
          icon="-&quot;
          checkedIcon="-&quot;
        />
      </RadioGroup>
    </FormControl>
  );
}

QRadios.propTypes = {
  classes: PropTypes.object.isRequired,
  required: PropTypes.bool,
  error: PropTypes.bool,
  id: PropTypes.string.isRequired,
  label: PropTypes.string.isRequired,
  name: PropTypes.string.isRequired,
  binaryChoice: PropTypes.bool,
  value: PropTypes.string,
  onChange: PropTypes.func.isRequired,
  onBlur: PropTypes.func
};

QRadios.defaultProps = {
  required: false,
  binaryChoice: false,
  error: false,
  onBlur: null,
  value: ''
};

export default withStyles(styles)(QRadios);

用法...

<QRadios
    error={!whateverThing.isValid}
    id="whateverThing"
    name="whateverThing"
    label="What's your judgement of whateverThing?"
    value={whateverThing.value}
    onChange={this.someHandlerFunc}
    onBlur={this.someCheckFunc}
/>

标签: reactjsmaterial-ui

解决方案


您是否查看过https://material-ui.com/components/toggle-button/https://material-ui.com/api/toggle-button-group/?我认为这是一个相对较新的添加(即当您解决此问题时不存在),但它可能对以后发现此问题的任何人有所帮助。

ToggleButtonGroup 将在给定自己的 value 属性时控制其子按钮的选定状态。

这是该页面上给出的示例:

      <ToggleButtonGroup
        value={alignment}
        exclusive
        onChange={handleAlignment}
        aria-label="text alignment"
      >
        <ToggleButton value="left" aria-label="left aligned">
          <FormatAlignLeftIcon />
        </ToggleButton>
        <ToggleButton value="center" aria-label="centered">
          <FormatAlignCenterIcon />
        </ToggleButton>
        <ToggleButton value="right" aria-label="right aligned">
          <FormatAlignRightIcon />
        </ToggleButton>
        <ToggleButton value="justify" aria-label="justified" disabled>
          <FormatAlignJustifyIcon />
        </ToggleButton>
      </ToggleButtonGroup>

推荐阅读