refactor(search): extract search into workspace package

This commit is contained in:
Maofeng
2026-09-20 15:52:09 +08:00
parent e02c3dceb5
commit 1fc56b6982
34 changed files with 262 additions and 360 deletions
+79
View File
@@ -0,0 +1,79 @@
import { Command } from "cmdk"
import { useTranslate } from "@workspace/i18n"
import { Button } from "@workspace/ui/components/button"
import { ScrollArea } from "@workspace/ui/components/scroll-area"
import { cn } from "@workspace/ui/lib/utils"
import { HistoryIcon, Trash2Icon, XIcon } from "@workspace/ui/components/icon"
import { searchMessages } from "./messages"
export interface SearchHistoryProps {
className?: string
items: readonly string[]
onSelect: (keyword: string) => void
onRemove: (keyword: string) => void
onClear: () => void
}
export function SearchHistory({
className,
items,
onClear,
onRemove,
onSelect,
}: SearchHistoryProps) {
const t = useTranslate()
return (
<div
className={cn("flex h-[min(65dvh,36rem)] min-h-0 flex-col", className)}
>
<ScrollArea className="min-h-0 flex-1 p-4">
<div className="sticky top-0 z-1 flex items-center justify-between bg-sidebar/90 ps-2 pb-2 backdrop-blur-xs">
<span className="flex items-center gap-2 text-sm font-medium">
{t(searchMessages.history)}
</span>
<Button
type="button"
variant="ghost"
className="hover:bg-destructive/10 hover:text-destructive"
size="xs"
onClick={onClear}
>
<Trash2Icon />
{t(searchMessages.clearHistory)}
</Button>
</div>
<Command.List
data-slot="command-list"
className="gap-1 px-1 pb-1 **:[[cmdk-list-sizer]]:space-y-1"
>
{items.map((item) => (
<Command.Item
key={item}
value={item}
onSelect={() => onSelect(item)}
className="flex cursor-pointer items-center gap-2 rounded-xl border border-sidebar-border/55 bg-popover p-2 shadow-xs transition-colors hover:bg-secondary [&>svg]:last:hidden"
>
<HistoryIcon className="size-4 text-muted-foreground opacity-65" />
<span className="min-w-0 flex-1 truncate text-left">{item}</span>
<Button
type="button"
variant="destructive"
size="icon-xs"
className="translate-x-1 opacity-100 group-hover/command-item:opacity-70 hover:opacity-100"
aria-label={t(searchMessages.removeHistory, { query: item })}
onClick={(event) => {
event.preventDefault()
event.stopPropagation()
onRemove(item)
}}
>
<XIcon />
</Button>
</Command.Item>
))}
</Command.List>
</ScrollArea>
</div>
)
}