Skip to content

Commit 714d995

Browse files
committed
Ads Modal component
This is same as v0.7.7, but without PWA-changes that can be dangerous for the current community-app version.
1 parent 1dca5c9 commit 714d995

File tree

9 files changed

+184
-22
lines changed

9 files changed

+184
-22
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Topcoder React Utils Changelog
22

3+
### v0.7.7
4+
- Adds [**`Modal`**](docs/modal.md) component.
5+
36
### v0.7.2
47
Fix of `<Link>` and `<NavLink>` logic.
58

README.md

+21-20
Original file line numberDiff line numberDiff line change
@@ -43,53 +43,54 @@ $ ./node_modules/.bin/topcoder-lib-setup
4343

4444
## Reference
4545
### Configurations
46-
- [**Babel Configurations**](docs/babel-config.md) &mdash; Standard
46+
- [**Babel Configurations**](docs/babel-config.md) &ndash; Standard
4747
configurations for [Babel](https://babeljs.io/);
48-
- [**ESLint Configurations**](docs/eslint-config.md) &mdash; Standard
48+
- [**ESLint Configurations**](docs/eslint-config.md) &ndash; Standard
4949
configurations for [ESLint](https://eslint.org/);
50-
- [**Jest Configurations**](docs/jest-config.md) &mdash; Standard configurations
50+
- [**Jest Configurations**](docs/jest-config.md) &ndash; Standard configurations
5151
for [Jest](https://facebook.github.io/jest/);
52-
- [**Stylelint Configurations**](docs/stylelint-config.md) &mdash; Standard
52+
- [**Stylelint Configurations**](docs/stylelint-config.md) &ndash; Standard
5353
configurations for [Stylelint](https://stylelint.io)
54-
- [**Webpack Configurations**](docs/webpack-config.md) &mdash; Standard
54+
- [**Webpack Configurations**](docs/webpack-config.md) &ndash; Standard
5555
configurations for [Webpack](https://webpack.js.org/).
5656

5757
### Components
58-
- [**`Avatar`**](docs/avatar.md) &mdash; The standard component for user avatars;
59-
- [**`Button`**](docs/button.md) &mdash; Handles buttons and button-like links
58+
- [**`Avatar`**](docs/avatar.md) &ndash; The standard component for user avatars;
59+
- [**`Button`**](docs/button.md) &ndash; Handles buttons and button-like links
6060
(components that look like regular buttons, but behave as links) in the same
6161
uniform manner;
62-
- [**`Link` and `NavLink`**](docs/link-and-navlink.md) &mdash; Auxiliary wrappers
62+
- [**`Link` and `NavLink`**](docs/link-and-navlink.md) &ndash; Auxiliary wrappers
6363
around [React Router](https://github.com/ReactTraining/react-router)'s `<Link>`
6464
and `<NavLink>` components; they help to handle external and internal links in
6565
the same uniform manner;
66-
- [**`ScalableRect`**](docs/scalable-rect.md) &mdash; Container that keeps
66+
- [**`Modal`**](docs/modal.md) &ndash; Themeable modal component;
67+
- [**`ScalableRect`**](docs/scalable-rect.md) &ndash; Container that keeps
6768
the specified aspect ratio regardless the width you set.
6869

6970
### NodeJS Scripts
70-
- [**topcoder-lib-setup**](docs/topcoder-lib-setup-script.md) &mdash; Helps to
71+
- [**topcoder-lib-setup**](docs/topcoder-lib-setup-script.md) &ndash; Helps to
7172
install and upgrade **topcoder-react-utils** and other similar libraries.
7273

7374
### Redux Templates
74-
- [**Item**](docs/redux-item.md) &mdash; An async piece of data in Redux store.
75+
- [**Item**](docs/redux-item.md) &ndash; An async piece of data in Redux store.
7576

7677
### Utilities
77-
- [**Client**](docs/client.md) &mdash; Client-side initialization code.
78-
- [**Config**](docs/config.md) &mdash; Isomorphic app config;
79-
- [**Global Styles**](docs/global-styles.md) &mdash; Global styles necessary for
78+
- [**Client**](docs/client.md) &ndash; Client-side initialization code.
79+
- [**Config**](docs/config.md) &ndash; Isomorphic app config;
80+
- [**Global Styles**](docs/global-styles.md) &ndash; Global styles necessary for
8081
a generic application;
81-
- [**Isomorphy**](docs/isomorphy-utils.md) &mdash; Collection of helpers to deal
82+
- [**Isomorphy**](docs/isomorphy-utils.md) &ndash; Collection of helpers to deal
8283
with isomorphic aspects of the code;
83-
- [**Jest utils**](docs/jest-utils.md) &mdash; Collection of helpers to be used
84+
- [**Jest utils**](docs/jest-utils.md) &ndash; Collection of helpers to be used
8485
in Jest tests code;
85-
- [**Redux utils**](docs/redux-utils.md) &mdash; *TO BE DOCUMENTED*
86-
- [**SCSS Mixins**](docs/scss-mixins.md) &mdash; Collection of useful style
86+
- [**Redux utils**](docs/redux-utils.md) &ndash; *TO BE DOCUMENTED*
87+
- [**SCSS Mixins**](docs/scss-mixins.md) &ndash; Collection of useful style
8788
mixins;
88-
- [**Server**](docs/server.md) &mdash; Easy creation and launch of web-server
89+
- [**Server**](docs/server.md) &ndash; Easy creation and launch of web-server
8990
with standard configuration, that serves a ReactJS application with or without
9091
server-side rendering, supports development tools (Hop Module Reloading), and
9192
can be further configured for the needs of specific projects.
92-
- [**Webpack**](docs/webpack-utils.md) &mdash; Various utils related to the
93+
- [**Webpack**](docs/webpack-utils.md) &ndash; Various utils related to the
9394
Webpack bundling process.
9495

9596
## Development

__tests__/__snapshots__/index.js.snap

+4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ exports[`Export at client side 1`] = `
44
Object {
55
"AppChunk": [Function],
66
"Avatar": [Function],
7+
"BaseModal": [Function],
78
"Button": [Function],
89
"DevTools": [Function],
910
"JU": null,
1011
"Link": [Function],
1112
"MetaTags": [Function],
13+
"Modal": [Function],
1214
"NavLink": [Function],
1315
"ScalableRect": [Function],
1416
"actions": Object {
@@ -64,6 +66,7 @@ exports[`Export at server side 1`] = `
6466
Object {
6567
"AppChunk": [Function],
6668
"Avatar": [Function],
69+
"BaseModal": [Function],
6770
"Button": [Function],
6871
"DevTools": [Function],
6972
"JU": Object {
@@ -162,6 +165,7 @@ Object {
162165
},
163166
"Link": [Function],
164167
"MetaTags": [Function],
168+
"Modal": [Function],
165169
"NavLink": [Function],
166170
"ScalableRect": [Function],
167171
"actions": Object {

docs/modal.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Modal
2+
3+
Implements a simple themeable modal window.
4+
5+
*TODO: This is a raw description of the component, should be improved*
6+
7+
**topcoder-react-utils** exports two versions of the modal component,
8+
`BaseModal` implements a non-themed version, and `Modal` is its version
9+
wrapped into a default style, using `react-css-super-themr` lib.
10+
11+
### Props
12+
13+
Both **BaseModal** and **Modal** components accept:
14+
15+
| Prop | Type | Default | Description |
16+
| --- | --- | --- | --- |
17+
| children | ReactJS Node | `null` | Modal content to render.|
18+
| onCancel | `Function` | `noop` | Callback to trigger when the modal is closed. |
19+
20+
**BaseModal** accepts additionally _theme_ prop, which should be an object,
21+
and defaults to `{}`. Theme object may have the following fields:
22+
23+
| Field | Description |
24+
| --- | --- |
25+
| container | CSS class to apply to the **BaseModal** root container. |
26+
| overlay | CSS class to apply to the overlay opened behind the **BaseModal** |
27+

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,5 @@
121121
"mkDistDir:prod": "mkdir -p dist/prod/shared/utils && mkdir -p dist/prod/client",
122122
"test": "npm run lint && npm run jest"
123123
},
124-
"version": "0.7.5"
124+
"version": "0.7.5.1"
125125
}

src/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import client from 'client';
88
import DevTools from 'components/DevTools';
99
import Link from 'components/Link';
1010
import MetaTags from 'components/MetaTags';
11+
import Modal, { BaseModal } from 'components/Modal';
1112
import NavLink from 'components/NavLink';
1213
import reducers from 'reducers';
1314
import ScalableRect from 'components/ScalableRect';
@@ -24,12 +25,14 @@ module.exports = {
2425
actions,
2526
AppChunk,
2627
Avatar,
28+
BaseModal,
2729
Button,
2830
client,
2931
DevTools,
3032
Link,
3133
NavLink,
3234
MetaTags,
35+
Modal,
3336
ScalableRect,
3437
reducers,
3538
server,

src/shared/components/Modal/index.jsx

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* This generic component will implement the semi-transparent background
3+
* and the white window in the center, which wraps the content provided as
4+
* children.
5+
*
6+
* When semi-transparent background is clicked, it should trigger the onCancel()
7+
* callback passed from the parent.
8+
*/
9+
10+
/* global document */
11+
12+
import _ from 'lodash';
13+
import React from 'react';
14+
import ReactDom from 'react-dom';
15+
import PT from 'prop-types';
16+
import { themr } from 'react-css-super-themr';
17+
18+
import defaultStyle from './style.scss';
19+
20+
/* NOTE: Modal component is implemented as class, as it demands advanced
21+
* interaction with DOM upon mount and unmount. */
22+
class Modal extends React.Component {
23+
constructor(props) {
24+
super(props);
25+
this.portal = document.createElement('div');
26+
}
27+
28+
componentDidMount() {
29+
document.body.classList.add('scrolling-disabled-by-modal');
30+
document.body.appendChild(this.portal);
31+
}
32+
33+
componentWillUnmount() {
34+
document.body.classList.remove('scrolling-disabled-by-modal');
35+
document.body.removeChild(this.portal);
36+
}
37+
38+
render() {
39+
const {
40+
children,
41+
onCancel,
42+
theme,
43+
} = this.props;
44+
return ReactDom.createPortal(
45+
(
46+
<React.Fragment>
47+
<div
48+
className={theme.container}
49+
onWheel={event => event.stopPropagation()}
50+
>
51+
{children}
52+
</div>
53+
<button
54+
onClick={() => onCancel()}
55+
className={theme.overlay}
56+
type="button"
57+
/>
58+
</React.Fragment>
59+
),
60+
this.portal,
61+
);
62+
}
63+
}
64+
65+
Modal.defaultProps = {
66+
onCancel: _.noop,
67+
children: null,
68+
theme: {},
69+
};
70+
71+
Modal.propTypes = {
72+
onCancel: PT.func,
73+
children: PT.node,
74+
theme: PT.shape(),
75+
};
76+
77+
/* Non-themed version of the Modal. */
78+
export const BaseModal = Modal;
79+
80+
export default themr('Modal', defaultStyle)(Modal);
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
@import '~styles/mixins';
2+
3+
:global {
4+
body.scrolling-disabled-by-modal {
5+
overflow: hidden;
6+
}
7+
}
8+
9+
.overlay {
10+
background: #ebebeb;
11+
border: none;
12+
height: 100%;
13+
left: 0;
14+
opacity: 0.8;
15+
outline: none;
16+
position: fixed;
17+
top: 0;
18+
width: 100%;
19+
z-index: 998;
20+
}
21+
22+
.container {
23+
background: #fff;
24+
box-shadow: 0 0 14px 1px rgba(38, 38, 40, 0.15);
25+
border-radius: 4;
26+
max-height: 95vh;
27+
max-width: $screen-md;
28+
overflow: hidden;
29+
padding: 40;
30+
width: 480px;
31+
position: fixed;
32+
top: 50%;
33+
left: 50%;
34+
transform: translate(-50%, -50%);
35+
z-index: 999;
36+
37+
@include xs-to-lg {
38+
max-width: 95vw;
39+
}
40+
41+
@include xs-to-sm {
42+
padding: 40px 10px;
43+
}
44+
}

0 commit comments

Comments
 (0)