diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 8698e4b..fae7a83 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -7,6 +7,7 @@ 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 */ @@ -16,15 +17,18 @@ type Hint = { caption: string; }; -type Props = { +type Props<T> = { onChange: (query: string) => void; - onSelected?: (value: Hint) => 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 */ @@ -67,17 +71,20 @@ const inputInGroup = [ /* Component implementation */ /* -------------------------------------------------------------------------- */ -export default function TextInputBox({ +export default function SearchBar<T>({ onChange, onSelected, hints, + displayValueResolver, disabled, - inGroup, + inGroup = false, className, maxScrollSize = 140, elementScrollSize = 36, + placeHolder = "Search...", + IsEmptyItems, ...props -}: Props) { +}: Props<T>) { const [selected, setSelected] = useState<any>(hints); const [query, setQuery] = useState(""); @@ -90,7 +97,7 @@ export default function TextInputBox({ onSelected && onSelected(value); }; return ( - <div className={classNames("w-60", className)}> + <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"> @@ -101,8 +108,10 @@ export default function TextInputBox({ className, ])} onChange={(event) => setQuery(event.target.value)} - placeholder={"Search..."} - displayValue={(hint: Hint | undefined) => hint?.caption ?? ""} + placeholder={placeHolder} + displayValue={(value: T) => + displayValueResolver ? displayValueResolver(value) : value + } /> </div> <div> @@ -113,36 +122,35 @@ export default function TextInputBox({ leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0" + afterLeave={() => setQuery("")} > <Combobox.Options> - {hints.length === 0 && query !== "" ? ( - <p className="">Nothing found.</p> - ) : null} + {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> - ))} + {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>