Skip to content

Commit

Permalink
Refactor navigation (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
wyhaines committed Feb 13, 2024
1 parent f6d4a75 commit bd15521
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 111 deletions.
4 changes: 4 additions & 0 deletions config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const config: Config = {
{
label: 'What is Topos?',
content: [
{
label: 'Getting Started',
path: '/',
},
{
label: 'Chapter overview: What is Topos?',
path: '/content/module-1',
Expand Down
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"katex": "^0.13.24",
"prismjs": "^1.29.0",
"react": "^18.2.0",
"react-collapsed": "^4.1.2",
"react-cookie": "^6.1.1",
"react-dom": "^18.2.0",
"react-icons": "^5.0.1",
Expand Down
105 changes: 105 additions & 0 deletions src/components/NavGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { NavItem } from './NavItem';
import React, { Dispatch, SetStateAction, useState } from 'react';
import { useCollapse } from 'react-collapsed';
import config from '../../config';
import { NavigationItemType } from '../interfaces/Config';
import { IconCaretDown } from './icons/IconCaretDown';
import { Link } from 'gatsby';
import { BiCollapseVertical, BiExpandVertical } from 'react-icons/bi';
import { twMerge } from 'tailwind-merge';

interface NavGroupItem {
label: string;
path?: string;
content?: Array<NavigationItemType>;
}

interface NavGroupProps {
navGroupItem: NavigationItemType;
navGroupIndex: number;
setNavExpanded: Dispatch<SetStateAction<boolean>>;
pageTransition: boolean;
}

export const NavGroup: React.FC<NavGroupProps> = ({
navGroupItem,
navGroupIndex,
setNavExpanded,
pageTransition,
}) => {
const [isExpanded, setExpanded] = useState(false);
const { getCollapseProps, getToggleProps } = useCollapse({ isExpanded });

// if (navGroupItem.path && !isExpanded) setExpanded(true);

return (
<li
className="flex flex-col gap-2"
key={`navGroup${navGroupIndex}`}
{...getToggleProps({
onClick: () => setExpanded((prevExpanded) => !prevExpanded),
})}
>
{navGroupItem.path ? (
<strong>
{isExpanded ? (
<BiCollapseVertical
style={{ marginTop: '3px', float: 'left', marginRight: '0.5rem' }}
/>
) : (
<BiExpandVertical
style={{ marginTop: '3px', float: 'left', marginRight: '0.5rem' }}
/>
)}
<Link
className="hover:text-action-reg"
to={navGroupItem.path}
activeClassName="text-action-reg text-semibold"
onClick={() => setNavExpanded(false)}
getProps={(props) => {
if (props.isCurrent && !isExpanded) {
setExpanded(true);
}

return {
className: props.isCurrent
? 'text-action-reg text-semibold'
: 'hover:text-action-reg',
};
}}
>
{navGroupItem.label}
</Link>
</strong>
) : (
<strong>
{isExpanded ? (
<BiCollapseVertical
style={{ marginTop: '3px', float: 'left', marginRight: '0.5rem' }}
/>
) : (
<BiExpandVertical
style={{ marginTop: '3px', float: 'left', marginRight: '0.5rem' }}
/>
)}
{navGroupItem.label}
</strong>
)}
{navGroupItem.content && (
<ul className={`flex flex-col gap-2`} {...getCollapseProps()}>
{navGroupItem.content.map(
(navItem: NavigationItemType, navItemIndex: number) => (
<NavItem
navItem={navItem}
key={`navItem${navItemIndex}`}
isExpanded={isExpanded}
setExpanded={setExpanded}
setNavExpanded={setNavExpanded}
/>
)
)}
</ul>
)}
</li>
);
};
108 changes: 108 additions & 0 deletions src/components/NavItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import React, { Dispatch, SetStateAction, useState } from 'react';
import config from '../../config';
import { NavigationItemType } from '../interfaces/Config';
import { IconCaretDown } from './icons/IconCaretDown';
import { Link } from 'gatsby';
import { twMerge } from 'tailwind-merge';

interface NavItem {
label: string;
path?: string;
content?: Array<NavigationItemType>;
}

interface NavItemProps {
navItem: NavigationItemType;
isExpanded: boolean;
setExpanded: Dispatch<SetStateAction<boolean>>;
setNavExpanded: Dispatch<SetStateAction<boolean>>;
}

// class NavItem extends React.Component<{ location: Location }> {
export const NavItem: React.FC<NavItemProps> = ({
navItem,
isExpanded,
setExpanded,
setNavExpanded,
}) => {
const PAGE_IN_PROGRESS_PATH = '/content/page-in-progress.html';

const disabled = navItem.label.toLowerCase().startsWith('disabled:');
const navItemLabel = navItem.label.replace('disabled:', '');
const disabledStyle = disabled
? {
opacity: 0.5,
pointerEvents: 'none',
}
: {};
return <li className={navItem.content ? '-translate-x-[1rem]' : ''}>
{navItem.path ? (
<Link
{...{
className: 'hover:text-action-reg max-md:block',
activeClassName: 'text-action-reg text-semibold',
style: disabledStyle,
to: navItem.path,
onClick: (event) => {
if (disabled) {
event.stopPropagation();
} else {
setNavExpanded(false);
}
},
}}
getProps={(props) => {
if (props.isCurrent && !isExpanded) {
setExpanded(true);
}

return {
className: props.isCurrent
? 'text-action-reg text-semibold'
: 'hover:text-action-reg',
};
}}
>
{navItemLabel}
</Link>
) : (
<button
className="inline-flex cursor-pointer items-center gap-2 hover:text-action-reg max-md:w-full"
onClick={() => setExpanded(!isExpanded)}
>
<span
className={twMerge(
'fill-icon inline-flex h-2 w-2 transition-all ease-in-out',
isExpanded ? 'rotate-0' : '-rotate-90'
)}
>
<IconCaretDown />
</span>
{navItem.label}
</button>
)}
{navItem.content && (
<ul
className={twMerge(
'ml-4 flex flex-col gap-2 pl-3 pt-3',
!isExpanded && 'hidden'
)}
aria-hidden={!isExpanded}
>
{navItem.content.map(
(subNavItem: NavigationItemType, subNavItemIndex: number) => {
return (
<NavItem
navItem={subNavItem}
key={`subNavItem${subNavItemIndex}`}
isExpanded={isExpanded}
setExpanded={setExpanded}
setNavExpanded={setNavExpanded}
/>
);
}
)}
</ul>
)}
</li>;
};
Loading

0 comments on commit bd15521

Please sign in to comment.