From e0459e607046b3314f49b342a37c97facd7697ab Mon Sep 17 00:00:00 2001 From: Marcell Toth Date: Tue, 23 Jun 2020 15:09:25 +0200 Subject: [PATCH] feat(toc): scroll the active item into view on mount (#173) * chore: add fake navigation to the ToC story * feat: scroll active item into view on initial render --- src/TableOfContents/index.tsx | 15 ++++++- src/__stories__/TableOfContents/index.tsx | 50 ++++++++++++++++++----- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/TableOfContents/index.tsx b/src/TableOfContents/index.tsx index 687ca969..0995ec72 100644 --- a/src/TableOfContents/index.tsx +++ b/src/TableOfContents/index.tsx @@ -216,6 +216,14 @@ function DefaultRowImpl({ item, isExpanded, toggl const isActive = item.isActive && !showSkeleton; const isDisabled = item.isDisabled; + const holderCallbackRef = React.useCallback((e: HTMLDivElement) => { + if (e && isActive) { + e.scrollIntoView({ block: 'center' }); + } + // we only want this on initial render + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + let icon = item.icon; if (item.activeIcon && (isActive || isSelected)) { icon = item.activeIcon; @@ -289,7 +297,12 @@ function DefaultRowImpl({ item, isExpanded, toggl ) : null; return ( -
+
{icon && ( diff --git a/src/__stories__/TableOfContents/index.tsx b/src/__stories__/TableOfContents/index.tsx index 60f6fefe..76a43b05 100644 --- a/src/__stories__/TableOfContents/index.tsx +++ b/src/__stories__/TableOfContents/index.tsx @@ -17,11 +17,7 @@ const styles = { storiesOf('TableOfContents', module) .addDecorator(withKnobs) .add('studio /w custom RowComponent', () => { - return ( -
- -
- ); + return ; }) .add('studio without rowComponent', () => { return ( @@ -52,8 +48,42 @@ const MobileStory = () => { ); }; -const RowComponent: RowComponentType = props => ( - - - -); +const NavigationContext = React.createContext({ path: '', setPath: (_: string) => {} }); + +const CustomComponentStory = () => { + const [path, setPath] = React.useState('/reference/petstore/openapi.v1.yaml/paths/~1pets~1{petId}/get'); + + const contextValue = React.useMemo(() => ({ path, setPath }), [path, setPath]); + + const contentsWithDynamicIsActive = React.useMemo(() => { + return studioContents.map(c => ({ ...c, isActive: c.to === path })); + }, [path]); + + return ( + +
+ +
+
+ ); +}; + +const RowComponent: RowComponentType = props => { + const { setPath } = React.useContext(NavigationContext); + + const handleClick = React.useCallback( + (e: React.MouseEvent) => { + if (props.item.to) { + setPath(props.item.to); + } + e.preventDefault(); + }, + [props.item.to, setPath], + ); + + return ( + + + + ); +};