weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
218 lines (205 loc) • 5.51 kB
JSX
'use strict';
/** @jsx createElement */
import { createElement, Component, PropTypes } from 'rax';
import { isWeb, isWeex } from 'nuke-env';
import { getText, genEventObject } from './util';
class BaseInput extends Component {
constructor(props, context) {
super(props);
this.fixedFont = context.commonConfigs && context.commonConfigs.fixedFont;
if ('fixedFont' in props) {
this.fixedFont = props.fixedFont;
}
this.getRef = this.getRef.bind(this);
this.setNativeFormatRule = this.setNativeFormatRule.bind(this);
this.inputHandler = this.inputHandler.bind(this);
this.returnHandler = this.returnHandler.bind(this);
this.changeHandler = this.changeHandler.bind(this);
this.focusHandler = this.focusHandler.bind(this);
this.blurHandler = this.blurHandler.bind(this);
this.focus = this.focus.bind(this);
this.blur = this.blur.bind(this);
}
shouldComponentUpdate(nextProps) {
if (nextProps.value !== null) {
return (
nextProps.value !== this.props.value ||
nextProps.readOnly !== this.props.readOnly ||
nextProps.type !== this.props.type ||
nextProps.disabled !== this.props.disabled ||
nextProps.maxLength !== this.props.maxLength ||
nextProps['data-style'] !== this.props['data-style'] ||
nextProps.style !== this.props.style ||
nextProps.placeholder !== this.props.placeholder
);
}
return (
typeof nextProps.value !== typeof this.props.value ||
nextProps.readOnly !== this.props.readOnly ||
nextProps.type !== this.props.type ||
nextProps.disabled !== this.props.disabled ||
nextProps.maxLength !== this.props.maxLength ||
nextProps.style !== this.props['data-style'] ||
nextProps.style !== this.props.style ||
nextProps.placeholder !== this.props.placeholder
);
}
getValue() {
if (isWeb) {
return this.refs.input.value;
}
return this.refs.input.attr.value;
}
getRef() {
return this.refs.input;
}
setNativeFormatRule(rules) {
this.refs.input.setTextFormatter(rules);
}
trigger(fn, ...attrs) {
if (typeof fn === 'string') fn = this.props[fn];
if (!(typeof fn === 'function')) return;
return fn.apply(this, attrs);
}
focusHandler(e) {
this.trigger('onFocus', e);
}
focus() {
this.focusInput();
}
focusInput() {
this.refs.input.focus && this.refs.input.focus();
}
blur() {
this.blurInput();
}
blurInput() {
this.refs.input.blur && this.refs.input.blur();
}
blurHandler(e) {
this.setState({
focus: false,
});
this.trigger('onBlur', e);
}
returnHandler(e) {
if (isWeb) {
if (e.keyCode === 13) {
this.trigger('onReturn', genEventObject(e));
}
} else {
this.trigger('onReturn', e);
}
}
inputHandler(e) {
this.trigger('onInput', getText(e), genEventObject(e));
}
changeHandler(e) {
const value = getText(e);
const { maxLength } = this.props;
if (maxLength && value && value.length > maxLength) return;
if ('value' in this.props) {
this.setState({ value });
}
this.trigger('onChange', value, genEventObject(e));
}
render() {
const {
value,
// onChange,
onFocus,
onInput,
onBlur,
readOnly,
disabled,
style,
maxLength,
multiple,
returnKeyType,
autoFocus,
fixedFont,
rows,
type,
placeholderColor,
...others
} = this.props;
const attrs = {
onChange: this.changeHandler,
onInput: this.inputHandler,
onFocus: this.focusHandler,
onBlur: this.blurHandler,
disabled,
rows,
returnKeyType,
maxlength: maxLength,
readOnly,
autofocus: autoFocus,
placeholderColor,
style: Object.assign({}, styles.default, isWeb ? styles.defaultWeb : {}, style),
};
if (!multiple) {
attrs.type = type;
}
if ('value' in this.props) {
attrs.value = value;
}
if (isWeb) {
attrs.onKeyUp = this.returnHandler;
// keys that should not be passed
['readOnly', 'autofocus'].map((item) => {
if (item in attrs && !attrs[item]) {
delete attrs[item];
}
});
} else {
attrs.onReturn = this.returnHandler;
attrs['data-placeholder-color'] = placeholderColor;
// in multiple mode, passing returnKeyType to weex will get single line input
if (multiple && !this.props.onReturn) {
delete attrs.onReturn;
delete attrs.returnKeyType;
}
}
let inputElement;
if (multiple) {
if (isWeb) {
inputElement = (
<textarea {...others} {...attrs} ref="input">
{attrs.value}
</textarea>
);
} else {
inputElement = <textarea {...others} {...attrs} ref="input" />;
}
} else {
inputElement = <input {...others} {...attrs} ref="input" />;
}
return inputElement;
}
}
BaseInput.contextTypes = {
androidConfigs: PropTypes.any,
};
BaseInput.defaultProps = {
rows: 2,
style: {},
readOnly: false,
};
const styles = {
default: {
backgroundColor: 'transparent',
borderWidth: 0,
color: '#000000',
padding: 0,
fontSize: 24,
lineHeight: 60,
},
defaultWeb: {
width: '100%',
boxSizing: 'border-box',
outline: 'none',
appearance: 'none',
},
};
BaseInput.displayName = 'BaseInput';
export default BaseInput;