fumadocs-ui 15.3.2 → 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 +7 -5
- 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 +6 -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.map +1 -1
- package/dist/components/ui/hide-if-empty.js +13 -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/home/navbar.js +1 -1
- package/dist/page-client.js +1 -1
- package/dist/style.css +13 -6
- 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
|
}
|
|
@@ -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,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,KAAK,EAAE,uBAAuB,
|
|
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"}
|
|
@@ -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,9 +1,6 @@
|
|
|
1
1
|
import type { TabsContentProps, TabsProps as BaseProps } from '@radix-ui/react-tabs';
|
|
2
2
|
import { type ReactNode } from 'react';
|
|
3
|
-
import * as Primitive from './ui/tabs.js';
|
|
4
|
-
export { Primitive };
|
|
5
3
|
export interface TabsProps extends BaseProps {
|
|
6
|
-
label?: ReactNode;
|
|
7
4
|
/**
|
|
8
5
|
* Identifier for Sharing value of tabs
|
|
9
6
|
*/
|
|
@@ -13,21 +10,33 @@ export interface TabsProps extends BaseProps {
|
|
|
13
10
|
*/
|
|
14
11
|
persist?: boolean;
|
|
15
12
|
/**
|
|
13
|
+
* If true, updates the URL hash based on the tab's id
|
|
14
|
+
*/
|
|
15
|
+
updateAnchor?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Use simple mode instead of advanced usage as documented in https://radix-ui.com/primitives/docs/components/tabs.
|
|
18
|
+
*/
|
|
19
|
+
items?: string[];
|
|
20
|
+
/**
|
|
21
|
+
* Shortcut for `defaultValue` when `items` is provided.
|
|
22
|
+
*
|
|
16
23
|
* @defaultValue 0
|
|
17
24
|
*/
|
|
18
25
|
defaultIndex?: number;
|
|
19
|
-
items?: string[];
|
|
20
26
|
/**
|
|
21
|
-
*
|
|
27
|
+
* Additional label in tabs list when `items` is provided.
|
|
22
28
|
*/
|
|
23
|
-
|
|
29
|
+
label?: ReactNode;
|
|
24
30
|
}
|
|
25
|
-
export declare
|
|
31
|
+
export declare const TabsList: import("react").ForwardRefExoticComponent<Omit<import("@radix-ui/react-tabs").TabsListProps & import("react").RefAttributes<HTMLDivElement>, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
32
|
+
export declare const TabsTrigger: import("react").ForwardRefExoticComponent<Omit<import("@radix-ui/react-tabs").TabsTriggerProps & import("react").RefAttributes<HTMLButtonElement>, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
33
|
+
export declare function Tabs({ groupId, items, persist, label, defaultIndex, updateAnchor, defaultValue, ...props }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
26
34
|
export type TabProps = Omit<TabsContentProps, 'value'> & {
|
|
27
35
|
/**
|
|
28
36
|
* Value of tab, detect from index if unspecified.
|
|
29
37
|
*/
|
|
30
|
-
value?:
|
|
38
|
+
value?: string;
|
|
31
39
|
};
|
|
32
|
-
export declare function Tab({ value,
|
|
40
|
+
export declare function Tab({ value, ...props }: TabProps): import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export declare function TabsContent({ value, className, ...props }: TabsContentProps): import("react/jsx-runtime").JSX.Element;
|
|
33
42
|
//# sourceMappingURL=tabs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/components/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,IAAI,SAAS,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"tabs.d.ts","sourceRoot":"","sources":["../../src/components/tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAChB,SAAS,IAAI,SAAS,EACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,SAAS,EAOf,MAAM,OAAO,CAAC;AAuBf,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;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;AAcD,eAAO,MAAM,QAAQ,sMAAqB,CAAC;AAC3C,eAAO,MAAM,WAAW,+MAAwB,CAAC;AAEjD,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,KAAK,EACL,OAAe,EACf,KAAK,EACL,YAAgB,EAChB,YAAoB,EACpB,YAAmE,EACnE,GAAG,KAAK,EACT,EAAE,SAAS,2CAmFX;AAED,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,GAAG;IACvD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,QAAQ,2CAgBhD;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,2CAmB3E"}
|
package/dist/components/tabs.js
CHANGED
|
@@ -4,7 +4,6 @@ import { createContext, useContext, useEffect, useId, useLayoutEffect, useMemo,
|
|
|
4
4
|
import { cn } from '../utils/cn.js';
|
|
5
5
|
import * as Primitive from './ui/tabs.js';
|
|
6
6
|
import { useEffectEvent } from 'fumadocs-core/utils/use-effect-event';
|
|
7
|
-
export { Primitive };
|
|
8
7
|
const listeners = new Map();
|
|
9
8
|
function addChangeListener(id, listener) {
|
|
10
9
|
const list = listeners.get(id) ?? [];
|
|
@@ -22,14 +21,16 @@ function useTabContext() {
|
|
|
22
21
|
throw new Error('You must wrap your component in <Tabs>');
|
|
23
22
|
return ctx;
|
|
24
23
|
}
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
export const TabsList = Primitive.TabsList;
|
|
25
|
+
export const TabsTrigger = Primitive.TabsTrigger;
|
|
26
|
+
export function Tabs({ groupId, items, persist = false, label, defaultIndex = 0, updateAnchor = false, defaultValue = items ? escapeValue(items[defaultIndex]) : undefined, ...props }) {
|
|
27
|
+
const [value, setValue] = useState(defaultValue);
|
|
28
28
|
const valueToIdMap = useMemo(() => new Map(), []);
|
|
29
29
|
const collection = useMemo(() => [], []);
|
|
30
30
|
const onUpdate = useEffectEvent((v) => {
|
|
31
|
-
if (
|
|
32
|
-
|
|
31
|
+
if (items && !items.some((item) => escapeValue(item) === v))
|
|
32
|
+
return;
|
|
33
|
+
setValue(v);
|
|
33
34
|
});
|
|
34
35
|
useLayoutEffect(() => {
|
|
35
36
|
if (!groupId)
|
|
@@ -74,23 +75,23 @@ export function Tabs({ groupId, items = [], persist = false, label, defaultIndex
|
|
|
74
75
|
else {
|
|
75
76
|
setValue(v);
|
|
76
77
|
}
|
|
77
|
-
}, ...props, className: cn('my-4', props.className), children: [_jsxs(
|
|
78
|
-
}
|
|
79
|
-
function toValue(v) {
|
|
80
|
-
return v.toLowerCase().replace(/\s/, '-');
|
|
78
|
+
}, ...props, className: cn('my-4', props.className), 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, valueToIdMap, collection }), [valueToIdMap, collection, items]), children: props.children })] }));
|
|
81
79
|
}
|
|
82
|
-
export function Tab({ value,
|
|
83
|
-
const { items
|
|
84
|
-
const
|
|
80
|
+
export function Tab({ value, ...props }) {
|
|
81
|
+
const { items } = useTabContext();
|
|
82
|
+
const resolved = value ??
|
|
85
83
|
// eslint-disable-next-line react-hooks/rules-of-hooks -- `value` is not supposed to change
|
|
86
|
-
items
|
|
87
|
-
if (!
|
|
84
|
+
items?.at(useCollectionIndex());
|
|
85
|
+
if (!resolved)
|
|
88
86
|
throw new Error('Failed to resolve tab `value`, please pass a `value` prop to the Tab component.');
|
|
89
|
-
|
|
87
|
+
return (_jsx(TabsContent, { value: escapeValue(resolved), ...props, children: props.children }));
|
|
88
|
+
}
|
|
89
|
+
export function TabsContent({ value, className, ...props }) {
|
|
90
|
+
const { valueToIdMap } = useTabContext();
|
|
90
91
|
if (props.id) {
|
|
91
|
-
valueToIdMap.set(
|
|
92
|
+
valueToIdMap.set(value, props.id);
|
|
92
93
|
}
|
|
93
|
-
return (_jsx(Primitive.TabsContent, { value:
|
|
94
|
+
return (_jsx(Primitive.TabsContent, { value: value, className: cn('prose-no-margin [&>figure:only-child]:-m-4 [&>figure:only-child]:border-none', className), ...props, children: props.children }));
|
|
94
95
|
}
|
|
95
96
|
/**
|
|
96
97
|
* Inspired by Headless UI.
|
|
@@ -112,3 +113,6 @@ function useCollectionIndex() {
|
|
|
112
113
|
collection.push(key);
|
|
113
114
|
return collection.indexOf(key);
|
|
114
115
|
}
|
|
116
|
+
function escapeValue(v) {
|
|
117
|
+
return v.toLowerCase().replace(/\s/, '-');
|
|
118
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hide-if-empty.d.ts","sourceRoot":"","sources":["../../../src/components/ui/hide-if-empty.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hide-if-empty.d.ts","sourceRoot":"","sources":["../../../src/components/ui/hide-if-empty.tsx"],"names":[],"mappings":"AAoCA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAyCtE"}
|
|
@@ -17,7 +17,19 @@ const init = `function isEmpty(node) {
|
|
|
17
17
|
|
|
18
18
|
return true;
|
|
19
19
|
}`;
|
|
20
|
-
|
|
20
|
+
function isEmpty(node) {
|
|
21
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
22
|
+
const child = node.childNodes.item(i);
|
|
23
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
else if (child.nodeType === Node.ELEMENT_NODE &&
|
|
27
|
+
window.getComputedStyle(child).display !== 'none') {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
21
33
|
/**
|
|
22
34
|
* The built-in CSS `:empty` selector cannot detect if the children is hidden, classes such as `md:hidden` causes it to fail.
|
|
23
35
|
* This component is an enhancement to `empty:hidden` to fix the issue described above.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scroll-area.d.ts","sourceRoot":"","sources":["../../../src/components/ui/scroll-area.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,QAAA,MAAM,UAAU,+
|
|
1
|
+
{"version":3,"file":"scroll-area.d.ts","sourceRoot":"","sources":["../../../src/components/ui/scroll-area.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,QAAA,MAAM,UAAU,+JAcd,CAAC;AAIH,QAAA,MAAM,cAAc,uKAWlB,CAAC;AAIH,QAAA,MAAM,SAAS,wKAiBb,CAAC;AAGH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { cn } from '../../utils/cn.js';
|
|
5
|
-
const ScrollArea = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(ScrollAreaPrimitive.Root, { ref: ref, className: cn('overflow-hidden', className), ...props, children: [children, _jsx(ScrollAreaPrimitive.Corner, {}), _jsx(ScrollBar, { orientation: "vertical" })] })));
|
|
5
|
+
const ScrollArea = React.forwardRef(({ className, children, ...props }, ref) => (_jsxs(ScrollAreaPrimitive.Root, { ref: ref, type: "scroll", className: cn('overflow-hidden', className), ...props, children: [children, _jsx(ScrollAreaPrimitive.Corner, {}), _jsx(ScrollBar, { orientation: "vertical" })] })));
|
|
6
6
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
7
7
|
const ScrollViewport = React.forwardRef(({ className, children, ...props }, ref) => (_jsx(ScrollAreaPrimitive.Viewport, { ref: ref, className: cn('size-full rounded-[inherit]', className), ...props, children: children })));
|
|
8
8
|
ScrollViewport.displayName = ScrollAreaPrimitive.Viewport.displayName;
|
|
@@ -7,9 +7,9 @@ const Tabs = React.forwardRef((props, ref) => {
|
|
|
7
7
|
return (_jsx(TabsPrimitive.Root, { ref: ref, ...props, className: cn('flex flex-col overflow-hidden rounded-xl border bg-fd-secondary', props.className) }));
|
|
8
8
|
});
|
|
9
9
|
Tabs.displayName = 'Tabs';
|
|
10
|
-
const TabsList = React.forwardRef((props, ref) => (_jsx(TabsPrimitive.List, { ref: ref, ...props, className: cn('flex gap-3.5 text-fd-secondary-foreground overflow-x-auto px-4', props.className) })));
|
|
10
|
+
const TabsList = React.forwardRef((props, ref) => (_jsx(TabsPrimitive.List, { ref: ref, ...props, className: cn('flex gap-3.5 text-fd-secondary-foreground overflow-x-auto px-4 not-prose', props.className) })));
|
|
11
11
|
TabsList.displayName = 'TabsList';
|
|
12
|
-
const TabsTrigger = React.forwardRef((props, ref) => (_jsx(TabsPrimitive.Trigger, { ref: ref, ...props, className: cn('whitespace-nowrap text-fd-muted-foreground border-b border-transparent py-2 text-sm font-medium transition-colors hover:text-fd-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=active]:border-fd-primary data-[state=active]:text-fd-primary', props.className) })));
|
|
12
|
+
const TabsTrigger = React.forwardRef((props, ref) => (_jsx(TabsPrimitive.Trigger, { ref: ref, ...props, className: 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-[state=active]:border-fd-primary data-[state=active]:text-fd-primary', props.className) })));
|
|
13
13
|
TabsTrigger.displayName = 'TabsTrigger';
|
|
14
14
|
const TabsContent = React.forwardRef((props, ref) => (_jsx(TabsPrimitive.Content, { ref: ref, ...props, className: cn('p-4 text-[15px] bg-fd-background rounded-xl outline-none', props.className) })));
|
|
15
15
|
TabsContent.displayName = 'TabsContent';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export declare function Navbar(props:
|
|
3
|
-
export declare function NavbarSidebarTrigger(props:
|
|
1
|
+
import { type ComponentProps } from 'react';
|
|
2
|
+
export declare function Navbar(props: ComponentProps<'header'>): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function NavbarSidebarTrigger({ className, ...props }: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
|
|
4
4
|
export declare function CollapsibleControl(): import("react/jsx-runtime").JSX.Element | undefined;
|
|
5
5
|
//# sourceMappingURL=docs-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-client.d.ts","sourceRoot":"","sources":["../../src/layouts/docs-client.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"docs-client.d.ts","sourceRoot":"","sources":["../../src/layouts/docs-client.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAQ5C,wBAAgB,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAiBrD;AAED,wBAAgB,oBAAoB,CAAC,EACnC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,QAAQ,CAAC,2CAmB1B;AAED,wBAAgB,kBAAkB,wDAyBjC"}
|
|
@@ -12,12 +12,13 @@ export function Navbar(props) {
|
|
|
12
12
|
const { isTransparent } = useNav();
|
|
13
13
|
return (_jsx("header", { id: "nd-subnav", ...props, className: cn('sticky top-(--fd-banner-height) z-30 flex h-14 items-center px-4 border-b transition-colors backdrop-blur-sm md:px-6', (!isTransparent || open) && 'bg-fd-background/80', props.className), children: props.children }));
|
|
14
14
|
}
|
|
15
|
-
export function NavbarSidebarTrigger(props) {
|
|
15
|
+
export function NavbarSidebarTrigger({ className, ...props }) {
|
|
16
16
|
const { setOpen } = useSidebar();
|
|
17
|
-
return (_jsx("button", { ...props, className: cn(buttonVariants({
|
|
17
|
+
return (_jsx("button", { ...props, "aria-label": "Open Sidebar", className: cn(buttonVariants({
|
|
18
18
|
color: 'ghost',
|
|
19
19
|
size: 'icon',
|
|
20
|
-
|
|
20
|
+
className,
|
|
21
|
+
})), onClick: () => setOpen((prev) => !prev), children: _jsx(Menu, {}) }));
|
|
21
22
|
}
|
|
22
23
|
export function CollapsibleControl() {
|
|
23
24
|
const { collapsed } = useSidebar();
|
|
@@ -20,7 +20,7 @@ export function Navbar(props) {
|
|
|
20
20
|
}
|
|
21
21
|
export const NavbarMenu = NavigationMenuItem;
|
|
22
22
|
export function NavbarMenuContent(props) {
|
|
23
|
-
return (_jsx(NavigationMenuContent, { ...props, className: cn('grid grid-cols-1 gap-
|
|
23
|
+
return (_jsx(NavigationMenuContent, { ...props, className: cn('grid grid-cols-1 gap-2 p-4 md:grid-cols-2 lg:grid-cols-3', props.className), children: props.children }));
|
|
24
24
|
}
|
|
25
25
|
export function NavbarMenuTrigger(props) {
|
|
26
26
|
return (_jsx(NavigationMenuTrigger, { ...props, className: cn(navItemVariants(), 'rounded-md', props.className), children: props.children }));
|
package/dist/page-client.js
CHANGED
|
@@ -21,7 +21,7 @@ export function TocPopoverTrigger({ items, ...props }) {
|
|
|
21
21
|
const selected = useMemo(() => items.findIndex((item) => active === item.url.slice(1)), [items, active]);
|
|
22
22
|
const path = useTreePath().at(-1);
|
|
23
23
|
const showItem = selected !== -1 && !open;
|
|
24
|
-
return (_jsxs(CollapsibleTrigger, { ...props, className: cn('flex flex-row items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:shrink-0 [&_svg]:size-4 md:px-6', props.className), children: [_jsx(ProgressCircle, { value: (selected + 1) / items.length, max: 1, className: cn(open && 'text-fd-primary') }), _jsxs("span", { className: "grid flex-1 *:row-start-1 *:col-start-1", children: [_jsx("span", { className: cn('truncate transition-all', open && 'text-fd-foreground', showItem && 'opacity-0 -translate-y-full pointer-events-none'), children: path?.name ?? text.toc }), _jsx("span", { className: cn('truncate transition-all', !showItem && 'opacity-0 translate-y-full pointer-events-none'), children: items[selected]?.title })] }), _jsx(ChevronDown, { className: cn('transition-transform', open && 'rotate-180') })] }));
|
|
24
|
+
return (_jsxs(CollapsibleTrigger, { ...props, className: cn('flex flex-row items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:shrink-0 [&_svg]:size-4 md:px-6', props.className), children: [_jsx(ProgressCircle, { value: (selected + 1) / items.length, max: 1, className: cn(open && 'text-fd-primary') }), _jsxs("span", { className: "grid flex-1 *:my-auto *:row-start-1 *:col-start-1", children: [_jsx("span", { className: cn('truncate transition-all', open && 'text-fd-foreground', showItem && 'opacity-0 -translate-y-full pointer-events-none'), children: path?.name ?? text.toc }), _jsx("span", { className: cn('truncate transition-all', !showItem && 'opacity-0 translate-y-full pointer-events-none'), children: items[selected]?.title })] }), _jsx(ChevronDown, { className: cn('transition-transform', open && 'rotate-180') })] }));
|
|
25
25
|
}
|
|
26
26
|
function clamp(input, min, max) {
|
|
27
27
|
if (input < min)
|
package/dist/style.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! tailwindcss v4.1.
|
|
1
|
+
/*! tailwindcss v4.1.7 | MIT License | https://tailwindcss.com */
|
|
2
2
|
@layer properties;
|
|
3
3
|
@layer theme, base, components, utilities;
|
|
4
4
|
@layer theme {
|
|
@@ -68,12 +68,14 @@
|
|
|
68
68
|
--color-fd-diff-add-symbol: rgb(10, 200, 100);
|
|
69
69
|
--animate-fd-fade-in: fd-fade-in 300ms ease;
|
|
70
70
|
--animate-fd-fade-out: fd-fade-out 300ms ease;
|
|
71
|
-
--animate-fd-dialog-in: fd-dialog-in
|
|
72
|
-
--animate-fd-dialog-out: fd-dialog-out
|
|
71
|
+
--animate-fd-dialog-in: fd-dialog-in 240ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
72
|
+
--animate-fd-dialog-out: fd-dialog-out 240ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
73
73
|
--animate-fd-popover-in: fd-popover-in 150ms ease;
|
|
74
74
|
--animate-fd-popover-out: fd-popover-out 150ms ease;
|
|
75
|
-
--animate-fd-collapsible-down: fd-collapsible-down 150ms
|
|
76
|
-
|
|
75
|
+
--animate-fd-collapsible-down: fd-collapsible-down 150ms
|
|
76
|
+
cubic-bezier(0.45, 0, 0.55, 1);
|
|
77
|
+
--animate-fd-collapsible-up: fd-collapsible-up 150ms
|
|
78
|
+
cubic-bezier(0.45, 0, 0.55, 1);
|
|
77
79
|
--animate-fd-accordion-down: fd-accordion-down 200ms ease-out;
|
|
78
80
|
--animate-fd-accordion-up: fd-accordion-up 200ms ease-out;
|
|
79
81
|
--animate-fd-nav-menu-in: fd-nav-menu-in 200ms ease;
|
|
@@ -1722,6 +1724,11 @@
|
|
|
1722
1724
|
grid-row-start: 1;
|
|
1723
1725
|
}
|
|
1724
1726
|
}
|
|
1727
|
+
.\*\:my-auto {
|
|
1728
|
+
:is(& > *) {
|
|
1729
|
+
margin-block: auto;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1725
1732
|
.\*\:flex {
|
|
1726
1733
|
:is(& > *) {
|
|
1727
1734
|
display: flex;
|
|
@@ -2764,7 +2771,7 @@
|
|
|
2764
2771
|
transform: scale(1);
|
|
2765
2772
|
}
|
|
2766
2773
|
to {
|
|
2767
|
-
transform: scale(1.
|
|
2774
|
+
transform: scale(1.04);
|
|
2768
2775
|
opacity: 0;
|
|
2769
2776
|
}
|
|
2770
2777
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fumadocs-ui",
|
|
3
|
-
"version": "15.3.
|
|
3
|
+
"version": "15.3.3",
|
|
4
4
|
"description": "The framework for building a documentation website in Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"NextJs",
|
|
@@ -88,21 +88,21 @@
|
|
|
88
88
|
"postcss-selector-parser": "^7.1.0",
|
|
89
89
|
"react-medium-image-zoom": "^5.2.14",
|
|
90
90
|
"react-remove-scroll": "^2.6.3",
|
|
91
|
-
"tailwind-merge": "^3.
|
|
92
|
-
"fumadocs-core": "15.3.
|
|
91
|
+
"tailwind-merge": "^3.3.0",
|
|
92
|
+
"fumadocs-core": "15.3.3"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@next/eslint-plugin-next": "^15.3.
|
|
96
|
-
"@tailwindcss/cli": "^4.1.
|
|
95
|
+
"@next/eslint-plugin-next": "^15.3.2",
|
|
96
|
+
"@tailwindcss/cli": "^4.1.7",
|
|
97
97
|
"@types/lodash.merge": "^4.6.9",
|
|
98
|
-
"@types/react": "^19.1.
|
|
99
|
-
"@types/react-dom": "^19.1.
|
|
100
|
-
"next": "15.3.
|
|
101
|
-
"tailwindcss": "^4.1.
|
|
98
|
+
"@types/react": "^19.1.4",
|
|
99
|
+
"@types/react-dom": "^19.1.5",
|
|
100
|
+
"next": "15.3.2",
|
|
101
|
+
"tailwindcss": "^4.1.7",
|
|
102
102
|
"tsc-alias": "^1.8.16",
|
|
103
103
|
"@fumadocs/cli": "0.1.1",
|
|
104
104
|
"eslint-config-custom": "0.0.0",
|
|
105
|
-
"fumadocs-core": "15.3.
|
|
105
|
+
"fumadocs-core": "15.3.3",
|
|
106
106
|
"tsconfig": "0.0.0"
|
|
107
107
|
},
|
|
108
108
|
"peerDependencies": {
|