@hanzo/radix 16.3.1
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/README.md +5 -0
- package/css/black.css +1 -0
- package/css/catppuccin.css +1 -0
- package/css/dusk.css +1 -0
- package/css/layouts/docs.css +1 -0
- package/css/layouts/home.css +1 -0
- package/css/layouts/notebook.css +1 -0
- package/css/neutral.css +1 -0
- package/css/ocean.css +1 -0
- package/css/preset.css +91 -0
- package/css/purple.css +1 -0
- package/css/shadcn.css +1 -0
- package/css/solar.css +1 -0
- package/css/style.css +9 -0
- package/css/vitepress.css +1 -0
- package/dist/components/accordion.d.ts +8 -0
- package/dist/components/accordion.d.ts.map +1 -0
- package/dist/components/accordion.js +43 -0
- package/dist/components/banner.d.ts +24 -0
- package/dist/components/banner.d.ts.map +1 -0
- package/dist/components/banner.js +54 -0
- package/dist/components/callout.d.ts +19 -0
- package/dist/components/callout.d.ts.map +1 -0
- package/dist/components/callout.js +34 -0
- package/dist/components/card.d.ts +11 -0
- package/dist/components/card.d.ts.map +1 -0
- package/dist/components/card.js +10 -0
- package/dist/components/codeblock.d.ts +42 -0
- package/dist/components/codeblock.d.ts.map +1 -0
- package/dist/components/codeblock.js +68 -0
- package/dist/components/dialog/search-algolia.d.ts +25 -0
- package/dist/components/dialog/search-algolia.d.ts.map +1 -0
- package/dist/components/dialog/search-algolia.js +35 -0
- package/dist/components/dialog/search-default.d.ts +29 -0
- package/dist/components/dialog/search-default.d.ts.map +1 -0
- package/dist/components/dialog/search-default.js +40 -0
- package/dist/components/dialog/search-orama.d.ts +30 -0
- package/dist/components/dialog/search-orama.d.ts.map +1 -0
- package/dist/components/dialog/search-orama.js +40 -0
- package/dist/components/dialog/search.d.ts +72 -0
- package/dist/components/dialog/search.d.ts.map +1 -0
- package/dist/components/dialog/search.js +192 -0
- package/dist/components/dynamic-codeblock.d.ts +21 -0
- package/dist/components/dynamic-codeblock.d.ts.map +1 -0
- package/dist/components/dynamic-codeblock.js +33 -0
- package/dist/components/files.d.ts +19 -0
- package/dist/components/files.d.ts.map +1 -0
- package/dist/components/files.js +18 -0
- package/dist/components/github-info.d.ts +8 -0
- package/dist/components/github-info.d.ts.map +1 -0
- package/dist/components/github-info.js +53 -0
- package/dist/components/heading.d.ts +8 -0
- package/dist/components/heading.d.ts.map +1 -0
- package/dist/components/heading.js +9 -0
- package/dist/components/image-zoom.css +77 -0
- package/dist/components/image-zoom.d.ts +16 -0
- package/dist/components/image-zoom.d.ts.map +1 -0
- package/dist/components/image-zoom.js +23 -0
- package/dist/components/inline-toc.d.ts +8 -0
- package/dist/components/inline-toc.d.ts.map +1 -0
- package/dist/components/inline-toc.js +10 -0
- package/dist/components/sidebar/base.d.ts +72 -0
- package/dist/components/sidebar/base.d.ts.map +1 -0
- package/dist/components/sidebar/base.js +186 -0
- package/dist/components/sidebar/link-item.d.ts +11 -0
- package/dist/components/sidebar/link-item.d.ts.map +1 -0
- package/dist/components/sidebar/link-item.js +13 -0
- package/dist/components/sidebar/page-tree.d.ts +19 -0
- package/dist/components/sidebar/page-tree.d.ts.map +1 -0
- package/dist/components/sidebar/page-tree.js +34 -0
- package/dist/components/sidebar/tabs/dropdown.d.ts +11 -0
- package/dist/components/sidebar/tabs/dropdown.d.ts.map +1 -0
- package/dist/components/sidebar/tabs/dropdown.js +34 -0
- package/dist/components/sidebar/tabs/index.d.ts +21 -0
- package/dist/components/sidebar/tabs/index.d.ts.map +1 -0
- package/dist/components/sidebar/tabs/index.js +49 -0
- package/dist/components/steps.d.ts +8 -0
- package/dist/components/steps.d.ts.map +1 -0
- package/dist/components/steps.js +7 -0
- package/dist/components/tabs.d.ts +31 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/tabs.js +64 -0
- package/dist/components/toc/clerk.d.ts +2 -0
- package/dist/components/toc/clerk.d.ts.map +1 -0
- package/dist/components/toc/clerk.js +1 -0
- package/dist/components/toc/default.d.ts +2 -0
- package/dist/components/toc/default.d.ts.map +1 -0
- package/dist/components/toc/default.js +1 -0
- package/dist/components/toc/index.d.ts +2 -0
- package/dist/components/toc/index.d.ts.map +1 -0
- package/dist/components/toc/index.js +1 -0
- package/dist/components/type-table.d.ts +32 -0
- package/dist/components/type-table.d.ts.map +1 -0
- package/dist/components/type-table.js +28 -0
- package/dist/components/ui/accordion.d.ts +8 -0
- package/dist/components/ui/accordion.d.ts.map +1 -0
- package/dist/components/ui/accordion.js +20 -0
- package/dist/components/ui/button.d.ts +8 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +20 -0
- package/dist/components/ui/collapsible.d.ts +9 -0
- package/dist/components/ui/collapsible.d.ts.map +1 -0
- package/dist/components/ui/collapsible.js +17 -0
- package/dist/components/ui/navigation-menu.d.ts +13 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.js +17 -0
- package/dist/components/ui/popover.d.ts +8 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +11 -0
- package/dist/components/ui/scroll-area.d.ts +8 -0
- package/dist/components/ui/scroll-area.d.ts.map +1 -0
- package/dist/components/ui/scroll-area.js +11 -0
- package/dist/components/ui/tabs.d.ts +21 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/tabs.js +79 -0
- package/dist/contexts/i18n.d.ts +2 -0
- package/dist/contexts/i18n.d.ts.map +1 -0
- package/dist/contexts/i18n.js +2 -0
- package/dist/contexts/search.d.ts +2 -0
- package/dist/contexts/search.d.ts.map +1 -0
- package/dist/contexts/search.js +2 -0
- package/dist/contexts/tree.d.ts +2 -0
- package/dist/contexts/tree.d.ts.map +1 -0
- package/dist/contexts/tree.js +2 -0
- package/dist/i18n.d.ts +2 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +1 -0
- package/dist/layouts/docs/client.d.ts +15 -0
- package/dist/layouts/docs/client.d.ts.map +1 -0
- package/dist/layouts/docs/client.js +41 -0
- package/dist/layouts/docs/index.d.ts +36 -0
- package/dist/layouts/docs/index.d.ts.map +1 -0
- package/dist/layouts/docs/index.js +69 -0
- package/dist/layouts/docs/page/client.d.ts +24 -0
- package/dist/layouts/docs/page/client.d.ts.map +1 -0
- package/dist/layouts/docs/page/client.js +119 -0
- package/dist/layouts/docs/page/index.d.ts +58 -0
- package/dist/layouts/docs/page/index.d.ts.map +1 -0
- package/dist/layouts/docs/page/index.js +51 -0
- package/dist/layouts/docs/sidebar.d.ts +17 -0
- package/dist/layouts/docs/sidebar.d.ts.map +1 -0
- package/dist/layouts/docs/sidebar.js +94 -0
- package/dist/layouts/home/client.d.ts +6 -0
- package/dist/layouts/home/client.d.ts.map +1 -0
- package/dist/layouts/home/client.js +113 -0
- package/dist/layouts/home/index.d.ts +12 -0
- package/dist/layouts/home/index.d.ts.map +1 -0
- package/dist/layouts/home/index.js +8 -0
- package/dist/layouts/home/navbar.d.ts +7 -0
- package/dist/layouts/home/navbar.d.ts.map +1 -0
- package/dist/layouts/home/navbar.js +16 -0
- package/dist/layouts/notebook/client.d.ts +23 -0
- package/dist/layouts/notebook/client.d.ts.map +1 -0
- package/dist/layouts/notebook/client.js +104 -0
- package/dist/layouts/notebook/index.d.ts +34 -0
- package/dist/layouts/notebook/index.d.ts.map +1 -0
- package/dist/layouts/notebook/index.js +92 -0
- package/dist/layouts/notebook/page/client.d.ts +24 -0
- package/dist/layouts/notebook/page/client.d.ts.map +1 -0
- package/dist/layouts/notebook/page/client.js +119 -0
- package/dist/layouts/notebook/page/index.d.ts +58 -0
- package/dist/layouts/notebook/page/index.d.ts.map +1 -0
- package/dist/layouts/notebook/page/index.js +51 -0
- package/dist/layouts/notebook/sidebar.d.ts +17 -0
- package/dist/layouts/notebook/sidebar.d.ts.map +1 -0
- package/dist/layouts/notebook/sidebar.js +91 -0
- package/dist/layouts/shared/index.d.ts +57 -0
- package/dist/layouts/shared/index.d.ts.map +1 -0
- package/dist/layouts/shared/index.js +23 -0
- package/dist/layouts/shared/language-toggle.d.ts +5 -0
- package/dist/layouts/shared/language-toggle.d.ts.map +1 -0
- package/dist/layouts/shared/language-toggle.js +24 -0
- package/dist/layouts/shared/search-toggle.d.ts +11 -0
- package/dist/layouts/shared/search-toggle.d.ts.map +1 -0
- package/dist/layouts/shared/search-toggle.js +27 -0
- package/dist/layouts/shared/theme-toggle.d.ts +5 -0
- package/dist/layouts/shared/theme-toggle.d.ts.map +1 -0
- package/dist/layouts/shared/theme-toggle.js +38 -0
- package/dist/mdx.d.ts +33 -0
- package/dist/mdx.d.ts.map +1 -0
- package/dist/mdx.js +40 -0
- package/dist/mdx.server.d.ts +13 -0
- package/dist/mdx.server.d.ts.map +1 -0
- package/dist/mdx.server.js +15 -0
- package/dist/og.d.ts +2 -0
- package/dist/og.d.ts.map +1 -0
- package/dist/og.js +1 -0
- package/dist/page.d.ts +27 -0
- package/dist/page.d.ts.map +1 -0
- package/dist/page.js +22 -0
- package/dist/provider/base.d.ts +40 -0
- package/dist/provider/base.d.ts.map +1 -0
- package/dist/provider/base.js +19 -0
- package/dist/provider/next.d.ts +14 -0
- package/dist/provider/next.d.ts.map +1 -0
- package/dist/provider/next.js +7 -0
- package/dist/provider/react-router.d.ts +14 -0
- package/dist/provider/react-router.d.ts.map +1 -0
- package/dist/provider/react-router.js +7 -0
- package/dist/provider/tanstack.d.ts +14 -0
- package/dist/provider/tanstack.d.ts.map +1 -0
- package/dist/provider/tanstack.js +7 -0
- package/dist/provider/waku.d.ts +14 -0
- package/dist/provider/waku.d.ts.map +1 -0
- package/dist/provider/waku.js +7 -0
- package/dist/style.css +3246 -0
- package/dist/utils/use-copy-button.d.ts +2 -0
- package/dist/utils/use-copy-button.d.ts.map +1 -0
- package/dist/utils/use-copy-button.js +1 -0
- package/dist/utils/use-footer-items.d.ts +2 -0
- package/dist/utils/use-footer-items.d.ts.map +1 -0
- package/dist/utils/use-footer-items.js +1 -0
- package/dist/utils/use-is-scroll-top.d.ts +2 -0
- package/dist/utils/use-is-scroll-top.d.ts.map +1 -0
- package/dist/utils/use-is-scroll-top.js +1 -0
- package/package.json +155 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Fragment, useMemo, useState } from 'react';
|
|
4
|
+
import { cva } from 'class-variance-authority';
|
|
5
|
+
import Link from '@hanzo/docs/link';
|
|
6
|
+
import { cn } from '@hanzo/ui/cn';
|
|
7
|
+
import { renderTitleNav, resolveLinkItems, } from '../../layouts/shared/index.js';
|
|
8
|
+
import { LinkItem } from '@hanzo/ui/link-item';
|
|
9
|
+
import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, } from '../../components/ui/navigation-menu.js';
|
|
10
|
+
import { buttonVariants } from '../../components/ui/button.js';
|
|
11
|
+
import { LargeSearchToggle, SearchToggle, } from '../../layouts/shared/search-toggle.js';
|
|
12
|
+
import { ThemeToggle } from '../../layouts/shared/theme-toggle.js';
|
|
13
|
+
import { LanguageToggle, LanguageToggleText, } from '../../layouts/shared/language-toggle.js';
|
|
14
|
+
import { ChevronDown, Languages } from '@hanzo/ui/icons';
|
|
15
|
+
import { useIsScrollTop } from '@hanzo/ui/hooks/use-is-scroll-top';
|
|
16
|
+
export const navItemVariants = cva('[&_svg]:size-4', {
|
|
17
|
+
variants: {
|
|
18
|
+
variant: {
|
|
19
|
+
main: 'inline-flex items-center gap-1 p-2 text-fd-muted-foreground transition-colors hover:text-fd-accent-foreground data-[active=true]:text-fd-primary',
|
|
20
|
+
button: buttonVariants({
|
|
21
|
+
color: 'secondary',
|
|
22
|
+
className: 'gap-1.5',
|
|
23
|
+
}),
|
|
24
|
+
icon: buttonVariants({
|
|
25
|
+
color: 'ghost',
|
|
26
|
+
size: 'icon',
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
variant: 'main',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
export function Header({ nav = {}, i18n = false, links, githubUrl, themeSwitch = {}, searchToggle = {}, }) {
|
|
35
|
+
const { navItems, menuItems } = useMemo(() => {
|
|
36
|
+
const navItems = [];
|
|
37
|
+
const menuItems = [];
|
|
38
|
+
for (const item of resolveLinkItems({ links, githubUrl })) {
|
|
39
|
+
switch (item.on ?? 'all') {
|
|
40
|
+
case 'menu':
|
|
41
|
+
menuItems.push(item);
|
|
42
|
+
break;
|
|
43
|
+
case 'nav':
|
|
44
|
+
navItems.push(item);
|
|
45
|
+
break;
|
|
46
|
+
default:
|
|
47
|
+
navItems.push(item);
|
|
48
|
+
menuItems.push(item);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { navItems, menuItems };
|
|
52
|
+
}, [links, githubUrl]);
|
|
53
|
+
return (_jsxs(HeaderNavigationMenu, { transparentMode: nav.transparentMode, children: [renderTitleNav(nav, {
|
|
54
|
+
className: 'inline-flex items-center gap-2.5 font-semibold',
|
|
55
|
+
}), nav.children, _jsx("ul", { className: "flex flex-row items-center gap-2 px-6 max-sm:hidden", children: navItems
|
|
56
|
+
.filter((item) => !isSecondary(item))
|
|
57
|
+
.map((item, i) => (_jsx(NavigationMenuLinkItem, { item: item, className: "text-sm" }, i))) }), _jsxs("div", { className: "flex flex-row items-center justify-end gap-1.5 flex-1 max-lg:hidden", children: [searchToggle.enabled !== false &&
|
|
58
|
+
(searchToggle.components?.lg ?? (_jsx(LargeSearchToggle, { className: "w-full rounded-full ps-2.5 max-w-[240px]", hideIfDisabled: true }))), themeSwitch.enabled !== false &&
|
|
59
|
+
(themeSwitch.component ?? _jsx(ThemeToggle, { mode: themeSwitch?.mode })), i18n && (_jsx(LanguageToggle, { children: _jsx(Languages, { className: "size-5" }) })), _jsx("ul", { className: "flex flex-row gap-2 items-center empty:hidden", children: navItems.filter(isSecondary).map((item, i) => (_jsx(NavigationMenuLinkItem, { className: cn(item.type === 'icon' && '-mx-1 first:ms-0 last:me-0'), item: item }, i))) })] }), _jsxs("ul", { className: "flex flex-row items-center ms-auto -me-1.5 lg:hidden", children: [searchToggle.enabled !== false &&
|
|
60
|
+
(searchToggle.components?.sm ?? (_jsx(SearchToggle, { className: "p-2", hideIfDisabled: true }))), _jsxs(NavigationMenuItem, { children: [_jsx(NavigationMenuTrigger, { "aria-label": "Toggle Menu", className: cn(buttonVariants({
|
|
61
|
+
size: 'icon',
|
|
62
|
+
color: 'ghost',
|
|
63
|
+
className: 'group [&_svg]:size-5.5',
|
|
64
|
+
})), onPointerMove: nav.enableHoverToOpen ? undefined : (e) => e.preventDefault(), children: _jsx(ChevronDown, { className: "transition-transform duration-300 group-data-[state=open]:rotate-180" }) }), _jsxs(NavigationMenuContent, { className: "flex flex-col p-4 sm:flex-row sm:items-center sm:justify-end", children: [menuItems
|
|
65
|
+
.filter((item) => !isSecondary(item))
|
|
66
|
+
.map((item, i) => (_jsx(MobileNavigationMenuLinkItem, { item: item, className: "sm:hidden" }, i))), _jsxs("div", { className: "-ms-1.5 flex flex-row items-center gap-2 max-sm:mt-2", children: [menuItems.filter(isSecondary).map((item, i) => (_jsx(MobileNavigationMenuLinkItem, { item: item, className: cn(item.type === 'icon' && '-mx-1 first:ms-0') }, i))), _jsx("div", { role: "separator", className: "flex-1" }), i18n && (_jsxs(LanguageToggle, { children: [_jsx(Languages, { className: "size-5" }), _jsx(LanguageToggleText, {}), _jsx(ChevronDown, { className: "size-3 text-fd-muted-foreground" })] })), themeSwitch.enabled !== false &&
|
|
67
|
+
(themeSwitch.component ?? (_jsx(ThemeToggle, { mode: themeSwitch?.mode })))] })] })] })] })] }));
|
|
68
|
+
}
|
|
69
|
+
function isSecondary(item) {
|
|
70
|
+
if ('secondary' in item && item.secondary != null)
|
|
71
|
+
return item.secondary;
|
|
72
|
+
return item.type === 'icon';
|
|
73
|
+
}
|
|
74
|
+
function HeaderNavigationMenu({ transparentMode = 'none', ...props }) {
|
|
75
|
+
const [value, setValue] = useState('');
|
|
76
|
+
const isTop = useIsScrollTop({ enabled: transparentMode === 'top' }) ?? true;
|
|
77
|
+
const isTransparent = transparentMode === 'top' ? isTop : transparentMode === 'always';
|
|
78
|
+
return (_jsx(NavigationMenu, { value: value, onValueChange: setValue, asChild: true, children: _jsx("header", { id: "nd-nav", ...props, className: cn('sticky h-14 top-0 z-40', props.className), children: _jsxs("div", { className: cn('backdrop-blur-lg border-b transition-colors *:mx-auto *:max-w-(--fd-layout-width)', value.length > 0 && 'max-lg:shadow-lg max-lg:rounded-b-2xl', (!isTransparent || value.length > 0) && 'bg-fd-background/80'), children: [_jsx(NavigationMenuList, { className: "flex h-14 w-full items-center px-4", asChild: true, children: _jsx("nav", { children: props.children }) }), _jsx(NavigationMenuViewport, {})] }) }) }));
|
|
79
|
+
}
|
|
80
|
+
function NavigationMenuLinkItem({ item, ...props }) {
|
|
81
|
+
if (item.type === 'custom')
|
|
82
|
+
return _jsx("div", { ...props, children: item.children });
|
|
83
|
+
if (item.type === 'menu') {
|
|
84
|
+
const children = item.items.map((child, j) => {
|
|
85
|
+
if (child.type === 'custom') {
|
|
86
|
+
return _jsx(Fragment, { children: child.children }, j);
|
|
87
|
+
}
|
|
88
|
+
const { banner = child.icon ? (_jsx("div", { className: "w-fit rounded-md border bg-fd-muted p-1 [&_svg]:size-4", children: child.icon })) : null, ...rest } = child.menu ?? {};
|
|
89
|
+
return (_jsx(NavigationMenuLink, { asChild: true, children: _jsx(Link, { href: child.url, external: child.external, ...rest, className: cn('flex flex-col gap-2 rounded-lg border bg-fd-card p-3 transition-colors hover:bg-fd-accent/80 hover:text-fd-accent-foreground', rest.className), children: rest.children ?? (_jsxs(_Fragment, { children: [banner, _jsx("p", { className: "text-base font-medium", children: child.text }), _jsx("p", { className: "text-sm text-fd-muted-foreground empty:hidden", children: child.description })] })) }) }, `${j}-${child.url}`));
|
|
90
|
+
});
|
|
91
|
+
return (_jsxs(NavigationMenuItem, { ...props, children: [_jsx(NavigationMenuTrigger, { className: cn(navItemVariants(), 'rounded-md'), children: item.url ? (_jsx(Link, { href: item.url, external: item.external, children: item.text })) : (item.text) }), _jsx(NavigationMenuContent, { className: "grid grid-cols-1 gap-2 p-4 md:grid-cols-2 lg:grid-cols-3", children: children })] }));
|
|
92
|
+
}
|
|
93
|
+
return (_jsx(NavigationMenuItem, { ...props, children: _jsx(NavigationMenuLink, { asChild: true, children: _jsx(LinkItem, { item: item, "aria-label": item.type === 'icon' ? item.label : undefined, className: cn(navItemVariants({ variant: item.type })), children: item.type === 'icon' ? item.icon : item.text }) }) }));
|
|
94
|
+
}
|
|
95
|
+
function MobileNavigationMenuLinkItem({ item, ...props }) {
|
|
96
|
+
if (item.type === 'custom')
|
|
97
|
+
return _jsx("div", { className: cn('grid', props.className), children: item.children });
|
|
98
|
+
if (item.type === 'menu') {
|
|
99
|
+
const header = (_jsxs(_Fragment, { children: [item.icon, item.text] }));
|
|
100
|
+
return (_jsxs("div", { className: cn('mb-4 flex flex-col', props.className), children: [_jsx("p", { className: "mb-1 text-sm text-fd-muted-foreground", children: item.url ? (_jsx(NavigationMenuLink, { asChild: true, children: _jsx(Link, { href: item.url, external: item.external, children: header }) })) : (header) }), item.items.map((child, i) => (_jsx(MobileNavigationMenuLinkItem, { item: child }, i)))] }));
|
|
101
|
+
}
|
|
102
|
+
return (_jsx(NavigationMenuLink, { asChild: true, children: _jsxs(LinkItem, { item: item, className: cn({
|
|
103
|
+
main: 'inline-flex items-center gap-2 py-1.5 transition-colors hover:text-fd-popover-foreground/50 data-[active=true]:font-medium data-[active=true]:text-fd-primary [&_svg]:size-4',
|
|
104
|
+
icon: buttonVariants({
|
|
105
|
+
size: 'icon',
|
|
106
|
+
color: 'ghost',
|
|
107
|
+
}),
|
|
108
|
+
button: buttonVariants({
|
|
109
|
+
color: 'secondary',
|
|
110
|
+
className: 'gap-1.5 [&_svg]:size-4',
|
|
111
|
+
}),
|
|
112
|
+
}[item.type ?? 'main'], props.className), "aria-label": item.type === 'icon' ? item.label : undefined, children: [item.icon, item.type === 'icon' ? undefined : item.text] }) }));
|
|
113
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
import { type BaseLayoutProps, type NavOptions } from '../../layouts/shared/index.js';
|
|
3
|
+
export interface HomeLayoutProps extends BaseLayoutProps {
|
|
4
|
+
nav?: Partial<NavOptions & {
|
|
5
|
+
/**
|
|
6
|
+
* Open mobile menu when hovering the trigger
|
|
7
|
+
*/
|
|
8
|
+
enableHoverToOpen?: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export declare function HomeLayout(props: HomeLayoutProps & ComponentProps<'main'>): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/layouts/home/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGzE,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,GAAG,CAAC,EAAE,OAAO,CACX,UAAU,GAAG;QACX;;WAEG;QACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;KAC7B,CACF,CAAC;CACH;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,2CAkCzE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '@hanzo/ui/cn';
|
|
3
|
+
import { Header } from '../../layouts/home/client.js';
|
|
4
|
+
export function HomeLayout(props) {
|
|
5
|
+
const { nav = {}, links, githubUrl, i18n, themeSwitch = {}, searchToggle, ...rest } = props;
|
|
6
|
+
return (_jsxs("main", { id: "nd-home-layout", ...rest, className: cn('flex flex-1 flex-col [--fd-layout-width:1400px]', rest.className), children: [nav.enabled !== false &&
|
|
7
|
+
(nav.component ?? (_jsx(Header, { links: links, nav: nav, themeSwitch: themeSwitch, searchToggle: searchToggle, i18n: i18n, githubUrl: githubUrl }))), props.children] }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type LinkProps } from '@hanzo/docs/link';
|
|
2
|
+
import { type NavigationMenuContentProps, type NavigationMenuTriggerProps } from '../../components/ui/navigation-menu.js';
|
|
3
|
+
export declare const NavbarMenu: import("react").ForwardRefExoticComponent<Omit<import("@radix-ui/react-navigation-menu").NavigationMenuItemProps & import("react").RefAttributes<HTMLLIElement>, "ref"> & import("react").RefAttributes<HTMLLIElement>>;
|
|
4
|
+
export declare function NavbarMenuContent(props: NavigationMenuContentProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function NavbarMenuTrigger(props: NavigationMenuTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function NavbarMenuLink(props: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=navbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navbar.d.ts","sourceRoot":"","sources":["../../../src/layouts/home/navbar.tsx"],"names":[],"mappings":"AACA,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAEL,KAAK,0BAA0B,EAI/B,KAAK,0BAA0B,EAChC,MAAM,iCAAiC,CAAC;AAGzC,eAAO,MAAM,UAAU,yNAAqB,CAAC;AAE7C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,2CAYlE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,0BAA0B,2CASlE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,2CAc9C"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import Link from '@hanzo/docs/link';
|
|
4
|
+
import { cn } from '@hanzo/ui/cn';
|
|
5
|
+
import { NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuTrigger, } from '../../components/ui/navigation-menu.js';
|
|
6
|
+
import { navItemVariants } from './client.js';
|
|
7
|
+
export const NavbarMenu = NavigationMenuItem;
|
|
8
|
+
export function NavbarMenuContent(props) {
|
|
9
|
+
return (_jsx(NavigationMenuContent, { ...props, className: cn('grid grid-cols-1 gap-2 p-4 md:grid-cols-2 lg:grid-cols-3', props.className), children: props.children }));
|
|
10
|
+
}
|
|
11
|
+
export function NavbarMenuTrigger(props) {
|
|
12
|
+
return (_jsx(NavigationMenuTrigger, { ...props, className: cn(navItemVariants(), 'rounded-md', props.className), children: props.children }));
|
|
13
|
+
}
|
|
14
|
+
export function NavbarMenuLink(props) {
|
|
15
|
+
return (_jsx(NavigationMenuLink, { asChild: true, children: _jsx(Link, { ...props, className: cn('flex flex-col gap-2 rounded-lg border bg-fd-card p-3 transition-colors hover:bg-fd-accent/80 hover:text-fd-accent-foreground', props.className), children: props.children }) }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ComponentProps, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import { type LinkItemType } from '@hanzo/ui/link-item';
|
|
3
|
+
import { type SidebarTabWithProps } from '../../components/sidebar/tabs/dropdown.js';
|
|
4
|
+
export declare const LayoutContext: import("react").Context<(LayoutInfo & {
|
|
5
|
+
isNavTransparent: boolean;
|
|
6
|
+
}) | null>;
|
|
7
|
+
export interface LayoutInfo {
|
|
8
|
+
tabMode: 'sidebar' | 'navbar';
|
|
9
|
+
navMode: 'top' | 'auto';
|
|
10
|
+
}
|
|
11
|
+
export declare function LayoutContextProvider({ navTransparentMode, navMode, tabMode, children, }: LayoutInfo & {
|
|
12
|
+
navTransparentMode?: 'always' | 'top' | 'none';
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function LayoutHeader(props: ComponentProps<'header'>): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function LayoutBody({ className, style, children, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function LayoutHeaderTabs({ options, className, ...props }: ComponentProps<'div'> & {
|
|
18
|
+
options: SidebarTabWithProps[];
|
|
19
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export declare function NavbarLinkItem({ item, className, ...props }: {
|
|
21
|
+
item: LinkItemType;
|
|
22
|
+
} & HTMLAttributes<HTMLElement>): string | number | bigint | boolean | import("react/jsx-runtime").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
23
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/layouts/notebook/client.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,cAAc,EAEnB,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAMf,OAAO,EAEL,KAAK,YAAY,EAElB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,oCAAoC,CAAC;AAE5C,eAAO,MAAM,aAAa;sBAEF,OAAO;UAGxB,CAAC;AAER,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,OAAO,EAAE,KAAK,GAAG,MAAM,CAAC;CACzB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,kBAA2B,EAC3B,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE,UAAU,GAAG;IACd,kBAAkB,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;IAC/C,QAAQ,EAAE,SAAS,CAAC;CACrB,2CAoBA;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAS3D;AAED,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,2CAqCvB;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IACzB,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,2CAmCA;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,SAAS,EACT,GAAG,KAAK,EACT,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GAAG,cAAc,CAAC,WAAW,CAAC,2UAmBtD"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { cn } from '@hanzo/ui/cn';
|
|
4
|
+
import { createContext, Fragment, use, useMemo, useRef, useState, } from 'react';
|
|
5
|
+
import { useSidebar } from '../../components/sidebar/base.js';
|
|
6
|
+
import { ChevronDown } from '@hanzo/ui/icons';
|
|
7
|
+
import Link from '@hanzo/docs/link';
|
|
8
|
+
import { usePathname } from '@hanzo/docs/framework';
|
|
9
|
+
import { useIsScrollTop } from '@hanzo/ui/hooks/use-is-scroll-top';
|
|
10
|
+
import { LinkItem, } from '@hanzo/ui/link-item';
|
|
11
|
+
import { Popover, PopoverContent, PopoverTrigger, } from '../../components/ui/popover.js';
|
|
12
|
+
import { isTabActive, } from '../../components/sidebar/tabs/dropdown.js';
|
|
13
|
+
export const LayoutContext = createContext(null);
|
|
14
|
+
export function LayoutContextProvider({ navTransparentMode = 'none', navMode, tabMode, children, }) {
|
|
15
|
+
const isTop = useIsScrollTop({ enabled: navTransparentMode === 'top' }) ?? true;
|
|
16
|
+
const isNavTransparent = navTransparentMode === 'top' ? isTop : navTransparentMode === 'always';
|
|
17
|
+
return (_jsx(LayoutContext, { value: useMemo(() => ({
|
|
18
|
+
isNavTransparent,
|
|
19
|
+
navMode,
|
|
20
|
+
tabMode,
|
|
21
|
+
}), [isNavTransparent, navMode, tabMode]), children: children }));
|
|
22
|
+
}
|
|
23
|
+
export function LayoutHeader(props) {
|
|
24
|
+
const { open } = useSidebar();
|
|
25
|
+
const { isNavTransparent } = use(LayoutContext);
|
|
26
|
+
return (_jsx("header", { "data-transparent": isNavTransparent && !open, ...props, children: props.children }));
|
|
27
|
+
}
|
|
28
|
+
export function LayoutBody({ className, style, children, ...props }) {
|
|
29
|
+
const { navMode } = use(LayoutContext);
|
|
30
|
+
const { collapsed } = useSidebar();
|
|
31
|
+
const pageCol = 'calc(var(--fd-layout-width,97rem) - var(--fd-sidebar-col) - var(--fd-toc-width))';
|
|
32
|
+
return (_jsx("div", { id: "nd-notebook-layout", className: cn('grid overflow-x-clip min-h-(--fd-docs-height) transition-[grid-template-columns] auto-cols-auto auto-rows-auto [--fd-docs-height:100dvh] [--fd-header-height:0px] [--fd-toc-popover-height:0px] [--fd-sidebar-width:0px] [--fd-toc-width:0px]', className), style: {
|
|
33
|
+
gridTemplate: navMode === 'top'
|
|
34
|
+
? `". header header header ."
|
|
35
|
+
"sidebar sidebar toc-popover toc-popover ."
|
|
36
|
+
"sidebar sidebar main toc ." 1fr / minmax(min-content, 1fr) var(--fd-sidebar-col) minmax(0, ${pageCol}) var(--fd-toc-width) minmax(min-content, 1fr)`
|
|
37
|
+
: `"sidebar sidebar header header ."
|
|
38
|
+
"sidebar sidebar toc-popover toc-popover ."
|
|
39
|
+
"sidebar sidebar main toc ." 1fr / minmax(min-content, 1fr) var(--fd-sidebar-col) minmax(0, ${pageCol}) var(--fd-toc-width) minmax(min-content, 1fr)`,
|
|
40
|
+
'--fd-docs-row-1': 'var(--fd-banner-height, 0px)',
|
|
41
|
+
'--fd-docs-row-2': 'calc(var(--fd-docs-row-1) + var(--fd-header-height))',
|
|
42
|
+
'--fd-docs-row-3': 'calc(var(--fd-docs-row-2) + var(--fd-toc-popover-height))',
|
|
43
|
+
'--fd-sidebar-col': collapsed ? '0px' : 'var(--fd-sidebar-width)',
|
|
44
|
+
...style,
|
|
45
|
+
}, ...props, children: children }));
|
|
46
|
+
}
|
|
47
|
+
export function LayoutHeaderTabs({ options, className, ...props }) {
|
|
48
|
+
const pathname = usePathname();
|
|
49
|
+
const selectedIdx = useMemo(() => {
|
|
50
|
+
return options.findLastIndex((option) => isTabActive(option, pathname));
|
|
51
|
+
}, [options, pathname]);
|
|
52
|
+
return (_jsx("div", { className: cn('flex flex-row items-end gap-6', className), ...props, children: options.map((option, i) => {
|
|
53
|
+
const { title, url, unlisted, props: { className, ...rest } = {}, } = option;
|
|
54
|
+
const isSelected = selectedIdx === i;
|
|
55
|
+
return (_jsx(Link, { href: url, className: cn('inline-flex border-b-2 border-transparent transition-colors items-center pb-1.5 font-medium gap-2 text-fd-muted-foreground text-sm text-nowrap hover:text-fd-accent-foreground', unlisted && !isSelected && 'hidden', isSelected && 'border-fd-primary text-fd-primary', className), ...rest, children: title }, i));
|
|
56
|
+
}) }));
|
|
57
|
+
}
|
|
58
|
+
export function NavbarLinkItem({ item, className, ...props }) {
|
|
59
|
+
if (item.type === 'custom')
|
|
60
|
+
return item.children;
|
|
61
|
+
if (item.type === 'menu') {
|
|
62
|
+
return _jsx(NavbarLinkItemMenu, { item: item, className: className, ...props });
|
|
63
|
+
}
|
|
64
|
+
return (_jsx(LinkItem, { item: item, className: cn('text-sm text-fd-muted-foreground transition-colors hover:text-fd-accent-foreground data-[active=true]:text-fd-primary', className), ...props, children: item.text }));
|
|
65
|
+
}
|
|
66
|
+
function NavbarLinkItemMenu({ item, hoverDelay = 50, className, ...props }) {
|
|
67
|
+
const [open, setOpen] = useState(false);
|
|
68
|
+
const timeoutRef = useRef(null);
|
|
69
|
+
const freezeUntil = useRef(null);
|
|
70
|
+
const delaySetOpen = (value) => {
|
|
71
|
+
if (timeoutRef.current) {
|
|
72
|
+
clearTimeout(timeoutRef.current);
|
|
73
|
+
timeoutRef.current = null;
|
|
74
|
+
}
|
|
75
|
+
timeoutRef.current = window.setTimeout(() => {
|
|
76
|
+
setOpen(value);
|
|
77
|
+
freezeUntil.current = Date.now() + 300;
|
|
78
|
+
}, hoverDelay);
|
|
79
|
+
};
|
|
80
|
+
const onPointerEnter = (e) => {
|
|
81
|
+
if (e.pointerType === 'touch')
|
|
82
|
+
return;
|
|
83
|
+
delaySetOpen(true);
|
|
84
|
+
};
|
|
85
|
+
const onPointerLeave = (e) => {
|
|
86
|
+
if (e.pointerType === 'touch')
|
|
87
|
+
return;
|
|
88
|
+
delaySetOpen(false);
|
|
89
|
+
};
|
|
90
|
+
function isTouchDevice() {
|
|
91
|
+
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
92
|
+
}
|
|
93
|
+
return (_jsxs(Popover, { open: open, onOpenChange: (value) => {
|
|
94
|
+
if (freezeUntil.current === null || Date.now() >= freezeUntil.current)
|
|
95
|
+
setOpen(value);
|
|
96
|
+
}, children: [_jsxs(PopoverTrigger, { className: cn('inline-flex items-center gap-1.5 p-1 text-sm text-fd-muted-foreground transition-colors has-data-[active=true]:text-fd-primary data-[state=open]:text-fd-accent-foreground focus-visible:outline-none', className), onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, ...props, children: [item.url ? (_jsx(LinkItem, { item: item, children: item.text })) : (item.text), _jsx(ChevronDown, { className: "size-3" })] }), _jsx(PopoverContent, { className: "flex flex-col p-1 text-fd-muted-foreground text-start", onPointerEnter: onPointerEnter, onPointerLeave: onPointerLeave, children: item.items.map((child, i) => {
|
|
97
|
+
if (child.type === 'custom')
|
|
98
|
+
return _jsx(Fragment, { children: child.children }, i);
|
|
99
|
+
return (_jsxs(LinkItem, { item: child, className: "inline-flex items-center gap-2 rounded-md p-2 transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground data-[active=true]:text-fd-primary [&_svg]:size-4", onClick: () => {
|
|
100
|
+
if (isTouchDevice())
|
|
101
|
+
setOpen(false);
|
|
102
|
+
}, children: [child.icon, child.text] }, i));
|
|
103
|
+
}) })] }));
|
|
104
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ComponentProps, type FC, type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import { type BaseLayoutProps } from '../../layouts/shared/index.js';
|
|
3
|
+
import { Sidebar } from './sidebar.js';
|
|
4
|
+
import type * as PageTree from '@hanzo/docs/page-tree';
|
|
5
|
+
import type { SidebarPageTreeComponents } from '../../components/sidebar/page-tree.js';
|
|
6
|
+
import { type GetSidebarTabsOptions } from '../../components/sidebar/tabs/index.js';
|
|
7
|
+
import { type SidebarTabWithProps } from '../../components/sidebar/tabs/dropdown.js';
|
|
8
|
+
export interface DocsLayoutProps extends BaseLayoutProps {
|
|
9
|
+
tree: PageTree.Root;
|
|
10
|
+
tabMode?: 'sidebar' | 'navbar';
|
|
11
|
+
nav?: BaseLayoutProps['nav'] & {
|
|
12
|
+
mode?: 'top' | 'auto';
|
|
13
|
+
};
|
|
14
|
+
sidebar?: SidebarOptions;
|
|
15
|
+
containerProps?: HTMLAttributes<HTMLDivElement>;
|
|
16
|
+
}
|
|
17
|
+
interface SidebarOptions extends ComponentProps<'aside'>, Pick<ComponentProps<typeof Sidebar>, 'defaultOpenLevel' | 'prefetch'> {
|
|
18
|
+
components?: Partial<SidebarPageTreeComponents>;
|
|
19
|
+
/**
|
|
20
|
+
* Root Toggle options
|
|
21
|
+
*/
|
|
22
|
+
tabs?: SidebarTabWithProps[] | GetSidebarTabsOptions | false;
|
|
23
|
+
banner?: ReactNode | FC<ComponentProps<'div'>>;
|
|
24
|
+
footer?: ReactNode | FC<ComponentProps<'div'>>;
|
|
25
|
+
/**
|
|
26
|
+
* Support collapsing the sidebar on desktop mode
|
|
27
|
+
*
|
|
28
|
+
* @defaultValue true
|
|
29
|
+
*/
|
|
30
|
+
collapsible?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function DocsLayout(props: DocsLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/layouts/notebook/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,EAAE,EACP,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AACf,OAAO,EACL,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,OAAO,EAQR,MAAM,WAAW,CAAC;AAOnB,OAAO,KAAK,KAAK,QAAQ,MAAM,uBAAuB,CAAC;AAavD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,oCAAoC,CAAC;AAE5C,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAE/B,GAAG,CAAC,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG;QAC7B,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;KACvB,CAAC;IAEF,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,cAAc,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC;CACjD;AAED,UAAU,cACR,SACE,cAAc,CAAC,OAAO,CAAC,EACvB,IAAI,CAAC,cAAc,CAAC,OAAO,OAAO,CAAC,EAAE,kBAAkB,GAAG,UAAU,CAAC;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEhD;;OAEG;IACH,IAAI,CAAC,EAAE,mBAAmB,EAAE,GAAG,qBAAqB,GAAG,KAAK,CAAC;IAE7D,MAAM,CAAC,EAAE,SAAS,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAC/C,MAAM,CAAC,EAAE,SAAS,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAE/C;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CAsNhD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, } from 'react';
|
|
3
|
+
import { renderTitleNav, resolveLinkItems, } from '../../layouts/shared/index.js';
|
|
4
|
+
import { Sidebar, SidebarCollapseTrigger, SidebarContent, SidebarDrawer, SidebarLinkItem, SidebarPageTree, SidebarTrigger, SidebarViewport, } from './sidebar.js';
|
|
5
|
+
import { TreeContextProvider } from '../../contexts/tree.js';
|
|
6
|
+
import { cn } from '@hanzo/ui/cn';
|
|
7
|
+
import { buttonVariants } from '../../components/ui/button.js';
|
|
8
|
+
import { Languages, Sidebar as SidebarIcon, X } from '@hanzo/ui/icons';
|
|
9
|
+
import { LanguageToggle } from '../../layouts/shared/language-toggle.js';
|
|
10
|
+
import { ThemeToggle } from '../../layouts/shared/theme-toggle.js';
|
|
11
|
+
import { LayoutBody, LayoutContextProvider, LayoutHeader, LayoutHeaderTabs, NavbarLinkItem, } from '../../layouts/notebook/client.js';
|
|
12
|
+
import { LargeSearchToggle, SearchToggle, } from '../../layouts/shared/search-toggle.js';
|
|
13
|
+
import { LinkItem } from '@hanzo/ui/link-item';
|
|
14
|
+
import { getSidebarTabs, } from '../../components/sidebar/tabs/index.js';
|
|
15
|
+
import { SidebarTabsDropdown, } from '../../components/sidebar/tabs/dropdown.js';
|
|
16
|
+
export function DocsLayout(props) {
|
|
17
|
+
const { tabMode = 'sidebar', nav = {}, sidebar: { tabs: tabOptions, defaultOpenLevel, prefetch, ...sidebarProps } = {}, i18n = false, themeSwitch = {}, tree, } = props;
|
|
18
|
+
const navMode = nav.mode ?? 'auto';
|
|
19
|
+
const links = resolveLinkItems(props);
|
|
20
|
+
const tabs = useMemo(() => {
|
|
21
|
+
if (Array.isArray(tabOptions)) {
|
|
22
|
+
return tabOptions;
|
|
23
|
+
}
|
|
24
|
+
if (typeof tabOptions === 'object') {
|
|
25
|
+
return getSidebarTabs(tree, tabOptions);
|
|
26
|
+
}
|
|
27
|
+
if (tabOptions !== false) {
|
|
28
|
+
return getSidebarTabs(tree);
|
|
29
|
+
}
|
|
30
|
+
return [];
|
|
31
|
+
}, [tabOptions, tree]);
|
|
32
|
+
function sidebar() {
|
|
33
|
+
const { banner, footer, components, collapsible = true, ...rest } = sidebarProps;
|
|
34
|
+
const iconLinks = links.filter((item) => item.type === 'icon');
|
|
35
|
+
const Header = typeof banner === 'function'
|
|
36
|
+
? banner
|
|
37
|
+
: ({ className, ...props }) => (_jsxs("div", { className: cn('flex flex-col gap-3 p-4 pb-2 empty:hidden', className), ...props, children: [props.children, banner] }));
|
|
38
|
+
const Footer = typeof footer === 'function'
|
|
39
|
+
? footer
|
|
40
|
+
: ({ className, ...props }) => (_jsxs("div", { className: cn('hidden flex-row text-fd-muted-foreground items-center border-t p-4 pt-2', iconLinks.length > 0 && 'max-lg:flex', className), ...props, children: [props.children, footer] }));
|
|
41
|
+
const viewport = (_jsxs(SidebarViewport, { children: [links
|
|
42
|
+
.filter((item) => item.type !== 'icon')
|
|
43
|
+
.map((item, i, arr) => (_jsx(SidebarLinkItem, { item: item, className: cn('lg:hidden', i === arr.length - 1 && 'mb-4') }, i))), _jsx(SidebarPageTree, { ...components })] }));
|
|
44
|
+
return (_jsxs(_Fragment, { children: [_jsxs(SidebarContent, { ...rest, children: [_jsxs(Header, { children: [navMode === 'auto' && (_jsxs("div", { className: "flex justify-between", children: [renderTitleNav(nav, {
|
|
45
|
+
className: 'inline-flex items-center gap-2.5 font-medium',
|
|
46
|
+
}), collapsible && (_jsx(SidebarCollapseTrigger, { className: cn(buttonVariants({
|
|
47
|
+
color: 'ghost',
|
|
48
|
+
size: 'icon-sm',
|
|
49
|
+
className: 'mt-px mb-auto text-fd-muted-foreground',
|
|
50
|
+
})), children: _jsx(SidebarIcon, {}) }))] })), nav.children, tabs.length > 0 && (_jsx(SidebarTabsDropdown, { options: tabs, className: cn(tabMode === 'navbar' && 'lg:hidden') }))] }), viewport, _jsx(Footer, { children: iconLinks.map((item, i) => (_jsx(LinkItem, { item: item, className: cn(buttonVariants({
|
|
51
|
+
size: 'icon-sm',
|
|
52
|
+
color: 'ghost',
|
|
53
|
+
className: 'lg:hidden',
|
|
54
|
+
})), "aria-label": item.label, children: item.icon }, i))) })] }), _jsxs(SidebarDrawer, { ...rest, children: [_jsxs(Header, { children: [_jsx(SidebarTrigger, { className: cn(buttonVariants({
|
|
55
|
+
size: 'icon-sm',
|
|
56
|
+
color: 'ghost',
|
|
57
|
+
className: 'ms-auto text-fd-muted-foreground',
|
|
58
|
+
})), children: _jsx(X, {}) }), tabs.length > 0 && _jsx(SidebarTabsDropdown, { options: tabs })] }), viewport, _jsxs(Footer, { className: cn('hidden flex-row items-center justify-end', (i18n || themeSwitch.enabled !== false) && 'flex', iconLinks.length > 0 && 'max-lg:flex'), children: [iconLinks.map((item, i) => (_jsx(LinkItem, { item: item, className: cn(buttonVariants({
|
|
59
|
+
size: 'icon-sm',
|
|
60
|
+
color: 'ghost',
|
|
61
|
+
}), 'text-fd-muted-foreground lg:hidden', i === iconLinks.length - 1 && 'me-auto'), "aria-label": item.label, children: item.icon }, i))), i18n && (_jsx(LanguageToggle, { children: _jsx(Languages, { className: "size-4.5 text-fd-muted-foreground" }) })), themeSwitch.enabled !== false &&
|
|
62
|
+
(themeSwitch.component ?? (_jsx(ThemeToggle, { mode: themeSwitch.mode ?? 'light-dark-system' })))] })] })] }));
|
|
63
|
+
}
|
|
64
|
+
return (_jsx(TreeContextProvider, { tree: tree, children: _jsx(LayoutContextProvider, { navMode: nav.mode ?? 'auto', tabMode: tabMode, navTransparentMode: nav.transparentMode, children: _jsx(Sidebar, { defaultOpenLevel: defaultOpenLevel, prefetch: prefetch, children: _jsxs(LayoutBody, { ...props.containerProps, children: [sidebar(), _jsx(DocsNavbar, { ...props, links: links, tabs: tabs }), props.children] }) }) }) }));
|
|
65
|
+
}
|
|
66
|
+
function DocsNavbar({ links, tabs, tabMode = 'sidebar', sidebar: { collapsible: sidebarCollapsible = true } = {}, searchToggle = {}, themeSwitch = {}, nav = {}, i18n, }) {
|
|
67
|
+
const navMode = nav.mode ?? 'auto';
|
|
68
|
+
const showLayoutTabs = tabMode === 'navbar' && tabs.length > 0;
|
|
69
|
+
return (_jsxs(LayoutHeader, { id: "nd-subnav", className: cn('sticky [grid-area:header] flex flex-col top-(--fd-docs-row-1) z-10 backdrop-blur-sm transition-colors data-[transparent=false]:bg-fd-background/80 layout:[--fd-header-height:--spacing(14)]', showLayoutTabs && 'lg:layout:[--fd-header-height:--spacing(24)]'), children: [_jsxs("div", { "data-header-body": "", className: "flex border-b px-4 gap-2 h-14 md:px-6", children: [_jsxs("div", { className: cn('items-center', navMode === 'top' && 'flex flex-1', navMode === 'auto' &&
|
|
70
|
+
'hidden has-data-[collapsed=true]:md:flex max-md:flex'), children: [sidebarCollapsible && navMode === 'auto' && (_jsx(SidebarCollapseTrigger, { className: cn(buttonVariants({
|
|
71
|
+
color: 'ghost',
|
|
72
|
+
size: 'icon-sm',
|
|
73
|
+
}), 'text-fd-muted-foreground data-[collapsed=false]:hidden max-md:hidden'), children: _jsx(SidebarIcon, {}) })), renderTitleNav(nav, {
|
|
74
|
+
className: cn('inline-flex items-center gap-2.5 font-semibold', navMode === 'auto' && 'md:hidden'),
|
|
75
|
+
})] }), searchToggle.enabled !== false &&
|
|
76
|
+
(searchToggle.components?.lg ? (_jsx("div", { className: cn('w-full my-auto max-md:hidden', navMode === 'top' ? 'rounded-xl max-w-sm' : 'max-w-[240px]'), children: searchToggle.components.lg })) : (_jsx(LargeSearchToggle, { hideIfDisabled: true, className: cn('w-full my-auto max-md:hidden', navMode === 'top'
|
|
77
|
+
? 'rounded-xl max-w-sm ps-2.5'
|
|
78
|
+
: 'max-w-[240px]') }))), _jsxs("div", { className: "flex flex-1 items-center justify-end md:gap-2", children: [_jsx("div", { className: "flex items-center gap-6 empty:hidden max-lg:hidden", children: links
|
|
79
|
+
.filter((item) => item.type !== 'icon')
|
|
80
|
+
.map((item, i) => (_jsx(NavbarLinkItem, { item: item }, i))) }), nav.children, links
|
|
81
|
+
.filter((item) => item.type === 'icon')
|
|
82
|
+
.map((item, i) => (_jsx(LinkItem, { item: item, className: cn(buttonVariants({ size: 'icon-sm', color: 'ghost' }), 'text-fd-muted-foreground max-lg:hidden'), "aria-label": item.label, children: item.icon }, i))), _jsxs("div", { className: "flex items-center md:hidden", children: [searchToggle.enabled !== false &&
|
|
83
|
+
(searchToggle.components?.sm ?? (_jsx(SearchToggle, { hideIfDisabled: true, className: "p-2" }))), _jsx(SidebarTrigger, { className: cn(buttonVariants({
|
|
84
|
+
color: 'ghost',
|
|
85
|
+
size: 'icon-sm',
|
|
86
|
+
className: 'p-2 -me-1.5',
|
|
87
|
+
})), children: _jsx(SidebarIcon, {}) })] }), _jsxs("div", { className: "flex items-center gap-2 max-md:hidden", children: [i18n && (_jsx(LanguageToggle, { children: _jsx(Languages, { className: "size-4.5 text-fd-muted-foreground" }) })), themeSwitch.enabled !== false &&
|
|
88
|
+
(themeSwitch.component ?? (_jsx(ThemeToggle, { mode: themeSwitch.mode ?? 'light-dark-system' }))), sidebarCollapsible && navMode === 'top' && (_jsx(SidebarCollapseTrigger, { className: cn(buttonVariants({
|
|
89
|
+
color: 'secondary',
|
|
90
|
+
size: 'icon-sm',
|
|
91
|
+
}), 'text-fd-muted-foreground rounded-full -me-1.5'), children: _jsx(SidebarIcon, {}) }))] })] })] }), showLayoutTabs && (_jsx(LayoutHeaderTabs, { "data-header-tabs": "", className: "overflow-x-auto border-b px-6 h-10 max-lg:hidden", options: tabs }))] }));
|
|
92
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ComponentProps } from 'react';
|
|
2
|
+
import type * as PageTree from '@hanzo/docs/page-tree';
|
|
3
|
+
import { type BreadcrumbOptions } from '@hanzo/docs/breadcrumb';
|
|
4
|
+
export declare function PageTOCPopover({ className, children, ...rest }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function PageTOCPopoverTrigger({ className, ...props }: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function PageTOCPopoverContent(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function PageLastUpdate({ date: value, ...props }: Omit<ComponentProps<'p'>, 'children'> & {
|
|
8
|
+
date: Date;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
type Item = Pick<PageTree.Item, 'name' | 'description' | 'url'>;
|
|
11
|
+
export interface FooterProps extends ComponentProps<'div'> {
|
|
12
|
+
/**
|
|
13
|
+
* Items including information for the next and previous page
|
|
14
|
+
*/
|
|
15
|
+
items?: {
|
|
16
|
+
previous?: Item;
|
|
17
|
+
next?: Item;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function PageFooter({ items, ...props }: FooterProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export type BreadcrumbProps = BreadcrumbOptions & ComponentProps<'div'>;
|
|
22
|
+
export declare function PageBreadcrumb({ includeRoot, includeSeparator, includePage, ...props }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element | null;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/layouts/notebook/page/client.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EASpB,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,KAAK,QAAQ,MAAM,uBAAuB,CAAC;AAEvD,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,wBAAwB,CAAC;AAiBhC,wBAAgB,cAAc,CAAC,EAC7B,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,KAAK,CAAC,2CAqDvB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAqD1B;AA8DD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAUjE;AAED,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EAAE,KAAK,EACX,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,2CAiBxD;AAED,KAAK,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,KAAK,CAAC,CAAC;AAChE,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,KAAK,CAAC;IACxD;;OAEG;IACH,KAAK,CAAC,EAAE;QACN,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,IAAI,CAAC,EAAE,IAAI,CAAC;KACb,CAAC;CACH;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,2CA8B1D;AA8BD,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;AAExE,wBAAgB,cAAc,CAAC,EAC7B,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,GAAG,KAAK,EACT,EAAE,eAAe,kDA6CjB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, Fragment, use, useEffect, useEffectEvent, useMemo, useRef, useState, } from 'react';
|
|
4
|
+
import { ChevronDown, ChevronLeft, ChevronRight } from '@hanzo/ui/icons';
|
|
5
|
+
import Link from '@hanzo/docs/link';
|
|
6
|
+
import { cn } from '@hanzo/ui/cn';
|
|
7
|
+
import { useI18n } from '../../../contexts/i18n.js';
|
|
8
|
+
import { useTreeContext, useTreePath } from '../../../contexts/tree.js';
|
|
9
|
+
import { usePathname } from '@hanzo/docs/framework';
|
|
10
|
+
import { getBreadcrumbItemsFromPath, } from '@hanzo/docs/breadcrumb';
|
|
11
|
+
import { isActive } from '@hanzo/ui/urls';
|
|
12
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../../components/ui/collapsible.js';
|
|
13
|
+
import { useTOCItems } from '../../../components/toc/index.js';
|
|
14
|
+
import { useActiveAnchor } from '@hanzo/docs/toc';
|
|
15
|
+
import { LayoutContext } from '../client.js';
|
|
16
|
+
import { useFooterItems } from '@hanzo/ui/hooks/use-footer-items';
|
|
17
|
+
const TocPopoverContext = createContext(null);
|
|
18
|
+
export function PageTOCPopover({ className, children, ...rest }) {
|
|
19
|
+
const ref = useRef(null);
|
|
20
|
+
const [open, setOpen] = useState(false);
|
|
21
|
+
const { isNavTransparent } = use(LayoutContext);
|
|
22
|
+
const onClick = useEffectEvent((e) => {
|
|
23
|
+
if (!open)
|
|
24
|
+
return;
|
|
25
|
+
if (ref.current && !ref.current.contains(e.target))
|
|
26
|
+
setOpen(false);
|
|
27
|
+
});
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
window.addEventListener('click', onClick);
|
|
30
|
+
return () => {
|
|
31
|
+
window.removeEventListener('click', onClick);
|
|
32
|
+
};
|
|
33
|
+
}, []);
|
|
34
|
+
return (_jsx(TocPopoverContext, { value: useMemo(() => ({
|
|
35
|
+
open,
|
|
36
|
+
setOpen,
|
|
37
|
+
}), [setOpen, open]), children: _jsx(Collapsible, { open: open, onOpenChange: setOpen, "data-toc-popover": "", className: cn('sticky top-(--fd-docs-row-2) z-10 [grid-area:toc-popover] h-(--fd-toc-popover-height) xl:hidden max-xl:layout:[--fd-toc-popover-height:--spacing(10)]', className), ...rest, children: _jsx("header", { ref: ref, className: cn('border-b backdrop-blur-sm transition-colors', (!isNavTransparent || open) && 'bg-fd-background/80', open && 'shadow-lg'), children: children }) }) }));
|
|
38
|
+
}
|
|
39
|
+
export function PageTOCPopoverTrigger({ className, ...props }) {
|
|
40
|
+
const { text } = useI18n();
|
|
41
|
+
const { open } = use(TocPopoverContext);
|
|
42
|
+
const items = useTOCItems();
|
|
43
|
+
const active = useActiveAnchor();
|
|
44
|
+
const selected = useMemo(() => items.findIndex((item) => active === item.url.slice(1)), [items, active]);
|
|
45
|
+
const path = useTreePath().at(-1);
|
|
46
|
+
const showItem = selected !== -1 && !open;
|
|
47
|
+
return (_jsxs(CollapsibleTrigger, { className: cn('flex w-full h-10 items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:size-4 md:px-6', className), "data-toc-popover-trigger": "", ...props, children: [_jsx(ProgressCircle, { value: (selected + 1) / Math.max(1, items.length), max: 1, className: cn('shrink-0', open && 'text-fd-primary') }), _jsxs("span", { className: "grid flex-1 *:my-auto *:row-start-1 *:col-start-1", children: [_jsx("span", { className: cn('truncate transition-[opacity,translate,color]', open && 'text-fd-foreground', showItem && 'opacity-0 -translate-y-full pointer-events-none'), children: path?.name ?? text.toc }), _jsx("span", { className: cn('truncate transition-[opacity,translate]', !showItem && 'opacity-0 translate-y-full pointer-events-none'), children: items[selected]?.title })] }), _jsx(ChevronDown, { className: cn('shrink-0 transition-transform mx-0.5', open && 'rotate-180') })] }));
|
|
48
|
+
}
|
|
49
|
+
function clamp(input, min, max) {
|
|
50
|
+
if (input < min)
|
|
51
|
+
return min;
|
|
52
|
+
if (input > max)
|
|
53
|
+
return max;
|
|
54
|
+
return input;
|
|
55
|
+
}
|
|
56
|
+
function ProgressCircle({ value, strokeWidth = 2, size = 24, min = 0, max = 100, ...restSvgProps }) {
|
|
57
|
+
const normalizedValue = clamp(value, min, max);
|
|
58
|
+
const radius = (size - strokeWidth) / 2;
|
|
59
|
+
const circumference = 2 * Math.PI * radius;
|
|
60
|
+
const progress = (normalizedValue / max) * circumference;
|
|
61
|
+
const circleProps = {
|
|
62
|
+
cx: size / 2,
|
|
63
|
+
cy: size / 2,
|
|
64
|
+
r: radius,
|
|
65
|
+
fill: 'none',
|
|
66
|
+
strokeWidth,
|
|
67
|
+
};
|
|
68
|
+
return (_jsxs("svg", { role: "progressbar", viewBox: `0 0 ${size} ${size}`, "aria-valuenow": normalizedValue, "aria-valuemin": min, "aria-valuemax": max, ...restSvgProps, children: [_jsx("circle", { ...circleProps, className: "stroke-current/25" }), _jsx("circle", { ...circleProps, stroke: "currentColor", strokeDasharray: circumference, strokeDashoffset: circumference - progress, strokeLinecap: "round", transform: `rotate(-90 ${size / 2} ${size / 2})`, className: "transition-all" })] }));
|
|
69
|
+
}
|
|
70
|
+
export function PageTOCPopoverContent(props) {
|
|
71
|
+
return (_jsx(CollapsibleContent, { "data-toc-popover-content": "", ...props, className: cn('flex flex-col px-4 max-h-[50vh] md:px-6', props.className), children: props.children }));
|
|
72
|
+
}
|
|
73
|
+
export function PageLastUpdate({ date: value, ...props }) {
|
|
74
|
+
const { text } = useI18n();
|
|
75
|
+
const [date, setDate] = useState('');
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
// to the timezone of client
|
|
78
|
+
setDate(value.toLocaleDateString());
|
|
79
|
+
}, [value]);
|
|
80
|
+
return (_jsxs("p", { ...props, className: cn('text-sm text-fd-muted-foreground', props.className), children: [text.lastUpdate, " ", date] }));
|
|
81
|
+
}
|
|
82
|
+
export function PageFooter({ items, ...props }) {
|
|
83
|
+
const footerList = useFooterItems();
|
|
84
|
+
const pathname = usePathname();
|
|
85
|
+
const { previous, next } = useMemo(() => {
|
|
86
|
+
if (items)
|
|
87
|
+
return items;
|
|
88
|
+
const idx = footerList.findIndex((item) => isActive(item.url, pathname, false));
|
|
89
|
+
if (idx === -1)
|
|
90
|
+
return {};
|
|
91
|
+
return {
|
|
92
|
+
previous: footerList[idx - 1],
|
|
93
|
+
next: footerList[idx + 1],
|
|
94
|
+
};
|
|
95
|
+
}, [footerList, items, pathname]);
|
|
96
|
+
return (_jsxs("div", { ...props, className: cn('@container grid gap-4', previous && next ? 'grid-cols-2' : 'grid-cols-1', props.className), children: [previous ? _jsx(FooterItem, { item: previous, index: 0 }) : null, next ? _jsx(FooterItem, { item: next, index: 1 }) : null] }));
|
|
97
|
+
}
|
|
98
|
+
function FooterItem({ item, index }) {
|
|
99
|
+
const { text } = useI18n();
|
|
100
|
+
const Icon = index === 0 ? ChevronLeft : ChevronRight;
|
|
101
|
+
return (_jsxs(Link, { href: item.url, className: cn('flex flex-col gap-2 rounded-lg border p-4 text-sm transition-colors hover:bg-fd-accent/80 hover:text-fd-accent-foreground @max-lg:col-span-full', index === 1 && 'text-end'), children: [_jsxs("div", { className: cn('inline-flex items-center gap-1.5 font-medium', index === 1 && 'flex-row-reverse'), children: [_jsx(Icon, { className: "-mx-1 size-4 shrink-0 rtl:rotate-180" }), _jsx("p", { children: item.name })] }), _jsx("p", { className: "text-fd-muted-foreground truncate", children: item.description ?? (index === 0 ? text.previousPage : text.nextPage) })] }));
|
|
102
|
+
}
|
|
103
|
+
export function PageBreadcrumb({ includeRoot, includeSeparator, includePage, ...props }) {
|
|
104
|
+
const path = useTreePath();
|
|
105
|
+
const { root } = useTreeContext();
|
|
106
|
+
const items = useMemo(() => {
|
|
107
|
+
return getBreadcrumbItemsFromPath(root, path, {
|
|
108
|
+
includePage,
|
|
109
|
+
includeSeparator,
|
|
110
|
+
includeRoot,
|
|
111
|
+
});
|
|
112
|
+
}, [includePage, includeRoot, includeSeparator, path, root]);
|
|
113
|
+
if (items.length === 0)
|
|
114
|
+
return null;
|
|
115
|
+
return (_jsx("div", { ...props, className: cn('flex items-center gap-1.5 text-sm text-fd-muted-foreground', props.className), children: items.map((item, i) => {
|
|
116
|
+
const className = cn('truncate', i === items.length - 1 && 'text-fd-primary font-medium');
|
|
117
|
+
return (_jsxs(Fragment, { children: [i !== 0 && _jsx(ChevronRight, { className: "size-3.5 shrink-0" }), item.url ? (_jsx(Link, { href: item.url, className: cn(className, 'transition-opacity hover:opacity-80'), children: item.name })) : (_jsx("span", { className: className, children: item.name }))] }, i));
|
|
118
|
+
}) }));
|
|
119
|
+
}
|