├── .babelrc ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── contributing.md ├── dist └── react-css-loaders.js ├── docs ├── favicon.ico ├── index.html └── js │ └── bundle.js ├── lib ├── bar │ ├── Bar.jsx │ └── BarLoader.jsx ├── bubble-spin │ ├── BubbleSpin.jsx │ └── BubbleSpinLoader.jsx ├── bubble │ ├── Bubble.jsx │ └── BubbleLoader.jsx ├── comet-spin │ ├── CometSpin.jsx │ └── CometSpinLoader.jsx ├── cylinder-spin │ ├── CylinderSpin.jsx │ └── CylinderSpinLoader.jsx ├── index.js ├── resize-spin │ ├── ResizeSpin.jsx │ └── ResizeSpinLoader.jsx ├── rotate-spin │ ├── RotateSpin.jsx │ └── RotateSpinLoader.jsx └── spin │ ├── Spin.jsx │ └── SpinLoader.jsx ├── package.json ├── react-css-loaders.d.ts ├── tests ├── helpers │ └── setup.js └── lib │ ├── Bar.spec.js │ ├── Bubble.spec.js │ ├── BubbleSpin.spec.js │ ├── CometSpen.spec.js │ ├── CylinderSpin.spec.js │ ├── ResizeSpin.spec.js │ ├── RotateSpin.spec.js │ └── Spin.spec.js ├── webpack.config.js └── webpack.config.prod.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain 2 | # consistent coding styles between different editors and IDEs. 3 | 4 | root = true 5 | 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "airbnb" 4 | ], 5 | "globals": { 6 | document: true, 7 | window: true, 8 | }, 9 | "rules": { 10 | "no-console": ["off"], 11 | "no-unused-expressions": ["off"], 12 | "no-use-before-define": ["off"], 13 | "no-restricted-syntax": ["off"], 14 | "no-param-reassign": ["off"], 15 | "no-confusing-arrow": ["off"], 16 | "class-methods-use-this": ["off"], 17 | "jsx-a11y/no-static-element-interactions": ["off"], 18 | "react/jsx-boolean-value": ["off"], 19 | "react/react-in-jsx-scope": ["off"], 20 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 21 | "react/forbid-prop-types": ["off"], 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | /lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | /coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | /build 24 | 25 | # Others 26 | /.nyc_output 27 | /app 28 | /site 29 | 30 | # Dependency directory 31 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 32 | node_modules 33 | package-lock.json 34 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 8 4 | install: npm install 5 | before_install: 6 | - "npm install react@16.4.1 react-dom@16.4.1 styled-components@3.4.10" 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Lucas Bassetti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React CSS Loaders 2 | 3 | Travis CI npm version [![Coverage Status](https://coveralls.io/repos/github/LucasBassetti/react-css-loaders/badge.svg)](https://coveralls.io/github/LucasBassetti/react-css-loaders) 4 | 5 | 6 | A collection of pure CSS React loading components. Based on Luke Haas [css-loaders](https://github.com/lukehaas/css-loaders) project. 7 | 8 | 9 | 10 | 11 | 12 | ## Contents 13 | - [Getting Started](#getting-started) 14 | - [Usage](#usage) 15 | - [Components](#components) 16 | - [BarLoader](#barloader) 17 | - [BubbleLoader](#bubbleloader) 18 | - [BubbleSpinLoader](#bubblespinloader) 19 | - [CometSpinLoader](#cometspinloader) 20 | - [CylinderSpinLoader](#cylinderspinloader) 21 | - [ResizeSpinLoader](#resizespinloader) 22 | - [RotateSpinLoader](#rotatespinloader) 23 | - [SpinLoader](#spinloader) 24 | - [How to Contribute](#how-to-contribute) 25 | 26 | ## Getting Start 27 | 28 | ```bash 29 | npm install react-css-loaders --save 30 | ``` 31 | 32 | ## Usage 33 | 34 | ``` javascript 35 | import { BarLoader } from 'react-css-loaders'; 36 | ... 37 | 38 | ... 39 | ``` 40 | 41 | ## Components 42 | 43 | ### BarLoader 44 | 45 | ##### Usage 46 | 47 | `` 48 | 49 | ##### Properties 50 | 51 | | Name | Type | Default | 52 | |---|---|---| 53 | | `color` | `PropTypes.string` | `#000` | 54 | | `duration` | `PropTypes.number` | `1` | 55 | | `size` | `PropTypes.number` | `11` | 56 | 57 | ### BubbleLoader 58 | 59 | ##### Usage 60 | 61 | `` 62 | 63 | ##### Properties 64 | 65 | | Name | Type | Default | 66 | |---|---|---| 67 | | `color` | `PropTypes.string` | `#000` | 68 | | `duration` | `PropTypes.number` | `1.8` | 69 | | `size` | `PropTypes.number` | `10` | 70 | 71 | ### BubbleSpinLoader 72 | 73 | ##### Usage 74 | 75 | `` 76 | 77 | ##### Properties 78 | 79 | | Name | Type | Default | 80 | |---|---|---| 81 | | `color` | `PropTypes.string` | `#000` | 82 | | `duration` | `PropTypes.number` | `1.3` | 83 | | `size` | `PropTypes.number` | `20` | 84 | 85 | ### CometSpinLoader 86 | 87 | ##### Usage 88 | 89 | `` 90 | 91 | ##### Properties 92 | 93 | | Name | Type | Default | 94 | |---|---|---| 95 | | `color` | `PropTypes.string` | `#000` | 96 | | `duration` | `PropTypes.number` | `1.7` | 97 | | `size` | `PropTypes.number` | `90` | 98 | 99 | ### CylinderSpinLoader 100 | 101 | ##### Usage 102 | 103 | `` 104 | 105 | ##### Properties 106 | 107 | | Name | Type | Default | 108 | |---|---|---| 109 | | `color` | `PropTypes.string` | `#000` | 110 | | `duration` | `PropTypes.number` | `1.1` | 111 | | `size` | `PropTypes.number` | `25` | 112 | 113 | ### ResizeSpinLoader 114 | 115 | ##### Usage 116 | 117 | `` 118 | 119 | ##### Properties 120 | 121 | | Name | Type | Default | 122 | |---|---|---| 123 | | `background` | `PropTypes.string` | `#000` | 124 | | `color` | `PropTypes.string` | `#000` | 125 | | `duration` | `PropTypes.number` | `2` | 126 | | `size` | `PropTypes.number` | `11` | 127 | 128 | ### RotateSpinLoader 129 | 130 | ##### Usage 131 | 132 | `` 133 | 134 | ##### Properties 135 | 136 | | Name | Type | Default | 137 | |---|---|---| 138 | | `color` | `PropTypes.string` | `#000` | 139 | | `duration` | `PropTypes.number` | `1.1` | 140 | | `size` | `PropTypes.number` | `10` | 141 | 142 | ### SpinLoader 143 | 144 | ##### Usage 145 | 146 | `` 147 | 148 | ##### Properties 149 | 150 | | Name | Type | Default | 151 | |---|---|---| 152 | | `background` | `PropTypes.string` | `#fff` | 153 | | `color` | `PropTypes.string` | `#000` | 154 | | `duration` | `PropTypes.number` | `1.4` | 155 | | `size` | `PropTypes.number` | `10` | 156 | 157 | ## Authors 158 | 159 | | ![Lucas Bassetti](https://avatars3.githubusercontent.com/u/1014326?v=3&s=150)| 160 | |:---------------------:| 161 | | [Lucas Bassetti](https://github.com/LucasBassetti/) | 162 | 163 | See also the list of [contributors](https://github.com/LucasBassetti/react-css-loaders/contributors) who participated in this project. 164 | 165 | ## How to Contribute 166 | 167 | Please check the [contributing guide](https://github.com/LucasBassetti/react-css-loaders/blob/master/contributing.md) 168 | 169 | ## License 170 | 171 | MIT · [Lucas Bassetti](http://lucasbassetti.com.br) 172 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing guide 2 | 3 | Want to contribute to React CSS Loader? Awesome! 4 | There are many ways you can contribute, see below. 5 | 6 | ## Opening issues 7 | 8 | Open an issue to report bugs or to propose new features. 9 | 10 | - Reporting bugs: describe the bug as clearly as you can, including steps to reproduce, what happened and what you were expecting to happen. Also include browser version, OS and other related software's (npm, Node.js, etc) versions when applicable. 11 | 12 | - Proposing features: explain the proposed feature, what it should do, why it is useful, how users should use it. Give us as much info as possible so it will be easier to discuss, access and implement the proposed feature. When you're unsure about a certain aspect of the feature, feel free to leave it open for others to discuss and find an appropriate solution. 13 | 14 | ## Proposing pull requests 15 | 16 | Pull requests are very welcome. Note that if you are going to propose drastic changes, be sure to open an issue for discussion first, to make sure that your PR will be accepted before you spend effort coding it. 17 | 18 | Fork the repository, clone it locally and create a branch for your proposed bug fix or new feature. Avoid working directly on the master branch. 19 | 20 | Implement your bug fix or feature, write tests to cover it and make sure all tests are passing (run a final `npm test` to make sure everything is correct). Then commit your changes, push your bug fix/feature branch to the origin (your forked repo) and open a pull request to the upstream (the repository you originally forked)'s master branch. 21 | 22 | ## Documentation 23 | 24 | Documentation is extremely important and takes a fair deal of time and effort to write and keep updated. Please submit any and all improvements you can make to the repository's docs. 25 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LucasBassetti/react-css-loaders/097407f522183a9cdeb5f7097e67583033af91bf/docs/favicon.ico -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | React CSS Loaders 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | 52 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /lib/bar/Bar.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0%, 5 | 80%, 6 | 100% { 7 | box-shadow: 0 0; 8 | height: 4em; 9 | } 10 | 40% { 11 | box-shadow: 0 -2em; 12 | height: 5em; 13 | } 14 | `; 15 | 16 | const Bar = styled.div` 17 | animation: ${props => `${loading} ${props.duration}s infinite ease-in-out`}; 18 | animation-delay: ${props => `${props.duration * -0.16}s`}; 19 | background: ${props => props.color}; 20 | color: ${props => props.color}; 21 | font-size: ${props => `${props.size}px`}; 22 | height: 4em; 23 | margin: 88px auto; 24 | position: relative; 25 | text-indent: -9999em; 26 | transform: translateZ(0); 27 | width: 1em; 28 | 29 | &:before { 30 | animation: ${props => `${loading} ${props.duration}s infinite ease-in-out;`}; 31 | animation-delay: ${props => `${props.duration * -0.32}s`}; 32 | background: ${props => props.color}; 33 | content: ''; 34 | height: 4em; 35 | left: -1.5em; 36 | position: absolute; 37 | top: 0; 38 | width: 1em; 39 | } 40 | 41 | &:after { 42 | animation: ${props => `${loading} ${props.duration}s infinite ease-in-out`}; 43 | animation-delay: ${props => `${props.duration * 0.08}s`}; 44 | background: ${props => props.color}; 45 | content: ''; 46 | height: 4em; 47 | left: 1.5em; 48 | position: absolute; 49 | top: 0; 50 | width: 1em; 51 | } 52 | `; 53 | 54 | export default Bar; 55 | -------------------------------------------------------------------------------- /lib/bar/BarLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Bar from './Bar'; 4 | 5 | const BarLoader = props => ( 6 | 7 | ); 8 | 9 | BarLoader.propTypes = { 10 | color: PropTypes.string, 11 | duration: PropTypes.number, 12 | size: PropTypes.number, 13 | }; 14 | 15 | BarLoader.defaultProps = { 16 | color: '#000', 17 | duration: 1, 18 | size: 11, 19 | }; 20 | 21 | export default BarLoader; 22 | -------------------------------------------------------------------------------- /lib/bubble-spin/BubbleSpin.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0%, 5 | 100% { 6 | box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0; 7 | } 8 | 12.5% { 9 | box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; 10 | } 11 | 25% { 12 | box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0, 0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em; 13 | } 14 | 37.5% { 15 | box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em, 0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em; 16 | } 17 | 50% { 18 | box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em, 0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em; 19 | } 20 | 62.5% { 21 | box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em; 22 | } 23 | 75% { 24 | box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0; 25 | } 26 | 87.5% { 27 | box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em, 0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em; 28 | } 29 | `; 30 | 31 | const BubbleSpin = styled.div` 32 | animation: ${props => `${loading} ${props.duration}s infinite linear;`}; 33 | border-radius: 50%; 34 | color: ${props => props.color}; 35 | font-size: ${props => `${props.size}px`}; 36 | height: 1em; 37 | margin: 100px auto; 38 | position: relative; 39 | text-indent: -9999em; 40 | transform: translateZ(0); 41 | width: 1em; 42 | `; 43 | 44 | export default BubbleSpin; 45 | -------------------------------------------------------------------------------- /lib/bubble-spin/BubbleSpinLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import BubbleSpin from './BubbleSpin'; 4 | 5 | const BubbleSpinLoader = props => ( 6 | 7 | ); 8 | 9 | BubbleSpinLoader.propTypes = { 10 | color: PropTypes.string, 11 | duration: PropTypes.number, 12 | size: PropTypes.number, 13 | }; 14 | 15 | BubbleSpinLoader.defaultProps = { 16 | color: '#000', 17 | duration: 1.3, 18 | size: 20, 19 | }; 20 | 21 | export default BubbleSpinLoader; 22 | -------------------------------------------------------------------------------- /lib/bubble/Bubble.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0%, 5 | 80%, 6 | 100% { 7 | box-shadow: 0 2.5em 0 -1.3em; 8 | } 9 | 40% { 10 | box-shadow: 0 2.5em 0 0; 11 | } 12 | `; 13 | 14 | const Bubble = styled.div` 15 | animation: ${props => `${loading} ${props.duration}s infinite ease-in-out;`}; 16 | animation-delay: ${props => `${props.duration * -0.16}s`}; 17 | animation-fill-mode: both; 18 | border-radius: 50%; 19 | color: ${props => props.color}; 20 | font-size: ${props => `${props.size}px`}; 21 | height: 2.5em; 22 | margin: 80px auto; 23 | position: relative; 24 | text-indent: -9999em; 25 | transform: translateZ(0); 26 | width: 2.5em; 27 | 28 | &:before { 29 | animation: ${props => `${loading} ${props.duration}s infinite ease-in-out;`}; 30 | animation-delay: ${props => `${props.duration * -0.32}s`}; 31 | animation-fill-mode: both; 32 | border-radius: 50%; 33 | content: ''; 34 | height: 2.5em; 35 | left: -3.5em; 36 | position: absolute; 37 | top: 0; 38 | width: 2.5em; 39 | } 40 | 41 | &:after { 42 | animation: ${props => `${loading} ${props.duration}s infinite ease-in-out;`}; 43 | animation-fill-mode: both; 44 | border-radius: 50%; 45 | content: ''; 46 | height: 2.5em; 47 | left: 3.5em; 48 | position: absolute; 49 | top: 0; 50 | width: 2.5em; 51 | } 52 | `; 53 | 54 | export default Bubble; 55 | -------------------------------------------------------------------------------- /lib/bubble/BubbleLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Bubble from './Bubble'; 4 | 5 | const BubbleLoader = props => ( 6 | 7 | ); 8 | 9 | BubbleLoader.propTypes = { 10 | color: PropTypes.string, 11 | duration: PropTypes.number, 12 | size: PropTypes.number, 13 | }; 14 | 15 | BubbleLoader.defaultProps = { 16 | color: '#000', 17 | duration: 1.8, 18 | size: 10, 19 | }; 20 | 21 | export default BubbleLoader; 22 | -------------------------------------------------------------------------------- /lib/comet-spin/CometSpin.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0% { 5 | box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; 6 | } 7 | 5%, 8 | 95% { 9 | box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; 10 | } 11 | 10%, 12 | 59% { 13 | box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em, -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em, -0.297em -0.775em 0 -0.477em; 14 | } 15 | 20% { 16 | box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em, -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em, -0.749em -0.34em 0 -0.477em; 17 | } 18 | 38% { 19 | box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em, -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em, -0.82em -0.09em 0 -0.477em; 20 | } 21 | 100% { 22 | box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em, 0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em; 23 | } 24 | `; 25 | 26 | const round = keyframes` 27 | 0% { 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | transform: rotate(360deg); 32 | } 33 | `; 34 | 35 | const CometSpin = styled.div` 36 | animation: ${props => `${loading} ${props.duration}s infinite ease, ${round} ${props.duration}s infinite ease`}; 37 | border-radius: 50%; 38 | color: ${props => props.color}; 39 | font-size: ${props => `${props.size}px`}; 40 | height: 1em; 41 | margin: 72px auto; 42 | overflow: hidden; 43 | position: relative; 44 | text-indent: -9999em; 45 | transform: translateZ(0); 46 | width: 1em; 47 | `; 48 | 49 | export default CometSpin; 50 | -------------------------------------------------------------------------------- /lib/comet-spin/CometSpinLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import CometSpin from './CometSpin'; 4 | 5 | const CometSpinLoader = props => ( 6 | 7 | ); 8 | 9 | CometSpinLoader.propTypes = { 10 | color: PropTypes.string, 11 | duration: PropTypes.number, 12 | size: PropTypes.number, 13 | }; 14 | 15 | CometSpinLoader.defaultProps = { 16 | color: '#000', 17 | duration: 1.7, 18 | size: 90, 19 | }; 20 | 21 | export default CometSpinLoader; 22 | -------------------------------------------------------------------------------- /lib/cylinder-spin/CylinderSpin.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | function animation(props) { 4 | const d = document.createElement('div'); 5 | d.style.color = props.color; 6 | document.body.appendChild(d); 7 | const rgbcolor = window.getComputedStyle(d).color; 8 | const match = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor); 9 | const color = `${match[1]}, ${match[2]}, ${match[3]}`; 10 | 11 | return keyframes` 12 | 0%, 13 | 100% { 14 | box-shadow: 0em -2.6em 0em 0em ${props.color}, 1.8em -1.8em 0 0em rgba(${color}, 0.2), 2.5em 0em 0 0em rgba(${color}, 0.2), 1.75em 1.75em 0 0em rgba(${color}, 0.2), 0em 2.5em 0 0em rgba(${color}, 0.2), -1.8em 1.8em 0 0em rgba(${color}, 0.2), -2.6em 0em 0 0em rgba(${color}, 0.5), -1.8em -1.8em 0 0em rgba(${color}, 0.7); 15 | } 16 | 12.5% { 17 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.7), 1.8em -1.8em 0 0em ${props.color}, 2.5em 0em 0 0em rgba(${color}, 0.2), 1.75em 1.75em 0 0em rgba(${color}, 0.2), 0em 2.5em 0 0em rgba(${color}, 0.2), -1.8em 1.8em 0 0em rgba(${color}, 0.2), -2.6em 0em 0 0em rgba(${color}, 0.2), -1.8em -1.8em 0 0em rgba(${color}, 0.5); 18 | } 19 | 25% { 20 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.5), 1.8em -1.8em 0 0em rgba(${color}, 0.7), 2.5em 0em 0 0em ${props.color}, 1.75em 1.75em 0 0em rgba(${color}, 0.2), 0em 2.5em 0 0em rgba(${color}, 0.2), -1.8em 1.8em 0 0em rgba(${color}, 0.2), -2.6em 0em 0 0em rgba(${color}, 0.2), -1.8em -1.8em 0 0em rgba(${color}, 0.2); 21 | } 22 | 37.5% { 23 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.2), 1.8em -1.8em 0 0em rgba(${color}, 0.5), 2.5em 0em 0 0em rgba(${color}, 0.7), 1.75em 1.75em 0 0em ${props.color}, 0em 2.5em 0 0em rgba(${color}, 0.2), -1.8em 1.8em 0 0em rgba(${color}, 0.2), -2.6em 0em 0 0em rgba(${color}, 0.2), -1.8em -1.8em 0 0em rgba(${color}, 0.2); 24 | } 25 | 50% { 26 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.2), 1.8em -1.8em 0 0em rgba(${color}, 0.2), 2.5em 0em 0 0em rgba(${color}, 0.5), 1.75em 1.75em 0 0em rgba(${color}, 0.7), 0em 2.5em 0 0em ${props.color}, -1.8em 1.8em 0 0em rgba(${color}, 0.2), -2.6em 0em 0 0em rgba(${color}, 0.2), -1.8em -1.8em 0 0em rgba(${color}, 0.2); 27 | } 28 | 62.5% { 29 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.2), 1.8em -1.8em 0 0em rgba(${color}, 0.2), 2.5em 0em 0 0em rgba(${color}, 0.2), 1.75em 1.75em 0 0em rgba(${color}, 0.5), 0em 2.5em 0 0em rgba(${color}, 0.7), -1.8em 1.8em 0 0em ${props.color}, -2.6em 0em 0 0em rgba(${color}, 0.2), -1.8em -1.8em 0 0em rgba(${color}, 0.2); 30 | } 31 | 75% { 32 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.2), 1.8em -1.8em 0 0em rgba(${color}, 0.2), 2.5em 0em 0 0em rgba(${color}, 0.2), 1.75em 1.75em 0 0em rgba(${color}, 0.2), 0em 2.5em 0 0em rgba(${color}, 0.5), -1.8em 1.8em 0 0em rgba(${color}, 0.7), -2.6em 0em 0 0em ${props.color}, -1.8em -1.8em 0 0em rgba(${color}, 0.2); 33 | } 34 | 87.5% { 35 | box-shadow: 0em -2.6em 0em 0em rgba(${color}, 0.2), 1.8em -1.8em 0 0em rgba(${color}, 0.2), 2.5em 0em 0 0em rgba(${color}, 0.2), 1.75em 1.75em 0 0em rgba(${color}, 0.2), 0em 2.5em 0 0em rgba(${color}, 0.2), -1.8em 1.8em 0 0em rgba(${color}, 0.5), -2.6em 0em 0 0em rgba(${color}, 0.7), -1.8em -1.8em 0 0em ${props.color}; 36 | } 37 | `; 38 | } 39 | 40 | const CylinderSpin = styled.div` 41 | animation: ${props => `${animation(props)} ${props.duration}s infinite ease;`}; 42 | border-radius: 50%; 43 | font-size: ${props => `${props.size}px`}; 44 | height: 1em; 45 | margin: 100px auto; 46 | position: relative; 47 | text-indent: -9999em; 48 | transform: translateZ(0); 49 | width: 1em; 50 | `; 51 | 52 | export default CylinderSpin; 53 | -------------------------------------------------------------------------------- /lib/cylinder-spin/CylinderSpinLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import CylinderSpin from './CylinderSpin'; 4 | 5 | const CylinderSpinLoader = props => ( 6 | 7 | ); 8 | 9 | CylinderSpinLoader.propTypes = { 10 | color: PropTypes.string, 11 | duration: PropTypes.number, 12 | size: PropTypes.number, 13 | }; 14 | 15 | CylinderSpinLoader.defaultProps = { 16 | color: '#000', 17 | duration: 1.1, 18 | size: 25, 19 | }; 20 | 21 | export default CylinderSpinLoader; 22 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | import BarLoader from './bar/BarLoader'; 2 | import BubbleLoader from './bubble/BubbleLoader'; 3 | import BubbleSpinLoader from './bubble-spin/BubbleSpinLoader'; 4 | import CometSpinLoader from './comet-spin/CometSpinLoader'; 5 | import CylinderSpinLoader from './cylinder-spin/CylinderSpinLoader'; 6 | import ResizeSpinLoader from './resize-spin/ResizeSpinLoader'; 7 | import RotateSpinLoader from './rotate-spin/RotateSpinLoader'; 8 | import SpinLoader from './spin/SpinLoader'; 9 | 10 | export { 11 | BarLoader, 12 | BubbleLoader, 13 | BubbleSpinLoader, 14 | CometSpinLoader, 15 | CylinderSpinLoader, 16 | ResizeSpinLoader, 17 | RotateSpinLoader, 18 | SpinLoader, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/resize-spin/ResizeSpin.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0% { 5 | transform: rotate(0deg); 6 | } 7 | 100% { 8 | transform: rotate(360deg); 9 | } 10 | `; 11 | 12 | const ResizeSpin = styled.div` 13 | border-radius: 50%; 14 | box-shadow: inset 0 0 0 1em; 15 | color: ${props => props.color}; 16 | font-size: ${props => `${props.size}px`}; 17 | height: 10em; 18 | margin: 55px auto; 19 | position: relative; 20 | text-indent: -99999em; 21 | transform: translateZ(0); 22 | width: 10em; 23 | 24 | &:before { 25 | animation: ${props => `${loading} ${props.duration}s infinite ease 1.5s`}; 26 | background: ${props => props.background}; 27 | border-radius: 50%; 28 | border-radius: 10.2em 0 0 10.2em; 29 | content: ''; 30 | height: 10.2em; 31 | left: -0.1em; 32 | position: absolute; 33 | top: -0.1em; 34 | transform-origin: 5.2em 5.1em; 35 | width: 5.2em; 36 | } 37 | 38 | &:after { 39 | animation: ${props => `${loading} ${props.duration}s infinite ease`}; 40 | background: ${props => props.background}; 41 | border-radius: 50%; 42 | border-radius: 0 10.2em 10.2em 0; 43 | content: ''; 44 | height: 10.2em; 45 | left: 5.1em; 46 | position: absolute; 47 | top: -0.1em; 48 | transform-origin: 0px 5.1em; 49 | width: 5.2em; 50 | } 51 | `; 52 | 53 | export default ResizeSpin; 54 | -------------------------------------------------------------------------------- /lib/resize-spin/ResizeSpinLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import ResizeSpin from './ResizeSpin'; 4 | 5 | const ResizeSpinLoader = props => ( 6 | 7 | ); 8 | 9 | ResizeSpinLoader.propTypes = { 10 | background: PropTypes.string, 11 | color: PropTypes.string, 12 | duration: PropTypes.number, 13 | size: PropTypes.number, 14 | }; 15 | 16 | ResizeSpinLoader.defaultProps = { 17 | background: '#fff', 18 | color: '#000', 19 | duration: 2, 20 | size: 11, 21 | }; 22 | 23 | export default ResizeSpinLoader; 24 | -------------------------------------------------------------------------------- /lib/rotate-spin/RotateSpin.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0% { 5 | transform: rotate(0deg); 6 | } 7 | 100% { 8 | transform: rotate(360deg); 9 | } 10 | `; 11 | 12 | function getColor(props) { 13 | const d = document.createElement('div'); 14 | d.style.color = props.color; 15 | document.body.appendChild(d); 16 | const rgbcolor = window.getComputedStyle(d).color; 17 | const match = /rgba?\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+[.d+]*)*\)/g.exec(rgbcolor); 18 | const color = `${match[1]}, ${match[2]}, ${match[3]}`; 19 | return color; 20 | } 21 | 22 | const RotateSpin = styled.div` 23 | animation: ${props => `${loading} ${props.duration}s infinite linear`}; 24 | border: ${props => `1.1em solid rgba(${getColor(props)}, 0.2)`}; 25 | border-left: ${props => `1.1em solid ${props.color}`}; 26 | border-radius: 50%; 27 | font-size: ${props => `${props.size}px`}; 28 | height: 10em; 29 | margin: 60px auto; 30 | position: relative; 31 | text-indent: -9999em; 32 | transform: translateZ(0); 33 | width: 10em; 34 | 35 | &:after { 36 | border-radius: 50%; 37 | height: 10em; 38 | width: 10em; 39 | } 40 | `; 41 | 42 | export default RotateSpin; 43 | -------------------------------------------------------------------------------- /lib/rotate-spin/RotateSpinLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import RotateSpin from './RotateSpin'; 4 | 5 | const RotateSpinLoader = props => ( 6 | 7 | ); 8 | 9 | RotateSpinLoader.propTypes = { 10 | color: PropTypes.string, 11 | duration: PropTypes.number, 12 | size: PropTypes.number, 13 | }; 14 | 15 | RotateSpinLoader.defaultProps = { 16 | color: '#000', 17 | duration: 1.1, 18 | size: 10, 19 | }; 20 | 21 | export default RotateSpinLoader; 22 | -------------------------------------------------------------------------------- /lib/spin/Spin.jsx: -------------------------------------------------------------------------------- 1 | import styled, { keyframes } from 'styled-components'; 2 | 3 | const loading = keyframes` 4 | 0% { 5 | transform: rotate(0deg); 6 | } 7 | 100% { 8 | transform: rotate(360deg); 9 | } 10 | `; 11 | 12 | const Spin = styled.div` 13 | animation: ${props => `${loading} ${props.duration}s infinite linear;`}; 14 | background: ${props => props.color}; 15 | background: ${props => `linear-gradient(to right, ${props.color} 10%, rgba(255, 255, 255, 0) 42%);`}; 16 | border-radius: 50%; 17 | font-size: ${props => `${props.size}px`}; 18 | height: 11em; 19 | margin: 50px auto; 20 | position: relative; 21 | text-indent: -9999em; 22 | transform: translateZ(0); 23 | width: 11em; 24 | 25 | &:before { 26 | background: ${props => props.color}; 27 | border-radius: 100% 0 0 0; 28 | content: ''; 29 | height: 50%; 30 | left: 0; 31 | position: absolute; 32 | top: 0; 33 | width: 50%; 34 | } 35 | 36 | &:after { 37 | background: ${props => props.background}; 38 | border-radius: 50%; 39 | bottom: 0; 40 | content: ''; 41 | height: 75%; 42 | left: 0; 43 | margin: auto; 44 | position: absolute; 45 | right: 0; 46 | top: 0; 47 | width: 75%; 48 | } 49 | `; 50 | 51 | export default Spin; 52 | -------------------------------------------------------------------------------- /lib/spin/SpinLoader.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import Spin from './Spin'; 4 | 5 | const SpinLoader = props => ( 6 | 7 | ); 8 | 9 | SpinLoader.propTypes = { 10 | background: PropTypes.string, 11 | color: PropTypes.string, 12 | duration: PropTypes.number, 13 | size: PropTypes.number, 14 | }; 15 | 16 | SpinLoader.defaultProps = { 17 | background: '#fff', 18 | color: '#000', 19 | duration: 1.4, 20 | size: 10, 21 | }; 22 | 23 | export default SpinLoader; 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-css-loaders", 3 | "version": "0.0.6", 4 | "description": "React CSS Loaders", 5 | "main": "dist/react-css-loaders.min.js", 6 | "types": "dist/react-css-loaders.d.ts", 7 | "scripts": { 8 | "lint": "./node_modules/.bin/eslint lib/*.jsx", 9 | "prepush": "npm run lint", 10 | "start": "webpack-dev-server --inline --content-base build/", 11 | "test": "./node_modules/.bin/mocha tests/helpers/setup.js tests/**/*.spec.js --require babel-register", 12 | "test:watch": "npm test -- --watch", 13 | "test:coverage": "nyc npm test", 14 | "build": "webpack --config webpack.config.prod.js --output-filename react-css-loaders.js && cp react-css-loaders.d.ts dist/react-css-loaders.d.ts", 15 | "build:prod": "webpack --config webpack.config.prod.js --output-filename react-css-loaders.min.js -p", 16 | "build:all": "rm -rf ./dist && npm run build && npm run build:prod", 17 | "prepublish": "npm run build:all", 18 | "coveralls": "npm run test:coverage && nyc report --reporter=text-lcov | coveralls" 19 | }, 20 | "files": [ 21 | "dist" 22 | ], 23 | "nyc": { 24 | "reporter": [ 25 | "text", 26 | "html" 27 | ], 28 | "exclude": [ 29 | "tests/**" 30 | ], 31 | "extension": [ 32 | ".jsx" 33 | ] 34 | }, 35 | "repository": { 36 | "type": "git", 37 | "url": "https://github.com/LucasBassetti/react-css-loaders" 38 | }, 39 | "keywords": [ 40 | "react", 41 | "css", 42 | "loaders" 43 | ], 44 | "license": "MIT", 45 | "bugs": { 46 | "url": "https://github.com/LucasBassetti/react-css-loaders/issues" 47 | }, 48 | "homepage": "https://github.com/LucasBassetti/react-css-loaders#readme", 49 | "devDependencies": { 50 | "babel-core": "^6.7.7", 51 | "babel-eslint": "^7.1.1", 52 | "babel-loader": "^7.1.1", 53 | "babel-polyfill": "^6.7.4", 54 | "babel-preset-es2015": "6.24.0", 55 | "babel-preset-react": "^6.11.1", 56 | "babel-register": "^6.24.1", 57 | "chai": "^3.5.0", 58 | "clean-webpack-plugin": "^0.1.8", 59 | "copy-webpack-plugin": "^2.1.1", 60 | "coveralls": "^2.13.1", 61 | "enzyme": "^3.11.0", 62 | "enzyme-adapter-react-16": "^1.15.2", 63 | "eslint": "^3.19.0", 64 | "eslint-config-airbnb": "^14.1.0", 65 | "eslint-plugin-import": "^2.2.0", 66 | "eslint-plugin-jsx-a11y": "^4.0.0", 67 | "eslint-plugin-react": "^6.10.3", 68 | "file-loader": "^0.11.1", 69 | "husky": "^0.13.3", 70 | "jsdom": "^9.12.0", 71 | "mocha": "^3.2.0", 72 | "nyc": "^10.2.0", 73 | "sinon": "^2.1.0", 74 | "webpack": "^3.3.0", 75 | "webpack-dev-server": "^2.5.1" 76 | }, 77 | "dependencies": { 78 | "prop-types": "^15.5.8", 79 | "react": "^16.4.1", 80 | "react-dom": "^16.4.1" 81 | }, 82 | "peerDependencies": { 83 | "styled-components": "^3.x" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /react-css-loaders.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-css-loaders' { 2 | import {FC} from "react"; 3 | 4 | export interface IReactCssLoaderProps { 5 | color?: string, 6 | duration?: number, 7 | size?: number 8 | } 9 | 10 | export interface IReactCssLoaderWithBackgroundProps extends IReactCssLoaderProps { 11 | background?: string 12 | } 13 | 14 | export const BarLoader: FC; 15 | export const BubbleLoader: FC; 16 | export const BubbleSpinLoader: FC; 17 | export const CometSpinLoader: FC; 18 | export const CylinderSpinLoader: FC; 19 | export const RotateSpinLoader: FC; 20 | export const ResizeSpinLoader: FC; 21 | export const SpinLoader: FC; 22 | } 23 | -------------------------------------------------------------------------------- /tests/helpers/setup.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | 6 | const jsdom = require('jsdom').jsdom; 7 | 8 | const exposedProperties = ['window', 'navigator', 'document']; 9 | 10 | global.document = jsdom(''); 11 | global.window = document.defaultView; 12 | Object.keys(document.defaultView).forEach((property) => { 13 | if (typeof global[property] === 'undefined') { 14 | exposedProperties.push(property); 15 | global[property] = document.defaultView[property]; 16 | } 17 | }); 18 | 19 | global.navigator = { 20 | userAgent: 'node.js', 21 | }; 22 | -------------------------------------------------------------------------------- /tests/lib/Bar.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { BarLoader } from '../../lib/index'; 6 | 7 | describe('BarLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(BarLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default color (#000)', () => { 17 | expect(props.color).to.be.equal('#000'); 18 | }); 19 | 20 | it('should render with default duration (1)', () => { 21 | expect(props.duration).to.be.equal(1); 22 | }); 23 | 24 | it('should render with default size (11)', () => { 25 | expect(props.size).to.be.equal(11); 26 | }); 27 | }); 28 | 29 | describe('custom', () => { 30 | const wrapper = mount( 31 | , 36 | ); 37 | const props = wrapper.props(); 38 | 39 | it('should render', () => { 40 | expect(wrapper.find(BarLoader)).to.exist; 41 | }); 42 | 43 | it('should render with color equal #AAA', () => { 44 | expect(props.color).to.be.equal('#AAA'); 45 | }); 46 | 47 | it('should render with duration equal 5', () => { 48 | expect(props.duration).to.be.equal(5); 49 | }); 50 | 51 | it('should render with size equal 20', () => { 52 | expect(props.size).to.be.equal(20); 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /tests/lib/Bubble.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { BubbleLoader } from '../../lib/index'; 6 | 7 | describe('BubbleLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(BubbleLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default color (#000)', () => { 17 | expect(props.color).to.be.equal('#000'); 18 | }); 19 | 20 | it('should render with default duration (1.8)', () => { 21 | expect(props.duration).to.be.equal(1.8); 22 | }); 23 | 24 | it('should render with default size (10)', () => { 25 | expect(props.size).to.be.equal(10); 26 | }); 27 | }); 28 | 29 | describe('custom', () => { 30 | const wrapper = mount( 31 | , 36 | ); 37 | const props = wrapper.props(); 38 | 39 | it('should render', () => { 40 | expect(wrapper.find(BubbleLoader)).to.exist; 41 | }); 42 | 43 | it('should render with color equal #AAA', () => { 44 | expect(props.color).to.be.equal('#AAA'); 45 | }); 46 | 47 | it('should render with duration equal 5', () => { 48 | expect(props.duration).to.be.equal(5); 49 | }); 50 | 51 | it('should render with size equal 20', () => { 52 | expect(props.size).to.be.equal(20); 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /tests/lib/BubbleSpin.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { BubbleSpinLoader } from '../../lib/index'; 6 | 7 | describe('BubbleSpinLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(BubbleSpinLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default color (#000)', () => { 17 | expect(props.color).to.be.equal('#000'); 18 | }); 19 | 20 | it('should render with default duration (1.3)', () => { 21 | expect(props.duration).to.be.equal(1.3); 22 | }); 23 | 24 | it('should render with default size (20)', () => { 25 | expect(props.size).to.be.equal(20); 26 | }); 27 | }); 28 | 29 | describe('custom', () => { 30 | const wrapper = mount( 31 | , 36 | ); 37 | const props = wrapper.props(); 38 | 39 | it('should render', () => { 40 | expect(wrapper.find(BubbleSpinLoader)).to.exist; 41 | }); 42 | 43 | it('should render with color equal #AAA', () => { 44 | expect(props.color).to.be.equal('#AAA'); 45 | }); 46 | 47 | it('should render with duration equal 5', () => { 48 | expect(props.duration).to.be.equal(5); 49 | }); 50 | 51 | it('should render with size equal 30', () => { 52 | expect(props.size).to.be.equal(30); 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /tests/lib/CometSpen.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { CometSpinLoader } from '../../lib/index'; 6 | 7 | describe('CometSpinLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(CometSpinLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default color (#000)', () => { 17 | expect(props.color).to.be.equal('#000'); 18 | }); 19 | 20 | it('should render with default duration (1.7)', () => { 21 | expect(props.duration).to.be.equal(1.7); 22 | }); 23 | 24 | it('should render with default size (90)', () => { 25 | expect(props.size).to.be.equal(90); 26 | }); 27 | }); 28 | 29 | describe('custom', () => { 30 | const wrapper = mount( 31 | , 36 | ); 37 | const props = wrapper.props(); 38 | 39 | it('should render', () => { 40 | expect(wrapper.find(CometSpinLoader)).to.exist; 41 | }); 42 | 43 | it('should render with color equal #AAA', () => { 44 | expect(props.color).to.be.equal('#AAA'); 45 | }); 46 | 47 | it('should render with duration equal 5', () => { 48 | expect(props.duration).to.be.equal(5); 49 | }); 50 | 51 | it('should render with size equal 20', () => { 52 | expect(props.size).to.be.equal(20); 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /tests/lib/CylinderSpin.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { CylinderSpinLoader } from '../../lib/index'; 6 | 7 | describe('CylinderSpinLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(CylinderSpinLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default color (#000)', () => { 17 | expect(props.color).to.be.equal('#000'); 18 | }); 19 | 20 | it('should render with default duration (1.1)', () => { 21 | expect(props.duration).to.be.equal(1.1); 22 | }); 23 | 24 | it('should render with default size (25)', () => { 25 | expect(props.size).to.be.equal(25); 26 | }); 27 | }); 28 | 29 | describe('custom', () => { 30 | const wrapper = mount( 31 | , 36 | ); 37 | const props = wrapper.props(); 38 | 39 | it('should render', () => { 40 | expect(wrapper.find(CylinderSpinLoader)).to.exist; 41 | }); 42 | 43 | it('should render with color equal #AAA', () => { 44 | expect(props.color).to.be.equal('#AAA'); 45 | }); 46 | 47 | it('should render with duration equal 5', () => { 48 | expect(props.duration).to.be.equal(5); 49 | }); 50 | 51 | it('should render with size equal 20', () => { 52 | expect(props.size).to.be.equal(20); 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /tests/lib/ResizeSpin.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { ResizeSpinLoader } from '../../lib/index'; 6 | 7 | describe('ResizeSpinLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(ResizeSpinLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default background (#fff)', () => { 17 | expect(props.background).to.be.equal('#fff'); 18 | }); 19 | 20 | it('should render with default color (#000)', () => { 21 | expect(props.color).to.be.equal('#000'); 22 | }); 23 | 24 | it('should render with default duration (2)', () => { 25 | expect(props.duration).to.be.equal(2); 26 | }); 27 | 28 | it('should render with default size (11)', () => { 29 | expect(props.size).to.be.equal(11); 30 | }); 31 | }); 32 | 33 | describe('custom', () => { 34 | const wrapper = mount( 35 | , 41 | ); 42 | const props = wrapper.props(); 43 | 44 | it('should render', () => { 45 | expect(wrapper.find(ResizeSpinLoader)).to.exist; 46 | }); 47 | 48 | it('should render with background equal #000', () => { 49 | expect(props.background).to.be.equal('#000'); 50 | }); 51 | 52 | it('should render with color equal #AAA', () => { 53 | expect(props.color).to.be.equal('#AAA'); 54 | }); 55 | 56 | it('should render with duration equal 5', () => { 57 | expect(props.duration).to.be.equal(5); 58 | }); 59 | 60 | it('should render with size equal 20', () => { 61 | expect(props.size).to.be.equal(20); 62 | }); 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /tests/lib/RotateSpin.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { RotateSpinLoader } from '../../lib/index'; 6 | 7 | describe('RotateSpinLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(RotateSpinLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default color (#000)', () => { 17 | expect(props.color).to.be.equal('#000'); 18 | }); 19 | 20 | it('should render with default duration (1.1)', () => { 21 | expect(props.duration).to.be.equal(1.1); 22 | }); 23 | 24 | it('should render with default size (10)', () => { 25 | expect(props.size).to.be.equal(10); 26 | }); 27 | }); 28 | 29 | describe('custom', () => { 30 | const wrapper = mount( 31 | , 36 | ); 37 | const props = wrapper.props(); 38 | 39 | it('should render', () => { 40 | expect(wrapper.find(RotateSpinLoader)).to.exist; 41 | }); 42 | 43 | it('should render with color equal #AAA', () => { 44 | expect(props.color).to.be.equal('#AAA'); 45 | }); 46 | 47 | it('should render with duration equal 5', () => { 48 | expect(props.duration).to.be.equal(5); 49 | }); 50 | 51 | it('should render with size equal 20', () => { 52 | expect(props.size).to.be.equal(20); 53 | }); 54 | }); 55 | }); 56 | -------------------------------------------------------------------------------- /tests/lib/Spin.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it } from 'mocha'; 3 | import { expect } from 'chai'; 4 | import { mount } from 'enzyme'; 5 | import { SpinLoader } from '../../lib/index'; 6 | 7 | describe('SpinLoader', () => { 8 | describe('default', () => { 9 | const wrapper = mount(); 10 | const props = wrapper.props(); 11 | 12 | it('should render', () => { 13 | expect(wrapper.find(SpinLoader)).to.exist; 14 | }); 15 | 16 | it('should render with default background (#fff)', () => { 17 | expect(props.background).to.be.equal('#fff'); 18 | }); 19 | 20 | it('should render with default color (#000)', () => { 21 | expect(props.color).to.be.equal('#000'); 22 | }); 23 | 24 | it('should render with default duration (1.4)', () => { 25 | expect(props.duration).to.be.equal(1.4); 26 | }); 27 | 28 | it('should render with default size (10)', () => { 29 | expect(props.size).to.be.equal(10); 30 | }); 31 | }); 32 | 33 | describe('custom', () => { 34 | const wrapper = mount( 35 | , 41 | ); 42 | const props = wrapper.props(); 43 | 44 | it('should render', () => { 45 | expect(wrapper.find(SpinLoader)).to.exist; 46 | }); 47 | 48 | it('should render with background equal #000', () => { 49 | expect(props.background).to.be.equal('#000'); 50 | }); 51 | 52 | it('should render with color equal #AAA', () => { 53 | expect(props.color).to.be.equal('#AAA'); 54 | }); 55 | 56 | it('should render with duration equal 5', () => { 57 | expect(props.duration).to.be.equal(5); 58 | }); 59 | 60 | it('should render with size equal 20', () => { 61 | expect(props.size).to.be.equal(20); 62 | }); 63 | }); 64 | }); 65 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: path.resolve(__dirname, 'app/main.jsx'), 5 | output: { 6 | path: path.resolve(__dirname, 'app'), 7 | publicPath: '/', 8 | filename: 'bundle.js', 9 | }, 10 | devServer: { 11 | contentBase: path.join(__dirname, 'app'), 12 | }, 13 | resolve: { 14 | extensions: ['.js', '.jsx'], 15 | }, 16 | devtool: 'source-map', 17 | module: { 18 | rules: [ 19 | { 20 | test: /\.jsx?$/, 21 | exclude: /(node_modules|bower_components)/, 22 | use: ['babel-loader'], 23 | }, 24 | ], 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: path.resolve(__dirname, 'lib/index'), 5 | output: { 6 | path: path.resolve(__dirname, 'dist'), 7 | library: 'reactLoaders', 8 | libraryTarget: 'umd', 9 | }, 10 | resolve: { 11 | extensions: ['.js', '.jsx'], 12 | }, 13 | module: { 14 | rules: [ 15 | { 16 | test: /\.jsx?$/, 17 | exclude: /(node_modules|bower_components)/, 18 | use: ['babel-loader'], 19 | }, 20 | ], 21 | }, 22 | }; 23 | --------------------------------------------------------------------------------