From 8a8f26967890f07eb79e1776b93477bc479c93e2 Mon Sep 17 00:00:00 2001 From: twlite <46562212+twlite@users.noreply.github.com> Date: Sat, 14 Dec 2024 01:10:22 +0545 Subject: [PATCH] feat: rewrite docs site --- apps/docs/.eslintrc.json | 3 + apps/docs/.gitignore | 31 +- apps/docs/README.md | 26 + apps/docs/app/(home)/layout.tsx | 11 + apps/docs/app/(home)/page.tsx | 115 ++++ apps/docs/app/api/search/route.ts | 4 + apps/docs/app/docs/[[...slug]]/page.tsx | 62 +++ apps/docs/app/docs/layout.tsx | 12 + .../{styles/globals.css => app/global.css} | 0 apps/docs/app/guide/[[...slug]]/page.tsx | 62 +++ apps/docs/app/guide/layout.tsx | 12 + apps/docs/app/layout.config.tsx | 45 ++ apps/docs/app/layout.tsx | 18 + apps/docs/cli.json | 8 + apps/docs/components/accordion.tsx | 114 ++++ apps/docs/components/banner.tsx | 137 +++++ apps/docs/components/callout.tsx | 51 ++ apps/docs/components/card.tsx | 61 +++ apps/docs/components/codeblock.tsx | 182 +++++++ apps/docs/components/docs.client.tsx | 124 +++++ apps/docs/components/docs.tsx | 249 +++++++++ apps/docs/components/docs/navbar.tsx | 47 ++ apps/docs/components/docs/shared.tsx | 106 ++++ apps/docs/components/docs/sidebar.tsx | 473 +++++++++++++++++ apps/docs/components/files.tsx | 81 +++ apps/docs/components/heading.tsx | 33 ++ apps/docs/components/home.tsx | 222 ++++++++ apps/docs/components/home/menu.tsx | 77 +++ apps/docs/components/home/navbar.tsx | 130 +++++ apps/docs/components/image-zoom.css | 77 +++ apps/docs/components/image-zoom.tsx | 51 ++ apps/docs/components/inline-toc.tsx | 47 ++ .../components/layout/language-toggle.tsx | 68 +++ apps/docs/components/layout/nav.tsx | 90 ++++ apps/docs/components/layout/root-toggle.tsx | 107 ++++ apps/docs/components/layout/search-toggle.tsx | 63 +++ apps/docs/components/layout/theme-toggle.tsx | 47 ++ apps/docs/components/layout/toc-clerk.tsx | 174 +++++++ apps/docs/components/layout/toc-thumb.tsx | 80 +++ apps/docs/components/layout/toc.tsx | 168 ++++++ apps/docs/components/links.tsx | 127 +++++ apps/docs/components/page.tsx | 389 ++++++++++++++ apps/docs/components/shared.tsx | 93 ++++ apps/docs/components/steps.tsx | 17 + apps/docs/components/tabs.tsx | 246 +++++++++ apps/docs/components/type-table.tsx | 97 ++++ apps/docs/components/ui/button.tsx | 19 + apps/docs/components/ui/collapsible.tsx | 30 ++ apps/docs/components/ui/navigation-menu.tsx | 66 +++ apps/docs/components/ui/popover.tsx | 32 ++ apps/docs/components/ui/scroll-area.tsx | 57 ++ apps/docs/components/ui/tabs.tsx | 66 +++ .../docs/classes/CommandKit.mdx | 5 + .../docs/classes/components/ButtonKit.mdx | 5 +- apps/docs/content/docs/enums/ReloadType.mdx | 14 + .../docs/typedef/AutocompleteProps.mdx | 5 + .../docs/typedef/CommandData.mdx | 5 + ...tonBuilderInteractionCollectorDispatch.mdx | 5 + ...nteractionCollectorDispatchContextData.mdx | 5 + .../typedef/CommandKitButtonBuilderOnEnd.mdx | 8 + .../docs/typedef/CommandObject.mdx | 5 + .../docs/typedef/CommandOptions.mdx | 5 + .../docs/typedef/ContextMenuCommandProps.mdx | 5 + .../docs/typedef/SlashCommandProps.mdx | 5 + .../docs/typedef/ValidationProps.mdx | 5 + .../{pages => content}/guide/buttonkit.mdx | 29 +- .../guide/command-file-setup.mdx | 65 +-- .../guide/commandkit-config.mdx | 22 +- .../guide/commandkit-setup.mdx | 27 +- .../guide/create-commandkit.mdx | 13 +- .../guide/event-file-setup.mdx | 86 +-- .../{pages => content}/guide/installation.mdx | 13 +- .../guide/migrating-from-djs-commander.mdx | 7 +- .../{pages => content}/guide/using-cli.mdx | 7 +- .../guide/validation-file-setup.mdx | 27 +- apps/docs/lib/api-source.ts | 8 + apps/docs/lib/cn.ts | 1 + apps/docs/lib/get-sidebar-tabs.tsx | 53 ++ apps/docs/lib/is-active.ts | 7 + apps/docs/lib/source.ts | 8 + apps/docs/lib/use-copy-button.ts | 35 ++ apps/docs/next.config.js | 6 - apps/docs/next.config.mjs | 10 + apps/docs/package.json | 63 ++- apps/docs/page.client.tsx | 191 +++++++ apps/docs/pages/404.mdx | 3 - apps/docs/pages/_app.mdx | 13 - apps/docs/pages/_meta.json | 14 - apps/docs/pages/docs/_meta.json | 5 - apps/docs/pages/docs/classes/_meta.json | 4 - .../pages/docs/classes/components/_meta.json | 3 - apps/docs/pages/docs/enums/ReloadType.mdx | 9 - apps/docs/pages/docs/enums/_meta.json | 3 - .../typedef/CommandKitButtonBuilderOnEnd.mdx | 3 - apps/docs/pages/docs/typedef/_meta.json | 12 - apps/docs/pages/guide/_meta.json | 13 - apps/docs/pages/guide/using-signals.mdx | 490 ------------------ apps/docs/pages/index.mdx | 62 --- apps/docs/source.config.ts | 17 + apps/docs/tailwind.config.js | 13 + apps/docs/tailwind.config.ts | 15 - apps/docs/theme.config.tsx | 86 --- apps/docs/tsconfig.json | 13 +- 103 files changed, 5332 insertions(+), 908 deletions(-) create mode 100644 apps/docs/.eslintrc.json create mode 100644 apps/docs/README.md create mode 100644 apps/docs/app/(home)/layout.tsx create mode 100644 apps/docs/app/(home)/page.tsx create mode 100644 apps/docs/app/api/search/route.ts create mode 100644 apps/docs/app/docs/[[...slug]]/page.tsx create mode 100644 apps/docs/app/docs/layout.tsx rename apps/docs/{styles/globals.css => app/global.css} (100%) create mode 100644 apps/docs/app/guide/[[...slug]]/page.tsx create mode 100644 apps/docs/app/guide/layout.tsx create mode 100644 apps/docs/app/layout.config.tsx create mode 100644 apps/docs/app/layout.tsx create mode 100644 apps/docs/cli.json create mode 100644 apps/docs/components/accordion.tsx create mode 100644 apps/docs/components/banner.tsx create mode 100644 apps/docs/components/callout.tsx create mode 100644 apps/docs/components/card.tsx create mode 100644 apps/docs/components/codeblock.tsx create mode 100644 apps/docs/components/docs.client.tsx create mode 100644 apps/docs/components/docs.tsx create mode 100644 apps/docs/components/docs/navbar.tsx create mode 100644 apps/docs/components/docs/shared.tsx create mode 100644 apps/docs/components/docs/sidebar.tsx create mode 100644 apps/docs/components/files.tsx create mode 100644 apps/docs/components/heading.tsx create mode 100644 apps/docs/components/home.tsx create mode 100644 apps/docs/components/home/menu.tsx create mode 100644 apps/docs/components/home/navbar.tsx create mode 100644 apps/docs/components/image-zoom.css create mode 100644 apps/docs/components/image-zoom.tsx create mode 100644 apps/docs/components/inline-toc.tsx create mode 100644 apps/docs/components/layout/language-toggle.tsx create mode 100644 apps/docs/components/layout/nav.tsx create mode 100644 apps/docs/components/layout/root-toggle.tsx create mode 100644 apps/docs/components/layout/search-toggle.tsx create mode 100644 apps/docs/components/layout/theme-toggle.tsx create mode 100644 apps/docs/components/layout/toc-clerk.tsx create mode 100644 apps/docs/components/layout/toc-thumb.tsx create mode 100644 apps/docs/components/layout/toc.tsx create mode 100644 apps/docs/components/links.tsx create mode 100644 apps/docs/components/page.tsx create mode 100644 apps/docs/components/shared.tsx create mode 100644 apps/docs/components/steps.tsx create mode 100644 apps/docs/components/tabs.tsx create mode 100644 apps/docs/components/type-table.tsx create mode 100644 apps/docs/components/ui/button.tsx create mode 100644 apps/docs/components/ui/collapsible.tsx create mode 100644 apps/docs/components/ui/navigation-menu.tsx create mode 100644 apps/docs/components/ui/popover.tsx create mode 100644 apps/docs/components/ui/scroll-area.tsx create mode 100644 apps/docs/components/ui/tabs.tsx rename apps/docs/{pages => content}/docs/classes/CommandKit.mdx (92%) rename apps/docs/{pages => content}/docs/classes/components/ButtonKit.mdx (93%) create mode 100644 apps/docs/content/docs/enums/ReloadType.mdx rename apps/docs/{pages => content}/docs/typedef/AutocompleteProps.mdx (75%) rename apps/docs/{pages => content}/docs/typedef/CommandData.mdx (65%) rename apps/docs/{pages => content}/docs/typedef/CommandKitButtonBuilderInteractionCollectorDispatch.mdx (60%) rename apps/docs/{pages => content}/docs/typedef/CommandKitButtonBuilderInteractionCollectorDispatchContextData.mdx (77%) create mode 100644 apps/docs/content/docs/typedef/CommandKitButtonBuilderOnEnd.mdx rename apps/docs/{pages => content}/docs/typedef/CommandObject.mdx (75%) rename apps/docs/{pages => content}/docs/typedef/CommandOptions.mdx (93%) rename apps/docs/{pages => content}/docs/typedef/ContextMenuCommandProps.mdx (76%) rename apps/docs/{pages => content}/docs/typedef/SlashCommandProps.mdx (78%) rename apps/docs/{pages => content}/docs/typedef/ValidationProps.mdx (86%) rename apps/docs/{pages => content}/guide/buttonkit.mdx (93%) rename apps/docs/{pages => content}/guide/command-file-setup.mdx (90%) rename apps/docs/{pages => content}/guide/commandkit-config.mdx (85%) rename apps/docs/{pages => content}/guide/commandkit-setup.mdx (93%) rename apps/docs/{pages => content}/guide/create-commandkit.mdx (85%) rename apps/docs/{pages => content}/guide/event-file-setup.mdx (75%) rename apps/docs/{pages => content}/guide/installation.mdx (84%) rename apps/docs/{pages => content}/guide/migrating-from-djs-commander.mdx (95%) rename apps/docs/{pages => content}/guide/using-cli.mdx (93%) rename apps/docs/{pages => content}/guide/validation-file-setup.mdx (87%) create mode 100644 apps/docs/lib/api-source.ts create mode 100644 apps/docs/lib/cn.ts create mode 100644 apps/docs/lib/get-sidebar-tabs.tsx create mode 100644 apps/docs/lib/is-active.ts create mode 100644 apps/docs/lib/source.ts create mode 100644 apps/docs/lib/use-copy-button.ts delete mode 100644 apps/docs/next.config.js create mode 100644 apps/docs/next.config.mjs create mode 100644 apps/docs/page.client.tsx delete mode 100644 apps/docs/pages/404.mdx delete mode 100644 apps/docs/pages/_app.mdx delete mode 100644 apps/docs/pages/_meta.json delete mode 100644 apps/docs/pages/docs/_meta.json delete mode 100644 apps/docs/pages/docs/classes/_meta.json delete mode 100644 apps/docs/pages/docs/classes/components/_meta.json delete mode 100644 apps/docs/pages/docs/enums/ReloadType.mdx delete mode 100644 apps/docs/pages/docs/enums/_meta.json delete mode 100644 apps/docs/pages/docs/typedef/CommandKitButtonBuilderOnEnd.mdx delete mode 100644 apps/docs/pages/docs/typedef/_meta.json delete mode 100644 apps/docs/pages/guide/_meta.json delete mode 100644 apps/docs/pages/guide/using-signals.mdx delete mode 100644 apps/docs/pages/index.mdx create mode 100644 apps/docs/source.config.ts create mode 100644 apps/docs/tailwind.config.js delete mode 100644 apps/docs/tailwind.config.ts delete mode 100644 apps/docs/theme.config.tsx diff --git a/apps/docs/.eslintrc.json b/apps/docs/.eslintrc.json new file mode 100644 index 0000000..3722418 --- /dev/null +++ b/apps/docs/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals", "next/typescript"] +} diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore index 8f322f0..55a12ae 100644 --- a/apps/docs/.gitignore +++ b/apps/docs/.gitignore @@ -1,35 +1,28 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies +# deps /node_modules -/.pnp -.pnp.js -# testing -/coverage +# generated content +.contentlayer +.content-collections +.source -# next.js +# test & build +/coverage /.next/ /out/ - -# production /build +*.tsbuildinfo # misc .DS_Store *.pem - -# debug +/.pnp +.pnp.js npm-debug.log* yarn-debug.log* yarn-error.log* -# local env files +# others .env*.local - -# vercel .vercel - -# typescript -*.tsbuildinfo -next-env.d.ts +next-env.d.ts \ No newline at end of file diff --git a/apps/docs/README.md b/apps/docs/README.md new file mode 100644 index 0000000..dd12f47 --- /dev/null +++ b/apps/docs/README.md @@ -0,0 +1,26 @@ +# docs + +This is a Next.js application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). + +Run development server: + +```bash +npm run dev +# or +pnpm dev +# or +yarn dev +``` + +Open http://localhost:3000 with your browser to see the result. + +## Learn More + +To learn more about Next.js and Fumadocs, take a look at the following +resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js + features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs diff --git a/apps/docs/app/(home)/layout.tsx b/apps/docs/app/(home)/layout.tsx new file mode 100644 index 0000000..608a58b --- /dev/null +++ b/apps/docs/app/(home)/layout.tsx @@ -0,0 +1,11 @@ +import type { ReactNode } from 'react'; +import { HomeLayout } from 'fumadocs-ui/layouts/home'; +import { baseOptions } from '@/app/layout.config'; + +export default function Layout({ + children, +}: { + children: ReactNode; +}): React.ReactElement { + return {children}; +} diff --git a/apps/docs/app/(home)/page.tsx b/apps/docs/app/(home)/page.tsx new file mode 100644 index 0000000..3ab192f --- /dev/null +++ b/apps/docs/app/(home)/page.tsx @@ -0,0 +1,115 @@ +import { Card, Cards } from '@/components/card'; +import { Heading } from '@/components/heading'; +import Link from 'next/link'; + +// export default function HomePage() { +// return ( +//
+//

Hello World

+//

+// You can open{' '} +// +// /docs +// {' '} +// and see the documentation. +//

+//
+// ); +// } + +const features = [ + { + title: 'Beginner friendly ๐Ÿš€', + description: 'CommandKit aims to be beginner friendly.', + }, + { + title: 'Slash + context menu commands support โœ…', + description: 'CommandKit supports slash and context menu commands.', + }, + { + title: 'Multiple dev guilds, users, & roles support ๐Ÿค', + description: 'CommandKit supports multiple dev guilds, users, and roles.', + }, + { + title: 'Automatic command updates ๐Ÿค–', + description: 'CommandKit automatically updates commands.', + }, + { + title: 'REST registration behaviour ๐Ÿ“', + description: 'CommandKit has REST registration behaviour.', + }, + { + title: 'And much more! ๐Ÿงช', + description: 'CommandKit has much more features.', + }, +]; + +export default function HomePage() { + return ( + <> +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + CommandKit Logo + +
+

+ Let{' '} + + CommandKit + {' '} + handle it for you! +

+

+ A Discord.js handler for commands and events. +

+ +
+ + Guide + + + Docs + + + GitHub + +
+
+
+
+ + Features + + + {features.map((feature) => ( + + ))} + +
+ + ); +} diff --git a/apps/docs/app/api/search/route.ts b/apps/docs/app/api/search/route.ts new file mode 100644 index 0000000..14fc8ba --- /dev/null +++ b/apps/docs/app/api/search/route.ts @@ -0,0 +1,4 @@ +import { source } from '@/lib/api-source'; +import { createFromSource } from 'fumadocs-core/search/server'; + +export const { GET } = createFromSource(source); diff --git a/apps/docs/app/docs/[[...slug]]/page.tsx b/apps/docs/app/docs/[[...slug]]/page.tsx new file mode 100644 index 0000000..5957959 --- /dev/null +++ b/apps/docs/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,62 @@ +import { source } from '@/lib/api-source'; +import { + DocsPage, + DocsBody, + DocsDescription, + DocsTitle, +} from 'fumadocs-ui/page'; +import { notFound } from 'next/navigation'; +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; +import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock'; +import { Callout } from 'fumadocs-ui/components/callout'; + +export default async function Page(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDX = page.data.body; + + return ( + + {page.data.title} + {page.data.description} + + ( + +
{props.children}
+
+ ), + Callout, + }} + /> +
+
+ ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title, + description: page.data.description, + }; +} diff --git a/apps/docs/app/docs/layout.tsx b/apps/docs/app/docs/layout.tsx new file mode 100644 index 0000000..2db8326 --- /dev/null +++ b/apps/docs/app/docs/layout.tsx @@ -0,0 +1,12 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import type { ReactNode } from 'react'; +import { baseOptions } from '@/app/layout.config'; +import { source } from '@/lib/api-source'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/apps/docs/styles/globals.css b/apps/docs/app/global.css similarity index 100% rename from apps/docs/styles/globals.css rename to apps/docs/app/global.css diff --git a/apps/docs/app/guide/[[...slug]]/page.tsx b/apps/docs/app/guide/[[...slug]]/page.tsx new file mode 100644 index 0000000..b6ec8f1 --- /dev/null +++ b/apps/docs/app/guide/[[...slug]]/page.tsx @@ -0,0 +1,62 @@ +import { source } from '@/lib/source'; +import { + DocsPage, + DocsBody, + DocsDescription, + DocsTitle, +} from 'fumadocs-ui/page'; +import { notFound } from 'next/navigation'; +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; +import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock'; +import { Callout } from 'fumadocs-ui/components/callout'; + +export default async function Page(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDX = page.data.body; + + return ( + + {page.data.title} + {page.data.description} + + ( + +
{props.children}
+
+ ), + Callout, + }} + /> +
+
+ ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title, + description: page.data.description, + }; +} diff --git a/apps/docs/app/guide/layout.tsx b/apps/docs/app/guide/layout.tsx new file mode 100644 index 0000000..a91d558 --- /dev/null +++ b/apps/docs/app/guide/layout.tsx @@ -0,0 +1,12 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import type { ReactNode } from 'react'; +import { baseOptions } from '@/app/layout.config'; +import { source } from '@/lib/source'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/apps/docs/app/layout.config.tsx b/apps/docs/app/layout.config.tsx new file mode 100644 index 0000000..3e56723 --- /dev/null +++ b/apps/docs/app/layout.config.tsx @@ -0,0 +1,45 @@ +import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'; + +/** + * Shared layout configurations + * + * you can configure layouts individually from: + * Home Layout: app/(home)/layout.tsx + * Docs Layout: app/docs/layout.tsx + */ +export const baseOptions: BaseLayoutProps = { + nav: { + title: 'CommandKit', + }, + links: [ + { + text: 'Guide', + url: '/guide/installation', + active: 'nested-url', + }, + { + text: 'Documentation', + url: '/docs/typedef/AutocompleteProps', + active: 'nested-url', + }, + { + url: 'https://ctrl.lol/discord', + external: true, + type: 'icon', + icon: ( + + Discord + + + ), + text: 'Discord', + }, + ], + githubUrl: 'https://github.com/underctrl-io/commandkit', +}; diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx new file mode 100644 index 0000000..9b67cdd --- /dev/null +++ b/apps/docs/app/layout.tsx @@ -0,0 +1,18 @@ +import './global.css'; +import { RootProvider } from 'fumadocs-ui/provider'; +import { Inter } from 'next/font/google'; +import type { ReactNode } from 'react'; + +const inter = Inter({ + subsets: ['latin'], +}); + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + + {children} + + + ); +} diff --git a/apps/docs/cli.json b/apps/docs/cli.json new file mode 100644 index 0000000..9a197fd --- /dev/null +++ b/apps/docs/cli.json @@ -0,0 +1,8 @@ +{ + "aliases": { + "cn": "./lib/utils.ts", + "componentsDir": "./components", + "uiDir": "./components/ui", + "libDir": "./lib" + } +} \ No newline at end of file diff --git a/apps/docs/components/accordion.tsx b/apps/docs/components/accordion.tsx new file mode 100644 index 0000000..206496c --- /dev/null +++ b/apps/docs/components/accordion.tsx @@ -0,0 +1,114 @@ +'use client'; + +import * as AccordionPrimitive from '@radix-ui/react-accordion'; +import type { + AccordionMultipleProps, + AccordionSingleProps, +} from '@radix-ui/react-accordion'; +import { Check, ChevronRight, LinkIcon } from 'lucide-react'; +import { + forwardRef, + type ComponentPropsWithoutRef, + useState, + useEffect, +} from 'react'; +import { cn } from '../lib/cn'; +import { useCopyButton } from '../lib/use-copy-button'; +import { buttonVariants } from './ui/button'; + +export const Accordions = forwardRef< + HTMLDivElement, + | Omit + | Omit +>(({ type = 'single', className, defaultValue, ...props }, ref) => { + const [value, setValue] = useState( + type === 'single' ? (defaultValue ?? '') : (defaultValue ?? []), + ); + + useEffect(() => { + const id = window.location.hash.substring(1); + + if (id.length > 0) + setValue((prev) => (typeof prev === 'string' ? id : [id, ...prev])); + }, []); + + return ( + // @ts-expect-error -- Multiple types + + ); +}); + +Accordions.displayName = 'Accordions'; + +export const Accordion = forwardRef< + HTMLDivElement, + Omit, 'value'> & { + title: string; + } +>(({ title, className, id, children, ...props }, ref) => { + return ( + + + + + {title} + + {id ? : null} + + +
{children}
+
+
+ ); +}); + +function CopyButton({ id }: { id: string }): React.ReactElement { + const [checked, onClick] = useCopyButton(() => { + const url = new URL(window.location.href); + url.hash = id; + + void navigator.clipboard.writeText(url.toString()); + }); + + return ( + + ); +} + +Accordion.displayName = 'Accordion'; diff --git a/apps/docs/components/banner.tsx b/apps/docs/components/banner.tsx new file mode 100644 index 0000000..c2ea9ec --- /dev/null +++ b/apps/docs/components/banner.tsx @@ -0,0 +1,137 @@ +'use client'; + +import { type HTMLAttributes, useCallback, useEffect, useState } from 'react'; +import { X } from 'lucide-react'; +import { cn } from '../lib/cn'; +import { buttonVariants } from './ui/button'; + +export function Banner({ + id, + variant = 'normal', + changeLayout = true, + ...props +}: HTMLAttributes & { + /** + * @defaultValue 'normal' + */ + variant?: 'rainbow' | 'normal'; + + /** + * Change Fumadocs layout styles + * + * @defaultValue true + */ + changeLayout?: boolean; +}): React.ReactElement { + const [open, setOpen] = useState(true); + const globalKey = id ? `nd-banner-${id}` : undefined; + + useEffect(() => { + if (globalKey) setOpen(localStorage.getItem(globalKey) !== 'true'); + }, [globalKey]); + + const onClick = useCallback(() => { + setOpen(false); + if (globalKey) localStorage.setItem(globalKey, 'true'); + }, [globalKey]); + + return ( +
+ {changeLayout && open ? ( + + ) : null} + {globalKey ? ( + + ) : null} + {id ? ( +