diff --git a/.babelrc b/.babelrc
index b4d1f4c6..06fe9d71 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,4 +1,9 @@
{
"presets": ["@babel/preset-env", "@babel/preset-react"],
- "plugins": ["@babel/plugin-proposal-class-properties"]
+ "plugins": ["@babel/plugin-proposal-class-properties"],
+ "env": {
+ "development": {
+ "compact": false
+ }
+ }
}
\ No newline at end of file
diff --git a/.eslintrc b/.eslintrc
index 98f1037b..a7c29747 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -3,7 +3,12 @@
"extends": "airbnb",
"rules": {
"react/jsx-filename-extension": 0,
- "import/no-extraneous-dependencies": ["error" , { "devDependencies" : true }],
+ "import/no-extraneous-dependencies": [
+ "error",
+ {
+ "devDependencies": true
+ }
+ ],
"jsx-a11y/label-has-for": 0
},
"parserOptions": {
diff --git a/.gitignore b/.gitignore
index e6b340f0..9c490389 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,5 @@ coverage
.nyc_output
/dist
/stats
-/components
\ No newline at end of file
+/components
+/yarn.lock
\ No newline at end of file
diff --git a/lib/autocomplete/index.js b/lib/autocomplete/index.js
index c0d899ee..fd9ee882 100644
--- a/lib/autocomplete/index.js
+++ b/lib/autocomplete/index.js
@@ -185,7 +185,7 @@ class AutoComplete extends Component {
if (
focusedItem
&& ((findNode(this.listRef).scrolldataTop
- + findNode(this.listRef).offsetTop) > focusedItem.offsetTop)
+ + findNode(this.listRef).offsetTop) > focusedItem.offsetTop)
) {
findNode(this.listRef).scrollTop
-= focusedItem.offsetHeight;
@@ -318,8 +318,8 @@ AutoComplete.defaultProps = {
className: '',
labelKey: 'label',
valueKey: 'value',
- onChange: () => {},
- onKeyPress: () => {},
+ onChange: () => { },
+ onKeyPress: () => { },
};
export default themr('CBAutoComplete', defaultTheme)(AutoComplete);
diff --git a/lib/button/index.js b/lib/button/index.js
index 2077a924..04a540a9 100644
--- a/lib/button/index.js
+++ b/lib/button/index.js
@@ -1,3 +1,5 @@
+/* eslint-disable */
+
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
@@ -36,7 +38,7 @@ class Button extends Component {
[theme[`${type}Bordered`]]: bordered,
[theme[`${type}Borderless`]]: borderless,
[theme.iconButton]: iconButton,
- },
+ }
);
let Icon;
@@ -52,7 +54,9 @@ class Button extends Component {
const rootProps = {
...others,
href: !href ? undefined : href,
- className: classnames(theme.buttonWrapper, { [theme.iconButtonWrapper]: iconButton }),
+ className: classnames(theme.buttonWrapper, {
+ [theme.iconButtonWrapper]: iconButton,
+ }),
onMouseUp: this.handleMouseUp,
onMouseLeave: this.handleMouseLeave,
};
@@ -64,10 +68,11 @@ class Button extends Component {
className: classes,
disabled,
};
+
return (
- { icon !== null && }
+ {icon !== null && }
{children}
diff --git a/lib/card/index.js b/lib/card/index.js
index e8091fe8..d4720d9a 100644
--- a/lib/card/index.js
+++ b/lib/card/index.js
@@ -1,3 +1,5 @@
+/* eslint-disable */
+
import React from 'react';
import PropTypes from 'prop-types';
import { themr } from 'react-css-themr';
diff --git a/lib/globals/_theme.scss b/lib/globals/_theme.scss
index 0bf52675..d4d22d07 100644
--- a/lib/globals/_theme.scss
+++ b/lib/globals/_theme.scss
@@ -17,8 +17,9 @@ $input-active-item: rgba(71, 233, 243, 0.2);
$input-bottom-border: #6c757d;
$primary-input-active-border: #47e9f3;
$secondary-input-active-border: #d8d8d8;
-$dropdown-menu-shadow: 1px 1px 1px 2px rgba(233, 226, 226, 0.5), 0 1px 1px 0 rgba(194, 194, 194, 0.5);
-
+$dropdown-menu-shadow: 1px 1px 1px 2px rgba(233, 226, 226, 0.5),
+0 1px 1px 0 rgba(194, 194, 194, 0.5);
+
$orange-yellow: #ffa500;
$bright-cyan: #47e9f3;
$very-light-pink: #d8d8d8;
@@ -55,3 +56,10 @@ $dark-hot-pink-20: rgba(225, 0, 80, 0.2);
$orange-yellow-20: rgba(255, 165, 0, 0.2);
$battleship-grey-20: rgba(108, 117, 125, 0.2);
$dark-hot-pink-50: rgba(225, 0, 80, 0.5);
+
+$shimmer-color-light: #f6f7f8;
+$shimmer-color-dark: #edeef1;
+
+$shadow-light: 0 2px 4px 0 rgba(0, 1, 38, 0.4);
+
+$border-radius-medium: 6px;
\ No newline at end of file
diff --git a/lib/globals/animations.module.scss b/lib/globals/animations.module.scss
index 27889a73..fb13f985 100644
--- a/lib/globals/animations.module.scss
+++ b/lib/globals/animations.module.scss
@@ -1,41 +1,107 @@
@mixin inputFocus() {
- -o-animation-name: animateFocus;
- -moz-animation-name: animateFocus;
- -webkit-animation-name: animateFocus;
- animation-name: animateFocus;
- @keyframes animateFocus {
- 0% {
- width: 0%;
- }
- 100% {
- width: 100%;
- }
+ -o-animation-name: animateFocus;
+ -moz-animation-name: animateFocus;
+ -webkit-animation-name: animateFocus;
+ animation-name: animateFocus;
+ @keyframes animateFocus {
+ 0% {
+ width: 0%;
}
+
+ 100% {
+ width: 100%;
+ }
+ }
}
@mixin zoomIn() {
- -o-animation-name: animateZoom;
- -moz-animation-name: animateZoom;
- -webkit-animation-name: animateZoom;
- animation-name: animateZoom;
- @keyframes animateZoom {
- 0% {
- transform: scale(0.1);
- }
- 100% {
- transform: scale(1);
- }
+ -o-animation-name: animateZoom;
+ -moz-animation-name: animateZoom;
+ -webkit-animation-name: animateZoom;
+ animation-name: animateZoom;
+ @keyframes animateZoom {
+ 0% {
+ transform: scale(0.1);
+ }
+ 100% {
+ transform: scale(1);
}
+ }
}
@mixin sectionEntry($duration) {
- visibility: hidden;
- opacity: 0;
- transform: translate(0, 10px) perspective(200px) rotateX(-2deg);
- &.enabled {
- visibility: visible;
- opacity: 1;
- transition: visibility $duration, opacity $duration, transform $duration;
- transform: translate(0, 0);
+ visibility: hidden;
+ opacity: 0;
+ transform: translate(0, 10px) perspective(200px) rotateX(-2deg);
+
+ &.enabled {
+ visibility: visible;
+ opacity: 1;
+ transition: visibility $duration, opacity $duration, transform $duration;
+ transform: translate(0, 0);
+ }
+}
+
+@mixin lineShimmer($length: 80px, $duration: 1s, $timingFunction: linear) {
+ animation-duration: $duration;
+ animation-fill-mode: forwards;
+ animation-iteration-count: infinite;
+ animation-name: placeholderShimmer;
+ animation-timing-function: $timingFunction;
+
+ -webkit-animation-duration: $duration;
+ -webkit-animation-fill-mode: forwards;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-animation-name: placeholderShimmer;
+ -webkit-animation-timing-function: $timingFunction;
+
+ @keyframes placeholderShimmer {
+ 0% {
+ background-position: -700px 0;
+ }
+ 100% {
+ background-position: 700px 0;
+ }
+ }
+
+ @-webkit-keyframes placeholderShimmer {
+ 0% {
+ background-position: -700px 0;
+ }
+ 100% {
+ background-position: 700px 0;
+ }
+ }
+}
+
+@mixin boxShimmer($length: 80px, $duration: 1s, $timingFunction: linear) {
+ animation-duration: $duration;
+ animation-fill-mode: forwards;
+ animation-iteration-count: infinite;
+ animation-name: boxPlaceholderShimmer;
+ animation-timing-function: $timingFunction;
+
+ -webkit-animation-duration: $duration;
+ -webkit-animation-fill-mode: forwards;
+ -webkit-animation-iteration-count: infinite;
+ -webkit-animation-name: boxPlaceholderShimmer;
+ -webkit-animation-timing-function: $timingFunction;
+
+ @keyframes boxPlaceholderShimmer {
+ 0% {
+ background-position: -80px 0;
+ }
+ 100% {
+ background-position: 80px 0;
+ }
+ }
+
+ @-webkit-keyframes boxPlaceholderShimmer {
+ 0% {
+ background-position: -80px 0;
+ }
+ 100% {
+ background-position: 80px 0;
}
+ }
}
\ No newline at end of file
diff --git a/lib/index.js b/lib/index.js
index b307f158..45f36df1 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -24,3 +24,10 @@ export { default as Carousel } from './carousel';
export { default as ProgressBar } from './progressbar';
export { default as Table } from './table';
export { default as Pagination } from './pagination';
+export {
+ BoxPlaceholder,
+ LinePlaceholder,
+ ParagraphPlaceHolder,
+ CardPlaceholder,
+ ImageCard,
+} from './placeholders';
diff --git a/lib/navbar/index.js b/lib/navbar/index.js
index bc68c1b8..e21ffc93 100644
--- a/lib/navbar/index.js
+++ b/lib/navbar/index.js
@@ -143,7 +143,8 @@ class Navbar extends React.Component {
{leftIcon && (
{React.isValidElement(leftIcon) ? leftIcon :
}
-
)
+
+ )
}
{this.renderLeftContent()}
@@ -152,7 +153,8 @@ class Navbar extends React.Component {
{rightIcon && (
{React.isValidElement(rightIcon) ? rightIcon :
}
-
)
+
+ )
}
diff --git a/lib/placeholders/box/index.js b/lib/placeholders/box/index.js
new file mode 100644
index 00000000..75222a4d
--- /dev/null
+++ b/lib/placeholders/box/index.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+import { themr } from 'react-css-themr';
+
+import '../../globals/fonts.scss';
+import defaultTheme from './theme.module.scss';
+
+const BoxPlaceholder = ({ theme, shape }) => {
+ const classes = classnames(theme.styles, theme.boxStyles, theme[shape]);
+
+ const boxPlaceholderProps = {
+ className: classes,
+ };
+
+ return
;
+};
+
+BoxPlaceholder.propTypes = {
+ theme: PropTypes.shape({}),
+ shape: PropTypes.oneOf(['square', 'circle']),
+};
+
+BoxPlaceholder.defaultProps = {
+ theme: {},
+ shape: 'square',
+};
+
+export default themr('BPLACEHOLDER', defaultTheme)(BoxPlaceholder);
diff --git a/lib/placeholders/box/readMe.md b/lib/placeholders/box/readMe.md
new file mode 100644
index 00000000..2290cb85
--- /dev/null
+++ b/lib/placeholders/box/readMe.md
@@ -0,0 +1,74 @@
+## Box Placeholder
+
+The box placeholder component.
+
+### Properties
+
+| Name | Type | Default | Description |
+| :------ | :------- | :-------- | :---------------------------- |
+| `shape` | `String` | `square` | Prop to set the shape of box. Circle or Square. |
+
+### Theme
+
+| Name | Description |
+| :---------- | :---------------------------------------- |
+| `boxStyles` | Class used for the style the box element. |
+
+### Usage
+
+```
+
+class Demo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ?
:
+
User Content
+
+ )
+ }
+}
+```
+
+
+### You can make custom card placeholder by putting together box and line placeholder.
+
+```
+
+const CustomPlaceholder = () => (
+
+)
+
+class Demo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ?
:
+
User Content
+
+ )
+ }
+}
+```
diff --git a/lib/placeholders/box/tests/accessibility.test.js b/lib/placeholders/box/tests/accessibility.test.js
new file mode 100644
index 00000000..215803ad
--- /dev/null
+++ b/lib/placeholders/box/tests/accessibility.test.js
@@ -0,0 +1,32 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect, assert } from 'chai';
+
+import BoxPlaceholder from '..';
+
+/* eslint-disable no-undef */
+describe('BoxPlaceholder accessibility tests', () => {
+ let wrappedComponent;
+ let expectedValue;
+ let actualValue;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('allows us to set props', () => {
+ expect(wrappedComponent.props().shape).to.equal('circle');
+ wrappedComponent.setProps({ shape: 'square' });
+ expect(wrappedComponent.props().shape).to.equal('square');
+ });
+
+ it('should accept `Shape` prop', () => {
+ expectedValue = 'circle';
+ actualValue = () => wrappedComponent.prop('shape');
+ assert.strictEqual(actualValue(), expectedValue);
+ });
+});
diff --git a/lib/placeholders/box/tests/render.test.js b/lib/placeholders/box/tests/render.test.js
new file mode 100644
index 00000000..f83dc9e8
--- /dev/null
+++ b/lib/placeholders/box/tests/render.test.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import BoxPlaceHolder from '..';
+
+/* eslint-disable no-undef */
+describe('Box placeholder render test', () => {
+ let wrappedComponent;
+ const expectedValue = 1;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('Should render the BoxPlaceholder component', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ it('Should render a `BoxPlaceholder` with defalult `shape`', () => {
+ expect(wrappedComponent.props().shape).to.equal('square');
+ });
+});
diff --git a/lib/placeholders/box/theme.module.scss b/lib/placeholders/box/theme.module.scss
new file mode 100644
index 00000000..d4faba29
--- /dev/null
+++ b/lib/placeholders/box/theme.module.scss
@@ -0,0 +1,29 @@
+@import '../../globals/theme';
+@import '../../globals/animations.module.scss';
+
+:local(.styles) {
+ background: $shimmer-color-light;
+ background-image: linear-gradient(
+ to right,
+ $shimmer-color-light 0%,
+ $shimmer-color-dark 20%,
+ $shimmer-color-light 40%,
+ $shimmer-color-light 100%
+ );
+ background-repeat: no-repeat;
+ // **** change here for height ***
+ // background-size: 800px 80px;
+ display: inline-block;
+ position: relative;
+
+ @include boxShimmer();
+}
+
+:local(.boxStyles) {
+ width: 80px;
+ height: 80px;
+}
+
+:local(.circle) {
+ border-radius: 100px;
+}
diff --git a/lib/placeholders/card/index.js b/lib/placeholders/card/index.js
new file mode 100644
index 00000000..295e18ea
--- /dev/null
+++ b/lib/placeholders/card/index.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { themr } from 'react-css-themr';
+
+import BoxPlaceholder from '../box';
+import LinePlaceholder from '../line';
+import Card from '../../card';
+
+import '../../globals/fonts.scss';
+import defaultTheme from './theme.module.scss';
+
+const CardPlaceholder = ({
+ theme, imageShape, className, wrapContent, elevation, noPadding, cardTheme,
+}) => (
+
+
+
+
+
+
+);
+
+CardPlaceholder.propTypes = {
+ theme: PropTypes.shape({}),
+ imageShape: PropTypes.oneOf(['shape', 'circle']),
+ className: PropTypes.string,
+ cardTheme: PropTypes.shape({
+ card: PropTypes.string,
+ cardHeader: PropTypes.string,
+ }),
+ wrapContent: PropTypes.bool,
+ noPadding: PropTypes.bool,
+ elevation: PropTypes.oneOf(['low', 'medium', 'high']),
+};
+
+CardPlaceholder.defaultProps = {
+ theme: {},
+ imageShape: 'circle',
+ className: null,
+ elevation: 'low',
+ cardTheme: {},
+ wrapContent: false,
+ noPadding: false,
+};
+
+export default themr('CARDPLACEHOLDER', defaultTheme)(CardPlaceholder);
diff --git a/lib/placeholders/card/readMe.md b/lib/placeholders/card/readMe.md
new file mode 100644
index 00000000..c32200ea
--- /dev/null
+++ b/lib/placeholders/card/readMe.md
@@ -0,0 +1,39 @@
+## Card Placeholder
+
+The card placeholder component.
+
+### Properties
+
+| Name | Type | Default | Description |
+| :----------- | :------- | :------- | :------------------------------------------ |
+| `imageShape` | `String` | `circle` | Set the shape of the box in card component. |
+| `className` | `String` | | Additional class(es) for custom styling. These classes will be added along with library specific styles |
+| `wrapContent` | `Boolean` | `false` | If `true` sets the width of the parent card to width of its content else sets width to maximum available width inside its parent |
+| `elevation` | `String` | `low` | This set elevation/depth of shadow of the card. The possible values are `low`, `medium`, `high` |
+| `noPadding` | `Boolean` | `false` | If `true` card container will not give padding by default |
+
+### Theme
+
+| Name | Description |
+| :----------- | :------------------------------- |
+| `imageWrapper` | Controles the flex direction of image box and line. |
+
+### Usage
+
+```
+
+class Demo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ?
:
+ User Content
+
+ )
+ }
+}
+```
diff --git a/lib/placeholders/card/tests/accessibility.test.js b/lib/placeholders/card/tests/accessibility.test.js
new file mode 100644
index 00000000..18a5c91e
--- /dev/null
+++ b/lib/placeholders/card/tests/accessibility.test.js
@@ -0,0 +1,34 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import CardPlaceholder from '..';
+import LinePlaceHolder from '../../line';
+
+/* eslint-disable no-undef */
+describe('CardPlaceholder accessibility tests', () => {
+ let wrappedComponent;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('allows us to set props', () => {
+ expect(wrappedComponent.props().imageShape).to.equal('circle');
+ wrappedComponent.setProps({ imageShape: 'default' });
+ expect(wrappedComponent.props().imageShape).to.equal('default');
+ });
+
+ it('should contain at least 2 `Line Placeholders` ', () => {
+ expect(
+ wrappedComponent.containsAllMatchingElements([
+ ,
+ ,
+ ]),
+ ).to.equal(true);
+ });
+});
diff --git a/lib/placeholders/card/tests/render.test.js b/lib/placeholders/card/tests/render.test.js
new file mode 100644
index 00000000..3a6081b3
--- /dev/null
+++ b/lib/placeholders/card/tests/render.test.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import CardPlaceholder from '..';
+
+/* eslint-disable no-undef */
+describe('CardPlaceholder render tests', () => {
+ let wrappedComponent;
+ const expectedValue = 12;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('Should render the `CardPlaceholder` component', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ it('Should render a `CardPlaceholder` with defalult `shape`', () => {
+ expect(wrappedComponent.props().imageShape).to.equal('circle');
+ });
+});
diff --git a/lib/placeholders/card/theme.module.scss b/lib/placeholders/card/theme.module.scss
new file mode 100644
index 00000000..3e93811a
--- /dev/null
+++ b/lib/placeholders/card/theme.module.scss
@@ -0,0 +1,10 @@
+@import '../../globals/theme';
+
+:local(.imageWrapper) {
+ display: flex;
+ align-items: center;
+}
+
+:local(.gutterSpaceHorizontal) {
+ margin-right: 16px;
+}
diff --git a/lib/placeholders/imageCard/index.js b/lib/placeholders/imageCard/index.js
new file mode 100644
index 00000000..5d6d4a2e
--- /dev/null
+++ b/lib/placeholders/imageCard/index.js
@@ -0,0 +1,41 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+import { themr } from 'react-css-themr';
+
+import LinePlaceHolder from '../line';
+
+import '../../globals/fonts.scss';
+import defaultTheme from './theme.module.scss';
+import BoxPlaceholder from '../box';
+
+const ImageCard = ({ theme, lines, imageShape }) => {
+ const classes = classnames(theme.imageCardStyles);
+
+ const ImageCardProps = {
+ className: classes,
+ };
+
+ return (
+
+
+ {lines.map(line => (
+
+ ))}
+
+ );
+};
+
+ImageCard.propTypes = {
+ theme: PropTypes.shape({}),
+ lines: PropTypes.arrayOf(PropTypes.string),
+ imageShape: PropTypes.oneOf(['default', 'circle']),
+};
+
+ImageCard.defaultProps = {
+ theme: {},
+ lines: ['25', '75', '50', '100'],
+ imageShape: 'circle',
+};
+
+export default themr('ImageCard', defaultTheme)(ImageCard);
diff --git a/lib/placeholders/imageCard/readMe.md b/lib/placeholders/imageCard/readMe.md
new file mode 100644
index 00000000..014a1da0
--- /dev/null
+++ b/lib/placeholders/imageCard/readMe.md
@@ -0,0 +1,40 @@
+## Imagecard Placeholder
+
+The image card placeholder component.
+
+### Properties
+
+| Name | Type | Default | Description |
+| :----------- | :------- | :-------------------------- | :---------------------------------------------- |
+| `imageShape` | `String` | `circle` | Set the shape of the box in card component. |
+| `lines` | `array` | `['25', '75', '50', '100']` | Set the no of lines in card as array of widths. |
+
+### Theme
+
+| Name | Description |
+| :---------------- | :------------------------------- |
+| `imageCardStyles` | Class used for the root element. |
+
+### Usage
+
+```
+
+class Demo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ?
:
+
User Content
+
+ )
+ }
+}
+```
diff --git a/lib/placeholders/imageCard/tests/accessibility.test.js b/lib/placeholders/imageCard/tests/accessibility.test.js
new file mode 100644
index 00000000..6e7806b7
--- /dev/null
+++ b/lib/placeholders/imageCard/tests/accessibility.test.js
@@ -0,0 +1,36 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import ImageCardPlaceholder from '..';
+import LinePlaceHolder from '../../line';
+
+/* eslint-disable no-undef */
+describe('ImageCardPlaceholder accessibility tests', () => {
+ let wrappedComponent;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('allows us to set props', () => {
+ expect(wrappedComponent.props().imageShape).to.equal('circle');
+ wrappedComponent.setProps({ imageShape: 'default' });
+ expect(wrappedComponent.props().imageShape).to.equal('default');
+ });
+
+ it('should contain at least 4 `Line Placeholders` ', () => {
+ expect(
+ wrappedComponent.containsAllMatchingElements([
+ ,
+ ,
+ ,
+ ,
+ ])
+ ).to.equal(true);
+ });
+});
diff --git a/lib/placeholders/imageCard/tests/render.test.js b/lib/placeholders/imageCard/tests/render.test.js
new file mode 100644
index 00000000..a4bf384a
--- /dev/null
+++ b/lib/placeholders/imageCard/tests/render.test.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import ImageCardPlaceholder from '..';
+
+/* eslint-disable no-undef */
+describe('Box placeholder render test', () => {
+ let wrappedComponent;
+ const expectedValue = 6;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('Should render the ImageCardPlaceholder component', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ it('Should render a `ImageCardPlaceholder` with defalult `imageShape`', () => {
+ expect(wrappedComponent.props().imageShape).to.equal('circle');
+ });
+});
diff --git a/lib/placeholders/imageCard/theme.module.scss b/lib/placeholders/imageCard/theme.module.scss
new file mode 100644
index 00000000..08a66856
--- /dev/null
+++ b/lib/placeholders/imageCard/theme.module.scss
@@ -0,0 +1,8 @@
+@import '../../globals/theme';
+
+:local(.imageCardStyles) {
+ padding: 16px;
+
+ width: 200px;
+ height: 200px;
+}
\ No newline at end of file
diff --git a/lib/placeholders/index.js b/lib/placeholders/index.js
new file mode 100644
index 00000000..c8ded68a
--- /dev/null
+++ b/lib/placeholders/index.js
@@ -0,0 +1,13 @@
+import BoxPlaceholder from './box';
+import LinePlaceholder from './line';
+import ParagraphPlaceHolder from './paragraph';
+import CardPlaceholder from './card';
+import ImageCard from './imageCard';
+
+export {
+ BoxPlaceholder,
+ LinePlaceholder,
+ ParagraphPlaceHolder,
+ CardPlaceholder,
+ ImageCard,
+};
diff --git a/lib/placeholders/line/index.js b/lib/placeholders/line/index.js
new file mode 100644
index 00000000..2cea5f21
--- /dev/null
+++ b/lib/placeholders/line/index.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+import { themr } from 'react-css-themr';
+
+import '../../globals/fonts.scss';
+import defaultTheme from './theme.module.scss';
+
+const LinePlaceholder = ({ theme, lineWidth }) => {
+ const classes = classnames(
+ theme.styles,
+ theme.lineStyles,
+ theme[`lineWidth${lineWidth}`]
+ );
+
+ const linePlaceholderProps = {
+ className: classes,
+ };
+
+ return
;
+};
+
+LinePlaceholder.propTypes = {
+ theme: PropTypes.shape({}),
+ lineWidth: PropTypes.string,
+};
+
+LinePlaceholder.defaultProps = { theme: {}, lineWidth: '100' };
+
+export default themr('LPlaceholder', defaultTheme)(LinePlaceholder);
diff --git a/lib/placeholders/line/readMe.md b/lib/placeholders/line/readMe.md
new file mode 100644
index 00000000..bc432a79
--- /dev/null
+++ b/lib/placeholders/line/readMe.md
@@ -0,0 +1,59 @@
+## Line Placeholder
+
+The line placeholder component.
+
+### Properties
+
+| Name | Type | Default | Description |
+| :---------- | :------- | :------ | :------------------------------------------------ |
+| `lineWidth` | `String` | `100` | Set the line width of the from 10 to 100 with step of 10. |
+
+### Theme
+
+| Name | Description |
+| :----------- | :------------------------------- |
+| `lineStyles` | Class used for the root element. |
+
+### Usage
+
+```
+
+class Demo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ?
:
+
User Content
+
+ )
+ }
+}
+```
+
+### You can make a paragraph placeholder by simple wrap line placeholder in a single div.
+
+```
+
+class ParagraphDemo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ? (
+
+
+
+
) :
+
User Content
+
+ )
+ }
+}
+```
diff --git a/lib/placeholders/line/tests/accessibility.test.js b/lib/placeholders/line/tests/accessibility.test.js
new file mode 100644
index 00000000..af3f17b6
--- /dev/null
+++ b/lib/placeholders/line/tests/accessibility.test.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import LinePlaceholder from '..';
+
+/* eslint-disable no-undef */
+/* eslint-disable-next-line comma-dangle */
+
+describe('LinePlaceholder accessibility tests', () => {
+ let wrappedComponent;
+ const expectedValue = 1;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('allows us to set props', () => {
+ expect(wrappedComponent.props().lineWidth).to.equal('100');
+ wrappedComponent.setProps({ lineWidth: '75' });
+ expect(wrappedComponent.props().lineWidth).to.equal('75');
+ });
+
+ it('should have `lineWidth` prop and with value `100`', () => {
+ expect(
+ wrappedComponent
+ .find('LinePlaceholder')
+ .at(0)
+ // eslint-disable-next-line comma-dangle
+ .props().lineWidth
+ ).to.equal('100');
+ });
+
+ it('should have only a single `div`', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ it('should render the `Line Placeholder` along with props ', () => {
+ expect(wrappedComponent.contains(
)).to.equal(false);
+ });
+
+ it('should render the `Card Placeholder` containing minimum 1 `div` element', () => {
+ expect(wrappedComponent.containsAllMatchingElements([
])).to.equal(
+ true,
+ );
+ });
+});
diff --git a/lib/placeholders/line/tests/render.test.js b/lib/placeholders/line/tests/render.test.js
new file mode 100644
index 00000000..c199a72b
--- /dev/null
+++ b/lib/placeholders/line/tests/render.test.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import LinePlaceholder from '..';
+
+/* eslint-disable no-undef */
+describe('LinePlaceholder render tests', () => {
+ let wrappedComponent;
+ const expectedValue = 1;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('Should render the LinePlaceholder component', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ it('Should render a LinePlaceholder with defalult lineWidth', () => {
+ expect(wrappedComponent.props().lineWidth).to.equal('100');
+ });
+});
diff --git a/lib/placeholders/line/theme.module.scss b/lib/placeholders/line/theme.module.scss
new file mode 100644
index 00000000..a872b061
--- /dev/null
+++ b/lib/placeholders/line/theme.module.scss
@@ -0,0 +1,67 @@
+@import '../../globals/theme';
+@import '../../globals/animations.module.scss';
+
+:local(.styles) {
+ background: $shimmer-color-light;
+ background-image: linear-gradient(
+ to right,
+ $shimmer-color-light 0%,
+ $shimmer-color-dark 20%,
+ $shimmer-color-light 40%,
+ $shimmer-color-light 100%
+ );
+ background-repeat: no-repeat;
+ // **** change here for height ***
+ // background-size: 800px 16px;
+ display: block;
+ position: relative;
+
+ margin: 12px 0px;
+
+ @include lineShimmer($length: 700px);
+}
+
+:local(.lineStyles) {
+ width: 100%;
+ height: 10px;
+ border-radius: 4px;
+}
+
+:local(.lineWidth10) {
+ width: 10%;
+}
+
+:local(.lineWidth20) {
+ width: 20%;
+}
+
+:local(.lineWidth30) {
+ width: 30%;
+}
+
+:local(.lineWidth40) {
+ width: 40%;
+}
+:local(.lineWidth50) {
+ width: 50%;
+}
+
+:local(.lineWidth60) {
+ width: 60%;
+}
+
+:local(.lineWidth70) {
+ width: 70%;
+}
+
+:local(.lineWidth80) {
+ width: 80%;
+}
+:local(.lineWidth90) {
+ width: 90%;
+}
+
+:local(.lineWidth100) {
+ width: 100%;
+}
+
diff --git a/lib/placeholders/paragraph/index.js b/lib/placeholders/paragraph/index.js
new file mode 100644
index 00000000..e9f9c4b5
--- /dev/null
+++ b/lib/placeholders/paragraph/index.js
@@ -0,0 +1,39 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classnames from 'classnames';
+import { themr } from 'react-css-themr';
+
+import LinePlaceholder from '../line';
+
+import '../../globals/fonts.scss';
+import defaultTheme from './theme.module.scss';
+
+const ParagraphPlaceholder = ({ theme, lines }) => {
+ const classes = classnames(theme.styles, theme.paragraphStyles);
+
+ const paragraphPlaceholderProps = {
+ className: classes,
+ };
+
+ return (
+
+ {lines.map(line => (
+
+ ))}
+
+ );
+};
+
+ParagraphPlaceholder.prototype = {
+ theme: PropTypes.shape({}),
+ lines: PropTypes.array,
+};
+
+ParagraphPlaceholder.defaultProps = {
+ theme: {},
+ lines: ['25', '50', '75', '100'],
+};
+
+export default themr('ParagraphPlaceholder', defaultTheme)(
+ ParagraphPlaceholder
+);
diff --git a/lib/placeholders/paragraph/readMe.md b/lib/placeholders/paragraph/readMe.md
new file mode 100644
index 00000000..ae7484b5
--- /dev/null
+++ b/lib/placeholders/paragraph/readMe.md
@@ -0,0 +1,35 @@
+## Paragraph Placeholder
+
+The paragrapg placeholder component.
+
+### Properties
+
+| Name | Type | Default | Description |
+| :------ | :------ | :-------------------------- | :---------------------------------------------- |
+| `lines` | `array` | `['25', '75', '50', '100']` | Set the no of lines in card as array of widths. |
+
+### Theme
+
+| Name | Description |
+| :---------------- | :------------------------------- |
+| `paragraphStyles` | Class used for the root element. |
+
+### Usage
+
+```
+
+class Demo extends React.Component {
+ state = {
+ loading: false,
+ }
+ render() {
+ const {loading} = this.state;
+ return (
+
+ { loading ?
:
+
User Content
+
+ )
+ }
+}
+```
diff --git a/lib/placeholders/paragraph/tests/accessibility.test.js b/lib/placeholders/paragraph/tests/accessibility.test.js
new file mode 100644
index 00000000..f3e8c0de
--- /dev/null
+++ b/lib/placeholders/paragraph/tests/accessibility.test.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import ParagraphPlaceholder from '..';
+
+/* eslint-disable no-undef */
+/* eslint-disable-next-line comma-dangle */
+
+describe('ParagraphPlaceholder accessibility tests', () => {
+ let wrappedComponent;
+ const expectedValue = 5;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('allows us to set props', () => {
+ expect(wrappedComponent.props().lineWidth).to.equal('100');
+ wrappedComponent.setProps({ lineWidth: '75' });
+ expect(wrappedComponent.props().lineWidth).to.equal('75');
+ });
+
+ it('should have `lineWidth` prop and with value `100`', () => {
+ expect(
+ wrappedComponent
+ .find('ParagraphPlaceholder')
+ .at(0)
+ // eslint-disable-next-line comma-dangle
+ .props().lineWidth
+ ).to.equal('100');
+ });
+
+ it('should have only a single `div`', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ it('should render the `Line Placeholder` along with props ', () => {
+ expect(wrappedComponent.contains(
)).to.equal(false);
+ });
+
+ it('should render the `Card Placeholder` containing minimum 1 `div` element', () => {
+ expect(wrappedComponent.containsAllMatchingElements([
])).to.equal(
+ true,
+ );
+ });
+});
diff --git a/lib/placeholders/paragraph/tests/render.test.js b/lib/placeholders/paragraph/tests/render.test.js
new file mode 100644
index 00000000..f2a44591
--- /dev/null
+++ b/lib/placeholders/paragraph/tests/render.test.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import { expect } from 'chai';
+
+import ParagraphPlaceholder from '..';
+
+/* eslint-disable no-undef */
+describe('ParagraphPlaceholder render tests', () => {
+ let wrappedComponent;
+ const expectedValue = 5;
+ const actualValue = element => wrappedComponent.find(element).length;
+
+ beforeEach(() => {
+ wrappedComponent = mount( );
+ });
+
+ afterEach(() => {
+ wrappedComponent.unmount();
+ });
+
+ it('Should render the ParagraphPlaceholder component', () => {
+ expect(actualValue('div')).equal(expectedValue);
+ });
+
+ // it('Should render a ParagraphPlaceholder with defalult lines', () => {
+ // expect(wrappedComponent.props().lines).to.equal(
+ // '['25', '50', '75', '100']'
+ // );
+ // });
+});
diff --git a/lib/placeholders/paragraph/theme.module.scss b/lib/placeholders/paragraph/theme.module.scss
new file mode 100644
index 00000000..11c5f868
--- /dev/null
+++ b/lib/placeholders/paragraph/theme.module.scss
@@ -0,0 +1,10 @@
+@import '../../globals/theme';
+
+:local(.styles) {
+ box-shadow: $shadow-light;
+}
+
+:local(.paragraphStyles) {
+ padding: 16px;
+ border-radius: $border-radius-medium;
+}
diff --git a/package-lock.json b/package-lock.json
index 22f6e68f..d1d77261 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2298,27 +2298,47 @@
"dev": true
},
"cacache": {
- "version": "11.3.2",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz",
- "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==",
+ "version": "11.3.3",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz",
+ "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==",
"dev": true,
"requires": {
- "bluebird": "^3.5.3",
+ "bluebird": "^3.5.5",
"chownr": "^1.1.1",
"figgy-pudding": "^3.5.1",
- "glob": "^7.1.3",
+ "glob": "^7.1.4",
"graceful-fs": "^4.1.15",
"lru-cache": "^5.1.1",
"mississippi": "^3.0.0",
"mkdirp": "^0.5.1",
"move-concurrently": "^1.0.1",
"promise-inflight": "^1.0.1",
- "rimraf": "^2.6.2",
+ "rimraf": "^2.6.3",
"ssri": "^6.0.1",
"unique-filename": "^1.1.1",
"y18n": "^4.0.0"
},
"dependencies": {
+ "bluebird": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
+ "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -2328,6 +2348,15 @@
"yallist": "^3.0.2"
}
},
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
@@ -2542,9 +2571,9 @@
}
},
"chownr": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
- "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz",
+ "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==",
"dev": true
},
"chrome-trace-event": {
@@ -4393,9 +4422,9 @@
}
},
"duplexify": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz",
- "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==",
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
"dev": true,
"requires": {
"end-of-stream": "^1.0.0",
@@ -5465,13 +5494,13 @@
"dev": true
},
"flush-write-stream": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
- "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
"dev": true,
"requires": {
- "inherits": "^2.0.1",
- "readable-stream": "^2.0.4"
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.3.6"
}
},
"follow-redirects": {
@@ -7457,54 +7486,6 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true
},
- "isomorphic-style-loader": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/isomorphic-style-loader/-/isomorphic-style-loader-5.0.1.tgz",
- "integrity": "sha512-USUsfZUaDyEwK/aJAO9tNsH4hcW6wcSFZYCn2LZsGYV68VOhCC0ocN8h+rBLvqwmLN8J9t4XbkxBGeHGdzNa6w==",
- "dev": true,
- "requires": {
- "hoist-non-react-statics": "^3.0.0",
- "loader-utils": "^1.2.3",
- "react": "^16.3.0"
- },
- "dependencies": {
- "big.js": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
- "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
- "dev": true
- },
- "hoist-non-react-statics": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
- "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
- "dev": true,
- "requires": {
- "react-is": "^16.7.0"
- }
- },
- "json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.0"
- }
- },
- "loader-utils": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
- "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
- "dev": true,
- "requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^2.0.0",
- "json5": "^1.0.1"
- }
- }
- }
- },
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@@ -16016,9 +15997,9 @@
}
},
"serialize-javascript": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz",
- "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz",
+ "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==",
"dev": true
},
"serve-index": {
@@ -16880,20 +16861,20 @@
}
},
"terser": {
- "version": "3.13.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-3.13.1.tgz",
- "integrity": "sha512-ogyZye4DFqOtMzT92Y3Nxxw8OvXmL39HOALro4fc+EUYFFF9G/kk0znkvwMz6PPYgBtdKAodh3FPR70eugdaQA==",
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz",
+ "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==",
"dev": true,
"requires": {
- "commander": "~2.17.1",
+ "commander": "^2.20.0",
"source-map": "~0.6.1",
- "source-map-support": "~0.5.6"
+ "source-map-support": "~0.5.12"
},
"dependencies": {
"commander": {
- "version": "2.17.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
- "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
+ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true
},
"source-map": {
@@ -16901,33 +16882,51 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.12",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
+ "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
}
}
},
"terser-webpack-plugin": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.0.tgz",
- "integrity": "sha512-QW7RACLS89RalHtLDb0s8+Iqcs/IAEw1rnVrV+mS7Gx1kgPG8o1g33JhAGDgc/CQ84hLsTW5WrAMdVysh692yg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.3.0.tgz",
+ "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==",
"dev": true,
"requires": {
- "cacache": "^11.0.2",
+ "cacache": "^11.3.2",
"find-cache-dir": "^2.0.0",
+ "is-wsl": "^1.1.0",
+ "loader-utils": "^1.2.3",
"schema-utils": "^1.0.0",
- "serialize-javascript": "^1.4.0",
+ "serialize-javascript": "^1.7.0",
"source-map": "^0.6.1",
- "terser": "^3.8.1",
- "webpack-sources": "^1.1.0",
- "worker-farm": "^1.5.2"
+ "terser": "^4.0.0",
+ "webpack-sources": "^1.3.0",
+ "worker-farm": "^1.7.0"
},
"dependencies": {
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+ "dev": true
+ },
"find-cache-dir": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz",
- "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+ "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
"dev": true,
"requires": {
"commondir": "^1.0.1",
- "make-dir": "^1.0.0",
+ "make-dir": "^2.0.0",
"pkg-dir": "^3.0.0"
}
},
@@ -16940,6 +16939,26 @@
"locate-path": "^3.0.0"
}
},
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "loader-utils": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+ "dev": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^2.0.0",
+ "json5": "^1.0.1"
+ }
+ },
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@@ -16950,10 +16969,20 @@
"path-exists": "^3.0.0"
}
},
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
"p-limit": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz",
- "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+ "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@@ -16969,9 +16998,15 @@
}
},
"p-try": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
- "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true
},
"pkg-dir": {
@@ -17236,6 +17271,7 @@
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
"integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
"dev": true,
+ "optional": true,
"requires": {
"commander": "~2.17.1",
"source-map": "~0.6.1"
@@ -17245,100 +17281,15 @@
"version": "2.17.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
"integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
- },
- "uglifyjs-webpack-plugin": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-2.1.0.tgz",
- "integrity": "sha512-xD8HaE8sFvhYsE2Lr4lSQ/Y2K0DBEaZGqIsrIccdxaAWdFdeYcm54CcMoCCPDpixqUlZAukUMq3cmgIqXubjsQ==",
- "dev": true,
- "requires": {
- "cacache": "^11.2.0",
- "find-cache-dir": "^2.0.0",
- "schema-utils": "^1.0.0",
- "serialize-javascript": "^1.4.0",
- "source-map": "^0.6.1",
- "uglify-js": "^3.0.0",
- "webpack-sources": "^1.1.0",
- "worker-farm": "^1.5.2"
- },
- "dependencies": {
- "find-cache-dir": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz",
- "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==",
- "dev": true,
- "requires": {
- "commondir": "^1.0.1",
- "make-dir": "^1.0.0",
- "pkg-dir": "^3.0.0"
- }
- },
- "find-up": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
- "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
- "requires": {
- "locate-path": "^3.0.0"
- }
- },
- "locate-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
- "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
- "dev": true,
- "requires": {
- "p-locate": "^3.0.0",
- "path-exists": "^3.0.0"
- }
- },
- "p-limit": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz",
- "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==",
- "dev": true,
- "requires": {
- "p-try": "^2.0.0"
- }
- },
- "p-locate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
- "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
- "dev": true,
- "requires": {
- "p-limit": "^2.0.0"
- }
- },
- "p-try": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
- "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
- "dev": true
- },
- "pkg-dir": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
- "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
- "dev": true,
- "requires": {
- "find-up": "^3.0.0"
- }
+ "optional": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -17427,9 +17378,9 @@
}
},
"unique-slug": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz",
- "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
"dev": true,
"requires": {
"imurmurhash": "^0.1.4"
@@ -18378,9 +18329,9 @@
"dev": true
},
"worker-farm": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
- "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+ "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
"dev": true,
"requires": {
"errno": "~0.1.7"
diff --git a/webpack.common.js b/webpack.common.js
index d8ed26ba..84723c5b 100644
--- a/webpack.common.js
+++ b/webpack.common.js
@@ -41,7 +41,7 @@ module.exports = {
rules: [
{
test: /\.js$/,
- exclude: /node_modules/,
+ exclude: path.resolve(__dirname, 'node_modules'),
use: {
loader: 'babel-loader',
},
diff --git a/webpack.config.js b/webpack.config.js
index 80dade4b..80940183 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -3,11 +3,11 @@ const common = require('./webpack.common.js');
const path = require('path');
module.exports = merge(common, {
- devtool: 'inline-source-map',
- mode: 'development',
- watch: true,
- watchOptions: {
- aggregateTimeout: 1000,
- ignored: ['node_modules', 'test'],
- },
+ devtool: "cheap-module-eval-source-map",
+ mode: "development",
+ watch: true,
+ watchOptions: {
+ aggregateTimeout: 1000,
+ ignored: ["node_modules", "test"]
+ }
});