All files / Components DropDownButton.js

100% Statements 19/19
100% Branches 3/3
100% Functions 6/6
100% Lines 18/18

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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87            1x               6x   6x 6x 3x     6x 2x     6x 1x 1x     6x                             6x   12x 12x           6x   6x                                       1x         1x          
import React, { useEffect, useState } from 'react';
import PropsTypes from 'prop-types';
import classNames from 'classnames';
 
import Button from './Button';
 
const DropDownButton = props => {
    const {
        show,
        text,
        origin,
        buttonClassNames,
        dropClassNames,
        ...rest
    } = props;
 
    const [open, setOpen] = useState(show);
    useEffect((show) => {
        setOpen(show)
    }, [show]);
 
    const toggle = () => {
        setOpen(!open);
    }
 
    const close = action => {
        action();
        setOpen(false);
    }
 
    const dropClass = classNames(
        `origin-top-${origin}`,
        'absolute',
        `${origin}-0`,
        'w-56',
        'bg-white',
        'dark:bg-gray-700',
        'shadow-lg',
        'ring-1',
        'ring-black',
        'ring-opacity-5',
        'z-20',
        dropClassNames,
    );
 
    const childrenWithClose = React.Children.map(props.children, child => {
        /* istanbul ignore else */
        if (React.isValidElement(child)) {
            return React.cloneElement(child, { onClick: () => close(child.props.onClick) });
        }
        /* istanbul ignore next */
        return child;
    });
 
    const id = `options-menu-${Math.floor(Math.random() * 1000)}`;
 
    return (
        <div className="relative">
            <Button className={buttonClassNames} {...rest}
                id={id} aria-haspopup="true" aria-expanded="false" onClick={toggle}>
                {text}
            </Button>
            {
                (open)
                    ? (
                        <div className={dropClass}>
                            <div className="py-1 flex flex-col" role="menu" aria-orientation="vertical" aria-labelledby={id}>
                                {childrenWithClose}
                            </div>
                        </div>
                    ) : null
            }
        </div>
    )
}
 
DropDownButton.propTypes = {
    text: PropsTypes.oneOfType([PropsTypes.string, PropsTypes.object]),
    origin: PropsTypes.oneOf(['right', 'left']),
}
 
DropDownButton.defaultProps = {
    origin: 'right',
}
 
export default DropDownButton;