85 lines
3.1 KiB
JavaScript
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>
|
|
);
|
|
}
|