mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-26 10:55:57 +00:00
UI: separate UI and docs components
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
build,
|
||||
combineRegistry,
|
||||
RegistryCompiler,
|
||||
writeFumadocsRegistry,
|
||||
writeShadcnRegistry,
|
||||
} from '@fumadocs/cli/build';
|
||||
@@ -9,8 +9,8 @@ import * as ui from '../../../packages/ui/src/_registry';
|
||||
|
||||
export async function buildRegistry() {
|
||||
const [mainRegistry, uiRegistry] = await Promise.all([
|
||||
build(registry),
|
||||
build(ui.registry),
|
||||
new RegistryCompiler(registry).compile(),
|
||||
new RegistryCompiler(ui.registry).compile(),
|
||||
]);
|
||||
const all = combineRegistry(mainRegistry, uiRegistry);
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
"./style.css": "./dist/style.css",
|
||||
"./css/*": "./css/*",
|
||||
"./image-zoom.css": "./dist/image-zoom.css",
|
||||
"./components/tabs.unstyled": {
|
||||
"import": "./dist/components/ui/tabs.js",
|
||||
"types": "./dist/components/ui/tabs.d.ts"
|
||||
},
|
||||
"./components/*": {
|
||||
"import": "./dist/components/*.js",
|
||||
"types": "./dist/components/*.d.ts",
|
||||
|
||||
@@ -252,6 +252,10 @@ export const registry: Registry = {
|
||||
type: 'components',
|
||||
path: 'components/accordion.tsx',
|
||||
},
|
||||
{
|
||||
type: 'ui',
|
||||
path: 'components/ui/accordion.tsx',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -358,8 +362,8 @@ export const registry: Registry = {
|
||||
path: 'components/tabs.tsx',
|
||||
},
|
||||
{
|
||||
type: 'components',
|
||||
path: 'components/tabs.unstyled.tsx',
|
||||
type: 'ui',
|
||||
path: 'components/ui/tabs.tsx',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import type {
|
||||
AccordionMultipleProps,
|
||||
AccordionSingleProps,
|
||||
} from '@radix-ui/react-accordion';
|
||||
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
||||
import { Check, ChevronRight, Link as LinkIcon } from '@icons';
|
||||
import { Check, Link as LinkIcon } from '@icons';
|
||||
import {
|
||||
type ComponentPropsWithoutRef,
|
||||
forwardRef,
|
||||
ComponentProps,
|
||||
type ReactNode,
|
||||
useEffect,
|
||||
useRef,
|
||||
@@ -18,12 +12,21 @@ import { cn } from '@/utils/cn';
|
||||
import { useCopyButton } from '@/utils/use-copy-button';
|
||||
import { buttonVariants } from '@/components/ui/button';
|
||||
import { mergeRefs } from '@/utils/merge-refs';
|
||||
import {
|
||||
Accordion as Root,
|
||||
AccordionContent,
|
||||
AccordionHeader,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from '@/components/ui/accordion';
|
||||
|
||||
export const Accordions = forwardRef<
|
||||
HTMLDivElement,
|
||||
| Omit<AccordionSingleProps, 'value' | 'onValueChange'>
|
||||
| Omit<AccordionMultipleProps, 'value' | 'onValueChange'>
|
||||
>(({ type = 'single', className, defaultValue, ...props }, ref) => {
|
||||
export function Accordions({
|
||||
type = 'single',
|
||||
ref,
|
||||
className,
|
||||
defaultValue,
|
||||
...props
|
||||
}: ComponentProps<typeof Root>) {
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const composedRef = mergeRefs(ref, rootRef);
|
||||
const [value, setValue] = useState<string | string[]>(() =>
|
||||
@@ -45,7 +48,7 @@ export const Accordions = forwardRef<
|
||||
|
||||
return (
|
||||
// @ts-expect-error -- Multiple types
|
||||
<AccordionPrimitive.Root
|
||||
<Root
|
||||
type={type}
|
||||
ref={composedRef}
|
||||
value={value}
|
||||
@@ -58,51 +61,32 @@ export const Accordions = forwardRef<
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Accordions.displayName = 'Accordions';
|
||||
|
||||
export const Accordion = forwardRef<
|
||||
HTMLDivElement,
|
||||
Omit<
|
||||
ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>,
|
||||
'value' | 'title'
|
||||
> & {
|
||||
title: string | ReactNode;
|
||||
value?: string;
|
||||
}
|
||||
>(
|
||||
(
|
||||
{ title, className, id, value = String(title), children, ...props },
|
||||
ref,
|
||||
) => {
|
||||
return (
|
||||
<AccordionPrimitive.Item
|
||||
ref={ref}
|
||||
value={value}
|
||||
className={cn('scroll-m-24', className)}
|
||||
{...props}
|
||||
>
|
||||
<AccordionPrimitive.Header
|
||||
id={id}
|
||||
data-accordion-value={value}
|
||||
className="not-prose flex flex-row items-center text-fd-card-foreground font-medium has-focus-visible:bg-fd-accent"
|
||||
>
|
||||
<AccordionPrimitive.Trigger className="group flex flex-1 items-center gap-2 px-3 py-2.5 text-start focus-visible:outline-none">
|
||||
<ChevronRight className="size-4 shrink-0 text-fd-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-90" />
|
||||
{title}
|
||||
</AccordionPrimitive.Trigger>
|
||||
{id ? <CopyButton id={id} /> : null}
|
||||
</AccordionPrimitive.Header>
|
||||
<AccordionPrimitive.Content className="overflow-hidden data-[state=closed]:animate-fd-accordion-up data-[state=open]:animate-fd-accordion-down">
|
||||
<div className="px-4 pb-2 text-[0.9375rem] prose-no-margin">
|
||||
{children}
|
||||
</div>
|
||||
</AccordionPrimitive.Content>
|
||||
</AccordionPrimitive.Item>
|
||||
);
|
||||
},
|
||||
);
|
||||
export function Accordion({
|
||||
title,
|
||||
id,
|
||||
value = String(title),
|
||||
children,
|
||||
...props
|
||||
}: Omit<ComponentProps<typeof AccordionItem>, 'value' | 'title'> & {
|
||||
title: string | ReactNode;
|
||||
value?: string;
|
||||
}) {
|
||||
return (
|
||||
<AccordionItem value={value} {...props}>
|
||||
<AccordionHeader id={id} data-accordion-value={value}>
|
||||
<AccordionTrigger>{title}</AccordionTrigger>
|
||||
{id ? <CopyButton id={id} /> : null}
|
||||
</AccordionHeader>
|
||||
<AccordionContent>
|
||||
<div className="px-4 pb-2 text-[0.9375rem] prose-no-margin">
|
||||
{children}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
);
|
||||
}
|
||||
|
||||
function CopyButton({ id }: { id: string }) {
|
||||
const [checked, onClick] = useCopyButton(() => {
|
||||
@@ -132,5 +116,3 @@ function CopyButton({ id }: { id: string }) {
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
Accordion.displayName = 'Accordion';
|
||||
|
||||
@@ -15,18 +15,19 @@ import {
|
||||
import Link, { type LinkProps } from 'fumadocs-core/link';
|
||||
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
|
||||
import { cn } from '@/utils/cn';
|
||||
import { ScrollArea, ScrollViewport } from '@/components/ui/scroll-area';
|
||||
import {
|
||||
ScrollArea,
|
||||
type ScrollAreaProps,
|
||||
ScrollViewport,
|
||||
} from '@/components/ui/scroll-area';
|
||||
import { isActive } from '@/utils/is-active';
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
type CollapsibleContentProps,
|
||||
CollapsibleTrigger,
|
||||
type CollapsibleTriggerProps,
|
||||
} from '@/components/ui/collapsible';
|
||||
import { type ScrollAreaProps } from '@radix-ui/react-scroll-area';
|
||||
import type {
|
||||
CollapsibleContentProps,
|
||||
CollapsibleTriggerProps,
|
||||
} from '@radix-ui/react-collapsible';
|
||||
import { useMediaQuery } from 'fumadocs-core/utils/use-media-query';
|
||||
import { Presence } from '@radix-ui/react-presence';
|
||||
import scrollIntoView from 'scroll-into-view-if-needed';
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
useState,
|
||||
} from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
import * as Unstyled from './tabs.unstyled';
|
||||
import * as Unstyled from './ui/tabs';
|
||||
|
||||
type CollectionKey = string | symbol;
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
'use client';
|
||||
|
||||
import * as Primitive from '@radix-ui/react-accordion';
|
||||
import { ChevronRight } from '@icons';
|
||||
import { type ComponentProps } from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
export function Accordion({
|
||||
className,
|
||||
...props
|
||||
}: ComponentProps<typeof Primitive.Root>) {
|
||||
return (
|
||||
<Primitive.Root
|
||||
className={cn(
|
||||
'divide-y divide-fd-border overflow-hidden rounded-lg border bg-fd-card',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function AccordionItem({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<typeof Primitive.Item>) {
|
||||
return (
|
||||
<Primitive.Item className={cn('scroll-m-24', className)} {...props}>
|
||||
{children}
|
||||
</Primitive.Item>
|
||||
);
|
||||
}
|
||||
|
||||
export function AccordionHeader({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<typeof Primitive.Header>) {
|
||||
return (
|
||||
<Primitive.Header
|
||||
className={cn(
|
||||
'not-prose flex flex-row items-center text-fd-card-foreground font-medium has-focus-visible:bg-fd-accent',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Primitive.Header>
|
||||
);
|
||||
}
|
||||
|
||||
export function AccordionTrigger({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<typeof Primitive.Trigger>) {
|
||||
return (
|
||||
<Primitive.Trigger
|
||||
className={cn(
|
||||
'group flex flex-1 items-center gap-2 px-3 py-2.5 text-start focus-visible:outline-none',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronRight className="size-4 shrink-0 text-fd-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-90" />
|
||||
{children}
|
||||
</Primitive.Trigger>
|
||||
);
|
||||
}
|
||||
|
||||
export function AccordionContent({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: ComponentProps<typeof Primitive.Content>) {
|
||||
return (
|
||||
<Primitive.Content
|
||||
className={cn(
|
||||
'overflow-hidden data-[state=closed]:animate-fd-accordion-up data-[state=open]:animate-fd-accordion-down',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Primitive.Content>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
'use client';
|
||||
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
|
||||
import * as Primitive from '@radix-ui/react-collapsible';
|
||||
import { forwardRef, useEffect, useState } from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
const Collapsible = CollapsiblePrimitive.Root;
|
||||
const Collapsible = Primitive.Root;
|
||||
|
||||
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
|
||||
const CollapsibleTrigger = Primitive.CollapsibleTrigger;
|
||||
|
||||
const CollapsibleContent = forwardRef<
|
||||
HTMLDivElement,
|
||||
React.ComponentPropsWithoutRef<typeof CollapsiblePrimitive.CollapsibleContent>
|
||||
React.ComponentPropsWithoutRef<typeof Primitive.CollapsibleContent>
|
||||
>(({ children, ...props }, ref) => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
@@ -18,7 +18,7 @@ const CollapsibleContent = forwardRef<
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<CollapsiblePrimitive.CollapsibleContent
|
||||
<Primitive.CollapsibleContent
|
||||
ref={ref}
|
||||
{...props}
|
||||
className={cn(
|
||||
@@ -29,11 +29,14 @@ const CollapsibleContent = forwardRef<
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</CollapsiblePrimitive.CollapsibleContent>
|
||||
</Primitive.CollapsibleContent>
|
||||
);
|
||||
});
|
||||
|
||||
CollapsibleContent.displayName =
|
||||
CollapsiblePrimitive.CollapsibleContent.displayName;
|
||||
CollapsibleContent.displayName = Primitive.CollapsibleContent.displayName;
|
||||
|
||||
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
||||
|
||||
export type CollapsibleProps = Primitive.CollapsibleProps;
|
||||
export type CollapsibleContentProps = Primitive.CollapsibleContentProps;
|
||||
export type CollapsibleTriggerProps = Primitive.CollapsibleTriggerProps;
|
||||
|
||||
@@ -3,6 +3,9 @@ import * as React from 'react';
|
||||
import * as Primitive from '@radix-ui/react-navigation-menu';
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
export type NavigationMenuContentProps = Primitive.NavigationMenuContentProps;
|
||||
export type NavigationMenuTriggerProps = Primitive.NavigationMenuTriggerProps;
|
||||
|
||||
const NavigationMenu = Primitive.Root;
|
||||
|
||||
const NavigationMenuList = Primitive.List;
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
||||
import * as Primitive from '@radix-ui/react-scroll-area';
|
||||
import * as React from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
const ScrollArea = React.forwardRef<
|
||||
React.ComponentRef<typeof ScrollAreaPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||
React.ComponentRef<typeof Primitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof Primitive.Root>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Root
|
||||
<Primitive.Root
|
||||
ref={ref}
|
||||
type="scroll"
|
||||
className={cn('overflow-hidden', className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
<Primitive.Corner />
|
||||
<ScrollBar orientation="vertical" />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
</Primitive.Root>
|
||||
));
|
||||
|
||||
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
||||
ScrollArea.displayName = Primitive.Root.displayName;
|
||||
|
||||
const ScrollViewport = React.forwardRef<
|
||||
React.ComponentRef<typeof ScrollAreaPrimitive.Viewport>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Viewport>
|
||||
React.ComponentRef<typeof Primitive.Viewport>,
|
||||
React.ComponentPropsWithoutRef<typeof Primitive.Viewport>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
<Primitive.Viewport
|
||||
ref={ref}
|
||||
className={cn('size-full rounded-[inherit]', className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
</Primitive.Viewport>
|
||||
));
|
||||
|
||||
ScrollViewport.displayName = ScrollAreaPrimitive.Viewport.displayName;
|
||||
ScrollViewport.displayName = Primitive.Viewport.displayName;
|
||||
|
||||
const ScrollBar = React.forwardRef<
|
||||
React.ComponentRef<typeof ScrollAreaPrimitive.Scrollbar>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>
|
||||
React.ComponentRef<typeof Primitive.Scrollbar>,
|
||||
React.ComponentPropsWithoutRef<typeof Primitive.Scrollbar>
|
||||
>(({ className, orientation = 'vertical', ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Scrollbar
|
||||
<Primitive.Scrollbar
|
||||
ref={ref}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
@@ -50,9 +50,10 @@ const ScrollBar = React.forwardRef<
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-fd-border" />
|
||||
</ScrollAreaPrimitive.Scrollbar>
|
||||
<Primitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-fd-border" />
|
||||
</Primitive.Scrollbar>
|
||||
));
|
||||
ScrollBar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;
|
||||
ScrollBar.displayName = Primitive.Scrollbar.displayName;
|
||||
|
||||
export { ScrollArea, ScrollBar, ScrollViewport };
|
||||
export type ScrollAreaProps = Primitive.ScrollAreaProps;
|
||||
|
||||
@@ -3,14 +3,12 @@ import Link, { type LinkProps } from 'fumadocs-core/link';
|
||||
import { cn } from '@/utils/cn';
|
||||
import {
|
||||
NavigationMenuContent,
|
||||
type NavigationMenuContentProps,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuTrigger,
|
||||
type NavigationMenuTriggerProps,
|
||||
} from '@/components/ui/navigation-menu';
|
||||
import type {
|
||||
NavigationMenuContentProps,
|
||||
NavigationMenuTriggerProps,
|
||||
} from '@radix-ui/react-navigation-menu';
|
||||
import { navItemVariants } from './client';
|
||||
|
||||
export const NavbarMenu = NavigationMenuItem;
|
||||
|
||||
Reference in New Issue
Block a user