All files / components/ButtonsAndLinks/DropdownButton DropdownButton.tsx

100% Statements 8/8
100% Branches 4/4
100% Functions 5/5
100% Lines 8/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65                                        25x 76x   76x             2x         15x                     69x           9x 9x                      
import { useState } from 'react'
import { Button, ButtonProps } from '../Button/Button'
 
export type DropdownButtonProps = {
	/** Button Text. */
	children: React.ReactNode
	/** Button Props. */
	buttonProps?: Omit<ButtonProps, 'children'>
	/** Dropdown Options. */
	options: {
		onClick: () => void
		label: string
	}[]
	/** For testing. */
	datacy?: string
}
 
/**
 * Button with a dropdown menu which can be used without formik.
 */
export const DropdownButton: React.FC<DropdownButtonProps> = ({ datacy, children, options, buttonProps }) => {
	const [isOpen, setIsOpen] = useState(false)
 
	return (
		<div className="relative mb-2 md:mb-4">
			{/* When dropdown open click outside close it. */}
			{isOpen && (
				<div
					className="fixed inset-0 z-10 h-full w-full cursor-pointer"
					aria-hidden="true"
					onClick={() => setIsOpen(false)}
				></div>
			)}
 
			{/* Input */}
			<Button type="button" datacy={datacy} className="relative" {...buttonProps} onClick={() => setIsOpen(true)}>
				{children}
			</Button>
 
			{/* Options */}
			{isOpen && (
				<div
					className="absolute z-10 mt-1 w-max rounded-xl bg-white py-2 shadow-[-10px_10px_10px_rgba(203,210,217,0.10),10px_10px_10px_rgba(203,210,217,0.10)]"
					tabIndex={-1}
				>
					{options.map((option, index) => (
						<button
							datacy={`dropdownbutton-option-${index}`}
							type="button"
							className="flex w-full items-center px-5 py-2 text-gray-700 hover:text-black"
							key={option.label}
							onClick={() => {
								setIsOpen(false)
								option.onClick()
							}}
						>
							<span className="truncate pr-1">{option.label}</span>
						</button>
					))}
				</div>
			)}
		</div>
	)
}