diff --git a/packages/docusaurus/lib/client/App.js b/packages/docusaurus/lib/client/App.js
index f9ac309c68..9ada08c456 100644
--- a/packages/docusaurus/lib/client/App.js
+++ b/packages/docusaurus/lib/client/App.js
@@ -7,13 +7,13 @@
import React, {useState} from 'react';
import {renderRoutes} from 'react-router-config';
-import ReactListenerProvider from 'react-listener-provider';
import Head from '@docusaurus/Head'; // eslint-disable-line
import routes from '@generated/routes'; // eslint-disable-line
import metadata from '@generated/metadata'; // eslint-disable-line
import siteConfig from '@generated/docusaurus.config'; //eslint-disable-line
import DocusaurusContext from '@docusaurus/context'; // eslint-disable-line
+import PendingNavigation from './PendingNavigation';
function App() {
const [context, setContext] = useState({});
@@ -36,7 +36,9 @@ function App() {
type="text/css"
/>
- {renderRoutes(routes)}
+
+ {renderRoutes(routes)}
+
);
}
diff --git a/packages/docusaurus/lib/client/PendingNavigation.js b/packages/docusaurus/lib/client/PendingNavigation.js
new file mode 100644
index 0000000000..f792558d96
--- /dev/null
+++ b/packages/docusaurus/lib/client/PendingNavigation.js
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2017-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React from 'react';
+import {Route, withRouter} from 'react-router-dom';
+import nprogress from 'nprogress';
+import 'nprogress/nprogress.css';
+import preload from './preload';
+
+nprogress.configure({showSpinner: false});
+
+class PendingNavigation extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.progressBarTimeout = null;
+ this.state = {
+ previousLocation: null,
+ };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ const navigated = nextProps.location !== this.props.location;
+ const {routes, delay = 1000} = this.props;
+
+ if (navigated) {
+ window.scrollTo(0, 0);
+
+ this.startProgressBar(delay);
+ // save the location so we can render the old screen
+ this.setState({
+ previousLocation: this.props.location,
+ });
+
+ // load data while the old screen remains
+ preload(routes, nextProps.location.pathname)
+ .then(() => {
+ this.setState(
+ {
+ previousLocation: null,
+ },
+ this.stopProgressBar,
+ );
+ })
+ .catch(e => console.warn(e));
+ }
+ }
+
+ clearProgressBarTimeout() {
+ if (this.progressBarTimeout) {
+ clearTimeout(this.progressBarTimeout);
+ this.progressBarTimeout = null;
+ }
+ }
+
+ startProgressBar(delay) {
+ this.clearProgressBarTimeout();
+ this.progressBarTimeout = setTimeout(() => {
+ nprogress.start();
+ }, delay);
+ }
+
+ stopProgressBar() {
+ this.clearProgressBarTimeout();
+ nprogress.done();
+ }
+
+ render() {
+ const {children, location} = this.props;
+ const {previousLocation} = this.state;
+
+ // use a controlled to trick all descendants into
+ // rendering the old location
+ return (
+ children} />
+ );
+ }
+}
+
+export default withRouter(PendingNavigation);
diff --git a/packages/docusaurus/lib/client/exports/Link.js b/packages/docusaurus/lib/client/exports/Link.js
index b7c7b03726..58ad2aeec9 100644
--- a/packages/docusaurus/lib/client/exports/Link.js
+++ b/packages/docusaurus/lib/client/exports/Link.js
@@ -6,15 +6,15 @@
*/
import React, {useEffect} from 'react';
-import Perimeter from 'react-perimeter';
import {NavLink} from 'react-router-dom';
const internalRegex = /^\/(?!\/)/;
function Link(props) {
- const {to, href, preloadProximity = 20} = props;
+ const {to, href} = props;
const targetLink = to || href;
const isInternal = internalRegex.test(targetLink);
+ let preloaded = false;
const IOSupported =
typeof window !== 'undefined' && 'IntersectionObserver' in window;
@@ -47,6 +47,13 @@ function Link(props) {
}
};
+ const onMouseEnter = () => {
+ if (!preloaded) {
+ window.docusaurus.preload(targetLink);
+ preloaded = true;
+ }
+ };
+
useEffect(() => {
// If IO is not supported. We prefetch by default (only once)
if (!IOSupported && isInternal) {
@@ -64,12 +71,12 @@ function Link(props) {
// eslint-disable-next-line jsx-a11y/anchor-has-content
) : (
- window.docusaurus.preload(targetLink)}
- once>
-
-
+
);
}
diff --git a/packages/docusaurus/package.json b/packages/docusaurus/package.json
index 8f4a5c4669..61364dc75e 100644
--- a/packages/docusaurus/package.json
+++ b/packages/docusaurus/package.json
@@ -55,13 +55,12 @@
"is-wsl": "^1.1.0",
"lodash": "^4.17.11",
"mini-css-extract-plugin": "^0.4.1",
+ "nprogress": "^0.2.0",
"portfinder": "^1.0.13",
"react-dev-utils": "^8.0.0",
"react-helmet": "^6.0.0-beta",
- "react-listener-provider": "^0.2.0",
"react-loadable": "^5.5.0",
"react-loadable-ssr-addon": "^0.1.6",
- "react-perimeter": "^0.4.0",
"react-router-config": "^5.0.0",
"react-router-dom": "^5.0.0",
"semver": "^6.0.0",
diff --git a/yarn.lock b/yarn.lock
index c5be8a6519..357ad2eb8d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9509,6 +9509,11 @@ npm-which@^3.0.1:
gauge "~2.7.3"
set-blocking "~2.0.0"
+nprogress@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1"
+ integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E=
+
nth-check@^1.0.2, nth-check@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
@@ -10986,11 +10991,6 @@ react-is@^16.8.1, react-is@^16.8.4:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.5.tgz#c54ac229dd66b5afe0de5acbe47647c3da692ff8"
integrity sha512-sudt2uq5P/2TznPV4Wtdi+Lnq3yaYW8LfvPKLM9BKD8jJNBkxMVyB0C9/GmVhLw7Jbdmndk/73n7XQGeN9A3QQ==
-react-listener-provider@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/react-listener-provider/-/react-listener-provider-0.2.0.tgz#fb6ce123f9e20ad948f75906ddf647db1df31f18"
- integrity sha1-+2zhI/niCtlI91kG3fZH2x3zHxg=
-
react-loadable-ssr-addon@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon/-/react-loadable-ssr-addon-0.1.6.tgz#de3e45f2b3876dc7b9afae19138370f0588b7300"
@@ -11003,13 +11003,6 @@ react-loadable@^5.5.0:
dependencies:
prop-types "^15.5.0"
-react-perimeter@^0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/react-perimeter/-/react-perimeter-0.4.0.tgz#be86b5560bb96650272aaf7bd37639460b82645b"
- integrity sha512-hSjth5oh4L/ZVR6PfR9eu7B1lil0AteGXLn7ki7YNJI7bkKlZf28pwFyFKNIXkoRJT3FiD01kGYkAmIz1k8b9A==
- optionalDependencies:
- react-listener-provider "^0.2.0"
-
react-router-config@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.0.0.tgz#3d7e298dc64479bf9e1cc77080b8778e9a8d966c"