Skip to content

Commit

Permalink
feat: sync scroll sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Jun 1, 2020
1 parent 9f8dd0c commit b47edf6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
56 changes: 44 additions & 12 deletions ui/app/src/SideContext/SideContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/** @jsx jsx */
import { FC, ReactNode, RefObject, useEffect, useState } from 'react';
import { FC, RefObject, useEffect, useState, useCallback } from 'react';
import { jsx, Box, NavLink, Flex, Theme } from 'theme-ui';

import {
Sidebar as AppSidebar,
SidebarContext,
Expand All @@ -14,27 +13,50 @@ export interface SideContext {
}

export const SideContext: FC<SideContext> = ({ pageRef }) => {
const [items, setItems] = useState<ReactNode[] | undefined>();
const [items, setItems] = useState<Element[] | undefined>();
const [activeItem, setActiveItem] = useState<Element | undefined>();

const onScroll = useCallback(() => {
const curScroll = window.scrollY;
const pageScroll = pageRef?.current?.getBoundingClientRect().top || 0;
//find first anchor element that is above the scroll position
const curItem = items
? items.find(el => {
const itemPos = el.getBoundingClientRect().top - pageScroll + 100;
console.log(curScroll, pageScroll, itemPos);
return itemPos > curScroll;
})
: undefined;

if (curItem !== activeItem) {
setActiveItem(curItem);
}
}, [activeItem, items, pageRef]);

useEffect(() => {
const links: ReactNode[] = [];
const links: Element[] = [];
const pageEl = pageRef?.current;
if (pageEl) {
const anchors = pageEl.querySelectorAll('a[data-title]');
if (anchors.length > 0) {
anchors.forEach((anchor, index) => {
const href = anchor.getAttribute('href');
anchors.forEach(el => {
const href = el.getAttribute('href');
if (href) {
links.push(
<NavLink key={`context_link_${index}`} href={href}>
{anchor.getAttribute('data-title')}
</NavLink>,
);
links.push(el);
}
});
}
}
setItems(links.length ? links : undefined);
}, [pageRef]);

useEffect(() => {
window.addEventListener('scroll', onScroll, false);
onScroll();
return () => {
window.removeEventListener('scroll', onScroll);
};
}, [onScroll]);
return (
<SidebarContextProvider>
<SidebarContext.Consumer>
Expand All @@ -51,7 +73,17 @@ export const SideContext: FC<SideContext> = ({ pageRef }) => {
borderLeft: (t: Theme) => `1px solid ${t.colors?.shadow}`,
}}
>
<Flex sx={{ flexDirection: 'column' }}>{items}</Flex>
<Flex as="nav" sx={{ flexDirection: 'column' }}>
{items?.map((el, index) => (
<NavLink
key={`context_link_${index}`}
href={el.getAttribute('href') || undefined}
className={el === activeItem ? 'active' : undefined}
>
{el.getAttribute('data-title')}
</NavLink>
))}
</Flex>
</Box>
</AppSidebar>
)}
Expand Down
12 changes: 12 additions & 0 deletions ui/components/src/ThemeContext/ThemeContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,17 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
bg: 'action',
},
},
links: {
nav: {
fontWeight: 300,
fontSize: '14px',
lineHeight: '1.6rem',
'&.active': {
fontWeight: 700,
color: 'primary',
},
},
},
colors: {
...polaris.colors,
gray: '#f6f6f6',
Expand Down Expand Up @@ -130,6 +141,7 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
dark,
);
}, [dark, customTheme]);

return (
<ThemeContext.Provider
value={{
Expand Down

0 comments on commit b47edf6

Please sign in to comment.