@fumadocs/base-ui 16.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/css/black.css +1 -0
  4. package/css/catppuccin.css +1 -0
  5. package/css/dusk.css +1 -0
  6. package/css/layouts/docs.css +1 -0
  7. package/css/layouts/home.css +1 -0
  8. package/css/layouts/notebook.css +1 -0
  9. package/css/neutral.css +1 -0
  10. package/css/ocean.css +1 -0
  11. package/css/preset.css +10 -0
  12. package/css/purple.css +1 -0
  13. package/css/shadcn.css +1 -0
  14. package/css/solar.css +1 -0
  15. package/css/style.css +9 -0
  16. package/css/vitepress.css +1 -0
  17. package/dist/components/accordion.d.ts +8 -0
  18. package/dist/components/accordion.d.ts.map +1 -0
  19. package/dist/components/accordion.js +41 -0
  20. package/dist/components/banner.d.ts +24 -0
  21. package/dist/components/banner.d.ts.map +1 -0
  22. package/dist/components/banner.js +54 -0
  23. package/dist/components/callout.d.ts +19 -0
  24. package/dist/components/callout.d.ts.map +1 -0
  25. package/dist/components/callout.js +34 -0
  26. package/dist/components/card.d.ts +11 -0
  27. package/dist/components/card.d.ts.map +1 -0
  28. package/dist/components/card.js +10 -0
  29. package/dist/components/codeblock.d.ts +42 -0
  30. package/dist/components/codeblock.d.ts.map +1 -0
  31. package/dist/components/codeblock.js +68 -0
  32. package/dist/components/dialog/search-algolia.d.ts +25 -0
  33. package/dist/components/dialog/search-algolia.d.ts.map +1 -0
  34. package/dist/components/dialog/search-algolia.js +35 -0
  35. package/dist/components/dialog/search-default.d.ts +29 -0
  36. package/dist/components/dialog/search-default.d.ts.map +1 -0
  37. package/dist/components/dialog/search-default.js +40 -0
  38. package/dist/components/dialog/search-orama.d.ts +30 -0
  39. package/dist/components/dialog/search-orama.d.ts.map +1 -0
  40. package/dist/components/dialog/search-orama.js +40 -0
  41. package/dist/components/dialog/search.d.ts +72 -0
  42. package/dist/components/dialog/search.d.ts.map +1 -0
  43. package/dist/components/dialog/search.js +192 -0
  44. package/dist/components/dynamic-codeblock.d.ts +21 -0
  45. package/dist/components/dynamic-codeblock.d.ts.map +1 -0
  46. package/dist/components/dynamic-codeblock.js +33 -0
  47. package/dist/components/files.d.ts +19 -0
  48. package/dist/components/files.d.ts.map +1 -0
  49. package/dist/components/files.js +18 -0
  50. package/dist/components/github-info.d.ts +8 -0
  51. package/dist/components/github-info.d.ts.map +1 -0
  52. package/dist/components/github-info.js +53 -0
  53. package/dist/components/heading.d.ts +8 -0
  54. package/dist/components/heading.d.ts.map +1 -0
  55. package/dist/components/heading.js +9 -0
  56. package/dist/components/image-zoom.css +77 -0
  57. package/dist/components/image-zoom.d.ts +16 -0
  58. package/dist/components/image-zoom.d.ts.map +1 -0
  59. package/dist/components/image-zoom.js +23 -0
  60. package/dist/components/inline-toc.d.ts +8 -0
  61. package/dist/components/inline-toc.d.ts.map +1 -0
  62. package/dist/components/inline-toc.js +10 -0
  63. package/dist/components/sidebar/base.d.ts +72 -0
  64. package/dist/components/sidebar/base.d.ts.map +1 -0
  65. package/dist/components/sidebar/base.js +197 -0
  66. package/dist/components/sidebar/link-item.d.ts +11 -0
  67. package/dist/components/sidebar/link-item.d.ts.map +1 -0
  68. package/dist/components/sidebar/link-item.js +13 -0
  69. package/dist/components/sidebar/page-tree.d.ts +19 -0
  70. package/dist/components/sidebar/page-tree.d.ts.map +1 -0
  71. package/dist/components/sidebar/page-tree.js +34 -0
  72. package/dist/components/sidebar/tabs/dropdown.d.ts +11 -0
  73. package/dist/components/sidebar/tabs/dropdown.d.ts.map +1 -0
  74. package/dist/components/sidebar/tabs/dropdown.js +34 -0
  75. package/dist/components/sidebar/tabs/index.d.ts +21 -0
  76. package/dist/components/sidebar/tabs/index.d.ts.map +1 -0
  77. package/dist/components/sidebar/tabs/index.js +49 -0
  78. package/dist/components/steps.d.ts +8 -0
  79. package/dist/components/steps.d.ts.map +1 -0
  80. package/dist/components/steps.js +7 -0
  81. package/dist/components/tabs.d.ts +31 -0
  82. package/dist/components/tabs.d.ts.map +1 -0
  83. package/dist/components/tabs.js +64 -0
  84. package/dist/components/toc/clerk.d.ts +2 -0
  85. package/dist/components/toc/clerk.d.ts.map +1 -0
  86. package/dist/components/toc/clerk.js +1 -0
  87. package/dist/components/toc/default.d.ts +2 -0
  88. package/dist/components/toc/default.d.ts.map +1 -0
  89. package/dist/components/toc/default.js +1 -0
  90. package/dist/components/toc/index.d.ts +2 -0
  91. package/dist/components/toc/index.d.ts.map +1 -0
  92. package/dist/components/toc/index.js +1 -0
  93. package/dist/components/type-table.d.ts +32 -0
  94. package/dist/components/type-table.d.ts.map +1 -0
  95. package/dist/components/type-table.js +28 -0
  96. package/dist/components/ui/accordion.d.ts +8 -0
  97. package/dist/components/ui/accordion.d.ts.map +1 -0
  98. package/dist/components/ui/accordion.js +20 -0
  99. package/dist/components/ui/button.d.ts +8 -0
  100. package/dist/components/ui/button.d.ts.map +1 -0
  101. package/dist/components/ui/button.js +20 -0
  102. package/dist/components/ui/collapsible.d.ts +9 -0
  103. package/dist/components/ui/collapsible.d.ts.map +1 -0
  104. package/dist/components/ui/collapsible.js +9 -0
  105. package/dist/components/ui/navigation-menu.d.ts +12 -0
  106. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  107. package/dist/components/ui/navigation-menu.js +15 -0
  108. package/dist/components/ui/popover.d.ts +8 -0
  109. package/dist/components/ui/popover.d.ts.map +1 -0
  110. package/dist/components/ui/popover.js +11 -0
  111. package/dist/components/ui/scroll-area.d.ts +8 -0
  112. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  113. package/dist/components/ui/scroll-area.js +11 -0
  114. package/dist/components/ui/tabs.d.ts +22 -0
  115. package/dist/components/ui/tabs.d.ts.map +1 -0
  116. package/dist/components/ui/tabs.js +79 -0
  117. package/dist/contexts/i18n.d.ts +2 -0
  118. package/dist/contexts/i18n.d.ts.map +1 -0
  119. package/dist/contexts/i18n.js +1 -0
  120. package/dist/contexts/search.d.ts +2 -0
  121. package/dist/contexts/search.d.ts.map +1 -0
  122. package/dist/contexts/search.js +1 -0
  123. package/dist/contexts/tree.d.ts +2 -0
  124. package/dist/contexts/tree.d.ts.map +1 -0
  125. package/dist/contexts/tree.js +1 -0
  126. package/dist/i18n.d.ts +2 -0
  127. package/dist/i18n.d.ts.map +1 -0
  128. package/dist/i18n.js +1 -0
  129. package/dist/layouts/docs/client.d.ts +15 -0
  130. package/dist/layouts/docs/client.d.ts.map +1 -0
  131. package/dist/layouts/docs/client.js +41 -0
  132. package/dist/layouts/docs/index.d.ts +36 -0
  133. package/dist/layouts/docs/index.d.ts.map +1 -0
  134. package/dist/layouts/docs/index.js +66 -0
  135. package/dist/layouts/docs/page/client.d.ts +24 -0
  136. package/dist/layouts/docs/page/client.d.ts.map +1 -0
  137. package/dist/layouts/docs/page/client.js +119 -0
  138. package/dist/layouts/docs/page/index.d.ts +58 -0
  139. package/dist/layouts/docs/page/index.d.ts.map +1 -0
  140. package/dist/layouts/docs/page/index.js +51 -0
  141. package/dist/layouts/docs/sidebar.d.ts +17 -0
  142. package/dist/layouts/docs/sidebar.d.ts.map +1 -0
  143. package/dist/layouts/docs/sidebar.js +94 -0
  144. package/dist/layouts/home/client.d.ts +6 -0
  145. package/dist/layouts/home/client.d.ts.map +1 -0
  146. package/dist/layouts/home/client.js +136 -0
  147. package/dist/layouts/home/index.d.ts +7 -0
  148. package/dist/layouts/home/index.d.ts.map +1 -0
  149. package/dist/layouts/home/index.js +8 -0
  150. package/dist/layouts/home/navbar.d.ts +7 -0
  151. package/dist/layouts/home/navbar.d.ts.map +1 -0
  152. package/dist/layouts/home/navbar.js +16 -0
  153. package/dist/layouts/notebook/client.d.ts +23 -0
  154. package/dist/layouts/notebook/client.d.ts.map +1 -0
  155. package/dist/layouts/notebook/client.js +104 -0
  156. package/dist/layouts/notebook/index.d.ts +34 -0
  157. package/dist/layouts/notebook/index.d.ts.map +1 -0
  158. package/dist/layouts/notebook/index.js +89 -0
  159. package/dist/layouts/notebook/page/client.d.ts +24 -0
  160. package/dist/layouts/notebook/page/client.d.ts.map +1 -0
  161. package/dist/layouts/notebook/page/client.js +119 -0
  162. package/dist/layouts/notebook/page/index.d.ts +58 -0
  163. package/dist/layouts/notebook/page/index.d.ts.map +1 -0
  164. package/dist/layouts/notebook/page/index.js +51 -0
  165. package/dist/layouts/notebook/sidebar.d.ts +17 -0
  166. package/dist/layouts/notebook/sidebar.d.ts.map +1 -0
  167. package/dist/layouts/notebook/sidebar.js +91 -0
  168. package/dist/layouts/shared/index.d.ts +56 -0
  169. package/dist/layouts/shared/index.d.ts.map +1 -0
  170. package/dist/layouts/shared/index.js +17 -0
  171. package/dist/layouts/shared/language-toggle.d.ts +5 -0
  172. package/dist/layouts/shared/language-toggle.d.ts.map +1 -0
  173. package/dist/layouts/shared/language-toggle.js +24 -0
  174. package/dist/layouts/shared/search-toggle.d.ts +11 -0
  175. package/dist/layouts/shared/search-toggle.d.ts.map +1 -0
  176. package/dist/layouts/shared/search-toggle.js +27 -0
  177. package/dist/layouts/shared/theme-toggle.d.ts +5 -0
  178. package/dist/layouts/shared/theme-toggle.d.ts.map +1 -0
  179. package/dist/layouts/shared/theme-toggle.js +38 -0
  180. package/dist/mdx.d.ts +33 -0
  181. package/dist/mdx.d.ts.map +1 -0
  182. package/dist/mdx.js +40 -0
  183. package/dist/mdx.server.d.ts +13 -0
  184. package/dist/mdx.server.d.ts.map +1 -0
  185. package/dist/mdx.server.js +15 -0
  186. package/dist/og.d.ts +2 -0
  187. package/dist/og.d.ts.map +1 -0
  188. package/dist/og.js +1 -0
  189. package/dist/page.d.ts +27 -0
  190. package/dist/page.d.ts.map +1 -0
  191. package/dist/page.js +22 -0
  192. package/dist/provider/base.d.ts +40 -0
  193. package/dist/provider/base.d.ts.map +1 -0
  194. package/dist/provider/base.js +19 -0
  195. package/dist/provider/next.d.ts +14 -0
  196. package/dist/provider/next.d.ts.map +1 -0
  197. package/dist/provider/next.js +7 -0
  198. package/dist/provider/react-router.d.ts +14 -0
  199. package/dist/provider/react-router.d.ts.map +1 -0
  200. package/dist/provider/react-router.js +7 -0
  201. package/dist/provider/tanstack.d.ts +14 -0
  202. package/dist/provider/tanstack.d.ts.map +1 -0
  203. package/dist/provider/tanstack.js +7 -0
  204. package/dist/provider/waku.d.ts +14 -0
  205. package/dist/provider/waku.d.ts.map +1 -0
  206. package/dist/provider/waku.js +7 -0
  207. package/dist/style.css +3159 -0
  208. package/dist/utils/use-copy-button.d.ts +2 -0
  209. package/dist/utils/use-copy-button.d.ts.map +1 -0
  210. package/dist/utils/use-copy-button.js +1 -0
  211. package/dist/utils/use-footer-items.d.ts +2 -0
  212. package/dist/utils/use-footer-items.d.ts.map +1 -0
  213. package/dist/utils/use-footer-items.js +1 -0
  214. package/dist/utils/use-is-scroll-top.d.ts +2 -0
  215. package/dist/utils/use-is-scroll-top.d.ts.map +1 -0
  216. package/dist/utils/use-is-scroll-top.js +1 -0
  217. package/package.json +133 -0
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useDocsSearch, } from 'fumadocs-core/search/client';
4
+ import { useMemo, useState } from 'react';
5
+ import { useOnChange } from 'fumadocs-core/utils/use-on-change';
6
+ import { SearchDialog, SearchDialogClose, SearchDialogContent, SearchDialogFooter, SearchDialogHeader, SearchDialogIcon, SearchDialogInput, SearchDialogList, SearchDialogOverlay, TagsList, TagsListItem, } from './search.js';
7
+ import { useI18n } from '../../contexts/i18n.js';
8
+ /**
9
+ * Orama Cloud integration
10
+ */
11
+ export default function OramaSearchDialog({ client, searchOptions, tags = [], defaultTag, showOrama = true, allowClear = false, index, footer, links = [], ...props }) {
12
+ const { locale } = useI18n();
13
+ const [tag, setTag] = useState(defaultTag);
14
+ const { search, setSearch, query } = useDocsSearch({
15
+ type: 'orama-cloud',
16
+ client,
17
+ index,
18
+ params: searchOptions,
19
+ locale,
20
+ tag,
21
+ });
22
+ const defaultItems = useMemo(() => {
23
+ if (links.length === 0)
24
+ return null;
25
+ return links.map(([name, link]) => ({
26
+ type: 'page',
27
+ id: name,
28
+ content: name,
29
+ url: link,
30
+ }));
31
+ }, [links]);
32
+ useOnChange(defaultTag, (v) => {
33
+ setTag(v);
34
+ });
35
+ const label = showOrama && _jsx(Label, {});
36
+ return (_jsxs(SearchDialog, { search: search, onSearchChange: setSearch, isLoading: query.isLoading, ...props, children: [_jsx(SearchDialogOverlay, {}), _jsxs(SearchDialogContent, { children: [_jsxs(SearchDialogHeader, { children: [_jsx(SearchDialogIcon, {}), _jsx(SearchDialogInput, {}), _jsx(SearchDialogClose, {})] }), _jsx(SearchDialogList, { items: query.data !== 'empty' ? query.data : defaultItems }), _jsxs(SearchDialogFooter, { children: [tags.length > 0 ? (_jsxs(TagsList, { tag: tag, onTagChange: setTag, allowClear: allowClear, children: [tags.map((tag) => (_jsx(TagsListItem, { value: tag.value, children: tag.name }, tag.value))), label] })) : (label), footer] })] })] }));
37
+ }
38
+ function Label() {
39
+ return (_jsx("a", { href: "https://orama.com", rel: "noreferrer noopener", className: "ms-auto text-xs text-fd-muted-foreground", children: "Search powered by Orama" }));
40
+ }
@@ -0,0 +1,72 @@
1
+ import { type ComponentProps, type ReactNode } from 'react';
2
+ import { Dialog } from '@base-ui/react/dialog';
3
+ import type { HighlightedText, ReactSortedResult as BaseResultType } from 'fumadocs-core/search';
4
+ import type { SharedProps } from '../../contexts/search.js';
5
+ export type SearchItemType = (BaseResultType & {
6
+ external?: boolean;
7
+ }) | {
8
+ id: string;
9
+ type: 'action';
10
+ node: ReactNode;
11
+ onSelect: () => void;
12
+ };
13
+ export type { SharedProps };
14
+ export interface SearchDialogProps extends SharedProps {
15
+ search: string;
16
+ onSearchChange: (v: string) => void;
17
+ isLoading?: boolean;
18
+ children: ReactNode;
19
+ }
20
+ export declare function SearchDialog({ open, onOpenChange, search, onSearchChange, isLoading, children, }: SearchDialogProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function SearchDialogHeader(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
22
+ export declare function SearchDialogInput(props: ComponentProps<'input'>): import("react/jsx-runtime").JSX.Element;
23
+ export declare function SearchDialogClose({ children, className, ...props }: ComponentProps<'button'>): import("react/jsx-runtime").JSX.Element;
24
+ export declare function SearchDialogFooter(props: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
25
+ export declare function SearchDialogOverlay({ className, ...props }: ComponentProps<typeof Dialog.Backdrop>): import("react/jsx-runtime").JSX.Element;
26
+ export declare function SearchDialogContent({ children, className, ...props }: ComponentProps<typeof Dialog.Popup>): import("react/jsx-runtime").JSX.Element;
27
+ export declare function SearchDialogList({ items, Empty, Item, ...props }: Omit<ComponentProps<'div'>, 'children'> & {
28
+ items: SearchItemType[] | null | undefined;
29
+ /**
30
+ * Renderer for empty list UI
31
+ */
32
+ Empty?: () => ReactNode;
33
+ /**
34
+ * Renderer for items
35
+ */
36
+ Item?: (props: {
37
+ item: SearchItemType;
38
+ onClick: () => void;
39
+ }) => ReactNode;
40
+ }): import("react/jsx-runtime").JSX.Element;
41
+ export declare function SearchDialogListItem({ item, className, children, renderHighlights: render, ...props }: ComponentProps<'button'> & {
42
+ renderHighlights?: typeof renderHighlights;
43
+ item: SearchItemType;
44
+ }): import("react/jsx-runtime").JSX.Element;
45
+ export declare function SearchDialogIcon(props: ComponentProps<'svg'>): import("react/jsx-runtime").JSX.Element;
46
+ export interface TagsListProps extends ComponentProps<'div'> {
47
+ tag?: string;
48
+ onTagChange: (tag: string | undefined) => void;
49
+ allowClear?: boolean;
50
+ }
51
+ export declare function TagsList({ tag, onTagChange, allowClear, ...props }: TagsListProps): import("react/jsx-runtime").JSX.Element;
52
+ export declare function TagsListItem({ value, className, ...props }: ComponentProps<'button'> & {
53
+ value: string;
54
+ }): import("react/jsx-runtime").JSX.Element;
55
+ declare function renderHighlights(highlights: HighlightedText<ReactNode>[]): ReactNode;
56
+ export declare function useSearch(): {
57
+ open: boolean;
58
+ onOpenChange: (open: boolean) => void;
59
+ search: string;
60
+ onSearchChange: (v: string) => void;
61
+ isLoading: boolean;
62
+ };
63
+ export declare function useTagsList(): {
64
+ value?: string;
65
+ onValueChange: (value: string | undefined) => void;
66
+ allowClear: boolean;
67
+ };
68
+ export declare function useSearchList(): {
69
+ active: string | null;
70
+ setActive: (v: string | null) => void;
71
+ };
72
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/components/dialog/search.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { ChevronRight, Hash, Search as SearchIcon } from '@fumadocs/ui/icons';
4
+ import { createContext, Fragment, useCallback, useContext, useEffect, useEffectEvent, useMemo, useRef, useState, } from 'react';
5
+ import { I18nLabel, useI18n } from '../../contexts/i18n.js';
6
+ import { cn } from '@fumadocs/ui/cn';
7
+ import { Dialog } from '@base-ui/react/dialog';
8
+ import { cva } from 'class-variance-authority';
9
+ import { useRouter } from 'fumadocs-core/framework';
10
+ import { useOnChange } from 'fumadocs-core/utils/use-on-change';
11
+ import scrollIntoView from 'scroll-into-view-if-needed';
12
+ import { buttonVariants } from '../../components/ui/button.js';
13
+ const Context = createContext(null);
14
+ const ListContext = createContext(null);
15
+ const TagsListContext = createContext(null);
16
+ export function SearchDialog({ open, onOpenChange, search, onSearchChange, isLoading = false, children, }) {
17
+ const [active, setActive] = useState(null);
18
+ return (_jsx(Dialog.Root, { open: open, onOpenChange: onOpenChange, children: _jsx(Context.Provider, { value: useMemo(() => ({
19
+ open,
20
+ onOpenChange,
21
+ search,
22
+ onSearchChange,
23
+ active,
24
+ setActive,
25
+ isLoading,
26
+ }), [active, isLoading, onOpenChange, onSearchChange, open, search]), children: children }) }));
27
+ }
28
+ export function SearchDialogHeader(props) {
29
+ return (_jsx("div", { ...props, className: cn('flex flex-row items-center gap-2 p-3', props.className) }));
30
+ }
31
+ export function SearchDialogInput(props) {
32
+ const { text } = useI18n();
33
+ const { search, onSearchChange } = useSearch();
34
+ return (_jsx("input", { ...props, value: search, onChange: (e) => onSearchChange(e.target.value), placeholder: text.search, className: "w-0 flex-1 bg-transparent text-lg placeholder:text-fd-muted-foreground focus-visible:outline-none" }));
35
+ }
36
+ export function SearchDialogClose({ children = 'ESC', className, ...props }) {
37
+ const { onOpenChange } = useSearch();
38
+ return (_jsx("button", { type: "button", onClick: () => onOpenChange(false), className: cn(buttonVariants({
39
+ color: 'outline',
40
+ size: 'sm',
41
+ className: 'font-mono text-fd-muted-foreground',
42
+ }), className), ...props, children: children }));
43
+ }
44
+ export function SearchDialogFooter(props) {
45
+ return (_jsx("div", { ...props, className: cn('bg-fd-secondary/50 p-3 empty:hidden', props.className) }));
46
+ }
47
+ export function SearchDialogOverlay({ className, ...props }) {
48
+ return (_jsx(Dialog.Backdrop, { ...props, className: (s) => cn('fixed inset-0 z-50 backdrop-blur-xs bg-fd-overlay data-[open]:animate-fd-fade-in data-[closed]:animate-fd-fade-out', typeof className === 'function' ? className(s) : className) }));
49
+ }
50
+ export function SearchDialogContent({ children, className, ...props }) {
51
+ const { text } = useI18n();
52
+ return (_jsx(Dialog.Portal, { children: _jsxs(Dialog.Popup, { "aria-describedby": undefined, ...props, className: (s) => cn('fixed left-1/2 top-4 md:top-[calc(50%-250px)] z-50 w-[calc(100%-1rem)] max-w-screen-sm -translate-x-1/2 rounded-xl border bg-fd-popover text-fd-popover-foreground shadow-2xl shadow-black/50 overflow-hidden data-[closed]:animate-fd-dialog-out data-[open]:animate-fd-dialog-in', '*:border-b *:has-[+:last-child[data-empty=true]]:border-b-0 *:data-[empty=true]:border-b-0 *:last:border-b-0', typeof className === 'function' ? className(s) : className), children: [_jsx(Dialog.Title, { className: "hidden", children: text.search }), children] }) }));
53
+ }
54
+ export function SearchDialogList({ items = null, Empty = () => (_jsx("div", { className: "py-12 text-center text-sm text-fd-muted-foreground", children: _jsx(I18nLabel, { label: "searchNoResult" }) })), Item = (props) => _jsx(SearchDialogListItem, { ...props }), ...props }) {
55
+ const ref = useRef(null);
56
+ const [active, setActive] = useState(() => items && items.length > 0 ? items[0].id : null);
57
+ const { onOpenChange } = useSearch();
58
+ const router = useRouter();
59
+ const onOpen = (item) => {
60
+ if (item.type === 'action') {
61
+ item.onSelect();
62
+ }
63
+ else if (item.external) {
64
+ window.open(item.url, '_blank')?.focus();
65
+ }
66
+ else {
67
+ router.push(item.url);
68
+ }
69
+ onOpenChange(false);
70
+ };
71
+ const onKey = useEffectEvent((e) => {
72
+ if (!items || e.isComposing)
73
+ return;
74
+ if (e.key === 'ArrowDown' || e.key == 'ArrowUp') {
75
+ let idx = items.findIndex((item) => item.id === active);
76
+ if (idx === -1)
77
+ idx = 0;
78
+ else if (e.key === 'ArrowDown')
79
+ idx++;
80
+ else
81
+ idx--;
82
+ setActive(items.at(idx % items.length)?.id ?? null);
83
+ e.preventDefault();
84
+ }
85
+ if (e.key === 'Enter') {
86
+ const selected = items.find((item) => item.id === active);
87
+ if (selected)
88
+ onOpen(selected);
89
+ e.preventDefault();
90
+ }
91
+ });
92
+ useEffect(() => {
93
+ const element = ref.current;
94
+ if (!element)
95
+ return;
96
+ const observer = new ResizeObserver(() => {
97
+ const viewport = element.firstElementChild;
98
+ element.style.setProperty('--fd-animated-height', `${viewport.clientHeight}px`);
99
+ });
100
+ const viewport = element.firstElementChild;
101
+ if (viewport)
102
+ observer.observe(viewport);
103
+ window.addEventListener('keydown', onKey);
104
+ return () => {
105
+ observer.disconnect();
106
+ window.removeEventListener('keydown', onKey);
107
+ };
108
+ }, []);
109
+ useOnChange(items, () => {
110
+ if (items && items.length > 0) {
111
+ setActive(items[0].id);
112
+ }
113
+ });
114
+ return (_jsx("div", { ...props, ref: ref, "data-empty": items === null, className: cn('overflow-hidden h-(--fd-animated-height) transition-[height]', props.className), children: _jsx("div", { className: cn('w-full flex flex-col overflow-y-auto max-h-[460px] p-1', !items && 'hidden'), children: _jsxs(ListContext.Provider, { value: useMemo(() => ({
115
+ active,
116
+ setActive,
117
+ }), [active]), children: [items?.length === 0 && Empty(), items?.map((item) => (_jsx(Fragment, { children: Item({ item, onClick: () => onOpen(item) }) }, item.id)))] }) }) }));
118
+ }
119
+ export function SearchDialogListItem({ item, className, children, renderHighlights: render = renderHighlights, ...props }) {
120
+ const { active: activeId, setActive } = useSearchList();
121
+ const active = item.id === activeId;
122
+ if (item.type === 'action') {
123
+ children ?? (children = item.node);
124
+ }
125
+ else {
126
+ children ?? (children = _jsxs(_Fragment, { children: [_jsx("div", { className: "inline-flex items-center text-fd-muted-foreground text-xs empty:hidden", children: item.breadcrumbs?.map((item, i) => (_jsxs(Fragment, { children: [i > 0 && _jsx(ChevronRight, { className: "size-4" }), item] }, i))) }), item.type !== 'page' && (_jsx("div", { role: "none", className: "absolute start-3 inset-y-0 w-px bg-fd-border" })), _jsxs("p", { className: cn('min-w-0 truncate', item.type !== 'page' && 'ps-4', item.type === 'page' || item.type === 'heading'
127
+ ? 'font-medium'
128
+ : 'text-fd-popover-foreground/80'), children: [item.type === 'heading' && (_jsx(Hash, { className: "inline me-1 size-4 text-fd-muted-foreground" })), item.contentWithHighlights
129
+ ? render(item.contentWithHighlights)
130
+ : item.content] })] }));
131
+ }
132
+ return (_jsx("button", { type: "button", ref: useCallback((element) => {
133
+ if (active && element) {
134
+ scrollIntoView(element, {
135
+ scrollMode: 'if-needed',
136
+ block: 'nearest',
137
+ boundary: element.parentElement,
138
+ });
139
+ }
140
+ }, [active]), "aria-selected": active, className: cn('relative select-none px-2.5 py-2 text-start text-sm rounded-lg', active && 'bg-fd-accent text-fd-accent-foreground', className), onPointerMove: () => setActive(item.id), ...props, children: children }));
141
+ }
142
+ export function SearchDialogIcon(props) {
143
+ const { isLoading } = useSearch();
144
+ return (_jsx(SearchIcon, { ...props, className: cn('size-5 text-fd-muted-foreground', isLoading && 'animate-pulse duration-400', props.className) }));
145
+ }
146
+ const itemVariants = cva('rounded-md border px-2 py-0.5 text-xs font-medium text-fd-muted-foreground transition-colors', {
147
+ variants: {
148
+ active: {
149
+ true: 'bg-fd-accent text-fd-accent-foreground',
150
+ },
151
+ },
152
+ });
153
+ export function TagsList({ tag, onTagChange, allowClear = false, ...props }) {
154
+ return (_jsx("div", { ...props, className: cn('flex items-center gap-1 flex-wrap', props.className), children: _jsx(TagsListContext.Provider, { value: useMemo(() => ({
155
+ value: tag,
156
+ onValueChange: onTagChange,
157
+ allowClear,
158
+ }), [allowClear, onTagChange, tag]), children: props.children }) }));
159
+ }
160
+ export function TagsListItem({ value, className, ...props }) {
161
+ const { onValueChange, value: selectedValue, allowClear } = useTagsList();
162
+ const selected = value === selectedValue;
163
+ return (_jsx("button", { type: "button", "data-active": selected, className: cn(itemVariants({ active: selected, className })), onClick: () => {
164
+ onValueChange(selected && allowClear ? undefined : value);
165
+ }, tabIndex: -1, ...props, children: props.children }));
166
+ }
167
+ function renderHighlights(highlights) {
168
+ return highlights.map((node, i) => {
169
+ if (node.styles?.highlight) {
170
+ return (_jsx("span", { className: "text-fd-primary underline", children: node.content }, i));
171
+ }
172
+ return _jsx(Fragment, { children: node.content }, i);
173
+ });
174
+ }
175
+ export function useSearch() {
176
+ const ctx = useContext(Context);
177
+ if (!ctx)
178
+ throw new Error('Missing <SearchDialog />');
179
+ return ctx;
180
+ }
181
+ export function useTagsList() {
182
+ const ctx = useContext(TagsListContext);
183
+ if (!ctx)
184
+ throw new Error('Missing <TagsList />');
185
+ return ctx;
186
+ }
187
+ export function useSearchList() {
188
+ const ctx = useContext(ListContext);
189
+ if (!ctx)
190
+ throw new Error('Missing <SearchDialogList />');
191
+ return ctx;
192
+ }
@@ -0,0 +1,21 @@
1
+ import { type CodeBlockProps } from '../components/codeblock.js';
2
+ import type { HighlightOptionsCommon, HighlightOptionsThemes } from 'fumadocs-core/highlight';
3
+ export interface DynamicCodeblockProps {
4
+ lang: string;
5
+ code: string;
6
+ /**
7
+ * Extra props for the underlying `<CodeBlock />` component.
8
+ *
9
+ * Ignored if you defined your own `pre` component in `options.components`.
10
+ */
11
+ codeblock?: CodeBlockProps;
12
+ /**
13
+ * Wrap in React `<Suspense />` and provide a fallback.
14
+ *
15
+ * @defaultValue true
16
+ */
17
+ wrapInSuspense?: boolean;
18
+ options?: Omit<HighlightOptionsCommon, 'lang'> & HighlightOptionsThemes;
19
+ }
20
+ export declare function DynamicCodeBlock({ lang, code, codeblock, options, wrapInSuspense, }: DynamicCodeblockProps): import("react/jsx-runtime").JSX.Element;
21
+ //# sourceMappingURL=dynamic-codeblock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-codeblock.d.ts","sourceRoot":"","sources":["../../src/components/dynamic-codeblock.tsx"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,cAAc,EAAO,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAEV,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AAajC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,GAAG,sBAAsB,CAAC;CACzE;AAkBD,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,OAAO,EACP,cAAqB,GACtB,EAAE,qBAAqB,2CAgCvB"}
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { CodeBlock, Pre } from '../components/codeblock.js';
4
+ import { useShiki } from 'fumadocs-core/highlight/client';
5
+ import { cn } from '@fumadocs/ui/cn';
6
+ import { createContext, Suspense, use, useDeferredValue, useId, } from 'react';
7
+ const PropsContext = createContext(undefined);
8
+ function DefaultPre(props) {
9
+ const extraProps = use(PropsContext);
10
+ return (_jsx(CodeBlock, { ...props, ...extraProps, className: cn('my-0', props.className, extraProps?.className), children: _jsx(Pre, { children: props.children }) }));
11
+ }
12
+ export function DynamicCodeBlock({ lang, code, codeblock, options, wrapInSuspense = true, }) {
13
+ const id = useId();
14
+ const shikiOptions = {
15
+ lang,
16
+ ...options,
17
+ components: {
18
+ pre: DefaultPre,
19
+ ...options?.components,
20
+ },
21
+ };
22
+ const children = (_jsx(PropsContext, { value: codeblock, children: _jsx(Internal, { id: id, ...useDeferredValue({ code, options: shikiOptions }) }) }));
23
+ if (wrapInSuspense)
24
+ return (_jsx(Suspense, { fallback: _jsx(Placeholder, { code: code, components: shikiOptions.components }), children: children }));
25
+ return children;
26
+ }
27
+ function Placeholder({ code, components = {}, }) {
28
+ const { pre: Pre = 'pre', code: Code = 'code' } = components;
29
+ return (_jsx(Pre, { children: _jsx(Code, { children: code.split('\n').map((line, i) => (_jsx("span", { className: "line", children: line }, i))) }) }));
30
+ }
31
+ function Internal({ id, code, options, }) {
32
+ return useShiki(code, options, [id, options.lang, code]);
33
+ }
@@ -0,0 +1,19 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ export declare function Files({ className, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement;
3
+ export interface FileProps extends HTMLAttributes<HTMLDivElement> {
4
+ name: string;
5
+ icon?: ReactNode;
6
+ }
7
+ export interface FolderProps extends HTMLAttributes<HTMLDivElement> {
8
+ name: string;
9
+ disabled?: boolean;
10
+ /**
11
+ * Open folder by default
12
+ *
13
+ * @defaultValue false
14
+ */
15
+ defaultOpen?: boolean;
16
+ }
17
+ export declare function File({ name, icon, className, ...rest }: FileProps): React.ReactElement;
18
+ export declare function Folder({ name, defaultOpen, ...props }: FolderProps): React.ReactElement;
19
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/components/files.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAY,MAAM,OAAO,CAAC;AAYtE,wBAAgB,KAAK,CAAC,EACpB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,YAAY,CASrD;AAED,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,cAAc,CAAC;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,MAAM,WAAW,WAAY,SAAQ,cAAc,CAAC,cAAc,CAAC;IACjE,IAAI,EAAE,MAAM,CAAC;IAEb,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,IAAmB,EACnB,SAAS,EACT,GAAG,IAAI,EACR,EAAE,SAAS,GAAG,KAAK,CAAC,YAAY,CAOhC;AAED,wBAAgB,MAAM,CAAC,EACrB,IAAI,EACJ,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,WAAW,GAAG,KAAK,CAAC,YAAY,CAclC"}
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { cva } from 'class-variance-authority';
4
+ import { File as FileIcon, Folder as FolderIcon, FolderOpen, } from '@fumadocs/ui/icons';
5
+ import { useState } from 'react';
6
+ import { cn } from '@fumadocs/ui/cn';
7
+ import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from './ui/collapsible.js';
8
+ const itemVariants = cva('flex flex-row items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground [&_svg]:size-4');
9
+ export function Files({ className, ...props }) {
10
+ return (_jsx("div", { className: cn('not-prose rounded-md border bg-fd-card p-2', className), ...props, children: props.children }));
11
+ }
12
+ export function File({ name, icon = _jsx(FileIcon, {}), className, ...rest }) {
13
+ return (_jsxs("div", { className: cn(itemVariants({ className })), ...rest, children: [icon, name] }));
14
+ }
15
+ export function Folder({ name, defaultOpen = false, ...props }) {
16
+ const [open, setOpen] = useState(defaultOpen);
17
+ return (_jsxs(Collapsible, { open: open, onOpenChange: setOpen, ...props, children: [_jsxs(CollapsibleTrigger, { className: cn(itemVariants({ className: 'w-full' })), children: [open ? _jsx(FolderOpen, {}) : _jsx(FolderIcon, {}), name] }), _jsx(CollapsibleContent, { children: _jsx("div", { className: "ms-2 flex flex-col border-l ps-2", children: props.children }) })] }));
18
+ }
@@ -0,0 +1,8 @@
1
+ import { type AnchorHTMLAttributes } from 'react';
2
+ export declare function GithubInfo({ repo, owner, token, baseUrl, ...props }: AnchorHTMLAttributes<HTMLAnchorElement> & {
3
+ owner: string;
4
+ repo: string;
5
+ token?: string;
6
+ baseUrl?: string;
7
+ }): Promise<import("react/jsx-runtime").JSX.Element>;
8
+ //# sourceMappingURL=github-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-info.d.ts","sourceRoot":"","sources":["../../src/components/github-info.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAsClD,wBAAsB,UAAU,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,KAAK,EACL,OAAO,EACP,GAAG,KAAK,EACT,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,oDA4BA"}
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '@fumadocs/ui/cn';
3
+ import { Star } from '@fumadocs/ui/icons';
4
+ async function getRepoStarsAndForks(owner, repo, token, baseUrl = 'https://api.github.com') {
5
+ const endpoint = `${baseUrl}/repos/${owner}/${repo}`;
6
+ const headers = new Headers({
7
+ 'Content-Type': 'application/json',
8
+ });
9
+ if (token)
10
+ headers.set('Authorization', `Bearer ${token}`);
11
+ const response = await fetch(endpoint, {
12
+ headers,
13
+ next: {
14
+ revalidate: 60,
15
+ },
16
+ });
17
+ if (!response.ok) {
18
+ const message = await response.text();
19
+ throw new Error(`Failed to fetch repository data: ${message}`);
20
+ }
21
+ const data = await response.json();
22
+ return {
23
+ stars: data.stargazers_count,
24
+ forks: data.forks_count,
25
+ };
26
+ }
27
+ export async function GithubInfo({ repo, owner, token, baseUrl, ...props }) {
28
+ const { stars } = await getRepoStarsAndForks(owner, repo, token, baseUrl);
29
+ const humanizedStars = humanizeNumber(stars);
30
+ return (_jsxs("a", { href: `https://github.com/${owner}/${repo}`, rel: "noreferrer noopener", target: "_blank", ...props, className: cn('flex flex-col gap-1.5 p-2 rounded-lg text-sm text-fd-foreground/80 transition-colors lg:flex-row lg:items-center hover:text-fd-accent-foreground hover:bg-fd-accent', props.className), children: [_jsxs("p", { className: "flex items-center gap-2 truncate", children: [_jsxs("svg", { fill: "currentColor", viewBox: "0 0 24 24", className: "size-3.5", children: [_jsx("title", { children: "GitHub" }), _jsx("path", { d: "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" })] }), owner, "/", repo] }), _jsxs("p", { className: "flex text-xs items-center gap-1 text-fd-muted-foreground", children: [_jsx(Star, { className: "size-3" }), humanizedStars] })] }));
31
+ }
32
+ /**
33
+ * Converts a number to a human-readable string with K suffix for thousands
34
+ * @example 1500 -> "1.5K", 1000000 -> "1000000"
35
+ */
36
+ function humanizeNumber(num) {
37
+ if (num < 1000) {
38
+ return num.toString();
39
+ }
40
+ if (num < 100000) {
41
+ // For numbers between 1,000 and 99,999, show with one decimal (e.g., 1.5K)
42
+ const value = (num / 1000).toFixed(1);
43
+ // Remove trailing .0 if present
44
+ const formattedValue = value.endsWith('.0') ? value.slice(0, -2) : value;
45
+ return `${formattedValue}K`;
46
+ }
47
+ if (num < 1000000) {
48
+ // For numbers between 10,000 and 999,999, show as whole K (e.g., 10K, 999K)
49
+ return `${Math.floor(num / 1000)}K`;
50
+ }
51
+ // For 1,000,000 and above, just return the number
52
+ return num.toString();
53
+ }
@@ -0,0 +1,8 @@
1
+ import type { ComponentPropsWithoutRef } from 'react';
2
+ type Types = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
3
+ type HeadingProps<T extends Types> = Omit<ComponentPropsWithoutRef<T>, 'as'> & {
4
+ as?: T;
5
+ };
6
+ export declare function Heading<T extends Types = 'h1'>({ as, className, ...props }: HeadingProps<T>): React.ReactElement;
7
+ export {};
8
+ //# sourceMappingURL=heading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heading.d.ts","sourceRoot":"","sources":["../../src/components/heading.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,OAAO,CAAC;AAGtD,KAAK,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACrD,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG;IAC7E,EAAE,CAAC,EAAE,CAAC,CAAC;CACR,CAAC;AAEF,wBAAgB,OAAO,CAAC,CAAC,SAAS,KAAK,GAAG,IAAI,EAAE,EAC9C,EAAE,EACF,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,YAAY,CAmBtC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Link } from '@fumadocs/ui/icons';
3
+ import { cn } from '@fumadocs/ui/cn';
4
+ export function Heading({ as, className, ...props }) {
5
+ const As = as ?? 'h1';
6
+ if (!props.id)
7
+ return _jsx(As, { className: className, ...props });
8
+ return (_jsxs(As, { className: cn('flex scroll-m-28 flex-row items-center gap-2', className), ...props, children: [_jsx("a", { "data-card": "", href: `#${props.id}`, className: "peer", children: props.children }), _jsx(Link, { "aria-hidden": true, className: "size-3.5 shrink-0 text-fd-muted-foreground opacity-0 transition-opacity peer-hover:opacity-100" })] }));
9
+ }
@@ -0,0 +1,77 @@
1
+ [data-rmiz] {
2
+ display: block;
3
+ position: relative;
4
+ }
5
+
6
+ [data-rmiz-ghost] {
7
+ pointer-events: none;
8
+ position: absolute;
9
+ }
10
+
11
+ [data-rmiz-btn-zoom],
12
+ [data-rmiz-btn-unzoom] {
13
+ display: none;
14
+ }
15
+
16
+ [data-rmiz-content='found'] img {
17
+ cursor: zoom-in;
18
+ }
19
+
20
+ [data-rmiz-modal][open] {
21
+ width: 100vw /* fallback */;
22
+ width: 100dvw;
23
+
24
+ height: 100vh /* fallback */;
25
+ height: 100dvh;
26
+
27
+ background-color: transparent;
28
+ max-width: none;
29
+ max-height: none;
30
+ margin: 0;
31
+ padding: 0;
32
+ position: fixed;
33
+ overflow: hidden;
34
+ }
35
+
36
+ [data-rmiz-modal]:focus-visible {
37
+ outline: none;
38
+ }
39
+
40
+ [data-rmiz-modal-overlay] {
41
+ transition: background-color 0.3s;
42
+ position: absolute;
43
+ inset: 0;
44
+ }
45
+
46
+ [data-rmiz-modal-overlay='visible'] {
47
+ background-color: var(--color-fd-background);
48
+ }
49
+
50
+ [data-rmiz-modal-overlay='hidden'] {
51
+ background-color: transparent;
52
+ }
53
+
54
+ [data-rmiz-modal-content] {
55
+ width: 100%;
56
+ height: 100%;
57
+ position: relative;
58
+ }
59
+
60
+ [data-rmiz-modal]::backdrop {
61
+ display: none;
62
+ }
63
+
64
+ [data-rmiz-modal-img] {
65
+ cursor: zoom-out;
66
+ image-rendering: high-quality;
67
+ transform-origin: 0 0;
68
+ transition: transform 0.3s;
69
+ position: absolute;
70
+ }
71
+
72
+ @media (prefers-reduced-motion: reduce) {
73
+ [data-rmiz-modal-overlay],
74
+ [data-rmiz-modal-img] {
75
+ transition-duration: 0.01ms !important;
76
+ }
77
+ }
@@ -0,0 +1,16 @@
1
+ import { type ImageProps } from 'fumadocs-core/framework';
2
+ import type { ComponentProps } from 'react';
3
+ import { type UncontrolledProps } from 'react-medium-image-zoom';
4
+ import './image-zoom.css';
5
+ export type ImageZoomProps = ImageProps & {
6
+ /**
7
+ * Image props when zoom in
8
+ */
9
+ zoomInProps?: ComponentProps<'img'>;
10
+ /**
11
+ * Props for `react-medium-image-zoom`
12
+ */
13
+ rmiz?: UncontrolledProps;
14
+ };
15
+ export declare function ImageZoom({ zoomInProps, children, rmiz, ...props }: ImageZoomProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=image-zoom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-zoom.d.ts","sourceRoot":"","sources":["../../src/components/image-zoom.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,kBAAkB,CAAC;AAE1B,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG;IACxC;;OAEG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;IAEpC;;OAEG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;CAC1B,CAAC;AAeF,wBAAgB,SAAS,CAAC,EACxB,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,cAAc,2CAoBhB"}
@@ -0,0 +1,23 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Image } from 'fumadocs-core/framework';
4
+ import Zoom from 'react-medium-image-zoom';
5
+ import './image-zoom.css';
6
+ function getImageSrc(src) {
7
+ if (typeof src === 'string')
8
+ return src;
9
+ if (typeof src === 'object') {
10
+ // Next.js
11
+ if ('default' in src)
12
+ return src.default.src;
13
+ return src.src;
14
+ }
15
+ return '';
16
+ }
17
+ export function ImageZoom({ zoomInProps, children, rmiz, ...props }) {
18
+ return (_jsx(Zoom, { zoomMargin: 20, wrapElement: "span", ...rmiz, zoomImg: {
19
+ src: getImageSrc(props.src),
20
+ sizes: undefined,
21
+ ...zoomInProps,
22
+ }, children: children ?? (_jsx(Image, { sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 70vw, 900px", ...props })) }));
23
+ }
@@ -0,0 +1,8 @@
1
+ import type { TOCItemType } from 'fumadocs-core/toc';
2
+ import { Collapsible } from './ui/collapsible.js';
3
+ import type { ComponentProps } from 'react';
4
+ export interface InlineTocProps extends ComponentProps<typeof Collapsible> {
5
+ items: TOCItemType[];
6
+ }
7
+ export declare function InlineTOC({ items, className, ...props }: InlineTocProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=inline-toc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-toc.d.ts","sourceRoot":"","sources":["../../src/components/inline-toc.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,WAAW,EAGZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,OAAO,WAAW,CAAC;IACxE,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,2CAiCvE"}