refactor(v2): convert SearchBar to hooks (#1755)

* Refactored with Hooks

* refactored for improvements

* Added classnames for conditional CSS rendering
This commit is contained in:
Shirshendu Bhowmick 2019-09-15 00:02:46 +05:30 committed by Yangshun Tay
parent 250a818e7f
commit 0bbf7b8202
3 changed files with 59 additions and 60 deletions

View file

@ -45,7 +45,7 @@ const Sun = () => <span className={classnames(styles.toggle, styles.sun)} />;
function Navbar() { function Navbar() {
const context = useDocusaurusContext(); const context = useDocusaurusContext();
const [sidebarShown, setSidebarShown] = useState(false); const [sidebarShown, setSidebarShown] = useState(false);
const [searchBarExpanded, setSearchBarExpanded] = useState(false); const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false);
const currentTheme = const currentTheme =
typeof document !== 'undefined' typeof document !== 'undefined'
? document.querySelector('html').getAttribute('data-theme') ? document.querySelector('html').getAttribute('data-theme')
@ -82,10 +82,6 @@ function Navbar() {
} }
}; };
const handleSearchBarToggle = () => {
setSearchBarExpanded(!searchBarExpanded);
};
return ( return (
<React.Fragment> <React.Fragment>
<Head> <Head>
@ -132,7 +128,7 @@ function Navbar() {
)} )}
{title != null && ( {title != null && (
<strong <strong
className={searchBarExpanded ? styles.hideLogoText : ''}> className={isSearchBarExpanded ? styles.hideLogoText : ''}>
{title} {title}
</strong> </strong>
)} )}
@ -161,7 +157,10 @@ function Navbar() {
/> />
{algolia && ( {algolia && (
<div className="navbar__search" key="search-box"> <div className="navbar__search" key="search-box">
<SearchBar handleSearchBarToggle={handleSearchBarToggle} /> <SearchBar
handleSearchBarToggle={setIsSearchBarExpanded}
isSearchBarExpanded={isSearchBarExpanded}
/>
</div> </div>
)} )}
</div> </div>

View file

@ -8,7 +8,8 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"docsearch.js": "^2.6.3" "docsearch.js": "^2.6.3",
"classnames": "^2.2.6"
}, },
"peerDependencies": { "peerDependencies": {
"@docusaurus/core": "^2.0.0", "@docusaurus/core": "^2.0.0",

View file

@ -5,25 +5,27 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import React, {Fragment} from 'react'; import React, {
useState,
useEffect,
Fragment,
useContext,
useRef,
useCallback,
} from 'react';
import classnames from 'classnames';
import DocusaurusContext from '@docusaurus/context'; import DocusaurusContext from '@docusaurus/context';
import './styles.css'; import './styles.css';
class Search extends React.Component { const Search = props => {
constructor(props) { const [isEnabled, setIsEnabled] = useState(true);
super(props); const searchBarRef = useRef(null);
this.state = { const context = useContext(DocusaurusContext);
enabled: true,
isExpanded: false,
};
this.searchBarRef = React.createRef();
this.toggleSearchIconClick = this.toggleSearchIconClick.bind(this);
}
componentDidMount() { useEffect(() => {
const {siteConfig = {}} = this.context; const {siteConfig = {}} = context;
const { const {
themeConfig: {algolia}, themeConfig: {algolia},
} = siteConfig; } = siteConfig;
@ -42,48 +44,45 @@ class Search extends React.Component {
}); });
} else { } else {
console.warn('Search has failed to load and now is being disabled'); console.warn('Search has failed to load and now is being disabled');
this.setState({enabled: false}); setIsEnabled(false);
} }
} }, []);
toggleSearchIconClick() { const toggleSearchIconClick = useCallback(() => {
this.setState( props.handleSearchBarToggle(!props.isSearchBarExpanded);
oldState => ({ }, [props.isSearchBarExpanded]);
isExpanded: !oldState.isExpanded,
}),
() => {
this.searchBarRef.current.focus();
this.props.handleSearchBarToggle();
},
);
}
render() { useEffect(() => {
const {enabled, isExpanded} = this.state; if (props.isSearchBarExpanded) {
searchBarRef.current.focus();
}
}, [props.isSearchBarExpanded]);
return enabled ? ( return isEnabled ? (
<Fragment> <Fragment>
<span <span
role="button" role="button"
className={`search-icon ${isExpanded ? 'search-icon-hidden' : ''}`} className={classnames('search-icon', {
onClick={this.toggleSearchIconClick} 'search-icon-hidden': props.isSearchBarExpanded,
onKeyDown={this.toggleSearchIconClick} })}
tabIndex={0} onClick={toggleSearchIconClick}
/> onKeyDown={toggleSearchIconClick}
<input tabIndex={0}
id="search_input_react" />
type="search" <input
placeholder="Search" id="search_input_react"
aria-label="Search" type="search"
className={`${isExpanded ? 'search-bar-expanded' : 'search-bar'}`} placeholder="Search"
onBlur={this.toggleSearchIconClick} aria-label="Search"
ref={this.searchBarRef} className={classnames(
/> {'search-bar-expanded': props.isSearchBarExpanded},
</Fragment> {'search-bar': !props.isSearchBarExpanded},
) : null; )}
} onBlur={toggleSearchIconClick}
} ref={searchBarRef}
/>
Search.contextType = DocusaurusContext; </Fragment>
) : null;
};
export default Search; export default Search;