From 5e3b000bd65978e0eb7e3909693e68c993d04fbe Mon Sep 17 00:00:00 2001 From: filantrop <filantrop83@gmail.com> Date: Wed, 24 Aug 2022 15:32:48 +0300 Subject: [PATCH] fix style and add inGroup props for InputGroup --- src/components/Select.tsx | 74 +++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 752939c..1670d5d 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -7,18 +7,22 @@ import { Listbox, Transition } from "@headlessui/react"; import classNames from "classnames"; import "../index.css"; import { ReactComponent as SelectIcon } from "../assets/svg/select-arrow.svg"; +import { Scrollbar } from "react-scrollbars-custom"; /* -------------------------------------------------------------------------- */ /* Component props */ /* -------------------------------------------------------------------------- */ type Props<T> = { + inGroup?: boolean; options?: T[]; disabled?: boolean; className?: string; value: T; displayValueResolver?: (element: T) => any; onChange: (element: T) => void; + maxScrollSize?: number; + elementScrollSize?: number; } & Omit<React.ComponentPropsWithRef<"select">, "value" | "onChange">; /* -------------------------------------------------------------------------- */ @@ -43,7 +47,7 @@ const SelectOptionsStyle = ` absolute z-10 mt-1 w-full max-h-56 bg-white shadow-lg rounded py-1 - overflow-auto + overflow-hidden focus:outline-none text-base sm:text-sm @@ -54,23 +58,40 @@ const SelectIconStyle = ` absolute inset-y-0 right-0 flex items-center pr-2 `; + +const inputInGroup = [ + ` border-none + hover:none + active:none + focus:none + `, +]; /* -------------------------------------------------------------------------- */ /* Component implementation */ /* -------------------------------------------------------------------------- */ function Select<T>({ + inGroup = false, // We should use this flag to choose how we will style our component className, options = [], value, onChange, displayValueResolver, disabled, + maxScrollSize = 140, + elementScrollSize = 36, ...props }: Props<T>): JSX.Element { return ( - <div className={classNames("fixed top-16 w-60", className)}> + <div className={classNames("top-16 w-60", className)}> <Listbox value={value} {...props} onChange={onChange}> - <div className="relative mt-1"> - <Listbox.Button className={`${SelectButtonStyle}`}> + <div className="relative"> + <Listbox.Button + className={classNames([ + [`${SelectButtonStyle}`], + { [`${inputInGroup}`]: inGroup }, + className, + ])} + > {({ open }) => ( <> <span className="block truncate">{`${ @@ -86,7 +107,6 @@ function Select<T>({ </> )} </Listbox.Button> - <Transition as={Fragment} leave="transition ease-in duration-100" @@ -94,28 +114,38 @@ function Select<T>({ leaveTo="opacity-0" > <Listbox.Options className={`${SelectOptionsStyle}`}> - {options.map((option, id) => ( - <Listbox.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={option} - > - {`${ - displayValueResolver ? displayValueResolver(option) : option - }`} - </Listbox.Option> - ))} + <Scrollbar + style={{ + height: options.length * elementScrollSize, + maxHeight: maxScrollSize, + }} + > + {options.map((option, id) => ( + <Listbox.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={option} + > + {`${ + displayValueResolver + ? displayValueResolver(option) + : option + }`} + </Listbox.Option> + ))} + </Scrollbar> </Listbox.Options> </Transition> </div> </Listbox> </div> + // ); } export default Select;