@hanzo/ui 5.3.26 → 5.3.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/index.ts +26 -0
- package/dist/util/index.js +6 -0
- package/dist/util/index.mjs +6 -1
- package/docs/_registry/index.ts +426 -0
- package/docs/_registry/layout/docs-min.tsx +197 -0
- package/docs/_registry/layout/page-min.tsx +128 -0
- package/docs/components/accordion.tsx +118 -0
- package/docs/components/banner.tsx +144 -0
- package/docs/components/callout.tsx +112 -0
- package/docs/components/card.tsx +52 -0
- package/docs/components/codeblock.tsx +258 -0
- package/docs/components/dialog/search-algolia.tsx +132 -0
- package/docs/components/dialog/search-default.tsx +131 -0
- package/docs/components/dialog/search-orama.tsx +143 -0
- package/docs/components/dialog/search.tsx +529 -0
- package/docs/components/dynamic-codeblock.tsx +129 -0
- package/docs/components/files.tsx +81 -0
- package/docs/components/github-info.tsx +107 -0
- package/docs/components/heading.tsx +33 -0
- package/docs/components/image-zoom.css +77 -0
- package/docs/components/image-zoom.tsx +58 -0
- package/docs/components/index.ts +7 -0
- package/docs/components/inline-toc.tsx +48 -0
- package/docs/components/sidebar/base.tsx +451 -0
- package/docs/components/sidebar/link-item.tsx +65 -0
- package/docs/components/sidebar/page-tree.tsx +113 -0
- package/docs/components/sidebar/tabs/dropdown.tsx +109 -0
- package/docs/components/sidebar/tabs/index.tsx +89 -0
- package/docs/components/steps.tsx +9 -0
- package/docs/components/tabs.tsx +203 -0
- package/docs/components/toc/clerk.tsx +173 -0
- package/docs/components/toc/default.tsx +57 -0
- package/docs/components/toc/index.tsx +136 -0
- package/docs/components/type-table.tsx +174 -0
- package/docs/components/ui/accordion.tsx +88 -0
- package/docs/components/ui/button.tsx +28 -0
- package/docs/components/ui/collapsible.tsx +42 -0
- package/docs/components/ui/navigation-menu.tsx +83 -0
- package/docs/components/ui/popover.tsx +32 -0
- package/docs/components/ui/scroll-area.tsx +59 -0
- package/docs/components/ui/tabs.tsx +145 -0
- package/docs/contexts/i18n.tsx +56 -0
- package/docs/contexts/search.tsx +165 -0
- package/docs/contexts/tree.tsx +65 -0
- package/docs/css/black.css +39 -0
- package/docs/css/catppuccin.css +49 -0
- package/docs/css/colors/index.css +51 -0
- package/docs/css/dusk.css +47 -0
- package/docs/css/layouts/docs.css +1 -0
- package/docs/css/layouts/home.css +1 -0
- package/docs/css/layouts/notebook.css +1 -0
- package/docs/css/neutral.css +7 -0
- package/docs/css/ocean.css +48 -0
- package/docs/css/preset.css +305 -0
- package/docs/css/purple.css +39 -0
- package/docs/css/shadcn.css +36 -0
- package/docs/css/shiki.css +90 -0
- package/docs/css/solar.css +75 -0
- package/docs/css/style.css +9 -0
- package/docs/css/vitepress.css +77 -0
- package/docs/i18n.tsx +30 -0
- package/docs/icons.tsx +354 -0
- package/docs/layouts/docs/client.tsx +129 -0
- package/docs/layouts/docs/index.tsx +321 -0
- package/docs/layouts/docs/page/client.tsx +376 -0
- package/docs/layouts/docs/page/index.tsx +251 -0
- package/docs/layouts/docs/sidebar.tsx +265 -0
- package/docs/layouts/home/client.tsx +375 -0
- package/docs/layouts/home/index.tsx +51 -0
- package/docs/layouts/home/navbar.tsx +55 -0
- package/docs/layouts/notebook/client.tsx +281 -0
- package/docs/layouts/notebook/index.tsx +461 -0
- package/docs/layouts/notebook/page/client.tsx +375 -0
- package/docs/layouts/notebook/page/index.tsx +251 -0
- package/docs/layouts/notebook/sidebar.tsx +248 -0
- package/docs/layouts/shared/index.tsx +89 -0
- package/docs/layouts/shared/language-toggle.tsx +66 -0
- package/docs/layouts/shared/link-item.tsx +119 -0
- package/docs/layouts/shared/search-toggle.tsx +78 -0
- package/docs/layouts/shared/theme-toggle.tsx +86 -0
- package/docs/mdx.server.tsx +37 -0
- package/docs/mdx.tsx +97 -0
- package/docs/og.tsx +101 -0
- package/docs/page.tsx +85 -0
- package/docs/provider/base.tsx +173 -0
- package/docs/provider/next.tsx +23 -0
- package/docs/provider/react-router.tsx +23 -0
- package/docs/provider/tanstack.tsx +23 -0
- package/docs/provider/waku.tsx +23 -0
- package/docs/source.ts +3 -0
- package/docs/theme/typography/LICENSE +21 -0
- package/docs/theme/typography/index.ts +201 -0
- package/docs/theme/typography/styles.ts +449 -0
- package/docs/utils/cn.ts +1 -0
- package/docs/utils/is-active.ts +23 -0
- package/docs/utils/merge-refs.ts +15 -0
- package/docs/utils/use-copy-button.ts +39 -0
- package/docs/utils/use-footer-items.ts +27 -0
- package/docs/utils/use-is-scroll-top.ts +21 -0
- package/package.json +4 -2
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as Primitive from '@hanzo/docs-core/toc';
|
|
3
|
+
import {
|
|
4
|
+
type ComponentProps,
|
|
5
|
+
createContext,
|
|
6
|
+
use,
|
|
7
|
+
type RefObject,
|
|
8
|
+
useEffect,
|
|
9
|
+
useEffectEvent,
|
|
10
|
+
useRef,
|
|
11
|
+
} from 'react';
|
|
12
|
+
import { cn } from '@/utils/cn';
|
|
13
|
+
import { mergeRefs } from '@/utils/merge-refs';
|
|
14
|
+
|
|
15
|
+
const TOCContext = createContext<Primitive.TOCItemType[]>([]);
|
|
16
|
+
|
|
17
|
+
export function useTOCItems(): Primitive.TOCItemType[] {
|
|
18
|
+
return use(TOCContext);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function TOCProvider({
|
|
22
|
+
toc,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
}: ComponentProps<typeof Primitive.AnchorProvider>) {
|
|
26
|
+
return (
|
|
27
|
+
<TOCContext value={toc}>
|
|
28
|
+
<Primitive.AnchorProvider toc={toc} {...props}>
|
|
29
|
+
{children}
|
|
30
|
+
</Primitive.AnchorProvider>
|
|
31
|
+
</TOCContext>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function TOCScrollArea({
|
|
36
|
+
ref,
|
|
37
|
+
className,
|
|
38
|
+
...props
|
|
39
|
+
}: ComponentProps<'div'>) {
|
|
40
|
+
const viewRef = useRef<HTMLDivElement>(null);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div
|
|
44
|
+
ref={mergeRefs(viewRef, ref)}
|
|
45
|
+
className={cn(
|
|
46
|
+
'relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] mask-[linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3',
|
|
47
|
+
className,
|
|
48
|
+
)}
|
|
49
|
+
{...props}
|
|
50
|
+
>
|
|
51
|
+
<Primitive.ScrollProvider containerRef={viewRef}>
|
|
52
|
+
{props.children}
|
|
53
|
+
</Primitive.ScrollProvider>
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
type TocThumb = [top: number, height: number];
|
|
59
|
+
|
|
60
|
+
interface RefProps {
|
|
61
|
+
containerRef: RefObject<HTMLElement | null>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function TocThumb({
|
|
65
|
+
containerRef,
|
|
66
|
+
...props
|
|
67
|
+
}: ComponentProps<'div'> & RefProps) {
|
|
68
|
+
const thumbRef = useRef<HTMLDivElement>(null);
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<>
|
|
72
|
+
<div ref={thumbRef} role="none" {...props} />
|
|
73
|
+
<Updater containerRef={containerRef} thumbRef={thumbRef} />
|
|
74
|
+
</>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function Updater({
|
|
79
|
+
containerRef,
|
|
80
|
+
thumbRef,
|
|
81
|
+
}: RefProps & { thumbRef: RefObject<HTMLElement | null> }) {
|
|
82
|
+
const active = Primitive.useActiveAnchors();
|
|
83
|
+
const onPrint = useEffectEvent(() => {
|
|
84
|
+
if (!containerRef.current || !thumbRef.current) return;
|
|
85
|
+
|
|
86
|
+
update(thumbRef.current, calc(containerRef.current, active));
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (!containerRef.current) return;
|
|
91
|
+
const container = containerRef.current;
|
|
92
|
+
|
|
93
|
+
const observer = new ResizeObserver(onPrint);
|
|
94
|
+
observer.observe(container);
|
|
95
|
+
|
|
96
|
+
return () => {
|
|
97
|
+
observer.disconnect();
|
|
98
|
+
};
|
|
99
|
+
}, [containerRef]);
|
|
100
|
+
|
|
101
|
+
if (containerRef.current && thumbRef.current) {
|
|
102
|
+
update(thumbRef.current, calc(containerRef.current, active));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function calc(container: HTMLElement, active: string[]): TocThumb {
|
|
109
|
+
if (active.length === 0 || container.clientHeight === 0) {
|
|
110
|
+
return [0, 0];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
let upper = Number.MAX_VALUE,
|
|
114
|
+
lower = 0;
|
|
115
|
+
|
|
116
|
+
for (const item of active) {
|
|
117
|
+
const element = container.querySelector<HTMLElement>(`a[href="#${item}"]`);
|
|
118
|
+
if (!element) continue;
|
|
119
|
+
|
|
120
|
+
const styles = getComputedStyle(element);
|
|
121
|
+
upper = Math.min(upper, element.offsetTop + parseFloat(styles.paddingTop));
|
|
122
|
+
lower = Math.max(
|
|
123
|
+
lower,
|
|
124
|
+
element.offsetTop +
|
|
125
|
+
element.clientHeight -
|
|
126
|
+
parseFloat(styles.paddingBottom),
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return [upper, lower - upper];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function update(element: HTMLElement, info: TocThumb): void {
|
|
134
|
+
element.style.setProperty('--fd-top', `${info[0]}px`);
|
|
135
|
+
element.style.setProperty('--fd-height', `${info[1]}px`);
|
|
136
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ChevronDown } from '@icons';
|
|
4
|
+
import Link from '@hanzo/docs-core/link';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { cn } from '@/utils/cn';
|
|
7
|
+
import { type ReactNode, useState } from 'react';
|
|
8
|
+
import {
|
|
9
|
+
Collapsible,
|
|
10
|
+
CollapsibleContent,
|
|
11
|
+
CollapsibleTrigger,
|
|
12
|
+
} from '@/components/ui/collapsible';
|
|
13
|
+
|
|
14
|
+
export interface ParameterNode {
|
|
15
|
+
name: string;
|
|
16
|
+
description: ReactNode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface TypeNode {
|
|
20
|
+
/**
|
|
21
|
+
* Additional description of the field
|
|
22
|
+
*/
|
|
23
|
+
description?: ReactNode;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* type signature (short)
|
|
27
|
+
*/
|
|
28
|
+
type: ReactNode;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* type signature (full)
|
|
32
|
+
*/
|
|
33
|
+
typeDescription?: ReactNode;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Optional `href` for the type
|
|
37
|
+
*/
|
|
38
|
+
typeDescriptionLink?: string;
|
|
39
|
+
|
|
40
|
+
default?: ReactNode;
|
|
41
|
+
|
|
42
|
+
required?: boolean;
|
|
43
|
+
deprecated?: boolean;
|
|
44
|
+
|
|
45
|
+
parameters?: ParameterNode[];
|
|
46
|
+
|
|
47
|
+
returns?: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const keyVariants = cva('text-fd-primary', {
|
|
51
|
+
variants: {
|
|
52
|
+
deprecated: {
|
|
53
|
+
true: 'line-through text-fd-primary/50',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const fieldVariants = cva('text-fd-muted-foreground not-prose pe-2');
|
|
59
|
+
|
|
60
|
+
export function TypeTable({ type }: { type: Record<string, TypeNode> }) {
|
|
61
|
+
return (
|
|
62
|
+
<div className="@container flex flex-col p-1 bg-fd-card text-fd-card-foreground rounded-2xl border my-6 text-sm overflow-hidden">
|
|
63
|
+
<div className="flex font-medium items-center px-3 py-1 not-prose text-fd-muted-foreground">
|
|
64
|
+
<p className="w-[25%]">Prop</p>
|
|
65
|
+
<p className="@max-xl:hidden">Type</p>
|
|
66
|
+
</div>
|
|
67
|
+
{Object.entries(type).map(([key, value]) => (
|
|
68
|
+
<Item key={key} name={key} item={value} />
|
|
69
|
+
))}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function Item({
|
|
75
|
+
name,
|
|
76
|
+
item: {
|
|
77
|
+
parameters = [],
|
|
78
|
+
description,
|
|
79
|
+
required = false,
|
|
80
|
+
deprecated,
|
|
81
|
+
typeDescription,
|
|
82
|
+
default: defaultValue,
|
|
83
|
+
type,
|
|
84
|
+
typeDescriptionLink,
|
|
85
|
+
returns,
|
|
86
|
+
},
|
|
87
|
+
}: {
|
|
88
|
+
name: string;
|
|
89
|
+
item: TypeNode;
|
|
90
|
+
}) {
|
|
91
|
+
const [open, setOpen] = useState(false);
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<Collapsible
|
|
95
|
+
open={open}
|
|
96
|
+
onOpenChange={setOpen}
|
|
97
|
+
className={cn(
|
|
98
|
+
'rounded-xl border overflow-hidden transition-all',
|
|
99
|
+
open
|
|
100
|
+
? 'shadow-sm bg-fd-background not-last:mb-2'
|
|
101
|
+
: 'border-transparent',
|
|
102
|
+
)}
|
|
103
|
+
>
|
|
104
|
+
<CollapsibleTrigger className="relative flex flex-row items-center w-full group text-start px-3 py-2 not-prose hover:bg-fd-accent">
|
|
105
|
+
<code
|
|
106
|
+
className={cn(
|
|
107
|
+
keyVariants({
|
|
108
|
+
deprecated,
|
|
109
|
+
className: 'min-w-fit w-[25%] font-medium pe-2',
|
|
110
|
+
}),
|
|
111
|
+
)}
|
|
112
|
+
>
|
|
113
|
+
{name}
|
|
114
|
+
{!required && '?'}
|
|
115
|
+
</code>
|
|
116
|
+
{typeDescriptionLink ? (
|
|
117
|
+
<Link href={typeDescriptionLink} className="underline @max-xl:hidden">
|
|
118
|
+
{type}
|
|
119
|
+
</Link>
|
|
120
|
+
) : (
|
|
121
|
+
<span className="@max-xl:hidden">{type}</span>
|
|
122
|
+
)}
|
|
123
|
+
<ChevronDown className="absolute end-2 size-4 text-fd-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
|
|
124
|
+
</CollapsibleTrigger>
|
|
125
|
+
<CollapsibleContent>
|
|
126
|
+
<div className="grid grid-cols-[1fr_3fr] gap-y-4 text-sm p-3 overflow-auto fd-scroll-container border-t">
|
|
127
|
+
<div className="text-sm prose col-span-full prose-no-margin empty:hidden">
|
|
128
|
+
{description}
|
|
129
|
+
</div>
|
|
130
|
+
{typeDescription && (
|
|
131
|
+
<>
|
|
132
|
+
<p className={cn(fieldVariants())}>Type</p>
|
|
133
|
+
<p className="my-auto not-prose">{typeDescription}</p>
|
|
134
|
+
</>
|
|
135
|
+
)}
|
|
136
|
+
{defaultValue && (
|
|
137
|
+
<>
|
|
138
|
+
<p className={cn(fieldVariants())}>Default</p>
|
|
139
|
+
<p className="my-auto not-prose">{defaultValue}</p>
|
|
140
|
+
</>
|
|
141
|
+
)}
|
|
142
|
+
{parameters.length > 0 && (
|
|
143
|
+
<>
|
|
144
|
+
<p className={cn(fieldVariants())}>Parameters</p>
|
|
145
|
+
<div className="flex flex-col gap-2">
|
|
146
|
+
{parameters.map((param) => (
|
|
147
|
+
<div
|
|
148
|
+
key={param.name}
|
|
149
|
+
className="inline-flex items-center flex-wrap gap-1"
|
|
150
|
+
>
|
|
151
|
+
<p className="font-medium not-prose text-nowrap">
|
|
152
|
+
{param.name} -
|
|
153
|
+
</p>
|
|
154
|
+
<div className="text-sm prose prose-no-margin">
|
|
155
|
+
{param.description}
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
))}
|
|
159
|
+
</div>
|
|
160
|
+
</>
|
|
161
|
+
)}
|
|
162
|
+
{returns && (
|
|
163
|
+
<>
|
|
164
|
+
<p className={cn(fieldVariants())}>Returns</p>
|
|
165
|
+
<div className="my-auto text-sm prose prose-no-margin">
|
|
166
|
+
{returns}
|
|
167
|
+
</div>
|
|
168
|
+
</>
|
|
169
|
+
)}
|
|
170
|
+
</div>
|
|
171
|
+
</CollapsibleContent>
|
|
172
|
+
</Collapsible>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as Primitive from '@radix-ui/react-accordion';
|
|
4
|
+
import { ChevronRight } from '@icons';
|
|
5
|
+
import { type ComponentProps } from 'react';
|
|
6
|
+
import { cn } from '@/utils/cn';
|
|
7
|
+
|
|
8
|
+
export function Accordion({
|
|
9
|
+
className,
|
|
10
|
+
...props
|
|
11
|
+
}: ComponentProps<typeof Primitive.Root>) {
|
|
12
|
+
return (
|
|
13
|
+
<Primitive.Root
|
|
14
|
+
className={cn(
|
|
15
|
+
'divide-y divide-fd-border overflow-hidden rounded-lg border bg-fd-card',
|
|
16
|
+
className,
|
|
17
|
+
)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function AccordionItem({
|
|
24
|
+
className,
|
|
25
|
+
children,
|
|
26
|
+
...props
|
|
27
|
+
}: ComponentProps<typeof Primitive.Item>) {
|
|
28
|
+
return (
|
|
29
|
+
<Primitive.Item className={cn('scroll-m-24', className)} {...props}>
|
|
30
|
+
{children}
|
|
31
|
+
</Primitive.Item>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function AccordionHeader({
|
|
36
|
+
className,
|
|
37
|
+
children,
|
|
38
|
+
...props
|
|
39
|
+
}: ComponentProps<typeof Primitive.Header>) {
|
|
40
|
+
return (
|
|
41
|
+
<Primitive.Header
|
|
42
|
+
className={cn(
|
|
43
|
+
'not-prose flex flex-row items-center text-fd-card-foreground font-medium has-focus-visible:bg-fd-accent',
|
|
44
|
+
className,
|
|
45
|
+
)}
|
|
46
|
+
{...props}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
</Primitive.Header>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function AccordionTrigger({
|
|
54
|
+
className,
|
|
55
|
+
children,
|
|
56
|
+
...props
|
|
57
|
+
}: ComponentProps<typeof Primitive.Trigger>) {
|
|
58
|
+
return (
|
|
59
|
+
<Primitive.Trigger
|
|
60
|
+
className={cn(
|
|
61
|
+
'group flex flex-1 items-center gap-2 px-3 py-2.5 text-start focus-visible:outline-none',
|
|
62
|
+
className,
|
|
63
|
+
)}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
<ChevronRight className="size-4 shrink-0 text-fd-muted-foreground transition-transform duration-200 group-data-[state=open]:rotate-90" />
|
|
67
|
+
{children}
|
|
68
|
+
</Primitive.Trigger>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function AccordionContent({
|
|
73
|
+
className,
|
|
74
|
+
children,
|
|
75
|
+
...props
|
|
76
|
+
}: ComponentProps<typeof Primitive.Content>) {
|
|
77
|
+
return (
|
|
78
|
+
<Primitive.Content
|
|
79
|
+
className={cn(
|
|
80
|
+
'overflow-hidden data-[state=closed]:animate-fd-accordion-up data-[state=open]:animate-fd-accordion-down',
|
|
81
|
+
className,
|
|
82
|
+
)}
|
|
83
|
+
{...props}
|
|
84
|
+
>
|
|
85
|
+
{children}
|
|
86
|
+
</Primitive.Content>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cva, type VariantProps } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
const variants = {
|
|
4
|
+
primary: 'bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/80',
|
|
5
|
+
outline: 'border hover:bg-fd-accent hover:text-fd-accent-foreground',
|
|
6
|
+
ghost: 'hover:bg-fd-accent hover:text-fd-accent-foreground',
|
|
7
|
+
secondary:
|
|
8
|
+
'border bg-fd-secondary text-fd-secondary-foreground hover:bg-fd-accent hover:text-fd-accent-foreground',
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
export const buttonVariants = cva(
|
|
12
|
+
'inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring',
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
variant: variants,
|
|
16
|
+
// fumadocs use `color` instead of `variant`
|
|
17
|
+
color: variants,
|
|
18
|
+
size: {
|
|
19
|
+
sm: 'gap-1 px-2 py-1.5 text-xs',
|
|
20
|
+
icon: 'p-1.5 [&_svg]:size-5',
|
|
21
|
+
'icon-sm': 'p-1.5 [&_svg]:size-4.5',
|
|
22
|
+
'icon-xs': 'p-1 [&_svg]:size-4',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export type ButtonProps = VariantProps<typeof buttonVariants>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as Primitive from '@radix-ui/react-collapsible';
|
|
3
|
+
import { forwardRef, useEffect, useState } from 'react';
|
|
4
|
+
import { cn } from '@/utils/cn';
|
|
5
|
+
|
|
6
|
+
const Collapsible = Primitive.Root;
|
|
7
|
+
|
|
8
|
+
const CollapsibleTrigger = Primitive.CollapsibleTrigger;
|
|
9
|
+
|
|
10
|
+
const CollapsibleContent = forwardRef<
|
|
11
|
+
HTMLDivElement,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof Primitive.CollapsibleContent>
|
|
13
|
+
>(({ children, ...props }, ref) => {
|
|
14
|
+
const [mounted, setMounted] = useState(false);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setMounted(true);
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Primitive.CollapsibleContent
|
|
22
|
+
ref={ref}
|
|
23
|
+
{...props}
|
|
24
|
+
className={cn(
|
|
25
|
+
'overflow-hidden',
|
|
26
|
+
mounted &&
|
|
27
|
+
'data-[state=closed]:animate-fd-collapsible-up data-[state=open]:animate-fd-collapsible-down',
|
|
28
|
+
props.className,
|
|
29
|
+
)}
|
|
30
|
+
>
|
|
31
|
+
{children}
|
|
32
|
+
</Primitive.CollapsibleContent>
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
CollapsibleContent.displayName = Primitive.CollapsibleContent.displayName;
|
|
37
|
+
|
|
38
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
|
39
|
+
|
|
40
|
+
export type CollapsibleProps = Primitive.CollapsibleProps;
|
|
41
|
+
export type CollapsibleContentProps = Primitive.CollapsibleContentProps;
|
|
42
|
+
export type CollapsibleTriggerProps = Primitive.CollapsibleTriggerProps;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as Primitive from '@radix-ui/react-navigation-menu';
|
|
4
|
+
import { cn } from '@/utils/cn';
|
|
5
|
+
|
|
6
|
+
export type NavigationMenuContentProps = Primitive.NavigationMenuContentProps;
|
|
7
|
+
export type NavigationMenuTriggerProps = Primitive.NavigationMenuTriggerProps;
|
|
8
|
+
|
|
9
|
+
const NavigationMenu = Primitive.Root;
|
|
10
|
+
|
|
11
|
+
const NavigationMenuList = Primitive.List;
|
|
12
|
+
|
|
13
|
+
const NavigationMenuItem = React.forwardRef<
|
|
14
|
+
React.ComponentRef<typeof Primitive.NavigationMenuItem>,
|
|
15
|
+
React.ComponentPropsWithoutRef<typeof Primitive.NavigationMenuItem>
|
|
16
|
+
>(({ className, children, ...props }, ref) => (
|
|
17
|
+
<Primitive.NavigationMenuItem
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={cn('list-none', className)}
|
|
20
|
+
{...props}
|
|
21
|
+
>
|
|
22
|
+
{children}
|
|
23
|
+
</Primitive.NavigationMenuItem>
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
NavigationMenuItem.displayName = Primitive.NavigationMenuItem.displayName;
|
|
27
|
+
|
|
28
|
+
const NavigationMenuTrigger = React.forwardRef<
|
|
29
|
+
React.ComponentRef<typeof Primitive.Trigger>,
|
|
30
|
+
React.ComponentPropsWithoutRef<typeof Primitive.Trigger>
|
|
31
|
+
>(({ className, children, ...props }, ref) => (
|
|
32
|
+
<Primitive.Trigger
|
|
33
|
+
ref={ref}
|
|
34
|
+
className={cn('data-[state=open]:bg-fd-accent/50', className)}
|
|
35
|
+
{...props}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
</Primitive.Trigger>
|
|
39
|
+
));
|
|
40
|
+
NavigationMenuTrigger.displayName = Primitive.Trigger.displayName;
|
|
41
|
+
|
|
42
|
+
const NavigationMenuContent = React.forwardRef<
|
|
43
|
+
React.ComponentRef<typeof Primitive.Content>,
|
|
44
|
+
React.ComponentPropsWithoutRef<typeof Primitive.Content>
|
|
45
|
+
>(({ className, ...props }, ref) => (
|
|
46
|
+
<Primitive.Content
|
|
47
|
+
ref={ref}
|
|
48
|
+
className={cn(
|
|
49
|
+
'absolute inset-x-0 top-0 overflow-auto fd-scroll-container max-h-[80svh] data-[motion=from-end]:animate-fd-enterFromRight data-[motion=from-start]:animate-fd-enterFromLeft data-[motion=to-end]:animate-fd-exitToRight data-[motion=to-start]:animate-fd-exitToLeft',
|
|
50
|
+
className,
|
|
51
|
+
)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
));
|
|
55
|
+
NavigationMenuContent.displayName = Primitive.Content.displayName;
|
|
56
|
+
|
|
57
|
+
const NavigationMenuLink = Primitive.Link;
|
|
58
|
+
|
|
59
|
+
const NavigationMenuViewport = React.forwardRef<
|
|
60
|
+
React.ComponentRef<typeof Primitive.Viewport>,
|
|
61
|
+
React.ComponentPropsWithoutRef<typeof Primitive.Viewport>
|
|
62
|
+
>(({ className, ...props }, ref) => (
|
|
63
|
+
<div ref={ref} className="flex w-full justify-center">
|
|
64
|
+
<Primitive.Viewport
|
|
65
|
+
{...props}
|
|
66
|
+
className={cn(
|
|
67
|
+
'relative h-(--radix-navigation-menu-viewport-height) w-full origin-[top_center] overflow-hidden transition-[width,height] duration-300 data-[state=closed]:animate-fd-nav-menu-out data-[state=open]:animate-fd-nav-menu-in',
|
|
68
|
+
className,
|
|
69
|
+
)}
|
|
70
|
+
/>
|
|
71
|
+
</div>
|
|
72
|
+
));
|
|
73
|
+
NavigationMenuViewport.displayName = Primitive.Viewport.displayName;
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
NavigationMenu,
|
|
77
|
+
NavigationMenuList,
|
|
78
|
+
NavigationMenuItem,
|
|
79
|
+
NavigationMenuContent,
|
|
80
|
+
NavigationMenuTrigger,
|
|
81
|
+
NavigationMenuLink,
|
|
82
|
+
NavigationMenuViewport,
|
|
83
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { cn } from '@/utils/cn';
|
|
5
|
+
|
|
6
|
+
const Popover = PopoverPrimitive.Root;
|
|
7
|
+
|
|
8
|
+
const PopoverTrigger = PopoverPrimitive.Trigger;
|
|
9
|
+
|
|
10
|
+
const PopoverContent = React.forwardRef<
|
|
11
|
+
React.ComponentRef<typeof PopoverPrimitive.Content>,
|
|
12
|
+
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
|
13
|
+
>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (
|
|
14
|
+
<PopoverPrimitive.Portal>
|
|
15
|
+
<PopoverPrimitive.Content
|
|
16
|
+
ref={ref}
|
|
17
|
+
align={align}
|
|
18
|
+
sideOffset={sideOffset}
|
|
19
|
+
side="bottom"
|
|
20
|
+
className={cn(
|
|
21
|
+
'z-50 origin-(--radix-popover-content-transform-origin) overflow-y-auto max-h-(--radix-popover-content-available-height) min-w-[240px] max-w-[98vw] rounded-xl border bg-fd-popover/60 backdrop-blur-lg p-2 text-sm text-fd-popover-foreground shadow-lg focus-visible:outline-none data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in',
|
|
22
|
+
className,
|
|
23
|
+
)}
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
</PopoverPrimitive.Portal>
|
|
27
|
+
));
|
|
28
|
+
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
|
29
|
+
|
|
30
|
+
const PopoverClose = PopoverPrimitive.PopoverClose;
|
|
31
|
+
|
|
32
|
+
export { Popover, PopoverTrigger, PopoverContent, PopoverClose };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as Primitive from '@radix-ui/react-scroll-area';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { cn } from '@/utils/cn';
|
|
4
|
+
|
|
5
|
+
const ScrollArea = React.forwardRef<
|
|
6
|
+
React.ComponentRef<typeof Primitive.Root>,
|
|
7
|
+
React.ComponentPropsWithoutRef<typeof Primitive.Root>
|
|
8
|
+
>(({ className, children, ...props }, ref) => (
|
|
9
|
+
<Primitive.Root
|
|
10
|
+
ref={ref}
|
|
11
|
+
type="scroll"
|
|
12
|
+
className={cn('overflow-hidden', className)}
|
|
13
|
+
{...props}
|
|
14
|
+
>
|
|
15
|
+
{children}
|
|
16
|
+
<Primitive.Corner />
|
|
17
|
+
<ScrollBar orientation="vertical" />
|
|
18
|
+
</Primitive.Root>
|
|
19
|
+
));
|
|
20
|
+
|
|
21
|
+
ScrollArea.displayName = Primitive.Root.displayName;
|
|
22
|
+
|
|
23
|
+
const ScrollViewport = React.forwardRef<
|
|
24
|
+
React.ComponentRef<typeof Primitive.Viewport>,
|
|
25
|
+
React.ComponentPropsWithoutRef<typeof Primitive.Viewport>
|
|
26
|
+
>(({ className, children, ...props }, ref) => (
|
|
27
|
+
<Primitive.Viewport
|
|
28
|
+
ref={ref}
|
|
29
|
+
className={cn('size-full rounded-[inherit]', className)}
|
|
30
|
+
{...props}
|
|
31
|
+
>
|
|
32
|
+
{children}
|
|
33
|
+
</Primitive.Viewport>
|
|
34
|
+
));
|
|
35
|
+
|
|
36
|
+
ScrollViewport.displayName = Primitive.Viewport.displayName;
|
|
37
|
+
|
|
38
|
+
const ScrollBar = React.forwardRef<
|
|
39
|
+
React.ComponentRef<typeof Primitive.Scrollbar>,
|
|
40
|
+
React.ComponentPropsWithoutRef<typeof Primitive.Scrollbar>
|
|
41
|
+
>(({ className, orientation = 'vertical', ...props }, ref) => (
|
|
42
|
+
<Primitive.Scrollbar
|
|
43
|
+
ref={ref}
|
|
44
|
+
orientation={orientation}
|
|
45
|
+
className={cn(
|
|
46
|
+
'flex select-none data-[state=hidden]:animate-fd-fade-out',
|
|
47
|
+
orientation === 'vertical' && 'h-full w-1.5',
|
|
48
|
+
orientation === 'horizontal' && 'h-1.5 flex-col',
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
>
|
|
53
|
+
<Primitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-fd-border" />
|
|
54
|
+
</Primitive.Scrollbar>
|
|
55
|
+
));
|
|
56
|
+
ScrollBar.displayName = Primitive.Scrollbar.displayName;
|
|
57
|
+
|
|
58
|
+
export { ScrollArea, ScrollBar, ScrollViewport };
|
|
59
|
+
export type ScrollAreaProps = Primitive.ScrollAreaProps;
|