Moving close button for Privacy modal to Message

This allow any Message to have a configurable close button. It also
makes the styling more robust
This commit is contained in:
Jeff Avallone 2019-01-19 13:41:42 -05:00
parent f9b34ebd94
commit fcf9a354f4
10 changed files with 83 additions and 87 deletions

View File

@ -16,16 +16,9 @@ exports[`Header closing the Privacy Policy modal 1`] = `
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<LoadNamespace(PrivacyPolicy) />
<button
className="modalClose"
onClick={[Function]}
>
<XSquare
color="currentColor"
size="24"
/>
</button>
<LoadNamespace(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"
@ -95,16 +88,9 @@ exports[`Header closing the Privacy Policy modal 2`] = `
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<LoadNamespace(PrivacyPolicy) />
<button
className="modalClose"
onClick={[Function]}
>
<XSquare
color="currentColor"
size="24"
/>
</button>
<LoadNamespace(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"
@ -174,16 +160,9 @@ exports[`Header opening the Privacy Policy modal 1`] = `
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<LoadNamespace(PrivacyPolicy) />
<button
className="modalClose"
onClick={[Function]}
>
<XSquare
color="currentColor"
size="24"
/>
</button>
<LoadNamespace(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"
@ -253,16 +232,9 @@ exports[`Header rendering 1`] = `
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<LoadNamespace(PrivacyPolicy) />
<button
className="modalClose"
onClick={[Function]}
>
<XSquare
color="currentColor"
size="24"
/>
</button>
<LoadNamespace(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"
@ -332,16 +304,9 @@ exports[`Header rendering with no banner 1`] = `
shouldFocusAfterRender={true}
shouldReturnFocusAfterClose={true}
>
<LoadNamespace(PrivacyPolicy) />
<button
className="modalClose"
onClick={[Function]}
>
<XSquare
color="currentColor"
size="24"
/>
</button>
<LoadNamespace(PrivacyPolicy)
onClose={[Function]}
/>
</Modal>
<header
className="header"

View File

@ -5,7 +5,6 @@ import { Link } from 'gatsby';
import { withNamespaces, Trans } from 'react-i18next';
import GitlabIcon from 'react-feather/dist/icons/gitlab';
import CloseIcon from 'react-feather/dist/icons/x-square';
import LocaleSwitcher from 'components/LocaleSwitcher';
import InstallPrompt from 'components/InstallPrompt';
@ -46,12 +45,7 @@ class Header extends React.PureComponent {
<Modal
isOpen={ showModal }
onRequestClose={ this.handleClose }>
<PrivacyPolicy />
<button
className={ style.modalClose }
onClick={ this.handleClose }>
<CloseIcon />
</button>
<PrivacyPolicy onClose={ this.handleClose } />
</Modal>
<header
className={ style.header }

View File

@ -66,27 +66,3 @@
}
}
}
.modalClose {
position: absolute;
top: 3rem;
right: 2rem;
line-height: 2.8rem;
padding: 1rem;
margin: 0;
border: 0 none;
background: transparent;
color: inherit;
&:hover svg,
&:active svg {
color: var(--color-white);
}
& svg {
display: inline-block;
width: 2.8rem;
height: 2.8rem;
vertical-align: middle;
}
}

View File

@ -21,6 +21,36 @@ exports[`Message rendering 1`] = `
</div>
`;
exports[`Message rendering with a close button 1`] = `
<div
className="message"
>
<div
className="header"
>
<h2>
Testing
</h2>
<button
onClick={[MockFunction]}
>
<XSquare
color="currentColor"
size="24"
/>
Close
</button>
</div>
<div
className="content"
>
<p>
Message content
</p>
</div>
</div>
`;
exports[`Message rendering with icon 1`] = `
<div
className="message"

View File

@ -6,6 +6,7 @@ import style from './style.module.css';
import InfoIcon from 'react-feather/dist/icons/info';
import ErrorIcon from 'react-feather/dist/icons/alert-octagon';
import WarningIcon from 'react-feather/dist/icons/alert-triangle';
import CloseIcon from 'react-feather/dist/icons/x-square';
const iconTypes = {
info: InfoIcon,
@ -23,7 +24,7 @@ const renderIcon = (type, icon) => {
return <Icon />;
};
const Message = ({ type, icon, heading, children }) => (
const Message = ({ type, icon, heading, onClose, children }) => (
<div className={ [
style.message,
type && style[type]
@ -31,6 +32,9 @@ const Message = ({ type, icon, heading, children }) => (
<div className={ style.header }>
{ renderIcon(type, icon) }
<h2>{ heading }</h2>
{ onClose && <button onClick={ onClose }>
<CloseIcon /> Close
</button> }
</div>
<div className={ style.content }>
{ children }
@ -49,6 +53,7 @@ Message.propTypes = {
PropTypes.func
]),
heading: PropTypes.string.isRequired,
onClose: PropTypes.func,
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node

View File

@ -24,6 +24,22 @@
width: 2.8rem;
vertical-align: bottom;
}
& button {
padding: 0;
margin: 0;
border: 0 none;
background: transparent;
color: var(--color-tan);
cursor: pointer;
float: right;
font-size: 0;
&:hover,
&:active {
color: var(--color-white);
}
}
}
.content {
@ -56,7 +72,7 @@
& .header {
background: var(--color-orange);
& svg {
& > svg {
background: var(--color-black);
color: var(--color-orange);
}
@ -68,7 +84,7 @@
background: var(--color-blue);
color: var(--color-white);
& svg {
& > svg {
background: var(--color-white);
color: var(--color-blue);
}

View File

@ -31,4 +31,13 @@ describe('Message', () => {
);
expect(component).toMatchSnapshot();
});
test('rendering with a close button', () => {
const component = shallow(
<Message heading="Testing" onClose={ jest.fn() }>
<p>Message content</p>
</Message>
);
expect(component).toMatchSnapshot();
});
});

View File

@ -3,6 +3,7 @@
exports[`PrivacyPolicy rendering 1`] = `
<Message
heading="TRANSLATE(Privacy Policy)"
onClose={[MockFunction]}
type="info"
>
<WithMergedOptions(TransComponent)

View File

@ -4,8 +4,8 @@ import { withNamespaces, Trans } from 'react-i18next';
import Message from 'components/Message';
export const PrivacyPolicy = ({ t }) => (
<Message type="info" heading={ t('Privacy Policy') }>
export const PrivacyPolicy = ({ t, ...props }) => (
<Message type="info" heading={ t('Privacy Policy') } { ...props }>
<Trans i18nKey="Privacy policy copy">
<p>
Regexper and the tools used to create it are all open source. If you are

View File

@ -7,7 +7,7 @@ import { PrivacyPolicy } from 'components/PrivacyPolicy';
describe('PrivacyPolicy', () => {
test('rendering', () => {
const component = shallow(
<PrivacyPolicy t={ mockT } />
<PrivacyPolicy onClose={ jest.fn() } t={ mockT } />
);
expect(component).toMatchSnapshot();
});