-
Notifications
You must be signed in to change notification settings - Fork 147
Expand file tree
/
Copy pathlink.jsx
More file actions
65 lines (62 loc) · 2.16 KB
/
link.jsx
File metadata and controls
65 lines (62 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import React from 'react';
import { Link as ReachLink, navigate } from '@reach/router';
const { getAsyncComponent } = require('../../routes');
const Promiseany = (
Promise.any ||
function ($) {
return new Promise(function (D, E, A, L) {
A = [];
L = $.map(function ($, i) {
return Promise.resolve($).then(D, function (O) {
return ((A[i] = O), --L) || E({ errors: A });
});
}).length;
});
}
).bind(Promise);
export const Link = ({ href, to, onMouseOver = () => {}, onClick, ...props }) => {
let preloadPromise;
let url = href || to || '';
if (url.startsWith('#') && !onClick) {
onClick = (ev) => {
ev.preventDefault(); // Don't use client-side routing
// Chrome does not jump until ALL network requests finish.
// We have to force it to...
const referencedElement = document.getElementById(url.replace('#', ''));
if (referencedElement) {
referencedElement.scrollIntoView();
}
// update URL without triggering route change
history.pushState({}, '', url);
};
}
if (url.includes('//') || url.startsWith('#')) {
return <a href={url} onClick={onClick} {...props} />;
} else if (url.startsWith('/')) {
if (!process.env.PRERENDER) {
const Component = getAsyncComponent(url);
if (Component) {
// Preload on hover
props.onMouseOver = () => {
preloadPromise = Component.preload();
onMouseOver();
};
// Wait up to an extra 500ms on click before showing 'Loading...'
props.onClick = (ev) => {
if (!(ev.ctrlKey || ev.metaKey)) {
// avoid disallowing cmnd/ctrl+click opening in new tab
ev.preventDefault();
if (typeof window !== 'undefined' && url !== location.pathname) {
Promiseany([preloadPromise, new Promise((res) => setTimeout(res, 500))])
.then(() => navigate(url))
.then(() => {
document.querySelector('#ws-page-main').scrollTo({ top: 0 }); // scroll to top of page
});
}
}
};
}
}
}
return <ReachLink to={url} {...props} />;
};