Docs: Create components documentation

This commit is contained in:
SonMooSans
2023-07-05 20:21:37 +08:00
parent e41ef15809
commit 7a7d0fa839
4 changed files with 246 additions and 0 deletions
@@ -0,0 +1,75 @@
---
title: Breadcrumb
description: The navigation component at the top of screen
---
The navigation component at the top of screen.
```
next-docs/breadcrumb
```
## Usage
it exports a `useBreadcrumb` hook:
```tsx
import { useBreadcrumb } from "next-docs/breadcrumb";
const tree: TreeNode[] = buildPageTree(allMeta, allDocs);
const pathname = usePathname();
const items = useBreadcrumb(pathname, tree);
```
### Breadcrumb Item
| Prop | Type | Description |
| ------ | ---------------- | ------------ |
| `name` | `string` | Name of item |
| `url` | `string \| null` | Href link |
## Example
Using `lucide-react` for icons.
```tsx
import { usePathname } from "next/navigation";
import type { TreeNode } from "next-docs/server";
import { useBreadcrumb } from "next-docs/breadcrumb";
import clsx from "clsx";
import { ChevronRightIcon } from "lucide-react";
import Link from "next/link";
import { Fragment } from "react";
const itemStyles = "overflow-hidden overflow-ellipsis whitespace-nowrap";
export function Breadcrumb({ tree }: { tree: TreeNode[] }) {
const pathname = usePathname();
//get breadcrumb items
const items = useBreadcrumb(pathname, tree);
return (
<div className="flex flex-row gap-1 text-sm text-muted-foreground items-center">
<p className={itemStyles}>Docs</p>
{items.map((item, i) => {
const active = items.length === i + 1;
const style = clsx(itemStyles, active && "text-foreground");
return (
<Fragment key={i}>
<ChevronRightIcon className="w-4 h-4 flex-shrink-0" />
{item.url != null ? (
<Link href={item.url} className={style}>
{item.name}
</Link>
) : (
<p className={style}>{item.name}</p>
)}
</Fragment>
);
})}
</div>
);
}
```
@@ -0,0 +1,4 @@
{
"title": "Components",
"pages": ["breadcrumb", "sidebar", "toc"]
}
@@ -0,0 +1,91 @@
---
title: Sidebar
description: The navigation bar at aside of viewport
---
Handles device resizing and remove scroll bar automatically.
```
next-docs/sidebar
```
## Usage
```tsx
import * as Base from "next-docs/sidebar";
return (
<Base.SidebarProvider>
<Base.SidebarTrigger />
<Base.SidebarList />
</Base.SidebarProvider>
);
```
### Sidebar Provider
| Prop | Type | Description |
| -------------- | ---------------------- | ----------- |
| `open` | `boolean?` | - |
| `onOpenChange` | `(v: boolean) => void` | - |
### Sidebar Trigger
Opens the sidebar on click.
| Prop | Type | Description |
| ---- | ------------- | ----------- |
| `as` | `ElementType` | - |
### Sidebar List
| Data Attribute | Values | Description |
| -------------- | ------------- | ------------------ |
| `data-open` | `true, false` | Is sidebar opening |
## Example
Using `@radix-ui/react-collapsible` and `lucide-react`:
```tsx
"use client";
import clsx from "clsx";
import { ChevronDownIcon, MenuIcon } from "lucide-react";
import { ReactNode, useEffect, useState } from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import type { TreeNode, FileNode, FolderNode } from "next-docs/server";
import * as Base from "next-docs/sidebar";
import * as Collapsible from "@radix-ui/react-collapsible";
export function SidebarProvider({ children }: { children: ReactNode }) {
return (
<Base.SidebarProvider>
<Base.SidebarTrigger className="flex flex-row gap-2 text-sm px-8 items-center">
<MenuIcon className="w-4 h-4" />
Menu
</Base.SidebarTrigger>
{children}
</Base.SidebarProvider>
);
}
export function Sidebar({ items }: { items: TreeNode[] }) {
return (
<Base.SidebarList
minWidth={1024} // when should it being displayed (ignore the trigger)
className={clsx(
"flex flex-col gap-3 fixed inset-0 top-24 overflow-auto",
"lg:sticky lg:top-12 lg:py-16 lg:max-h-[calc(100vh-3rem)]",
"max-lg:py-4 max-lg:px-8 max-lg:sm:px-14 max-lg:bg-background/50 max-lg:backdrop-blur-xl max-lg:z-40 max-lg:data-[open=false]:hidden"
)}
>
{items.map((item, i) => (
<SidebarItem key={i} item={item} />
))}
</Base.SidebarList>
);
}
```
_It doesn't include the implementation of `SidebarItem`_
+76
View File
@@ -0,0 +1,76 @@
---
title: TOC
description: Table of Content
---
A Table of Contents with active anchor observer.
```
next-docs/toc
```
## Usage
```tsx
import * as Base from "next-docs/toc";
return (
<Base.TOCProvider>
<Base.TOCItem />
</Base.TOCProvider>
);
```
### TOC Provider
| Prop | Type | Description |
| ---------- | ----------------- | ----------------- |
| `toc` | `TableOfContents` | Table of contents |
| `children` | `ReactNode` | - |
### TOC Item
| Prop | Type | Description |
| ------ | ------------- | ----------- |
| `item` | `TOCItemType` | The item |
| Data Attribute | Values | Description |
| -------------- | ------------- | ---------------- |
| `data-active` | `true, false` | Is active anchor |
## Example
```tsx
"use client";
import * as Primitive from "next-docs/toc";
import type { TOCItemType } from "next-docs/server";
export function TOC({ items }: { items: TOCItemType[] }) {
return (
<Primitive.TOCProvider toc={items}>
{items.map((item, i) => (
<TOCItem key={i} item={item} />
))}
</Primitive.TOCProvider>
);
}
function TOCItem({ item }: { item: TOCItemType }) {
return (
<div>
<Primitive.TOCItem
href={item.url}
item={item}
className="text-sm text-muted-foreground transition-colors data-[active=true]:font-semibold data-[active=true]:text-foreground"
>
{item.title}
</Primitive.TOCItem>
<div className="flex flex-col pl-4">
{item.items?.map((item, i) => (
<TOCItem key={i} item={item} />
))}
</div>
</div>
);
}
```