-
Notifications
You must be signed in to change notification settings - Fork 148
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ea7827b
commit e4eeba9
Showing
7 changed files
with
193 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import React from 'react' | ||
import { mount } from 'enzyme' | ||
import Dropdown from '../src/Dropdown' | ||
|
||
describe('Dropdown', () => { | ||
it('should render without crashing', () => { | ||
const onClose = jest.fn() | ||
mount(<Dropdown isOpen={true} onClose={onClose} />) | ||
}) | ||
|
||
it('should render with base styles', () => { | ||
const onClose = jest.fn() | ||
const expected = | ||
'absolute right-0 w-56 p-2 mt-2 text-gray-600 bg-white border border-gray-100 rounded-lg shadow-md min-w-max-content dark:text-gray-300 dark:border-gray-700 dark:bg-gray-700' | ||
const wrapper = mount(<Dropdown isOpen={true} onClose={onClose} />) | ||
|
||
expect(wrapper.find('ul').getDOMNode().getAttribute('class')).toContain(expected) | ||
}) | ||
|
||
it('should call onClose when Esc is pressed', () => { | ||
const map = {} | ||
document.addEventListener = jest.fn((e, cb) => { | ||
map[e] = cb | ||
}) | ||
const onClose = jest.fn() | ||
mount(<Dropdown isOpen={true} onClose={onClose} />) | ||
|
||
map.keydown({ key: 'Esc' }) | ||
|
||
expect(onClose).toHaveBeenCalled() | ||
}) | ||
|
||
it('should not call onClose when other key than Esc is pressed', () => { | ||
const map = {} | ||
document.addEventListener = jest.fn((e, cb) => { | ||
map[e] = cb | ||
}) | ||
const onClose = jest.fn() | ||
mount(<Dropdown isOpen={true} onClose={onClose} />) | ||
|
||
map.keydown({ key: 'Enter' }) | ||
|
||
expect(onClose).not.toHaveBeenCalled() | ||
}) | ||
|
||
it('should remove the event listener on unmount', () => { | ||
const map = {} | ||
const removeListener = jest.fn((e, cb) => { | ||
map[e] = cb | ||
}) | ||
document.removeEventListener = removeListener | ||
const onClose = jest.fn() | ||
const wrapper = mount(<Dropdown isOpen={true} onClose={onClose} />) | ||
|
||
wrapper.unmount() | ||
|
||
expect(removeListener).toHaveBeenCalled() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import React from 'react' | ||
import { mount } from 'enzyme' | ||
import DropdownItem from '../src/DropdownItem' | ||
import Button from '../src/Button' | ||
|
||
describe('DropdownItem', () => { | ||
it('should render without crashing', () => { | ||
mount(<DropdownItem />) | ||
}) | ||
|
||
it('should render with base styles', () => { | ||
const expected = 'mb-2 last:mb-0' | ||
const wrapper = mount(<DropdownItem />) | ||
|
||
expect(wrapper.find('li').getDOMNode().getAttribute('class')).toContain(expected) | ||
}) | ||
|
||
it('should contain a Button child', () => { | ||
const wrapper = mount(<DropdownItem />) | ||
|
||
expect(wrapper.find(Button)).toBeTruthy() | ||
}) | ||
|
||
it('should pass className to the inner button', () => { | ||
const expected = 'bg-red-600' | ||
const wrapper = mount(<DropdownItem className="bg-red-600" />) | ||
|
||
expect(wrapper.find(Button).getDOMNode().getAttribute('class')).toContain(expected) | ||
}) | ||
|
||
it('should pass extra props to the inner button', () => { | ||
const expected = 'test' | ||
const wrapper = mount(<DropdownItem tag="a" href="test" />) | ||
|
||
expect(wrapper.find('a').getDOMNode().getAttribute('href')).toContain(expected) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import React, { useEffect, useContext } from 'react' | ||
import classNames from 'classnames' | ||
import PropTypes from 'prop-types' | ||
import { ThemeContext } from './context/ThemeContext' | ||
import defaultTheme from './themes/default' | ||
import Transition from './Transition' | ||
import FocusLock from 'react-focus-lock' | ||
|
||
function Dropdown({ children, onClose, isOpen, className, ...other }) { | ||
const { dropdown } = useContext(ThemeContext) || defaultTheme | ||
|
||
const baseStyle = dropdown.base | ||
|
||
function handleEsc(e) { | ||
if (e.key === 'Esc' || e.key === 'Escape') { | ||
onClose() | ||
} | ||
} | ||
|
||
useEffect(() => { | ||
document.addEventListener('keydown', handleEsc) | ||
return () => { | ||
document.removeEventListener('keydown', handleEsc) | ||
} | ||
}) | ||
|
||
const cls = classNames(baseStyle, className) | ||
|
||
return ( | ||
<Transition | ||
show={isOpen} | ||
leave="transition ease-out duration-150" | ||
leaveFrom="opacity-100" | ||
leaveTo="opacity-0" | ||
> | ||
<div> | ||
<FocusLock returnFocus> | ||
<ul className={cls} aria-label="submenu" {...other}> | ||
{children} | ||
</ul> | ||
</FocusLock> | ||
</div> | ||
</Transition> | ||
) | ||
} | ||
|
||
Dropdown.propTypes = { | ||
children: PropTypes.node, | ||
className: PropTypes.string, | ||
onClose: PropTypes.func.isRequired, | ||
isOpen: PropTypes.bool.isRequired, | ||
} | ||
|
||
export default Dropdown |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import React, { useContext } from 'react' | ||
import PropTypes from 'prop-types' | ||
import { ThemeContext } from './context/ThemeContext' | ||
import defaultTheme from './themes/default' | ||
import Button from './Button' | ||
|
||
const DropdownItem = React.forwardRef(function DropdownItem(props, ref) { | ||
// Note: className is passed to the inner Button | ||
const { className, children, ...other } = props | ||
|
||
const { dropdownItem } = useContext(ThemeContext) || defaultTheme | ||
|
||
const baseStyle = dropdownItem.base | ||
|
||
return ( | ||
<li className={baseStyle}> | ||
<Button layout="__dropdownItem" ref={ref} className={className} {...other}> | ||
{children} | ||
</Button> | ||
</li> | ||
) | ||
}) | ||
|
||
DropdownItem.propTypes = { | ||
children: PropTypes.node, | ||
className: PropTypes.string, | ||
} | ||
|
||
export default DropdownItem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters