refactor(search): extract search into workspace package
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user