ui(search): use reicon controls

This commit is contained in:
ShadowArcanist
2026-06-16 21:09:30 +05:30
parent 39b6a3d02a
commit ee8cb1d4fb
3 changed files with 77 additions and 5 deletions
+46 -3
View File
@@ -1,9 +1,9 @@
'use client';
import type { ComponentProps, MouseEvent } from 'react';
import { useI18n } from 'fumadocs-ui/contexts/i18n';
import { useSearchContext } from 'fumadocs-ui/contexts/search';
import type { SearchTriggerProps } from 'fumadocs-ui/layouts/shared/slots/search-trigger';
import { FullSearchTrigger } from 'fumadocs-ui/layouts/shared/slots/search-trigger';
import type { FullSearchTriggerProps, SearchTriggerProps } from 'fumadocs-ui/layouts/shared/slots/search-trigger';
import {
Sidebar as NotebookSidebar,
SidebarCollapseTrigger,
@@ -51,6 +51,49 @@ export function MobileSearchTrigger({
);
}
export function FullSearchTriggerWithReicon({
hideIfDisabled,
className,
onClick,
...props
}: FullSearchTriggerProps) {
const { enabled, hotKey, setOpenSearch } = useSearchContext();
const { text } = useI18n();
if (hideIfDisabled && !enabled) return null;
function handleClick(event: MouseEvent<HTMLButtonElement>) {
onClick?.(event);
if (!event.defaultPrevented) {
setOpenSearch(true);
}
}
return (
<button
type="button"
data-search-full=""
{...props}
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',
className,
)}
onClick={handleClick}
>
<Search3 className="size-4" weight="Filled" aria-hidden="true" />
{text.search}
<div className="ms-auto inline-flex gap-0.5">
{hotKey.map((key, index) => (
<kbd key={index} className="rounded-md border bg-fd-background px-1.5">
{key.display}
</kbd>
))}
</div>
</button>
);
}
export function MobileSidebarTrigger({ className: _className, children: _children, ...props }: ComponentProps<'button'>) {
return (
<NotebookSidebarTrigger {...props} data-mobile-sidebar-toggle="" className={mobileHeaderButtonClassName}>
@@ -78,5 +121,5 @@ export const mobileSidebarSlots = {
export const mobileSearchTriggerSlots = {
sm: MobileSearchTrigger,
full: FullSearchTrigger,
full: FullSearchTriggerWithReicon,
};
+13
View File
@@ -0,0 +1,13 @@
import assert from 'node:assert/strict';
import fs from 'node:fs';
import { describe, test } from 'node:test';
describe('LocalSearchDialog', () => {
test('uses the reicon search icon in the dialog header', () => {
const source = fs.readFileSync('src/components/search.tsx', 'utf8');
assert.match(source, /Search3/);
assert.doesNotMatch(source, /SearchDialogIcon,/);
assert.doesNotMatch(source, /<SearchDialogIcon \/>/);
});
});
+18 -2
View File
@@ -1,19 +1,22 @@
'use client';
import { create } from '@orama/orama';
import type { ComponentProps } from 'react';
import {
SearchDialog,
SearchDialogClose,
SearchDialogContent,
SearchDialogHeader,
SearchDialogIcon,
SearchDialogInput,
SearchDialogList,
SearchDialogOverlay,
type SharedProps,
useSearch,
} from 'fumadocs-ui/components/dialog/search';
import { useI18n } from 'fumadocs-ui/contexts/i18n';
import { useDocsSearch } from 'fumadocs-core/search/client';
import { Search3 } from 'reicon-react';
import { cn } from '@/lib/cn';
import { site } from '@/lib/site';
function initOrama() {
@@ -37,7 +40,7 @@ export default function LocalSearchDialog(props: SharedProps) {
<SearchDialogOverlay />
<SearchDialogContent>
<SearchDialogHeader>
<SearchDialogIcon />
<SearchDialogIconWithReicon />
<SearchDialogInput />
<SearchDialogClose />
</SearchDialogHeader>
@@ -46,3 +49,16 @@ export default function LocalSearchDialog(props: SharedProps) {
</SearchDialog>
);
}
function SearchDialogIconWithReicon({ className, ...props }: ComponentProps<typeof Search3>) {
const { isLoading } = useSearch();
return (
<Search3
{...props}
className={cn('size-5 text-fd-muted-foreground', isLoading && 'animate-pulse duration-400', className)}
weight="Filled"
aria-hidden="true"
/>
);
}