fumadocs-ui 15.3.1 → 15.3.3
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/css/preset.css +23 -5
- package/css/shiki.css +14 -16
- package/dist/components/callout.d.ts +1 -1
- package/dist/components/callout.d.ts.map +1 -1
- package/dist/components/callout.js +6 -2
- package/dist/components/codeblock.d.ts +2 -3
- package/dist/components/codeblock.d.ts.map +1 -1
- package/dist/components/codeblock.js +8 -9
- package/dist/components/dialog/search-algolia.d.ts.map +1 -1
- package/dist/components/dialog/search-algolia.js +3 -3
- package/dist/components/dialog/search-default.d.ts.map +1 -1
- package/dist/components/dialog/search-default.js +2 -2
- package/dist/components/dialog/search-orama.d.ts.map +1 -1
- package/dist/components/dialog/search-orama.js +3 -3
- package/dist/components/dialog/search.d.ts +10 -9
- package/dist/components/dialog/search.d.ts.map +1 -1
- package/dist/components/dialog/search.js +30 -27
- package/dist/components/layout/sidebar.d.ts +1 -1
- package/dist/components/layout/sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar.js +10 -9
- package/dist/components/layout/toc.d.ts +1 -4
- package/dist/components/layout/toc.d.ts.map +1 -1
- package/dist/components/layout/toc.js +3 -5
- package/dist/components/tabs.d.ts +18 -9
- package/dist/components/tabs.d.ts.map +1 -1
- package/dist/components/tabs.js +22 -18
- package/dist/components/ui/hide-if-empty.d.ts +10 -0
- package/dist/components/ui/hide-if-empty.d.ts.map +1 -0
- package/dist/components/ui/hide-if-empty.js +64 -0
- package/dist/components/ui/navigation-menu.js +1 -1
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.js +1 -1
- package/dist/components/ui/tabs.js +2 -2
- package/dist/layouts/docs-client.d.ts +3 -3
- package/dist/layouts/docs-client.d.ts.map +1 -1
- package/dist/layouts/docs-client.js +4 -3
- package/dist/layouts/docs.d.ts +1 -1
- package/dist/layouts/docs.d.ts.map +1 -1
- package/dist/layouts/docs.js +8 -10
- package/dist/layouts/home/navbar.js +5 -5
- package/dist/layouts/home.d.ts.map +1 -1
- package/dist/layouts/home.js +1 -1
- package/dist/layouts/notebook-client.d.ts +0 -3
- package/dist/layouts/notebook-client.d.ts.map +1 -1
- package/dist/layouts/notebook-client.js +1 -7
- package/dist/layouts/notebook.d.ts.map +1 -1
- package/dist/layouts/notebook.js +16 -7
- package/dist/mdx.d.ts +1 -1
- package/dist/page-client.js +1 -1
- package/dist/page.d.ts +7 -9
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +5 -5
- package/dist/style.css +87 -58
- package/package.json +10 -10
package/css/preset.css
CHANGED
|
@@ -20,14 +20,16 @@
|
|
|
20
20
|
--animate-fd-fade-in: fd-fade-in 300ms ease;
|
|
21
21
|
--animate-fd-fade-out: fd-fade-out 300ms ease;
|
|
22
22
|
|
|
23
|
-
--animate-fd-dialog-in: fd-dialog-in
|
|
24
|
-
--animate-fd-dialog-out: fd-dialog-out
|
|
23
|
+
--animate-fd-dialog-in: fd-dialog-in 240ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
24
|
+
--animate-fd-dialog-out: fd-dialog-out 240ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
25
25
|
|
|
26
26
|
--animate-fd-popover-in: fd-popover-in 150ms ease;
|
|
27
27
|
--animate-fd-popover-out: fd-popover-out 150ms ease;
|
|
28
28
|
|
|
29
|
-
--animate-fd-collapsible-down: fd-collapsible-down 150ms
|
|
30
|
-
|
|
29
|
+
--animate-fd-collapsible-down: fd-collapsible-down 150ms
|
|
30
|
+
cubic-bezier(0.45, 0, 0.55, 1);
|
|
31
|
+
--animate-fd-collapsible-up: fd-collapsible-up 150ms
|
|
32
|
+
cubic-bezier(0.45, 0, 0.55, 1);
|
|
31
33
|
|
|
32
34
|
--animate-fd-accordion-down: fd-accordion-down 200ms ease-out;
|
|
33
35
|
--animate-fd-accordion-up: fd-accordion-up 200ms ease-out;
|
|
@@ -96,7 +98,7 @@
|
|
|
96
98
|
transform: scale(1);
|
|
97
99
|
}
|
|
98
100
|
to {
|
|
99
|
-
transform: scale(1.
|
|
101
|
+
transform: scale(1.04);
|
|
100
102
|
opacity: 0;
|
|
101
103
|
}
|
|
102
104
|
}
|
|
@@ -227,6 +229,22 @@
|
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
231
|
|
|
232
|
+
@utility fd-scroll-container {
|
|
233
|
+
&::-webkit-scrollbar {
|
|
234
|
+
width: 5px;
|
|
235
|
+
height: 5px;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
&::-webkit-scrollbar-thumb {
|
|
239
|
+
border-radius: 5px;
|
|
240
|
+
background: var(--color-fd-border);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
&::-webkit-scrollbar-track {
|
|
244
|
+
background: transparent;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
230
248
|
@utility fd-steps {
|
|
231
249
|
counter-reset: step;
|
|
232
250
|
position: relative;
|
package/css/shiki.css
CHANGED
|
@@ -4,8 +4,18 @@
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
code .line {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
line-height: 1.45em;
|
|
8
|
+
min-height: 1.45em;
|
|
9
|
+
@apply relative;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&.has-focused code .line:not(.focused) {
|
|
13
|
+
filter: blur(2px);
|
|
14
|
+
transition: filter 200ms;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&.has-focused:hover code .line:not(.focused) {
|
|
18
|
+
filter: blur(0);
|
|
9
19
|
}
|
|
10
20
|
|
|
11
21
|
&[data-line-numbers] code .twoslash-meta-line {
|
|
@@ -48,25 +58,13 @@
|
|
|
48
58
|
@apply text-fd-diff-add-symbol;
|
|
49
59
|
}
|
|
50
60
|
|
|
51
|
-
code .diff {
|
|
52
|
-
@apply relative;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
61
|
.highlighted {
|
|
56
62
|
@apply bg-fd-primary/10;
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
.highlighted-word {
|
|
60
|
-
padding: 1px
|
|
61
|
-
|
|
62
|
-
border: 1px solid
|
|
63
|
-
color-mix(in oklab, var(--color-fd-primary) 50%, transparent);
|
|
64
|
-
background-color: color-mix(
|
|
65
|
-
in oklab,
|
|
66
|
-
var(--color-fd-primary) 10%,
|
|
67
|
-
transparent
|
|
68
|
-
);
|
|
69
|
-
border-radius: 2px;
|
|
66
|
+
padding: 1px;
|
|
67
|
+
@apply border -my-px border-fd-primary/30 bg-fd-primary/10 rounded-md font-medium;
|
|
70
68
|
}
|
|
71
69
|
}
|
|
72
70
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callout.d.ts","sourceRoot":"","sources":["../../src/components/callout.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"callout.d.ts","sourceRoot":"","sources":["../../src/components/callout.tsx"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAkCxE,eAAO,MAAM,OAAO;YA1BV,SAAS;IACjB;;OAEG;WACI,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS;IAExD;;OAEG;WACI,SAAS;kDAoDjB,CAAC"}
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { CircleX, Info, TriangleAlert } from '../icons.js';
|
|
2
|
+
import { CircleCheck, CircleX, Info, TriangleAlert } from '../icons.js';
|
|
3
3
|
import { forwardRef } from 'react';
|
|
4
4
|
import { cn } from '../utils/cn.js';
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
|
-
const calloutVariants = cva('my-4 flex
|
|
6
|
+
const calloutVariants = cva('my-4 flex gap-2 rounded-lg border border-s-2 bg-fd-card p-3 text-sm text-fd-card-foreground shadow-md', {
|
|
7
7
|
variants: {
|
|
8
8
|
type: {
|
|
9
9
|
info: 'border-s-blue-500/50',
|
|
10
10
|
warn: 'border-s-orange-500/50',
|
|
11
11
|
error: 'border-s-red-500/50',
|
|
12
|
+
success: 'border-s-green-500/50',
|
|
12
13
|
},
|
|
13
14
|
},
|
|
14
15
|
});
|
|
15
16
|
export const Callout = forwardRef(({ className, children, title, type = 'info', icon, ...props }, ref) => {
|
|
17
|
+
if (type === 'warning')
|
|
18
|
+
type = 'warn';
|
|
16
19
|
return (_jsxs("div", { ref: ref, className: cn(calloutVariants({
|
|
17
20
|
type: type,
|
|
18
21
|
}), className), ...props, children: [icon ??
|
|
@@ -20,6 +23,7 @@ export const Callout = forwardRef(({ className, children, title, type = 'info',
|
|
|
20
23
|
info: _jsx(Info, { className: "size-5 fill-blue-500 text-fd-card" }),
|
|
21
24
|
warn: (_jsx(TriangleAlert, { className: "size-5 fill-orange-500 text-fd-card" })),
|
|
22
25
|
error: _jsx(CircleX, { className: "size-5 fill-red-500 text-fd-card" }),
|
|
26
|
+
success: (_jsx(CircleCheck, { className: "size-5 fill-green-500 text-fd-card" })),
|
|
23
27
|
}[type], _jsxs("div", { className: "min-w-0 flex flex-col gap-2 flex-1", children: [title ? _jsx("p", { className: "font-medium !my-0", children: title }) : null, _jsx("div", { className: "text-fd-muted-foreground prose-no-margin empty:hidden", children: children })] })] }));
|
|
24
28
|
});
|
|
25
29
|
Callout.displayName = 'Callout';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
-
import type { ScrollAreaViewportProps } from '@radix-ui/react-scroll-area';
|
|
3
2
|
export type CodeBlockProps = HTMLAttributes<HTMLElement> & {
|
|
4
3
|
/**
|
|
5
4
|
* Icon of code block
|
|
@@ -19,7 +18,7 @@ export type CodeBlockProps = HTMLAttributes<HTMLElement> & {
|
|
|
19
18
|
* @defaultValue false
|
|
20
19
|
*/
|
|
21
20
|
keepBackground?: boolean;
|
|
22
|
-
viewportProps?:
|
|
21
|
+
viewportProps?: HTMLAttributes<HTMLElement>;
|
|
23
22
|
/**
|
|
24
23
|
* show line numbers
|
|
25
24
|
*/
|
|
@@ -49,7 +48,7 @@ export declare const CodeBlock: import("react").ForwardRefExoticComponent<HTMLAt
|
|
|
49
48
|
* @defaultValue false
|
|
50
49
|
*/
|
|
51
50
|
keepBackground?: boolean;
|
|
52
|
-
viewportProps?:
|
|
51
|
+
viewportProps?: HTMLAttributes<HTMLElement>;
|
|
53
52
|
/**
|
|
54
53
|
* show line numbers
|
|
55
54
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codeblock.d.ts","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"codeblock.d.ts","sourceRoot":"","sources":["../../src/components/codeblock.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAKf,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG;IACzD;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,aAAa,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;IAE5C;;OAEG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,eAAO,MAAM,GAAG,2HAYf,CAAC;AAIF,eAAO,MAAM,SAAS;IAlDpB;;;;OAIG;WACI,SAAS;IAEhB;;;;OAIG;gBACS,OAAO;IAEnB;;;;OAIG;qBACc,OAAO;oBAER,cAAc,CAAC,WAAW,CAAC;IAE3C;;OAEG;0BACmB,OAAO;IAE7B;;OAEG;gCACyB,MAAM;+CA2GnC,CAAC"}
|
|
@@ -3,11 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { Check, Copy } from '../icons.js';
|
|
4
4
|
import { forwardRef, useRef, } from 'react';
|
|
5
5
|
import { cn } from '../utils/cn.js';
|
|
6
|
-
import { ScrollArea, ScrollBar, ScrollViewport, } from '../components/ui/scroll-area.js';
|
|
7
6
|
import { useCopyButton } from '../utils/use-copy-button.js';
|
|
8
7
|
import { buttonVariants } from '../components/ui/button.js';
|
|
9
8
|
export const Pre = forwardRef(({ className, ...props }, ref) => {
|
|
10
|
-
return (_jsx("pre", { ref: ref, className: cn('
|
|
9
|
+
return (_jsx("pre", { ref: ref, className: cn('min-w-full w-max *:flex *:flex-col', className), ...props, children: props.children }));
|
|
11
10
|
});
|
|
12
11
|
Pre.displayName = 'Pre';
|
|
13
12
|
export const CodeBlock = forwardRef(({ title, allowCopy = true, keepBackground = false, icon, viewportProps, children, ...props }, ref) => {
|
|
@@ -22,16 +21,16 @@ export const CodeBlock = forwardRef(({ title, allowCopy = true, keepBackground =
|
|
|
22
21
|
});
|
|
23
22
|
void navigator.clipboard.writeText(clone.textContent ?? '');
|
|
24
23
|
};
|
|
25
|
-
return (_jsxs("figure", { ref: ref, ...props, className: cn('not-prose group relative my-4 overflow-hidden rounded-lg border bg-fd-card text-sm outline-none', keepBackground && 'bg-(--shiki-light-bg) dark:bg-(--shiki-dark-bg)', props.className), children: [title ? (_jsxs("div", { className: "flex items-center gap-2 bg-fd-secondary px-4 py-1.5", children: [icon ? (_jsx("div", { className: "text-fd-muted-foreground [&_svg]:size-3.5", dangerouslySetInnerHTML: typeof icon === 'string'
|
|
24
|
+
return (_jsxs("figure", { ref: ref, dir: "ltr", ...props, className: cn('not-prose group relative my-4 overflow-hidden rounded-lg border bg-fd-card text-sm outline-none', keepBackground && 'bg-(--shiki-light-bg) dark:bg-(--shiki-dark-bg)', props.className), children: [title ? (_jsxs("div", { className: "flex items-center gap-2 bg-fd-secondary px-4 py-1.5", children: [icon ? (_jsx("div", { className: "text-fd-muted-foreground [&_svg]:size-3.5", dangerouslySetInnerHTML: typeof icon === 'string'
|
|
26
25
|
? {
|
|
27
26
|
__html: icon,
|
|
28
27
|
}
|
|
29
|
-
: undefined, children: typeof icon !== 'string' ? icon : null })) : null, _jsx("figcaption", { className: "flex-1 truncate text-fd-muted-foreground", children: title }), allowCopy ? (_jsx(CopyButton, { className: "-me-2", onCopy: onCopy })) : null] })) : (allowCopy && (_jsx(CopyButton, { className: "absolute right-2 top-2 z-[2] backdrop-blur-md", onCopy: onCopy }))),
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
: undefined, children: typeof icon !== 'string' ? icon : null })) : null, _jsx("figcaption", { className: "flex-1 truncate text-fd-muted-foreground", children: title }), allowCopy ? (_jsx(CopyButton, { className: "-me-2", onCopy: onCopy })) : null] })) : (allowCopy && (_jsx(CopyButton, { className: "absolute right-2 top-2 z-[2] backdrop-blur-md", onCopy: onCopy }))), _jsx("div", { ref: areaRef, ...viewportProps, className: cn('text-[13px] py-3.5 overflow-auto [&_.line]:px-4 max-h-[600px] fd-scroll-container', props['data-line-numbers'] && '[&_.line]:pl-3', viewportProps?.className), style: {
|
|
29
|
+
counterSet: props['data-line-numbers']
|
|
30
|
+
? `line ${Number(props['data-line-numbers-start'] ?? 1) - 1}`
|
|
31
|
+
: undefined,
|
|
32
|
+
...viewportProps?.style,
|
|
33
|
+
}, children: children })] }));
|
|
35
34
|
});
|
|
36
35
|
CodeBlock.displayName = 'CodeBlock';
|
|
37
36
|
function CopyButton({ className, onCopy, ...props }) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-algolia.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search-algolia.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"search-algolia.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search-algolia.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,cAAc,EAEpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAEjD,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,OAAO,EAGb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,wBAAyB,SAAQ,WAAW;IAC3D,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IAEjB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,KAAK,EACL,aAAa,EACb,IAAI,EACJ,UAAU,EACV,WAAmB,EACnB,UAAkB,EAClB,GAAG,KAAK,EACT,EAAE,wBAAwB,GAAG,SAAS,CA0CtC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useDocsSearch, } from 'fumadocs-core/search/client';
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
|
|
6
|
-
import { SearchDialog, TagsList, } from './search.js';
|
|
6
|
+
import { SearchDialog, TagsList, TagsListItem, } from './search.js';
|
|
7
7
|
export default function AlgoliaSearchDialog({ index, searchOptions, tags, defaultTag, showAlgolia = false, allowClear = false, ...props }) {
|
|
8
8
|
const [tag, setTag] = useState(defaultTag);
|
|
9
9
|
const { search, setSearch, query } = useDocsSearch({
|
|
@@ -14,7 +14,7 @@ export default function AlgoliaSearchDialog({ index, searchOptions, tags, defaul
|
|
|
14
14
|
useOnChange(defaultTag, (v) => {
|
|
15
15
|
setTag(v);
|
|
16
16
|
});
|
|
17
|
-
return (_jsx(SearchDialog, { search: search, onSearchChange: setSearch, results: query.data ?? [], isLoading: query.isLoading, ...props, footer:
|
|
17
|
+
return (_jsx(SearchDialog, { search: search, onSearchChange: setSearch, results: query.data ?? [], isLoading: query.isLoading, ...props, footer: _jsxs(_Fragment, { children: [tags ? (_jsxs(TagsList, { tag: tag, onTagChange: setTag, allowClear: allowClear, children: [tags.map((tag) => (_jsx(TagsListItem, { value: tag.value, children: tag.name }, tag.value))), showAlgolia && _jsx(AlgoliaTitle, {})] })) : (showAlgolia && _jsx(AlgoliaTitle, {})), props.footer] }) }));
|
|
18
18
|
}
|
|
19
19
|
function AlgoliaTitle() {
|
|
20
20
|
return (_jsx("a", { href: "https://algolia.com", rel: "noreferrer noopener", className: "ms-auto text-xs text-fd-muted-foreground", children: "Search powered by Algolia" }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-default.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search-default.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAGjD,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"search-default.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search-default.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAGjD,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,OAAO,EAGb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,wBAAyB,SAAQ,WAAW;IAC3D;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAE1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IAEjB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAC1C,UAAU,EACV,IAAI,EACJ,GAAG,EACH,OAAO,EACP,IAAc,EACd,UAAkB,EAClB,GAAG,KAAK,EACT,EAAE,wBAAwB,GAAG,SAAS,CA6CtC"}
|
|
@@ -4,7 +4,7 @@ import { useDocsSearch } from 'fumadocs-core/search/client';
|
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
|
|
6
6
|
import { useI18n } from '../../contexts/i18n.js';
|
|
7
|
-
import { SearchDialog, TagsList, } from './search.js';
|
|
7
|
+
import { SearchDialog, TagsList, TagsListItem, } from './search.js';
|
|
8
8
|
export default function DefaultSearchDialog({ defaultTag, tags, api, delayMs, type = 'fetch', allowClear = false, ...props }) {
|
|
9
9
|
const { locale } = useI18n();
|
|
10
10
|
const [tag, setTag] = useState(defaultTag);
|
|
@@ -20,5 +20,5 @@ export default function DefaultSearchDialog({ defaultTag, tags, api, delayMs, ty
|
|
|
20
20
|
useOnChange(defaultTag, (v) => {
|
|
21
21
|
setTag(v);
|
|
22
22
|
});
|
|
23
|
-
return (_jsx(SearchDialog, { search: search, onSearchChange: setSearch, isLoading: query.isLoading, results: query.data ?? [], ...props, footer:
|
|
23
|
+
return (_jsx(SearchDialog, { search: search, onSearchChange: setSearch, isLoading: query.isLoading, results: query.data ?? [], ...props, footer: _jsxs(_Fragment, { children: [tags && (_jsx(TagsList, { tag: tag, onTagChange: setTag, allowClear: allowClear, children: tags.map((tag) => (_jsx(TagsListItem, { value: tag.value, children: tag.name }, tag.value))) })), props.footer] }) }));
|
|
24
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-orama.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search-orama.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"search-orama.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search-orama.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAEjD,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,OAAO,EAGb,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACpC,aAAa,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IAEjB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,MAAM,EACN,aAAa,EACb,IAAI,EACJ,UAAU,EACV,SAAiB,EACjB,UAAkB,EAClB,KAAK,EACL,GAAG,KAAK,EACT,EAAE,sBAAsB,GAAG,SAAS,CA2CpC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useDocsSearch, } from 'fumadocs-core/search/client';
|
|
4
4
|
import { useState } from 'react';
|
|
5
5
|
import { useOnChange } from 'fumadocs-core/utils/use-on-change';
|
|
6
|
-
import { SearchDialog, TagsList, } from './search.js';
|
|
6
|
+
import { SearchDialog, TagsList, TagsListItem, } from './search.js';
|
|
7
7
|
/**
|
|
8
8
|
* Orama Cloud integration
|
|
9
9
|
*/
|
|
@@ -18,7 +18,7 @@ export default function OramaSearchDialog({ client, searchOptions, tags, default
|
|
|
18
18
|
useOnChange(defaultTag, (v) => {
|
|
19
19
|
setTag(v);
|
|
20
20
|
});
|
|
21
|
-
return (_jsx(SearchDialog, { search: search, onSearchChange: setSearch, results: query.data ?? [], isLoading: query.isLoading, ...props, footer:
|
|
21
|
+
return (_jsx(SearchDialog, { search: search, onSearchChange: setSearch, results: query.data ?? [], isLoading: query.isLoading, ...props, footer: _jsxs(_Fragment, { children: [tags ? (_jsxs(TagsList, { tag: tag, onTagChange: setTag, allowClear: allowClear, children: [tags.map((tag) => (_jsx(TagsListItem, { value: tag.value, children: tag.name }, tag.value))), showOrama && _jsx(Label, {})] })) : (showOrama && _jsx(Label, {})), props.footer] }) }));
|
|
22
22
|
}
|
|
23
23
|
function Label() {
|
|
24
24
|
return (_jsx("a", { href: "https://orama.com", rel: "noreferrer noopener", className: "ms-auto text-xs text-fd-muted-foreground", children: "Search powered by Orama" }));
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
2
2
|
import type { SortedResult } from 'fumadocs-core/server';
|
|
3
3
|
export type SearchLink = [name: string, href: string];
|
|
4
4
|
type ReactSortedResult = Omit<SortedResult, 'content'> & {
|
|
5
5
|
external?: boolean;
|
|
6
6
|
content: ReactNode;
|
|
7
7
|
};
|
|
8
|
+
export interface TagItem {
|
|
9
|
+
name: string;
|
|
10
|
+
value: string;
|
|
11
|
+
}
|
|
8
12
|
export interface SharedProps {
|
|
9
13
|
open: boolean;
|
|
10
14
|
onOpenChange: (open: boolean) => void;
|
|
@@ -22,17 +26,14 @@ interface SearchDialogProps extends SharedProps {
|
|
|
22
26
|
footer?: ReactNode;
|
|
23
27
|
}
|
|
24
28
|
export declare function SearchDialog({ open, onOpenChange, footer, links, search, onSearchChange, isLoading, ...props }: SearchDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
-
export interface
|
|
26
|
-
name: string;
|
|
27
|
-
value: string | undefined;
|
|
28
|
-
props?: HTMLAttributes<HTMLButtonElement>;
|
|
29
|
-
}
|
|
30
|
-
export interface TagsListProps extends HTMLAttributes<HTMLDivElement> {
|
|
29
|
+
export interface TagsListProps extends ComponentProps<'div'> {
|
|
31
30
|
tag?: string;
|
|
32
31
|
onTagChange: (tag: string | undefined) => void;
|
|
33
32
|
allowClear?: boolean;
|
|
34
|
-
items: TagItem[];
|
|
35
33
|
}
|
|
36
|
-
export declare function TagsList({ tag, onTagChange,
|
|
34
|
+
export declare function TagsList({ tag, onTagChange, allowClear, ...props }: TagsListProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export declare function TagsListItem({ value, className, ...props }: ComponentProps<'button'> & {
|
|
36
|
+
value: string;
|
|
37
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
37
38
|
export {};
|
|
38
39
|
//# sourceMappingURL=search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search.tsx"],"names":[],"mappings":"AASA,OAAO,
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search.tsx"],"names":[],"mappings":"AASA,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AAWf,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKzD,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAEtD,KAAK,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAEtC;;OAEG;IACH,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,UAAU,iBAAkB,SAAQ,WAAW;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC;IAEvC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,YAAY,EACZ,MAAM,EACN,KAAU,EACV,MAAM,EACN,cAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EAAE,iBAAiB,2CA6DnB;AAoJD,MAAM,WAAW,aAAc,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAmBD,wBAAgB,QAAQ,CAAC,EACvB,GAAG,EACH,WAAW,EACX,UAAkB,EAClB,GAAG,KAAK,EACT,EAAE,aAAa,2CAoBf;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf,2CAmBA"}
|
|
@@ -9,9 +9,10 @@ import { buttonVariants } from '../../components/ui/button.js';
|
|
|
9
9
|
import { Dialog, DialogContent, DialogOverlay, DialogTitle, } from '@radix-ui/react-dialog';
|
|
10
10
|
import { cva } from 'class-variance-authority';
|
|
11
11
|
import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
|
|
12
|
-
import { useRouter } from 'fumadocs-core/framework';
|
|
12
|
+
import { createContext, useRouter } from 'fumadocs-core/framework';
|
|
13
13
|
export function SearchDialog({ open, onOpenChange, footer, links = [], search, onSearchChange, isLoading, ...props }) {
|
|
14
14
|
const { text } = useI18n();
|
|
15
|
+
const [active, setActive] = useState();
|
|
15
16
|
const defaultItems = useMemo(() => links.map(([name, link]) => ({
|
|
16
17
|
type: 'page',
|
|
17
18
|
id: name,
|
|
@@ -20,25 +21,21 @@ export function SearchDialog({ open, onOpenChange, footer, links = [], search, o
|
|
|
20
21
|
})), [links]);
|
|
21
22
|
return (_jsxs(Dialog, { open: open, onOpenChange: onOpenChange, children: [_jsx(DialogOverlay, { className: "fixed inset-0 z-50 bg-black/30 backdrop-blur-sm data-[state=closed]:animate-fd-fade-out data-[state=open]:animate-fd-fade-in" }), _jsxs(DialogContent, { "aria-describedby": undefined, className: "fixed left-1/2 top-[10vh] z-50 w-[98vw] max-w-screen-sm -translate-x-1/2 rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-lg data-[state=closed]:animate-fd-dialog-out data-[state=open]:animate-fd-dialog-in", children: [_jsx(DialogTitle, { className: "hidden", children: text.search }), _jsxs("div", { className: "flex flex-row items-center gap-2 px-3", children: [_jsx(LoadingIndicator, { isLoading: isLoading ?? false }), _jsx("input", { value: search, onChange: (e) => {
|
|
22
23
|
onSearchChange(e.target.value);
|
|
24
|
+
setActive(undefined);
|
|
23
25
|
}, placeholder: text.search, className: "w-0 flex-1 bg-transparent py-3 text-base placeholder:text-fd-muted-foreground focus-visible:outline-none" }), _jsx("button", { type: "button", "aria-label": "Close Search", onClick: () => onOpenChange(false), className: cn(buttonVariants({
|
|
24
26
|
color: 'outline',
|
|
25
27
|
className: 'text-xs p-1.5',
|
|
26
|
-
})), children: "Esc" })] }), props.results !== 'empty' || defaultItems.length > 0 ? (_jsx(SearchResults, { items: props.results === 'empty' ? defaultItems : props.results, onSelect: () => onOpenChange(false) })) : null,
|
|
28
|
+
})), children: "Esc" })] }), props.results !== 'empty' || defaultItems.length > 0 ? (_jsx(SearchResults, { active: active, onActiveChange: setActive, items: props.results === 'empty' ? defaultItems : props.results, onSelect: () => onOpenChange(false) })) : null, _jsx("div", { className: "mt-auto flex flex-col border-t p-3 empty:hidden", children: footer })] })] }));
|
|
27
29
|
}
|
|
28
30
|
const icons = {
|
|
29
31
|
text: _jsx(Text, { className: "size-4 text-fd-muted-foreground" }),
|
|
30
32
|
heading: _jsx(Hash, { className: "size-4 text-fd-muted-foreground" }),
|
|
31
33
|
page: _jsx(FileText, { className: "size-4 text-fd-muted-foreground" }),
|
|
32
34
|
};
|
|
33
|
-
function SearchResults({ items, onSelect, ...props }) {
|
|
34
|
-
const [active, setActive] = useState();
|
|
35
|
+
function SearchResults({ items, active = items.at(0)?.id, onActiveChange, onSelect, ...props }) {
|
|
35
36
|
const { text } = useI18n();
|
|
36
37
|
const router = useRouter();
|
|
37
38
|
const sidebar = useSidebar();
|
|
38
|
-
if (items.length > 0 &&
|
|
39
|
-
(!active || items.every((item) => item.id !== active))) {
|
|
40
|
-
setActive(items[0].id);
|
|
41
|
-
}
|
|
42
39
|
const onOpen = ({ external, url }) => {
|
|
43
40
|
if (external)
|
|
44
41
|
window.open(url, '_blank')?.focus();
|
|
@@ -49,12 +46,14 @@ function SearchResults({ items, onSelect, ...props }) {
|
|
|
49
46
|
};
|
|
50
47
|
const onKey = useEffectEvent((e) => {
|
|
51
48
|
if (e.key === 'ArrowDown' || e.key == 'ArrowUp') {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
const idx = items.findIndex((item) => item.id === active);
|
|
50
|
+
if (idx === -1) {
|
|
51
|
+
onActiveChange(items.at(0)?.id);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
onActiveChange(items.at((e.key === 'ArrowDown' ? idx + 1 : idx - 1) % items.length)
|
|
55
|
+
?.id);
|
|
56
|
+
}
|
|
58
57
|
e.preventDefault();
|
|
59
58
|
}
|
|
60
59
|
if (e.key === 'Enter') {
|
|
@@ -70,21 +69,21 @@ function SearchResults({ items, onSelect, ...props }) {
|
|
|
70
69
|
window.removeEventListener('keydown', onKey);
|
|
71
70
|
};
|
|
72
71
|
}, [onKey]);
|
|
73
|
-
return (_jsxs("div", { ...props, className: cn('flex max-h-[460px] flex-col overflow-y-auto border-t p-2', props.className), children: [items.length === 0 ? (_jsx("div", { className: "py-12 text-center text-sm", children: text.searchNoResult })) : null, items.map((item) => (_jsxs(CommandItem, {
|
|
72
|
+
return (_jsxs("div", { ...props, className: cn('flex max-h-[460px] flex-col overflow-y-auto border-t p-2', props.className), children: [items.length === 0 ? (_jsx("div", { className: "py-12 text-center text-sm", children: text.searchNoResult })) : null, items.map((item) => (_jsxs(CommandItem, { active: active === item.id, onPointerMove: () => onActiveChange(item.id), onClick: () => {
|
|
74
73
|
onOpen(item);
|
|
75
74
|
}, children: [item.type !== 'page' ? (_jsx("div", { role: "none", className: "ms-2 h-full min-h-10 w-px bg-fd-border" })) : null, icons[item.type], _jsx("p", { className: "w-0 flex-1 truncate", children: item.content })] }, item.id)))] }));
|
|
76
75
|
}
|
|
77
76
|
function LoadingIndicator({ isLoading }) {
|
|
78
77
|
return (_jsxs("div", { className: "relative size-4", children: [_jsx(LoaderCircle, { className: cn('absolute size-full animate-spin text-fd-primary transition-opacity', !isLoading && 'opacity-0') }), _jsx(SearchIcon, { className: cn('absolute size-full text-fd-muted-foreground transition-opacity', isLoading && 'opacity-0') })] }));
|
|
79
78
|
}
|
|
80
|
-
function CommandItem({ active
|
|
79
|
+
function CommandItem({ active = false, ...props }) {
|
|
81
80
|
return (_jsx("button", { ref: useCallback((element) => {
|
|
82
|
-
if (active
|
|
81
|
+
if (active && element) {
|
|
83
82
|
element.scrollIntoView({
|
|
84
83
|
block: 'nearest',
|
|
85
84
|
});
|
|
86
85
|
}
|
|
87
|
-
}, [active
|
|
86
|
+
}, [active]), type: "button", "aria-selected": active, ...props, className: cn('flex min-h-10 select-none flex-row items-center gap-2.5 rounded-lg px-2 text-start text-sm', active && 'bg-fd-accent text-fd-accent-foreground', props.className), children: props.children }));
|
|
88
87
|
}
|
|
89
88
|
const itemVariants = cva('rounded-md border px-2 py-0.5 text-xs font-medium text-fd-muted-foreground transition-colors', {
|
|
90
89
|
variants: {
|
|
@@ -93,13 +92,17 @@ const itemVariants = cva('rounded-md border px-2 py-0.5 text-xs font-medium text
|
|
|
93
92
|
},
|
|
94
93
|
},
|
|
95
94
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
95
|
+
const TagsListContext = createContext('TagsList');
|
|
96
|
+
export function TagsList({ tag, onTagChange, allowClear = false, ...props }) {
|
|
97
|
+
return (_jsx("div", { ...props, className: cn('flex items-center gap-1 flex-wrap', props.className), children: _jsx(TagsListContext.Provider, { value: useMemo(() => ({
|
|
98
|
+
value: tag,
|
|
99
|
+
onValueChange: onTagChange,
|
|
100
|
+
allowClear,
|
|
101
|
+
}), [allowClear, onTagChange, tag]), children: props.children }) }));
|
|
102
|
+
}
|
|
103
|
+
export function TagsListItem({ value, className, ...props }) {
|
|
104
|
+
const ctx = TagsListContext.use();
|
|
105
|
+
return (_jsx("button", { type: "button", "data-active": value === ctx.value, className: cn(itemVariants({ active: value === ctx.value, className })), onClick: () => {
|
|
106
|
+
ctx.onValueChange(ctx.value === value && ctx.allowClear ? undefined : value);
|
|
107
|
+
}, tabIndex: -1, ...props, children: props.children }));
|
|
105
108
|
}
|
|
@@ -35,7 +35,7 @@ export declare function SidebarItem({ icon, ...props }: LinkProps & {
|
|
|
35
35
|
export declare function SidebarFolder({ defaultOpen, ...props }: ComponentProps<'div'> & {
|
|
36
36
|
defaultOpen?: boolean;
|
|
37
37
|
}): import("react/jsx-runtime").JSX.Element;
|
|
38
|
-
export declare function SidebarFolderTrigger(props: CollapsibleTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export declare function SidebarFolderTrigger({ className, ...props }: CollapsibleTriggerProps): import("react/jsx-runtime").JSX.Element;
|
|
39
39
|
export declare function SidebarFolderLink(props: LinkProps): import("react/jsx-runtime").JSX.Element;
|
|
40
40
|
export declare function SidebarFolderContent(props: CollapsibleContentProps): import("react/jsx-runtime").JSX.Element;
|
|
41
41
|
export declare function SidebarCollapseTrigger(props: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/sidebar.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,EAAE,EAGP,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,OAAO,CAAC;IAC3D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA2BD,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,YAAY,2CAkHd;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/layout/sidebar.tsx"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,EAAE,EAGP,KAAK,SAAS,EAKf,MAAM,OAAO,CAAC;AACf,OAAa,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAU1D,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,KAAK,EACV,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAMrD,MAAM,WAAW,YAAa,SAAQ,cAAc,CAAC,OAAO,CAAC;IAC3D;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA2BD,wBAAgB,OAAO,CAAC,EACtB,gBAAoB,EACpB,QAAe,EACf,WAAkB,EAClB,GAAG,KAAK,EACT,EAAE,YAAY,2CAkHd;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CASzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CASzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,2CAarD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,2CAkB1D;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,SAAS,GAAG;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,2CAsBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,2CAgBA;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,uBAAuB,2CAqBzB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,2CAsCjD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,2CAqBlE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAgBrE;AAgBD,MAAM,WAAW,iBAAiB;IAChC,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,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC1E,SAAS,EAAE,EAAE,CAAC;QAAE,IAAI,EAAE,QAAQ,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAC7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACzC,2CAuDA"}
|
|
@@ -45,7 +45,7 @@ export function Sidebar({ defaultOpenLevel = 0, prefetch = true, collapsible = t
|
|
|
45
45
|
});
|
|
46
46
|
if (isMobile) {
|
|
47
47
|
const state = open ? 'open' : 'closed';
|
|
48
|
-
return (_jsxs(_Fragment, { children: [_jsx(Presence, { present: open, children: _jsx("div", { "data-state": state, className: "fixed z-40 inset-0 bg-black/30 backdrop-blur-sm data-[state=open]:animate-fd-fade-in data-[state=closed]:animate-fd-fade-out", onClick: () => setOpen(false) }) }), _jsx(Presence, { present: open, children: ({ present }) => (_jsx(RemoveScroll, { as: "aside", enabled: present, id: "nd-sidebar-mobile", ...props, "data-state": state, className: cn('fixed text-[15px] flex flex-col rounded-e-xl border-e start-0 inset-y-0 w-[85%] max-w-[380px] z-40 bg-fd-background data-[state=open]:animate-fd-enterFromLeft data-[state=closed]:animate-fd-exitToLeft', !present && 'invisible', props.className), children: _jsx(Context.Provider, { value: context, children: props.children }) })) })] }));
|
|
48
|
+
return (_jsxs(_Fragment, { children: [_jsx(Presence, { present: open, children: _jsx("div", { "data-state": state, className: "fixed z-40 inset-0 bg-black/30 backdrop-blur-sm data-[state=open]:animate-fd-fade-in data-[state=closed]:animate-fd-fade-out", onClick: () => setOpen(false) }) }), _jsx(Presence, { present: open, children: ({ present }) => (_jsx(RemoveScroll, { as: "aside", enabled: present, id: "nd-sidebar-mobile", ...props, "data-state": state, className: cn('fixed text-[15px] flex flex-col py-3 rounded-e-xl border-e start-0 inset-y-0 w-[85%] max-w-[380px] z-40 bg-fd-background data-[state=open]:animate-fd-enterFromLeft data-[state=closed]:animate-fd-exitToLeft', !present && 'invisible', props.className), children: _jsx(Context.Provider, { value: context, children: props.children }) })) })] }));
|
|
49
49
|
}
|
|
50
50
|
return (_jsx("aside", { id: "nd-sidebar", ...props, "data-collapsed": collapsed, className: cn('sticky top-(--fd-sidebar-top) z-20 bg-fd-card text-sm h-(--fd-sidebar-height) max-md:hidden', collapsible && [
|
|
51
51
|
'transition-all',
|
|
@@ -76,13 +76,13 @@ export function Sidebar({ defaultOpenLevel = 0, prefetch = true, collapsible = t
|
|
|
76
76
|
}, Math.min(e.clientX, document.body.clientWidth - e.clientX) > 100
|
|
77
77
|
? 0
|
|
78
78
|
: 500);
|
|
79
|
-
}, children: _jsx("div", { className: "flex w-(--fd-sidebar-width) h-full max-w-full flex-col ms-auto border-e", children: _jsx(Context.Provider, { value: context, children: props.children }) }) }));
|
|
79
|
+
}, children: _jsx("div", { className: "flex w-(--fd-sidebar-width) h-full max-w-full flex-col pt-1.5 ms-auto border-e", children: _jsx(Context.Provider, { value: context, children: props.children }) }) }));
|
|
80
80
|
}
|
|
81
81
|
export function SidebarHeader(props) {
|
|
82
|
-
return (_jsx("div", { ...props, className: cn('flex flex-col gap-3 px-4
|
|
82
|
+
return (_jsx("div", { ...props, className: cn('flex flex-col gap-3 px-4 py-2', props.className), children: props.children }));
|
|
83
83
|
}
|
|
84
84
|
export function SidebarFooter(props) {
|
|
85
|
-
return (_jsx("div", { ...props, className: cn('flex flex-col border-t px-4 py-3
|
|
85
|
+
return (_jsx("div", { ...props, className: cn('flex flex-col border-t px-4 py-3', props.className), children: props.children }));
|
|
86
86
|
}
|
|
87
87
|
export function SidebarViewport(props) {
|
|
88
88
|
return (_jsx(ScrollArea, { ...props, className: cn('h-full', props.className), children: _jsx(ScrollViewport, { className: "p-4", style: {
|
|
@@ -113,10 +113,10 @@ export function SidebarFolder({ defaultOpen = false, ...props }) {
|
|
|
113
113
|
});
|
|
114
114
|
return (_jsx(Collapsible, { open: open, onOpenChange: setOpen, ...props, children: _jsx(FolderContext.Provider, { value: useMemo(() => ({ open, setOpen }), [open]), children: props.children }) }));
|
|
115
115
|
}
|
|
116
|
-
export function SidebarFolderTrigger(props) {
|
|
116
|
+
export function SidebarFolderTrigger({ className, ...props }) {
|
|
117
117
|
const { level } = useInternalContext();
|
|
118
118
|
const { open } = useFolderContext();
|
|
119
|
-
return (_jsxs(CollapsibleTrigger, {
|
|
119
|
+
return (_jsxs(CollapsibleTrigger, { className: cn(itemVariants({ active: false }), 'w-full', className), ...props, style: {
|
|
120
120
|
paddingInlineStart: getOffset(level),
|
|
121
121
|
...props.style,
|
|
122
122
|
}, children: [_jsx(Border, { level: level }), props.children, _jsx(ChevronDown, { "data-icon": true, className: cn('ms-auto transition-transform', !open && '-rotate-90') })] }));
|
|
@@ -127,12 +127,13 @@ export function SidebarFolderLink(props) {
|
|
|
127
127
|
const pathname = usePathname();
|
|
128
128
|
const active = props.href !== undefined && isActive(props.href, pathname, false);
|
|
129
129
|
return (_jsxs(Link, { ...props, "data-active": active, className: cn(itemVariants({ active }), 'w-full', props.className), onClick: (e) => {
|
|
130
|
-
if (e.target
|
|
131
|
-
|
|
130
|
+
if (e.target instanceof HTMLElement &&
|
|
131
|
+
e.target.hasAttribute('data-icon')) {
|
|
132
|
+
setOpen(!open);
|
|
132
133
|
e.preventDefault();
|
|
133
134
|
}
|
|
134
135
|
else {
|
|
135
|
-
setOpen(
|
|
136
|
+
setOpen(active ? !open : true);
|
|
136
137
|
}
|
|
137
138
|
}, prefetch: prefetch, style: {
|
|
138
139
|
paddingInlineStart: getOffset(level),
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { TOCItemType } from 'fumadocs-core/server';
|
|
2
2
|
import { type ComponentProps, type HTMLAttributes, type ReactNode } from 'react';
|
|
3
|
-
import { ScrollArea } from '../ui/scroll-area.js';
|
|
4
3
|
export interface TOCProps {
|
|
5
4
|
/**
|
|
6
5
|
* Custom content in TOC container, before the main TOC
|
|
@@ -14,9 +13,7 @@ export interface TOCProps {
|
|
|
14
13
|
}
|
|
15
14
|
export declare function Toc(props: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
16
15
|
export declare function TocItemsEmpty(): import("react/jsx-runtime").JSX.Element;
|
|
17
|
-
export declare function TOCScrollArea(
|
|
18
|
-
isMenu?: boolean;
|
|
19
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function TOCScrollArea(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
20
17
|
export declare function TOCItems({ items }: {
|
|
21
18
|
items: TOCItemType[];
|
|
22
19
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toc.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"toc.d.ts","sourceRoot":"","sources":["../../../src/components/layout/toc.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAMf,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,GAAG,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,2CAyBxD;AAED,wBAAgB,aAAa,4CAQ5B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,2CAiBzD;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,2CAqB3D"}
|
|
@@ -5,23 +5,21 @@ import { useRef, } from 'react';
|
|
|
5
5
|
import { cn } from '../../utils/cn.js';
|
|
6
6
|
import { useI18n } from '../../contexts/i18n.js';
|
|
7
7
|
import { TocThumb } from '../../components/layout/toc-thumb.js';
|
|
8
|
-
import { ScrollArea, ScrollViewport } from '../ui/scroll-area.js';
|
|
9
8
|
import { usePageStyles } from '../../contexts/layout.js';
|
|
10
9
|
export function Toc(props) {
|
|
11
10
|
const { toc } = usePageStyles();
|
|
12
11
|
return (_jsx("div", { id: "nd-toc", ...props, className: cn('sticky top-[calc(var(--fd-banner-height)+var(--fd-nav-height))] h-(--fd-toc-height) pb-2 pt-12', toc, props.className), style: {
|
|
13
12
|
...props.style,
|
|
14
13
|
'--fd-toc-height': 'calc(100dvh - var(--fd-banner-height) - var(--fd-nav-height))',
|
|
15
|
-
}, children: _jsx("div", { className: "flex h-full w-(--fd-toc-width) max-w-full flex-col
|
|
14
|
+
}, children: _jsx("div", { className: "flex h-full w-(--fd-toc-width) max-w-full flex-col pe-4", children: props.children }) }));
|
|
16
15
|
}
|
|
17
16
|
export function TocItemsEmpty() {
|
|
18
17
|
const { text } = useI18n();
|
|
19
18
|
return (_jsx("div", { className: "rounded-lg border bg-fd-card p-3 text-xs text-fd-muted-foreground", children: text.tocNoHeadings }));
|
|
20
19
|
}
|
|
21
|
-
export function TOCScrollArea(
|
|
20
|
+
export function TOCScrollArea(props) {
|
|
22
21
|
const viewRef = useRef(null);
|
|
23
|
-
return (_jsx(
|
|
24
|
-
'[mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] px-4 md:px-6 py-2'), children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: props.children }) }) }));
|
|
22
|
+
return (_jsx("div", { ...props, ref: viewRef, className: cn('relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3', props.className), children: _jsx(Primitive.ScrollProvider, { containerRef: viewRef, children: props.children }) }));
|
|
25
23
|
}
|
|
26
24
|
export function TOCItems({ items }) {
|
|
27
25
|
const containerRef = useRef(null);
|