Files
Vlad Morozov a3cdf46210 update demo
2025-04-22 19:38:59 +03:00

63 lines
2.1 KiB
TypeScript

import * as SelectPrimitive from "@radix-ui/react-select";
import { useState } from "react";
import { ChevronDownIcon } from "./Icons";
interface SelectProps<T> {
options: T[];
renderOption: (option: T) => React.ReactNode;
onSelect: (option: T) => void;
isSelected: (option: T) => boolean;
value: string | null | undefined;
placeholder?: string;
disabled?: boolean;
}
export function Select<T>(props: SelectProps<T>) {
const [isOpen, setIsOpen] = useState(false);
return (
<SelectPrimitive.Root
disabled={props.disabled}
open={isOpen}
onOpenChange={setIsOpen}
>
<SelectPrimitive.Trigger className="w-full text-white text-sm bg-zinc-700 py-2 px-6 rounded-lg cursor-pointer flex items-center justify-between h-fit disabled:opacity-50 min-h-[36px]">
<div className={`${props.value ? "text-white" : "text-zinc-400"}`}>
{props.value ? props.value : props.placeholder}
</div>
<ChevronDownIcon className="w-4 h-4" />
</SelectPrimitive.Trigger>
<SelectPrimitive.Portal>
<SelectPrimitive.Content
className="z-50 w-[var(--radix-select-trigger-width)] max-h-[300px] overflow-y-auto"
position="popper"
sideOffset={5}
>
<SelectPrimitive.Viewport className="rounded-lg border border-zinc-600 bg-zinc-700 shadow-lg py-1">
{props.options.map((option) => {
const isSelected = props.isSelected(option);
return (
<div
key={props.renderOption(option)?.toString()}
className={`py-2 px-4 cursor-pointer hover:bg-zinc-600 outline-none text-sm ${
isSelected ? "text-white bg-zinc-500" : "text-zinc-400"
}`}
onClick={() => {
props.onSelect(option);
setIsOpen(false);
}}
>
{props.renderOption(option)}
</div>
);
})}
</SelectPrimitive.Viewport>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
</SelectPrimitive.Root>
);
}