[英]Material-UI <Radio /> with a <Button />-like appearance
Using only Material-UI, is there any way to style<Radio />
objects with a <Button />
type of appearance?仅使用 Material-UI,有什么方法可以为具有
<Button />
外观类型的<Radio />
对象设置样式吗? If not, what would be the most simple alternative?如果没有,最简单的选择是什么?
After spending the past few days reading documentation and experimenting, I don't feel any closer to a solution.在过去几天阅读文档和试验之后,我感觉离解决方案还差得很远。 Thanks to anyone who can lend some guidance.
感谢任何可以提供指导的人。
Here's my starting point (without the <Button />
experiments) in case anyone would like to use what I'm working with:这是我的起点(没有
<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);
For anyone who is using an older version of Material-UI that lacks the built-in solution as per the answer below, you'll have to create your own CSS for the buttons.对于使用缺少内置解决方案的旧版本 Material-UI 的任何人,您必须为按钮创建自己的 CSS。 If you need help, this is how I implemented it:
如果您需要帮助,我就是这样实现的:
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="〇"
checkedIcon="〇"
/>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="okay"
classes={{
root: classes.yellowButtonRoot,
checked: classes.checked,
disabled: classes.disabled
}}
icon="△"
checkedIcon="△"
disabled={binaryChoice}
/>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="bad"
classes={{
root: classes.redButtonRoot,
checked: classes.checked
}}
icon="✕"
checkedIcon="✕"
/>
<Radio
htmlFor={id}
className={classes.radioFlex}
value="na"
classes={{
root: classes.greyButtonRoot,
checked: classes.checked
}}
icon="-"
checkedIcon="-"
/>
</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);
Usage...用法...
<QRadios
error={!whateverThing.isValid}
id="whateverThing"
name="whateverThing"
label="What's your judgement of whateverThing?"
value={whateverThing.value}
onChange={this.someHandlerFunc}
onBlur={this.someCheckFunc}
/>
Have you looked into https://material-ui.com/components/toggle-button/ or https://material-ui.com/api/toggle-button-group/ ?您是否查看过https://material-ui.com/components/toggle-button/或https://material-ui.com/api/toggle-button-group/ ? I think it's a relatively new addition (ie didn't exist when you resolved this), but it might be helpful for anyone who finds this question later.
我认为这是一个相对较新的补充(即在您解决此问题时不存在),但它可能对以后发现此问题的任何人都有帮助。
The ToggleButtonGroup will control the selected state of its child buttons when given its own value prop.
ToggleButtonGroup 将在给定自己的 value 属性时控制其子按钮的选定状态。
Here's the example given on that page:这是该页面上给出的示例:
<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>
This was you can make a radio button have a button like, i have created a pen for this please check https://codepen.io/praveen-rao-chavan/pen/JBpgLX这是你可以让一个单选按钮有一个按钮,我为此创建了一支笔,请检查https://codepen.io/praveen-rao-chavan/pen/JBpgLX
<section>
<h1>Simple material design CSS only radio button example</h1>
<div>
<ul class="donate-now">
<li class="md-radio">
<input id="1" type="radio" name="g" checked>
<label for="1">Option 1</label>
</li>
<li class="md-radio">
<input id="2" type="radio" name="g">
<label for="2">Option 2</label>
</li>
</ul>
</div>
</section>
CSS CSS
@import url(https://fonts.googleapis.com/css?family=Roboto);
$md-radio-checked-color: rgb(51, 122, 183);
$md-radio-border-color: rgba(0, 0, 0, 0.54);
$md-radio-size: 20px;
$md-radio-checked-size: 10px;
$md-radio-ripple-size: 15px;
@keyframes ripple {
0% {
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.0);
}
50% {
box-shadow: 0px 0px 0px $md-radio-ripple-size rgba(0, 0, 0, 0.1);
}
100% {
box-shadow: 0px 0px 0px $md-radio-ripple-size rgba(0, 0, 0, 0);
}
}
.md-radio {
margin: 16px 0;
&.md-radio-inline {
display: inline-block;
}
input[type="radio"] {
display: none;
&:checked + label:before {
--border-color: $md-radio-checked-color;
--animation: ripple 0.2s linear forwards;
}
&:checked + label:after {
--transform: scale(1);
}
}
label {
display: inline-block;
height:$md-radio-size;
position: relative;
padding: 0 ($md-radio-size + 10px);
margin-bottom: 0;
cursor: pointer;
vertical-align: bottom;
&:before, &:after {
position: absolute;
content: '';
border-radius: 50%;
transition: all .3s ease;
transition-property: transform, border-color;
}
&:before {
left: 0;
top: 0;
width: $md-radio-size;
height: $md-radio-size;
border: 2px solid $md-radio-border-color;
}
&:after {
top: $md-radio-size / 2 - $md-radio-checked-size / 2;
left: $md-radio-size / 2 - $md-radio-checked-size / 2;
width:$md-radio-checked-size;
height:$md-radio-checked-size;
transform: scale(0);
background:$md-radio-checked-color;
}
}
}
// *************************************
// *************************************
*, *:before, *:after {
box-sizing: border-box;
}
body {
background:#f0f0f0;
position: absolute;
width:100%;
padding:0;
margin:0;
font-family: "Roboto", sans-serif;
color: #333;
}
section {
background:white;
margin:0 auto;
padding: 4em;
max-width: 800px;
h1 {
margin: 0 0 2em;
}
}
.donate-now {
list-style-type:none;
margin:25px 0 0 0;
padding:0;
}
.donate-now li {
float:left;
margin:0 5px 0 0;
width:100px;
height:40px;
position:relative;
}
.donate-now label, .donate-now input {
display:block;
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
}
.donate-now input[type="radio"] {
opacity:0.011;
z-index:100;
}
.donate-now input[type="radio"]:checked + label {
background:yellow;
}
.donate-now label {
padding:5px;
border:1px solid #CCC;
cursor:pointer;
z-index:90;
}
.donate-now label:hover {
background:#DDD;
}
You can customize it to your styles.您可以根据自己的风格自定义它。
I use MUi5 toggle button and overwrite their style to become button-like我使用 MUi5 切换按钮并覆盖它们的样式以变成类似按钮的样式
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.