80 lines
2.7 KiB
TypeScript
80 lines
2.7 KiB
TypeScript
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>
|
|
)
|
|
}
|