update demo
This commit is contained in:
62
components/Select.tsx
Normal file
62
components/Select.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user