@fumadocs/base-ui 16.2.5
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/LICENSE +21 -0
- 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 +10 -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 +41 -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 +197 -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 +9 -0
- package/dist/components/ui/navigation-menu.d.ts +12 -0
- package/dist/components/ui/navigation-menu.d.ts.map +1 -0
- package/dist/components/ui/navigation-menu.js +15 -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 +22 -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 +1 -0
- package/dist/contexts/search.d.ts +2 -0
- package/dist/contexts/search.d.ts.map +1 -0
- package/dist/contexts/search.js +1 -0
- package/dist/contexts/tree.d.ts +2 -0
- package/dist/contexts/tree.d.ts.map +1 -0
- package/dist/contexts/tree.js +1 -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 +66 -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 +136 -0
- package/dist/layouts/home/index.d.ts +7 -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 +89 -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 +56 -0
- package/dist/layouts/shared/index.d.ts.map +1 -0
- package/dist/layouts/shared/index.js +17 -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 +3159 -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 +133 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronDown } from '@fumadocs/ui/icons';
|
|
4
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from './ui/collapsible.js';
|
|
5
|
+
import { cn } from '@fumadocs/ui/cn';
|
|
6
|
+
export function InlineTOC({ items, className, ...props }) {
|
|
7
|
+
return (_jsxs(Collapsible, { ...props, className: (s) => cn('not-prose rounded-lg border bg-fd-card text-fd-card-foreground', typeof className === 'function' ? className(s) : className), children: [_jsxs(CollapsibleTrigger, { className: "group inline-flex w-full items-center justify-between px-4 py-2.5 font-medium", children: [props.children ?? 'Table of Contents', _jsx(ChevronDown, { className: "size-4 transition-transform duration-200 group-data-[open]:rotate-180" })] }), _jsx(CollapsibleContent, { children: _jsx("div", { className: "flex flex-col p-4 pt-0 text-sm text-fd-muted-foreground", children: items.map((item) => (_jsx("a", { href: item.url, className: "border-s py-1.5 hover:text-fd-accent-foreground", style: {
|
|
8
|
+
paddingInlineStart: 12 * Math.max(item.depth - 1, 0),
|
|
9
|
+
}, children: item.title }, item.url))) }) })] }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { type ComponentProps, type PointerEvent, type ReactNode, type RefObject } from 'react';
|
|
2
|
+
import { type LinkProps } from 'fumadocs-core/link';
|
|
3
|
+
import { type ScrollAreaProps } from '../../components/ui/scroll-area.js';
|
|
4
|
+
import { type CollapsibleContentProps, type CollapsibleTriggerProps } from '../../components/ui/collapsible.js';
|
|
5
|
+
interface SidebarContext {
|
|
6
|
+
open: boolean;
|
|
7
|
+
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
8
|
+
collapsed: boolean;
|
|
9
|
+
setCollapsed: React.Dispatch<React.SetStateAction<boolean>>;
|
|
10
|
+
/**
|
|
11
|
+
* When set to false, don't close the sidebar when navigate to another page
|
|
12
|
+
*/
|
|
13
|
+
closeOnRedirect: RefObject<boolean>;
|
|
14
|
+
defaultOpenLevel: number;
|
|
15
|
+
prefetch: boolean;
|
|
16
|
+
mode: Mode;
|
|
17
|
+
}
|
|
18
|
+
export interface SidebarProviderProps {
|
|
19
|
+
/**
|
|
20
|
+
* Open folders by default if their level is lower or equal to a specific level
|
|
21
|
+
* (Starting from 1)
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue 0
|
|
24
|
+
*/
|
|
25
|
+
defaultOpenLevel?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Prefetch links
|
|
28
|
+
*
|
|
29
|
+
* @defaultValue true
|
|
30
|
+
*/
|
|
31
|
+
prefetch?: boolean;
|
|
32
|
+
children?: ReactNode;
|
|
33
|
+
}
|
|
34
|
+
type Mode = 'drawer' | 'full';
|
|
35
|
+
declare const SidebarContext: import("react").Context<SidebarContext | null>;
|
|
36
|
+
export declare function SidebarProvider({ defaultOpenLevel, prefetch, children, }: SidebarProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export declare function useSidebar(): SidebarContext;
|
|
38
|
+
export declare function useFolder(): {
|
|
39
|
+
open: boolean;
|
|
40
|
+
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
41
|
+
depth: number;
|
|
42
|
+
collapsible: boolean;
|
|
43
|
+
} | null;
|
|
44
|
+
export declare function useFolderDepth(): number;
|
|
45
|
+
export declare function SidebarContent({ children, }: {
|
|
46
|
+
children: (state: {
|
|
47
|
+
ref: RefObject<HTMLElement | null>;
|
|
48
|
+
collapsed: boolean;
|
|
49
|
+
hovered: boolean;
|
|
50
|
+
onPointerEnter: (event: PointerEvent) => void;
|
|
51
|
+
onPointerLeave: (event: PointerEvent) => void;
|
|
52
|
+
}) => ReactNode;
|
|
53
|
+
}): ReactNode;
|
|
54
|
+
export declare function SidebarDrawerOverlay(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element | undefined;
|
|
55
|
+
export declare function SidebarDrawerContent({ className, children, ...props }: ComponentProps<'aside'>): import("react/jsx-runtime").JSX.Element | undefined;
|
|
56
|
+
export declare function SidebarViewport({ className, ...props }: ScrollAreaProps): import("react/jsx-runtime").JSX.Element;
|
|
57
|
+
export declare function SidebarSeparator(props: ComponentProps<'p'>): import("react/jsx-runtime").JSX.Element;
|
|
58
|
+
export declare function SidebarItem({ icon, children, ...props }: LinkProps & {
|
|
59
|
+
icon?: ReactNode;
|
|
60
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
export declare function SidebarFolder({ defaultOpen: defaultOpenProp, collapsible, active, children, ...props }: ComponentProps<'div'> & {
|
|
62
|
+
active?: boolean;
|
|
63
|
+
defaultOpen?: boolean;
|
|
64
|
+
collapsible?: boolean;
|
|
65
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
66
|
+
export declare function SidebarFolderTrigger({ children, ...props }: CollapsibleTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
67
|
+
export declare function SidebarFolderLink({ children, ...props }: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
68
|
+
export declare function SidebarFolderContent(props: CollapsibleContentProps): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
export declare function SidebarTrigger({ children, ...props }: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
|
|
70
|
+
export declare function SidebarCollapseTrigger(props: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/base.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronDown, ExternalLink } from '@fumadocs/ui/icons';
|
|
4
|
+
import { createContext, use, useEffect, useMemo, useRef, useState, } from 'react';
|
|
5
|
+
import Link from 'fumadocs-core/link';
|
|
6
|
+
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
|
|
7
|
+
import { cn } from '@fumadocs/ui/cn';
|
|
8
|
+
import { ScrollArea, ScrollViewport, } from '../../components/ui/scroll-area.js';
|
|
9
|
+
import { isActive } from '@fumadocs/ui/urls';
|
|
10
|
+
import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '../../components/ui/collapsible.js';
|
|
11
|
+
import { useMediaQuery } from 'fumadocs-core/utils/use-media-query';
|
|
12
|
+
import scrollIntoView from 'scroll-into-view-if-needed';
|
|
13
|
+
import { usePathname } from 'fumadocs-core/framework';
|
|
14
|
+
import ReactDOM from 'react-dom';
|
|
15
|
+
const SidebarContext = createContext(null);
|
|
16
|
+
const FolderContext = createContext(null);
|
|
17
|
+
export function SidebarProvider({ defaultOpenLevel = 0, prefetch = true, children, }) {
|
|
18
|
+
const closeOnRedirect = useRef(true);
|
|
19
|
+
const [open, setOpen] = useState(false);
|
|
20
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
21
|
+
const pathname = usePathname();
|
|
22
|
+
const mode = useMediaQuery('(width < 768px)') ? 'drawer' : 'full';
|
|
23
|
+
useOnChange(pathname, () => {
|
|
24
|
+
if (closeOnRedirect.current) {
|
|
25
|
+
setOpen(false);
|
|
26
|
+
}
|
|
27
|
+
closeOnRedirect.current = true;
|
|
28
|
+
});
|
|
29
|
+
return (_jsx(SidebarContext, { value: useMemo(() => ({
|
|
30
|
+
open,
|
|
31
|
+
setOpen,
|
|
32
|
+
collapsed,
|
|
33
|
+
setCollapsed,
|
|
34
|
+
closeOnRedirect,
|
|
35
|
+
defaultOpenLevel,
|
|
36
|
+
prefetch,
|
|
37
|
+
mode,
|
|
38
|
+
}), [open, collapsed, defaultOpenLevel, prefetch, mode]), children: children }));
|
|
39
|
+
}
|
|
40
|
+
export function useSidebar() {
|
|
41
|
+
const ctx = use(SidebarContext);
|
|
42
|
+
if (!ctx)
|
|
43
|
+
throw new Error('Missing SidebarContext, make sure you have wrapped the component in <DocsLayout /> and the context is available.');
|
|
44
|
+
return ctx;
|
|
45
|
+
}
|
|
46
|
+
export function useFolder() {
|
|
47
|
+
return use(FolderContext);
|
|
48
|
+
}
|
|
49
|
+
export function useFolderDepth() {
|
|
50
|
+
return use(FolderContext)?.depth ?? 0;
|
|
51
|
+
}
|
|
52
|
+
export function SidebarContent({ children, }) {
|
|
53
|
+
const { collapsed, mode } = useSidebar();
|
|
54
|
+
const [hover, setHover] = useState(false);
|
|
55
|
+
const ref = useRef(null);
|
|
56
|
+
const timerRef = useRef(0);
|
|
57
|
+
useOnChange(collapsed, () => {
|
|
58
|
+
if (collapsed)
|
|
59
|
+
setHover(false);
|
|
60
|
+
});
|
|
61
|
+
if (mode !== 'full')
|
|
62
|
+
return;
|
|
63
|
+
function shouldIgnoreHover(e) {
|
|
64
|
+
const element = ref.current;
|
|
65
|
+
if (!element)
|
|
66
|
+
return true;
|
|
67
|
+
return (!collapsed ||
|
|
68
|
+
e.pointerType === 'touch' ||
|
|
69
|
+
element.getAnimations().length > 0);
|
|
70
|
+
}
|
|
71
|
+
return children({
|
|
72
|
+
ref,
|
|
73
|
+
collapsed,
|
|
74
|
+
hovered: hover,
|
|
75
|
+
onPointerEnter(e) {
|
|
76
|
+
if (shouldIgnoreHover(e))
|
|
77
|
+
return;
|
|
78
|
+
window.clearTimeout(timerRef.current);
|
|
79
|
+
setHover(true);
|
|
80
|
+
},
|
|
81
|
+
onPointerLeave(e) {
|
|
82
|
+
if (shouldIgnoreHover(e))
|
|
83
|
+
return;
|
|
84
|
+
window.clearTimeout(timerRef.current);
|
|
85
|
+
timerRef.current = window.setTimeout(() => setHover(false),
|
|
86
|
+
// if mouse is leaving the viewport, add a close delay
|
|
87
|
+
Math.min(e.clientX, document.body.clientWidth - e.clientX) > 100
|
|
88
|
+
? 0
|
|
89
|
+
: 500);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export function SidebarDrawerOverlay(props) {
|
|
94
|
+
const { open, setOpen, mode } = useSidebar();
|
|
95
|
+
const [hidden, setHidden] = useState(!open);
|
|
96
|
+
if (open && hidden)
|
|
97
|
+
setHidden(false);
|
|
98
|
+
if (mode !== 'drawer' || hidden)
|
|
99
|
+
return;
|
|
100
|
+
return (_jsx("div", { "data-state": open ? 'open' : 'closed', onClick: () => setOpen(false), onAnimationEnd: () => {
|
|
101
|
+
if (!open)
|
|
102
|
+
ReactDOM.flushSync(() => setHidden(true));
|
|
103
|
+
}, ...props }));
|
|
104
|
+
}
|
|
105
|
+
export function SidebarDrawerContent({ className, children, ...props }) {
|
|
106
|
+
const { open, mode } = useSidebar();
|
|
107
|
+
const [hidden, setHidden] = useState(!open);
|
|
108
|
+
if (open && hidden)
|
|
109
|
+
setHidden(false);
|
|
110
|
+
if (mode !== 'drawer')
|
|
111
|
+
return;
|
|
112
|
+
return (_jsx("aside", { id: "nd-sidebar-mobile", "data-state": open ? 'open' : 'closed', className: cn(hidden && 'invisible', className), onAnimationEnd: () => {
|
|
113
|
+
if (!open)
|
|
114
|
+
ReactDOM.flushSync(() => setHidden(true));
|
|
115
|
+
}, ...props, children: children }));
|
|
116
|
+
}
|
|
117
|
+
export function SidebarViewport({ className, ...props }) {
|
|
118
|
+
return (_jsx(ScrollArea, { className: (s) => cn('min-h-0 flex-1', typeof className === 'function' ? className(s) : className), ...props, children: _jsx(ScrollViewport, { className: "p-4 overscroll-contain", style: {
|
|
119
|
+
maskImage: 'linear-gradient(to bottom, transparent, white 12px, white calc(100% - 12px), transparent)',
|
|
120
|
+
}, children: props.children }) }));
|
|
121
|
+
}
|
|
122
|
+
export function SidebarSeparator(props) {
|
|
123
|
+
const depth = useFolderDepth();
|
|
124
|
+
return (_jsx("p", { ...props, className: cn('inline-flex items-center gap-2 mb-1.5 px-2 mt-6 empty:mb-0', depth === 0 && 'first:mt-0', props.className), children: props.children }));
|
|
125
|
+
}
|
|
126
|
+
export function SidebarItem({ icon, children, ...props }) {
|
|
127
|
+
const pathname = usePathname();
|
|
128
|
+
const ref = useRef(null);
|
|
129
|
+
const { prefetch } = useSidebar();
|
|
130
|
+
const active = props.href !== undefined && isActive(props.href, pathname, false);
|
|
131
|
+
useAutoScroll(active, ref);
|
|
132
|
+
return (_jsxs(Link, { ref: ref, "data-active": active, prefetch: prefetch, ...props, children: [icon ?? (props.external ? _jsx(ExternalLink, {}) : null), children] }));
|
|
133
|
+
}
|
|
134
|
+
export function SidebarFolder({ defaultOpen: defaultOpenProp, collapsible = true, active = false, children, ...props }) {
|
|
135
|
+
const { defaultOpenLevel } = useSidebar();
|
|
136
|
+
const depth = useFolderDepth() + 1;
|
|
137
|
+
const defaultOpen = collapsible === false ||
|
|
138
|
+
active ||
|
|
139
|
+
(defaultOpenProp ?? defaultOpenLevel >= depth);
|
|
140
|
+
const [open, setOpen] = useState(defaultOpen);
|
|
141
|
+
useOnChange(defaultOpen, (v) => {
|
|
142
|
+
if (v)
|
|
143
|
+
setOpen(v);
|
|
144
|
+
});
|
|
145
|
+
return (_jsx(Collapsible, { open: open, onOpenChange: setOpen, disabled: !collapsible, ...props, children: _jsx(FolderContext, { value: useMemo(() => ({ open, setOpen, depth, collapsible }), [collapsible, depth, open]), children: children }) }));
|
|
146
|
+
}
|
|
147
|
+
export function SidebarFolderTrigger({ children, ...props }) {
|
|
148
|
+
const { open, collapsible } = use(FolderContext);
|
|
149
|
+
if (collapsible) {
|
|
150
|
+
return (_jsxs(CollapsibleTrigger, { ...props, children: [children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
|
|
151
|
+
}
|
|
152
|
+
return _jsx("div", { ...props, children: children });
|
|
153
|
+
}
|
|
154
|
+
export function SidebarFolderLink({ children, ...props }) {
|
|
155
|
+
const ref = useRef(null);
|
|
156
|
+
const { open, setOpen, collapsible } = use(FolderContext);
|
|
157
|
+
const { prefetch } = useSidebar();
|
|
158
|
+
const pathname = usePathname();
|
|
159
|
+
const active = props.href !== undefined && isActive(props.href, pathname, false);
|
|
160
|
+
useAutoScroll(active, ref);
|
|
161
|
+
return (_jsxs(Link, { ref: ref, "data-active": active, onClick: (e) => {
|
|
162
|
+
if (!collapsible)
|
|
163
|
+
return;
|
|
164
|
+
if (e.target instanceof Element &&
|
|
165
|
+
e.target.matches('[data-icon], [data-icon] *')) {
|
|
166
|
+
setOpen(!open);
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
setOpen(active ? !open : true);
|
|
171
|
+
}
|
|
172
|
+
}, prefetch: prefetch, ...props, children: [children, collapsible && (_jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') }))] }));
|
|
173
|
+
}
|
|
174
|
+
export function SidebarFolderContent(props) {
|
|
175
|
+
return _jsx(CollapsibleContent, { ...props, children: props.children });
|
|
176
|
+
}
|
|
177
|
+
export function SidebarTrigger({ children, ...props }) {
|
|
178
|
+
const { setOpen } = useSidebar();
|
|
179
|
+
return (_jsx("button", { "aria-label": "Open Sidebar", onClick: () => setOpen((prev) => !prev), ...props, children: children }));
|
|
180
|
+
}
|
|
181
|
+
export function SidebarCollapseTrigger(props) {
|
|
182
|
+
const { collapsed, setCollapsed } = useSidebar();
|
|
183
|
+
return (_jsx("button", { type: "button", "aria-label": "Collapse Sidebar", "data-collapsed": collapsed, onClick: () => {
|
|
184
|
+
setCollapsed((prev) => !prev);
|
|
185
|
+
}, ...props, children: props.children }));
|
|
186
|
+
}
|
|
187
|
+
function useAutoScroll(active, ref) {
|
|
188
|
+
const { mode } = useSidebar();
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
if (active && ref.current) {
|
|
191
|
+
scrollIntoView(ref.current, {
|
|
192
|
+
boundary: document.getElementById(mode === 'drawer' ? 'nd-sidebar-mobile' : 'nd-sidebar'),
|
|
193
|
+
scrollMode: 'if-needed',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}, [active, mode, ref]);
|
|
197
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
import type * as Base from './base.js';
|
|
3
|
+
import type { LinkItemType } from '@fumadocs/ui/link-item';
|
|
4
|
+
type InternalComponents = Pick<typeof Base, 'SidebarFolder' | 'SidebarFolderLink' | 'SidebarFolderContent' | 'SidebarFolderTrigger' | 'SidebarItem'>;
|
|
5
|
+
export declare function createLinkItemRenderer({ SidebarFolder, SidebarFolderContent, SidebarFolderLink, SidebarFolderTrigger, SidebarItem, }: InternalComponents): ({ item, ...props }: HTMLAttributes<HTMLElement> & {
|
|
6
|
+
item: Exclude<LinkItemType, {
|
|
7
|
+
type: "icon";
|
|
8
|
+
}>;
|
|
9
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=link-item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link-item.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/link-item.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,KAAK,KAAK,IAAI,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,KAAK,kBAAkB,GAAG,IAAI,CAC5B,OAAO,IAAI,EACT,eAAe,GACf,mBAAmB,GACnB,sBAAsB,GACtB,sBAAsB,GACtB,aAAa,CAChB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,GACZ,EAAE,kBAAkB,IAIa,oBAG7B,cAAc,CAAC,WAAW,CAAC,GAAG;IAC/B,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/C,6CAoCF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function createLinkItemRenderer({ SidebarFolder, SidebarFolderContent, SidebarFolderLink, SidebarFolderTrigger, SidebarItem, }) {
|
|
3
|
+
/**
|
|
4
|
+
* Render sidebar items from page tree
|
|
5
|
+
*/
|
|
6
|
+
return function SidebarLinkItem({ item, ...props }) {
|
|
7
|
+
if (item.type === 'custom')
|
|
8
|
+
return _jsx("div", { ...props, children: item.children });
|
|
9
|
+
if (item.type === 'menu')
|
|
10
|
+
return (_jsxs(SidebarFolder, { ...props, children: [item.url ? (_jsxs(SidebarFolderLink, { href: item.url, external: item.external, children: [item.icon, item.text] })) : (_jsxs(SidebarFolderTrigger, { children: [item.icon, item.text] })), _jsx(SidebarFolderContent, { children: item.items.map((child, i) => (_jsx(SidebarLinkItem, { item: child }, i))) })] }));
|
|
11
|
+
return (_jsx(SidebarItem, { href: item.url, icon: item.icon, external: item.external, ...props, children: item.text }));
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FC, type ReactNode } from 'react';
|
|
2
|
+
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
3
|
+
import type * as Base from './base.js';
|
|
4
|
+
export interface SidebarPageTreeComponents {
|
|
5
|
+
Item: FC<{
|
|
6
|
+
item: PageTree.Item;
|
|
7
|
+
}>;
|
|
8
|
+
Folder: FC<{
|
|
9
|
+
item: PageTree.Folder;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}>;
|
|
12
|
+
Separator: FC<{
|
|
13
|
+
item: PageTree.Separator;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
type InternalComponents = Pick<typeof Base, 'SidebarSeparator' | 'SidebarFolder' | 'SidebarFolderLink' | 'SidebarFolderContent' | 'SidebarFolderTrigger' | 'SidebarItem'>;
|
|
17
|
+
export declare function createPageTreeRenderer({ SidebarFolder, SidebarFolderContent, SidebarFolderLink, SidebarFolderTrigger, SidebarSeparator, SidebarItem, }: InternalComponents): (components: Partial<SidebarPageTreeComponents>) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=page-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-tree.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/page-tree.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AACnE,OAAO,KAAK,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,KAAK,IAAI,MAAM,QAAQ,CAAC;AAEpC,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAA;KAAE,CAAC,CAAC;IAClC,MAAM,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC3D,SAAS,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAC7C;AAED,KAAK,kBAAkB,GAAG,IAAI,CAC5B,OAAO,IAAI,EACT,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,sBAAsB,GACtB,sBAAsB,GACtB,aAAa,CAChB,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,EACrC,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACZ,EAAE,kBAAkB,IAuCjB,YAAY,OAAO,CAAC,yBAAyB,CAAC,6CA6CjD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useTreeContext, useTreePath } from '../../contexts/tree.js';
|
|
3
|
+
import { useMemo, Fragment } from 'react';
|
|
4
|
+
export function createPageTreeRenderer({ SidebarFolder, SidebarFolderContent, SidebarFolderLink, SidebarFolderTrigger, SidebarSeparator, SidebarItem, }) {
|
|
5
|
+
function PageTreeFolder({ item, children, }) {
|
|
6
|
+
const path = useTreePath();
|
|
7
|
+
return (_jsxs(SidebarFolder, { collapsible: item.collapsible, active: path.includes(item), defaultOpen: item.defaultOpen, children: [item.index ? (_jsxs(SidebarFolderLink, { href: item.index.url, external: item.index.external, children: [item.icon, item.name] })) : (_jsxs(SidebarFolderTrigger, { children: [item.icon, item.name] })), _jsx(SidebarFolderContent, { children: children })] }));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Render sidebar items from page tree
|
|
11
|
+
*/
|
|
12
|
+
return function SidebarPageTree(components) {
|
|
13
|
+
const { root } = useTreeContext();
|
|
14
|
+
const { Separator, Item, Folder = PageTreeFolder } = components;
|
|
15
|
+
return useMemo(() => {
|
|
16
|
+
function renderSidebarList(items) {
|
|
17
|
+
return items.map((item, i) => {
|
|
18
|
+
if (item.type === 'separator') {
|
|
19
|
+
if (Separator)
|
|
20
|
+
return _jsx(Separator, { item: item }, i);
|
|
21
|
+
return (_jsxs(SidebarSeparator, { children: [item.icon, item.name] }, i));
|
|
22
|
+
}
|
|
23
|
+
if (item.type === 'folder') {
|
|
24
|
+
return (_jsx(Folder, { item: item, children: renderSidebarList(item.children) }, i));
|
|
25
|
+
}
|
|
26
|
+
if (Item)
|
|
27
|
+
return _jsx(Item, { item: item }, item.url);
|
|
28
|
+
return (_jsx(SidebarItem, { href: item.url, external: item.external, icon: item.icon, children: item.name }, item.url));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return (_jsx(Fragment, { children: renderSidebarList(root.children) }, root.$id));
|
|
32
|
+
}, [Folder, Item, Separator, root]);
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
|
+
import type { SidebarTab } from './index.js';
|
|
3
|
+
export interface SidebarTabWithProps extends SidebarTab {
|
|
4
|
+
props?: ComponentProps<'a'>;
|
|
5
|
+
}
|
|
6
|
+
export declare function SidebarTabsDropdown({ options, placeholder, ...props }: {
|
|
7
|
+
placeholder?: ReactNode;
|
|
8
|
+
options: SidebarTabWithProps[];
|
|
9
|
+
} & ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function isTabActive(tab: SidebarTab, pathname: string): boolean;
|
|
11
|
+
//# sourceMappingURL=dropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/tabs/dropdown.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAqB,MAAM,OAAO,CAAC;AAW/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC;AAEpC,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACrD,KAAK,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CAC7B;AAED,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,WAAW,EACX,GAAG,KAAK,EACT,EAAE;IACD,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,GAAG,cAAc,CAAC,QAAQ,CAAC,2CAkF3B;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAI5D"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Check, ChevronsUpDown } from '@fumadocs/ui/icons';
|
|
4
|
+
import { useMemo, useState } from 'react';
|
|
5
|
+
import Link from 'fumadocs-core/link';
|
|
6
|
+
import { usePathname } from 'fumadocs-core/framework';
|
|
7
|
+
import { cn } from '@fumadocs/ui/cn';
|
|
8
|
+
import { normalize, isActive } from '@fumadocs/ui/urls';
|
|
9
|
+
import { useSidebar } from '../../../components/sidebar/base.js';
|
|
10
|
+
import { Popover, PopoverContent, PopoverTrigger, } from '../../../components/ui/popover.js';
|
|
11
|
+
export function SidebarTabsDropdown({ options, placeholder, ...props }) {
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
const { closeOnRedirect } = useSidebar();
|
|
14
|
+
const pathname = usePathname();
|
|
15
|
+
const selected = useMemo(() => {
|
|
16
|
+
return options.findLast((item) => isTabActive(item, pathname));
|
|
17
|
+
}, [options, pathname]);
|
|
18
|
+
const onClick = () => {
|
|
19
|
+
closeOnRedirect.current = false;
|
|
20
|
+
setOpen(false);
|
|
21
|
+
};
|
|
22
|
+
const item = selected ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "size-9 shrink-0 empty:hidden md:size-5", children: selected.icon }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium", children: selected.title }), _jsx("p", { className: "text-sm text-fd-muted-foreground empty:hidden md:hidden", children: selected.description })] })] })) : (placeholder);
|
|
23
|
+
return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [item && (_jsxs(PopoverTrigger, { ...props, className: cn('flex items-center gap-2 rounded-lg p-2 border bg-fd-secondary/50 text-start text-fd-secondary-foreground transition-colors hover:bg-fd-accent data-[open]:bg-fd-accent data-[open]:text-fd-accent-foreground', props.className), children: [item, _jsx(ChevronsUpDown, { className: "shrink-0 ms-auto size-4 text-fd-muted-foreground" })] })), _jsx(PopoverContent, { className: "flex flex-col gap-1 w-(--anchor-width) p-1 fd-scroll-container", children: options.map((item) => {
|
|
24
|
+
const isActive = selected && item.url === selected.url;
|
|
25
|
+
if (!isActive && item.unlisted)
|
|
26
|
+
return;
|
|
27
|
+
return (_jsxs(Link, { href: item.url, onClick: onClick, ...item.props, className: cn('flex items-center gap-2 rounded-lg p-1.5 hover:bg-fd-accent hover:text-fd-accent-foreground', item.props?.className), children: [_jsx("div", { className: "shrink-0 size-9 md:mt-1 md:mb-auto md:size-5 empty:hidden", children: item.icon }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium", children: item.title }), _jsx("p", { className: "text-[0.8125rem] text-fd-muted-foreground empty:hidden", children: item.description })] }), _jsx(Check, { className: cn('shrink-0 ms-auto size-3.5 text-fd-primary', !isActive && 'invisible') })] }, item.url));
|
|
28
|
+
}) })] }));
|
|
29
|
+
}
|
|
30
|
+
export function isTabActive(tab, pathname) {
|
|
31
|
+
if (tab.urls)
|
|
32
|
+
return tab.urls.has(normalize(pathname));
|
|
33
|
+
return isActive(tab.url, pathname, true);
|
|
34
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type * as PageTree from 'fumadocs-core/page-tree';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
export interface SidebarTab {
|
|
4
|
+
/**
|
|
5
|
+
* Redirect URL of the folder, usually the index page
|
|
6
|
+
*/
|
|
7
|
+
url: string;
|
|
8
|
+
icon?: ReactNode;
|
|
9
|
+
title: ReactNode;
|
|
10
|
+
description?: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* Detect from a list of urls
|
|
13
|
+
*/
|
|
14
|
+
urls?: Set<string>;
|
|
15
|
+
unlisted?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface GetSidebarTabsOptions {
|
|
18
|
+
transform?: (option: SidebarTab, node: PageTree.Folder) => SidebarTab | null;
|
|
19
|
+
}
|
|
20
|
+
export declare function getSidebarTabs(tree: PageTree.Root, { transform }?: GetSidebarTabsOptions): SidebarTab[];
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/sidebar/tabs/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IAExB;;OAEG;IACH,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,KAAK,UAAU,GAAG,IAAI,CAAC;CAC9E;AAeD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,QAAQ,CAAC,IAAI,EACnB,EAAE,SAA4B,EAAE,GAAE,qBAA0B,GAC3D,UAAU,EAAE,CAkCd"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
const defaultTransform = (option, node) => {
|
|
3
|
+
if (!node.icon)
|
|
4
|
+
return option;
|
|
5
|
+
return {
|
|
6
|
+
...option,
|
|
7
|
+
icon: (_jsx("div", { className: "size-full [&_svg]:size-full max-md:p-1.5 max-md:rounded-md max-md:border max-md:bg-fd-secondary", children: node.icon })),
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export function getSidebarTabs(tree, { transform = defaultTransform } = {}) {
|
|
11
|
+
const results = [];
|
|
12
|
+
function scanOptions(node, unlisted) {
|
|
13
|
+
if ('root' in node && node.root) {
|
|
14
|
+
const urls = getFolderUrls(node);
|
|
15
|
+
if (urls.size > 0) {
|
|
16
|
+
const option = {
|
|
17
|
+
url: urls.values().next().value ?? '',
|
|
18
|
+
title: node.name,
|
|
19
|
+
icon: node.icon,
|
|
20
|
+
unlisted,
|
|
21
|
+
description: node.description,
|
|
22
|
+
urls,
|
|
23
|
+
};
|
|
24
|
+
const mapped = transform ? transform(option, node) : option;
|
|
25
|
+
if (mapped)
|
|
26
|
+
results.push(mapped);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const child of node.children) {
|
|
30
|
+
if (child.type === 'folder')
|
|
31
|
+
scanOptions(child, unlisted);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
scanOptions(tree);
|
|
35
|
+
if (tree.fallback)
|
|
36
|
+
scanOptions(tree.fallback, true);
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
function getFolderUrls(folder, output = new Set()) {
|
|
40
|
+
if (folder.index)
|
|
41
|
+
output.add(folder.index.url);
|
|
42
|
+
for (const child of folder.children) {
|
|
43
|
+
if (child.type === 'page' && !child.external)
|
|
44
|
+
output.add(child.url);
|
|
45
|
+
if (child.type === 'folder')
|
|
46
|
+
getFolderUrls(child, output);
|
|
47
|
+
}
|
|
48
|
+
return output;
|
|
49
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export declare function Steps({ children }: {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function Step({ children }: {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/components/steps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAE1D;AAED,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAEzD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
export function Steps({ children }) {
|
|
3
|
+
return _jsx("div", { className: "fd-steps", children: children });
|
|
4
|
+
}
|
|
5
|
+
export function Step({ children }) {
|
|
6
|
+
return _jsx("div", { className: "fd-step", children: children });
|
|
7
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
3
|
+
import * as Unstyled from './ui/tabs.js';
|
|
4
|
+
export interface TabsProps extends Omit<ComponentProps<typeof Unstyled.Tabs>, 'value' | 'onValueChange'> {
|
|
5
|
+
/**
|
|
6
|
+
* Use simple mode instead of advanced usage as documented in https://radix-ui.com/primitives/docs/components/tabs.
|
|
7
|
+
*/
|
|
8
|
+
items?: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Shortcut for `defaultValue` when `items` is provided.
|
|
11
|
+
*
|
|
12
|
+
* @defaultValue 0
|
|
13
|
+
*/
|
|
14
|
+
defaultIndex?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Additional label in tabs list when `items` is provided.
|
|
17
|
+
*/
|
|
18
|
+
label?: ReactNode;
|
|
19
|
+
}
|
|
20
|
+
export declare const TabsList: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").TabsListProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
21
|
+
export declare const TabsTrigger: React.ForwardRefExoticComponent<Omit<import("@base-ui/react").TabsTabProps & React.RefAttributes<Element>, "ref"> & React.RefAttributes<Element>>;
|
|
22
|
+
export declare function Tabs({ ref, className, items, label, defaultIndex, defaultValue, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export interface TabProps extends Omit<ComponentProps<typeof Unstyled.TabsContent>, 'value'> {
|
|
24
|
+
/**
|
|
25
|
+
* Value of tab, detect from index if unspecified.
|
|
26
|
+
*/
|
|
27
|
+
value?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function Tab({ value, ...props }: TabProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export declare function TabsContent({ value, className, ...props }: ComponentProps<typeof Unstyled.TabsContent>): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/components/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,SAAS,EAMf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAC;AAItC,MAAM,WAAW,SAAU,SAAQ,IAAI,CACrC,cAAc,CAAC,OAAO,QAAQ,CAAC,IAAI,CAAC,EACpC,OAAO,GAAG,eAAe,CAC1B;IACC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAaD,eAAO,MAAM,QAAQ,kKAcnB,CAAC;AAGH,eAAO,MAAM,WAAW,mJActB,CAAC;AAGH,wBAAgB,IAAI,CAAC,EACnB,GAAG,EACH,SAAS,EACT,KAAK,EACL,KAAK,EACL,YAAgB,EAChB,YAAmE,EACnE,GAAG,KAAK,EACT,EAAE,SAAS,2CAuCX;AAED,MAAM,WAAW,QAAS,SAAQ,IAAI,CACpC,cAAc,CAAC,OAAO,QAAQ,CAAC,WAAW,CAAC,EAC3C,OAAO,CACR;IACC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,QAAQ,2CAgBhD;AAED,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,WAAW,CAAC,2CAgB7C"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { createContext, useContext, useEffect, useId, useMemo, useState, } from 'react';
|
|
5
|
+
import { cn } from '@fumadocs/ui/cn';
|
|
6
|
+
import * as Unstyled from './ui/tabs.js';
|
|
7
|
+
const TabsContext = createContext(null);
|
|
8
|
+
function useTabContext() {
|
|
9
|
+
const ctx = useContext(TabsContext);
|
|
10
|
+
if (!ctx)
|
|
11
|
+
throw new Error('You must wrap your component in <Tabs>');
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
export const TabsList = React.forwardRef(({ className, ...props }, ref) => (_jsx(Unstyled.TabsList, { ref: ref, ...props, className: (s) => cn('flex gap-3.5 text-fd-secondary-foreground overflow-x-auto px-4 not-prose', typeof className === 'function' ? className(s) : className) })));
|
|
15
|
+
TabsList.displayName = 'TabsList';
|
|
16
|
+
export const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (_jsx(Unstyled.TabsTrigger, { ref: ref, ...props, className: (s) => cn('inline-flex items-center gap-2 whitespace-nowrap text-fd-muted-foreground border-b border-transparent py-2 text-sm font-medium transition-colors [&_svg]:size-4 hover:text-fd-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[active]:border-fd-primary data-[active]:text-fd-primary', typeof className === 'function' ? className(s) : className) })));
|
|
17
|
+
TabsTrigger.displayName = 'TabsTrigger';
|
|
18
|
+
export function Tabs({ ref, className, items, label, defaultIndex = 0, defaultValue = items ? escapeValue(items[defaultIndex]) : undefined, ...props }) {
|
|
19
|
+
const [value, setValue] = useState(defaultValue);
|
|
20
|
+
const collection = useMemo(() => [], []);
|
|
21
|
+
return (_jsxs(Unstyled.Tabs, { ref: ref, className: (s) => cn('flex flex-col overflow-hidden rounded-xl border bg-fd-secondary my-4', typeof className === 'function' ? className(s) : className), value: value, onValueChange: (v) => {
|
|
22
|
+
if (items && !items.some((item) => escapeValue(item) === v))
|
|
23
|
+
return;
|
|
24
|
+
setValue(v);
|
|
25
|
+
}, ...props, children: [items && (_jsxs(TabsList, { children: [label && (_jsx("span", { className: "text-sm font-medium my-auto me-auto", children: label })), items.map((item) => (_jsx(TabsTrigger, { value: escapeValue(item), children: item }, item)))] })), _jsx(TabsContext.Provider, { value: useMemo(() => ({ items, collection }), [collection, items]), children: props.children })] }));
|
|
26
|
+
}
|
|
27
|
+
export function Tab({ value, ...props }) {
|
|
28
|
+
const { items } = useTabContext();
|
|
29
|
+
const resolved = value ??
|
|
30
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks -- `value` is not supposed to change
|
|
31
|
+
items?.at(useCollectionIndex());
|
|
32
|
+
if (!resolved)
|
|
33
|
+
throw new Error('Failed to resolve tab `value`, please pass a `value` prop to the Tab component.');
|
|
34
|
+
return (_jsx(TabsContent, { value: escapeValue(resolved), ...props, children: props.children }));
|
|
35
|
+
}
|
|
36
|
+
export function TabsContent({ value, className, ...props }) {
|
|
37
|
+
return (_jsx(Unstyled.TabsContent, { value: value, keepMounted: true, className: (s) => cn('p-4 text-[0.9375rem] bg-fd-background rounded-xl outline-none prose-no-margin data-[inactive]:hidden [&>figure:only-child]:-m-4 [&>figure:only-child]:border-none', typeof className === 'function' ? className(s) : className), ...props, children: props.children }));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Inspired by Headless UI.
|
|
41
|
+
*
|
|
42
|
+
* Return the index of children, this is made possible by registering the order of render from children using React context.
|
|
43
|
+
* This is supposed by work with pre-rendering & pure client-side rendering.
|
|
44
|
+
*/
|
|
45
|
+
function useCollectionIndex() {
|
|
46
|
+
const key = useId();
|
|
47
|
+
const { collection } = useTabContext();
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
return () => {
|
|
50
|
+
const idx = collection.indexOf(key);
|
|
51
|
+
if (idx !== -1)
|
|
52
|
+
collection.splice(idx, 1);
|
|
53
|
+
};
|
|
54
|
+
}, [key, collection]);
|
|
55
|
+
if (!collection.includes(key))
|
|
56
|
+
collection.push(key);
|
|
57
|
+
return collection.indexOf(key);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* only escape whitespaces in values in simple mode
|
|
61
|
+
*/
|
|
62
|
+
function escapeValue(v) {
|
|
63
|
+
return v.toLowerCase().replace(/\s/, '-');
|
|
64
|
+
}
|