Skip to content

Commit

Permalink
fix: add absolute positioning to content modal - CCR-17 (#124)
Browse files Browse the repository at this point in the history
* feat: change key to description

* feat: reverse

* feat: absolute position

* chore: updated story

* feat: content height func

* chore: loki refs

* feat: move modal down for page headers

* fix: match mocks bottom overlay margin

* fix: long title or subtitle

* feat: add locators

* fix: locators

* fix: container overflow

* feat: modal outer frame and header

* feat: closer to completing refactor

* feat: done

* fix: padding

* chore: loki refs

* chore: loki refs

* feat: finally done

* feat: finally

* fix(content modal): scrolling inside (#1)

* chore: update story

* chore: loki refs

Co-authored-by: Vlad Baranchuk <[email protected]>
  • Loading branch information
alkalescent and kuguarpwnz authored Feb 22, 2021
1 parent 6198898 commit 482dad0
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 114 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
84 changes: 49 additions & 35 deletions lib/components/ContentModal/ContentModal.css
Original file line number Diff line number Diff line change
@@ -1,39 +1,21 @@
.overlay {
position: fixed;
top: 0;
right: 0;
top: 54px;
bottom: 0;
left: 0;
background-color: rgba(var(--vds-color-slate-darker), 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: var(--high-importance);
}

.large {
border-radius: 5px;
background-color: var(--vds-color-slate-lightest);
box-shadow: 0 0 4px 1px rgba(var(--vds-color-black), 0.3);
box-sizing: border-box;
width: 1080px;
}

.headerOuter {
padding: 22px 36px 14px 36px;
height: 36px;
display: flex;
justify-content: space-between;
right: 0;
background-color: var(--vds-color-ghosted);
}

.headerInner {
display: flex;
.noOverflow {
overflow: hidden;
}

.title {
margin: 1px 0 9px;
display: flex;
font: var(--vds-font-heading-md);
padding-bottom: 13px;
min-height: 40px;
}

.titleKey {
Expand All @@ -48,14 +30,16 @@
display: flex;
font: var(--vds-font-md);
color: var(--vds-color-slate-darkest);
white-space: nowrap;
overflow: hidden;
}

.subtitleWithIcon {
padding-bottom: 30px;
margin-bottom: 30px;
}

.subtitleWithoutIcon {
padding-bottom: 36px;
margin-bottom: 36px;
}

.headerButtonDisabled {
Expand Down Expand Up @@ -83,19 +67,49 @@
color: var(--vds-color-slate-primary);
}

.body {
padding: 0 36px 36px 36px;
.titleIcon {
padding: 3px 15px 0 0;
}

.content {
.subtitleIcon {
padding-right: 6px;
}

.modal {
display: flex;
flex-direction: column;
position: absolute;
top: 15px;
bottom: 15px;
left: 50%;
transform: translateX(-50%);
background-color: var(--vds-color-slate-lightest);
border-radius: 5px;
box-sizing: border-box;
padding: 22px 36px 36px;
width: 1080px;
min-height: 280px;
}

.header {
display: flex;
justify-content: space-between;
margin-bottom: 14px;
position: relative;
}

.inner {
padding: 0 24px;
border-radius: 3px;
background-color: var(--vds-color-white);
padding: 24px;
}

.titleIcon {
padding: 3px 15px 0 0;
.titles {
padding-top: 24px;
}

.subtitleIcon {
padding-right: 6px;
.content {
display: flex;
flex-direction: column;
overflow: hidden;
}
110 changes: 68 additions & 42 deletions lib/components/ContentModal/ContentModal.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable no-param-reassign */
import React from 'react';
import React, { useLayoutEffect } from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import { usePortal } from '@/helpers';
Expand All @@ -8,73 +7,90 @@ import { Chevron } from '@';
import styles from './ContentModal.css';

const ContentModal = ({
header,
modalHeader,
titleIconName,
title,
subtitleIconName,
subtitle,
children,
onRequestClose,
onRequestBack,
onCloseClick,
onBackClick,
contentHeader,
locators: { MODAL, CLOSE, KEY, VALUE },
render: renderProps,
}) => {
useLayoutEffect(() => {
const { scrollY } = window;
window.scrollTo({ top: 0 });
document.body.classList.add(styles.noOverflow);

return () => {
window.scrollTo({ top: scrollY });
document.body.classList.remove(styles.noOverflow);
};
}, []);
const reconcileIcon = (name) => name && Icon.NAMES[name] === name && <Icon name={name} />;
const TitleIcon = reconcileIcon(titleIconName);
const SubtitleIcon = reconcileIcon(subtitleIconName);
return usePortal(
<div className={styles.overlay}>
<div className={styles.large}>
<div className={styles.headerOuter}>
<section className={cn(styles.modal, MODAL)}>
<header className={styles.header}>
<div className={styles.backButton}>
<button
type="button"
className={cn(
styles.headerButtonDefault,
onRequestBack ? styles.headerButtonEnabled : styles.headerButtonDisabled,
onBackClick ? styles.headerButtonEnabled : styles.headerButtonDisabled,
)}
disabled={!onRequestBack}
onClick={onRequestBack}
disabled={!onBackClick}
onClick={onBackClick}
>
<Chevron variant={Chevron.VARIANT.THICKER} direction={Chevron.DIRECTION.LEFT} />
</button>
</div>
<div className={styles.headerInner}> {header} </div>
{modalHeader}
<div>
<button
type="button"
className={cn(
styles.headerButtonDefault,
onRequestClose ? styles.headerButtonEnabled : styles.headerButtonDisabled,
onCloseClick ? styles.headerButtonEnabled : styles.headerButtonDisabled,
CLOSE,
)}
onClick={onRequestClose}
onClick={onCloseClick}
>
</button>
</div>
</header>
<div className={cn(styles.titles, styles.inner)}>
{title && (
<div className={styles.title}>
{TitleIcon && <div className={styles.titleIcon}>{TitleIcon}</div>}
{title.key && <div className={cn(styles.titleKey, KEY)}> {title.key}:&nbsp;</div>}
<div className={cn(styles.titleValue, VALUE)}> {title.value} </div>
</div>
)}
{subtitle && (
<div
className={cn(
styles.subtitleDefault,
SubtitleIcon ? styles.subtitleWithIcon : styles.subtitleWithoutIcon,
)}
>
{SubtitleIcon && <div className={styles.subtitleIcon}>{SubtitleIcon}</div>}
{subtitle}
</div>
)}
</div>
<div className={styles.body}>
<div className={styles.content}>
{title && (
<div className={styles.title}>
{TitleIcon && <div className={styles.titleIcon}>{TitleIcon}</div>}
{title.key && <div className={styles.titleKey}> {title.key}:&nbsp;</div>}
<div className={styles.titleValue}> {title.value} </div>
</div>
)}
{subtitle && (
<div
className={cn(
styles.subtitleDefault,
SubtitleIcon ? styles.subtitleWithIcon : styles.subtitleWithoutIcon,
)}
>
{SubtitleIcon && <div className={styles.subtitleIcon}>{SubtitleIcon}</div>}
{subtitle}
</div>
)}
{children}
</div>
</div>
</div>
{renderProps(
<>
<div className={styles.inner}>{contentHeader}</div>
<div className={cn(styles.content, styles.inner)}>{children}</div>
</>,
)}
</section>
</div>,
);
};
Expand All @@ -89,19 +105,29 @@ ContentModal.propTypes = {
subtitleIconName: PropTypes.oneOf(Object.values(Icon.NAMES)),
subtitle: PropTypes.string,
children: PropTypes.node,
onRequestClose: PropTypes.func,
onRequestBack: PropTypes.func,
onCloseClick: PropTypes.func,
onBackClick: PropTypes.func,
locators: PropTypes.shape({
CLOSE: PropTypes.string,
MODAL: PropTypes.string,
KEY: PropTypes.string,
VALUE: PropTypes.string,
}),
render: PropTypes.func,
};

ContentModal.defaultProps = {
header: null,
modalHeader: null,
contentHeader: null,
title: null,
titleIconName: '',
subtitleIconName: '',
subtitle: '',
children: null,
onRequestClose: null,
onRequestBack: null,
onCloseClick: null,
onBackClick: null,
locators: { CLOSE: '', MODAL: '', KEY: '', VALUE: '' },
render: (x) => x,
};

export default Object.assign(ContentModal);
15 changes: 15 additions & 0 deletions lib/components/Tabs/Tabs.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,18 @@
.container :global(.react-tabs__tab:focus) {
outline: none;
}

.scrollable {
overflow: hidden;
}

.scrollable :global(.react-tabs) {
display: flex;
flex-direction: column;
}

.scrollable :global(.react-tabs__tab-panel) {
display: flex;
flex-direction: column;
overflow: hidden;
}
9 changes: 7 additions & 2 deletions lib/components/Tabs/Tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ const sizeClasses = {
* @prop {Node} children
* @returns {*}
*/
const Tabs = ({ size, children, ...tabsProps }) => {
const Tabs = ({ size, children, scrollable, ...tabsProps }) => {
return (
<div className={cn(sizeClasses[size], styles.container)}>
<div className={cn(sizeClasses[size], styles.container, { [styles.scrollable]: scrollable })}>
<TabsContainer {...tabsProps}>{children}</TabsContainer>
</div>
);
Expand All @@ -33,6 +33,11 @@ const Tabs = ({ size, children, ...tabsProps }) => {
Tabs.propTypes = {
size: PropTypes.oneOf(Object.values(SIZE)).isRequired,
children: PropTypes.node.isRequired,
scrollable: PropTypes.bool,
};

Tabs.defaultProps = {
scrollable: false,
};

export default Object.assign(Tabs, { SIZE });
Expand Down
Loading

0 comments on commit 482dad0

Please sign in to comment.