Compare commits

...

4 Commits

Author SHA1 Message Date
Trisha Lim
d746ce8c8d collapse upgrade guides on side nav 2025-03-25 18:11:15 +07:00
Benjamin S. Leveritt
297a2dd92d Fix depth indentation 2025-03-24 08:49:52 +00:00
Trisha Lim
fd17ecb2b0 make framework selector sticky, add gradient to bottom 2025-03-24 08:49:52 +00:00
Trisha Lim
7cd0bd7ebc reduce spacing in TOC to match left nav 2025-03-24 08:49:52 +00:00
8 changed files with 121 additions and 47 deletions

View File

@@ -10,6 +10,15 @@
:focus-visible {
@apply ring-2 ring-blue/75 dark:ring-blue-400/75;
}
details > summary {
@apply cursor-pointer;
&.list-none::-webkit-details-marker,
&.list-none::marker {
display: none;
}
}
}
@layer components {

View File

@@ -1,7 +1,10 @@
import { SideNavHeader } from "@/components/SideNavHeader";
import { SideNavItem } from "@/components/SideNavItem";
import { Framework } from "@/lib/framework";
import { useFramework } from "@/lib/use-framework";
import { clsx } from "clsx";
import { Icon } from "gcmp-design-system/src/app/components/atoms/Icon";
import { usePathname } from "next/navigation";
import React from "react";
interface SideNavItem {
@@ -13,6 +16,8 @@ interface SideNavItem {
[key in Framework]: number;
};
items?: SideNavItem[];
collapse?: boolean;
prefix?: string;
}
export function SideNav({
items,
@@ -26,42 +31,98 @@ export function SideNav({
footer?: React.ReactNode;
}) {
return (
<div className={clsx(className, "text-sm space-y-4 px-2")}>
<div
className={clsx(
className,
"text-sm h-full pt-3 md:pt-8 flex flex-col gap-4 px-2",
)}
>
{children}
{items.map(({ name, href, items }) => (
<div key={name}>
<SideNavHeader href={href}>{name}</SideNavHeader>
{items &&
items.map(({ name, href, items, done }) => (
<ul key={name}>
<li>
<SideNavItem href={href}>
<span
className={
done === 0 ? "text-stone-400 dark:text-stone-600" : ""
}
>
{name}
</span>
</SideNavItem>
</li>
<div className="flex-1 relative overflow-y-auto px-2 -mx-2">
{items.map((item) => (
<SideNavSection item={item} key={item.name} />
))}
{items && items?.length > 0 && (
<ul className="pl-4">
{items.map(({ name, href }) => (
<li key={href}>
<SideNavItem href={href}>{name}</SideNavItem>
</li>
))}
</ul>
)}
</ul>
))}
</div>
))}
{footer}
{footer}
<div
aria-hidden
className={clsx(
"h-12 right-0 sticky bottom-0 left-0",
"bg-gradient-to-t from-white to-transparent",
"dark:from-stone-950",
"hidden md:block",
)}
/>
</div>
</div>
);
}
export function SideNavSection({
item: { name, href, collapse, items, prefix },
}: { item: SideNavItem }) {
const path = usePathname();
const framework = useFramework();
if (!collapse) {
return (
<>
<SideNavHeader href={href}>{name}</SideNavHeader>
<SideNavSectionList items={items} />
</>
);
}
return (
<>
<details
className="group [&:not(:first-child)]:mt-4"
open={
prefix
? path.startsWith(
prefix.replace("/docs/", "/docs/" + framework + "/"),
)
: true
}
>
<summary className="list-none">
<SideNavHeader href={href}>
{name}
{collapse && (
<Icon
className="group-open:rotate-180 transition-transform group-hover:text-stone-500 text-stone-400 dark:text-stone-600"
name="chevronDown"
size="xs"
/>
)}
</SideNavHeader>
</summary>
<SideNavSectionList items={items} />
</details>
</>
);
}
export function SideNavSectionList({ items }: { items?: SideNavItem[] }) {
return (
!!items?.length && (
<ul>
{items.map(({ name, href, items, done }) => (
<li key={name}>
<SideNavItem href={href}>
<span
className={
done === 0 ? "text-stone-400 dark:text-stone-600" : ""
}
>
{name}
</span>
</SideNavItem>
</li>
))}
</ul>
)
);
}

View File

@@ -1,22 +1,26 @@
import { clsx } from "clsx";
import Link from "next/link";
export function SideNavHeader({
href,
children,
className,
}: {
href?: string;
children: React.ReactNode;
className?: string;
}) {
const className =
"block font-medium text-stone-900 py-1 dark:text-white mb-1";
const classes = clsx(
className,
"flex items-center gap-2 justify-between font-medium text-stone-900 py-1 dark:text-white mb-1 [&:not(:first-child)]:mt-4",
);
if (href) {
return (
<Link className={className} href={href}>
<Link className={classes} href={href}>
{children}
</Link>
);
}
return <p className={className}>{children}</p>;
return <p className={classes}>{children}</p>;
}

View File

@@ -40,9 +40,8 @@ export default function DocsLayout({
<div className="container relative md:grid md:grid-cols-12 md:gap-12">
<div
className={clsx(
"py-8",
"pr-3 md:col-span-4 lg:col-span-3",
"sticky align-start top-[72px] h-[calc(100vh-72px)] overflow-y-auto",
"sticky align-start top-[61px] h-[calc(100vh-61px)] overflow-y-auto",
"hidden md:block",
)}
>
@@ -53,7 +52,7 @@ export default function DocsLayout({
{tocItems?.length && (
<>
<TableOfContents
className="pl-3 py-6 shrink-0 text-sm sticky align-start top-[72px] w-[16rem] h-[calc(100vh-72px)] overflow-y-auto hidden lg:block"
className="pl-3 py-6 shrink-0 text-sm sticky align-start top-[61px] w-[16rem] h-[calc(100vh-61px)] overflow-y-auto hidden lg:block"
items={tocItems}
/>
</>

View File

@@ -20,9 +20,9 @@ const TocList = ({
};
return (
<ul className="space-y-3" style={{ paddingLeft: `${level}rem` }}>
<ul className="space-y-2" style={{ paddingLeft: "1rem" }}>
{items.map((item) => (
<li key={item.id} className="space-y-3">
<li key={item.id} className="space-y-2">
{item.id && (
<Link
href={`#${item.id}`}
@@ -35,7 +35,7 @@ const TocList = ({
{item.value}
</Link>
)}
{item.children && (
{!!item.children?.length && (
<TocList
items={item.children}
level={level + 1}

View File

@@ -20,8 +20,7 @@ export function DocNav({ className }: { className?: string }) {
if (!item.href?.startsWith("/docs")) return item;
const frameworkDone = (item.done as any)[framework] ?? 0;
let done =
typeof item.done === "number" ? item.done : frameworkDone;
let done = typeof item.done === "number" ? item.done : frameworkDone;
let href = item.href.replace("/docs", `/docs/${framework}`);
return {

View File

@@ -73,7 +73,7 @@ export function ClassOrInterface({
<div className="relative not-prose">
<div
id={name}
className="peer sticky top-0 mt-4 md:top-[72px] md:pt-8 bg-white dark:bg-stone-950 z-20"
className="peer sticky top-0 mt-4 md:top-[61px] md:pt-8 bg-white dark:bg-stone-950 z-20"
>
<Link
href={"#" + name}

View File

@@ -63,10 +63,12 @@ export const docNavigationItems = [
href: "/docs/inspector",
done: 100,
},
]
],
},
{
name: "Upgrade guides",
collapse: true,
prefix: "/docs/upgrade",
items: [
{
// upgrade guides