mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-23 04:00:04 +08:00
197 lines
4.8 KiB
JavaScript
197 lines
4.8 KiB
JavaScript
import applyNativeMethods from '../../modules/applyNativeMethods';
|
|
import ColorPropType from '../../propTypes/ColorPropType';
|
|
import createDOMElement from '../../modules/createDOMElement';
|
|
import multiplyStyleLengthValue from '../../modules/multiplyStyleLengthValue';
|
|
import StyleSheet from '../../apis/StyleSheet';
|
|
import UIManager from '../../apis/UIManager';
|
|
import View from '../View';
|
|
import ViewPropTypes from '../View/ViewPropTypes';
|
|
import React, { Component, PropTypes } from 'react';
|
|
|
|
const emptyObject = {};
|
|
const thumbDefaultBoxShadow = '0px 1px 3px rgba(0,0,0,0.5)';
|
|
const thumbFocusedBoxShadow = `${thumbDefaultBoxShadow}, 0 0 0 10px rgba(0,0,0,0.1)`;
|
|
|
|
class Switch extends Component {
|
|
static displayName = 'Switch';
|
|
|
|
static propTypes = {
|
|
...ViewPropTypes,
|
|
activeThumbColor: ColorPropType,
|
|
activeTrackColor: ColorPropType,
|
|
disabled: PropTypes.bool,
|
|
onValueChange: PropTypes.func,
|
|
thumbColor: ColorPropType,
|
|
trackColor: ColorPropType,
|
|
value: PropTypes.bool
|
|
};
|
|
|
|
static defaultProps = {
|
|
activeThumbColor: '#009688',
|
|
activeTrackColor: '#A3D3CF',
|
|
disabled: false,
|
|
style: emptyObject,
|
|
thumbColor: '#FAFAFA',
|
|
trackColor: '#939393',
|
|
value: false
|
|
};
|
|
|
|
blur() {
|
|
UIManager.blur(this._checkbox);
|
|
}
|
|
|
|
focus() {
|
|
UIManager.focus(this._checkbox);
|
|
}
|
|
|
|
render() {
|
|
const {
|
|
activeThumbColor,
|
|
activeTrackColor,
|
|
disabled,
|
|
onValueChange, // eslint-disable-line
|
|
style,
|
|
thumbColor,
|
|
trackColor,
|
|
value,
|
|
// remove any iOS-only props
|
|
onTintColor, // eslint-disable-line
|
|
thumbTintColor, // eslint-disable-line
|
|
tintColor, // eslint-disable-line
|
|
...other
|
|
} = this.props;
|
|
|
|
const { height: styleHeight, width: styleWidth } = StyleSheet.flatten(style);
|
|
const height = styleHeight || 20;
|
|
const minWidth = multiplyStyleLengthValue(height, 2);
|
|
const width = styleWidth > minWidth ? styleWidth : minWidth;
|
|
const trackBorderRadius = multiplyStyleLengthValue(height, 0.5);
|
|
const trackCurrentColor = value ? activeTrackColor : trackColor;
|
|
const thumbCurrentColor = value ? activeThumbColor : thumbColor;
|
|
const thumbHeight = height;
|
|
const thumbWidth = thumbHeight;
|
|
|
|
const rootStyle = [
|
|
styles.root,
|
|
style,
|
|
{ height, width },
|
|
disabled && styles.cursorDefault
|
|
];
|
|
|
|
const trackStyle = [
|
|
styles.track,
|
|
{
|
|
backgroundColor: trackCurrentColor,
|
|
borderRadius: trackBorderRadius
|
|
},
|
|
disabled && styles.disabledTrack
|
|
];
|
|
|
|
const thumbStyle = [
|
|
styles.thumb,
|
|
{
|
|
backgroundColor: thumbCurrentColor,
|
|
height: thumbHeight,
|
|
width: thumbWidth
|
|
},
|
|
disabled && styles.disabledThumb
|
|
];
|
|
|
|
const nativeControl = createDOMElement('input', {
|
|
checked: value,
|
|
disabled: disabled,
|
|
onBlur: this._handleFocusState,
|
|
onChange: this._handleChange,
|
|
onFocus: this._handleFocusState,
|
|
ref: this._setCheckboxRef,
|
|
style: [ styles.nativeControl, styles.cursorInherit ],
|
|
type: 'checkbox'
|
|
});
|
|
|
|
return (
|
|
<View {...other} style={rootStyle}>
|
|
<View style={trackStyle} />
|
|
<View
|
|
ref={this._setThumbRef}
|
|
style={[
|
|
thumbStyle,
|
|
value && styles.thumbOn,
|
|
{
|
|
marginLeft: value ? multiplyStyleLengthValue(thumbWidth, -1) : 0
|
|
}
|
|
]}
|
|
/>
|
|
{nativeControl}
|
|
</View>
|
|
);
|
|
}
|
|
|
|
_handleChange = (event: Object) => {
|
|
const { onValueChange } = this.props;
|
|
onValueChange && onValueChange(event.nativeEvent.target.checked);
|
|
}
|
|
|
|
_handleFocusState = (event: Object) => {
|
|
const isFocused = event.nativeEvent.type === 'focus';
|
|
const boxShadow = isFocused ? thumbFocusedBoxShadow : thumbDefaultBoxShadow;
|
|
this._thumb.setNativeProps({ style: { boxShadow } });
|
|
}
|
|
|
|
_setCheckboxRef = (component) => {
|
|
this._checkbox = component;
|
|
}
|
|
|
|
_setThumbRef = (component) => {
|
|
this._thumb = component;
|
|
}
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
root: {
|
|
cursor: 'pointer',
|
|
userSelect: 'none'
|
|
},
|
|
cursorDefault: {
|
|
cursor: 'default'
|
|
},
|
|
cursorInherit: {
|
|
cursor: 'inherit'
|
|
},
|
|
track: {
|
|
...StyleSheet.absoluteFillObject,
|
|
height: '70%',
|
|
margin: 'auto',
|
|
transitionDuration: '0.1s',
|
|
width: '90%'
|
|
},
|
|
disabledTrack: {
|
|
backgroundColor: '#D5D5D5'
|
|
},
|
|
thumb: {
|
|
alignSelf: 'flex-start',
|
|
borderRadius: '100%',
|
|
boxShadow: thumbDefaultBoxShadow,
|
|
left: '0%',
|
|
transform: [
|
|
{ translateZ: 0 }
|
|
],
|
|
transitionDuration: '0.1s'
|
|
},
|
|
thumbOn: {
|
|
left: '100%'
|
|
},
|
|
disabledThumb: {
|
|
backgroundColor: '#BDBDBD'
|
|
},
|
|
nativeControl: {
|
|
...StyleSheet.absoluteFillObject,
|
|
height: '100%',
|
|
margin: 0,
|
|
opacity: 0,
|
|
padding: 0,
|
|
width: '100%'
|
|
}
|
|
});
|
|
|
|
module.exports = applyNativeMethods(Switch);
|