diff --git a/apps/web/prebuild.js b/apps/web/prebuild.js
index 18dc759cc..945849036 100644
--- a/apps/web/prebuild.js
+++ b/apps/web/prebuild.js
@@ -1,7 +1,7 @@
const fs = require('fs')
const path = require('path')
-function walkDir(dir, basePath = '') {
+function walkDir(dirName, dir, basePath = '', depth = 1) {
const entries = fs.readdirSync(dir, { withFileTypes: true })
return entries
@@ -9,12 +9,31 @@ function walkDir(dir, basePath = '') {
const relativePath = path.join(basePath, entry.name)
if (entry.isDirectory()) {
- let route = { title: entry.name }
- const links = walkDir(path.join(dir, entry.name), relativePath)
+ let route = {
+ title: depth === 1 ? entry.name.toLocaleUpperCase() : entry.name,
+ }
+ const entryName = entry.name
+ const childPath = path.join(dir, entry.name)
+ const links = walkDir(entryName, childPath, relativePath, depth + 1)
if (links.length > 0) {
- route.links = links
- } else {
- route.href = '/' + relativePath
+ if (depth === 1) {
+ route.href = '.' + relativePath
+ route.links = links
+ } else if (depth === 2) {
+ route.href = '/docs/api-reference/' + relativePath
+ const mdxFilePath = path.join(childPath, 'page.mdx')
+ console.log(`Generating ${mdxFilePath}`)
+ const mdxContent = `# ${dirName} ${entryName}\n\n${links
+ .map(
+ (link) =>
+ `- [${
+ link.title.charAt(0).toUpperCase() +
+ link.title.slice(1).toLowerCase()
+ }](./${entryName}/${link.title})`
+ )
+ .join('\n')}`
+ fs.writeFileSync(mdxFilePath, mdxContent)
+ }
}
return route
}
@@ -29,7 +48,7 @@ function generateApiRefRoutes() {
return []
}
- return walkDir(apiRefPath)
+ return walkDir('api-reference', apiRefPath)
}
const apiRefRoutes = generateApiRefRoutes()
diff --git a/apps/web/src/components/Footer.tsx b/apps/web/src/components/Footer.tsx
index 4d34e2cec..ffcc2d179 100644
--- a/apps/web/src/components/Footer.tsx
+++ b/apps/web/src/components/Footer.tsx
@@ -5,15 +5,15 @@ import { usePathname } from 'next/navigation'
import { Button } from '@/components/Button'
import { routes } from '@/components/Navigation/routes'
-import { DiscordIcon } from '@/components/icons/DiscordIcon'
-import { GitHubIcon } from '@/components/icons/GitHubIcon'
import { TwitterIcon } from '@/components/icons/TwitterIcon'
+import { GitHubIcon } from '@/components/icons/GitHubIcon'
+import { DiscordIcon } from '@/components/icons/DiscordIcon'
function PageLink({
- label,
- page,
- previous = false,
-}: {
+ label,
+ page,
+ previous = false,
+ }: {
label: string
page: { href: string; title: string }
previous?: boolean
@@ -43,27 +43,10 @@ function PageLink({
function PageNavigation() {
let initialPathname = usePathname()
// Running on the server, there's bug with usePathname() and basePath https://github.com/vercel/next.js/issues/52700
- if (typeof window === 'undefined' && initialPathname === '/')
- initialPathname = '/docs'
+ if (typeof window === 'undefined' && initialPathname === '/') initialPathname = '/docs'
- const allPages = routes.flatMap((group) => {
- if ('links' in group) {
- return group.links.flatMap((link) => {
- if ('links' in link) {
- return {
- title: link.title,
- href: link.href,
- icon: link.icon,
- }
- }
- return link
- })
- }
- return [group]
- })
- const currentPageIndex = allPages.findIndex(
- (page) => page.href === initialPathname
- )
+ const allPages = routes.flatMap(group => group.links)
+ const currentPageIndex = allPages.findIndex(page => page.href === initialPathname)
if (currentPageIndex === -1) return null
@@ -76,12 +59,19 @@ function PageNavigation() {
{previousPage && (
)}
{nextPage && (
)}
@@ -89,18 +79,21 @@ function PageNavigation() {
}
function SocialLink({
- href,
- icon: Icon,
- children,
-}: {
+ href,
+ icon: Icon,
+ children,
+ }: {
href: string
icon: React.ComponentType<{ className?: string }>
children: React.ReactNode
}) {
return (
-
+
{children}
-
+
)
}
@@ -110,21 +103,29 @@ function SmallPrint() {
- © FoundryLabs, Inc. {new Date().getFullYear()}. All rights
- reserved.
+ © FoundryLabs, Inc. {new Date().getFullYear()}. All rights reserved.
548 Market Street #83122, San Francisco, CA 94104
-
+
Follow us on Twitter
-
+
Follow us on GitHub
-
+
Join our Discord server
@@ -135,8 +136,8 @@ function SmallPrint() {
export function Footer() {
return (
)
}
@@ -145,8 +146,8 @@ export function FooterMain() {
return (
)
-}
+}
\ No newline at end of file
diff --git a/apps/web/src/components/Search.tsx b/apps/web/src/components/Search.tsx
index 355b0c2ee..b9bba507c 100644
--- a/apps/web/src/components/Search.tsx
+++ b/apps/web/src/components/Search.tsx
@@ -1,5 +1,8 @@
'use client'
+import { forwardRef, Fragment, Suspense, useCallback, useEffect, useId, useRef, useState } from 'react'
+import Highlighter from 'react-highlight-words'
+import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import {
type AutocompleteApi,
type AutocompleteCollection,
@@ -7,22 +10,10 @@ import {
createAutocomplete,
} from '@algolia/autocomplete-core'
import clsx from 'clsx'
-import { usePathname, useRouter, useSearchParams } from 'next/navigation'
-import {
- forwardRef,
- Fragment,
- Suspense,
- useCallback,
- useEffect,
- useId,
- useRef,
- useState,
-} from 'react'
-import Highlighter from 'react-highlight-words'
-import { DialogAnimated } from '@/components/DialogAnimated'
import { routes } from '@/components/Navigation/routes'
import { type Result } from '@/mdx/search.mjs'
+import { DialogAnimated } from '@/components/DialogAnimated'
type EmptyObject = Record
@@ -91,7 +82,7 @@ function useAutocomplete({ close }: { close: () => void }) {
]
})
},
- })
+ }),
)
return { autocomplete, autocompleteState }
@@ -99,7 +90,12 @@ function useAutocomplete({ close }: { close: () => void }) {
function SearchIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
-
{hierarchy.length > 0 && (
{hierarchy.map((item, itemIndex, items) => (
-
+
@@ -241,7 +261,7 @@ function SearchResults({
if (collection.items.length === 0) {
return (
-
+
Nothing found for{' '}
@@ -281,15 +301,15 @@ const SearchInput = forwardRef<
return (
-
+
{
+ onKeyDown={event => {
if (
event.key === 'Escape' &&
!autocompleteState.isOpen &&
@@ -309,7 +329,8 @@ const SearchInput = forwardRef<
/>
{autocompleteState.status === 'stalled' && (
-
+
)}
@@ -317,10 +338,10 @@ const SearchInput = forwardRef<
})
function SearchDialog({
- open,
- setOpen,
- className,
-}: {
+ open,
+ setOpen,
+ className,
+ }: {
open: boolean
setOpen: (open: boolean) => void
className?: string
@@ -420,12 +441,12 @@ function useSearchProps() {
setOpen: useCallback(
(open: boolean) => {
const { width = 0, height = 0 } =
- buttonRef.current?.getBoundingClientRect() ?? {}
+ buttonRef.current?.getBoundingClientRect() ?? {}
if (!open || (width !== 0 && height !== 0)) {
setOpen(open)
}
},
- [setOpen]
+ [setOpen],
),
},
}
@@ -436,9 +457,7 @@ export function Search() {
const { buttonProps, dialogProps } = useSearchProps()
useEffect(() => {
- setModifierKey(
- /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘' : 'Ctrl '
- )
+ setModifierKey(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform) ? '⌘' : 'Ctrl ')
}, [])
return (
@@ -448,7 +467,7 @@ export function Search() {
className="hidden h-8 w-full items-center gap-2 whitespace-nowrap rounded-full bg-white pl-2 pr-3 text-sm text-zinc-500 ring-1 ring-zinc-900/10 transition hover:ring-zinc-900/20 ui-not-focus-visible:outline-none dark:bg-white/5 dark:text-zinc-400 dark:ring-inset dark:ring-white/10 dark:hover:ring-white/20 lg:flex"
{...buttonProps}
>
-
+
Search in docs...
{modifierKey}
@@ -456,7 +475,10 @@ export function Search() {
-
+
)
@@ -473,10 +495,13 @@ export function MobileSearch() {
aria-label="Search in docs..."
{...buttonProps}
>
-
+
-
+
)