diff --git a/src/_design-system/mdx-components/get-mdx-headings.tsx b/src/_design-system/mdx-components/get-mdx-headings.tsx index a162126a90..0f5eb88bde 100644 --- a/src/_design-system/mdx-components/get-mdx-headings.tsx +++ b/src/_design-system/mdx-components/get-mdx-headings.tsx @@ -30,7 +30,9 @@ const createHeading = ( id, className, ...props - }: React.ComponentPropsWithoutRef<"h2">): React.ReactElement { + }: React.ComponentPropsWithoutRef<"h2"> & { + size?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" + }): React.ReactElement { // Nextra tracks anchors in context const setActiveAnchor = useSetActiveAnchor() const slugs = useSlugs() @@ -61,7 +63,7 @@ const createHeading = ( className === "sr-only" ? // can be added by footnotes "sr-only" - : clsx(headingClasses[Tag], "text-neu-900", className) + : clsx(headingClasses[props.size || Tag], "text-neu-900", className) } {...props} > diff --git a/src/components/faq-aggregator/decorations/best-practices.svg b/src/components/faq-aggregator/decorations/best-practices.svg new file mode 100644 index 0000000000..ead38a4597 --- /dev/null +++ b/src/components/faq-aggregator/decorations/best-practices.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/decorations/frontend.svg b/src/components/faq-aggregator/decorations/frontend.svg new file mode 100644 index 0000000000..5b1be09991 --- /dev/null +++ b/src/components/faq-aggregator/decorations/frontend.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/decorations/general.svg b/src/components/faq-aggregator/decorations/general.svg new file mode 100644 index 0000000000..5285544d76 --- /dev/null +++ b/src/components/faq-aggregator/decorations/general.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/src/components/faq-aggregator/decorations/getting-started.svg b/src/components/faq-aggregator/decorations/getting-started.svg new file mode 100644 index 0000000000..853ff0bb18 --- /dev/null +++ b/src/components/faq-aggregator/decorations/getting-started.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/decorations/specification.svg b/src/components/faq-aggregator/decorations/specification.svg new file mode 100644 index 0000000000..586bf85db4 --- /dev/null +++ b/src/components/faq-aggregator/decorations/specification.svg @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/faq-aggregator/index.tsx b/src/components/faq-aggregator/index.tsx new file mode 100644 index 0000000000..84509b9e5d --- /dev/null +++ b/src/components/faq-aggregator/index.tsx @@ -0,0 +1,111 @@ +"use client" + +import { getMdxHeadings } from "@/_design-system/mdx-components/get-mdx-headings" +import { type ReactNode, useRef, useLayoutEffect, useState } from "react" +import ArrowDown from "@/app/conf/_design-system/pixelarticons/arrow-down.svg?svgr" +import BestPracticesIcon from "./decorations/best-practices.svg?svgr" +import FrontendIcon from "./decorations/frontend.svg?svgr" +import GeneralIcon from "./decorations/general.svg?svgr" +import GettingStartedIcon from "./decorations/getting-started.svg?svgr" +import SpecificationIcon from "./decorations/specification.svg?svgr" + +function slugify(text: string): string { + return String(text) + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-|-$)/g, "") +} + +const mdxHeadings = getMdxHeadings() + +const iconMap: Record = { + "getting-started": GettingStartedIcon, + "best-practices": BestPracticesIcon, + frontend: FrontendIcon, + general: GeneralIcon, + specification: SpecificationIcon, +} + +function FaqH1({ id, children }: { id?: string; children?: ReactNode }) { + const slug = id ?? slugify(String(children)) + const Icon = iconMap[slug] ?? GeneralIcon + + return ( +
+
+ +
+ + {children} + +
+ ) +} + +function FaqH2({ id, children }: { id?: string; children?: ReactNode }) { + const slug = id ?? slugify(String(children)) + return ( +
+ +

+ {children} +

+ +
+
+ ) +} + +export function FaqAggregator({ children }: { children: ReactNode }) { + const containerRef = useRef(null) + const [, forceUpdate] = useState(0) + + useLayoutEffect(() => { + const container = containerRef.current + if (!container) return + + const details = container.querySelectorAll("details") + details.forEach(detail => { + const answerContent: Node[] = [] + let sibling = detail.nextSibling + + while (sibling) { + const next = sibling.nextSibling + if (sibling instanceof Element) { + if ( + sibling.tagName === "DETAILS" || + (sibling as HTMLElement).dataset?.heading + ) + break + answerContent.push(sibling) + } else if ( + sibling.nodeType === Node.TEXT_NODE && + sibling.textContent?.trim() + ) { + answerContent.push(sibling) + } + sibling = next + } + + if (answerContent.length > 0) { + answerContent.forEach(node => detail.appendChild(node)) + } + }) + + forceUpdate(n => n + 1) + }, []) + + return
{children}
+} + +export const faqMdxComponents = { + h1: FaqH1, + h2: FaqH2, +} diff --git a/src/components/learn-aggregator/assets/books.svg b/src/components/learn-aggregator/assets/books.svg index b28d4f9656..08ba62271a 100644 --- a/src/components/learn-aggregator/assets/books.svg +++ b/src/components/learn-aggregator/assets/books.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/checkbox.svg b/src/components/learn-aggregator/assets/checkbox.svg index 2fc41369cb..432abbaee5 100644 --- a/src/components/learn-aggregator/assets/checkbox.svg +++ b/src/components/learn-aggregator/assets/checkbox.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + diff --git a/src/components/learn-aggregator/assets/circuit.svg b/src/components/learn-aggregator/assets/circuit.svg index df7625bffe..2324822e55 100644 --- a/src/components/learn-aggregator/assets/circuit.svg +++ b/src/components/learn-aggregator/assets/circuit.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/cog-double.svg b/src/components/learn-aggregator/assets/cog-double.svg index a169230ab5..0e8f272a77 100644 --- a/src/components/learn-aggregator/assets/cog-double.svg +++ b/src/components/learn-aggregator/assets/cog-double.svg @@ -1 +1,29 @@ - \ No newline at end of file + + + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/computer.svg b/src/components/learn-aggregator/assets/computer.svg index 49980390b9..2ea9a797c6 100644 --- a/src/components/learn-aggregator/assets/computer.svg +++ b/src/components/learn-aggregator/assets/computer.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/construction.svg b/src/components/learn-aggregator/assets/construction.svg index 87ea57c465..a3a332693e 100644 --- a/src/components/learn-aggregator/assets/construction.svg +++ b/src/components/learn-aggregator/assets/construction.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/dna.svg b/src/components/learn-aggregator/assets/dna.svg index 4914769413..bdf4234af5 100644 --- a/src/components/learn-aggregator/assets/dna.svg +++ b/src/components/learn-aggregator/assets/dna.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/globe.svg b/src/components/learn-aggregator/assets/globe.svg index 17f6cb543d..731792c5a9 100644 --- a/src/components/learn-aggregator/assets/globe.svg +++ b/src/components/learn-aggregator/assets/globe.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/hierarchy.svg b/src/components/learn-aggregator/assets/hierarchy.svg index f907687b01..ed0bcc4767 100644 --- a/src/components/learn-aggregator/assets/hierarchy.svg +++ b/src/components/learn-aggregator/assets/hierarchy.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/key.svg b/src/components/learn-aggregator/assets/key.svg index a5792cc894..74eb5cb72a 100644 --- a/src/components/learn-aggregator/assets/key.svg +++ b/src/components/learn-aggregator/assets/key.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/layer.svg b/src/components/learn-aggregator/assets/layer.svg index 54b7bb9542..2730903094 100644 --- a/src/components/learn-aggregator/assets/layer.svg +++ b/src/components/learn-aggregator/assets/layer.svg @@ -1 +1,24 @@ - \ No newline at end of file + + + + + + diff --git a/src/components/learn-aggregator/assets/nav-left-circle.svg b/src/components/learn-aggregator/assets/nav-left-circle.svg index 3b568b6fdd..395b0b562e 100644 --- a/src/components/learn-aggregator/assets/nav-left-circle.svg +++ b/src/components/learn-aggregator/assets/nav-left-circle.svg @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/note.svg b/src/components/learn-aggregator/assets/note.svg index 39e0de7c52..90b81e393d 100644 --- a/src/components/learn-aggregator/assets/note.svg +++ b/src/components/learn-aggregator/assets/note.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/product-check.svg b/src/components/learn-aggregator/assets/product-check.svg index 046554e4cd..b5ffbd2670 100644 --- a/src/components/learn-aggregator/assets/product-check.svg +++ b/src/components/learn-aggregator/assets/product-check.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + diff --git a/src/components/learn-aggregator/assets/safe.svg b/src/components/learn-aggregator/assets/safe.svg index 93f832daee..093727d0de 100644 --- a/src/components/learn-aggregator/assets/safe.svg +++ b/src/components/learn-aggregator/assets/safe.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/search.svg b/src/components/learn-aggregator/assets/search.svg index c52d9f08b7..3f824bc454 100644 --- a/src/components/learn-aggregator/assets/search.svg +++ b/src/components/learn-aggregator/assets/search.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + + + + + diff --git a/src/components/learn-aggregator/assets/share.svg b/src/components/learn-aggregator/assets/share.svg index 6567793f34..af002cf99c 100644 --- a/src/components/learn-aggregator/assets/share.svg +++ b/src/components/learn-aggregator/assets/share.svg @@ -1 +1,25 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/solve.svg b/src/components/learn-aggregator/assets/solve.svg index 0479304299..0705b3eba7 100644 --- a/src/components/learn-aggregator/assets/solve.svg +++ b/src/components/learn-aggregator/assets/solve.svg @@ -1 +1,17 @@ - \ No newline at end of file + + + + + diff --git a/src/components/learn-aggregator/assets/startup.svg b/src/components/learn-aggregator/assets/startup.svg index ee982cf48f..2fa142a43b 100644 --- a/src/components/learn-aggregator/assets/startup.svg +++ b/src/components/learn-aggregator/assets/startup.svg @@ -1 +1,23 @@ - \ No newline at end of file + + + + + + + + + + + diff --git a/src/components/learn-aggregator/assets/sync-square.svg b/src/components/learn-aggregator/assets/sync-square.svg index 1931355fad..d6d9b7b34b 100644 --- a/src/components/learn-aggregator/assets/sync-square.svg +++ b/src/components/learn-aggregator/assets/sync-square.svg @@ -1 +1,16 @@ - \ No newline at end of file + + + + + + + + diff --git a/src/components/learn-aggregator/assets/zoom-page.svg b/src/components/learn-aggregator/assets/zoom-page.svg index 9680c94c26..81e62c9a4f 100644 --- a/src/components/learn-aggregator/assets/zoom-page.svg +++ b/src/components/learn-aggregator/assets/zoom-page.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + diff --git a/src/components/learn-aggregator/common-questions.tsx b/src/components/learn-aggregator/common-questions.tsx index 7cafe1d814..d3013c7de9 100644 --- a/src/components/learn-aggregator/common-questions.tsx +++ b/src/components/learn-aggregator/common-questions.tsx @@ -25,19 +25,16 @@ export function CommonQuestionsSection( ) diff --git a/src/components/learn-aggregator/looking-for-more.tsx b/src/components/learn-aggregator/looking-for-more.tsx index 768aaa62da..95c719ad66 100644 --- a/src/components/learn-aggregator/looking-for-more.tsx +++ b/src/components/learn-aggregator/looking-for-more.tsx @@ -7,7 +7,7 @@ export function LookingForMore(props: React.HTMLAttributes) { {...props} className={clsx("gql-container gql-section", props.className)} > -
+

Looking for more?

diff --git a/src/components/nextra-mdx-wrapper.tsx b/src/components/nextra-mdx-wrapper.tsx index 83dde0bfa4..4dc9b4fc2f 100644 --- a/src/components/nextra-mdx-wrapper.tsx +++ b/src/components/nextra-mdx-wrapper.tsx @@ -36,6 +36,10 @@ export function NextraMdxWrapper({ directories, } = config.normalizePagesResult + if (themeContext.toc && typeof themeContext.toc === "object") { + toc = themeContext.toc + } + const tocEl = activeType === "page" || !themeContext.toc || diff --git a/src/components/table-of-contents.tsx b/src/components/table-of-contents.tsx index 0f8ca9af8f..84c3460434 100644 --- a/src/components/table-of-contents.tsx +++ b/src/components/table-of-contents.tsx @@ -86,7 +86,7 @@ export function TableOfContents({ }[depth], "block", activeAnchor[id]?.isActive - ? "text-pri-base contrast-more:!text-pri-base" + ? "text-pri-base contrast-more:!text-pri-base dark:text-pri-light" : "", )} > diff --git a/src/nextra-theme-docs.css b/src/nextra-theme-docs.css index 9b3d03e932..5f8993280a 100644 --- a/src/nextra-theme-docs.css +++ b/src/nextra-theme-docs.css @@ -1585,7 +1585,7 @@ pre } :target > .subheading-anchor:is(html[class~="dark"] *):after { --tw-text-opacity: 1; - color: rgb(115 115 115 / var(--tw-text-opacity, 1)); + color: rgb(110 117 87 / var(--tw-text-opacity, 1)); } .subheading-anchor:after { --tw-content: "#"; diff --git a/src/pages/faq/_meta.ts b/src/pages/faq/_meta.ts index db8b2a9b62..532f762bb3 100644 --- a/src/pages/faq/_meta.ts +++ b/src/pages/faq/_meta.ts @@ -1,8 +1,19 @@ export default { index: { - title: "Overview", + title: "FAQ", + type: "hidden", theme: { - toc: false, + sidebar: false, + timestamp: false, + breadcrumb: false, + toc: [ + { value: "Getting Started", id: "getting-started", depth: 2 }, + { value: "General", id: "general", depth: 2 }, + { value: "Best Practices", id: "best-practices", depth: 2 }, + { value: "Specification", id: "specification", depth: 2 }, + { value: "Frontend", id: "frontend", depth: 2 }, + { value: "Foundation", id: "foundation", depth: 2 }, + ], }, }, "getting-started": "", diff --git a/src/pages/faq/index.mdx b/src/pages/faq/index.mdx index 2a0a6574ef..0882acaec0 100644 --- a/src/pages/faq/index.mdx +++ b/src/pages/faq/index.mdx @@ -1,14 +1,23 @@ -import { Cards } from 'nextra/components' -import metaFile from './_meta' - -# Frequently Asked Questions (FAQ) - - - {Object.entries(metaFile).slice(1).map(([key]) => ( - word[0].toUpperCase() + word.slice(1)).join(' ')} - href={`/faq/${key}`} arrow - /> - ))} - +--- +title: FAQ +--- + +import { FaqAggregator, faqMdxComponents } from "@/components/faq-aggregator" + +import GettingStarted from "./getting-started.mdx" +import General from "./general.mdx" +import BestPractices from "./best-practices.mdx" +import Specification from "./specification.mdx" +import Frontend from "./frontend.mdx" +import Foundation from "./foundation.mdx" + +

Frequently Asked Questions

+ + + + + + + + + diff --git a/src/pages/learn/index.mdx b/src/pages/learn/index.mdx index e3462ff6a9..b2187f13d2 100644 --- a/src/pages/learn/index.mdx +++ b/src/pages/learn/index.mdx @@ -1,3 +1,7 @@ +--- +title: Learn +--- + import { Button } from '@/app/conf/_design-system/button'; import { NavbarFixed } from '../../components/navbar/navbar-fixed'