ERP-node/frontend/lib/registry/pop-components/pop-shared/ColumnCombobox.tsx

106 lines
3.0 KiB
TypeScript

"use client";
import React, { useState, useMemo } from "react";
import { Check, ChevronsUpDown } from "lucide-react";
import { Button } from "@/components/ui/button";
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 type { ColumnInfo } from "../pop-dashboard/utils/dataFetcher";
interface ColumnComboboxProps {
columns: ColumnInfo[];
value: string;
onSelect: (columnName: string) => void;
placeholder?: string;
}
export function ColumnCombobox({
columns,
value,
onSelect,
placeholder = "컬럼을 선택하세요",
}: ColumnComboboxProps) {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const filtered = useMemo(() => {
if (!search) return columns;
const q = search.toLowerCase();
return columns.filter((c) => c.name.toLowerCase().includes(q));
}, [columns, search]);
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant="outline"
role="combobox"
aria-expanded={open}
className="mt-1 h-8 w-full justify-between text-xs"
>
{value || placeholder}
<ChevronsUpDown className="ml-2 h-3.5 w-3.5 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent
className="p-0"
style={{ width: "var(--radix-popover-trigger-width)" }}
align="start"
>
<Command shouldFilter={false}>
<CommandInput
placeholder="컬럼명 검색..."
className="text-xs"
value={search}
onValueChange={setSearch}
/>
<CommandList>
<CommandEmpty className="py-4 text-center text-xs">
.
</CommandEmpty>
<CommandGroup>
{filtered.map((col) => (
<CommandItem
key={col.name}
value={col.name}
onSelect={() => {
onSelect(col.name);
setOpen(false);
setSearch("");
}}
className="text-xs"
>
<Check
className={cn(
"mr-2 h-3.5 w-3.5",
value === col.name ? "opacity-100" : "opacity-0"
)}
/>
<div className="flex items-center gap-2">
<span>{col.name}</span>
<span className="text-[10px] text-muted-foreground">
{col.type}
</span>
</div>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
);
}