-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #393 from gadget-inc/droberts/GGT-1931-no-scroll-o…
…n-replace-nav-on-page fix(navigation): don't scroll to hash on replace navigation within page
- Loading branch information
Showing
7 changed files
with
220 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
packages/fastify-renderer/src/client/react/wouter-extension.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import 'wouter' | ||
|
||
declare module 'wouter' { | ||
export interface RouterProps { | ||
navigationHistory?: NavigationHistory | ||
} | ||
|
||
export interface NavigationHistory { | ||
current?: NavigationHistoryItem | ||
previous?: NavigationHistoryItem | ||
} | ||
|
||
export interface NavigationHistoryItem { | ||
path: string | ||
replace: boolean | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import React from 'react' | ||
import { Link, useLocation } from 'wouter' | ||
|
||
const NavigationHistoryTest = () => { | ||
const [path, navigate] = useLocation() | ||
|
||
return ( | ||
<> | ||
<h1>Navigation Test</h1> | ||
<p>Leaving this page will set the navigation details on the window for inspection in the tests</p> | ||
<br /> | ||
<Link href="/navigation-history-test#section"> | ||
<a id="section-link">Go to the content</a> | ||
</Link> | ||
<br /> | ||
<Link href="/"> | ||
<a id="home-link">Home</a> | ||
</Link> | ||
<br /> | ||
<button | ||
id="section-link-replace" | ||
onClick={() => { | ||
navigate('/navigation-history-test#section', { replace: true }) | ||
}} | ||
> | ||
Update url without scrolling | ||
</button> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<br /> | ||
<h2 id="section">Another Section</h2> | ||
<p> | ||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Fuga earum maiores, excepturi aspernatur perspiciatis | ||
doloribus suscipit voluptates ipsam nam in nostrum vel obcaecati cum illum ex quasi quo est at. | ||
</p> | ||
</> | ||
) | ||
} | ||
|
||
export default NavigationHistoryTest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
packages/test-apps/simple-react/test/navigation-history.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { Page } from 'playwright-chromium' | ||
import { newTestPage, reactReady, rootURL } from '../../helpers' | ||
|
||
describe('navigation details', () => { | ||
let page: Page | ||
|
||
beforeEach(async () => { | ||
page = await newTestPage() | ||
await page.goto(`${rootURL}/navigation-history-test`) | ||
await reactReady(page) | ||
}) | ||
|
||
test('navigating to an anchor will scroll down to the anchor', async () => { | ||
const visibleBeforeClick = await isIntersectingViewport(page, '#section') | ||
expect(visibleBeforeClick).toBe(false) | ||
|
||
await page.click('#section-link') | ||
|
||
const visibleAfterClick = await isIntersectingViewport(page, '#section') | ||
expect(visibleAfterClick).toBe(true) | ||
}) | ||
|
||
test('navigating to an anchor that is on the same page via replace: true will not scroll to the anchor', async () => { | ||
const visibleBeforeClick = await isIntersectingViewport(page, '#section') | ||
expect(visibleBeforeClick).toBe(false) | ||
|
||
await page.click('#section-link-replace') | ||
|
||
const visibleAfterClick = await isIntersectingViewport(page, '#section') | ||
expect(visibleAfterClick).toBe(false) | ||
}) | ||
}) | ||
|
||
const isIntersectingViewport = (page: Page, selector: string): Promise<boolean> => { | ||
return page.$eval(selector, async (element) => { | ||
const visibleRatio: number = await new Promise((resolve) => { | ||
const observer = new IntersectionObserver((entries) => { | ||
resolve(entries[0].intersectionRatio) | ||
observer.disconnect() | ||
}) | ||
observer.observe(element) | ||
// Firefox doesn't call IntersectionObserver callback unless | ||
// there are rafs. | ||
requestAnimationFrame(() => { | ||
/**/ | ||
}) | ||
}) | ||
return visibleRatio > 0 | ||
}) | ||
} |