Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/components/docs-breadcrumbs.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { ChevronRightIcon } from "@heroicons/react/24/outline";
import { useRouter } from "next/router";
import Link from "@/components/link";
import { normalizeHref } from "@/utils/strings";

export default function DocsBreadcrumbs({ routes }) {
const generateBreadcrumbs = (breadcrumbRoutes, currentRoute) => {
const breadcrumbs = [];

const traverse = (navigationRoutes, path) => {
const currentIndex = navigationRoutes.findIndex(
(route) => normalizeHref(route.route) === normalizeHref(path),
);

if (currentIndex === -1) {
return;
}

breadcrumbs.unshift(navigationRoutes[currentIndex]);

const parentPath = navigationRoutes[currentIndex].parentPath;
if (!parentPath) {
return;
}

traverse(navigationRoutes, parentPath);
};

traverse(routes, currentRoute);
return breadcrumbs;
};

const router = useRouter();
const currentPath = router.pathname;
const breadcrumbLinks = generateBreadcrumbs(routes, currentPath);

if (breadcrumbLinks.length === 0 || currentPath === "/docs") {
return;
}

const homeRoute = routes[0];
homeRoute.title = "Docs";
breadcrumbLinks.unshift(homeRoute);

return (
<div className="mb-7 mt-4 md:mb-10 md:mt-2">
<div className="flex flex-wrap items-center gap-2 text-sm">
{breadcrumbLinks.map((breadcrumb, index) =>
normalizeHref(breadcrumb.route) === normalizeHref(currentPath) ? (
<span key={index}>{breadcrumb.title}</span>
) : (
<Link
key={index}
className="font-normal text-gray-500 no-underline transition duration-200 ease-in hover:text-white focus:text-white"
href={breadcrumb.route}
noDefaultStyles
aria-label={breadcrumb.title}
>
<span>{breadcrumb.title}</span>
<span>
<ChevronRightIcon className="inline h-5 w-10 pl-4 align-text-top" />
</span>
</Link>
),
)}
</div>
</div>
);
}
36 changes: 31 additions & 5 deletions src/components/docs-layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,65 @@ import {
DisclosurePanel,
} from "@headlessui/react";
import { ChevronRightIcon, ChevronDownIcon } from "@heroicons/react/24/outline";
import DocsBreadcrumbs from "./docs-breadcrumbs";
import DocsPreviousNextLinks from "./docs-previous-next-link";
import OnThisPageNav from "./on-this-page-nav";
import DocsNav from "@/components/docs-nav";
import routes from "@/pages/docs/nav.json";
import "rehype-callouts/theme/vitepress";

const flattenRoutes = (routeConfig) => {
const flatRoutes = [];

const traverse = (innerRoutes, parentPath = "") => {
for (const route of innerRoutes) {
const fullPath = `${parentPath}${route.route}`;
flatRoutes.push({ ...route, fullPath, parentPath });

if (route.children) {
traverse(route.children, `${parentPath}${route.route}`);
}
}
};

traverse(routeConfig);
return flatRoutes;
};

export default function DocumentPage({ children, metadata }) {
const flatRoutes = flattenRoutes(routes);
return (
<>
<Disclosure
as="div"
className="sticky top-[85px] z-10 border-b-[1px] border-gray-800 bg-gray-900/80 backdrop-blur-sm md:hidden"
className="sticky top-[84px] z-10 border-b-[1px] border-gray-800 bg-gray-900/80 backdrop-blur-sm md:hidden"
>
<DisclosureButton className="group flex items-center rounded-md px-2 py-1.5 text-white/70 hover:text-white">
<ChevronDownIcon className="relative z-20 hidden h-4 w-4 group-data-[open]:inline" />
<ChevronRightIcon className="inline h-4 w-4 group-data-[open]:hidden" />
<span className="pl-1">Menu</span>
</DisclosureButton>
<DisclosurePanel as="nav" className="hidden data-[open]:block">
<DocsNav className="container-main" routes={routes} />
<DocsNav
className="container-main h-screen max-h-screen overflow-y-scroll"
routes={routes}
/>
</DisclosurePanel>
</Disclosure>
<main className="relative mx-auto flex grid-cols-[1fr_auto_1fr] flex-col gap-6 md:grid">
<main className="relative mx-auto flex max-w-full grid-cols-[1fr_auto_1fr] flex-col gap-6 overflow-scroll md:grid">
<nav className="sticky top-[84px] hidden h-min w-60 overflow-y-auto p-6 md:block">
<DocsNav routes={routes} />
</nav>
<nav className="sticky top-[84px] order-last hidden h-min w-[240px] overflow-y-auto p-6 lg:block">
<OnThisPageNav>{children}</OnThisPageNav>
</nav>
<article className="container-main prose prose-invert min-h-[calc(100vh-120px)] max-w-[80ch] py-14 md:py-24">
<article className="container-main xs:py-20 prose prose-invert min-h-[calc(100vh-120px)] max-w-full py-0 sm:max-w-[80ch] sm:py-20 md:py-24">
<DocsBreadcrumbs routes={flatRoutes} />
{metadata?.title && (
<h1 className="article-title">{metadata.title}</h1>
<h1 className="article-title break-words">{metadata.title}</h1>
)}
{children}
<DocsPreviousNextLinks routes={flatRoutes} />
</article>
</main>
</>
Expand Down
4 changes: 2 additions & 2 deletions src/components/docs-nav.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Fragment } from "react";
import Link from "@/components/link";
import { classNames } from "@/utils/strings";
import { normalizeHref, classNames } from "@/utils/strings";

export default function DocsNav({ as, routes, level = 0, className }) {
const As = as || Fragment;
Expand Down Expand Up @@ -29,7 +29,7 @@ function NavItem({ item, level, ...props }) {
<li className="py-2 text-gray-400">
<Link
data-doc-nav-level={level}
href={item.route}
href={normalizeHref(item.route)}
noDefaultStyles
activeClassName="text-blue-500 active"
{...props}
Expand Down
53 changes: 53 additions & 0 deletions src/components/docs-previous-next-link.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ChevronLeftIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
import { useRouter } from "next/router";
import Link from "@/components/link";
import { normalizeHref } from "@/utils/strings";

export default function DocsPreviousNextLinks({ routes }) {
const router = useRouter();
const currentPath = router.pathname;

const currentIndex = routes.findIndex(
(route) => normalizeHref(route.route) === normalizeHref(currentPath),
);

if (currentIndex === -1) {
return;
}

const previousPage = routes[currentIndex - 1];
const nextPage = routes[currentIndex + 1];

return (
<nav aria-label="pagination" className="mb-4 mt-8 flex justify-between">
{previousPage && (
<Link
className="max-w-[200px] font-normal text-gray-400 no-underline transition duration-200 ease-in hover:text-white focus:text-white"
href={previousPage.route}
noDefaultStyles
aria-label={`Go to previous page: ${previousPage.title}`}
>
<span className="mb-1 ml-10 block text-sm">Previous</span>
<span>
<ChevronLeftIcon className="inline h-5 w-10 pr-4 align-text-top" />
</span>
<span className="text-white">{previousPage.title}</span>
</Link>
)}
{nextPage && (
<Link
className="max-w-[200px] font-normal text-gray-400 no-underline transition duration-200 ease-in hover:text-white focus:text-white"
href={nextPage.route}
noDefaultStyles
aria-label={`Go to next page: ${nextPage.title}`}
>
<span className="mb-1 block text-sm">Next</span>
<span className="text-white">{nextPage.title}</span>
<span>
<ChevronRightIcon className="inline h-5 w-10 pl-4 align-text-top" />
</span>
</Link>
)}
</nav>
);
}
2 changes: 1 addition & 1 deletion src/components/footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function Footer() {
<div className="grid grid-cols-1 gap-8 pt-14 sm:grid-cols-2 lg:grid-cols-3 lg:pt-24">
<FooterColumns />
</div>
<div className="mt-24 text-gray-500">
<div className="mt-2 text-gray-500 lg:mt-24">
<p>
Powered by{" "}
<Link
Expand Down
20 changes: 17 additions & 3 deletions src/components/header.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { SiDiscord, SiGithub } from "@icons-pack/react-simple-icons";
import { useState } from "react";
import FaustLogo from "./faust-logo";
import PrimaryMenu from "./primary-menu";
import SearchBar from "./search-bar";
import Link from "@/components/link";
import { classNames } from "@/utils/strings";

const socialIcons = [
{
Expand All @@ -18,8 +20,17 @@ const socialIcons = [
];

export default function Header() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isSearchOpen, setIsSearchOpen] = useState(false);

return (
<div className="container-blur-bg sticky top-0 z-10 border-b-[1px] border-gray-800 bg-gray-900/80">
<div
className={classNames(
"container-blur-bg top-0 border-b-[1px] border-gray-800 bg-gray-900/80",
isMenuOpen ? "fixed z-[11] w-full" : "sticky z-10",
isSearchOpen ? "z-[11]" : "z-10",
)}
>
<header className="container mx-auto flex items-center justify-between px-4 py-6 sm:px-6 md:max-w-6xl md:px-8">
<div className="flex items-center gap-8">
<Link
Expand All @@ -37,9 +48,12 @@ export default function Header() {
</Link>
</div>
<div className="flex items-center gap-5 md:w-full md:justify-between">
<PrimaryMenu />
<PrimaryMenu
onMenuToggle={setIsMenuOpen}
setIsMenuOpen={setIsMenuOpen}
/>
<span className="flex gap-5">
<SearchBar />
<SearchBar setIsSearchOpen={setIsSearchOpen} />
<div className="hidden items-center space-x-4 md:flex">
{socialIcons.map(({ url, name, icon: Icon }) => (
<Link
Expand Down
7 changes: 5 additions & 2 deletions src/components/primary-menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const CustomLink = forwardRef((props, reference) => {
);
});

export default function PrimaryMenu({ className }) {
export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
return (
<nav className={classNames("flex items-center space-x-4", className)}>
<ul className="hidden flex-row space-x-4 pl-4 md:flex">
Expand Down Expand Up @@ -51,7 +51,10 @@ export default function PrimaryMenu({ className }) {
</li>
</ul>
<Menu>
<MenuButton className="group rounded-md px-2 py-1.5 text-white/70 hover:text-white md:hidden">
<MenuButton
className="group rounded-md px-2 py-1.5 text-white/70 hover:text-white md:hidden"
onClick={() => setIsMenuOpen(!isMenuOpen)}
>
<span className="sr-only hidden group-data-[open]:block">
Open main nav
</span>
Expand Down
14 changes: 10 additions & 4 deletions src/components/search-bar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import debounce from "lodash.debounce";
import { useRouter } from "next/router";
import { useState, useEffect, useRef, useCallback } from "react";

export default function SearchBar() {
export default function SearchBar({ setIsSearchOpen }) {
const [items, setItems] = useState([]);
const [inputValue, setInputValue] = useState("");
const [isModalOpen, setIsModalOpen] = useState(false);
Expand All @@ -15,9 +15,13 @@ export default function SearchBar() {
setIsModalOpen(true);
setInputValue("");
setItems([]);
}, []);
setIsSearchOpen(true);
}, [setIsSearchOpen]);

const closeModal = useCallback(() => setIsModalOpen(false), []);
const closeModal = useCallback(() => {
setIsModalOpen(false);
setIsSearchOpen(false);
}, [setIsSearchOpen]);

const handleOutsideClick = useCallback(
(event) => {
Expand Down Expand Up @@ -125,7 +129,9 @@ export default function SearchBar() {
<>
<button
className="inline-flex items-center rounded-md bg-gray-800 px-2 py-1.5 text-sm font-medium text-gray-400 hover:bg-gray-700"
onClick={openModal}
onClick={() => {
openModal();
}}
type="button"
>
<span className="sr-only md:hidden">Open search</span>
Expand Down
12 changes: 6 additions & 6 deletions src/pages/docs/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ From data fetching to Block components, Faust.js® has you covered. Build your h

Some of the main Faust.js® features include:

| Feature | Description |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| [Authentication](/docs/how-to/authentication/) | Authenticate users in your Next.js app with WordPress |
| [Block Components](/docs/how-to/rendering-blocks/) | Render WordPress blocks in your Next.js app |
| [Post Preview](/docs/how-to/post-preview/) | Preview posts and pages in your Next.js app before publishing them |
| [Template Hierarchy](/docs/how-to/template-heirarchy/) | Fetch data and render posts and pages with a React based version of WordPress' Template Hierarchy |
| Feature | Description |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| [Authentication](/docs/how-to/authentication/) | Authenticate users in your Next.js app with WordPress |
| [Block Components](/docs/how-to/rendering-blocks/) | Render WordPress blocks in your Next.js app |
| [Post Preview](/docs/how-to/post-previews/) | Preview posts and pages in your Next.js app before publishing them |
| [Template Hierarchy](/docs/how-to/rendering-blocks-with-the-template-hierarchy/) | Fetch data and render posts and pages with a React based version of WordPress' Template Hierarchy |

## How to Use These Docs

Expand Down
4 changes: 4 additions & 0 deletions src/utils/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ export function classNames(...arguments_) {

return classes;
}

export function normalizeHref(path) {
return path.endsWith("/") ? path : `${path}/`;
}
Loading