Skip to content

Instantly share code, notes, and snippets.

@ebello
Created May 22, 2020 15:55
Show Gist options
  • Save ebello/c8bac3da3e491f40311641339b038352 to your computer and use it in GitHub Desktop.
Save ebello/c8bac3da3e491f40311641339b038352 to your computer and use it in GitHub Desktop.
Toggle Visibility React
/** @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;
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