211 lines
6.0 KiB
TypeScript

import {
Route,
createBrowserRouter,
createRoutesFromElements,
RouterProvider,
redirect,
} from "react-router-dom";
import MainLayout from "./MainLayout";
import Home from "./Home";
import DocsLayout from "./DocsLayout";
import ErrorBoundary from "./ErrorHandler";
import DynamicLayout from "./DynamicLayout";
import DocsIntroduction, {
tableOfContents as docsIntroductionToc,
} from "./docs/docs/introduction.mdx";
import DocsInstallation, {
tableOfContents as docsInstallationToc,
} from "./docs/docs/installation.mdx";
import ComponentsButton, {
tableOfContents as componentsButtonToc,
} from "./docs/components/Button.mdx";
import ComponentsCheckbox, {
tableOfContents as componentsCheckboxToc,
} from "./docs/components/Checkbox.mdx";
import ComponentsDialog, {
tableOfContents as componentsDialogToc,
} from "./docs/components/Dialog.mdx";
import ComponentsDrawer, {
tableOfContents as componentsDrawerToc,
} from "./docs/components/Drawer.mdx";
import ComponentsTabs, {
tableOfContents as componentsTabsToc,
} from "./docs/components/Tabs.mdx";
import ComponentsToast, {
tableOfContents as componentsToastToc,
} from "./docs/components/Toast.mdx";
import { ForwardedRef, forwardRef, useContext, useEffect, useRef } from "react";
import { HeadingContext } from "./HeadingContext";
function buildThresholdList() {
let thresholds = [];
let numSteps = 20;
for (let i = 1.0; i <= numSteps; i++) {
let ratio = i / numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
function HashedHeaders(Level: `h${1 | 2 | 3 | 4 | 5 | 6}`) {
return (prop: any, ref: ForwardedRef<HTMLHeadingElement>) => {
const internalRef = useRef<HTMLHeadingElement | null>(null);
const [_, setActiveHeadings] = useContext(HeadingContext);
useEffect(() => {
const observer = new IntersectionObserver(
([{ target, intersectionRatio }]) => {
if (intersectionRatio > 0.5) {
setActiveHeadings((prev) => [...prev, target.id]);
} else {
setActiveHeadings((prev) => prev.filter((id) => id !== target.id));
}
},
{
root: null,
rootMargin: "0px",
threshold: buildThresholdList(),
}
);
if (internalRef.current) {
observer.observe(internalRef.current);
}
return () => {
observer.disconnect();
};
}, [internalRef.current]);
return (
<Level
{...prop}
className={`${prop.className}`}
ref={(el) => {
internalRef.current = el;
if (typeof ref === "function") {
ref(el);
} else if (el && ref) {
ref.current = el;
}
}}
/>
);
};
}
const overrideComponents = {
pre: forwardRef<HTMLPreElement, any>((props: any, ref) => (
<pre ref={ref} {...props} className={`${props.className} hljs`} />
)),
code: forwardRef<HTMLElement, any>((props: any, ref) => (
<code
ref={ref}
{...props}
className={`${props.className} rounded-md bg-neutral-800 text-orange-500 font-light p-1 before:content-none after:content-none`}
/>
)),
table: forwardRef<HTMLTableElement, any>((props: any, ref) => (
<div className="overflow-auto">
<table ref={ref} {...props} className={`${props.className}`} />
</div>
)),
h1: forwardRef<HTMLHeadingElement, any>(HashedHeaders("h1")),
h2: forwardRef<HTMLHeadingElement, any>(HashedHeaders("h2")),
h3: forwardRef<HTMLHeadingElement, any>(HashedHeaders("h3")),
h4: forwardRef<HTMLHeadingElement, any>(HashedHeaders("h4")),
h5: forwardRef<HTMLHeadingElement, any>(HashedHeaders("h5")),
h6: forwardRef<HTMLHeadingElement, any>(HashedHeaders("h6")),
};
const router = createBrowserRouter(
createRoutesFromElements(
<Route path="/" element={<MainLayout />} errorElement={<ErrorBoundary />}>
<Route index element={<Home />} />
<Route path="docs" element={<DocsLayout />}>
<Route
index
element={
<DynamicLayout toc={docsIntroductionToc}>
<DocsIntroduction />
</DynamicLayout>
}
/>
<Route
path="installation"
element={
<DynamicLayout toc={docsInstallationToc}>
<DocsInstallation />
</DynamicLayout>
}
/>
<Route path="components">
<Route index loader={() => redirect("/docs/components/button")} />
<Route
path="button"
element={
<DynamicLayout toc={componentsButtonToc}>
<ComponentsButton components={overrideComponents} />
</DynamicLayout>
}
/>
<Route
path="checkbox"
element={
<DynamicLayout toc={componentsCheckboxToc}>
<ComponentsCheckbox components={overrideComponents} />
</DynamicLayout>
}
/>
<Route
path="dialog"
element={
<DynamicLayout toc={componentsDialogToc}>
<ComponentsDialog components={overrideComponents} />
</DynamicLayout>
}
/>
<Route
path="drawer"
element={
<DynamicLayout toc={componentsDrawerToc}>
<ComponentsDrawer components={overrideComponents} />
</DynamicLayout>
}
/>
<Route
path="tabs"
element={
<DynamicLayout toc={componentsTabsToc}>
<ComponentsTabs components={overrideComponents} />
</DynamicLayout>
}
/>
<Route
path="toast"
element={
<DynamicLayout toc={componentsToastToc}>
<ComponentsToast components={overrideComponents} />
</DynamicLayout>
}
/>
</Route>
</Route>
</Route>
)
);
function App() {
return (
<>
<RouterProvider router={router} />
</>
);
}
export default App;