标题,下划线 动画
禁用
import React from 'react' import {RadioButton, RadioButtonGroup} from 'material-ui/RadioButton' import MenuItem from 'material-ui/MenuItem' import get from 'lodash/get' import styled from "styled-components"; const Checked = <svg t="1606281388606" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2858" width="30" height="30"> <path d="M512 810.667c-164.693 0-298.667-134.016-298.667-298.667s133.973-298.667 298.667-298.667c164.651 0 298.667 134.016 298.667 298.667s-134.016 298.667-298.667 298.667zM512 253.184c-142.72 0-258.859 116.096-258.859 258.816s116.139 258.816 258.859 258.816c142.763 0 258.816-116.181 258.816-258.816 0-142.763-116.053-258.816-258.816-258.816z" p-id="2859" fill="#00bcd4" /> <path d="M682.667 512c0 94.257-76.41 170.667-170.667 170.667s-170.667-76.41-170.667-170.667c0-94.257 76.41-170.667 170.667-170.667s170.667 76.41 170.667 170.667z" p-id="2860" fill="#00bcd4" /> </svg> const UnChecked = <div style={{30,height:30,marginTop:1}}> <svg t="1606281728538" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3340" width="29" height="29"> <path d="M512 810.667c-164.693 0-298.667-134.016-298.667-298.667s133.973-298.667 298.667-298.667c164.651 0 298.667 134.016 298.667 298.667s-134.016 298.667-298.667 298.667zM512 253.184c-142.72 0-258.859 116.096-258.859 258.816s116.139 258.816 258.859 258.816c142.763 0 258.816-116.181 258.816-258.816 0-142.763-116.053-258.816-258.816-258.816z" p-id="3341"/> </svg> </div> const DisableChecked = <svg t="1606281388606" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2858" width="30" height="30"> <path d="M512 810.667c-164.693 0-298.667-134.016-298.667-298.667s133.973-298.667 298.667-298.667c164.651 0 298.667 134.016 298.667 298.667s-134.016 298.667-298.667 298.667zM512 253.184c-142.72 0-258.859 116.096-258.859 258.816s116.139 258.816 258.859 258.816c142.763 0 258.816-116.181 258.816-258.816 0-142.763-116.053-258.816-258.816-258.816z" p-id="2859" fill="rgba(0, 0, 0, 0.3)" /> <path d="M682.667 512c0 94.257-76.41 170.667-170.667 170.667s-170.667-76.41-170.667-170.667c0-94.257 76.41-170.667 170.667-170.667s170.667 76.41 170.667 170.667z" p-id="2860" fill="rgba(0, 0, 0, 0.3)" /> </svg> const DisableUnChecked = <div style={{30,height:30,marginTop:1}}> <svg t="1606281728538" className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3340" width="29" height="29"> <path d="M512 810.667c-164.693 0-298.667-134.016-298.667-298.667s133.973-298.667 298.667-298.667c164.651 0 298.667 134.016 298.667 298.667s-134.016 298.667-298.667 298.667zM512 253.184c-142.72 0-258.859 116.096-258.859 258.816s116.139 258.816 258.859 258.816c142.763 0 258.816-116.181 258.816-258.816 0-142.763-116.053-258.816-258.816-258.816z" p-id="3341" fill='rgba(0, 0, 0, 0.3)' /> </svg> </div> let font = 16; class RadioButtons extends React.Component { constructor(props) { const {defaultValue} = props; super(props); this.state = { checked: defaultValue, tp:40, lf:5, transform:false } } handleChange = (e) => { const {onChange} = this.props; this.setState({ checked:e.value, transform:true, }) setTimeout(()=>{ this.setState({ transform:false }) },400) if (typeof onChange === 'function') { onChange(e.value); } } componentDidMount() { // 标题动画 const {defaultValue,onChange} = this.props; setTimeout(()=>{ this.setState({ fs:14, tp:15, lf:0 }) },10) if(defaultValue){ onChange(defaultValue) } } diff(obj1, obj2) { let o1 = obj1 instanceof Object; let o2 = obj2 instanceof Object; if (!o1 || !o2) {/* 判断不是对象 */ return obj1 === obj2; } if (Object.keys(obj1).length !== Object.keys(obj2).length) { return false; //Object.keys() 返回一个由对象的自身可枚举属性(key值)组成的数组,例如:数组返回下表:let arr = ["a", "b", "c"];console.log(Object.keys(arr))->0,1,2; } for (let attr in obj1) { let t1 = obj1[attr] instanceof Object; let t2 = obj2[attr] instanceof Object; if (t1 && t2) { return this.diff(obj1[attr], obj2[attr]); } else if (obj1[attr] !== obj2[attr]) { return false; } } // 如果相等,返回true return true; } componentWillReceiveProps(nextProps, nextContext) { if(!this.diff(nextProps.defaultValue,this.props.defaultValue)){ this.setState({ checked: nextProps.defaultValue },()=>{ this.props.onChange(nextProps.defaultValue &&nextProps.defaultValue); }) } if(!this.diff(nextProps.options,this.props.options)){ this.setState({ checked:nextProps.options && nextProps.options[0].value },()=>{ this.props.onChange(nextProps.options &&nextProps.options[0].value); }) } } render() { const { value, disabled, options, optionText, optionValue, floatingLabelText, errorText } = this.props; const {checked,transform} = this.state; return ( <RadioButtons.Root> <span className={'radioTitle'} style={{ top:this.state.tp, left:this.state.lf, color: disabled ? 'rgba(0, 0, 0, 0.3)' : transform ? 'rgba(14,119,209)':'rgba(0, 0, 0, 0.3)' }} >{floatingLabelText}</span> <div className={'radioBox'} style={{ borderBottom: disabled ? '2px dotted rgba(0 ,0 ,0 ,.3)' : errorText ? '2px solid #f44336' : '1px solid rgba(178,178,178,.4)' }} > {options.map(item=>( <div key={item.value} className={'radioItem'} onClick={()=>{ if (disabled){ return } this.handleChange(item) }} > {checked === item.value ? ( disabled ? DisableChecked: Checked) : ( disabled ? DisableUnChecked: UnChecked)} <span style={{color:disabled?'rgba(0, 0, 0, 0.3)':'#333'}}>{item.text}</span> </div> ))} </div> <hr className={'transformLine'} style={{ transform: transform ? 'scaleX(1)' :'scaleX(0)' }}/> <div className={'errorText'}>{errorText}</div> </RadioButtons.Root> ) } } setTimeout(()=>{ font = 12 },1000) RadioButtons.Root = styled.div` position:relative; padding-top: 10px; margin-top: 20px; margin-bottom: 8px; .radioTitle { transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; z-index: 1; transform: scale(0.75) translate(0px, -28px); transform-origin: left top; pointer-events: none; user-select: none; position: absolute; } .radioBox { display:flex; align-items: center; justify-content: space-around; } .radioItem { display:flex; align-items: center; } .errorText { position: relative; bottom: -5px; font-size: 12px; line-height: 12px; color: rgb(244, 67, 54); transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; } .transformLine { border-top: none rgb(14, 119, 209); border-left: none rgb(14, 119, 209); border-right: none rgb(14, 119, 209); border-bottom: 2px solid rgb(14, 119, 209); bottom: 8px; box-sizing: content-box; margin: 0px; bottom:0; position: absolute; 100%; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; } ` export default RadioButtons;