-
-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[website] Modernize the Base UI website (#538)
Co-authored-by: colmtuite <[email protected]>
- Loading branch information
1 parent
30245d0
commit 053b139
Showing
1,052 changed files
with
10,714 additions
and
11,413 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
{ | ||
"recommendations": [ | ||
"editorconfig.editorconfig", | ||
"dbaeumer.vscode-eslint", | ||
"davidanson.vscode-markdownlint", | ||
"dbaeumer.vscode-eslint", | ||
"editorconfig.editorconfig", | ||
"esbenp.prettier-vscode", | ||
"unifiedjs.vscode-mdx", | ||
"yoavbls.pretty-ts-errors" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +0,0 @@ | ||
Broken links found by `pnpm docs:link-check` that exist: | ||
|
||
27 changes: 27 additions & 0 deletions
27
docs/app/(content)/components/[slug]/getApiReferenceData.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { readFile } from 'node:fs/promises'; | ||
import { ComponentAPIReference } from 'docs-base/types/ComponentAPIReference'; | ||
import kebabCase from 'lodash/kebabCase'; | ||
|
||
export function getApiReferenceData(componentNames: string[]): Promise<ComponentAPIReference[]> { | ||
return Promise.all( | ||
componentNames.map(async (componentName) => { | ||
const kebabedComponentName = kebabCase(componentName); | ||
const apiDescriptionFilePath = `data/api/${kebabedComponentName}.json`; | ||
const translationsFilePath = `data/translations/api-docs/${kebabedComponentName}/${kebabedComponentName}.json`; | ||
|
||
const apiDescription = JSON.parse(await readFile(apiDescriptionFilePath, 'utf-8')); | ||
const translations = JSON.parse(await readFile(translationsFilePath, 'utf-8')); | ||
|
||
return { | ||
name: componentName, | ||
description: translations.componentDescription, | ||
props: Object.keys(apiDescription.props).map((propName) => ({ | ||
name: propName, | ||
...apiDescription.props[propName], | ||
defaultValue: apiDescription.props[propName].default ?? null, | ||
...translations.propDescriptions[propName], | ||
})), | ||
} satisfies ComponentAPIReference; | ||
}), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import * as React from 'react'; | ||
import { Metadata } from 'next'; | ||
import { components } from 'docs-base/src/components/content/MDXComponents'; | ||
import { getMarkdownPage, getMarkdownPageMetadata } from 'docs-base/app/(content)/getMarkdownPage'; | ||
import { ComponentLinkHeader } from 'docs-base/src/components/content/ComponentLinkHeader'; | ||
import { Description } from 'docs-base/src/components/content/Description'; | ||
import { TableOfContents } from 'docs-base/src/components/TableOfContents'; | ||
import routes, { getSlugs } from 'docs-base/data/pages'; | ||
import { SiblingPageLinks } from 'docs-base/src/components/SiblingPageLinks'; | ||
import { EditPageGithubLink } from 'docs-base/src/components/EditPageGithhubLink'; | ||
import { | ||
ApiReference, | ||
getApiReferenceTableOfContents, | ||
} from 'docs-base/src/components/ApiReference'; | ||
import { DemoLoader, DemoLoaderProps } from 'docs-base/src/components/demo/DemoLoader'; | ||
import { getApiReferenceData } from './getApiReferenceData'; | ||
import classes from '../../styles.module.css'; | ||
|
||
const CATEGORY_SEGMENT = 'components'; | ||
|
||
interface Props { | ||
params: { | ||
slug: string; | ||
}; | ||
} | ||
|
||
function componentNameFromSlug(slug: string) { | ||
return slug.replace('react-', ''); | ||
} | ||
|
||
export default async function ComponentPage(props: Props) { | ||
const { | ||
params: { slug }, | ||
} = props; | ||
|
||
const componentName = componentNameFromSlug(slug); | ||
|
||
const { MDXContent, metadata, tableOfContents } = await getMarkdownPage( | ||
CATEGORY_SEGMENT, | ||
componentName, | ||
); | ||
|
||
const documentedComponents = metadata.components?.split(',').map((c: string) => c.trim()) ?? []; | ||
const componentsApi = await getApiReferenceData(documentedComponents); | ||
const apiReferenceToc = getApiReferenceTableOfContents(componentsApi); | ||
|
||
tableOfContents[0].children?.push(apiReferenceToc); | ||
|
||
const allComponents = { | ||
...components, | ||
// eslint-disable-next-line react/no-unstable-nested-components | ||
Demo: (demoProps: Omit<DemoLoaderProps, 'componentName'>) => ( | ||
<DemoLoader componentName={componentName} {...demoProps} /> | ||
), | ||
// eslint-disable-next-line react/no-unstable-nested-components | ||
Description: () => <Description text={metadata.description} />, | ||
// eslint-disable-next-line react/no-unstable-nested-components | ||
ComponentLinkHeader: () => ( | ||
<ComponentLinkHeader ariaSpecUrl={metadata.waiAria} githubLabel={metadata.githubLabel} /> | ||
), | ||
}; | ||
|
||
return ( | ||
<React.Fragment> | ||
<main className={classes.content}> | ||
<MDXContent components={{ ...allComponents }} /> | ||
<ApiReference componentsApi={componentsApi} /> | ||
<div> | ||
<div className={classes.editLink}> | ||
<EditPageGithubLink category={CATEGORY_SEGMENT} slug={componentName} /> | ||
</div> | ||
<div> | ||
<SiblingPageLinks currentSlug={`/${CATEGORY_SEGMENT}/${slug}`} pages={routes} /> | ||
</div> | ||
</div> | ||
</main> | ||
|
||
<TableOfContents toc={tableOfContents} renderDepth={3} /> | ||
</React.Fragment> | ||
); | ||
} | ||
|
||
export async function generateStaticParams() { | ||
return getSlugs(`/${CATEGORY_SEGMENT}`).map((slug) => ({ slug })); | ||
} | ||
|
||
export async function generateMetadata({ params }: Props): Promise<Metadata> { | ||
const { slug } = params; | ||
const componentName = componentNameFromSlug(slug); | ||
const { title = 'Components', description } = await getMarkdownPageMetadata( | ||
CATEGORY_SEGMENT, | ||
componentName, | ||
); | ||
|
||
return { | ||
title, | ||
description, | ||
twitter: { | ||
title, | ||
description, | ||
}, | ||
openGraph: { | ||
title, | ||
description, | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import path from 'node:path'; | ||
import fs from 'node:fs'; | ||
import { readFile } from 'node:fs/promises'; | ||
import rehypePrettyCode from 'rehype-pretty-code'; | ||
import { evaluate } from '@mdx-js/mdx'; | ||
import * as jsxRuntime from 'react/jsx-runtime'; | ||
import remarkFrontmatter from 'remark-frontmatter'; | ||
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'; | ||
import remarkGfm from 'remark-gfm'; | ||
import rehypeSlug from 'rehype-slug'; | ||
import extractToc, { type Toc } from '@stefanprobst/rehype-extract-toc'; | ||
import exportToc from '@stefanprobst/rehype-extract-toc/mdx'; | ||
import { read as readVFile } from 'to-vfile'; | ||
import { matter } from 'vfile-matter'; | ||
import { config } from 'docs-base/config'; | ||
|
||
export const DATA_PATH = path.join(process.cwd(), 'data'); | ||
|
||
export interface PageMetadata { | ||
title: string; | ||
description: string; | ||
components?: string; | ||
githubLabel?: string; | ||
waiAria?: string; | ||
slug: string; | ||
} | ||
|
||
export const getMarkdownPage = async (basePath: string, slug: string) => { | ||
const mdxFilePath = path.join(DATA_PATH, basePath, `/${slug}/${slug}.mdx`); | ||
const mdFilePath = path.join(DATA_PATH, basePath, `/${slug}/${slug}.md`); | ||
|
||
let filePath: string; | ||
|
||
if (fs.existsSync(mdxFilePath)) { | ||
filePath = mdxFilePath; | ||
} else if (fs.existsSync(mdFilePath)) { | ||
filePath = mdFilePath; | ||
} else { | ||
throw new Error(`No MD(X) file found for ${basePath}/${slug}`); | ||
} | ||
|
||
const mdxSource = await readFile(filePath, 'utf8'); | ||
|
||
const { | ||
default: MDXContent, | ||
frontmatter, | ||
tableOfContents, | ||
// @ts-ignore https://github.com/mdx-js/mdx/issues/2463 | ||
} = await evaluate(mdxSource, { | ||
...jsxRuntime, | ||
remarkPlugins: [remarkGfm, remarkFrontmatter, remarkMdxFrontmatter], | ||
rehypePlugins: [ | ||
[rehypePrettyCode, { theme: config.shikiThemes }], | ||
rehypeSlug, | ||
extractToc, | ||
exportToc, | ||
], | ||
}); | ||
|
||
return { | ||
metadata: { | ||
...(frontmatter as Partial<PageMetadata>), | ||
slug, | ||
} as PageMetadata, | ||
tableOfContents: tableOfContents as Toc, | ||
MDXContent, | ||
}; | ||
}; | ||
|
||
export const getMarkdownPageMetadata = async (basePath: string, slug: string) => { | ||
const mdxFilePath = path.join(DATA_PATH, basePath, `/${slug}/${slug}.mdx`); | ||
const mdFilePath = path.join(DATA_PATH, basePath, `/${slug}/${slug}.md`); | ||
|
||
let filePath: string; | ||
|
||
if (fs.existsSync(mdxFilePath)) { | ||
filePath = mdxFilePath; | ||
} else if (fs.existsSync(mdFilePath)) { | ||
filePath = mdFilePath; | ||
} else { | ||
throw new Error(`No MD(X) file found for ${basePath}/${slug}`); | ||
} | ||
|
||
const file = await readVFile(filePath); | ||
matter(file); | ||
|
||
return file.data.matter as PageMetadata; | ||
}; |
Oops, something went wrong.