Files
onspring-api-docs/src/app/components/SideBar.tsx
T

145 lines
3.9 KiB
TypeScript
Raw Normal View History

'use client';
2023-04-14 00:40:25 -05:00
import Link from 'next/link.js';
import { useState } from 'react';
import { useSectionContext } from '../context/section';
2023-04-27 16:03:27 -05:00
import { useThemeContext } from '../context/theme';
import { Doc, DocsStructure } from '../types/types';
import { toKebabCase } from '../utils/stringUtils';
2023-04-07 23:18:45 -05:00
import styles from './SideBar.module.css';
2023-04-09 14:50:50 -05:00
function TreeNode({ doc }: { doc: Doc }) {
const [isExpanded, setIsExpanded] =
useState<boolean>(true);
const { section, setSection } = useSectionContext();
const docTitleId = toKebabCase(doc.title);
const isActiveSection = docTitleId === section;
const linkStyle = isActiveSection
? styles.activeLink
: styles.link;
const hasChildren =
doc.children && doc.children?.length > 0;
return (
<li className={styles.listItem}>
{hasChildren ? (
2023-04-13 09:27:38 -05:00
<div className={styles.expandable}>
{doc.copy ? (
<a
onClick={() => setSection(docTitleId)}
href={`#${docTitleId}`}
className={linkStyle}
>
{doc.title}
</a>
) : (
<div className={styles.linkGroup}>
{doc.title}
</div>
)}
2023-04-18 22:51:50 -05:00
<div
className={styles.chevronContainer}
onClick={() => setIsExpanded(!isExpanded)}
>
2023-04-13 09:27:38 -05:00
{isExpanded ? (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className={styles.chevron}
viewBox="0 0 16 16"
>
<path
fillRule="evenodd"
d="M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z"
/>
</svg>
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
className={styles.chevron}
viewBox="0 0 16 16"
>
<path
fillRule="evenodd"
d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"
/>
</svg>
)}
</div>
</div>
) : doc.copy ? (
2023-04-10 00:04:49 -05:00
<a
onClick={() => setSection(docTitleId)}
href={`#${docTitleId}`}
className={linkStyle}
2023-04-10 00:04:49 -05:00
>
{doc.title}
</a>
) : (
<div>{doc.title}</div>
)}
{doc.children &&
doc.children?.length > 0 &&
isExpanded && <ListTree docs={doc.children} />}
</li>
);
}
2023-04-09 14:50:50 -05:00
function ListTree({ docs }: { docs: Doc[] }) {
return (
<ul className={styles.list}>
{docs.map(d => (
<TreeNode key={d.title} doc={d} />
))}
</ul>
);
}
export default function SideBar({
versionDocStructure,
}: {
versionDocStructure: DocsStructure;
}) {
const { theme, setTheme } = useThemeContext();
2023-04-07 23:18:45 -05:00
return (
<div className={styles.container}>
2023-04-20 23:36:52 -05:00
<div className={styles.titleContainer}>
<Link href="/" className={styles.link}>
<h1 className={styles.title}>
<span className={styles.onspring}>
Onspring
</span>{' '}
<span className={styles.api}>API</span>
</h1>
</Link>
2023-04-20 23:36:52 -05:00
<label className={styles.switch}>
<input
2023-04-20 23:36:52 -05:00
title="Toggle dark mode"
onChange={() =>
setTheme(theme === 'light' ? 'dark' : 'light')
}
type="checkbox"
2023-04-21 09:40:29 -05:00
checked={theme === 'dark'}
/>
2023-04-20 23:36:52 -05:00
<span
className={`${styles.slider} ${styles.round}`}
></span>
</label>
</div>
<ListTree docs={versionDocStructure.docs} />
2023-04-07 23:18:45 -05:00
</div>
);
}