fix props in component

This commit is contained in:
filantrop 2022-09-07 14:58:40 +03:00
parent ada0f450f5
commit f3ccb0523a

View File

@ -0,0 +1,164 @@
/* -------------------------------------------------------------------------- */
/* Imports */
/* -------------------------------------------------------------------------- */
import React from "react";
import classNames from "classnames";
import "../index.css";
import { Combobox, Transition } from "@headlessui/react";
import { Fragment, useEffect, useState } from "react";
import { Scrollbar } from "react-scrollbars-custom";
import { Function } from "lodash";
/* -------------------------------------------------------------------------- */
/* Component props */
/* -------------------------------------------------------------------------- */
type Hint = {
id: string;
caption: string;
};
type Props<T> = {
onChange: (query: string) => void;
onSelected: (value: Hint) => void;
IsEmptyItems: () => React.ReactNode;
hints: Hint[];
displayValueResolver?: (element: T) => any;
disabled?: boolean;
inGroup?: boolean;
className?: string;
maxScrollSize?: number;
elementScrollSize?: number;
placeHolder?: string;
};
/* -------------------------------------------------------------------------- */
/* styles */
/* -------------------------------------------------------------------------- */
const inputStyle = `
w-full
cursor-default
rounded
overflow-hidden
border
border-solid
shadow-none
border-gray-100
focus:outline-none
focus:border-gray-200
hover:border-gray-200
py-2 pl-3
text-sm
text-gray-900
`;
const inputList = `
absolute z-10 mt-1 w-full max-h-56
bg-white shadow-lg
rounded py-1
overflow-hidden
focus:outline-none
text-base
sm:text-sm`;
const inputInGroup = [
`border-none
hover:none
active:none
focus:none
`,
];
/* -------------------------------------------------------------------------- */
/* Component implementation */
/* -------------------------------------------------------------------------- */
export default function SearchBar<T>({
onChange,
onSelected,
hints,
displayValueResolver,
disabled,
inGroup = false,
className,
maxScrollSize = 140,
elementScrollSize = 36,
placeHolder = "Search...",
IsEmptyItems,
...props
}: Props<T>) {
const [selected, setSelected] = useState<any>(hints);
const [query, setQuery] = useState("");
useEffect(() => {
onChange(query);
}, [query, onChange]);
const handleSelected = (value: Hint) => {
setSelected(value);
onSelected && onSelected(value);
};
return (
<div>
<Combobox value={selected} {...props} onChange={handleSelected}>
<div className="relative">
<div className="relative w-full bg-white text-left focus:outline-none sm:text-sm">
<Combobox.Input
className={classNames([
[`${inputStyle}`],
{ [`${inputInGroup}`]: inGroup },
className,
])}
onChange={(event) => setQuery(event.target.value)}
placeholder={placeHolder}
displayValue={(value: T) =>
displayValueResolver ? displayValueResolver(value) : value
}
/>
</div>
<div>
{query.length > 0 && (
<div className={`${inputList}`}>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
afterLeave={() => setQuery("")}
>
<Combobox.Options>
{hints.length === 0 && query !== "" ? IsEmptyItems() : null}
{/* <Scrollbar
style={{
height: hints.length * elementScrollSize,
maxHeight: maxScrollSize,
}}
> */}
{hints.map((item: any, id: number) => (
<Combobox.Option
key={id}
className={({ active, selected }) =>
classNames(
active
? "text-gray-900 bg-blue-50"
: "font-normal ",
"cursor-default select-none relative py-2 pl-3 pr-9",
selected
? "text-gray-900 bg-blue-100"
: "font-normal "
)
}
value={item}
>
<div>{item.caption}</div>
</Combobox.Option>
))}
{/* </Scrollbar> */}
</Combobox.Options>
</Transition>
</div>
)}
</div>
</div>
</Combobox>
</div>
);
}