@fumadocs/base-ui 16.6.0 → 16.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/generated/shared.css +7 -4
- package/dist/components/dialog/search.d.ts.map +1 -1
- package/dist/components/dialog/search.js +5 -3
- package/dist/components/dialog/search.js.map +1 -1
- package/dist/components/type-table.d.ts +6 -3
- package/dist/components/type-table.d.ts.map +1 -1
- package/dist/components/type-table.js +21 -12
- package/dist/components/type-table.js.map +1 -1
- package/dist/components/ui/navigation-menu.d.ts +2 -2
- package/dist/components/ui/navigation-menu.d.ts.map +1 -1
- package/dist/layouts/home/navbar.d.ts +1 -1
- package/dist/layouts/home/navbar.d.ts.map +1 -1
- package/dist/layouts/shared/search-toggle.js +1 -1
- package/dist/layouts/shared/search-toggle.js.map +1 -1
- package/dist/style.css +21 -10
- package/package.json +7 -7
package/css/generated/shared.css
CHANGED
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
@source inline("active");
|
|
64
64
|
@source inline("activeType");
|
|
65
65
|
@source inline("add");
|
|
66
|
+
@source inline("addEventListener");
|
|
66
67
|
@source inline("advanced");
|
|
67
68
|
@source inline("after");
|
|
68
69
|
@source inline("algolia");
|
|
@@ -237,6 +238,7 @@
|
|
|
237
238
|
@source inline("data-icon");
|
|
238
239
|
@source inline("data-line-numbers");
|
|
239
240
|
@source inline("data-line-numbers-start");
|
|
241
|
+
@source inline("data-open:animate-fd-dialog-in");
|
|
240
242
|
@source inline("data-open:animate-fd-fade-in");
|
|
241
243
|
@source inline("data-open:bg-fd-accent");
|
|
242
244
|
@source inline("data-open:text-fd-accent-foreground");
|
|
@@ -244,7 +246,6 @@
|
|
|
244
246
|
@source inline("data-search-full");
|
|
245
247
|
@source inline("data-state");
|
|
246
248
|
@source inline("data-theme-toggle");
|
|
247
|
-
@source inline("dataopen:animate-fd-dialog-in");
|
|
248
249
|
@source inline("date");
|
|
249
250
|
@source inline("debounced");
|
|
250
251
|
@source inline("decimal");
|
|
@@ -318,6 +319,7 @@
|
|
|
318
319
|
@source inline("false");
|
|
319
320
|
@source inline("fd-moving-banner");
|
|
320
321
|
@source inline("fd-scroll-container");
|
|
322
|
+
@source inline("fd-search-dialog-content");
|
|
321
323
|
@source inline("fd-step");
|
|
322
324
|
@source inline("fd-steps");
|
|
323
325
|
@source inline("fetch");
|
|
@@ -485,7 +487,6 @@
|
|
|
485
487
|
@source inline("keepBackground");
|
|
486
488
|
@source inline("keepMounted");
|
|
487
489
|
@source inline("key");
|
|
488
|
-
@source inline("keyVariants");
|
|
489
490
|
@source inline("keydown");
|
|
490
491
|
@source inline("keyof");
|
|
491
492
|
@source inline("label");
|
|
@@ -691,6 +692,7 @@
|
|
|
691
692
|
@source inline("page");
|
|
692
693
|
@source inline("parameters");
|
|
693
694
|
@source inline("params");
|
|
695
|
+
@source inline("parentId");
|
|
694
696
|
@source inline("pass");
|
|
695
697
|
@source inline("passed");
|
|
696
698
|
@source inline("path");
|
|
@@ -776,6 +778,7 @@
|
|
|
776
778
|
@source inline("relative");
|
|
777
779
|
@source inline("remarkRehypeOptions");
|
|
778
780
|
@source inline("remove");
|
|
781
|
+
@source inline("removeEventListener");
|
|
779
782
|
@source inline("render");
|
|
780
783
|
@source inline("renderHighlights");
|
|
781
784
|
@source inline("renderMarkdown");
|
|
@@ -812,6 +815,7 @@
|
|
|
812
815
|
@source inline("s");
|
|
813
816
|
@source inline("scroll");
|
|
814
817
|
@source inline("scroll-into-view-if-needed");
|
|
818
|
+
@source inline("scroll-m-20");
|
|
815
819
|
@source inline("scroll-m-24");
|
|
816
820
|
@source inline("scroll-m-28");
|
|
817
821
|
@source inline("scrollIntoView");
|
|
@@ -844,7 +848,6 @@
|
|
|
844
848
|
@source inline("setTag");
|
|
845
849
|
@source inline("setValue");
|
|
846
850
|
@source inline("shadow-2xl");
|
|
847
|
-
@source inline("shadow-black/50");
|
|
848
851
|
@source inline("shadow-lg");
|
|
849
852
|
@source inline("shadow-md");
|
|
850
853
|
@source inline("shadow-sm");
|
|
@@ -1039,7 +1042,7 @@
|
|
|
1039
1042
|
@source inline("w-0");
|
|
1040
1043
|
@source inline("w-0.5");
|
|
1041
1044
|
@source inline("w-1.5");
|
|
1042
|
-
@source inline("w-
|
|
1045
|
+
@source inline("w-1/4");
|
|
1043
1046
|
@source inline("w-[calc(100%-1rem)]");
|
|
1044
1047
|
@source inline("w-fit");
|
|
1045
1048
|
@source inline("w-full");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","names":[],"sources":["../../../src/components/dialog/search.tsx"],"mappings":";;;;;;;KAgCY,cAAA,IACP,iBAAA;EACC,QAAA;AAAA;EAGA,EAAA;EACA,IAAA;EACA,IAAA,EAAM,SAAA;EACN,QAAA;AAAA;AAAA,UAMW,iBAAA,SAA0B,WAAA;EACzC,MAAA;EACA,cAAA,GAAiB,CAAA;EACjB,QAAA,IAAY,IAAA,EAAM,cAAA;EAClB,SAAA;EAEA,QAAA,EAAU,SAAA;AAAA;AAAA,iBAkHI,YAAA,CAAA;EACd,IAAA;EACA,YAAA;EACA,MAAA;EACA,cAAA;EACA,SAAA;EACA,QAAA,EAAU,YAAA;EACV;AAAA,GACC,iBAAA,GAAiB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA0CJ,kBAAA,CAAmB,KAAA,EAAO,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAI/C,iBAAA,CAAkB,KAAA,EAAO,cAAA,YAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAehD,iBAAA,CAAA;EACd,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,aAAwB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAsBX,kBAAA,CAAmB,KAAA,EAAO,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAI/C,mBAAA,CAAA;EACd,SAAA;EAAA,GACG;AAAA,GACF,cAAA,QAAsB,MAAA,CAAO,QAAA,IAAS,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAczB,mBAAA,CAAA;EACd,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,QAAsB,MAAA,CAAO,KAAA,IAAM,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"search.d.ts","names":[],"sources":["../../../src/components/dialog/search.tsx"],"mappings":";;;;;;;KAgCY,cAAA,IACP,iBAAA;EACC,QAAA;AAAA;EAGA,EAAA;EACA,IAAA;EACA,IAAA,EAAM,SAAA;EACN,QAAA;AAAA;AAAA,UAMW,iBAAA,SAA0B,WAAA;EACzC,MAAA;EACA,cAAA,GAAiB,CAAA;EACjB,QAAA,IAAY,IAAA,EAAM,cAAA;EAClB,SAAA;EAEA,QAAA,EAAU,SAAA;AAAA;AAAA,iBAkHI,YAAA,CAAA;EACd,IAAA;EACA,YAAA;EACA,MAAA;EACA,cAAA;EACA,SAAA;EACA,QAAA,EAAU,YAAA;EACV;AAAA,GACC,iBAAA,GAAiB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBA0CJ,kBAAA,CAAmB,KAAA,EAAO,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAI/C,iBAAA,CAAkB,KAAA,EAAO,cAAA,YAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAehD,iBAAA,CAAA;EACd,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,aAAwB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAsBX,kBAAA,CAAmB,KAAA,EAAO,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAI/C,mBAAA,CAAA;EACd,SAAA;EAAA,GACG;AAAA,GACF,cAAA,QAAsB,MAAA,CAAO,QAAA,IAAS,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAczB,mBAAA,CAAA;EACd,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,QAAsB,MAAA,CAAO,KAAA,IAAM,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAwBtB,gBAAA,CAAA;EACd,KAAA;EACA,KAAA;EAKA,IAAA;EAAA,GACG;AAAA,GACF,IAAA,CAAK,cAAA;EACN,KAAA,EAAO,cAAA;EAjRP;;;EAqRA,KAAA,SAAc,SAAA;EAnRI;;;EAuRlB,IAAA,IAAQ,KAAA;IAAS,IAAA,EAAM,cAAA;IAAgB,OAAA;EAAA,MAA0B,SAAA;AAAA,IAClE,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAyFe,oBAAA,CAAA;EACd,IAAA;EACA,SAAA;EACA,QAAA;EACA,cAAA;EACA,gBAAA,EAAkB,CAAA;EAAA,GACf;AAAA,GACF,cAAA;EACD,cAAA,IAAkB,CAAA,aAAc,SAAA,EAnQhC;EAqQA,gBAAA,IAAoB,MAAA,EAAQ,eAAA,CAAgB,SAAA,QAAiB,SAAA;EAC7D,IAAA,EAAM,cAAA;AAAA,IACP,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAoEe,gBAAA,CAAiB,KAAA,EAAO,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,UAe5C,aAAA,SAAsB,cAAA;EACrC,GAAA;EACA,WAAA,GAAc,GAAA;EACd,UAAA;AAAA;AAAA,iBAac,QAAA,CAAA;EAAW,GAAA;EAAK,WAAA;EAAa,UAAA;EAAA,GAAuB;AAAA,GAAS,aAAA,GAAa,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAqB1E,YAAA,CAAA;EACd,KAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA;EACD,KAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAkBe,SAAA,CAAA;;iBArgBC,IAAA;;mBAEE,CAAA;aACN,IAAA,EAAM,cAAA;;;iBAwgBH,WAAA,CAAA;;kBA7fE,KAAA;;;iBAmgBF,aAAA,CAAA;;cAxgBF,CAAA;AAAA"}
|
|
@@ -181,9 +181,10 @@ function SearchDialogOverlay({ className, ...props }) {
|
|
|
181
181
|
function SearchDialogContent({ children, className, ...props }) {
|
|
182
182
|
const { text } = useI18n();
|
|
183
183
|
return /* @__PURE__ */ jsx(Dialog.Portal, { children: /* @__PURE__ */ jsxs(Dialog.Popup, {
|
|
184
|
+
id: "fd-search-dialog-content",
|
|
184
185
|
"aria-describedby": void 0,
|
|
185
186
|
...props,
|
|
186
|
-
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
|
|
187
|
+
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 overflow-hidden data-closed:animate-fd-dialog-out data-open:animate-fd-dialog-in focus-visible:outline-none", "*: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),
|
|
187
188
|
children: [/* @__PURE__ */ jsx(Dialog.Title, {
|
|
188
189
|
className: "hidden",
|
|
189
190
|
children: text.search
|
|
@@ -222,10 +223,11 @@ function SearchDialogList({ items = null, Empty = () => /* @__PURE__ */ jsx("div
|
|
|
222
223
|
});
|
|
223
224
|
const viewport = element.firstElementChild;
|
|
224
225
|
if (viewport) observer.observe(viewport);
|
|
225
|
-
|
|
226
|
+
const content = document.getElementById("fd-search-dialog-content") ?? window;
|
|
227
|
+
content.addEventListener("keydown", onKey);
|
|
226
228
|
return () => {
|
|
227
229
|
observer.disconnect();
|
|
228
|
-
|
|
230
|
+
content.removeEventListener("keydown", onKey);
|
|
229
231
|
};
|
|
230
232
|
}, []);
|
|
231
233
|
useOnChange(items, () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","names":["SearchIcon"],"sources":["../../../src/components/dialog/search.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronRight, Hash, Search as SearchIcon } from 'lucide-react';\nimport {\n type ComponentProps,\n createContext,\n Fragment,\n type ReactNode,\n use,\n useCallback,\n useEffect,\n useEffectEvent,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { I18nLabel, useI18n } from '@/contexts/i18n';\nimport { cn } from '@/utils/cn';\nimport { Dialog } from '@base-ui/react/dialog';\nimport type { HighlightedText, ReactSortedResult as BaseResultType } from 'fumadocs-core/search';\nimport { cva } from 'class-variance-authority';\nimport { useRouter } from 'fumadocs-core/framework';\nimport type { SharedProps } from '@/contexts/search';\nimport { useOnChange } from 'fumadocs-core/utils/use-on-change';\nimport scrollIntoView from 'scroll-into-view-if-needed';\nimport { buttonVariants } from '@/components/ui/button';\nimport { createMarkdownRenderer } from 'fumadocs-core/content/md';\nimport rehypeRaw from 'rehype-raw';\nimport { visit } from 'unist-util-visit';\nimport type { Transformer } from 'unified';\nimport type { Root } from 'hast';\n\nexport type SearchItemType =\n | (BaseResultType & {\n external?: boolean;\n })\n | {\n id: string;\n type: 'action';\n node: ReactNode;\n onSelect: () => void;\n };\n\n// needed for backward compatible since some previous guides referenced it\nexport type { SharedProps };\n\nexport interface SearchDialogProps extends SharedProps {\n search: string;\n onSearchChange: (v: string) => void;\n onSelect?: (item: SearchItemType) => void;\n isLoading?: boolean;\n\n children: ReactNode;\n}\n\nconst RootContext = createContext<{\n open: boolean;\n onOpenChange: (open: boolean) => void;\n search: string;\n onSearchChange: (v: string) => void;\n onSelect: (item: SearchItemType) => void;\n isLoading: boolean;\n} | null>(null);\n\nconst ListContext = createContext<{\n active: string | null;\n setActive: (v: string | null) => void;\n} | null>(null);\n\nconst TagsListContext = createContext<{\n value?: string;\n onValueChange: (value: string | undefined) => void;\n allowClear: boolean;\n} | null>(null);\n\nconst PreContext = createContext(false);\n\nconst mdRenderer = createMarkdownRenderer({\n remarkRehypeOptions: {\n allowDangerousHtml: true,\n },\n rehypePlugins: [rehypeRaw, rehypeCustomElements],\n});\n\nconst mdComponents = {\n mark(props: ComponentProps<'mark'>) {\n return <span {...props} className=\"text-fd-primary underline\" />;\n },\n a: 'span',\n p(props: ComponentProps<'p'>) {\n return <p {...props} className=\"min-w-0\" />;\n },\n strong(props: ComponentProps<'strong'>) {\n return <strong {...props} className=\"text-fd-accent-foreground font-medium\" />;\n },\n code(props: ComponentProps<'pre'>) {\n // eslint-disable-next-line react-hooks/rules-of-hooks -- this is a component\n const inPre = use(PreContext);\n if (inPre)\n return (\n <code\n {...props}\n className=\"mask-[linear-gradient(to_bottom,white,white_30px,transparent_80px)]\"\n />\n );\n\n return (\n <code\n {...props}\n className=\"border rounded-md px-px bg-fd-secondary text-fd-secondary-foreground\"\n />\n );\n },\n custom({\n _tagName = 'fragment',\n children,\n ...rest\n }: Record<string, unknown> & { _tagName: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex max-w-full items-center border p-0.5 rounded-md bg-fd-card text-fd-card-foreground divide-x divide-fd-border\">\n <code className=\"rounded-sm px-0.5 me-1 bg-fd-primary font-medium text-xs text-fd-primary-foreground border-none\">\n {_tagName}\n </code>\n {Object.entries(rest).map(([k, v]) => {\n if (typeof v !== 'string') return;\n\n return (\n <code key={k} className=\"truncate text-xs text-fd-muted-foreground px-1\">\n <span className=\"text-fd-card-foreground\">{k}: </span>\n {v}\n </code>\n );\n })}\n {children && <span className=\"ps-1\">{children}</span>}\n </span>\n );\n },\n pre(props: ComponentProps<'pre'>) {\n return (\n <pre\n {...props}\n className={cn(\n 'flex flex-col border rounded-md my-0.5 p-2 bg-fd-secondary text-fd-secondary-foreground max-h-20 overflow-hidden',\n props.className,\n )}\n >\n <PreContext value={true}>{props.children}</PreContext>\n </pre>\n );\n },\n};\n\nfunction rehypeCustomElements(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, (node) => {\n if (\n node.type === 'element' &&\n document.createElement(node.tagName) instanceof HTMLUnknownElement\n ) {\n node.properties._tagName = node.tagName;\n node.tagName = 'custom';\n }\n });\n };\n}\n\nexport function SearchDialog({\n open,\n onOpenChange,\n search,\n onSearchChange,\n isLoading = false,\n onSelect: onSelectProp,\n children,\n}: SearchDialogProps) {\n const router = useRouter();\n const onOpenChangeCallback = useRef(onOpenChange);\n onOpenChangeCallback.current = onOpenChange;\n const onSearchChangeCallback = useRef(onSearchChange);\n onSearchChangeCallback.current = onSearchChange;\n const onSelect = (item: SearchItemType) => {\n if (item.type === 'action') {\n item.onSelect();\n } else if (item.external) {\n window.open(item.url, '_blank')?.focus();\n } else {\n router.push(item.url);\n }\n\n onOpenChange(false);\n onSelectProp?.(item);\n };\n const onSelectCallback = useRef(onSelect);\n onSelectCallback.current = onSelect;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <RootContext\n value={useMemo(\n () => ({\n open,\n search,\n isLoading,\n onOpenChange: (v) => onOpenChangeCallback.current(v),\n onSearchChange: (v) => onSearchChangeCallback.current(v),\n onSelect: (v) => onSelectCallback.current(v),\n }),\n [isLoading, open, search],\n )}\n >\n {children}\n </RootContext>\n </Dialog.Root>\n );\n}\n\nexport function SearchDialogHeader(props: ComponentProps<'div'>) {\n return <div {...props} className={cn('flex flex-row items-center gap-2 p-3', props.className)} />;\n}\n\nexport function SearchDialogInput(props: ComponentProps<'input'>) {\n const { text } = useI18n();\n const { search, onSearchChange } = useSearch();\n\n return (\n <input\n {...props}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n placeholder={text.search}\n className=\"w-0 flex-1 bg-transparent text-lg placeholder:text-fd-muted-foreground focus-visible:outline-none\"\n />\n );\n}\n\nexport function SearchDialogClose({\n children = 'ESC',\n className,\n ...props\n}: ComponentProps<'button'>) {\n const { onOpenChange } = useSearch();\n\n return (\n <button\n type=\"button\"\n onClick={() => onOpenChange(false)}\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'sm',\n className: 'font-mono text-fd-muted-foreground',\n }),\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport function SearchDialogFooter(props: ComponentProps<'div'>) {\n return <div {...props} className={cn('bg-fd-secondary/50 p-3 empty:hidden', props.className)} />;\n}\n\nexport function SearchDialogOverlay({\n className,\n ...props\n}: ComponentProps<typeof Dialog.Backdrop>) {\n return (\n <Dialog.Backdrop\n {...props}\n className={(s) =>\n cn(\n 'fixed inset-0 z-50 backdrop-blur-xs bg-fd-overlay data-open:animate-fd-fade-in data-closed:animate-fd-fade-out',\n typeof className === 'function' ? className(s) : className,\n )\n }\n />\n );\n}\n\nexport function SearchDialogContent({\n children,\n className,\n ...props\n}: ComponentProps<typeof Dialog.Popup>) {\n const { text } = useI18n();\n\n return (\n <Dialog.Portal>\n <Dialog.Popup\n aria-describedby={undefined}\n {...props}\n className={(s) =>\n cn(\n '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 dataopen:animate-fd-dialog-in',\n '*:border-b *:has-[+:last-child[data-empty=true]]:border-b-0 *:data-[empty=true]:border-b-0 *:last:border-b-0',\n typeof className === 'function' ? className(s) : className,\n )\n }\n >\n <Dialog.Title className=\"hidden\">{text.search}</Dialog.Title>\n {children}\n </Dialog.Popup>\n </Dialog.Portal>\n );\n}\n\nexport function SearchDialogList({\n items = null,\n Empty = () => (\n <div className=\"py-12 text-center text-sm text-fd-muted-foreground\">\n <I18nLabel label=\"searchNoResult\" />\n </div>\n ),\n Item = (props) => <SearchDialogListItem {...props} />,\n ...props\n}: Omit<ComponentProps<'div'>, 'children'> & {\n items: SearchItemType[] | null | undefined;\n /**\n * Renderer for empty list UI\n */\n Empty?: () => ReactNode;\n /**\n * Renderer for items\n */\n Item?: (props: { item: SearchItemType; onClick: () => void }) => ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { onSelect } = useSearch();\n const [active, setActive] = useState<string | null>(() =>\n items && items.length > 0 ? items[0].id : null,\n );\n\n const onKey = useEffectEvent((e: KeyboardEvent) => {\n if (!items || e.isComposing) return;\n\n if (e.key === 'ArrowDown' || e.key == 'ArrowUp') {\n let idx = items.findIndex((item) => item.id === active);\n if (idx === -1) idx = 0;\n else if (e.key === 'ArrowDown') idx++;\n else idx--;\n\n setActive(items.at(idx % items.length)?.id ?? null);\n e.preventDefault();\n }\n\n if (e.key === 'Enter') {\n const selected = items.find((item) => item.id === active);\n\n if (selected) onSelect(selected);\n e.preventDefault();\n }\n });\n\n useEffect(() => {\n const element = ref.current;\n if (!element) return;\n\n const observer = new ResizeObserver(() => {\n const viewport = element.firstElementChild!;\n\n element.style.setProperty('--fd-animated-height', `${viewport.clientHeight}px`);\n });\n\n const viewport = element.firstElementChild;\n if (viewport) observer.observe(viewport);\n\n window.addEventListener('keydown', onKey);\n return () => {\n observer.disconnect();\n window.removeEventListener('keydown', onKey);\n };\n }, []);\n\n useOnChange(items, () => {\n if (items && items.length > 0) {\n setActive(items[0].id);\n }\n });\n\n return (\n <div\n {...props}\n ref={ref}\n data-empty={items === null}\n className={cn(\n 'overflow-hidden h-(--fd-animated-height) transition-[height]',\n props.className,\n )}\n >\n <div\n className={cn('w-full flex flex-col overflow-y-auto max-h-[460px] p-1', !items && 'hidden')}\n >\n <ListContext\n value={useMemo(\n () => ({\n active,\n setActive,\n }),\n [active],\n )}\n >\n {items?.length === 0 && Empty()}\n\n {items?.map((item) => (\n <Fragment key={item.id}>{Item({ item, onClick: () => onSelect(item) })}</Fragment>\n ))}\n </ListContext>\n </div>\n </div>\n );\n}\n\nexport function SearchDialogListItem({\n item,\n className,\n children,\n renderMarkdown = (s) => <mdRenderer.Markdown components={mdComponents}>{s}</mdRenderer.Markdown>,\n renderHighlights: _,\n ...props\n}: ComponentProps<'button'> & {\n renderMarkdown?: (v: string) => ReactNode;\n /** @deprecated highlight blocks is now wrapped in `<mark />`, use `renderMarkdown` to handle instead. */\n renderHighlights?: (blocks: HighlightedText<ReactNode>[]) => ReactNode;\n item: SearchItemType;\n}) {\n const { active: activeId, setActive } = useSearchList();\n const active = item.id === activeId;\n\n if (item.type === 'action') {\n children ??= item.node;\n } else {\n children ??= (\n <>\n <div className=\"inline-flex items-center text-fd-muted-foreground text-xs empty:hidden\">\n {item.breadcrumbs?.map((item, i) => (\n <Fragment key={i}>\n {i > 0 && <ChevronRight className=\"size-4 rtl:rotate-180\" />}\n {item}\n </Fragment>\n ))}\n </div>\n\n {item.type !== 'page' && (\n <div role=\"none\" className=\"absolute start-3 inset-y-0 w-px bg-fd-border\" />\n )}\n {item.type === 'heading' && (\n <Hash className=\"absolute start-6 top-2.5 size-4 text-fd-muted-foreground\" />\n )}\n <div\n className={cn(\n 'min-w-0',\n item.type === 'text' && 'ps-4',\n item.type === 'heading' && 'ps-8',\n item.type === 'page' || item.type === 'heading'\n ? 'font-medium'\n : 'text-fd-popover-foreground/80',\n )}\n >\n {typeof item.content === 'string' ? renderMarkdown(item.content) : item.content}\n </div>\n </>\n );\n }\n\n return (\n <button\n type=\"button\"\n ref={useCallback(\n (element: HTMLButtonElement | null) => {\n if (active && element) {\n scrollIntoView(element, {\n scrollMode: 'if-needed',\n block: 'nearest',\n boundary: element.parentElement,\n });\n }\n },\n [active],\n )}\n aria-selected={active}\n className={cn(\n 'relative select-none shrink-0 px-2.5 py-2 text-start text-sm overflow-hidden rounded-lg',\n active && 'bg-fd-accent text-fd-accent-foreground',\n className,\n )}\n onPointerMove={() => setActive(item.id)}\n {...props}\n >\n {children}\n </button>\n );\n}\nexport function SearchDialogIcon(props: ComponentProps<'svg'>) {\n const { isLoading } = useSearch();\n\n return (\n <SearchIcon\n {...props}\n className={cn(\n 'size-5 text-fd-muted-foreground',\n isLoading && 'animate-pulse duration-400',\n props.className,\n )}\n />\n );\n}\n\nexport interface TagsListProps extends ComponentProps<'div'> {\n tag?: string;\n onTagChange: (tag: string | undefined) => void;\n allowClear?: boolean;\n}\n\nconst itemVariants = cva(\n 'rounded-md border px-2 py-0.5 text-xs font-medium text-fd-muted-foreground transition-colors',\n {\n variants: {\n active: {\n true: 'bg-fd-accent text-fd-accent-foreground',\n },\n },\n },\n);\nexport function TagsList({ tag, onTagChange, allowClear = false, ...props }: TagsListProps) {\n const onTagChangeCallback = useRef(onTagChange);\n onTagChangeCallback.current = onTagChange;\n return (\n <div {...props} className={cn('flex items-center gap-1 flex-wrap', props.className)}>\n <TagsListContext\n value={useMemo(\n () => ({\n value: tag,\n onValueChange: (v) => onTagChangeCallback.current(v),\n allowClear,\n }),\n [allowClear, tag],\n )}\n >\n {props.children}\n </TagsListContext>\n </div>\n );\n}\n\nexport function TagsListItem({\n value,\n className,\n ...props\n}: ComponentProps<'button'> & {\n value: string;\n}) {\n const { onValueChange, value: selectedValue, allowClear } = useTagsList();\n const selected = value === selectedValue;\n\n return (\n <button\n type=\"button\"\n data-active={selected}\n className={cn(itemVariants({ active: selected, className }))}\n onClick={() => onValueChange(selected && allowClear ? undefined : value)}\n tabIndex={-1}\n {...props}\n >\n {props.children}\n </button>\n );\n}\n\nexport function useSearch() {\n const ctx = use(RootContext);\n if (!ctx) throw new Error('Missing <SearchDialog />');\n return ctx;\n}\n\nexport function useTagsList() {\n const ctx = use(TagsListContext);\n if (!ctx) throw new Error('Missing <TagsList />');\n return ctx;\n}\n\nexport function useSearchList() {\n const ctx = use(ListContext);\n if (!ctx) throw new Error('Missing <SearchDialogList />');\n return ctx;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search.js","names":["SearchIcon"],"sources":["../../../src/components/dialog/search.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronRight, Hash, Search as SearchIcon } from 'lucide-react';\nimport {\n type ComponentProps,\n createContext,\n Fragment,\n type ReactNode,\n use,\n useCallback,\n useEffect,\n useEffectEvent,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { I18nLabel, useI18n } from '@/contexts/i18n';\nimport { cn } from '@/utils/cn';\nimport { Dialog } from '@base-ui/react/dialog';\nimport type { HighlightedText, ReactSortedResult } from 'fumadocs-core/search';\nimport { cva } from 'class-variance-authority';\nimport { useRouter } from 'fumadocs-core/framework';\nimport type { SharedProps } from '@/contexts/search';\nimport { useOnChange } from 'fumadocs-core/utils/use-on-change';\nimport scrollIntoView from 'scroll-into-view-if-needed';\nimport { buttonVariants } from '@/components/ui/button';\nimport { createMarkdownRenderer } from 'fumadocs-core/content/md';\nimport rehypeRaw from 'rehype-raw';\nimport { visit } from 'unist-util-visit';\nimport type { Transformer } from 'unified';\nimport type { Root } from 'hast';\n\nexport type SearchItemType =\n | (ReactSortedResult & {\n external?: boolean;\n })\n | {\n id: string;\n type: 'action';\n node: ReactNode;\n onSelect: () => void;\n };\n\n// needed for backward compatible since some previous guides referenced it\nexport type { SharedProps };\n\nexport interface SearchDialogProps extends SharedProps {\n search: string;\n onSearchChange: (v: string) => void;\n onSelect?: (item: SearchItemType) => void;\n isLoading?: boolean;\n\n children: ReactNode;\n}\n\nconst RootContext = createContext<{\n open: boolean;\n onOpenChange: (open: boolean) => void;\n search: string;\n onSearchChange: (v: string) => void;\n onSelect: (item: SearchItemType) => void;\n isLoading: boolean;\n} | null>(null);\n\nconst ListContext = createContext<{\n active: string | null;\n setActive: (v: string | null) => void;\n} | null>(null);\n\nconst TagsListContext = createContext<{\n value?: string;\n onValueChange: (value: string | undefined) => void;\n allowClear: boolean;\n} | null>(null);\n\nconst PreContext = createContext(false);\n\nconst mdRenderer = createMarkdownRenderer({\n remarkRehypeOptions: {\n allowDangerousHtml: true,\n },\n rehypePlugins: [rehypeRaw, rehypeCustomElements],\n});\n\nconst mdComponents = {\n mark(props: ComponentProps<'mark'>) {\n return <span {...props} className=\"text-fd-primary underline\" />;\n },\n a: 'span',\n p(props: ComponentProps<'p'>) {\n return <p {...props} className=\"min-w-0\" />;\n },\n strong(props: ComponentProps<'strong'>) {\n return <strong {...props} className=\"text-fd-accent-foreground font-medium\" />;\n },\n code(props: ComponentProps<'pre'>) {\n // eslint-disable-next-line react-hooks/rules-of-hooks -- this is a component\n const inPre = use(PreContext);\n if (inPre)\n return (\n <code\n {...props}\n className=\"mask-[linear-gradient(to_bottom,white,white_30px,transparent_80px)]\"\n />\n );\n\n return (\n <code\n {...props}\n className=\"border rounded-md px-px bg-fd-secondary text-fd-secondary-foreground\"\n />\n );\n },\n custom({\n _tagName = 'fragment',\n children,\n ...rest\n }: Record<string, unknown> & { _tagName: string; children: ReactNode }) {\n return (\n <span className=\"inline-flex max-w-full items-center border p-0.5 rounded-md bg-fd-card text-fd-card-foreground divide-x divide-fd-border\">\n <code className=\"rounded-sm px-0.5 me-1 bg-fd-primary font-medium text-xs text-fd-primary-foreground border-none\">\n {_tagName}\n </code>\n {Object.entries(rest).map(([k, v]) => {\n if (typeof v !== 'string') return;\n\n return (\n <code key={k} className=\"truncate text-xs text-fd-muted-foreground px-1\">\n <span className=\"text-fd-card-foreground\">{k}: </span>\n {v}\n </code>\n );\n })}\n {children && <span className=\"ps-1\">{children}</span>}\n </span>\n );\n },\n pre(props: ComponentProps<'pre'>) {\n return (\n <pre\n {...props}\n className={cn(\n 'flex flex-col border rounded-md my-0.5 p-2 bg-fd-secondary text-fd-secondary-foreground max-h-20 overflow-hidden',\n props.className,\n )}\n >\n <PreContext value={true}>{props.children}</PreContext>\n </pre>\n );\n },\n};\n\nfunction rehypeCustomElements(): Transformer<Root, Root> {\n return (tree) => {\n visit(tree, (node) => {\n if (\n node.type === 'element' &&\n document.createElement(node.tagName) instanceof HTMLUnknownElement\n ) {\n node.properties._tagName = node.tagName;\n node.tagName = 'custom';\n }\n });\n };\n}\n\nexport function SearchDialog({\n open,\n onOpenChange,\n search,\n onSearchChange,\n isLoading = false,\n onSelect: onSelectProp,\n children,\n}: SearchDialogProps) {\n const router = useRouter();\n const onOpenChangeCallback = useRef(onOpenChange);\n onOpenChangeCallback.current = onOpenChange;\n const onSearchChangeCallback = useRef(onSearchChange);\n onSearchChangeCallback.current = onSearchChange;\n const onSelect = (item: SearchItemType) => {\n if (item.type === 'action') {\n item.onSelect();\n } else if (item.external) {\n window.open(item.url, '_blank')?.focus();\n } else {\n router.push(item.url);\n }\n\n onOpenChange(false);\n onSelectProp?.(item);\n };\n const onSelectCallback = useRef(onSelect);\n onSelectCallback.current = onSelect;\n\n return (\n <Dialog.Root open={open} onOpenChange={onOpenChange}>\n <RootContext\n value={useMemo(\n () => ({\n open,\n search,\n isLoading,\n onOpenChange: (v) => onOpenChangeCallback.current(v),\n onSearchChange: (v) => onSearchChangeCallback.current(v),\n onSelect: (v) => onSelectCallback.current(v),\n }),\n [isLoading, open, search],\n )}\n >\n {children}\n </RootContext>\n </Dialog.Root>\n );\n}\n\nexport function SearchDialogHeader(props: ComponentProps<'div'>) {\n return <div {...props} className={cn('flex flex-row items-center gap-2 p-3', props.className)} />;\n}\n\nexport function SearchDialogInput(props: ComponentProps<'input'>) {\n const { text } = useI18n();\n const { search, onSearchChange } = useSearch();\n\n return (\n <input\n {...props}\n value={search}\n onChange={(e) => onSearchChange(e.target.value)}\n placeholder={text.search}\n className=\"w-0 flex-1 bg-transparent text-lg placeholder:text-fd-muted-foreground focus-visible:outline-none\"\n />\n );\n}\n\nexport function SearchDialogClose({\n children = 'ESC',\n className,\n ...props\n}: ComponentProps<'button'>) {\n const { onOpenChange } = useSearch();\n\n return (\n <button\n type=\"button\"\n onClick={() => onOpenChange(false)}\n className={cn(\n buttonVariants({\n color: 'outline',\n size: 'sm',\n className: 'font-mono text-fd-muted-foreground',\n }),\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport function SearchDialogFooter(props: ComponentProps<'div'>) {\n return <div {...props} className={cn('bg-fd-secondary/50 p-3 empty:hidden', props.className)} />;\n}\n\nexport function SearchDialogOverlay({\n className,\n ...props\n}: ComponentProps<typeof Dialog.Backdrop>) {\n return (\n <Dialog.Backdrop\n {...props}\n className={(s) =>\n cn(\n 'fixed inset-0 z-50 backdrop-blur-xs bg-fd-overlay data-open:animate-fd-fade-in data-closed:animate-fd-fade-out',\n typeof className === 'function' ? className(s) : className,\n )\n }\n />\n );\n}\n\nexport function SearchDialogContent({\n children,\n className,\n ...props\n}: ComponentProps<typeof Dialog.Popup>) {\n const { text } = useI18n();\n\n return (\n <Dialog.Portal>\n <Dialog.Popup\n id=\"fd-search-dialog-content\"\n aria-describedby={undefined}\n {...props}\n className={(s) =>\n cn(\n '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 overflow-hidden data-closed:animate-fd-dialog-out data-open:animate-fd-dialog-in focus-visible:outline-none',\n '*:border-b *:has-[+:last-child[data-empty=true]]:border-b-0 *:data-[empty=true]:border-b-0 *:last:border-b-0',\n typeof className === 'function' ? className(s) : className,\n )\n }\n >\n <Dialog.Title className=\"hidden\">{text.search}</Dialog.Title>\n {children}\n </Dialog.Popup>\n </Dialog.Portal>\n );\n}\n\nexport function SearchDialogList({\n items = null,\n Empty = () => (\n <div className=\"py-12 text-center text-sm text-fd-muted-foreground\">\n <I18nLabel label=\"searchNoResult\" />\n </div>\n ),\n Item = (props) => <SearchDialogListItem {...props} />,\n ...props\n}: Omit<ComponentProps<'div'>, 'children'> & {\n items: SearchItemType[] | null | undefined;\n /**\n * Renderer for empty list UI\n */\n Empty?: () => ReactNode;\n /**\n * Renderer for items\n */\n Item?: (props: { item: SearchItemType; onClick: () => void }) => ReactNode;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const { onSelect } = useSearch();\n const [active, setActive] = useState<string | null>(() =>\n items && items.length > 0 ? items[0].id : null,\n );\n\n const onKey = useEffectEvent((e: KeyboardEvent) => {\n if (!items || e.isComposing) return;\n\n if (e.key === 'ArrowDown' || e.key == 'ArrowUp') {\n let idx = items.findIndex((item) => item.id === active);\n if (idx === -1) idx = 0;\n else if (e.key === 'ArrowDown') idx++;\n else idx--;\n\n setActive(items.at(idx % items.length)?.id ?? null);\n e.preventDefault();\n }\n\n if (e.key === 'Enter') {\n const selected = items.find((item) => item.id === active);\n\n if (selected) onSelect(selected);\n e.preventDefault();\n }\n });\n\n useEffect(() => {\n const element = ref.current;\n if (!element) return;\n\n const observer = new ResizeObserver(() => {\n const viewport = element.firstElementChild!;\n\n element.style.setProperty('--fd-animated-height', `${viewport.clientHeight}px`);\n });\n\n const viewport = element.firstElementChild;\n if (viewport) observer.observe(viewport);\n\n const content: Pick<Window, 'addEventListener' | 'removeEventListener'> =\n document.getElementById('fd-search-dialog-content') ?? window;\n content.addEventListener('keydown', onKey);\n return () => {\n observer.disconnect();\n content.removeEventListener('keydown', onKey);\n };\n }, []);\n\n useOnChange(items, () => {\n if (items && items.length > 0) {\n setActive(items[0].id);\n }\n });\n\n return (\n <div\n {...props}\n ref={ref}\n data-empty={items === null}\n className={cn(\n 'overflow-hidden h-(--fd-animated-height) transition-[height]',\n props.className,\n )}\n >\n <div\n className={cn('w-full flex flex-col overflow-y-auto max-h-[460px] p-1', !items && 'hidden')}\n >\n <ListContext\n value={useMemo(\n () => ({\n active,\n setActive,\n }),\n [active],\n )}\n >\n {items?.length === 0 && Empty()}\n\n {items?.map((item) => (\n <Fragment key={item.id}>{Item({ item, onClick: () => onSelect(item) })}</Fragment>\n ))}\n </ListContext>\n </div>\n </div>\n );\n}\n\nexport function SearchDialogListItem({\n item,\n className,\n children,\n renderMarkdown = (s) => <mdRenderer.Markdown components={mdComponents}>{s}</mdRenderer.Markdown>,\n renderHighlights: _,\n ...props\n}: ComponentProps<'button'> & {\n renderMarkdown?: (v: string) => ReactNode;\n /** @deprecated highlight blocks is now wrapped in `<mark />`, use `renderMarkdown` to handle instead. */\n renderHighlights?: (blocks: HighlightedText<ReactNode>[]) => ReactNode;\n item: SearchItemType;\n}) {\n const { active: activeId, setActive } = useSearchList();\n const active = item.id === activeId;\n\n if (item.type === 'action') {\n children ??= item.node;\n } else {\n children ??= (\n <>\n <div className=\"inline-flex items-center text-fd-muted-foreground text-xs empty:hidden\">\n {item.breadcrumbs?.map((item, i) => (\n <Fragment key={i}>\n {i > 0 && <ChevronRight className=\"size-4 rtl:rotate-180\" />}\n {item}\n </Fragment>\n ))}\n </div>\n\n {item.type !== 'page' && (\n <div role=\"none\" className=\"absolute start-3 inset-y-0 w-px bg-fd-border\" />\n )}\n {item.type === 'heading' && (\n <Hash className=\"absolute start-6 top-2.5 size-4 text-fd-muted-foreground\" />\n )}\n <div\n className={cn(\n 'min-w-0',\n item.type === 'text' && 'ps-4',\n item.type === 'heading' && 'ps-8',\n item.type === 'page' || item.type === 'heading'\n ? 'font-medium'\n : 'text-fd-popover-foreground/80',\n )}\n >\n {typeof item.content === 'string' ? renderMarkdown(item.content) : item.content}\n </div>\n </>\n );\n }\n\n return (\n <button\n type=\"button\"\n ref={useCallback(\n (element: HTMLButtonElement | null) => {\n if (active && element) {\n scrollIntoView(element, {\n scrollMode: 'if-needed',\n block: 'nearest',\n boundary: element.parentElement,\n });\n }\n },\n [active],\n )}\n aria-selected={active}\n className={cn(\n 'relative select-none shrink-0 px-2.5 py-2 text-start text-sm overflow-hidden rounded-lg',\n active && 'bg-fd-accent text-fd-accent-foreground',\n className,\n )}\n onPointerMove={() => setActive(item.id)}\n {...props}\n >\n {children}\n </button>\n );\n}\nexport function SearchDialogIcon(props: ComponentProps<'svg'>) {\n const { isLoading } = useSearch();\n\n return (\n <SearchIcon\n {...props}\n className={cn(\n 'size-5 text-fd-muted-foreground',\n isLoading && 'animate-pulse duration-400',\n props.className,\n )}\n />\n );\n}\n\nexport interface TagsListProps extends ComponentProps<'div'> {\n tag?: string;\n onTagChange: (tag: string | undefined) => void;\n allowClear?: boolean;\n}\n\nconst itemVariants = cva(\n 'rounded-md border px-2 py-0.5 text-xs font-medium text-fd-muted-foreground transition-colors',\n {\n variants: {\n active: {\n true: 'bg-fd-accent text-fd-accent-foreground',\n },\n },\n },\n);\nexport function TagsList({ tag, onTagChange, allowClear = false, ...props }: TagsListProps) {\n const onTagChangeCallback = useRef(onTagChange);\n onTagChangeCallback.current = onTagChange;\n return (\n <div {...props} className={cn('flex items-center gap-1 flex-wrap', props.className)}>\n <TagsListContext\n value={useMemo(\n () => ({\n value: tag,\n onValueChange: (v) => onTagChangeCallback.current(v),\n allowClear,\n }),\n [allowClear, tag],\n )}\n >\n {props.children}\n </TagsListContext>\n </div>\n );\n}\n\nexport function TagsListItem({\n value,\n className,\n ...props\n}: ComponentProps<'button'> & {\n value: string;\n}) {\n const { onValueChange, value: selectedValue, allowClear } = useTagsList();\n const selected = value === selectedValue;\n\n return (\n <button\n type=\"button\"\n data-active={selected}\n className={cn(itemVariants({ active: selected, className }))}\n onClick={() => onValueChange(selected && allowClear ? undefined : value)}\n tabIndex={-1}\n {...props}\n >\n {props.children}\n </button>\n );\n}\n\nexport function useSearch() {\n const ctx = use(RootContext);\n if (!ctx) throw new Error('Missing <SearchDialog />');\n return ctx;\n}\n\nexport function useTagsList() {\n const ctx = use(TagsListContext);\n if (!ctx) throw new Error('Missing <TagsList />');\n return ctx;\n}\n\nexport function useSearchList() {\n const ctx = use(ListContext);\n if (!ctx) throw new Error('Missing <SearchDialogList />');\n return ctx;\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReactNode } from "react";
|
|
1
|
+
import { ComponentProps, ReactNode } from "react";
|
|
2
2
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/type-table.d.ts
|
|
@@ -30,10 +30,13 @@ interface TypeNode {
|
|
|
30
30
|
returns?: ReactNode;
|
|
31
31
|
}
|
|
32
32
|
declare function TypeTable({
|
|
33
|
-
|
|
33
|
+
id,
|
|
34
|
+
type,
|
|
35
|
+
className,
|
|
36
|
+
...props
|
|
34
37
|
}: {
|
|
35
38
|
type: Record<string, TypeNode>;
|
|
36
|
-
}): react_jsx_runtime0.JSX.Element;
|
|
39
|
+
} & ComponentProps<'div'>): react_jsx_runtime0.JSX.Element;
|
|
37
40
|
//#endregion
|
|
38
41
|
export { ParameterNode, TypeNode, TypeTable };
|
|
39
42
|
//# sourceMappingURL=type-table.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-table.d.ts","names":[],"sources":["../../src/components/type-table.tsx"],"mappings":";;;;UASiB,aAAA;EACf,IAAA;EACA,WAAA,EAAa,SAAA;AAAA;AAAA,UAGE,QAAA;;;;EAIf,WAAA,GAAc,SAAA;EAPD;;;EAYb,IAAA,EAAM,SAAA;EATiB;;;EAcvB,eAAA,GAAkB,SAAA;EAAA;;;EAKlB,mBAAA;EAEA,OAAA,GAAU,SAAA;EAEV,QAAA;EACA,UAAA;EAEA,UAAA,GAAa,aAAA;EAEb,OAAA,GAAU,SAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"type-table.d.ts","names":[],"sources":["../../src/components/type-table.tsx"],"mappings":";;;;UASiB,aAAA;EACf,IAAA;EACA,WAAA,EAAa,SAAA;AAAA;AAAA,UAGE,QAAA;;;;EAIf,WAAA,GAAc,SAAA;EAPD;;;EAYb,IAAA,EAAM,SAAA;EATiB;;;EAcvB,eAAA,GAAkB,SAAA;EAAA;;;EAKlB,mBAAA;EAEA,OAAA,GAAU,SAAA;EAEV,QAAA;EACA,UAAA;EAEA,UAAA,GAAa,aAAA;EAEb,OAAA,GAAU,SAAA;AAAA;AAAA,iBAKI,SAAA,CAAA;EACd,EAAA;EACA,IAAA;EACA,SAAA;EAAA,GACG;AAAA;EACA,IAAA,EAAM,MAAA,SAAe,QAAA;AAAA,IAAc,cAAA,UAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -2,47 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
import { cn } from "../utils/cn.js";
|
|
4
4
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "./ui/collapsible.js";
|
|
5
|
-
import { useState } from "react";
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
6
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import Link from "fumadocs-core/link";
|
|
8
8
|
import { ChevronDown } from "lucide-react";
|
|
9
9
|
import { cva } from "class-variance-authority";
|
|
10
10
|
|
|
11
11
|
//#region src/components/type-table.tsx
|
|
12
|
-
const keyVariants = cva("text-fd-primary", { variants: { deprecated: { true: "line-through text-fd-primary/50" } } });
|
|
13
12
|
const fieldVariants = cva("text-fd-muted-foreground not-prose pe-2");
|
|
14
|
-
function TypeTable({ type }) {
|
|
13
|
+
function TypeTable({ id, type, className, ...props }) {
|
|
15
14
|
return /* @__PURE__ */ jsxs("div", {
|
|
16
|
-
|
|
15
|
+
id,
|
|
16
|
+
className: cn("@container flex flex-col p-1 bg-fd-card text-fd-card-foreground rounded-2xl border my-6 text-sm overflow-hidden", className),
|
|
17
|
+
...props,
|
|
17
18
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
18
19
|
className: "flex font-medium items-center px-3 py-1 not-prose text-fd-muted-foreground",
|
|
19
20
|
children: [/* @__PURE__ */ jsx("p", {
|
|
20
|
-
className: "w-
|
|
21
|
+
className: "w-1/4",
|
|
21
22
|
children: "Prop"
|
|
22
23
|
}), /* @__PURE__ */ jsx("p", {
|
|
23
24
|
className: "@max-xl:hidden",
|
|
24
25
|
children: "Type"
|
|
25
26
|
})]
|
|
26
27
|
}), Object.entries(type).map(([key, value]) => /* @__PURE__ */ jsx(Item, {
|
|
28
|
+
parentId: id,
|
|
27
29
|
name: key,
|
|
28
30
|
item: value
|
|
29
31
|
}, key))]
|
|
30
32
|
});
|
|
31
33
|
}
|
|
32
|
-
function Item({ name, item: { parameters = [], description, required = false, deprecated, typeDescription, default: defaultValue, type, typeDescriptionLink, returns } }) {
|
|
34
|
+
function Item({ parentId, name, item: { parameters = [], description, required = false, deprecated, typeDescription, default: defaultValue, type, typeDescriptionLink, returns } }) {
|
|
33
35
|
const [open, setOpen] = useState(false);
|
|
36
|
+
const id = parentId ? `${parentId}-${name}` : void 0;
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const hash = window.location.hash;
|
|
39
|
+
if (!id || !hash) return;
|
|
40
|
+
if (`#${id}` === hash) setOpen(true);
|
|
41
|
+
}, [id]);
|
|
34
42
|
return /* @__PURE__ */ jsxs(Collapsible, {
|
|
43
|
+
id,
|
|
35
44
|
open,
|
|
36
|
-
onOpenChange:
|
|
37
|
-
|
|
45
|
+
onOpenChange: (v) => {
|
|
46
|
+
if (v && id) window.history.replaceState(null, "", `#${id}`);
|
|
47
|
+
setOpen(v);
|
|
48
|
+
},
|
|
49
|
+
className: cn("rounded-xl border overflow-hidden scroll-m-20 transition-all", open ? "shadow-sm bg-fd-background not-last:mb-2" : "border-transparent"),
|
|
38
50
|
children: [/* @__PURE__ */ jsxs(CollapsibleTrigger, {
|
|
39
51
|
className: "relative flex flex-row items-center w-full group text-start px-3 py-2 not-prose hover:bg-fd-accent",
|
|
40
52
|
children: [
|
|
41
53
|
/* @__PURE__ */ jsxs("code", {
|
|
42
|
-
className: cn(
|
|
43
|
-
deprecated,
|
|
44
|
-
className: "min-w-fit w-[25%] font-medium pe-2"
|
|
45
|
-
})),
|
|
54
|
+
className: cn("text-fd-primary min-w-fit w-1/4 font-mono font-medium pe-2", deprecated && "line-through text-fd-primary/50"),
|
|
46
55
|
children: [name, !required && "?"]
|
|
47
56
|
}),
|
|
48
57
|
typeDescriptionLink ? /* @__PURE__ */ jsx(Link, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-table.js","names":[],"sources":["../../src/components/type-table.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronDown } from 'lucide-react';\nimport Link from 'fumadocs-core/link';\nimport { cva } from 'class-variance-authority';\nimport { cn } from '@/utils/cn';\nimport { type ReactNode, useState } from 'react';\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';\n\nexport interface ParameterNode {\n name: string;\n description: ReactNode;\n}\n\nexport interface TypeNode {\n /**\n * Additional description of the field\n */\n description?: ReactNode;\n\n /**\n * type signature (short)\n */\n type: ReactNode;\n\n /**\n * type signature (full)\n */\n typeDescription?: ReactNode;\n\n /**\n * Optional `href` for the type\n */\n typeDescriptionLink?: string;\n\n default?: ReactNode;\n\n required?: boolean;\n deprecated?: boolean;\n\n parameters?: ParameterNode[];\n\n returns?: ReactNode;\n}\n\nconst
|
|
1
|
+
{"version":3,"file":"type-table.js","names":[],"sources":["../../src/components/type-table.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronDown } from 'lucide-react';\nimport Link from 'fumadocs-core/link';\nimport { cva } from 'class-variance-authority';\nimport { cn } from '@/utils/cn';\nimport { type ComponentProps, type ReactNode, useEffect, useState } from 'react';\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';\n\nexport interface ParameterNode {\n name: string;\n description: ReactNode;\n}\n\nexport interface TypeNode {\n /**\n * Additional description of the field\n */\n description?: ReactNode;\n\n /**\n * type signature (short)\n */\n type: ReactNode;\n\n /**\n * type signature (full)\n */\n typeDescription?: ReactNode;\n\n /**\n * Optional `href` for the type\n */\n typeDescriptionLink?: string;\n\n default?: ReactNode;\n\n required?: boolean;\n deprecated?: boolean;\n\n parameters?: ParameterNode[];\n\n returns?: ReactNode;\n}\n\nconst fieldVariants = cva('text-fd-muted-foreground not-prose pe-2');\n\nexport function TypeTable({\n id,\n type,\n className,\n ...props\n}: { type: Record<string, TypeNode> } & ComponentProps<'div'>) {\n return (\n <div\n id={id}\n className={cn(\n '@container flex flex-col p-1 bg-fd-card text-fd-card-foreground rounded-2xl border my-6 text-sm overflow-hidden',\n className,\n )}\n {...props}\n >\n <div className=\"flex font-medium items-center px-3 py-1 not-prose text-fd-muted-foreground\">\n <p className=\"w-1/4\">Prop</p>\n <p className=\"@max-xl:hidden\">Type</p>\n </div>\n {Object.entries(type).map(([key, value]) => (\n <Item key={key} parentId={id} name={key} item={value} />\n ))}\n </div>\n );\n}\n\nfunction Item({\n parentId,\n name,\n item: {\n parameters = [],\n description,\n required = false,\n deprecated,\n typeDescription,\n default: defaultValue,\n type,\n typeDescriptionLink,\n returns,\n },\n}: {\n parentId?: string;\n name: string;\n item: TypeNode;\n}) {\n const [open, setOpen] = useState(false);\n const id = parentId ? `${parentId}-${name}` : undefined;\n\n useEffect(() => {\n const hash = window.location.hash;\n if (!id || !hash) return;\n if (`#${id}` === hash) setOpen(true);\n }, [id]);\n\n return (\n <Collapsible\n id={id}\n open={open}\n onOpenChange={(v) => {\n if (v && id) {\n window.history.replaceState(null, '', `#${id}`);\n }\n setOpen(v);\n }}\n className={cn(\n 'rounded-xl border overflow-hidden scroll-m-20 transition-all',\n open ? 'shadow-sm bg-fd-background not-last:mb-2' : 'border-transparent',\n )}\n >\n <CollapsibleTrigger className=\"relative flex flex-row items-center w-full group text-start px-3 py-2 not-prose hover:bg-fd-accent\">\n <code\n className={cn(\n 'text-fd-primary min-w-fit w-1/4 font-mono font-medium pe-2',\n deprecated && 'line-through text-fd-primary/50',\n )}\n >\n {name}\n {!required && '?'}\n </code>\n {typeDescriptionLink ? (\n <Link href={typeDescriptionLink} className=\"underline @max-xl:hidden\">\n {type}\n </Link>\n ) : (\n <span className=\"@max-xl:hidden\">{type}</span>\n )}\n <ChevronDown className=\"absolute end-2 size-4 text-fd-muted-foreground transition-transform group-data-[open]:rotate-180\" />\n </CollapsibleTrigger>\n <CollapsibleContent>\n <div className=\"grid grid-cols-[1fr_3fr] gap-y-4 text-sm p-3 overflow-auto fd-scroll-container border-t\">\n <div className=\"text-sm prose col-span-full prose-no-margin empty:hidden\">\n {description}\n </div>\n {typeDescription && (\n <>\n <p className={cn(fieldVariants())}>Type</p>\n <p className=\"my-auto not-prose\">{typeDescription}</p>\n </>\n )}\n {defaultValue && (\n <>\n <p className={cn(fieldVariants())}>Default</p>\n <p className=\"my-auto not-prose\">{defaultValue}</p>\n </>\n )}\n {parameters.length > 0 && (\n <>\n <p className={cn(fieldVariants())}>Parameters</p>\n <div className=\"flex flex-col gap-2\">\n {parameters.map((param) => (\n <div key={param.name} className=\"inline-flex items-center flex-wrap gap-1\">\n <p className=\"font-medium not-prose text-nowrap\">{param.name} -</p>\n <div className=\"text-sm prose prose-no-margin\">{param.description}</div>\n </div>\n ))}\n </div>\n </>\n )}\n {returns && (\n <>\n <p className={cn(fieldVariants())}>Returns</p>\n <div className=\"my-auto text-sm prose prose-no-margin\">{returns}</div>\n </>\n )}\n </div>\n </CollapsibleContent>\n </Collapsible>\n );\n}\n"],"mappings":";;;;;;;;;;;AA6CA,MAAM,gBAAgB,IAAI,0CAA0C;AAEpE,SAAgB,UAAU,EACxB,IACA,MACA,WACA,GAAG,SAC0D;AAC7D,QACE,qBAAC;EACK;EACJ,WAAW,GACT,mHACA,UACD;EACD,GAAI;aAEJ,qBAAC;GAAI,WAAU;cACb,oBAAC;IAAE,WAAU;cAAQ;KAAQ,EAC7B,oBAAC;IAAE,WAAU;cAAiB;KAAQ;IAClC,EACL,OAAO,QAAQ,KAAK,CAAC,KAAK,CAAC,KAAK,WAC/B,oBAAC;GAAe,UAAU;GAAI,MAAM;GAAK,MAAM;KAApC,IAA6C,CACxD;GACE;;AAIV,SAAS,KAAK,EACZ,UACA,MACA,MAAM,EACJ,aAAa,EAAE,EACf,aACA,WAAW,OACX,YACA,iBACA,SAAS,cACT,MACA,qBACA,aAMD;CACD,MAAM,CAAC,MAAM,WAAW,SAAS,MAAM;CACvC,MAAM,KAAK,WAAW,GAAG,SAAS,GAAG,SAAS;AAE9C,iBAAgB;EACd,MAAM,OAAO,OAAO,SAAS;AAC7B,MAAI,CAAC,MAAM,CAAC,KAAM;AAClB,MAAI,IAAI,SAAS,KAAM,SAAQ,KAAK;IACnC,CAAC,GAAG,CAAC;AAER,QACE,qBAAC;EACK;EACE;EACN,eAAe,MAAM;AACnB,OAAI,KAAK,GACP,QAAO,QAAQ,aAAa,MAAM,IAAI,IAAI,KAAK;AAEjD,WAAQ,EAAE;;EAEZ,WAAW,GACT,gEACA,OAAO,6CAA6C,qBACrD;aAED,qBAAC;GAAmB,WAAU;;IAC5B,qBAAC;KACC,WAAW,GACT,8DACA,cAAc,kCACf;gBAEA,MACA,CAAC,YAAY;MACT;IACN,sBACC,oBAAC;KAAK,MAAM;KAAqB,WAAU;eACxC;MACI,GAEP,oBAAC;KAAK,WAAU;eAAkB;MAAY;IAEhD,oBAAC,eAAY,WAAU,qGAAqG;;IACzG,EACrB,oBAAC,gCACC,qBAAC;GAAI,WAAU;;IACb,oBAAC;KAAI,WAAU;eACZ;MACG;IACL,mBACC,8CACE,oBAAC;KAAE,WAAW,GAAG,eAAe,CAAC;eAAE;MAAQ,EAC3C,oBAAC;KAAE,WAAU;eAAqB;MAAoB,IACrD;IAEJ,gBACC,8CACE,oBAAC;KAAE,WAAW,GAAG,eAAe,CAAC;eAAE;MAAW,EAC9C,oBAAC;KAAE,WAAU;eAAqB;MAAiB,IAClD;IAEJ,WAAW,SAAS,KACnB,8CACE,oBAAC;KAAE,WAAW,GAAG,eAAe,CAAC;eAAE;MAAc,EACjD,oBAAC;KAAI,WAAU;eACZ,WAAW,KAAK,UACf,qBAAC;MAAqB,WAAU;iBAC9B,qBAAC;OAAE,WAAU;kBAAqC,MAAM,MAAK;QAAM,EACnE,oBAAC;OAAI,WAAU;iBAAiC,MAAM;QAAkB;QAFhE,MAAM,KAGV,CACN;MACE,IACL;IAEJ,WACC,8CACE,oBAAC;KAAE,WAAW,GAAG,eAAe,CAAC;eAAE;MAAW,EAC9C,oBAAC;KAAI,WAAU;eAAyC;MAAc,IACrE;;IAED,GACa;GACT"}
|
|
@@ -6,8 +6,8 @@ import * as _base_ui_react0 from "@base-ui/react";
|
|
|
6
6
|
type NavigationMenuContentProps = NavigationMenu.Content.Props;
|
|
7
7
|
type NavigationMenuTriggerProps = NavigationMenu.Trigger.Props;
|
|
8
8
|
declare const NavigationMenuRoot: React.ForwardRefExoticComponent<Omit<_base_ui_react0.NavigationMenuRootProps, "ref"> & React.RefAttributes<HTMLElement>>;
|
|
9
|
-
declare const NavigationMenuList: React.ForwardRefExoticComponent<Omit<_base_ui_react0.NavigationMenuListProps, "ref"> & React.RefAttributes<
|
|
10
|
-
declare const NavigationMenuItem: React.ForwardRefExoticComponent<Omit<Omit<_base_ui_react0.NavigationMenuItemProps, "ref"> & React.RefAttributes<
|
|
9
|
+
declare const NavigationMenuList: React.ForwardRefExoticComponent<Omit<_base_ui_react0.NavigationMenuListProps, "ref"> & React.RefAttributes<HTMLUListElement>>;
|
|
10
|
+
declare const NavigationMenuItem: React.ForwardRefExoticComponent<Omit<Omit<_base_ui_react0.NavigationMenuItemProps, "ref"> & React.RefAttributes<HTMLLIElement>, "ref"> & React.RefAttributes<HTMLLIElement>>;
|
|
11
11
|
declare const NavigationMenuTrigger: React.ForwardRefExoticComponent<Omit<Omit<_base_ui_react0.NavigationMenuTriggerProps, "ref"> & React.RefAttributes<HTMLButtonElement>, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
12
12
|
declare const NavigationMenuContent: React.ForwardRefExoticComponent<Omit<Omit<_base_ui_react0.NavigationMenuContentProps, "ref"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
13
13
|
declare const NavigationMenuLink: React.ForwardRefExoticComponent<Omit<_base_ui_react0.NavigationMenuLinkProps, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-menu.d.ts","names":[],"sources":["../../../src/components/ui/navigation-menu.tsx"],"mappings":";;;;;KAKY,0BAAA,GAA6B,cAAA,CAAU,OAAA,CAAQ,KAAA;AAAA,KAC/C,0BAAA,GAA6B,cAAA,CAAU,OAAA,CAAQ,KAAA;AAAA,cAErD,kBAAA,EAAkB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAiB,eAAA,CAAjB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,WAAA;AAAA,cAElB,kBAAA,EAAkB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAiB,eAAA,CAAjB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,
|
|
1
|
+
{"version":3,"file":"navigation-menu.d.ts","names":[],"sources":["../../../src/components/ui/navigation-menu.tsx"],"mappings":";;;;;KAKY,0BAAA,GAA6B,cAAA,CAAU,OAAA,CAAQ,KAAA;AAAA,KAC/C,0BAAA,GAA6B,cAAA,CAAU,OAAA,CAAQ,KAAA;AAAA,cAErD,kBAAA,EAAkB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAiB,eAAA,CAAjB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,WAAA;AAAA,cAElB,kBAAA,EAAkB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAiB,eAAA,CAAjB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,gBAAA;AAAA,cAElB,kBAAA,EAAkB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,IAAA,CAWtB,eAAA,CAXsB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,aAAA,YAAA,KAAA,CAAA,aAAA,CAAA,aAAA;AAAA,cAelB,qBAAA,EAAqB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,IAAA,CAOzB,eAAA,CAPyB,0BAAA,WAAA,KAAA,CAAA,aAAA,CAAA,iBAAA,YAAA,KAAA,CAAA,aAAA,CAAA,iBAAA;AAAA,cAUrB,qBAAA,EAAqB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,IAAA,CAoBzB,eAAA,CApByB,0BAAA,WAAA,KAAA,CAAA,aAAA,CAAA,cAAA,YAAA,KAAA,CAAA,aAAA,CAAA,cAAA;AAAA,cAuBrB,kBAAA,EAAkB,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAiB,eAAA,CAAjB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,iBAAA"}
|
|
@@ -5,7 +5,7 @@ import { LinkProps } from "fumadocs-core/link";
|
|
|
5
5
|
import * as _base_ui_react0 from "@base-ui/react";
|
|
6
6
|
|
|
7
7
|
//#region src/layouts/home/navbar.d.ts
|
|
8
|
-
declare const NavbarMenu: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react0.NavigationMenuItemProps, "ref"> & react.RefAttributes<
|
|
8
|
+
declare const NavbarMenu: react.ForwardRefExoticComponent<Omit<Omit<_base_ui_react0.NavigationMenuItemProps, "ref"> & react.RefAttributes<HTMLLIElement>, "ref"> & react.RefAttributes<HTMLLIElement>>;
|
|
9
9
|
declare function NavbarMenuContent({
|
|
10
10
|
className,
|
|
11
11
|
...props
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar.d.ts","names":[],"sources":["../../../src/layouts/home/navbar.tsx"],"mappings":";;;;;;;cAaa,UAAA,EAAU,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,IAAA,CAAqB,eAAA,CAArB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,
|
|
1
|
+
{"version":3,"file":"navbar.d.ts","names":[],"sources":["../../../src/layouts/home/navbar.tsx"],"mappings":";;;;;;;cAaa,UAAA,EAAU,KAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,IAAA,CAAqB,eAAA,CAArB,uBAAA,WAAA,KAAA,CAAA,aAAA,CAAA,aAAA,YAAA,KAAA,CAAA,aAAA,CAAA,aAAA;AAAA,iBAEP,iBAAA,CAAA;EAAoB,SAAA;EAAA,GAAc;AAAA,GAAS,0BAAA,GAA0B,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAgBrE,iBAAA,CAAA;EAAoB,SAAA;EAAA,GAAc;AAAA,GAAS,0BAAA,GAA0B,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,iBAiBrE,cAAA,CAAe,KAAA,EAAO,SAAA,GAAS,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -33,7 +33,7 @@ function LargeSearchToggle({ hideIfDisabled, ...props }) {
|
|
|
33
33
|
type: "button",
|
|
34
34
|
"data-search-full": "",
|
|
35
35
|
...props,
|
|
36
|
-
className: cn("inline-flex items-center gap-2 rounded-lg border bg-fd-secondary/50 p-1.5 ps-2 text-sm text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground", props.className),
|
|
36
|
+
className: cn("inline-flex items-center gap-2 rounded-lg border bg-fd-secondary/50 p-1.5 ps-2 text-sm text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring", props.className),
|
|
37
37
|
onClick: () => {
|
|
38
38
|
setOpenSearch(true);
|
|
39
39
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-toggle.js","names":[],"sources":["../../../src/layouts/shared/search-toggle.tsx"],"sourcesContent":["'use client';\nimport type { ComponentProps } from 'react';\nimport { Search } from 'lucide-react';\nimport { useSearchContext } from '@/contexts/search';\nimport { useI18n } from '@/contexts/i18n';\nimport { cn } from '@/utils/cn';\nimport { type ButtonProps, buttonVariants } from '@/components/ui/button';\n\ninterface SearchToggleProps extends Omit<ComponentProps<'button'>, 'color'>, ButtonProps {\n hideIfDisabled?: boolean;\n}\n\nexport function SearchToggle({\n hideIfDisabled,\n size = 'icon-sm',\n color = 'ghost',\n ...props\n}: SearchToggleProps) {\n const { setOpenSearch, enabled } = useSearchContext();\n if (hideIfDisabled && !enabled) return null;\n\n return (\n <button\n type=\"button\"\n className={cn(\n buttonVariants({\n size,\n color,\n }),\n props.className,\n )}\n data-search=\"\"\n aria-label=\"Open Search\"\n onClick={() => {\n setOpenSearch(true);\n }}\n >\n <Search />\n </button>\n );\n}\n\nexport function LargeSearchToggle({\n hideIfDisabled,\n ...props\n}: ComponentProps<'button'> & {\n hideIfDisabled?: boolean;\n}) {\n const { enabled, hotKey, setOpenSearch } = useSearchContext();\n const { text } = useI18n();\n if (hideIfDisabled && !enabled) return null;\n\n return (\n <button\n type=\"button\"\n data-search-full=\"\"\n {...props}\n className={cn(\n 'inline-flex items-center gap-2 rounded-lg border bg-fd-secondary/50 p-1.5 ps-2 text-sm text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground',\n props.className,\n )}\n onClick={() => {\n setOpenSearch(true);\n }}\n >\n <Search className=\"size-4\" />\n {text.search}\n <div className=\"ms-auto inline-flex gap-0.5\">\n {hotKey.map((k, i) => (\n <kbd key={i} className=\"rounded-md border bg-fd-background px-1.5\">\n {k.display}\n </kbd>\n ))}\n </div>\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,aAAa,EAC3B,gBACA,OAAO,WACP,QAAQ,SACR,GAAG,SACiB;CACpB,MAAM,EAAE,eAAe,YAAY,kBAAkB;AACrD,KAAI,kBAAkB,CAAC,QAAS,QAAO;AAEvC,QACE,oBAAC;EACC,MAAK;EACL,WAAW,GACT,eAAe;GACb;GACA;GACD,CAAC,EACF,MAAM,UACP;EACD,eAAY;EACZ,cAAW;EACX,eAAe;AACb,iBAAc,KAAK;;YAGrB,oBAAC,WAAS;GACH;;AAIb,SAAgB,kBAAkB,EAChC,gBACA,GAAG,SAGF;CACD,MAAM,EAAE,SAAS,QAAQ,kBAAkB,kBAAkB;CAC7D,MAAM,EAAE,SAAS,SAAS;AAC1B,KAAI,kBAAkB,CAAC,QAAS,QAAO;AAEvC,QACE,qBAAC;EACC,MAAK;EACL,oBAAiB;EACjB,GAAI;EACJ,WAAW,GACT,
|
|
1
|
+
{"version":3,"file":"search-toggle.js","names":[],"sources":["../../../src/layouts/shared/search-toggle.tsx"],"sourcesContent":["'use client';\nimport type { ComponentProps } from 'react';\nimport { Search } from 'lucide-react';\nimport { useSearchContext } from '@/contexts/search';\nimport { useI18n } from '@/contexts/i18n';\nimport { cn } from '@/utils/cn';\nimport { type ButtonProps, buttonVariants } from '@/components/ui/button';\n\ninterface SearchToggleProps extends Omit<ComponentProps<'button'>, 'color'>, ButtonProps {\n hideIfDisabled?: boolean;\n}\n\nexport function SearchToggle({\n hideIfDisabled,\n size = 'icon-sm',\n color = 'ghost',\n ...props\n}: SearchToggleProps) {\n const { setOpenSearch, enabled } = useSearchContext();\n if (hideIfDisabled && !enabled) return null;\n\n return (\n <button\n type=\"button\"\n className={cn(\n buttonVariants({\n size,\n color,\n }),\n props.className,\n )}\n data-search=\"\"\n aria-label=\"Open Search\"\n onClick={() => {\n setOpenSearch(true);\n }}\n >\n <Search />\n </button>\n );\n}\n\nexport function LargeSearchToggle({\n hideIfDisabled,\n ...props\n}: ComponentProps<'button'> & {\n hideIfDisabled?: boolean;\n}) {\n const { enabled, hotKey, setOpenSearch } = useSearchContext();\n const { text } = useI18n();\n if (hideIfDisabled && !enabled) return null;\n\n return (\n <button\n type=\"button\"\n data-search-full=\"\"\n {...props}\n className={cn(\n 'inline-flex items-center gap-2 rounded-lg border bg-fd-secondary/50 p-1.5 ps-2 text-sm text-fd-muted-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring',\n props.className,\n )}\n onClick={() => {\n setOpenSearch(true);\n }}\n >\n <Search className=\"size-4\" />\n {text.search}\n <div className=\"ms-auto inline-flex gap-0.5\">\n {hotKey.map((k, i) => (\n <kbd key={i} className=\"rounded-md border bg-fd-background px-1.5\">\n {k.display}\n </kbd>\n ))}\n </div>\n </button>\n );\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,aAAa,EAC3B,gBACA,OAAO,WACP,QAAQ,SACR,GAAG,SACiB;CACpB,MAAM,EAAE,eAAe,YAAY,kBAAkB;AACrD,KAAI,kBAAkB,CAAC,QAAS,QAAO;AAEvC,QACE,oBAAC;EACC,MAAK;EACL,WAAW,GACT,eAAe;GACb;GACA;GACD,CAAC,EACF,MAAM,UACP;EACD,eAAY;EACZ,cAAW;EACX,eAAe;AACb,iBAAc,KAAK;;YAGrB,oBAAC,WAAS;GACH;;AAIb,SAAgB,kBAAkB,EAChC,gBACA,GAAG,SAGF;CACD,MAAM,EAAE,SAAS,QAAQ,kBAAkB,kBAAkB;CAC7D,MAAM,EAAE,SAAS,SAAS;AAC1B,KAAI,kBAAkB,CAAC,QAAS,QAAO;AAEvC,QACE,qBAAC;EACC,MAAK;EACL,oBAAiB;EACjB,GAAI;EACJ,WAAW,GACT,mQACA,MAAM,UACP;EACD,eAAe;AACb,iBAAc,KAAK;;;GAGrB,oBAAC,UAAO,WAAU,WAAW;GAC5B,KAAK;GACN,oBAAC;IAAI,WAAU;cACZ,OAAO,KAAK,GAAG,MACd,oBAAC;KAAY,WAAU;eACpB,EAAE;OADK,EAEJ,CACN;KACE;;GACC"}
|
package/dist/style.css
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
|
8
8
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
9
9
|
"Courier New", monospace;
|
|
10
|
-
--color-black: #000;
|
|
11
10
|
--spacing: 0.25rem;
|
|
12
11
|
--breakpoint-sm: 40rem;
|
|
13
12
|
--container-sm: 24rem;
|
|
@@ -66,6 +65,7 @@
|
|
|
66
65
|
--color-fd-diff-add-symbol: rgb(10, 200, 100);
|
|
67
66
|
--animate-fd-fade-in: fd-fade-in 300ms ease;
|
|
68
67
|
--animate-fd-fade-out: fd-fade-out 300ms ease;
|
|
68
|
+
--animate-fd-dialog-in: fd-dialog-in 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
69
69
|
--animate-fd-dialog-out: fd-dialog-out 300ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
70
70
|
--animate-fd-popover-in: fd-popover-in 100ms ease;
|
|
71
71
|
--animate-fd-popover-out: fd-popover-out 100ms ease;
|
|
@@ -1037,12 +1037,12 @@
|
|
|
1037
1037
|
.w-1\.5 {
|
|
1038
1038
|
width: calc(var(--spacing) * 1.5);
|
|
1039
1039
|
}
|
|
1040
|
+
.w-1\/4 {
|
|
1041
|
+
width: calc(1/4 * 100%);
|
|
1042
|
+
}
|
|
1040
1043
|
.w-4 {
|
|
1041
1044
|
width: calc(var(--spacing) * 4);
|
|
1042
1045
|
}
|
|
1043
|
-
.w-\[25\%\] {
|
|
1044
|
-
width: 25%;
|
|
1045
|
-
}
|
|
1046
1046
|
.w-\[85\%\] {
|
|
1047
1047
|
width: 85%;
|
|
1048
1048
|
}
|
|
@@ -1167,6 +1167,9 @@
|
|
|
1167
1167
|
.animate-pulse {
|
|
1168
1168
|
animation: var(--animate-pulse);
|
|
1169
1169
|
}
|
|
1170
|
+
.scroll-m-20 {
|
|
1171
|
+
scroll-margin: calc(var(--spacing) * 20);
|
|
1172
|
+
}
|
|
1170
1173
|
.scroll-m-24 {
|
|
1171
1174
|
scroll-margin: calc(var(--spacing) * 24);
|
|
1172
1175
|
}
|
|
@@ -1759,12 +1762,6 @@
|
|
|
1759
1762
|
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
1760
1763
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1761
1764
|
}
|
|
1762
|
-
.shadow-black\/50 {
|
|
1763
|
-
--tw-shadow-color: color-mix(in srgb, #000 50%, transparent);
|
|
1764
|
-
@supports (color: color-mix(in lab, red, red)) {
|
|
1765
|
-
--tw-shadow-color: color-mix(in oklab, color-mix(in oklab, var(--color-black) 50%, transparent) var(--tw-shadow-alpha), transparent);
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
1765
|
.outline {
|
|
1769
1766
|
outline-style: var(--tw-outline-style);
|
|
1770
1767
|
outline-width: 1px;
|
|
@@ -2287,6 +2284,11 @@
|
|
|
2287
2284
|
transition-property: none;
|
|
2288
2285
|
}
|
|
2289
2286
|
}
|
|
2287
|
+
.data-open\:animate-fd-dialog-in {
|
|
2288
|
+
&[data-open] {
|
|
2289
|
+
animation: var(--animate-fd-dialog-in);
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2290
2292
|
.data-open\:animate-fd-fade-in {
|
|
2291
2293
|
&[data-open] {
|
|
2292
2294
|
animation: var(--animate-fd-fade-in);
|
|
@@ -3235,6 +3237,15 @@
|
|
|
3235
3237
|
transform: translateX(var(--fd-sidebar-drawer-offset));
|
|
3236
3238
|
}
|
|
3237
3239
|
}
|
|
3240
|
+
@keyframes fd-dialog-in {
|
|
3241
|
+
from {
|
|
3242
|
+
transform: scale(1.06);
|
|
3243
|
+
opacity: 0;
|
|
3244
|
+
}
|
|
3245
|
+
to {
|
|
3246
|
+
transform: scale(1);
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3238
3249
|
@keyframes fd-dialog-out {
|
|
3239
3250
|
from {
|
|
3240
3251
|
transform: scale(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fumadocs/base-ui",
|
|
3
|
-
"version": "16.6.
|
|
3
|
+
"version": "16.6.1",
|
|
4
4
|
"description": "The Base UI version of Fumadocs UI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Docs",
|
|
@@ -94,10 +94,10 @@
|
|
|
94
94
|
"access": "public"
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@base-ui/react": "^1.
|
|
97
|
+
"@base-ui/react": "^1.2.0",
|
|
98
98
|
"class-variance-authority": "^0.7.1",
|
|
99
99
|
"lucide-react": "^0.563.0",
|
|
100
|
-
"motion": "^12.
|
|
100
|
+
"motion": "^12.34.0",
|
|
101
101
|
"next-themes": "^0.4.6",
|
|
102
102
|
"react-medium-image-zoom": "^5.4.0",
|
|
103
103
|
"react-remove-scroll": "^2.7.2",
|
|
@@ -110,15 +110,15 @@
|
|
|
110
110
|
"devDependencies": {
|
|
111
111
|
"@tailwindcss/cli": "^4.1.18",
|
|
112
112
|
"@types/hast": "^3.0.4",
|
|
113
|
-
"@types/node": "^25.2.
|
|
114
|
-
"@types/react": "^19.2.
|
|
113
|
+
"@types/node": "^25.2.3",
|
|
114
|
+
"@types/react": "^19.2.14",
|
|
115
115
|
"@types/react-dom": "^19.2.3",
|
|
116
116
|
"tailwindcss": "^4.1.18",
|
|
117
117
|
"tsdown": "^0.20.3",
|
|
118
118
|
"unified": "^11.0.5",
|
|
119
119
|
"@fumadocs/cli": "1.2.4",
|
|
120
120
|
"eslint-config-custom": "0.0.0",
|
|
121
|
-
"fumadocs-core": "16.6.
|
|
121
|
+
"fumadocs-core": "16.6.1",
|
|
122
122
|
"tsconfig": "0.0.0"
|
|
123
123
|
},
|
|
124
124
|
"peerDependencies": {
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"react": "^19.2.0",
|
|
128
128
|
"react-dom": "^19.2.0",
|
|
129
129
|
"tailwindcss": "^4.0.0",
|
|
130
|
-
"fumadocs-core": "16.6.
|
|
130
|
+
"fumadocs-core": "16.6.1"
|
|
131
131
|
},
|
|
132
132
|
"peerDependenciesMeta": {
|
|
133
133
|
"next": {
|