123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import React, { PureComponent } from 'react';
- import PropTypes from 'prop-types';
- import { Input, Icon, AutoComplete } from 'antd';
- import classNames from 'classnames';
- import Debounce from 'lodash-decorators/debounce';
- import Bind from 'lodash-decorators/bind';
- import styles from './index.less';
- export default class HeaderSearch extends PureComponent {
- static propTypes = {
- className: PropTypes.string,
- placeholder: PropTypes.string,
- onSearch: PropTypes.func,
- onPressEnter: PropTypes.func,
- defaultActiveFirstOption: PropTypes.bool,
- dataSource: PropTypes.array,
- defaultOpen: PropTypes.bool,
- onVisibleChange: PropTypes.func,
- };
- static defaultProps = {
- defaultActiveFirstOption: false,
- onPressEnter: () => {},
- onSearch: () => {},
- className: '',
- placeholder: '',
- dataSource: [],
- defaultOpen: false,
- onVisibleChange: () => {},
- };
- static getDerivedStateFromProps(props) {
- if ('open' in props) {
- return {
- searchMode: props.open,
- };
- }
- return null;
- }
- constructor(props) {
- super(props);
- this.state = {
- searchMode: props.defaultOpen,
- value: '',
- };
- }
- componentWillUnmount() {
- clearTimeout(this.timeout);
- }
- onKeyDown = e => {
- if (e.key === 'Enter') {
- const { onPressEnter } = this.props;
- const { value } = this.state;
- this.timeout = setTimeout(() => {
- onPressEnter(value); // Fix duplicate onPressEnter
- }, 0);
- }
- };
- onChange = value => {
- const { onChange } = this.props;
- this.setState({ value });
- if (onChange) {
- onChange(value);
- }
- };
- enterSearchMode = () => {
- const { onVisibleChange } = this.props;
- onVisibleChange(true);
- this.setState({ searchMode: true }, () => {
- const { searchMode } = this.state;
- if (searchMode) {
- this.input.focus();
- }
- });
- };
- leaveSearchMode = () => {
- this.setState({
- searchMode: false,
- value: '',
- });
- };
- // NOTE: 不能小于500,如果长按某键,第一次触发auto repeat的间隔是500ms,小于500会导致触发2次
- @Bind()
- @Debounce(500, {
- leading: true,
- trailing: false,
- })
- debouncePressEnter() {
- const { onPressEnter } = this.props;
- const { value } = this.state;
- onPressEnter(value);
- }
- render() {
- const { className, placeholder, open, ...restProps } = this.props;
- const { searchMode, value } = this.state;
- delete restProps.defaultOpen; // for rc-select not affected
- const inputClass = classNames(styles.input, {
- [styles.show]: searchMode,
- });
- return (
- <span
- className={classNames(className, styles.headerSearch)}
- onClick={this.enterSearchMode}
- onTransitionEnd={({ propertyName }) => {
- if (propertyName === 'width' && !searchMode) {
- const { onVisibleChange } = this.props;
- onVisibleChange(searchMode);
- }
- }}
- >
- <Icon type="search" key="Icon" />
- <AutoComplete
- key="AutoComplete"
- {...restProps}
- className={inputClass}
- value={value}
- onChange={this.onChange}
- getPopupContainer={triggerNode => triggerNode.parentNode}
- >
- <Input
- ref={node => {
- this.input = node;
- }}
- aria-label={placeholder}
- placeholder={placeholder}
- onKeyDown={this.onKeyDown}
- onBlur={this.leaveSearchMode}
- />
- </AutoComplete>
- </span>
- );
- }
- }
|