1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-18 01:03:40 +00:00
seahub/frontend/src/components/search-input.js

135 lines
3.6 KiB
JavaScript
Raw Normal View History

import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Utils } from '../utils/utils';
const propTypes = {
placeholder: PropTypes.string,
autoFocus: PropTypes.bool,
className: PropTypes.string,
onChange: PropTypes.func.isRequired,
onKeyDown: PropTypes.func,
wait: PropTypes.number,
disabled: PropTypes.bool,
style: PropTypes.object,
isClearable: PropTypes.bool,
clearValue: PropTypes.func,
clearClassName: PropTypes.string,
components: PropTypes.object,
value: PropTypes.string,
};
class SearchInput extends Component {
constructor(props) {
super(props);
this.state = {
2025-03-10 06:27:08 +00:00
searchValue: props.value || '',
};
this.isInputtingChinese = false;
this.timer = null;
this.inputRef = null;
}
componentDidMount() {
if (this.props.autoFocus && this.inputRef && this.inputRef !== document.activeElement) {
setTimeout(() => {
this.inputRef.focus();
}, 0);
}
}
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.value !== this.props.value) {
2024-07-18 03:58:42 +00:00
this.setState({ searchValue: nextProps.value });
}
}
componentWillUnmount() {
this.timer && clearTimeout(this.timer);
this.timer = null;
this.inputRef = null;
}
onCompositionStart = () => {
this.isInputtingChinese = true;
};
onChange = (e) => {
this.timer && clearTimeout(this.timer);
2025-03-10 06:27:08 +00:00
const { onChange, wait = 100 } = this.props;
let text = e.target.value;
2024-07-18 03:58:42 +00:00
this.setState({ searchValue: text || '' }, () => {
if (this.isInputtingChinese) return;
this.timer = setTimeout(() => {
onChange && onChange(this.state.searchValue.trim());
}, wait);
});
};
onCompositionEnd = (e) => {
this.isInputtingChinese = false;
this.onChange(e);
};
clearSearch = () => {
const { clearValue } = this.props;
2024-07-18 03:58:42 +00:00
this.setState({ searchValue: '' }, () => {
clearValue && clearValue();
});
};
setFocus = (isSelectAllText) => {
if (this.inputRef === document.activeElement) return;
this.inputRef.focus();
if (isSelectAllText) {
const txtLength = this.state.searchValue.length;
this.inputRef.setSelectionRange(0, txtLength);
}
};
renderClear = () => {
const { isClearable, clearClassName, components = {} } = this.props;
const { searchValue } = this.state;
if (!isClearable || !searchValue) return null;
const { ClearIndicator } = components;
if (React.isValidElement(ClearIndicator)) {
2024-07-18 03:58:42 +00:00
return React.cloneElement(ClearIndicator, { clearValue: this.clearSearch });
2024-12-26 07:17:16 +00:00
} else if (Utils.isFunction(ClearIndicator)) {
return <ClearIndicator clearValue={this.clearSearch} />;
}
return (
<i className={classnames('search-text-clear input-icon-addon', clearClassName)} onClick={this.clearSearch}>×</i>
);
};
render() {
2025-03-10 06:27:08 +00:00
const { placeholder, autoFocus, className, onKeyDown, disabled = false, style } = this.props;
const { searchValue } = this.state;
return (
<Fragment>
<input
type="text"
value={searchValue}
className={classnames('form-control', className)}
onChange={this.onChange}
autoFocus={autoFocus}
placeholder={placeholder}
onCompositionStart={this.onCompositionStart}
onCompositionEnd={this.onCompositionEnd}
onKeyDown={onKeyDown}
disabled={disabled}
style={style}
ref={ref => this.inputRef = ref}
/>
{this.renderClear()}
</Fragment>
);
}
}
SearchInput.propTypes = propTypes;
export default SearchInput;