shellphone.app/app/features/core/components/select.tsx

69 lines
2.4 KiB
TypeScript
Raw Normal View History

2022-05-14 10:22:06 +00:00
import { Fragment } from "react";
import { Listbox, Transition } from "@headlessui/react";
import { HiCheck as CheckIcon, HiSelector as SelectorIcon } from "react-icons/hi";
import clsx from "clsx";
type Option = { name: string; value: string };
type Props = {
options: Option[];
onChange: (selectedValue: Option) => void;
value: Option;
};
export default function Select({ options, onChange, value }: Props) {
return (
<Listbox value={value} onChange={onChange}>
<div className="relative mt-1">
<Listbox.Button className="relative w-full py-2 pl-3 pr-10 text-left bg-white rounded-lg shadow-md cursor-default focus:outline-none focus-visible:ring-2 focus-visible:ring-opacity-75 focus-visible:ring-white focus-visible:ring-offset-orange-300 focus-visible:ring-offset-2 focus-visible:border-indigo-500 sm:text-sm">
<span className="block truncate">{value.name}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<SelectorIcon className="w-5 h-5 text-gray-400" aria-hidden="true" />
</span>
</Listbox.Button>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute w-full py-1 mt-1 overflow-auto text-base bg-white rounded-md shadow-lg max-h-60 ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{options.map((option, index) => (
<Listbox.Option
key={`option-${option}-${index}`}
className={({ active }) =>
clsx(
"cursor-default select-none relative py-2 pl-10 pr-4",
active ? "text-amber-900 bg-amber-100" : "text-gray-900",
)
}
value={option}
>
{({ selected, active }) => (
<>
<span
className={clsx("block truncate", selected ? "font-medium" : "font-normal")}
>
{option.name}
</span>
{selected ? (
<span
className={clsx(
"absolute inset-y-0 left-0 flex items-center pl-3",
active ? "text-amber-600" : "text-amber-600",
)}
>
<CheckIcon className="w-5 h-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</Listbox>
);
}