mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-29 18:27:56 +02:00
fix(v2): fix input losing focus on init (#2188)
* fix(v2): fix input losing focus on init * fix(v2): add onMouseOver handler
This commit is contained in:
parent
7e750de6fa
commit
5252111fa0
1 changed files with 55 additions and 59 deletions
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useRef, useCallback} from 'react';
|
import React, {useState, useRef, useCallback} from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
|
@ -13,10 +13,8 @@ import {useHistory} from '@docusaurus/router';
|
||||||
|
|
||||||
import './styles.css';
|
import './styles.css';
|
||||||
|
|
||||||
let loaded = false;
|
|
||||||
|
|
||||||
const Search = props => {
|
const Search = props => {
|
||||||
const initialized = useRef(false);
|
const [algoliaLoaded, setAlgoliaLoaded] = useState(false);
|
||||||
const searchBarRef = useRef(null);
|
const searchBarRef = useRef(null);
|
||||||
const {siteConfig = {}} = useDocusaurusContext();
|
const {siteConfig = {}} = useDocusaurusContext();
|
||||||
const {
|
const {
|
||||||
|
@ -24,63 +22,62 @@ const Search = props => {
|
||||||
} = siteConfig;
|
} = siteConfig;
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
function initAlgolia(focusOnInit) {
|
function initAlgolia() {
|
||||||
if (!initialized.current) {
|
window.docsearch({
|
||||||
window.docsearch({
|
appId: algolia.appId,
|
||||||
appId: algolia.appId,
|
apiKey: algolia.apiKey,
|
||||||
apiKey: algolia.apiKey,
|
indexName: algolia.indexName,
|
||||||
indexName: algolia.indexName,
|
inputSelector: '#search_input_react',
|
||||||
inputSelector: '#search_input_react',
|
algoliaOptions: algolia.algoliaOptions,
|
||||||
algoliaOptions: algolia.algoliaOptions,
|
// Override algolia's default selection event, allowing us to do client-side
|
||||||
// Override algolia's default selection event, allowing us to do client-side
|
// navigation and avoiding a full page refresh.
|
||||||
// navigation and avoiding a full page refresh.
|
handleSelected: (_input, _event, suggestion) => {
|
||||||
handleSelected: (_input, _event, suggestion) => {
|
// Use an anchor tag to parse the absolute url into a relative url
|
||||||
// Use an anchor tag to parse the absolute url into a relative url
|
// Alternatively, we can use new URL(suggestion.url) but its not supported in IE
|
||||||
// Alternatively, we can use new URL(suggestion.url) but its not supported in IE
|
const a = document.createElement('a');
|
||||||
const a = document.createElement('a');
|
a.href = suggestion.url;
|
||||||
a.href = suggestion.url;
|
|
||||||
|
|
||||||
// Algolia use closest parent element id #__docusaurus when a h1 page title does not have an id
|
// Algolia use closest parent element id #__docusaurus when a h1 page title does not have an id
|
||||||
// So, we can safely remove it. See https://github.com/facebook/docusaurus/issues/1828 for more details.
|
// So, we can safely remove it. See https://github.com/facebook/docusaurus/issues/1828 for more details.
|
||||||
const routePath =
|
const routePath =
|
||||||
`#__docusaurus` === a.hash
|
`#__docusaurus` === a.hash
|
||||||
? `${a.pathname}`
|
? `${a.pathname}`
|
||||||
: `${a.pathname}${a.hash}`;
|
: `${a.pathname}${a.hash}`;
|
||||||
history.push(routePath);
|
history.push(routePath);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
initialized.current = true;
|
|
||||||
// Needed because the search input loses focus after calling window.docsearch()
|
// Needed because the search input loses focus after calling window.docsearch()
|
||||||
if (focusOnInit) {
|
searchBarRef.current.focus();
|
||||||
searchBarRef.current.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadAlgolia(focusAfterLoading) {
|
const loadAlgolia = () => {
|
||||||
if (!loaded) {
|
if (algoliaLoaded) {
|
||||||
Promise.all([import('docsearch.js'), import('./algolia.css')]).then(
|
return;
|
||||||
([{default: docsearch}]) => {
|
|
||||||
loaded = true;
|
|
||||||
window.docsearch = docsearch;
|
|
||||||
initAlgolia(focusAfterLoading);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
initAlgolia(focusAfterLoading);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const toggleSearchIconClick = useCallback(
|
Promise.all([import('docsearch.js'), import('./algolia.css')]).then(
|
||||||
event => {
|
([{default: docsearch}]) => {
|
||||||
if (!searchBarRef.current.contains(event.target)) {
|
setAlgoliaLoaded(true);
|
||||||
searchBarRef.current.focus();
|
window.docsearch = docsearch;
|
||||||
}
|
initAlgolia();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
props.handleSearchBarToggle(!props.isSearchBarExpanded);
|
const toggleSearchIconClick = useCallback(() => {
|
||||||
},
|
loadAlgolia();
|
||||||
[props.isSearchBarExpanded],
|
|
||||||
);
|
if (algoliaLoaded) {
|
||||||
|
searchBarRef.current.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
props.handleSearchBarToggle(!props.isSearchBarExpanded);
|
||||||
|
}, [props.isSearchBarExpanded]);
|
||||||
|
|
||||||
|
const handleSearchInputBlur = useCallback(() => {
|
||||||
|
props.handleSearchBarToggle(!props.isSearchBarExpanded);
|
||||||
|
}, [algoliaLoaded]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="navbar__search" key="search-box">
|
<div className="navbar__search" key="search-box">
|
||||||
|
@ -104,10 +101,9 @@ const Search = props => {
|
||||||
{'search-bar-expanded': props.isSearchBarExpanded},
|
{'search-bar-expanded': props.isSearchBarExpanded},
|
||||||
{'search-bar': !props.isSearchBarExpanded},
|
{'search-bar': !props.isSearchBarExpanded},
|
||||||
)}
|
)}
|
||||||
onClick={loadAlgolia.bind(this, true)}
|
onMouseOver={loadAlgolia}
|
||||||
onMouseOver={loadAlgolia.bind(this, false)}
|
onFocus={loadAlgolia}
|
||||||
onFocus={toggleSearchIconClick}
|
onBlur={handleSearchInputBlur}
|
||||||
onBlur={toggleSearchIconClick}
|
|
||||||
ref={searchBarRef}
|
ref={searchBarRef}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue