style: added direction for multi-level drop-down (#328)

* feat: made new multi-level select listbox

* refractor: changeds Multi-level-select component and added direction props

* style: added direction for multi-level drop-down
This commit is contained in:
Dakshesh Jain 2023-02-23 17:02:26 +05:30 committed by GitHub
parent 4caa4e33b1
commit 1e63c5b1b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -20,10 +20,11 @@ type TMultipleSelectProps = {
selected: TSelectOption | null; selected: TSelectOption | null;
setSelected: (value: any) => void; setSelected: (value: any) => void;
label: string; label: string;
direction?: "left" | "right";
}; };
export const MultiSelect: React.FC<TMultipleSelectProps> = (props) => { export const MultiLevelSelect: React.FC<TMultipleSelectProps> = (props) => {
const { options, selected, setSelected, label } = props; const { options, selected, setSelected, label, direction = "right" } = props;
const [openChildFor, setOpenChildFor] = useState<TSelectOption | null>(null); const [openChildFor, setOpenChildFor] = useState<TSelectOption | null>(null);
@ -42,7 +43,7 @@ export const MultiSelect: React.FC<TMultipleSelectProps> = (props) => {
<div className="relative mt-1"> <div className="relative mt-1">
<Listbox.Button <Listbox.Button
onClick={() => setOpenChildFor(null)} onClick={() => setOpenChildFor(null)}
className="relative w-full cursor-default rounded-lg bg-white py-2 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-orange-300 sm:text-sm" className="relative w-full cursor-default rounded-lg bg-white py-2 pl-3 pr-10 text-left shadow-md sm:text-sm"
> >
<span className="block truncate">{selected?.label ?? label}</span> <span className="block truncate">{selected?.label ?? label}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"> <span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
@ -58,35 +59,41 @@ export const MultiSelect: React.FC<TMultipleSelectProps> = (props) => {
> >
<Listbox.Options <Listbox.Options
static static
className="absolute mt-1 max-h-60 w-full overflowa-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" className="absolute mt-1 max-h-60 w-full rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
> >
{options.map((option) => ( {options.map((option) => (
<Listbox.Option <Listbox.Option
key={option.id} key={option.id}
className={({ active }) => className={
`relative cursor-default select-none py-2 pl-10 pr-4 ${ "relative cursor-default select-none py-2 pl-10 pr-4 hover:bg-gray-100 hover:text-gray-900"
active ? "bg-amber-100 text-amber-900" : "text-gray-900"
}`
} }
onClick={(e: any) => { onClick={(e: any) => {
if (option.children !== null) { if (option.children !== null) {
e.preventDefault(); e.preventDefault();
setOpenChildFor(option); setOpenChildFor(option);
} }
if (option.id === openChildFor?.id) {
e.preventDefault();
setOpenChildFor(null);
}
}} }}
value={option} value={option}
> >
{({ selected }) => ( {({ selected }) => (
<> <>
{openChildFor?.id === option.id && ( {openChildFor?.id === option.id && (
<div className="w-72 h-auto max-h-72 bg-white border border-gray-200 rounded-lg rounded-tl-none shadow-md absolute left-full translate-x-2"> <div
className={`w-72 h-auto max-h-72 bg-white border border-gray-200 absolute rounded-lg ${
direction === "right"
? "rounded-tl-none shadow-md left-full translate-x-2"
: "rounded-tr-none shadow-md right-full -translate-x-2"
}`}
>
{option.children?.map((child) => ( {option.children?.map((child) => (
<Listbox.Option <Listbox.Option
key={child.id} key={child.id}
className={({ active }) => className={
`relative cursor-default select-none py-2 pl-10 pr-4 ${ "relative cursor-default select-none py-2 pl-10 pr-4 hover:bg-gray-100 hover:text-gray-900"
active ? "bg-amber-100 text-amber-900" : "text-gray-900"
}`
} }
as="div" as="div"
value={child} value={child}
@ -101,7 +108,7 @@ export const MultiSelect: React.FC<TMultipleSelectProps> = (props) => {
{child.label} {child.label}
</span> </span>
{selected ? ( {selected ? (
<span className="absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600"> <span className="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-600">
<CheckIcon className="h-5 w-5" aria-hidden="true" /> <CheckIcon className="h-5 w-5" aria-hidden="true" />
</span> </span>
) : null} ) : null}
@ -110,7 +117,13 @@ export const MultiSelect: React.FC<TMultipleSelectProps> = (props) => {
</Listbox.Option> </Listbox.Option>
))} ))}
<div className="w-0 h-0 absolute top-0 left-0 -translate-x-2 border-t-8 border-gray-300 border-r-8 border-b-8 border-b-transparent border-t-transparent border-l-transparent" /> <div
className={`w-0 h-0 absolute border-t-8 border-gray-300 ${
direction === "right"
? "top-0 left-0 -translate-x-2 border-r-8 border-b-8 border-b-transparent border-t-transparent border-l-transparent"
: "top-0 right-0 translate-x-2 border-l-8 border-b-8 border-b-transparent border-t-transparent border-r-transparent"
}`}
/>
</div> </div>
)} )}
<span <span
@ -119,7 +132,7 @@ export const MultiSelect: React.FC<TMultipleSelectProps> = (props) => {
{option.label} {option.label}
</span> </span>
{selected ? ( {selected ? (
<span className="absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600"> <span className="absolute inset-y-0 left-0 flex items-center pl-3 text-gray-600">
<CheckIcon className="h-5 w-5" aria-hidden="true" /> <CheckIcon className="h-5 w-5" aria-hidden="true" />
</span> </span>
) : null} ) : null}