Fix more outdated blue color referencespull/29/head
@ -0,0 +1,84 @@ |
||||
import { Menu, Popover, Transition } from '@headlessui/react'; |
||||
import { Fragment, ReactElement, ReactNode } from 'react'; |
||||
|
||||
interface MenuProps { |
||||
buttonContent: ReactNode; |
||||
buttonClasses?: string; |
||||
buttonTitle?: string; |
||||
menuItems: ReactNode[]; |
||||
menuClasses?: string; |
||||
} |
||||
|
||||
// Uses Headless menu, which auto-closes on any item click
|
||||
export function DropdownMenu({ |
||||
buttonContent, |
||||
buttonClasses, |
||||
buttonTitle, |
||||
menuItems, |
||||
menuClasses, |
||||
}: MenuProps) { |
||||
return ( |
||||
<Menu as="div" className="relative"> |
||||
<Menu.Button title={buttonTitle} className={`flex ${buttonClasses}`}> |
||||
{buttonContent} |
||||
</Menu.Button> |
||||
<Transition |
||||
as={Fragment} |
||||
enter="transition ease-out duration-200" |
||||
enterFrom="transform opacity-0 scale-95" |
||||
enterTo="transform opacity-100 scale-100" |
||||
leave="transition ease-in duration-100" |
||||
leaveFrom="transform opacity-100 scale-100" |
||||
leaveTo="transform opacity-0 scale-95" |
||||
> |
||||
<Menu.Items |
||||
className={`z-50 absolute -right-1.5 mt-3 origin-top-right rounded-md bg-white shadow-md drop-shadow-md ring-1 ring-black ring-opacity-5 focus:outline-none ${menuClasses}`} |
||||
> |
||||
{menuItems.map((mi, i) => ( |
||||
<Menu.Item key={`menu-item-${i}`}>{mi}</Menu.Item> |
||||
))} |
||||
</Menu.Items> |
||||
</Transition> |
||||
</Menu> |
||||
); |
||||
} |
||||
|
||||
interface ModalProps { |
||||
buttonContent: ReactNode; |
||||
buttonClasses?: string; |
||||
buttonTitle?: string; |
||||
modalContent: (close: () => void) => ReactElement; |
||||
modalClasses?: string; |
||||
} |
||||
|
||||
// Uses Headless Popover, which is a more general purpose dropdown box
|
||||
export function DropdownModal({ |
||||
buttonContent, |
||||
buttonClasses, |
||||
buttonTitle, |
||||
modalContent, |
||||
modalClasses, |
||||
}: ModalProps) { |
||||
return ( |
||||
<Popover className="relative"> |
||||
<Popover.Button title={buttonTitle} className={`flex ${buttonClasses}`}> |
||||
{buttonContent} |
||||
</Popover.Button> |
||||
<Transition |
||||
as={Fragment} |
||||
enter="transition ease-out duration-200" |
||||
enterFrom="transform opacity-0 scale-95" |
||||
enterTo="transform opacity-100 scale-100" |
||||
leave="transition ease-in duration-100" |
||||
leaveFrom="transform opacity-100 scale-100" |
||||
leaveTo="transform opacity-0 scale-95" |
||||
> |
||||
<Popover.Panel |
||||
className={`z-50 absolute mt-3 origin-top-right rounded-md bg-white shadow-md drop-shadow-md ring-1 ring-black ring-opacity-5 focus:outline-none ${modalClasses}`} |
||||
> |
||||
{({ close }) => modalContent(close)} |
||||
</Popover.Panel> |
||||
</Transition> |
||||
</Popover> |
||||
); |
||||
} |
@ -0,0 +1,64 @@ |
||||
import { Dialog, Transition } from '@headlessui/react'; |
||||
import { Fragment, PropsWithChildren } from 'react'; |
||||
|
||||
import XCircle from '../../images/icons/x-circle.svg'; |
||||
import { IconButton } from '../buttons/IconButton'; |
||||
|
||||
export function Modal({ |
||||
isOpen, |
||||
title, |
||||
close, |
||||
width, |
||||
children, |
||||
}: PropsWithChildren<{ isOpen: boolean; title: string; close: () => void; width?: string }>) { |
||||
return ( |
||||
<Transition appear show={isOpen} as={Fragment}> |
||||
<Dialog as="div" className="relative z-30" onClose={close}> |
||||
<Transition.Child |
||||
as={Fragment} |
||||
enter="ease-out duration-300" |
||||
enterFrom="opacity-0" |
||||
enterTo="opacity-100" |
||||
leave="ease-in duration-200" |
||||
leaveFrom="opacity-100" |
||||
leaveTo="opacity-0" |
||||
> |
||||
<div className="fixed inset-0 bg-black bg-opacity-25" /> |
||||
</Transition.Child> |
||||
|
||||
<div className="fixed inset-0 overflow-y-auto"> |
||||
<div className="flex min-h-full items-center justify-center p-4 text-center"> |
||||
<Transition.Child |
||||
as={Fragment} |
||||
enter="ease-out duration-300" |
||||
enterFrom="opacity-0 scale-95" |
||||
enterTo="opacity-100 scale-100" |
||||
leave="ease-in duration-200" |
||||
leaveFrom="opacity-100 scale-100" |
||||
leaveTo="opacity-0 scale-95" |
||||
> |
||||
<Dialog.Panel |
||||
className={`w-full ${ |
||||
width || 'max-w-xs' |
||||
} max-h-[90vh] transform overflow-auto rounded-md bg-white px-4 py-4 text-left shadow-lg transition-all`}
|
||||
> |
||||
<Dialog.Title as="h3" className="text text-gray-700"> |
||||
{title} |
||||
</Dialog.Title> |
||||
{children} |
||||
<div className="absolute right-3 top-3"> |
||||
<IconButton |
||||
imgSrc={XCircle} |
||||
onClick={close} |
||||
title="Close" |
||||
classes="hover:rotate-90" |
||||
/> |
||||
</div> |
||||
</Dialog.Panel> |
||||
</Transition.Child> |
||||
</div> |
||||
</div> |
||||
</Dialog> |
||||
</Transition> |
||||
); |
||||
} |
Before Width: | Height: | Size: 313 B After Width: | Height: | Size: 287 B |
After Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |