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 ( 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 : navbar-left-logo} -
) + + ) }
{this.renderLeftContent()} @@ -152,7 +153,8 @@ class Navbar extends React.Component { {rightIcon && (
{React.isValidElement(rightIcon) ? rightIcon : navbar-right-logo} -
) +
+ ) }
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"] + } });