Mobile Organized Content #79
|
@ -182,13 +182,14 @@
|
|||
justify-content: center;
|
||||
background: var(--light-blue-1);
|
||||
width: 80%;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
text-align: left;
|
||||
padding: 2rem;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
transform: translateX(0);
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.mobileNavClosed {
|
||||
|
@ -212,7 +213,7 @@
|
|||
.burger {
|
||||
display: flex;
|
||||
}
|
||||
.organizedContent > .nav {
|
||||
.wrapper > .nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,17 +29,6 @@ interface Props {
|
|||
currentId: string;
|
||||
link: Link;
|
||||
}
|
||||
interface ChildProps {
|
||||
sections: Section[];
|
||||
currentIndex: number;
|
||||
link: Link;
|
||||
}
|
||||
|
||||
interface MobileProps {
|
||||
open: boolean;
|
||||
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
childProps?: ChildProps;
|
||||
}
|
||||
|
||||
export function OrganizedContent(props: Props) {
|
||||
const sections = createSections(props.sections);
|
||||
|
@ -53,18 +42,6 @@ export function OrganizedContent(props: Props) {
|
|||
const section = sections[currentIndex];
|
||||
const isReadAll = section.id === READ_ALL_ID;
|
||||
|
||||
const childProps: ChildProps = {
|
||||
sections: props.sections,
|
||||
currentIndex: currentIndex,
|
||||
link: props.link,
|
||||
};
|
||||
|
||||
const mobileProps: MobileProps = {
|
||||
open: open,
|
||||
setOpen: setOpen,
|
||||
childProps: childProps,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
open
|
||||
? (document.body.style.overflow = "hidden")
|
||||
|
@ -91,7 +68,13 @@ export function OrganizedContent(props: Props) {
|
|||
</>
|
||||
)}
|
||||
</div>
|
||||
<MobileWrapper {...mobileProps} />
|
||||
<MobileWrapper
|
||||
open={open}
|
||||
setOpen={setOpen}
|
||||
sections={sections}
|
||||
currentIndex={currentIndex}
|
||||
link={props.link}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -172,7 +155,32 @@ function Footer({ sections, currentIndex, link: Link }: FooterProps) {
|
|||
);
|
||||
}
|
||||
|
||||
const Burger = ({ open, setOpen }: MobileProps) => {
|
||||
interface MobileProps {
|
||||
open: boolean;
|
||||
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
sections: Section[];
|
||||
currentIndex: number;
|
||||
link: Link;
|
||||
}
|
||||
|
||||
function MobileWrapper(mobileProps: MobileProps) {
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
useOutsideAlerter(wrapperRef, mobileProps.setOpen);
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<Burger open={mobileProps.open} setOpen={mobileProps.setOpen} />
|
||||
<Menu {...mobileProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface BurgerProps {
|
||||
open: boolean;
|
||||
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const Burger = ({ open, setOpen }: BurgerProps) => {
|
||||
const [prevScrollPos, setPrevScrollPos] = useState(0);
|
||||
const [visible, setVisible] = useState(true);
|
||||
const debouncedPrevScrollPos = useDebounce<number>(prevScrollPos, 100);
|
||||
|
@ -212,25 +220,20 @@ const Burger = ({ open, setOpen }: MobileProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
function MobileWrapper(mobileProps: MobileProps) {
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
useOutsideAlerter(wrapperRef, mobileProps.setOpen);
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<Burger {...mobileProps} />
|
||||
<Menu {...mobileProps} />
|
||||
</div>
|
||||
);
|
||||
interface MenuProps {
|
||||
open: boolean;
|
||||
sections: Section[];
|
||||
currentIndex: number;
|
||||
link: Link;
|
||||
}
|
||||
|
||||
const Menu = ({ open, childProps }: MobileProps) => {
|
||||
const Menu = ({ open, sections, currentIndex, link }: MenuProps) => {
|
||||
const mobileNav = open
|
||||
? styles.mobileNav
|
||||
: styles.mobileNav + " " + styles.mobileNavClosed;
|
||||
return (
|
||||
<div className={mobileNav}>
|
||||
<Nav {...childProps} />
|
||||
<Nav sections={sections} currentIndex={currentIndex} link={link} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -240,19 +243,14 @@ function useOutsideAlerter(
|
|||
setOpen: React.Dispatch<React.SetStateAction<boolean>>
|
||||
) {
|
||||
useEffect(() => {
|
||||
/**
|
||||
* Alert if clicked on outside of element
|
||||
*/
|
||||
const handleClickOutside = (event: Event) => {
|
||||
if (ref.current && !ref.current.contains(event.target as Node)) {
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Bind the event listener
|
||||
document.addEventListener("mousedown", handleClickOutside);
|
||||
return () => {
|
||||
// Unbind the event listener on clean up
|
||||
document.removeEventListener("mousedown", handleClickOutside);
|
||||
};
|
||||
}, [ref, setOpen]);
|
||||
|
|
|
@ -18,7 +18,7 @@ export default function App({ Component, pageProps }: AppProps): JSX.Element {
|
|||
<ThemeProvider theme="light">
|
||||
<MDXProvider components={{ a: Link }}>
|
||||
<div className={styles.appContainer}>
|
||||
<Navbar />
|
||||
{/* <Navbar /> mobile OrganizedContent doesnt like non-mobile navbar*/}
|
||||
{/* Wrapping content with a div to allow for a display: block parent */}
|
||||
<div className={styles.contentContainer}>
|
||||
<Layout>
|
||||
|
|
Loading…
Reference in New Issue