Skip to content

Commit

Permalink
Merge pull request #214 from augustomallmann/scroll-top-false
Browse files Browse the repository at this point in the history
feat: disable scrolling to the top of the page
  • Loading branch information
tj-kev committed Feb 11, 2022
2 parents ee780aa + f7b693b commit 194d674
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
24 changes: 24 additions & 0 deletions docs/flareact-link.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,27 @@ export default function Index() {
);
}
```

## Scroll

The default behaviour of the Link component is to scroll to the top of the page.
When there's a hash defined, it will scroll to the specific ID.

This feature is useful for a layered component where each tab needs to update the route.
By default, the scroll would go to the top of the page, but the correct behaviour is to update the route and change the tab's content.

You can disable this behaviour by passing a `false` value to `scroll`:

```js
import Link from "flareact/link";

export default function Index() {
return (
<div>
<Link href="/about" scroll={false}>
<a>Change route without scrolling top</a>
</Link>
</div>
);
}
```
4 changes: 2 additions & 2 deletions src/link.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function Link(props) {
const [childElm, setChildElm] = useState();
const child = Children.only(props.children);

const { href, as } = props;
const { href, as, scroll = true } = props;

const shouldPrefetch = props.prefetch !== false;

Expand Down Expand Up @@ -54,7 +54,7 @@ export default function Link(props) {

e.preventDefault();

router.push(href, as);
router.push(href, as, scroll);
}

const childProps = {
Expand Down
20 changes: 12 additions & 8 deletions src/router.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useContext, useState, useEffect, useMemo } from "react";
import { extractDynamicParams } from "./utils";
import React, { useContext, useEffect, useMemo, useState } from "react";

import { DYNAMIC_PAGE } from "./worker/pages";
import { extractDynamicParams } from "./utils";

const RouterContext = React.createContext();

Expand Down Expand Up @@ -45,17 +46,17 @@ export function RouterProvider({
}, [protocol, host, route.asPath, params]);

useEffect(() => {
// On initial page load, replace history state with format expected by router
// On initial page load, replace history state with format expected by router
window.history.replaceState(route, null, route.asPath);
}, [])

useEffect(() => {
async function loadNewPage() {
const { href, asPath } = route;
const { href, asPath, scroll } = route;
const pagePath = normalizePathname(href);
const normalizedAsPath = normalizePathname(asPath);

if (!pageCache[normalizedAsPath] || hasPagePropsExpired(pageCache[normalizedAsPath].expiry)) {
if ( !pageCache[normalizedAsPath] || hasPagePropsExpired(pageCache[normalizedAsPath].expiry)) {
const page = await pageLoader.loadPage(pagePath);
const { pageProps } = await pageLoader.loadPageProps(normalizedAsPath);
const revalidateSeconds = getRevalidateValue(pageProps);
Expand All @@ -69,7 +70,9 @@ export function RouterProvider({
}

setComponent(pageCache[normalizedAsPath]);
setTimeout(() => scrollToHash(asPath), 0);
if (scroll) {
setTimeout(() => scrollToHash(asPath), 0);
}
}

if (initialPath === route.asPath) {
Expand All @@ -83,7 +86,7 @@ export function RouterProvider({
if (seconds === null) {
return null;
}

return Date.now() + (seconds * 1000);
}

Expand All @@ -107,12 +110,13 @@ export function RouterProvider({
return pageProps.revalidate;
}

function push(href, as) {
function push(href, as, scroll) {
const asPath = as || href;

setRoute({
href,
asPath,
scroll
});

// Blank this out so any return trips to the original component re-fetches props.
Expand Down

0 comments on commit 194d674

Please sign in to comment.