This commit is contained in:
oneao committed 2026-03-18 17:14:34 +08:00
1 parent 52cef511d6
commit 68f08d921a
184 files changed
+19499 -1

No files matched your search

@@ -0,0 +1,75 @@
import type { ReactNode } from 'react'
import Heading from '@theme/Heading'
import clsx from 'clsx'
import styles from './styles.module.css'
interface FeatureItem {
title: string
Svg: React.ComponentType<React.ComponentProps<'svg'>>
description: ReactNode
}
const FeatureList: FeatureItem[] = [
{
title: 'Easy to Use',
Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default,
description: (
<>
Docusaurus was designed from the ground up to be easily installed and used to get your
website up and running quickly.
</>
),
},
{
title: 'Focus on What Matters',
Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default,
description: (
<>
Docusaurus lets you focus on your docs, and we&apos;ll do the chores. Go ahead and move your
docs into the
{' '}
<code>docs</code>
{' '}
directory.
</>
),
},
{
title: 'Powered by React',
Svg: require('@site/static/img/undraw_docusaurus_react.svg').default,
description: (
<>
Extend or customize your website layout by reusing React. Docusaurus can be extended while
reusing the same header and footer.
</>
),
},
]
function Feature({ title, Svg, description }: FeatureItem) {
return (
<div className={clsx('col col--4')}>
<div className="text--center">
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>
)
}
export default function HomepageFeatures(): ReactNode {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
)
}
@@ -0,0 +1,11 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}
+130
View File
@@ -0,0 +1,130 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
--ifm-color-primary-darkest: #205d3b;
--ifm-color-primary-light: #33925d;
--ifm-color-primary-lighter: #359962;
--ifm-color-primary-lightest: #3cad6e;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme="dark"] {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
--ifm-color-primary-darkest: #1a8870;
--ifm-color-primary-light: #29d5b0;
--ifm-color-primary-lighter: #32d8b4;
--ifm-color-primary-lightest: #4fddbf;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}
/* navbar */
.navbar--gitee-link,
.navbar--github-link,
.navbar--email-link {
width: 2rem;
height: 2rem;
padding: 0.25rem;
margin: 0rem 0.2rem;
border-radius: 50%;
transition: background var(--ifm-transition-fast);
}
.navbar--gitee-link:hover,
.navbar--github-link:hover,
.navbar--email-link:hover {
background: var(--ifm-color-emphasis-200);
}
.navbar--gitee-link:before {
content: "";
height: 100%;
display: block;
background: url("data:image/svg+xml,%3Csvg fill='%23000000' viewBox='0 0 24 24' role='img' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Cpath d='M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E")
no-repeat;
}
html[data-theme="dark"] .navbar--gitee-link:before {
background: url("data:image/svg+xml,%3Csvg fill='%23ffffff' viewBox='0 0 24 24' role='img' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Cpath d='M11.984 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.016 0zm6.09 5.333c.328 0 .593.266.592.593v1.482a.594.594 0 0 1-.593.592H9.777c-.982 0-1.778.796-1.778 1.778v5.63c0 .327.266.592.593.592h5.63c.982 0 1.778-.796 1.778-1.778v-.296a.593.593 0 0 0-.592-.593h-4.15a.592.592 0 0 1-.592-.592v-1.482a.593.593 0 0 1 .593-.592h6.815c.327 0 .593.265.593.592v3.408a4 4 0 0 1-4 4H5.926a.593.593 0 0 1-.593-.593V9.778a4.444 4.444 0 0 1 4.445-4.444h8.296z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E")
no-repeat;
}
.navbar--github-link:before {
content: "";
height: 100%;
display: block;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}
html[data-theme="dark"] .navbar--github-link:before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}
.navbar--email-link:before {
content: "";
height: 100%;
display: block;
background: url("data:image/svg+xml,%3Csvg height='24px' width='24px' version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 508 508' xml:space='preserve' fill='%23000000' stroke='%23000000'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Ccircle style='fill:%23324A5E;' cx='254' cy='254' r='254'%3E%3C/circle%3E%3Cpath style='fill:%23E6E9EE;' d='M423,372.4H85c-1.8,0-3.3-1.5-3.3-3.3V138.9c0-1.8,1.5-3.3,3.3-3.3h338c1.8,0,3.3,1.5,3.3,3.3v230.2 C426.3,370.9,424.8,372.4,423,372.4z'%3E%3C/path%3E%3Cpath style='fill:%23CED5E0;' d='M86.1,369c2.3,2.1,5.4,3.4,8.8,3.4h318.2c3.4,0,6.5-1.3,8.8-3.4L254,236.4L86.1,369z'%3E%3C/path%3E%3Cpath style='fill:%23FFFFFF;' d='M270.4,269.1l151.7-130c-2.4-2.2-5.5-3.6-9-3.6H94.9c-3.5,0-6.6,1.4-9,3.6l151.7,130 C247,277.2,261,277.2,270.4,269.1z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E")
no-repeat;
}
html[data-theme="dark"] .navbar--email-link:before {
background: url("data:image/svg+xml,%3Csvg height='24px' width='24px' version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 508 508' xml:space='preserve' fill='%23ffffff' stroke='%23ffffff'%3E%3Cg id='SVGRepo_bgCarrier' stroke-width='0'%3E%3C/g%3E%3Cg id='SVGRepo_tracerCarrier' stroke-linecap='round' stroke-linejoin='round'%3E%3C/g%3E%3Cg id='SVGRepo_iconCarrier'%3E%3Ccircle style='fill:%23324A5E;' cx='254' cy='254' r='254'%3E%3C/circle%3E%3Cpath style='fill:%23E6E9EE;' d='M423,372.4H85c-1.8,0-3.3-1.5-3.3-3.3V138.9c0-1.8,1.5-3.3,3.3-3.3h338c1.8,0,3.3,1.5,3.3,3.3v230.2 C426.3,370.9,424.8,372.4,423,372.4z'%3E%3C/path%3E%3Cpath style='fill:%23CED5E0;' d='M86.1,369c2.3,2.1,5.4,3.4,8.8,3.4h318.2c3.4,0,6.5-1.3,8.8-3.4L254,236.4L86.1,369z'%3E%3C/path%3E%3Cpath style='fill:%23FFFFFF;' d='M270.4,269.1l151.7-130c-2.4-2.2-5.5-3.6-9-3.6H94.9c-3.5,0-6.6,1.4-9,3.6l151.7,130 C247,277.2,261,277.2,270.4,269.1z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E")
no-repeat;
}
@media screen and (max-width: 996px) {
.navbar--github-link,
.navbar--gitee-link,
.navbar--email-link {
margin: 0rem;
padding: var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal);
line-height: 1.25;
width: 100%;
color: var(--ifm-menu-color);
font-size: 1rem;
}
.navbar--github-link::before {
content: "GitHub";
background-image: none;
}
[data-theme="dark"] .navbar--github-link::before {
content: "GitHub";
background-image: none;
}
.navbar--gitee-link::before {
content: "Gitee";
background-image: none;
}
[data-theme="dark"] .navbar--gitee-link::before {
content: "Gitee";
background-image: none;
}
.navbar--email-link::before {
content: "Email";
background-image: none;
}
[data-theme="dark"] .navbar--email-link::before {
content: "Email";
background-image: none;
}
}
@@ -0,0 +1,23 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}
+43
View File
@@ -0,0 +1,43 @@
import type { ReactNode } from 'react'
import Link from '@docusaurus/Link'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import HomepageFeatures from '@site/src/components/HomepageFeatures'
import Heading from '@theme/Heading'
import Layout from '@theme/Layout'
import clsx from 'clsx'
import styles from './index.module.css'
function HomepageHeader() {
const { siteConfig } = useDocusaurusContext()
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
{/* <Link className="button button--secondary button--lg" to="/docs/intro">
Docusaurus Tutorial - 5min ⏱️
</Link> */}
</div>
</div>
</header>
)
}
export default function Home(): ReactNode {
const { siteConfig } = useDocusaurusContext()
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
>
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>
)
}
@@ -0,0 +1,7 @@
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.
@@ -0,0 +1,35 @@
import React from 'react';
import {PageMetadata} from '@docusaurus/theme-common';
import {useBlogPost} from '@docusaurus/plugin-content-blog/client';
export default function BlogPostPageMetadata() {
const {assets, metadata} = useBlogPost();
const {title, description, date, tags, authors, frontMatter} = metadata;
const {keywords} = frontMatter;
const image = assets.image ?? frontMatter.image;
return (
<PageMetadata
title={frontMatter.title_meta ?? title}
description={description}
keywords={keywords}
image={image}>
<meta property="og:type" content="article" />
<meta property="article:published_time" content={date} />
{/* TODO double check those article meta array syntaxes, see https://ogp.me/#array */}
{authors.some((author) => author.url) && (
<meta
property="article:author"
content={authors
.map((author) => author.url)
.filter(Boolean)
.join(',')}
/>
)}
{tags.length > 0 && (
<meta
property="article:tag"
content={tags.map((tag) => tag.label).join(',')}
/>
)}
</PageMetadata>
);
}
@@ -0,0 +1,14 @@
import Head from '@docusaurus/Head'
import { useBlogPostStructuredData } from '@docusaurus/plugin-content-blog/client'
import React from 'react'
export default function BlogPostStructuredData() {
const structuredData = useBlogPostStructuredData()
return (
<Head>
<script type="application/ld+json">
{JSON.stringify(structuredData)}
</script>
</Head>
)
}
@@ -0,0 +1,91 @@
import {
BlogPostProvider,
useBlogPost,
} from '@docusaurus/plugin-content-blog/client'
import { HtmlClassNameProvider, ThemeClassNames } from '@docusaurus/theme-common'
import BlogLayout from '@theme/BlogLayout'
import BlogPostItem from '@theme/BlogPostItem'
import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata'
import BlogPostPageStructuredData from '@theme/BlogPostPage/StructuredData'
import BlogPostPaginator from '@theme/BlogPostPaginator'
import ContentVisibility from '@theme/ContentVisibility'
import TOC from '@theme/TOC'
import clsx from 'clsx'
import React, { useEffect, useRef } from 'react'
function BlogPostPageContent({ sidebar, children }) {
const { metadata, toc } = useBlogPost()
const { nextItem, prevItem, frontMatter } = metadata
const {
hide_table_of_contents: hideTableOfContents,
toc_min_heading_level: tocMinHeadingLevel,
toc_max_heading_level: tocMaxHeadingLevel,
} = frontMatter
const commentElement = useRef(null)
useEffect(() => {
// Update the document title using the browser API
let s = document.createElement('script')
s.src = 'https://giscus.app/client.js'
s.setAttribute('data-repo', 'oneao/docusaurus')
s.setAttribute('data-repo-id', 'R_kgDOQ1seUQ')
s.setAttribute('data-category', 'Announcements')
s.setAttribute('data-category-id', 'DIC_kwDOQ1seUc4C0swY')
s.setAttribute('data-mapping', 'pathname')
s.setAttribute('data-reactions-enabled', '1')
s.setAttribute('data-emit-metadata', '0')
s.setAttribute('data-input-position', 'bottom')
s.setAttribute('data-theme', document.documentElement.getAttribute('data-theme'))
s.setAttribute('data-lang', 'zh-CN')
s.setAttribute('crossorigin', 'anonymous')
s.async = true
commentElement.current.appendChild(s)
}, [])
return (
<BlogLayout
sidebar={sidebar}
toc={
!hideTableOfContents && toc.length > 0
? (
<TOC
toc={toc}
minHeadingLevel={tocMinHeadingLevel}
maxHeadingLevel={tocMaxHeadingLevel}
/>
)
: undefined
}
>
<ContentVisibility metadata={metadata} />
<BlogPostItem>{children}</BlogPostItem>
{(nextItem || prevItem) && (
<BlogPostPaginator nextItem={nextItem} prevItem={prevItem} />
)}
<div style={{ marginTop: '20px' }} ref={commentElement}></div>
</BlogLayout>
)
}
export default function BlogPostPage(props) {
const BlogPostContent = props.content
return (
<BlogPostProvider content={props.content} isBlogPostPage>
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogPostPage,
)}
>
<BlogPostPageMetadata />
<BlogPostPageStructuredData />
<BlogPostPageContent sidebar={props.sidebar}>
<BlogPostContent />
</BlogPostPageContent>
</HtmlClassNameProvider>
</BlogPostProvider>
)
}
@@ -0,0 +1,81 @@
import { useDoc } from '@docusaurus/plugin-content-docs/client'
import { useWindowSize } from '@docusaurus/theme-common'
import ContentVisibility from '@theme/ContentVisibility'
import DocBreadcrumbs from '@theme/DocBreadcrumbs'
import DocItemContent from '@theme/DocItem/Content'
import DocItemFooter from '@theme/DocItem/Footer'
import DocItemPaginator from '@theme/DocItem/Paginator'
import DocItemTOCDesktop from '@theme/DocItem/TOC/Desktop'
import DocItemTOCMobile from '@theme/DocItem/TOC/Mobile'
import DocVersionBadge from '@theme/DocVersionBadge'
import DocVersionBanner from '@theme/DocVersionBanner'
import clsx from 'clsx'
import React, { useEffect, useRef } from 'react'
import styles from './styles.module.css'
/**
* Decide if the toc should be rendered, on mobile or desktop viewports
*/
function useDocTOC() {
const { frontMatter, toc } = useDoc()
const windowSize = useWindowSize()
const hidden = frontMatter.hide_table_of_contents
const canRender = !hidden && toc.length > 0
const mobile = canRender ? <DocItemTOCMobile /> : undefined
const desktop
= canRender && (windowSize === 'desktop' || windowSize === 'ssr')
? (
<DocItemTOCDesktop />
)
: undefined
return {
hidden,
mobile,
desktop,
}
}
export default function DocItemLayout({ children }) {
const docTOC = useDocTOC()
const { metadata } = useDoc()
const commentElement = useRef(null)
useEffect(() => {
// Update the document title using the browser API
let s = document.createElement('script')
s.src = 'https://giscus.app/client.js'
s.setAttribute('data-repo', 'oneao/docusaurus')
s.setAttribute('data-repo-id', 'R_kgDOQ1seUQ')
s.setAttribute('data-category', 'Announcements')
s.setAttribute('data-category-id', 'DIC_kwDOQ1seUc4C0swY')
s.setAttribute('data-mapping', 'pathname')
s.setAttribute('data-reactions-enabled', '1')
s.setAttribute('data-emit-metadata', '0')
s.setAttribute('data-input-position', 'bottom')
s.setAttribute('data-theme', document.documentElement.getAttribute('data-theme'))
s.setAttribute('data-lang', 'zh-CN')
s.setAttribute('crossorigin', 'anonymous')
s.async = true
commentElement.current.appendChild(s)
}, [])
return (
<div className="row">
<div className={clsx('col', !docTOC.hidden && styles.docItemCol)}>
<ContentVisibility metadata={metadata} />
<DocVersionBanner />
<div className={styles.docItemContainer}>
<article>
<DocBreadcrumbs />
<DocVersionBadge />
{docTOC.mobile}
<DocItemContent>{children}</DocItemContent>
<div style={{ marginTop: '20px' }} ref={commentElement}></div>
<DocItemFooter />
</article>
<DocItemPaginator />
</div>
</div>
{docTOC.desktop && <div className="col col--3">{docTOC.desktop}</div>}
</div>
)
}
@@ -0,0 +1,10 @@
.docItemContainer header + *,
.docItemContainer article > *:first-child {
margin-top: 0;
}
@media (min-width: 997px) {
.docItemCol {
max-width: 75% !important;
}
}