@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,251 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
import { cn } from '@/utils/cn';
|
|
3
|
+
import { buttonVariants } from '@/components/ui/button';
|
|
4
|
+
import { Edit, Text } from '@icons';
|
|
5
|
+
import { I18nLabel } from '@/contexts/i18n';
|
|
6
|
+
import {
|
|
7
|
+
type BreadcrumbProps,
|
|
8
|
+
type FooterProps,
|
|
9
|
+
PageBreadcrumb,
|
|
10
|
+
PageFooter,
|
|
11
|
+
PageTOCPopover,
|
|
12
|
+
PageTOCPopoverContent,
|
|
13
|
+
PageTOCPopoverTrigger,
|
|
14
|
+
} from './client';
|
|
15
|
+
import type { AnchorProviderProps, TOCItemType } from '@hanzo/docs-core/toc';
|
|
16
|
+
import * as TocDefault from '@/components/toc/default';
|
|
17
|
+
import * as TocClerk from '@/components/toc/clerk';
|
|
18
|
+
import { TOCProvider, TOCScrollArea } from '@/components/toc';
|
|
19
|
+
|
|
20
|
+
interface BreadcrumbOptions extends BreadcrumbProps {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
component: ReactNode;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface FooterOptions extends FooterProps {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
component: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface DocsPageProps {
|
|
31
|
+
toc?: TOCItemType[];
|
|
32
|
+
tableOfContent?: Partial<TableOfContentOptions>;
|
|
33
|
+
tableOfContentPopover?: Partial<TableOfContentPopoverOptions>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Extend the page to fill all available space
|
|
37
|
+
*
|
|
38
|
+
* @defaultValue false
|
|
39
|
+
*/
|
|
40
|
+
full?: boolean;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Replace or disable breadcrumb
|
|
44
|
+
*/
|
|
45
|
+
breadcrumb?: Partial<BreadcrumbOptions>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Footer navigation, you can disable it by passing `false`
|
|
49
|
+
*/
|
|
50
|
+
footer?: Partial<FooterOptions>;
|
|
51
|
+
|
|
52
|
+
children?: ReactNode;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
type TableOfContentOptions = Pick<AnchorProviderProps, 'single'> & {
|
|
56
|
+
/**
|
|
57
|
+
* Custom content in TOC container, before the main TOC
|
|
58
|
+
*/
|
|
59
|
+
header?: ReactNode;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Custom content in TOC container, after the main TOC
|
|
63
|
+
*/
|
|
64
|
+
footer?: ReactNode;
|
|
65
|
+
|
|
66
|
+
enabled: boolean;
|
|
67
|
+
component: ReactNode;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @defaultValue 'normal'
|
|
71
|
+
*/
|
|
72
|
+
style?: 'normal' | 'clerk';
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type TableOfContentPopoverOptions = Omit<TableOfContentOptions, 'single'>;
|
|
76
|
+
|
|
77
|
+
export function DocsPage({
|
|
78
|
+
breadcrumb: {
|
|
79
|
+
enabled: breadcrumbEnabled = true,
|
|
80
|
+
component: breadcrumb,
|
|
81
|
+
...breadcrumbProps
|
|
82
|
+
} = {},
|
|
83
|
+
footer = {},
|
|
84
|
+
full = false,
|
|
85
|
+
tableOfContentPopover: {
|
|
86
|
+
enabled: tocPopoverEnabled,
|
|
87
|
+
component: tocPopover,
|
|
88
|
+
...tocPopoverOptions
|
|
89
|
+
} = {},
|
|
90
|
+
tableOfContent: {
|
|
91
|
+
enabled: tocEnabled,
|
|
92
|
+
component: tocReplace,
|
|
93
|
+
...tocOptions
|
|
94
|
+
} = {},
|
|
95
|
+
toc = [],
|
|
96
|
+
children,
|
|
97
|
+
}: DocsPageProps) {
|
|
98
|
+
// disable TOC on full mode, you can still enable it with `enabled` option.
|
|
99
|
+
tocEnabled ??=
|
|
100
|
+
!full &&
|
|
101
|
+
(toc.length > 0 ||
|
|
102
|
+
tocOptions.footer !== undefined ||
|
|
103
|
+
tocOptions.header !== undefined);
|
|
104
|
+
|
|
105
|
+
tocPopoverEnabled ??=
|
|
106
|
+
toc.length > 0 ||
|
|
107
|
+
tocPopoverOptions.header !== undefined ||
|
|
108
|
+
tocPopoverOptions.footer !== undefined;
|
|
109
|
+
|
|
110
|
+
let wrapper = (children: ReactNode) => children;
|
|
111
|
+
|
|
112
|
+
if (tocEnabled || tocPopoverEnabled) {
|
|
113
|
+
wrapper = (children) => (
|
|
114
|
+
<TOCProvider single={tocOptions.single} toc={toc}>
|
|
115
|
+
{children}
|
|
116
|
+
</TOCProvider>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return wrapper(
|
|
121
|
+
<>
|
|
122
|
+
{tocPopoverEnabled &&
|
|
123
|
+
(tocPopover ?? (
|
|
124
|
+
<PageTOCPopover>
|
|
125
|
+
<PageTOCPopoverTrigger />
|
|
126
|
+
<PageTOCPopoverContent>
|
|
127
|
+
{tocPopoverOptions.header}
|
|
128
|
+
<TOCScrollArea>
|
|
129
|
+
{tocPopoverOptions.style === 'clerk' ? (
|
|
130
|
+
<TocClerk.TOCItems />
|
|
131
|
+
) : (
|
|
132
|
+
<TocDefault.TOCItems />
|
|
133
|
+
)}
|
|
134
|
+
</TOCScrollArea>
|
|
135
|
+
{tocPopoverOptions.footer}
|
|
136
|
+
</PageTOCPopoverContent>
|
|
137
|
+
</PageTOCPopover>
|
|
138
|
+
))}
|
|
139
|
+
<article
|
|
140
|
+
id="nd-page"
|
|
141
|
+
data-full={full}
|
|
142
|
+
className={cn(
|
|
143
|
+
'flex flex-col w-full max-w-[900px] mx-auto [grid-area:main] px-4 py-6 gap-4 md:px-6 md:pt-8 xl:px-8 xl:pt-14',
|
|
144
|
+
full ? 'max-w-[1200px]' : 'xl:layout:[--fd-toc-width:268px]',
|
|
145
|
+
)}
|
|
146
|
+
>
|
|
147
|
+
{breadcrumbEnabled &&
|
|
148
|
+
(breadcrumb ?? <PageBreadcrumb {...breadcrumbProps} />)}
|
|
149
|
+
{children}
|
|
150
|
+
{footer.enabled !== false &&
|
|
151
|
+
(footer.component ?? <PageFooter items={footer.items} />)}
|
|
152
|
+
</article>
|
|
153
|
+
{tocEnabled &&
|
|
154
|
+
(tocReplace ?? (
|
|
155
|
+
<div
|
|
156
|
+
id="nd-toc"
|
|
157
|
+
className="sticky top-(--fd-docs-row-1) h-[calc(var(--fd-docs-height)-var(--fd-docs-row-1))] flex flex-col [grid-area:toc] w-(--fd-toc-width) pt-12 pe-4 pb-2 max-xl:hidden"
|
|
158
|
+
>
|
|
159
|
+
{tocOptions.header}
|
|
160
|
+
<h3
|
|
161
|
+
id="toc-title"
|
|
162
|
+
className="inline-flex items-center gap-1.5 text-sm text-fd-muted-foreground"
|
|
163
|
+
>
|
|
164
|
+
<Text className="size-4" />
|
|
165
|
+
<I18nLabel label="toc" />
|
|
166
|
+
</h3>
|
|
167
|
+
<TOCScrollArea>
|
|
168
|
+
{tocOptions.style === 'clerk' ? (
|
|
169
|
+
<TocClerk.TOCItems />
|
|
170
|
+
) : (
|
|
171
|
+
<TocDefault.TOCItems />
|
|
172
|
+
)}
|
|
173
|
+
</TOCScrollArea>
|
|
174
|
+
{tocOptions.footer}
|
|
175
|
+
</div>
|
|
176
|
+
))}
|
|
177
|
+
</>,
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function EditOnGitHub(props: ComponentProps<'a'>) {
|
|
182
|
+
return (
|
|
183
|
+
<a
|
|
184
|
+
target="_blank"
|
|
185
|
+
rel="noreferrer noopener"
|
|
186
|
+
{...props}
|
|
187
|
+
className={cn(
|
|
188
|
+
buttonVariants({
|
|
189
|
+
color: 'secondary',
|
|
190
|
+
size: 'sm',
|
|
191
|
+
className: 'gap-1.5 not-prose',
|
|
192
|
+
}),
|
|
193
|
+
props.className,
|
|
194
|
+
)}
|
|
195
|
+
>
|
|
196
|
+
{props.children ?? (
|
|
197
|
+
<>
|
|
198
|
+
<Edit className="size-3.5" />
|
|
199
|
+
<I18nLabel label="editOnGithub" />
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
</a>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Add typography styles
|
|
208
|
+
*/
|
|
209
|
+
export function DocsBody({
|
|
210
|
+
children,
|
|
211
|
+
className,
|
|
212
|
+
...props
|
|
213
|
+
}: ComponentProps<'div'>) {
|
|
214
|
+
return (
|
|
215
|
+
<div {...props} className={cn('prose flex-1', className)}>
|
|
216
|
+
{children}
|
|
217
|
+
</div>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function DocsDescription({
|
|
222
|
+
children,
|
|
223
|
+
className,
|
|
224
|
+
...props
|
|
225
|
+
}: ComponentProps<'p'>) {
|
|
226
|
+
// Don't render if no description provided
|
|
227
|
+
if (children === undefined) return null;
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<p
|
|
231
|
+
{...props}
|
|
232
|
+
className={cn('mb-8 text-lg text-fd-muted-foreground', className)}
|
|
233
|
+
>
|
|
234
|
+
{children}
|
|
235
|
+
</p>
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export function DocsTitle({
|
|
240
|
+
children,
|
|
241
|
+
className,
|
|
242
|
+
...props
|
|
243
|
+
}: ComponentProps<'h1'>) {
|
|
244
|
+
return (
|
|
245
|
+
<h1 {...props} className={cn('text-[1.75em] font-semibold', className)}>
|
|
246
|
+
{children}
|
|
247
|
+
</h1>
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export { PageLastUpdate, PageBreadcrumb } from './client';
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as Base from '@/components/sidebar/base';
|
|
3
|
+
import { cn } from '@/utils/cn';
|
|
4
|
+
import { type ComponentProps, useRef } from 'react';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { createPageTreeRenderer } from '@/components/sidebar/page-tree';
|
|
7
|
+
import { createLinkItemRenderer } from '@/components/sidebar/link-item';
|
|
8
|
+
import { buttonVariants } from '@/components/ui/button';
|
|
9
|
+
import { SearchToggle } from '@/layouts/shared/search-toggle';
|
|
10
|
+
import { Sidebar as SidebarIcon } from '@icons';
|
|
11
|
+
import { mergeRefs } from '@/utils/merge-refs';
|
|
12
|
+
|
|
13
|
+
const itemVariants = cva(
|
|
14
|
+
'relative flex flex-row items-center gap-2 rounded-lg p-2 text-start text-fd-muted-foreground wrap-anywhere [&_svg]:size-4 [&_svg]:shrink-0',
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
link: 'transition-colors hover:bg-fd-accent/50 hover:text-fd-accent-foreground/80 hover:transition-none data-[active=true]:bg-fd-primary/10 data-[active=true]:text-fd-primary data-[active=true]:hover:transition-colors',
|
|
19
|
+
button:
|
|
20
|
+
'transition-colors hover:bg-fd-accent/50 hover:text-fd-accent-foreground/80 hover:transition-none',
|
|
21
|
+
},
|
|
22
|
+
highlight: {
|
|
23
|
+
true: "data-[active=true]:before:content-[''] data-[active=true]:before:bg-fd-primary data-[active=true]:before:absolute data-[active=true]:before:w-px data-[active=true]:before:inset-y-2.5 data-[active=true]:before:start-2.5",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
function getItemOffset(depth: number) {
|
|
30
|
+
return `calc(${2 + 3 * depth} * var(--spacing))`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Explicit exports instead of destructured re-exports for webpack compatibility
|
|
34
|
+
export const Sidebar = Base.SidebarProvider;
|
|
35
|
+
export const SidebarFolder = Base.SidebarFolder;
|
|
36
|
+
export const SidebarCollapseTrigger = Base.SidebarCollapseTrigger;
|
|
37
|
+
export const SidebarViewport = Base.SidebarViewport;
|
|
38
|
+
export const SidebarTrigger = Base.SidebarTrigger;
|
|
39
|
+
|
|
40
|
+
export function SidebarContent({
|
|
41
|
+
ref: refProp,
|
|
42
|
+
className,
|
|
43
|
+
children,
|
|
44
|
+
...props
|
|
45
|
+
}: ComponentProps<'aside'>) {
|
|
46
|
+
const ref = useRef<HTMLElement>(null);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Base.SidebarContent>
|
|
50
|
+
{({ collapsed, hovered, ref: asideRef, ...rest }) => (
|
|
51
|
+
<>
|
|
52
|
+
<div
|
|
53
|
+
data-sidebar-placeholder=""
|
|
54
|
+
className="sticky top-(--fd-docs-row-1) z-20 [grid-area:sidebar] pointer-events-none *:pointer-events-auto h-[calc(var(--fd-docs-height)-var(--fd-docs-row-1))] md:layout:[--fd-sidebar-width:268px] max-md:hidden"
|
|
55
|
+
>
|
|
56
|
+
{collapsed && (
|
|
57
|
+
<div className="absolute start-0 inset-y-0 w-4" {...rest} />
|
|
58
|
+
)}
|
|
59
|
+
<aside
|
|
60
|
+
id="nd-sidebar"
|
|
61
|
+
ref={mergeRefs(ref, refProp, asideRef)}
|
|
62
|
+
data-collapsed={collapsed}
|
|
63
|
+
data-hovered={collapsed && hovered}
|
|
64
|
+
className={cn(
|
|
65
|
+
'absolute flex flex-col w-full start-0 inset-y-0 items-end bg-fd-card text-sm border-e duration-250 *:w-(--fd-sidebar-width)',
|
|
66
|
+
collapsed && [
|
|
67
|
+
'inset-y-2 rounded-xl transition-transform border w-(--fd-sidebar-width)',
|
|
68
|
+
hovered
|
|
69
|
+
? 'shadow-lg translate-x-2 rtl:-translate-x-2'
|
|
70
|
+
: '-translate-x-(--fd-sidebar-width) rtl:translate-x-full',
|
|
71
|
+
],
|
|
72
|
+
ref.current &&
|
|
73
|
+
(ref.current.getAttribute('data-collapsed') === 'true') !==
|
|
74
|
+
collapsed &&
|
|
75
|
+
'transition-[width,inset-block,translate,background-color]',
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
78
|
+
{...props}
|
|
79
|
+
{...rest}
|
|
80
|
+
>
|
|
81
|
+
{children}
|
|
82
|
+
</aside>
|
|
83
|
+
</div>
|
|
84
|
+
<div
|
|
85
|
+
data-sidebar-panel=""
|
|
86
|
+
className={cn(
|
|
87
|
+
'fixed flex top-[calc(--spacing(4)+var(--fd-toc-popover-height))] start-4 shadow-lg transition-opacity rounded-xl p-0.5 border bg-fd-muted text-fd-muted-foreground z-10',
|
|
88
|
+
(!collapsed || hovered) && 'pointer-events-none opacity-0',
|
|
89
|
+
)}
|
|
90
|
+
>
|
|
91
|
+
<SidebarCollapseTrigger
|
|
92
|
+
className={cn(
|
|
93
|
+
buttonVariants({
|
|
94
|
+
color: 'ghost',
|
|
95
|
+
size: 'icon-sm',
|
|
96
|
+
className: 'rounded-lg',
|
|
97
|
+
}),
|
|
98
|
+
)}
|
|
99
|
+
>
|
|
100
|
+
<SidebarIcon />
|
|
101
|
+
</SidebarCollapseTrigger>
|
|
102
|
+
<SearchToggle className="rounded-lg" hideIfDisabled />
|
|
103
|
+
</div>
|
|
104
|
+
</>
|
|
105
|
+
)}
|
|
106
|
+
</Base.SidebarContent>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function SidebarDrawer({
|
|
111
|
+
children,
|
|
112
|
+
className,
|
|
113
|
+
...props
|
|
114
|
+
}: ComponentProps<typeof Base.SidebarDrawerContent>) {
|
|
115
|
+
return (
|
|
116
|
+
<>
|
|
117
|
+
<Base.SidebarDrawerOverlay className="fixed z-40 inset-0 backdrop-blur-xs data-[state=open]:animate-fd-fade-in data-[state=closed]:animate-fd-fade-out" />
|
|
118
|
+
<Base.SidebarDrawerContent
|
|
119
|
+
className={cn(
|
|
120
|
+
'fixed text-[0.9375rem] flex flex-col shadow-lg border-s end-0 inset-y-0 w-[85%] max-w-[380px] z-40 bg-fd-background data-[state=open]:animate-fd-sidebar-in data-[state=closed]:animate-fd-sidebar-out',
|
|
121
|
+
className,
|
|
122
|
+
)}
|
|
123
|
+
{...props}
|
|
124
|
+
>
|
|
125
|
+
{children}
|
|
126
|
+
</Base.SidebarDrawerContent>
|
|
127
|
+
</>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function SidebarSeparator({
|
|
132
|
+
className,
|
|
133
|
+
style,
|
|
134
|
+
children,
|
|
135
|
+
...props
|
|
136
|
+
}: ComponentProps<'p'>) {
|
|
137
|
+
const depth = Base.useFolderDepth();
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<Base.SidebarSeparator
|
|
141
|
+
className={cn('[&_svg]:size-4 [&_svg]:shrink-0', className)}
|
|
142
|
+
style={{
|
|
143
|
+
paddingInlineStart: getItemOffset(depth),
|
|
144
|
+
...style,
|
|
145
|
+
}}
|
|
146
|
+
{...props}
|
|
147
|
+
>
|
|
148
|
+
{children}
|
|
149
|
+
</Base.SidebarSeparator>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function SidebarItem({
|
|
154
|
+
className,
|
|
155
|
+
style,
|
|
156
|
+
children,
|
|
157
|
+
...props
|
|
158
|
+
}: ComponentProps<typeof Base.SidebarItem>) {
|
|
159
|
+
const depth = Base.useFolderDepth();
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<Base.SidebarItem
|
|
163
|
+
className={cn(
|
|
164
|
+
itemVariants({ variant: 'link', highlight: depth >= 1 }),
|
|
165
|
+
className,
|
|
166
|
+
)}
|
|
167
|
+
style={{
|
|
168
|
+
paddingInlineStart: getItemOffset(depth),
|
|
169
|
+
...style,
|
|
170
|
+
}}
|
|
171
|
+
{...props}
|
|
172
|
+
>
|
|
173
|
+
{children}
|
|
174
|
+
</Base.SidebarItem>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function SidebarFolderTrigger({
|
|
179
|
+
className,
|
|
180
|
+
style,
|
|
181
|
+
...props
|
|
182
|
+
}: ComponentProps<typeof Base.SidebarFolderTrigger>) {
|
|
183
|
+
const { depth, collapsible } = Base.useFolder()!;
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<Base.SidebarFolderTrigger
|
|
187
|
+
className={cn(
|
|
188
|
+
itemVariants({ variant: collapsible ? 'button' : null }),
|
|
189
|
+
'w-full',
|
|
190
|
+
className,
|
|
191
|
+
)}
|
|
192
|
+
style={{
|
|
193
|
+
paddingInlineStart: getItemOffset(depth - 1),
|
|
194
|
+
...style,
|
|
195
|
+
}}
|
|
196
|
+
{...props}
|
|
197
|
+
>
|
|
198
|
+
{props.children}
|
|
199
|
+
</Base.SidebarFolderTrigger>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function SidebarFolderLink({
|
|
204
|
+
className,
|
|
205
|
+
style,
|
|
206
|
+
...props
|
|
207
|
+
}: ComponentProps<typeof Base.SidebarFolderLink>) {
|
|
208
|
+
const depth = Base.useFolderDepth();
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<Base.SidebarFolderLink
|
|
212
|
+
className={cn(
|
|
213
|
+
itemVariants({ variant: 'link', highlight: depth > 1 }),
|
|
214
|
+
'w-full',
|
|
215
|
+
className,
|
|
216
|
+
)}
|
|
217
|
+
style={{
|
|
218
|
+
paddingInlineStart: getItemOffset(depth - 1),
|
|
219
|
+
...style,
|
|
220
|
+
}}
|
|
221
|
+
{...props}
|
|
222
|
+
>
|
|
223
|
+
{props.children}
|
|
224
|
+
</Base.SidebarFolderLink>
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function SidebarFolderContent({
|
|
229
|
+
className,
|
|
230
|
+
children,
|
|
231
|
+
...props
|
|
232
|
+
}: ComponentProps<typeof Base.SidebarFolderContent>) {
|
|
233
|
+
const depth = Base.useFolderDepth();
|
|
234
|
+
|
|
235
|
+
return (
|
|
236
|
+
<Base.SidebarFolderContent
|
|
237
|
+
className={cn(
|
|
238
|
+
'relative',
|
|
239
|
+
depth === 1 &&
|
|
240
|
+
"before:content-[''] before:absolute before:w-px before:inset-y-1 before:bg-fd-border before:start-2.5",
|
|
241
|
+
className,
|
|
242
|
+
)}
|
|
243
|
+
{...props}
|
|
244
|
+
>
|
|
245
|
+
{children}
|
|
246
|
+
</Base.SidebarFolderContent>
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export const SidebarPageTree = createPageTreeRenderer({
|
|
251
|
+
SidebarFolder,
|
|
252
|
+
SidebarFolderContent,
|
|
253
|
+
SidebarFolderLink,
|
|
254
|
+
SidebarFolderTrigger,
|
|
255
|
+
SidebarItem,
|
|
256
|
+
SidebarSeparator,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
export const SidebarLinkItem = createLinkItemRenderer({
|
|
260
|
+
SidebarFolder,
|
|
261
|
+
SidebarFolderContent,
|
|
262
|
+
SidebarFolderLink,
|
|
263
|
+
SidebarFolderTrigger,
|
|
264
|
+
SidebarItem,
|
|
265
|
+
});
|