feat(website): switch overload on hash location (#9699)

* feat(website): switch overload on hash location

* Update apps/website/src/components/OverloadSwitcher.tsx

---------

Co-authored-by: Noel <buechler.noel@outlook.com>
This commit is contained in:
brynpttrsn 2023-07-15 13:34:28 -04:00 committed by GitHub
parent 3c85fb21e6
commit 20268ac0c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 4 deletions

View file

@ -4,17 +4,52 @@ import { VscChevronDown } from '@react-icons/all-files/vsc/VscChevronDown';
import { VscVersions } from '@react-icons/all-files/vsc/VscVersions';
import { Menu, MenuButton, MenuItem, useMenuState } from 'ariakit/menu';
import type { PropsWithChildren, ReactNode } from 'react';
import { useMemo, useState } from 'react';
import { useCallback, useMemo, useState, useEffect } from 'react';
export interface OverloadSwitcherProps {
methodName: string;
overloads: ReactNode[];
}
export default function OverloadSwitcher({ overloads, children }: PropsWithChildren<{ overloads: ReactNode[] }>) {
export default function OverloadSwitcher({
methodName,
overloads,
children,
}: PropsWithChildren<{ methodName: string; overloads: ReactNode[] }>) {
const [hash, setHash] = useState(() => (typeof window === 'undefined' ? '' : window.location.hash));
const hashChangeHandler = useCallback(() => {
setHash(window.location.hash);
}, []);
const [overloadIndex, setOverloadIndex] = useState(1);
const overloadedNode = overloads[overloadIndex - 1]!;
const menu = useMenuState({ gutter: 8, sameWidth: true, fitViewport: true });
useEffect(() => {
window.addEventListener('hashchange', hashChangeHandler);
return () => {
window.removeEventListener('hashchange', hashChangeHandler);
};
});
useEffect(() => {
if (hash) {
const elementId = hash.replace('#', '');
const [name, idx] = elementId.split(':');
if (name && methodName === name) {
if (idx) {
const hashOverload = Number.parseInt(idx, 10);
const resolvedOverload = Math.max(Math.min(hashOverload, overloads.length), 1);
setOverloadIndex(Number.isNaN(resolvedOverload) ? 1 : resolvedOverload);
}
const element = document.querySelector(`[id^='${name}']`);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}
}
}, [hash, methodName, overloads.length]);
const menuItems = useMemo(
() =>
overloads.map((_, idx) => (

View file

@ -16,7 +16,7 @@ export function Function({ item }: { item: ApiFunction }) {
return (
<div>
{header}
<OverloadSwitcher overloads={overloads} />
<OverloadSwitcher methodName={item.displayName} overloads={overloads} />
</div>
);
}

View file

@ -28,7 +28,7 @@ export function Method({
</Fragment>
));
return <OverloadSwitcher overloads={overloads} />;
return <OverloadSwitcher methodName={method.displayName} overloads={overloads} />;
}
// We have just a single method, render it on the server.