UNPKG

weex-nuke

Version:

基于 Rax 、Weex 的高性能组件体系 ~~

271 lines (250 loc) 6.51 kB
'use strict'; /** @jsx createElement */ import { Component, createElement, PropTypes } from 'rax'; import Icon from 'nuke-icon'; import Dom from 'nuke-dom'; import Input from 'nuke-normal-input'; import View from 'nuke-view'; import Text from 'nuke-text'; import Touchable from 'nuke-touchable'; import { isWeb, isWeex } from 'nuke-env'; import { connectStyle } from 'nuke-theme-provider'; import stylesProvider from '../styles'; class SearchBar extends Component { constructor(props) { super(props); let value = ''; if ('defaultValue' in props) { value = props.defaultValue; } else if ('defaultValue' in props) { value = props.value; } this.state = { focus: false, value, }; this.userInputValue = value || ''; const events = [ 'focusHandler', 'blurHandler', 'changeHandler', 'inputHandler', 'searchHandler', 'returnHandler', 'textSearchHandler', ]; events.forEach((m) => { this[m] = this[m].bind(this); }); } // calcRem componentDidMount() { const { centered } = this.props; if (!centered) return; Dom.getRect('parentDOM').then( (wrap) => { this.setState({ strentchStyle: { width: isWeb ? `${wrap.width}px` : wrap.width, // web 端 offset 的单位是 px }, }); }, () => {} ); } componentWillReceiveProps(nextProps) { if ('value' in nextProps) { this.setState({ value: nextProps.value, }); this.userInputValue = nextProps.value; } } render() { const { value, disabled, defaultValue, placeholder, onInput, onChange, onSearch, inputStyle, style = {}, themeStyle: styles, ...others } = this.props; const searchbarWrapStyle = Object.assign({}, styles.wrap, style); return ( <View clsName="search-bar-wrap" style={searchbarWrapStyle} {...others}> <View clsName="body" ref="parentDOM" style={[styles.body, inputStyle]}> {this.renderPlaceholder(styles)} {this.renderInput()} </View> {this.renderSearchButton(styles)} </View> ); } // 输入框以及placeholder renderInput() { const { maxLength, disabled, themeStyle: styles } = this.props; return ( <Input ref={(ref) => { this._input = ref; }} style={styles['input-wrap']} type="search" returnKeyType="search" materialDesign={false} maxLength={maxLength} value={this.state.value} onFocus={this.focusHandler} onBlur={this.blurHandler} onReturn={this.returnHandler} disabled={disabled} inputStyle={styles['input-ele']} onInput={this.inputHandler} onChange={this.changeHandler} /> ); } // 模拟的 placeholder renderPlaceholder(styles) { const { placeholder, centered, placeholderColor } = this.props; const { focus } = this.state; let element; const textStyle = {}; const TextAttrArr = ['color', 'fontSize', 'fontStyle', 'fontWeight']; TextAttrArr.forEach((item) => { if (styles.placeholder[item]) { textStyle[item] = styles.placeholder[item]; } }); if (isWeb) { element = placeholder && !this.userInputValue && !focus ? ( <Text style={[textStyle, { color: placeholderColor }]}> {placeholder} </Text> ) : null; } else { element = placeholder && !this.userInputValue && !focus ? ( <Text style={[textStyle, { color: placeholderColor }]}> {placeholder} </Text> ) : null; } const iconDOM = ( <Icon style={[styles.icon, { color: placeholderColor }]} name="search" /> ); const placeholderStyle = centered && !focus && !this.userInputValue ? { ...styles['body-centered'], ...this.state.strentchStyle } : {}; return ( <View role="placeholder-wrap" ref="placeholderDOM" style={[styles.placeholder, placeholderStyle]} > {iconDOM} {element} </View> ); } // 搜索按钮 renderSearchButton(styles) { if (!this.props.showSearchButton) return null; return ( <Touchable onPress={this.searchHandler} style={styles.button}> <Text onPress={this.textSearchHandler} style={styles['button-text']}> {this.props.locale.search} </Text> </Touchable> ); } focusHandler(e) { this.setState({ focus: true, }); this.trigger('onFocus', e); } trigger(fn, ...attrs) { if (typeof fn === 'string') fn = this.props[fn]; if (!(typeof fn === 'function')) return; return fn.apply(this, attrs); } blurHandler(e) { this.setState({ focus: false, }); this.trigger('onBlur', e); } inputHandler(e) { this.userInputValue = e.value; this.trigger('onInput', e); } changeHandler(value, e) { this.setState({ value, }); this.userInputValue = value; this.trigger('onChange', value, e); } returnHandler(e) { const value = e.value; this.setState({ value }); this.searchHandler(); } searchHandler(e) { // alert(this.userInputValue); this._input.wrappedInstance.blur(); this.props.onSearch && this.props.onSearch({ value: this.userInputValue }); } textSearchHandler(e) { if (isWeb) { e.stopPropagation(); } this.searchHandler(); } } SearchBar.propTypes = { onCancel: PropTypes.func, onChange: PropTypes.func, onSearch: PropTypes.func, value: PropTypes.string, defaultValue: PropTypes.string, locale: PropTypes.object, disabled: PropTypes.bool, showSearchButton: PropTypes.bool, centered: PropTypes.bool, placeholderColor: PropTypes.string, inputStyle: PropTypes.any, style: PropTypes.any, placeholder: PropTypes.string, onInput: PropTypes.func, }; SearchBar.defaultProps = { locale: { search: '搜索', }, onSearch: () => {}, showSearchButton: true, disabled: false, centered: false, defaultValue: null, onCancel: () => {}, inputStyle: {}, onChange: () => {}, onInput: () => {}, placeholderColor: '#cccccc', placeholder: '', style: {}, }; SearchBar.displayName = 'SearchBar'; const StyledSearchBar = connectStyle(stylesProvider, { withRef: true })( SearchBar ); export default StyledSearchBar;