Add radio button component
parent
b038f704a8
commit
07d182a8ff
|
@ -0,0 +1,77 @@
|
|||
/* global React */
|
||||
|
||||
import { addons } from 'react/addons';
|
||||
import Ripple from '../ripple';
|
||||
import style from './style';
|
||||
import events from '../utils/events';
|
||||
|
||||
export default React.createClass({
|
||||
mixins: [addons.PureRenderMixin],
|
||||
|
||||
displayName: 'RadioButton',
|
||||
|
||||
propTypes: {
|
||||
checked: React.PropTypes.bool,
|
||||
className: React.PropTypes.string,
|
||||
disabled: React.PropTypes.bool,
|
||||
label: React.PropTypes.string,
|
||||
name: React.PropTypes.string,
|
||||
onBlur: React.PropTypes.func,
|
||||
onChange: React.PropTypes.func,
|
||||
onFocus: React.PropTypes.func,
|
||||
value: React.PropTypes.any
|
||||
},
|
||||
|
||||
getDefaultProps () {
|
||||
return {
|
||||
checked: false,
|
||||
className: '',
|
||||
disabled: false
|
||||
};
|
||||
},
|
||||
|
||||
handleChange (event) {
|
||||
if (!this.props.checked && this.props.onChange) {
|
||||
this.props.onChange(event, this);
|
||||
}
|
||||
},
|
||||
|
||||
handleClick (event) {
|
||||
events.pauseEvent(event);
|
||||
if (!this.props.disabled) this.handleChange(event);
|
||||
},
|
||||
|
||||
handleMouseDown (event) {
|
||||
if (!this.props.disabled) this.refs.ripple.start(event);
|
||||
},
|
||||
|
||||
render () {
|
||||
let labelClassName = style[this.props.disabled ? 'disabled' : 'field'];
|
||||
let radioClassName = style[this.props.checked ? 'radio-checked' : 'radio'];
|
||||
if (this.props.className) labelClassName += ` ${this.props.className}`;
|
||||
|
||||
return (
|
||||
<label className={labelClassName} onClick={this.handleClick}>
|
||||
<input
|
||||
{...this.props}
|
||||
ref='input'
|
||||
type='radio'
|
||||
className={style.input}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
<span role='radio' className={radioClassName} onMouseDown={this.handleMouseDown}>
|
||||
<Ripple ref='ripple' role='ripple' className={style.ripple} spread={3} centered />
|
||||
</span>
|
||||
{ this.props.label ? <span className={style.text}>{this.props.label}</span> : null }
|
||||
</label>
|
||||
);
|
||||
},
|
||||
|
||||
blur () {
|
||||
this.refs.input.getDOMNode().blur();
|
||||
},
|
||||
|
||||
focus () {
|
||||
this.refs.input.getDOMNode().focus();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,108 @@
|
|||
@import "../variables";
|
||||
@import "../mixins";
|
||||
$radio-button-size: 1.6 * $unit !default;
|
||||
$radio-inner-margin: $radio-button-size / 4;
|
||||
$radio-inner-color: unquote("rgb(#{$color-primary})") !default;
|
||||
$radio-focus-color: unquote("rgba(#{$color-black}, 0.1)") !default;
|
||||
$radio-checked-focus-color: unquote("rgba(#{$color-primary}, 0.26)") !default;
|
||||
$radio-text-color: unquote("rgb(#{$color-black})") !default;
|
||||
$radio-disabled-color: unquote("rgba(#{$color-black}, 0.26)") !default;
|
||||
|
||||
.field {
|
||||
position: relative;
|
||||
display: block;
|
||||
height: $radio-button-size;
|
||||
margin-bottom: 1.5 * $unit;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: inline-block;
|
||||
padding-left: $unit;
|
||||
font-size: 1.4 * $unit;
|
||||
line-height: $radio-button-size;
|
||||
color: $radio-text-color;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.input {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
opacity: 0;
|
||||
appearance: none;
|
||||
|
||||
&:focus:not(&:active) {
|
||||
+ .radio {
|
||||
box-shadow: 0 0 0 $unit $radio-focus-color;
|
||||
}
|
||||
|
||||
+ .radio-checked {
|
||||
box-shadow: 0 0 0 $unit $radio-checked-focus-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.radio {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: $radio-button-size;
|
||||
height: $radio-button-size;
|
||||
vertical-align: top;
|
||||
cursor: pointer;
|
||||
border: .2 * $unit solid $radio-text-color;
|
||||
border-radius: 50%;
|
||||
|
||||
&:before {
|
||||
@include material-animation-default();
|
||||
position: absolute;
|
||||
top: $radio-inner-margin - .2 * $unit;
|
||||
left: $radio-inner-margin - .2 * $unit;
|
||||
width: $radio-button-size - $radio-inner-margin * 2;
|
||||
height: $radio-button-size - $radio-inner-margin * 2;
|
||||
content: "";
|
||||
background-color: $radio-inner-color;
|
||||
border-radius: 50%;
|
||||
transition-property: transform;
|
||||
transform: scale3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.radio-checked {
|
||||
@extend .radio;
|
||||
border: .2 * $unit solid $radio-inner-color;
|
||||
|
||||
&:before {
|
||||
transform: scale3d(1, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.ripple {
|
||||
background-color: $radio-inner-color;
|
||||
opacity: .3;
|
||||
transition-duration: 650ms;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
@extend .field;
|
||||
|
||||
.text {
|
||||
color: $radio-disabled-color;
|
||||
}
|
||||
|
||||
.radio {
|
||||
cursor: auto;
|
||||
border-color: $radio-disabled-color;
|
||||
}
|
||||
|
||||
.radio-checked {
|
||||
cursor: auto;
|
||||
background-color: $radio-disabled-color;
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue