const React = require('react'); const { connect } = require('react-redux'); const { themeStyle } = require('@joplin/lib/theme'); const { _ } = require('@joplin/lib/locale'); class NoteSearchBarComponent extends React.Component { constructor() { super(); this.searchInput_change = this.searchInput_change.bind(this); this.searchInput_keyDown = this.searchInput_keyDown.bind(this); this.previousButton_click = this.previousButton_click.bind(this); this.nextButton_click = this.nextButton_click.bind(this); this.closeButton_click = this.closeButton_click.bind(this); this.backgroundColor = undefined; } style() { const theme = themeStyle(this.props.themeId); const style = { root: Object.assign({}, theme.textStyle, { backgroundColor: theme.backgroundColor, color: theme.colorFaded, }), }; return style; } componentDidMount() { this.refs.searchInput.focus(); } buttonIconComponent(iconName, clickHandler, isEnabled) { const theme = themeStyle(this.props.themeId); const searchButton = { paddingLeft: 4, paddingRight: 4, paddingTop: 2, paddingBottom: 2, textDecoration: 'none', marginRight: 5, }; const iconStyle = { display: 'flex', fontSize: Math.round(theme.fontSize) * 1.2, color: theme.color, opacity: isEnabled ? 1.0 : theme.disabledOpacity, }; const icon = ; return ( {icon} ); } searchInput_change(event) { const query = event.currentTarget.value; this.triggerOnChange(query); } searchInput_keyDown(event) { if (event.keyCode === 13) { // ENTER event.preventDefault(); if (!event.shiftKey) { if (this.props.onNext) this.props.onNext(); } else { if (this.props.onPrevious) this.props.onPrevious(); } } if (event.keyCode === 27) { // ESCAPE event.preventDefault(); if (this.props.onClose) this.props.onClose(); } if (event.keyCode === 70) { // F key if (event.ctrlKey) { event.target.select(); } } } previousButton_click() { if (this.props.onPrevious) this.props.onPrevious(); } nextButton_click() { if (this.props.onNext) this.props.onNext(); } closeButton_click() { if (this.props.onClose) this.props.onClose(); } triggerOnChange(query) { if (this.props.onChange) this.props.onChange(query); } focus() { this.refs.searchInput.focus(); this.refs.searchInput.select(); } render() { const query = this.props.query ? this.props.query : ''; // backgroundColor needs to cached to a local variable to prevent the // colour from blinking. // For more info: https://github.com/laurent22/joplin/pull/2329#issuecomment-578376835 const theme = themeStyle(this.props.themeId); if (!this.props.searching) { if (this.props.resultCount === 0 && query.length > 0) { this.backgroundColor = theme.warningBackgroundColor; } else { this.backgroundColor = theme.backgroundColor; } } if (this.backgroundColor === undefined) { this.backgroundColor = theme.backgroundColor; } const buttonEnabled = (this.backgroundColor === theme.backgroundColor); const closeButton = this.buttonIconComponent('fa-times', this.closeButton_click, true); const previousButton = this.buttonIconComponent('fa-chevron-up', this.previousButton_click, buttonEnabled); const nextButton = this.buttonIconComponent('fa-chevron-down', this.nextButton_click, buttonEnabled); const textStyle = Object.assign({ fontSize: theme.fontSize, fontFamily: theme.fontFamily, color: theme.colorFaded, backgroundColor: theme.backgroundColor, }); const matchesFoundString = (query.length > 0 && this.props.resultCount > 0) ? (
{`${this.props.selectedIndex + 1} / ${this.props.resultCount}`}
) : null; const allowScrolling = this.props.visiblePanes.indexOf('editor') >= 0; const viewerWarning = (
{'Jumping between matches is not available in the viewer, please toggle the editor'}
); return (
{closeButton} {allowScrolling ? nextButton : null} {allowScrolling ? previousButton : null} {allowScrolling ? matchesFoundString : null} {!allowScrolling ? viewerWarning : null}
); } } const mapStateToProps = state => { return { themeId: state.settings.theme, }; }; const NoteSearchBar = connect( mapStateToProps, null, null, { withRef: true } )(NoteSearchBarComponent); module.exports = NoteSearchBar;