Skip to content

Commit

Permalink
Merge pull request #357 from hsource/dismiss-backdrop-click
Browse files Browse the repository at this point in the history
Made clicking on more parts of the backdrop dismiss modal
  • Loading branch information
davwheat authored Mar 21, 2020
2 parents c66321d + 2261155 commit a74c4bc
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 11 deletions.
5 changes: 4 additions & 1 deletion src/components/Carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { type ModalProps } from './Modal/Modal';
import { className, isTouch } from '../utils';
import formatters from '../formatters';
import { type ViewsType } from '../types';
import componentBaseClassNames from './componentBaseClassNames';

type SpringConfig = { [key: string]: number };
export type fn = any => void;
Expand Down Expand Up @@ -87,6 +88,8 @@ const defaultProps = {
},
};

const trackBaseClassName = componentBaseClassNames.Track;

class Carousel extends Component<CarouselProps, CarouselState> {
commonProps: any; // TODO
components: CarouselComponents;
Expand Down Expand Up @@ -381,7 +384,7 @@ class Carousel extends Component<CarouselProps, CarouselState> {
{...this.getTrackProps(this.props)}
style={{ display: 'flex', alignItems: 'center' }}
currentView={currentIndex}
className={className('track')}
className={className(trackBaseClassName)}
onViewChange={this.handleViewChange}
ref={this.getTrack}
>
Expand Down
7 changes: 5 additions & 2 deletions src/components/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { smallDevice } from './css-helpers';
import { Div, Span } from '../primitives';
import type { PropsWithStyles, ViewType } from '../types';
import { className } from '../utils';
import componentBaseClassNames from './componentBaseClassNames';

type State = { isModal: boolean, interactionIsIdle: boolean };
type Props = State &
Expand Down Expand Up @@ -42,6 +43,8 @@ export const footerCSS = ({ isModal, interactionIsIdle }: State) => ({
},
});

const footerBaseClassName = componentBaseClassNames.Footer;

const Footer = (props: Props) => {
const { components, getStyles, innerProps, isFullscreen, isModal } = props;

Expand All @@ -51,12 +54,12 @@ const Footer = (props: Props) => {

const state = { isFullscreen, isModal };
const cn = {
container: className('footer', state),
container: className(footerBaseClassName, state),
caption: className('footer__caption', state),
count: className('footer__count', state),
};
const css = {
container: getStyles('footer', props),
container: getStyles(footerBaseClassName, props),
caption: getStyles('footerCaption', props),
count: getStyles('footerCount', props),
};
Expand Down
7 changes: 5 additions & 2 deletions src/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Button, Div } from '../primitives';
import { className } from '../utils';
import type { PropsWithStyles } from '../types';
import { Close, FullscreenEnter, FullscreenExit } from './svg';
import componentBaseClassNames from './componentBaseClassNames';

type State = { interactionIsIdle: boolean };
type Props = PropsWithStyles &
Expand Down Expand Up @@ -36,6 +37,8 @@ export const headerCSS = ({ interactionIsIdle }: State) => ({
zIndex: 1,
});

const headerBaseClassName = componentBaseClassNames.Header;

const Header = (props: Props) => {
const {
components,
Expand All @@ -61,8 +64,8 @@ const Header = (props: Props) => {

return (
<Div
css={getStyles('header', props)}
className={className('header', state)}
css={getStyles(headerBaseClassName, props)}
className={className(headerBaseClassName, state)}
// TODO glam prefixer fails on gradients
// https://github.com/threepointone/glam/issues/35
style={{
Expand Down
24 changes: 20 additions & 4 deletions src/components/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Fade, SlideUp } from './Animation';
import { type CarouselType } from '../Carousel';
import { defaultModalStyles, type ModalStylesConfig } from '../../styles';
import { isTouch, className } from '../../utils';
import componentBaseClassNames from '../componentBaseClassNames';

type MouseOrKeyboardEvent = MouseEvent | KeyboardEvent;
export type CloseType = (event: MouseOrKeyboardEvent) => void;
Expand Down Expand Up @@ -55,6 +56,17 @@ const defaultProps = {
preventScroll: true,
styles: {},
};

/** Classes that when clicked on, close the backdrop */
const backdropClassNames = new Set(
[
componentBaseClassNames.View,
componentBaseClassNames.Header,
componentBaseClassNames.Footer,
componentBaseClassNames.Track,
].map(className),
);

class Modal extends Component<Props, State> {
commonProps: any; // TODO
components: ModalComponents;
Expand Down Expand Up @@ -106,10 +118,14 @@ class Modal extends Component<Props, State> {
if (allowClose) this.handleClose(event);
};
handleBackdropClick = (event: MouseEvent) => {
if (
!event.target.classList.contains(className('view')) ||
!this.props.closeOnBackdropClick
) {
let hasBackdropClassName = false;
for (const targetClass of event.target.classList) {
if (backdropClassNames.has(targetClass)) {
hasBackdropClassName = true;
}
}

if (!hasBackdropClassName || !this.props.closeOnBackdropClick) {
return;
}

Expand Down
7 changes: 5 additions & 2 deletions src/components/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Div, Img } from '../primitives';
import { type PropsWithStyles } from '../types';
import { className } from '../utils';
import { getSource } from './component-helpers';
import componentBaseClassNames from './componentBaseClassNames';

type Props = PropsWithStyles & {
data: Object,
Expand All @@ -20,6 +21,8 @@ export const viewCSS = () => ({
textAlign: 'center',
});

const viewBaseClassName = componentBaseClassNames.View;

const View = (props: Props) => {
const { data, formatters, getStyles, index, isFullscreen, isModal } = props;
const innerProps = {
Expand All @@ -29,8 +32,8 @@ const View = (props: Props) => {

return (
<Div
css={getStyles('view', props)}
className={className('view', { isFullscreen, isModal })}
css={getStyles(viewBaseClassName, props)}
className={className(viewBaseClassName, { isFullscreen, isModal })}
>
<Img
{...innerProps}
Expand Down
13 changes: 13 additions & 0 deletions src/components/componentBaseClassNames.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Used to get the HTML class to select specific components.
* We call `className()` in utils with each of these to get the full className,
* with prefixes.
*/
const componentBaseClassNames = {
Header: 'header',
Footer: 'footer',
View: 'view',
Track: 'track',
};

export default componentBaseClassNames;

0 comments on commit a74c4bc

Please sign in to comment.