mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
UI: Introduce more pre-built components on page
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-ui': minor
|
||||
---
|
||||
|
||||
Introduce `DocsTitle`, `DocsDescription` and `DocsCategory` components
|
||||
@@ -1,7 +1,12 @@
|
||||
import { Edit } from 'lucide-react';
|
||||
import type { Metadata } from 'next';
|
||||
import { Card, Cards } from 'fumadocs-ui/components/card';
|
||||
import { DocsPage, DocsBody } from 'fumadocs-ui/page';
|
||||
import {
|
||||
DocsPage,
|
||||
DocsBody,
|
||||
DocsTitle,
|
||||
DocsDescription,
|
||||
DocsCategory,
|
||||
} from 'fumadocs-ui/page';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { type ReactNode } from 'react';
|
||||
import { utils, type Page } from '@/utils/source';
|
||||
@@ -54,13 +59,9 @@ export default function Page({
|
||||
}}
|
||||
tableOfContentPopover={{ footer }}
|
||||
>
|
||||
<h1 className="text-3xl font-bold text-fd-foreground sm:text-4xl">
|
||||
{page.data.title}
|
||||
</h1>
|
||||
<DocsTitle>{page.data.title}</DocsTitle>
|
||||
{page.data.description ? (
|
||||
<p className="mb-8 text-lg text-fd-muted-foreground">
|
||||
{page.data.description}
|
||||
</p>
|
||||
<DocsDescription>{page.data.description}</DocsDescription>
|
||||
) : null}
|
||||
<DocsBody>
|
||||
{preview && preview in Preview ? Preview[preview] : null}
|
||||
@@ -76,34 +77,14 @@ export default function Page({
|
||||
: () => undefined,
|
||||
}}
|
||||
/>
|
||||
{page.data.index ? <Category page={page} /> : null}
|
||||
{page.data.index ? (
|
||||
<DocsCategory page={page} pages={utils.getPages()} />
|
||||
) : null}
|
||||
</DocsBody>
|
||||
</DocsPage>
|
||||
);
|
||||
}
|
||||
|
||||
function Category({ page }: { page: Page }): React.ReactElement {
|
||||
const filtered = utils
|
||||
.getPages()
|
||||
.filter(
|
||||
(item) =>
|
||||
item.file.dirname === page.file.dirname && item.file.name !== 'index',
|
||||
);
|
||||
|
||||
return (
|
||||
<Cards>
|
||||
{filtered.map((item) => (
|
||||
<Card
|
||||
key={item.url}
|
||||
title={item.data.title}
|
||||
description={item.data.description ?? 'No Description'}
|
||||
href={item.url}
|
||||
/>
|
||||
))}
|
||||
</Cards>
|
||||
);
|
||||
}
|
||||
|
||||
export function generateMetadata({ params }: { params: Param }): Metadata {
|
||||
const page = utils.getPage(params.slug);
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { BreadcrumbOptions, useBreadcrumb } from 'fumadocs-core/breadcrumb';
|
||||
import {
|
||||
type BreadcrumbOptions,
|
||||
useBreadcrumb,
|
||||
} from 'fumadocs-core/breadcrumb';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { Fragment } from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useTreeContext } from '@/contexts/tree';
|
||||
|
||||
export interface BreadcrumbProps
|
||||
@@ -19,7 +21,7 @@ export interface BreadcrumbProps
|
||||
export function Breadcrumb({
|
||||
full = false,
|
||||
...options
|
||||
}: BreadcrumbProps): React.ReactElement {
|
||||
}: BreadcrumbProps): React.ReactNode {
|
||||
const { root } = useTreeContext();
|
||||
const pathname = usePathname();
|
||||
const items = useBreadcrumb(pathname, root, {
|
||||
@@ -27,13 +29,10 @@ export function Breadcrumb({
|
||||
...options,
|
||||
});
|
||||
|
||||
if (items.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'-mb-3 flex flex-row items-center gap-1 text-sm font-medium text-fd-muted-foreground',
|
||||
items.length === 0 && 'hidden',
|
||||
)}
|
||||
>
|
||||
<div className="-mb-3 flex flex-row items-center gap-1 text-sm font-medium text-fd-muted-foreground">
|
||||
{items.map((item, i) => (
|
||||
<Fragment key={i}>
|
||||
{i !== 0 && (
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { type TableOfContents } from 'fumadocs-core/server';
|
||||
import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';
|
||||
import type { Page } from 'fumadocs-core/source';
|
||||
import { Card, Cards } from '@/components/card';
|
||||
import { replaceOrDefault } from './utils/shared';
|
||||
import { cn } from './utils/cn';
|
||||
import type { BreadcrumbProps, FooterProps, TOCProps } from './page.client';
|
||||
@@ -130,6 +132,73 @@ export const DocsBody = forwardRef<
|
||||
|
||||
DocsBody.displayName = 'DocsBody';
|
||||
|
||||
export const DocsDescription = forwardRef<
|
||||
HTMLParagraphElement,
|
||||
HTMLAttributes<HTMLParagraphElement>
|
||||
>((props, ref) => {
|
||||
return (
|
||||
<p
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={cn('mb-8 text-lg text-fd-muted-foreground', props.className)}
|
||||
>
|
||||
{props.children}
|
||||
</p>
|
||||
);
|
||||
});
|
||||
|
||||
DocsDescription.displayName = 'DocsDescription';
|
||||
|
||||
export const DocsTitle = forwardRef<
|
||||
HTMLHeadingElement,
|
||||
HTMLAttributes<HTMLHeadingElement>
|
||||
>((props, ref) => {
|
||||
return (
|
||||
<h1
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={cn('text-3xl font-bold sm:text-4xl', props.className)}
|
||||
>
|
||||
{props.children}
|
||||
</h1>
|
||||
);
|
||||
});
|
||||
|
||||
DocsTitle.displayName = 'DocsTitle';
|
||||
|
||||
export function DocsCategory({
|
||||
page,
|
||||
pages,
|
||||
...props
|
||||
}: HTMLAttributes<HTMLDivElement> & {
|
||||
page: Page;
|
||||
pages: Page[];
|
||||
}): React.ReactElement {
|
||||
const filtered = pages.filter(
|
||||
(item) =>
|
||||
item.file.dirname === page.file.dirname &&
|
||||
item.file.name !== page.file.name,
|
||||
);
|
||||
|
||||
return (
|
||||
<Cards {...props}>
|
||||
{filtered.map((item) => (
|
||||
<Card
|
||||
key={item.url}
|
||||
title={item.data.title}
|
||||
description={
|
||||
(item.data as { description?: string }).description ??
|
||||
'No Description'
|
||||
}
|
||||
href={item.url}
|
||||
/>
|
||||
))}
|
||||
</Cards>
|
||||
);
|
||||
}
|
||||
|
||||
DocsBody.displayName = 'DocsBody';
|
||||
|
||||
/**
|
||||
* For separate MDX page
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user