Skip to content

Commit

Permalink
refactor: migrate Modal to styled-components
Browse files Browse the repository at this point in the history
  • Loading branch information
TahimiLeonBravo committed Oct 12, 2019
1 parent 0883ec3 commit 6dce3c5
Show file tree
Hide file tree
Showing 10 changed files with 175 additions and 319 deletions.
5 changes: 3 additions & 2 deletions src/components/Modal/header.js
@@ -1,12 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import StyledHeader from './styled/header';

export default function Header({ title, id }) {
if (typeof title === 'string') {
return (
<header className="rainbow-modal_header">
<StyledHeader>
<h2 id={id}>{title}</h2>
</header>
</StyledHeader>
);
}
return title;
Expand Down
64 changes: 17 additions & 47 deletions src/components/Modal/index.js
@@ -1,17 +1,19 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { createPortal } from 'react-dom';
import classnames from 'classnames';
import RenderIf from './../RenderIf';
import ButtonIcon from './../ButtonIcon';
import { uniqueId } from './../../libs/utils';
import { ESCAPE_KEY, TAB_KEY } from './../../libs/constants';
import Header from './header';
import CloseIcon from './closeIcon';
import manageTab from './manageTab';
import { disableBodyScroll, enableBodyScroll, clearAllBodyScrollLocks } from './scrollController';
import CounterManager from './counterManager';
import './styles.css';
import StyledBackDrop from './styled/backDrop';
import StyledModalContainer from './styled/modalContainer';
import StyledCloseButton from './styled/closeButton';
import StyledContent from './styled/content';
import StyledFooter from './styled/footer';

/**
* Modals are used to display content in a layer above the app.
Expand Down Expand Up @@ -75,34 +77,6 @@ export default class Modal extends Component {
clearAllBodyScrollLocks();
}

getBackDropClassNames() {
const { isOpen } = this.props;
return classnames('rainbow-modal_backdrop', {
'rainbow-modal_backdrop--open': isOpen,
});
}

getContainerClassNames() {
const { className, isOpen } = this.props;
return classnames(
'rainbow-modal',
{
'rainbow-modal--open': isOpen,
'rainbow-modal--close': !isOpen,
},
this.getSizeClassNames(),
className,
);
}

getSizeClassNames() {
const { size } = this.props;
if (size === 'small') {
return null;
}
return `rainbow-modal--${size}`;
}

handleKeyPressed(event) {
event.stopPropagation();
const { isOpen } = this.props;
Expand Down Expand Up @@ -135,30 +109,30 @@ export default class Modal extends Component {
}

render() {
const { title, style, children, footer, isOpen, id } = this.props;
const { title, style, children, footer, isOpen, id, size } = this.props;

if (isOpen) {
return createPortal(
<div
<StyledBackDrop
role="presentation"
isOpen={isOpen}
id={id}
onClick={this.handleClick}
className={this.getBackDropClassNames()}
onKeyDown={this.handleKeyPressed}
>
<section
<StyledModalContainer
role="dialog"
tabIndex={-1}
aria-labelledby={this.modalHeadingId}
aria-modal
aria-hidden={!isOpen}
aria-describedby={this.modalContentId}
className={this.getContainerClassNames()}
style={style}
ref={this.modalRef}
isOpen={isOpen}
size={size}
>
<ButtonIcon
className="rainbow-modal_close-button"
<StyledCloseButton
icon={<CloseIcon />}
title="Close"
onClick={this.closeModal}
Expand All @@ -167,19 +141,15 @@ export default class Modal extends Component {

<Header id={this.modalHeadingId} title={title} />

<div
className="rainbow-modal_content"
id={this.modalContentId}
ref={this.contentRef}
>
<StyledContent id={this.modalContentId} ref={this.contentRef}>
{children}
</div>
</StyledContent>

<RenderIf isTrue={!!footer}>
<footer className="rainbow-modal_footer">{footer}</footer>
<StyledFooter>{footer}</StyledFooter>
</RenderIf>
</section>
</div>,
</StyledModalContainer>
</StyledBackDrop>,
document.body,
);
}
Expand Down
28 changes: 28 additions & 0 deletions src/components/Modal/styled/backDrop.js
@@ -0,0 +1,28 @@
import styled from 'styled-components';
import { COLOR_GRAY_TRANSPARENT_2 } from '../../../styles/colors';

const StyledBackDrop = styled.div`
z-index: -1;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
background: ${COLOR_GRAY_TRANSPARENT_2};
display: flex;
justify-content: center;
align-items: center;
position: fixed;
transition: opacity 0.3s linear, z-index 0.3s linear;
${props =>
props.isOpen &&
`
visibility: visible;
z-index: 1000000;
opacity: 1;
`};
`;

export default StyledBackDrop;
11 changes: 11 additions & 0 deletions src/components/Modal/styled/closeButton.js
@@ -0,0 +1,11 @@
import styled from 'styled-components';
import ButtonIcon from '../../ButtonIcon';

const StyledCloseButton = styled(ButtonIcon)`
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 1000002;
`;

export default StyledCloseButton;
11 changes: 11 additions & 0 deletions src/components/Modal/styled/content.js
@@ -0,0 +1,11 @@
import styled from 'styled-components';

const StyledContent = styled.div`
padding: 1rem;
overflow: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
box-sizing: border-box;
`;

export default StyledContent;
11 changes: 11 additions & 0 deletions src/components/Modal/styled/footer.js
@@ -0,0 +1,11 @@
import styled from 'styled-components';
import { COLOR_GRAY_2 } from '../../../styles/colors';

const StyledFooter = styled.footer`
border-top: 0.0625px solid ${COLOR_GRAY_2};
padding: 0.75rem 1rem;
flex-shrink: 0;
display: block;
`;

export default StyledFooter;
14 changes: 14 additions & 0 deletions src/components/Modal/styled/header.js
@@ -0,0 +1,14 @@
import styled from 'styled-components';
import { COLOR_GRAY_4 } from '../../../styles/colors';

const StyledHeader = styled.header`
font-family: 'Lato Light', Arial, sans-serif;
position: relative;
padding: 1rem;
text-align: center;
font-size: 1.5rem;
color: ${COLOR_GRAY_4};
display: block;
`;

export default StyledHeader;
80 changes: 80 additions & 0 deletions src/components/Modal/styled/modalContainer.js
@@ -0,0 +1,80 @@
import styled from 'styled-components';
import { BORDER_RADIUS_1 } from '../../../styles/borderRadius';
import { COLOR_WHITE } from '../../../styles/colors';

const StyledModalContainer = styled.section`
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 55%;
min-width: 18rem;
max-height: 80vh;
min-height: 4rem;
background-color: ${COLOR_WHITE};
border-radius: ${BORDER_RADIUS_1};
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.16);
flex-direction: column;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: normal;
position: relative;
&:focus {
outline: 0;
}
${props =>
props.isOpen &&
`
animation: slide-up-in 0.2s linear;
opacity: 1;
transform: scale(1, 1) translateY(0);
`};
${props =>
!props.isOpen &&
`
animation: slide-down-out 0.2s linear;
opacity: 0;
transform: translateY(50%);
`};
${props => props.size === 'large' && 'width: 85%;'}
${props => props.size === 'medium' && 'width: 70%;'}
@media (min-width: 1240px) {
width: 520px;
${props => props.size === 'large' && 'width: 920px;'}
${props => props.size === 'medium' && 'width: 720px;'}
}
@media (max-width: 800px) {
width: 95%;
}
@keyframes slide-up-in {
0% {
opacity: 0;
transform: scale(0.8, 0.8) translateY(70%);
}
100% {
opacity: 1;
transform: scale(1, 1) translateY(0);
}
}
@keyframes slide-down-out {
0% {
opacity: 1;
transform: translateY(0);
}
100% {
opacity: 0;
transform: translateY(50%);
}
}
`;

export default StyledModalContainer;

0 comments on commit 6dce3c5

Please sign in to comment.