Files
gunshiz d120b5f787
CI / verify (push) Successful in 45s
CI / build-and-deploy (push) Failing after 1m2s
feat : init
2026-09-09 17:58:37 +07:00

21 lines
2.4 KiB
TypeScript

"use client";
import { useState } from "react";
import { CheckIcon, ChevronsUpDownIcon } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { cn } from "@/lib/utils";
import { rarityGradientClass } from "@/lib/catalog-rarity";
import type { CatalogItem } from "@/lib/translator/types";
export function CatalogCombobox({ items, value, onChange, placeholder }: { items: CatalogItem[]; value: string; onChange: (item: CatalogItem) => void; placeholder: string }) {
const [open, setOpen] = useState(false);
const selected = items.find((item) => item.id === value);
return <Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger render={<Button variant="outline" className="w-full justify-between normal-case tracking-normal" />}>{selected ? <Avatar size="sm" className={rarityGradientClass(selected.rarity)}><AvatarImage src={selected.imageUrl || undefined} alt="" /><AvatarFallback>{selected.name.slice(0, 1)}</AvatarFallback></Avatar> : null}<span className="min-w-0 flex-1 truncate text-left">{selected?.name ?? placeholder}</span>{selected?.rarity ? <span className="shrink-0 text-muted-foreground tabular-nums">{selected.rarity}★</span> : null}<ChevronsUpDownIcon data-icon="inline-end" /></PopoverTrigger>
<PopoverContent className="w-(--anchor-width) p-0" align="start"><Command><CommandInput placeholder={`Search ${placeholder.toLowerCase()}...`} /><CommandList><CommandEmpty>No matching item.</CommandEmpty><CommandGroup>{items.map((item) => <CommandItem key={item.id} value={`${item.name} ${item.key}`} disabled={!item.supported} onSelect={() => { onChange(item); setOpen(false); }}><CheckIcon className={cn(item.id === value ? "opacity-100" : "opacity-0")} /><Avatar size="sm" className={rarityGradientClass(item.rarity)}><AvatarImage src={item.imageUrl || undefined} alt="" /><AvatarFallback>{item.name.slice(0, 1)}</AvatarFallback></Avatar><span className="min-w-0 flex-1 truncate">{item.name}</span>{item.rarity ? <span className="ml-auto shrink-0 text-muted-foreground tabular-nums">{item.rarity}★</span> : null}</CommandItem>)}</CommandGroup></CommandList></Command></PopoverContent>
</Popover>;
}