rtgk-screen-web/pages/components/Combobox/index.js

85 lines
3.1 KiB
JavaScript

import react from "react";
import { Fragment, useState } from "react";
import { Listbox, Transition } from "@headlessui/react";
import { CheckIcon, SelectorIcon } from "@heroicons/react/solid";
export default function AutoCompleteComboBox({
dataSource,
selectedone,
selectChanged,
}) {
if (!dataSource) {
dataSource = [{ name: "无" }];
}
react.useEffect(() => {
if (JSON.stringify(dataSource[0]) === JSON.stringify(selected)) {
return;
}
if (selectedone && dataSource.length > 0) {
setSelected(dataSource.filter((x) => x.code === selectedone)[0]);
} else {
setSelected(dataSource[0]);
}
}, [dataSource, selectedone]);
const [selected, setSelected] = useState(dataSource[0]);
react.useEffect(() => {
selectChanged(selected);
}, [selected]);
return (
<div className="w-60">
<Listbox value={selected} onChange={setSelected}>
<div className="relative mt-1">
<Listbox.Button className="relative w-full py-1 pl-3 pr-10 text-left bg-white rounded-lg border 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 sm:text-sm">
<span className="block truncate">{selected?.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">
{dataSource.map((item, itemIdx) => (
<Listbox.Option
key={itemIdx}
className={({ active }) =>
`cursor-default select-none relative py-0.5 my-0.5 pl-10 pr-4 ${
active ? "text-amber-900 bg-amber-100" : "text-gray-900"
}`
}
value={item}
>
{({ selected }) => (
<>
<span
className={`block truncate ${
selected ? "font-medium" : "font-normal"
}`}
>
{item.name}
</span>
{selected ? (
<span className="absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600">
<CheckIcon className="w-5 h-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</Listbox>
</div>
);
}