-
Notifications
You must be signed in to change notification settings - Fork 946
fix #259 partially converting some of the components from headlessui to shadcn #531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
4363fdf
e670be8
02cb48d
eb9ea8e
2587cec
18c4b5c
f094097
47de3cd
05a97ba
baec826
514f244
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,10 +1,13 @@ | ||||||
import { Menu, Transition } from "@headlessui/react"; | ||||||
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"; | ||||||
import { Fragment, Dispatch, SetStateAction } from "react"; | ||||||
|
||||||
function classNames(...classes: string[]) { | ||||||
return classes.filter(Boolean).join(" "); | ||||||
} | ||||||
import { CheckIcon} from "lucide-react"; | ||||||
import { Dispatch, SetStateAction, useState } from "react"; | ||||||
import * as React from "react" | ||||||
import { | ||||||
Select, | ||||||
SelectContent, | ||||||
SelectTrigger, | ||||||
SelectValue, | ||||||
} from "@/components/ui/select" | ||||||
import { cn } from "@/lib/utils"; | ||||||
|
||||||
interface DropDownProps { | ||||||
options: string[]; | ||||||
|
@@ -17,58 +20,48 @@ export default function DropDown({ | |||||
option, | ||||||
setOption, | ||||||
}: DropDownProps) { | ||||||
return ( | ||||||
<Menu as="div" className="relative block text-left w-full"> | ||||||
<div> | ||||||
<Menu.Button className="inline-flex w-full justify-between items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-400 font-light shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue"> | ||||||
{option} | ||||||
<ChevronDownIcon | ||||||
className="-mr-1 ml-2 h-5 w-5 ui-open:hidden" | ||||||
aria-hidden="true" | ||||||
/> | ||||||
<ChevronUpIcon | ||||||
className="-mr-1 ml-2 h-5 w-5 hidden ui-open:block" | ||||||
aria-hidden="true" | ||||||
/> | ||||||
</Menu.Button> | ||||||
</div> | ||||||
const [menuOpen, setMenuOpen] = useState<boolean>(false); | ||||||
const [isFirstClick, setIsFirstClick] = useState<boolean>(false); | ||||||
|
||||||
<Transition | ||||||
as={Fragment} | ||||||
enter="transition ease-out duration-100" | ||||||
enterFrom="transform opacity-0 scale-95" | ||||||
enterTo="transform opacity-100 scale-100" | ||||||
leave="transition ease-in duration-75" | ||||||
leaveFrom="transform opacity-100 scale-100" | ||||||
leaveTo="transform opacity-0 scale-95" | ||||||
> | ||||||
<Menu.Items | ||||||
className="absolute left-0 z-10 mt-2 w-full origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" | ||||||
key={option} | ||||||
> | ||||||
<div className=""> | ||||||
{options.map((optionItem) => ( | ||||||
<Menu.Item key={optionItem}> | ||||||
{({ active }) => ( | ||||||
<button | ||||||
onClick={() => setOption(optionItem)} | ||||||
className={classNames( | ||||||
active ? "bg-gray-100 text-gray-900" : "text-gray-700", | ||||||
option === optionItem ? "bg-gray-200" : "", | ||||||
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between", | ||||||
)} | ||||||
> | ||||||
<span>{optionItem}</span> | ||||||
{option === optionItem ? ( | ||||||
<CheckIcon className="w-4 h-4 text-bold" /> | ||||||
) : null} | ||||||
</button> | ||||||
)} | ||||||
</Menu.Item> | ||||||
))} | ||||||
</div> | ||||||
</Menu.Items> | ||||||
</Transition> | ||||||
</Menu> | ||||||
); | ||||||
const handleMenuStateChange = (open: boolean) => { | ||||||
if (isFirstClick) { | ||||||
setMenuOpen(true); // Keep the dropdown open on the first click | ||||||
return; | ||||||
} | ||||||
|
||||||
// If the menu is closed, reset the isFirstClick state | ||||||
if (!open) { | ||||||
setIsFirstClick(false); | ||||||
setMenuOpen(false); // Ensure the dropdown is closed | ||||||
} else { | ||||||
setMenuOpen(true); // Open the dropdown | ||||||
} | ||||||
}; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not needed. This is only to for a double-click delete confirmation |
||||||
return ( | ||||||
<Select open={menuOpen} onOpenChange={handleMenuStateChange}> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
<SelectTrigger className="inline-flex w-full justify-between items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-400 font-light shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue text-base"> | ||||||
<SelectValue placeholder={option}/> | ||||||
</SelectTrigger> | ||||||
<SelectContent> | ||||||
{options.map((optionItem) => ( | ||||||
<button | ||||||
onClick={() => { | ||||||
setOption(optionItem) | ||||||
setMenuOpen(false) | ||||||
}} | ||||||
className={cn( | ||||||
option === optionItem ? "bg-gray-200" : "hover:bg-gray-100", | ||||||
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between", | ||||||
)} | ||||||
> | ||||||
<span>{optionItem}</span> | ||||||
{option === optionItem ? ( | ||||||
<CheckIcon className="w-4 h-4 text-bold" /> | ||||||
) : null} | ||||||
</button> | ||||||
))} | ||||||
</SelectContent> | ||||||
</Select> | ||||||
) | ||||||
} | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to change the accordion behaviour. Let's leave the chevron. This component is used in other places and relies on the chevron. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,11 +1,13 @@ | ||||||
import { Dispatch, Fragment, SetStateAction } from "react"; | ||||||
|
||||||
import { Menu, Transition } from "@headlessui/react"; | ||||||
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"; | ||||||
|
||||||
function classNames(...classes: string[]) { | ||||||
return classes.filter(Boolean).join(" "); | ||||||
} | ||||||
import { CheckIcon} from "lucide-react"; | ||||||
import { Dispatch, SetStateAction, useState } from "react"; | ||||||
import * as React from "react" | ||||||
import { | ||||||
Select, | ||||||
SelectContent, | ||||||
SelectTrigger, | ||||||
SelectValue, | ||||||
} from "@/components/ui/select" | ||||||
import { cn } from "@/lib/utils"; | ||||||
|
||||||
interface DropDownProps { | ||||||
options: string[]; | ||||||
|
@@ -18,58 +20,48 @@ export default function DropDown({ | |||||
option, | ||||||
setOption, | ||||||
}: DropDownProps) { | ||||||
return ( | ||||||
<Menu as="div" className="relative block w-full text-left"> | ||||||
<div> | ||||||
<Menu.Button className="inline-flex w-full items-center justify-between rounded-md border border-black bg-white px-4 py-2 text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none"> | ||||||
{option} | ||||||
<ChevronDownIcon | ||||||
className="-mr-1 ml-2 h-5 w-5 ui-open:hidden" | ||||||
aria-hidden="true" | ||||||
/> | ||||||
<ChevronUpIcon | ||||||
className="-mr-1 ml-2 hidden h-5 w-5 ui-open:block" | ||||||
aria-hidden="true" | ||||||
/> | ||||||
</Menu.Button> | ||||||
</div> | ||||||
const [menuOpen, setMenuOpen] = useState<boolean>(false); | ||||||
const [isFirstClick, setIsFirstClick] = useState<boolean>(false); | ||||||
|
||||||
<Transition | ||||||
as={Fragment} | ||||||
enter="transition ease-out duration-100" | ||||||
enterFrom="transform opacity-0 scale-95" | ||||||
enterTo="transform opacity-100 scale-100" | ||||||
leave="transition ease-in duration-75" | ||||||
leaveFrom="transform opacity-100 scale-100" | ||||||
leaveTo="transform opacity-0 scale-95" | ||||||
> | ||||||
<Menu.Items | ||||||
className="absolute left-0 z-10 mt-2 w-full origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none" | ||||||
key={option} | ||||||
> | ||||||
<div className=""> | ||||||
{options.map((optionItem) => ( | ||||||
<Menu.Item key={optionItem}> | ||||||
{({ active }) => ( | ||||||
<button | ||||||
onClick={() => setOption(optionItem)} | ||||||
className={classNames( | ||||||
active ? "bg-gray-100 text-gray-900" : "text-gray-700", | ||||||
option === optionItem ? "bg-gray-200" : "", | ||||||
"flex w-full items-center justify-between space-x-2 px-4 py-2 text-left text-sm", | ||||||
)} | ||||||
> | ||||||
<span>{optionItem}</span> | ||||||
{option === optionItem ? ( | ||||||
<CheckIcon className="text-bold h-4 w-4" /> | ||||||
) : null} | ||||||
</button> | ||||||
)} | ||||||
</Menu.Item> | ||||||
))} | ||||||
</div> | ||||||
</Menu.Items> | ||||||
</Transition> | ||||||
</Menu> | ||||||
); | ||||||
const handleMenuStateChange = (open: boolean) => { | ||||||
if (isFirstClick) { | ||||||
setMenuOpen(true); // Keep the dropdown open on the first click | ||||||
return; | ||||||
} | ||||||
|
||||||
// If the menu is closed, reset the isFirstClick state | ||||||
if (!open) { | ||||||
setIsFirstClick(false); | ||||||
setMenuOpen(false); // Ensure the dropdown is closed | ||||||
} else { | ||||||
setMenuOpen(true); // Open the dropdown | ||||||
} | ||||||
}; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No needed. same as above |
||||||
return ( | ||||||
<Select open={menuOpen} onOpenChange={handleMenuStateChange}> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
<SelectTrigger className="inline-flex w-full justify-between items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-400 font-light shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue text-base"> | ||||||
<SelectValue placeholder={option}/> | ||||||
</SelectTrigger> | ||||||
<SelectContent> | ||||||
{options.map((optionItem) => ( | ||||||
<button | ||||||
onClick={() => { | ||||||
setOption(optionItem) | ||||||
setMenuOpen(false) | ||||||
}} | ||||||
className={cn( | ||||||
option === optionItem ? "bg-gray-200" : "hover:bg-gray-100", | ||||||
"px-4 py-2 text-sm w-full text-left flex items-center space-x-2 justify-between", | ||||||
)} | ||||||
> | ||||||
<span>{optionItem}</span> | ||||||
{option === optionItem ? ( | ||||||
<CheckIcon className="w-4 h-4 text-bold" /> | ||||||
) : null} | ||||||
</button> | ||||||
))} | ||||||
</SelectContent> | ||||||
</Select> | ||||||
) | ||||||
} | ||||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a
select
component from shadcn not a popover.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay will make the changes