added SearchBar for MainSection
This commit is contained in:
parent
d5e5fe995b
commit
c34cac7cee
156
src/components/SearchBar.tsx
Normal file
156
src/components/SearchBar.tsx
Normal file
@ -0,0 +1,156 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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";
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Component props */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
type Hint = {
|
||||
id: string;
|
||||
caption: string;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
onChange: (query: string) => void;
|
||||
onSelected?: (value: Hint) => void;
|
||||
hints: Hint[];
|
||||
disabled?: boolean;
|
||||
inGroup?: boolean;
|
||||
className?: string;
|
||||
maxScrollSize?: number;
|
||||
elementScrollSize?: number;
|
||||
};
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 TextInputBox({
|
||||
onChange,
|
||||
onSelected,
|
||||
hints,
|
||||
disabled,
|
||||
inGroup,
|
||||
className,
|
||||
maxScrollSize = 140,
|
||||
elementScrollSize = 36,
|
||||
...props
|
||||
}: Props) {
|
||||
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 className={classNames("w-60", className)}>
|
||||
<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={"Search..."}
|
||||
displayValue={(hint: Hint | undefined) => hint?.caption ?? ""}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
{query.length > 0 && (
|
||||
<div className={`${inputList}`}>
|
||||
<Transition
|
||||
as={Fragment}
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<Combobox.Options>
|
||||
{hints.length === 0 && query !== "" ? (
|
||||
<p className="">Nothing found.</p>
|
||||
) : 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>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user