Created
May 22, 2020 15:55
-
-
Save ebello/c8bac3da3e491f40311641339b038352 to your computer and use it in GitHub Desktop.
Toggle Visibility React
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
/** @jsx jsx */ | |
import { jsx } from 'theme-ui'; | |
import React, { useState } from 'react'; | |
import PropTypes from 'prop-types'; | |
const ToggleVisibility = ({ trigger, children, initiallyVisible }) => { | |
const [isVisible, setIsVisible] = useState(initiallyVisible); | |
return ( | |
<React.Fragment> | |
<span | |
role="button" | |
tabIndex={0} | |
onClick={() => setIsVisible(!isVisible)} | |
onKeyUp={({ key }) => { | |
if (key === 'Enter') { | |
setIsVisible(!isVisible); | |
} | |
}} | |
sx={{ | |
cursor: 'pointer', | |
}} | |
> | |
{trigger} | |
</span> | |
{isVisible && children} | |
</React.Fragment> | |
); | |
}; | |
ToggleVisibility.propTypes = { | |
trigger: PropTypes.node.isRequired, | |
children: PropTypes.oneOfType([ | |
PropTypes.arrayOf(PropTypes.node), | |
PropTypes.node, | |
]).isRequired, | |
initiallyVisible: PropTypes.bool, | |
}; | |
ToggleVisibility.defaultProps = { | |
initiallyVisible: false, | |
}; | |
export default ToggleVisibility; |
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
import React from 'react'; | |
import { fireEvent } from '@testing-library/react'; | |
import { renderWithProviders } from '../../../test-config/render'; | |
import ToggleVisibility from './toggle-visibility'; | |
describe('ToggleVisibility', () => { | |
it('renders with required elements', () => { | |
const { asFragment } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>}> | |
<span>hidden content</span> | |
</ToggleVisibility>, | |
); | |
expect(asFragment()).toMatchSnapshot(); | |
}); | |
it('renders with optional elements', () => { | |
const { asFragment } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>} initiallyVisible> | |
<span>visible content</span> | |
</ToggleVisibility>, | |
); | |
expect(asFragment()).toMatchSnapshot(); | |
}); | |
it('renders with required elements and trigger clicked', async () => { | |
const { getByText, asFragment } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>}> | |
<span>hidden content</span> | |
</ToggleVisibility>, | |
); | |
const trigger = getByText('trigger'); | |
fireEvent.click(trigger); | |
expect(asFragment()).toMatchSnapshot(); | |
}); | |
it('renders with optional elements and trigger clicked', async () => { | |
const { getByText, asFragment } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>} initiallyVisible> | |
<span>visible content</span> | |
</ToggleVisibility>, | |
); | |
const trigger = getByText('trigger'); | |
fireEvent.click(trigger); | |
expect(asFragment()).toMatchSnapshot(); | |
}); | |
it('shows the hidden content when trigger is clicked', async () => { | |
const { getByText } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>}> | |
<span>hidden content</span> | |
</ToggleVisibility>, | |
); | |
const trigger = getByText('trigger'); | |
fireEvent.click(trigger); | |
expect(getByText('hidden content')).toBeInTheDocument(); | |
}); | |
it('shows the hidden content when trigger is focused and enter key is hit', async () => { | |
const { getByText } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>}> | |
<span>hidden content</span> | |
</ToggleVisibility>, | |
); | |
const trigger = getByText('trigger'); | |
fireEvent.focus(trigger); | |
fireEvent.keyUp(trigger, { key: 'Enter', code: 13 }); | |
expect(getByText('hidden content')).toBeInTheDocument(); | |
}); | |
it('modal closes when close button is clicked', async () => { | |
const { getByText, queryByText } = renderWithProviders( | |
<ToggleVisibility trigger={<span>trigger</span>} initiallyVisible> | |
<span>visible content</span> | |
</ToggleVisibility>, | |
); | |
const trigger = getByText('trigger'); | |
fireEvent.click(trigger); | |
expect(queryByText('visible content')).not.toBeInTheDocument(); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment