UNPKG

@kiwicom/smart-faq

Version:

173 lines (145 loc) 4.58 kB
// @flow import * as React from 'react'; import { Search } from '@kiwicom/orbit-components/lib/icons'; import { withRouter } from 'react-router-dom'; import type { ContextRouter } from 'react-router-dom'; import IntlContext from '@kiwicom/nitro/lib/services/intl/context'; import type { Context as Intl } from '@kiwicom/nitro/lib/services/intl/context'; import InputField from '@kiwicom/orbit-components/lib/InputField'; import ButtonLink from '@kiwicom/orbit-components/lib/ButtonLink'; import CloseCircle from '@kiwicom/orbit-components/lib/icons/CloseCircle'; import LogContext from '@kiwicom/nitro/lib/services/log/context'; import { SearchState } from '../../SmartFAQ/context/SearchState'; import PageVariant from '../../SmartFAQ/context/PageVariant'; import type { SearchStateType } from '../../SmartFAQ/context/SearchState'; import { debounce } from '../../SmartFAQ/helpers/functionUtils'; import { events } from '../../const/events'; import type { log } from '../../const/events'; type ContainerProps = {| ...ContextRouter, autofocus?: boolean, |}; type Props = {| ...ContainerProps, searchContext: SearchStateType, intl: Intl, isFullPage: boolean, log: log, |}; type State = {| value: string, |}; class SearchBar extends React.Component<Props, State> { input = React.createRef(); constructor(props: Props) { super(props); this.state = { value: props.searchContext.searchText, }; } componentDidMount() { const { autofocus } = this.props; const input = this.input.current; if (input && autofocus) { input.focus(); } } componentDidUpdate(prevProps) { if ( prevProps.searchContext.searchText !== this.props.searchContext.searchText ) { // I know what I'm doing - keep local state synced with context // eslint-disable-next-line react/no-did-update-set-state this.setState({ value: this.props.searchContext.searchText }); } } getResetButton = () => { const { searchText } = this.props.searchContext; const isSearching = searchText.length > 0; if (!isSearching) { // show reset icon only when some text was entered return null; } return ( <ButtonLink transparent type="secondary" icon={<CloseCircle />} onClick={this.handleSearchCancel} dataTest="SearchBarInput-ResetButton" /> ); }; updateSearchText = searchedText => { const { searchContext, log } = this.props; const { changeSearchText, resetQueriesCount, incrementQueriesCount, } = searchContext; changeSearchText(searchedText); incrementQueriesCount(); if (searchedText.length >= 2) { log(events.FAQ_SEARCH, { searchedText: searchedText.toLowerCase() }); } if (searchedText.length) { incrementQueriesCount(); } else { resetQueriesCount(); } }; // this is regular method and can't be before "updateSearchText"! // eslint-disable-next-line react/sort-comp debouncedUpdateSearchText = debounce(this.updateSearchText, 350); handleSearchCancel = () => { this.setState({ value: '' }); this.updateSearchText(''); }; handleSearchChange = (e: SyntheticInputEvent<HTMLInputElement>) => { const searchedText = e.target.value; if ( searchedText.length && this.props.match.url.includes('article') && !this.props.isFullPage ) { this.props.history.push('/faq'); } this.setState({ value: searchedText }); this.debouncedUpdateSearchText(searchedText); }; render() { const { intl, isFullPage } = this.props; const { value } = this.state; const placeholder = isFullPage ? __('smartfaq.full_page.search.placeholder') : __('smartfaq.search_input.placeholder'); return ( <InputField type="text" ref={this.input} value={value} onChange={this.handleSearchChange} placeholder={intl.translate(placeholder)} prefix={<Search />} suffix={this.getResetButton()} dataTest="SearchBarInput" /> ); } } const WrappedSearchBar = (props: ContainerProps) => { const searchContext = React.useContext(SearchState); const intl = React.useContext(IntlContext); const { log } = React.useContext(LogContext); const { variant } = React.useContext(PageVariant); return ( <SearchBar {...props} log={log} searchContext={searchContext} intl={intl} isFullPage={variant === 'fullPage'} /> ); }; export default withRouter(WrappedSearchBar);