Skip to content

Commit 20500c8

Browse files
author
Alexandre Lotte
committed
Add configurable navigation delay + onRouteChangeStart subscription
1 parent 4c278c0 commit 20500c8

5 files changed

Lines changed: 41 additions & 12 deletions

File tree

src/components/Link.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const Link = ({ href, ...rest }: LinkProps, children) => ({
6262
}
6363
const DumbNavigate = (state: State, ev) => {
6464
ev.preventDefault();
65-
return [state, navigate({ to: href })];
65+
return [state, navigate({ to: href, delay: options.navigationDelay })];
6666
};
6767
return h(
6868
"a",
@@ -87,10 +87,10 @@ const Link = ({ href, ...rest }: LinkProps, children) => ({
8787
ev.preventDefault();
8888
const action = PreloadPage(state, href);
8989
if (Array.isArray(action)) {
90-
action.push(navigate({ to: href }));
90+
action.push(navigate({ to: href, delay: options.navigationDelay }));
9191
return action;
9292
}
93-
return [action, navigate({ to: href })];
93+
return [action, navigate({ to: href, delay: options.navigationDelay })];
9494
};
9595

9696
const PreloadPageHandler = (state: State, _ev) => {

src/effects/navigate.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
11
interface NavigateArgs {
22
to: string;
3+
delay?: number;
34
}
45

56
/**
67
* Trigger a page navigation
78
*/
8-
const navigateRunner = (dispatch, { to }: NavigateArgs) => {
9-
// Internal links
10-
if (to.startsWith('/')) {
11-
history.pushState(null, '', to)
12-
dispatchEvent(new CustomEvent("pushstate"))
13-
} else {
9+
const navigateRunner = (dispatch, { to, delay = 0 }: NavigateArgs) => {
10+
dispatchEvent(new CustomEvent("navigationstart"))
11+
setTimeout(() => {
12+
// Internal links
13+
if (to.startsWith('/')) {
14+
history.pushState(null, '', to)
15+
dispatchEvent(new CustomEvent("pushstate"))
16+
} else {
1417

15-
// Handle external links
16-
window.location.href = to
17-
}
18+
// Handle external links
19+
window.location.href = to
20+
}
21+
}, delay)
1822
}
1923

2024
const navigate = (args: NavigateArgs) => [navigateRunner, args]

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ export { default as Link } from './components/Link'
33
export { default as Router } from './components/Router'
44
export { default as navigate } from './effects/navigate'
55
export { default as loadStatic } from './effects/loadStatic'
6+
export { default as onRouteChangeStart } from './subscriptions/onRouteChangeStart'
67
export { default as onRouteChanged } from './subscriptions/onRouteChanged'
78
export { default as htmlToVdom } from './utils/htmlToVdom'
89
export { default as isPrerendering } from './utils/isPrerendering'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Action } from 'hyperapp'
2+
3+
interface OnRouteChangeStartArgs {
4+
action: Action<any>;
5+
}
6+
7+
/**
8+
* Every time the browser's location changes,
9+
* trigger the given action with the new location as params
10+
*/
11+
const onRouteChangeStartRunner = (dispatch, { action }: OnRouteChangeStartArgs) => {
12+
const handleLocationChange = () => {
13+
dispatch(action)
14+
}
15+
addEventListener('navigationstart', handleLocationChange)
16+
return () => {
17+
removeEventListener('navigationstart', handleLocationChange)
18+
}
19+
}
20+
21+
const onRouteChangeStart = (args: OnRouteChangeStartArgs) => [onRouteChangeStartRunner, args]
22+
23+
export default onRouteChangeStart

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface Options {
66
notFound?: (state: State) => any
77
fastClicks?: boolean
88
eagerLoad?: boolean
9+
navigationDelay?: number
910
}
1011

1112
export interface Config {

0 commit comments

Comments
 (0)