mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 05:23:40 +00:00
UI: Recommend using custom button/link instead for edit on GitHub button
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-ui': patch
|
||||
---
|
||||
|
||||
Recommend using custom button/link instead for edit on GitHub button
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
title: Changelog
|
||||
description: Updates of Fumadocs
|
||||
---
|
||||
|
||||
<include cwd>../../packages/ui/CHANGELOG.md</include>
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"description": "Changelogs of Fumadocs",
|
||||
"root": true
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"pages": ["ui", "headless", "mdx", "cli", "changelogs", "openapi"]
|
||||
"pages": ["ui", "headless", "mdx", "cli", "openapi"]
|
||||
}
|
||||
|
||||
@@ -38,7 +38,26 @@ It applies the [Typography](/docs/ui/theme#typography) styles, wrap your content
|
||||
import { DocsBody } from 'fumadocs-ui/page';
|
||||
|
||||
<DocsBody>
|
||||
<h1>This heading looks good!</h1>
|
||||
<h2>This heading looks good!</h2>
|
||||
</DocsBody>;
|
||||
```
|
||||
|
||||
### Edit on GitHub
|
||||
|
||||
You can also add your own component.
|
||||
|
||||
```tsx
|
||||
import { DocsBody } from 'fumadocs-ui/page';
|
||||
|
||||
<DocsBody>
|
||||
<a
|
||||
href={`https://github.com/fuma-nama/fumadocs/blob/main/${page.file.path}`}
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
className="w-fit border rounded-xl p-2 font-medium text-sm text-fd-secondary-foreground bg-fd-secondary transition-colors hover:text-fd-accent-foreground hover:bg-fd-accent"
|
||||
>
|
||||
Edit on GitHub
|
||||
</a>
|
||||
</DocsBody>;
|
||||
```
|
||||
|
||||
@@ -68,12 +87,14 @@ import { DocsPage } from 'fumadocs-ui/page';
|
||||
<DocsPage toc={headings}>...</DocsPage>;
|
||||
```
|
||||
|
||||
Customise or disable TOC from your documentation with the `tableOfContent` option.
|
||||
You can customise or disable it with the `tableOfContent` option, or with `tableOfContentPopover` on smaller devices.
|
||||
|
||||
```tsx
|
||||
import { DocsPage } from 'fumadocs-ui/page';
|
||||
|
||||
<DocsPage tableOfContent={options}>...</DocsPage>;
|
||||
<DocsPage tableOfContent={options} tableOfContentPopover={options}>
|
||||
...
|
||||
</DocsPage>;
|
||||
```
|
||||
|
||||
<AutoTypeTable path="./content/docs/ui/props.ts" name="TOCProps" />
|
||||
@@ -94,19 +115,6 @@ import { DocsPage } from 'fumadocs-ui/page';
|
||||
</DocsPage>;
|
||||
```
|
||||
|
||||
#### Popover Mode
|
||||
|
||||
On smaller devices, it is shown on a popover instead.
|
||||
Customise it with the `tableOfContentPopover` option.
|
||||
|
||||
```tsx
|
||||
import { DocsPage } from 'fumadocs-ui/page';
|
||||
|
||||
<DocsPage tableOfContentPopover={options}>...</DocsPage>;
|
||||
```
|
||||
|
||||
<AutoTypeTable path="./content/docs/ui/props.ts" name="TOCPopoverProps" />
|
||||
|
||||
### Last Updated Time
|
||||
|
||||
Display last updated time of the page.
|
||||
@@ -137,30 +145,7 @@ const time = await getGithubLastEdit({
|
||||
<DocsPage lastUpdate={new Date(time)} />;
|
||||
```
|
||||
|
||||
<Callout type='info' title='Note'>
|
||||
|
||||
You can also specify the last updated time of documents (e.g. using frontmatter).
|
||||
Don't forget to [update the schema type](/docs/mdx/collections#schema) on Fumadocs MDX first.
|
||||
|
||||
</Callout>
|
||||
|
||||
### Edit on GitHub
|
||||
|
||||
Add "Edit on GitHub" button to the page.
|
||||
|
||||
```tsx
|
||||
import { DocsPage } from 'fumadocs-ui/page';
|
||||
|
||||
<DocsPage
|
||||
editOnGithub={{
|
||||
owner: 'fuma-nama',
|
||||
repo: 'fumadocs',
|
||||
sha: 'main',
|
||||
// file path, make sure it's valid
|
||||
path: `content/docs/${page.file.path}`,
|
||||
}}
|
||||
/>;
|
||||
```
|
||||
Or you may specify the updated time in [frontmatter](/docs/mdx/collections#schema).
|
||||
|
||||
### Footer
|
||||
|
||||
|
||||
+1
-3
@@ -14,8 +14,6 @@ const client = algo(appId, apiKey);
|
||||
|
||||
const index = client.initIndex(indexName);
|
||||
|
||||
export default function CustomSearchDialog(
|
||||
props: SharedProps,
|
||||
): React.ReactElement {
|
||||
export default function CustomSearchDialog(props: SharedProps) {
|
||||
return <SearchDialog index={index} {...props} showAlgolia />;
|
||||
}
|
||||
@@ -177,19 +177,7 @@ For the setup guide, see [Integrate Algolia Search](/docs/headless/search/algoli
|
||||
While generally we recommend building your own search with their client-side
|
||||
SDK, you can also plug the built-in dialog interface.
|
||||
|
||||
```tsx title="components/search.tsx"
|
||||
'use client';
|
||||
import algo from 'algoliasearch/lite';
|
||||
import type { SharedProps } from 'fumadocs-ui/components/dialog/search';
|
||||
import SearchDialog from 'fumadocs-ui/components/dialog/search-algolia';
|
||||
|
||||
const client = algo('appId', 'apiKey');
|
||||
const index = client.initIndex('indexName');
|
||||
|
||||
export default function CustomSearchDialog(props: SharedProps) {
|
||||
return <SearchDialog index={index} {...props} />;
|
||||
}
|
||||
```
|
||||
<include meta='title="components/search.tsx"'>./search-algolia.tsx</include>
|
||||
|
||||
1. Replace `appId`, `apiKey` and `indexName` with your desired values.
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import * as fs from 'node:fs/promises';
|
||||
import fg from 'fast-glob';
|
||||
import matter from 'gray-matter';
|
||||
import { remark } from 'remark';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkStringify from 'remark-stringify';
|
||||
import remarkMdx from 'remark-mdx';
|
||||
import { remarkInclude } from 'fumadocs-mdx/config';
|
||||
|
||||
export const revalidate = false;
|
||||
|
||||
const processor = remark()
|
||||
.use(remarkMdx)
|
||||
// https://fumadocs.dev/docs/mdx/include
|
||||
.use(remarkInclude)
|
||||
// gfm styles
|
||||
.use(remarkGfm)
|
||||
// .use(your remark plugins)
|
||||
.use(remarkStringify); // to string
|
||||
|
||||
export async function GET() {
|
||||
// all scanned content
|
||||
const files = await fg(['./content/docs/**/*.mdx']);
|
||||
|
||||
const scan = files.map(async (file) => {
|
||||
const fileContent = await fs.readFile(file);
|
||||
const { content, data } = matter(fileContent.toString());
|
||||
|
||||
const processed = await processor.process({
|
||||
path: file,
|
||||
value: content,
|
||||
});
|
||||
|
||||
return `file: ${file}
|
||||
meta: ${JSON.stringify(data, null, 2)}
|
||||
|
||||
${processed}`;
|
||||
});
|
||||
|
||||
const scanned = await Promise.all(scan);
|
||||
|
||||
return new Response(scanned.join('\n\n'));
|
||||
}
|
||||
@@ -48,7 +48,6 @@
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-mdx": "^3.1.0",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"remark-stringify": "^11.0.0",
|
||||
"scroll-into-view-if-needed": "^3.1.0",
|
||||
"shiki": "^3.3.0",
|
||||
"tailwind-merge": "^3.2.0",
|
||||
@@ -66,6 +65,7 @@
|
||||
"@types/node": "22.15.3",
|
||||
"@types/react": "^19.1.2",
|
||||
"@types/react-dom": "^19.1.3",
|
||||
"algoliasearch": "4.24.0",
|
||||
"eslint-config-custom": "workspace:*",
|
||||
"fast-glob": "^3.3.3",
|
||||
"gray-matter": "^4.0.3",
|
||||
|
||||
@@ -13,7 +13,7 @@ export const buttonVariants = cva(
|
||||
'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent hover:text-fd-accent-foreground',
|
||||
},
|
||||
size: {
|
||||
sm: 'gap-1 p-1 text-xs',
|
||||
sm: 'gap-1 px-2 py-1.5 text-xs',
|
||||
icon: 'p-1.5 [&_svg]:size-5',
|
||||
'icon-sm': 'p-1.5 [&_svg]:size-4.5',
|
||||
},
|
||||
|
||||
+24
-24
@@ -1,24 +1,25 @@
|
||||
import type { TableOfContents } from 'fumadocs-core/server';
|
||||
import {
|
||||
type AnchorHTMLAttributes,
|
||||
type ComponentProps,
|
||||
forwardRef,
|
||||
type HTMLAttributes,
|
||||
type ReactNode,
|
||||
} from 'react';
|
||||
import { type AnchorProviderProps, AnchorProvider } from 'fumadocs-core/toc';
|
||||
import { AnchorProvider, type AnchorProviderProps } from 'fumadocs-core/toc';
|
||||
import { slot } from '@/layouts/shared';
|
||||
import { cn } from './utils/cn';
|
||||
import {
|
||||
Breadcrumb,
|
||||
type BreadcrumbProps,
|
||||
Footer,
|
||||
type FooterProps,
|
||||
LastUpdate,
|
||||
TocPopover,
|
||||
Breadcrumb,
|
||||
type BreadcrumbProps,
|
||||
PageBody,
|
||||
PageArticle,
|
||||
TocPopoverTrigger,
|
||||
PageBody,
|
||||
TocPopover,
|
||||
TocPopoverContent,
|
||||
TocPopoverTrigger,
|
||||
} from './page-client';
|
||||
import {
|
||||
Toc,
|
||||
@@ -114,6 +115,7 @@ export interface DocsPageProps {
|
||||
export function DocsPage({
|
||||
toc = [],
|
||||
full = false,
|
||||
editOnGithub,
|
||||
tableOfContentPopover: {
|
||||
enabled: tocPopoverEnabled,
|
||||
component: tocPopoverReplace,
|
||||
@@ -183,12 +185,14 @@ export function DocsPage({
|
||||
{props.children}
|
||||
<div role="none" className="flex-1" />
|
||||
<div className="flex flex-row flex-wrap items-center justify-between gap-4 empty:hidden">
|
||||
{props.editOnGithub ? (
|
||||
<EditOnGitHub {...props.editOnGithub} />
|
||||
) : null}
|
||||
{props.lastUpdate ? (
|
||||
{editOnGithub && (
|
||||
<EditOnGitHub
|
||||
href={`https://github.com/${editOnGithub.owner}/${editOnGithub.repo}/blob/${editOnGithub.sha}/${editOnGithub.path.startsWith('/') ? editOnGithub.path.slice(1) : editOnGithub.path}`}
|
||||
/>
|
||||
)}
|
||||
{props.lastUpdate && (
|
||||
<LastUpdate date={new Date(props.lastUpdate)} />
|
||||
) : null}
|
||||
)}
|
||||
</div>
|
||||
{slot(props.footer, <Footer items={props.footer?.items} />)}
|
||||
</PageArticle>
|
||||
@@ -219,31 +223,27 @@ export function DocsPage({
|
||||
);
|
||||
}
|
||||
|
||||
function EditOnGitHub({
|
||||
owner,
|
||||
repo,
|
||||
sha,
|
||||
path,
|
||||
...props
|
||||
}: EditOnGitHubOptions) {
|
||||
const href = `https://github.com/${owner}/${repo}/blob/${sha}/${path.startsWith('/') ? path.slice(1) : path}`;
|
||||
|
||||
export function EditOnGitHub(props: ComponentProps<'a'>) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
{...props}
|
||||
className={cn(
|
||||
buttonVariants({
|
||||
color: 'secondary',
|
||||
className: 'gap-1.5 text-fd-muted-foreground',
|
||||
size: 'sm',
|
||||
className: 'gap-1.5 not-prose',
|
||||
}),
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<Edit className="size-3.5" />
|
||||
<I18nLabel label="editOnGithub" />
|
||||
{props.children ?? (
|
||||
<>
|
||||
<Edit className="size-3.5" />
|
||||
<I18nLabel label="editOnGithub" />
|
||||
</>
|
||||
)}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
Generated
+6
-6
Reference in New Issue
Block a user