Skip to content

Commit

Permalink
chore: upgrade to react router v6 (PROVCON-3003)
Browse files Browse the repository at this point in the history
  • Loading branch information
darekplawecki committed Dec 16, 2024
1 parent be11c9a commit 5e518d4
Show file tree
Hide file tree
Showing 26 changed files with 3,848 additions and 4,421 deletions.
3 changes: 2 additions & 1 deletion demo/.babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"module-resolver",
{
"alias": {
"@stoplight/elements": "../packages/elements/src"
"@stoplight/elements": "../packages/elements/src",
"@stoplight/elements-dev-portal": "../packages/elements-dev-portal/src"
}
}
],
Expand Down
5 changes: 3 additions & 2 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
},
"dependencies": {
"@stoplight/mosaic": "^1.53.4",
"@stoplight/elements": "^8.4.2",
"@stoplight/elements": "^8.5.2",
"@stoplight/elements-dev-portal": "^2.5.2",
"history": "^5.0.0",
"react": "16.14.0",
"react-dom": "16.14.0",
"react-github-btn": "1.4.0",
"react-router-dom": "6.0.0-beta.0"
"react-router-dom": "^6.28.0"
},
"devDependencies": {
"@types/jest": "^26.0.22",
Expand Down
4 changes: 2 additions & 2 deletions demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Flex, Provider as MosaicProvider, useIconStore } from '@stoplight/mosaic';
import React, { useState } from 'react';
import { useSearchParams } from 'react-router-dom';

import { DemoNavbar } from './components/DemoNavbar';
import { ElementsAPI } from './components/ElementsAPI';
import { DEFAULT_API_URL } from './constants';
import { GlobalContext } from './context';

export function App() {
const [searchParams] = useSearchParams();
const { search } = window.location;
const searchParams = new URLSearchParams(search);
const setDefaultStyle = useIconStore(state => state.setDefaultStyle);

React.useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion demo/src/components/ElementsAPI.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const ElementsAPI: React.FC = () => {

return (
<Box flex={1} overflowY={layout !== 'stacked' ? 'hidden' : undefined}>
<API apiDescriptionUrl={specUrlWithProxy} router="hash" layout={layout} />
<API apiDescriptionUrl={specUrlWithProxy} router="history" layout={layout} />
</Box>
);
};
5 changes: 1 addition & 4 deletions demo/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@ import '@stoplight/elements-core/styles.css';
import { subscribeTheme } from '@stoplight/mosaic';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';

import { App } from './App';

subscribeTheme();

ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
<App />
</React.StrictMode>,
document.getElementById('root'),
);
2 changes: 2 additions & 0 deletions demo/webpack/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');

const absoluteElementsPath = resolve(__dirname, '../../packages/elements/src');
const absoluteElementsCorePath = resolve(__dirname, '../../packages/elements-core/src');
const absoluteElementsDevPortalPath = resolve(__dirname, '../../packages/elements-dev-portal/src');

console.log(absoluteElementsPath);

Expand All @@ -15,6 +16,7 @@ module.exports = {
alias: {
'@stoplight/elements': absoluteElementsPath,
'@stoplight/elements-core': absoluteElementsCorePath,
'@stoplight/elements-dev-portal': absoluteElementsDevPortalPath,
},
fallback: {
stream: false,
Expand Down
3 changes: 1 addition & 2 deletions packages/elements-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@
"nanoid": "^3.1.32",
"prop-types": "^15.7.2",
"react-query": "^3.34.19",
"react-router-dom": "^5.2.0",
"react-router-hash-link": "^2.1.0",
"react-router-dom": "^6.28.0",
"tslib": "^2.1.0",
"urijs": "^1.19.11",
"util": "^0.12.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ describe('Article', () => {
});

it('given hash router, should have correct links', () => {
location.hash = '#/test';
const { unmount } = render(<ArticleWithRouter router="hash" data="[abc](#abc)" />);

expect(screen.getByText(/abc/i)).toHaveAttribute('href', '#/test#abc');
expect(screen.getByText(/abc/i)).toHaveAttribute('href', '#abc');

unmount();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useResponsiveLayout } from '../../hooks/useResponsiveLayout';
import { LogoProps } from '../../types';
import { Logo } from '../Logo';
import { PoweredByLink } from '../PoweredByLink';
import type { TableOfContentsItem } from '../TableOfContents';
import type { CustomLinkComponent, TableOfContentsItem } from '../TableOfContents';
import { TableOfContents } from '../TableOfContents';
import { MobileTopNav } from './MobileTopNav';

Expand Down Expand Up @@ -129,7 +129,7 @@ export const Sidebar = ({
<TableOfContents
tree={tree}
activeId={pathname}
Link={Link}
Link={Link as CustomLinkComponent}
onLinkClick={onTocClick}
isInResponsiveMode={isInResponsiveMode}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { LinkProps } from '@stoplight/mosaic';
import React from 'react';
import { HashLink } from 'react-router-hash-link';

const externalRegex = new RegExp('^(?:[a-z]+:)?//', 'i');

Expand All @@ -21,8 +20,8 @@ export const ReactRouterMarkdownLink = ({
);
}
return (
<HashLink to={href} title={title}>
<a href={href as string} title={title}>
{children}
</HashLink>
</a>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* This is copied from https://github.com/ncoughlin/scroll-to-hash-element/blob/main/src/index.tsx
* Unfortunately this package does not contain typescript definitions, so we can not use it directly.
*/
import { useEffect, useLayoutEffect, useRef, useState } from 'react';

interface ScrollToHashElementProps {
/** On first run do we jump or scroll? */
initialBehavior?: ScrollBehavior;
behavior?: ScrollBehavior;
inline?: ScrollLogicalPosition;
block?: ScrollLogicalPosition;
}

export const ScrollToHashElement = ({
behavior = 'auto',
initialBehavior = 'auto',
inline = 'nearest',
block = 'start',
}: ScrollToHashElementProps): null => {
const [hash, setHash] = useState(window.location.hash);
const [count, setCount] = useState(0);
const originalListeners = useRef<{ [key: string]: Function }>({});

// We need to know if this is the first run. If it is, we can do an instant jump, no scrolling.
const [firstRun, setFirstRun] = useState(true);
useEffect(() => setFirstRun(false), []);

useEffect(() => {
const handleLocationChange = () => {
setHash(window.location.hash);

// We increment count just so the layout effect will run if the hash is the same.
// Otherwise the user might click a hashlink a second time and it won't go anywhere.
setCount((count: number) => count + 1);
};

const onPopState = () => {
window.dispatchEvent(new Event('locationchange'));
};

const addWindowListeners = () => {
originalListeners.current.pushState = window.history.pushState;
originalListeners.current.replaceState = window.history.replaceState;

window.history.pushState = function (...args: any) {
const result = originalListeners.current.pushState.apply(this, args);
window.dispatchEvent(new Event('pushstate'));
window.dispatchEvent(new Event('locationchange'));
return result;
};

window.history.replaceState = function (...args: any) {
const result = originalListeners.current.replaceState.apply(this, args);
window.dispatchEvent(new Event('replacestate'));
window.dispatchEvent(new Event('locationchange'));
return result;
};

window.addEventListener('popstate', onPopState);
window.addEventListener('locationchange', handleLocationChange);
};

// Cleanup the event listeners on component unmount
const removeWindowListeners = () => {
window.history.pushState = originalListeners.current.pushState as typeof window.history.pushState;
window.history.replaceState = originalListeners.current.replaceState as typeof window.history.replaceState;
window.removeEventListener('popstate', onPopState);
window.removeEventListener('locationchange', handleLocationChange);
};

addWindowListeners();
return removeWindowListeners;
}, []);

useLayoutEffect(() => {
const removeHashCharacter = (str: string) => {
return str.slice(1);
};

if (hash) {
const element = document.getElementById(removeHashCharacter(hash));

if (element) {
// console.log(`scrollIntoView ${hash} behavior: ${behavior}, inline: ${inline}, block: ${block}`);
element.scrollIntoView({
behavior: firstRun ? initialBehavior : behavior,
inline: inline,
block: block,
});
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hash, count, firstRun]);

return null;
};
Loading

0 comments on commit 5e518d4

Please sign in to comment.