├── .babelrc ├── .eslintrc ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── css ├── base.css ├── chasing-dots.css ├── circle.css ├── cube-grid.css ├── double-bounce.css ├── fade-in.css ├── fading-circle.css ├── folding-cube.css ├── loaders-css.css ├── pulse.css ├── rotating-plane.css ├── three-bounce.css ├── wandering-cubes.css ├── wave.css └── wordpress.css ├── package.json ├── src ├── index.jsx └── spinners.js ├── test ├── index.test.jsx └── mocha.opts ├── www ├── .gatsby-context.js ├── README.md ├── config.toml ├── html.js ├── package.json ├── pages │ ├── 404.md │ ├── _template.jsx │ └── index.js ├── utils │ └── typography.js └── yarn.lock └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react", "stage-0"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": [ 4 | "eslint-config-airbnb", 5 | ], 6 | "env": { 7 | "browser": true, 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.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 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | dist 27 | examples/bundle.js 28 | public/ 29 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 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 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Deployed apps should consider commenting this line out: 24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 25 | node_modules 26 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4" 4 | - "6" 5 | before_script: 6 | - npm install 7 | - npm test 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Kyle Mathews 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BIN = ./node_modules/.bin 2 | 3 | release-patch: 4 | @$(call release,patch) 5 | 6 | release-minor: 7 | @$(call release,minor) 8 | 9 | release-major: 10 | @$(call release,major) 11 | 12 | build: 13 | npm run build 14 | @$(BIN)/webpack 15 | 16 | publish: 17 | git push --tags origin HEAD:master 18 | npm run build 19 | npm publish 20 | 21 | publish-gh-pages: 22 | git checkout gh-pages 23 | git merge master 24 | webpack 25 | cp examples/* . 26 | git add --all . 27 | git commit -m "New release" 28 | git push origin gh-pages 29 | git checkout master 30 | 31 | define release 32 | npm version $(1) 33 | endef 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | react-spinkit 2 | ============= 3 | 4 | A collection of loading indicators animated with CSS for React 5 | 6 | Currently I've ported all the spinner animations from 7 | [Spinkit](https://github.com/tobiasahlin/SpinKit). If you have other favorite 8 | css spinner you'd like to include, open an issue. 9 | 10 | ## Install 11 | 12 | ```console 13 | $ npm install react-spinkit --save 14 | ``` 15 | 16 | ## Usage 17 | ```javascript 18 | var Spinner = require('react-spinkit'); 19 | 20 | 21 | ``` 22 | 23 | See more examples on the [demo page](http://kyleamathews.github.io/react-spinkit/). 24 | 25 | ## CSS 26 | CSS is loaded automatically when using [Webpack](http://webpack.github.io) with the 27 | [css-loader](https://github.com/webpack/css-loader) and [style-loader](https://github.com/webpack/style-loader), or Browserify/[CSSify](https://github.com/davidguttman/cssify) 28 | to build your project. 29 | 30 | ## External spinners 31 | This also includes most of the spinners from [loaders.css](https://github.com/ConnorAtherton/loaders.css). Note that while 32 | all of the native spinners from Spinkit are contained within their bounding divs, 33 | some of the loaders.css spinners have a zero-sized parent div and extend outward 34 | from that (as you can see on the demos page). Regardless of this, they are all 35 | easily centerable with flexbox. 36 | 37 | ## Webpack or Browserify is required 38 | Currently we only support Browserify and Webpack. If you'd like support 39 | for other build tools that also support requiring CSS, PRs are welcome. 40 | 41 | ## Fades in spinners after one second 42 | According to [research by Jakob Nielsen](http://www.nngroup.com/articles/response-times-3-important-limits/), 43 | feedback after user operations isn't necessary for about a second so by 44 | default, react-spinkit will fade in your spinner at one second. Nevertheless, 45 | you can configure spinner fade-in behavior with the `fadeIn` prop, which 46 | accepts values `full` (the default), `half`, `quarter`, and `none` for one 47 | second, a half second, a quarter second, and no fade in, respectively. 48 | For example: ``. 49 | 50 | ## PropTypes 51 | * **name**—specify spinner to use (defaults to `three-bounce`). 52 | * **fadeIn**-set the time before the spinner fades in. 53 | * **overrideSpinnerClassName**—change the default `sk-spinner` className. 54 | * **className**-add a custom classname to the outer div. 55 | * **color**-programmatically set the color of the spinners; this can either be a 56 | hex value or a color word. 57 | 58 | ## Server-side rendering 59 | If you want to use this for server-side rendering, set 60 | `process.env.REACT_SPINKIT_NO_STYLES` in your server build environment, 61 | in webpack via `webpack.DefinePlugin`, or whatever is appropriate to your 62 | build process. This will skip the import of styles and allow evaluation of 63 | the SpinKit code in node. 64 | 65 | ## Demo and documentation 66 | http://kyleamathews.github.io/react-spinkit/ 67 | -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | .sk-spinner { 2 | color: #333; 3 | } 4 | 5 | .sk-spinner > div { 6 | background-color: currentColor; 7 | } 8 | -------------------------------------------------------------------------------- /css/chasing-dots.css: -------------------------------------------------------------------------------- 1 | .sk-chasing-dots { 2 | width: 27px; 3 | height: 27px; 4 | position: relative; 5 | 6 | -webkit-animation: sk-rotate 2.0s infinite linear; 7 | animation: sk-rotate 2.0s infinite linear; 8 | } 9 | 10 | .sk-chasing-dots > div { 11 | width: 60%; 12 | height: 60%; 13 | display: inline-block; 14 | position: absolute; 15 | top: 0; 16 | background-color: currentColor; 17 | border-radius: 100%; 18 | 19 | -webkit-animation: sk-bounce 2.0s infinite ease-in-out; 20 | animation: sk-bounce 2.0s infinite ease-in-out; 21 | } 22 | 23 | .sk-chasing-dots > div:last-child { 24 | top: auto; 25 | bottom: 0; 26 | 27 | -webkit-animation-delay: -1.0s; 28 | animation-delay: -1.0s; 29 | } 30 | 31 | @-webkit-keyframes sk-rotate { 100% { -webkit-transform: rotate(360deg) }} 32 | @keyframes sk-rotate { 33 | 100% { 34 | transform: rotate(360deg); 35 | -webkit-transform: rotate(360deg); 36 | } 37 | } 38 | 39 | @-webkit-keyframes sk-bounce { 40 | 0%, 100% { -webkit-transform: scale(0.0) } 41 | 50% { -webkit-transform: scale(1.0) } 42 | } 43 | 44 | @keyframes sk-bounce { 45 | 0%, 100% { 46 | transform: scale(0.0); 47 | -webkit-transform: scale(0.0); 48 | } 50% { 49 | transform: scale(1.0); 50 | -webkit-transform: scale(1.0); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /css/circle.css: -------------------------------------------------------------------------------- 1 | .sk-circle { 2 | width: 22px; 3 | height: 22px; 4 | position: relative; 5 | } 6 | 7 | .sk-circle > div { 8 | background-color: initial; 9 | width: 100%; 10 | height: 100%; 11 | position: absolute; 12 | left: 0; 13 | top: 0; 14 | } 15 | 16 | .sk-circle > div::before { 17 | content: ''; 18 | display: block; 19 | margin: 0 auto; 20 | width: 20%; 21 | height: 20%; 22 | background-color: currentColor; 23 | border-radius: 100%; 24 | 25 | -webkit-animation: sk-bouncedelay 1.2s infinite ease-in-out; 26 | animation: sk-bouncedelay 1.2s infinite ease-in-out; 27 | /* Prevent first frame from flickering when animation starts */ 28 | -webkit-animation-fill-mode: both; 29 | animation-fill-mode: both; 30 | } 31 | 32 | .sk-circle > div:nth-child(2) { -webkit-transform: rotate(30deg); transform: rotate(30deg) } 33 | .sk-circle > div:nth-child(3) { -webkit-transform: rotate(60deg); transform: rotate(60deg) } 34 | .sk-circle > div:nth-child(4) { -webkit-transform: rotate(90deg); transform: rotate(90deg) } 35 | .sk-circle > div:nth-child(5) { -webkit-transform: rotate(120deg); transform: rotate(120deg) } 36 | .sk-circle > div:nth-child(6) { -webkit-transform: rotate(150deg); transform: rotate(150deg) } 37 | .sk-circle > div:nth-child(7) { -webkit-transform: rotate(180deg); transform: rotate(180deg) } 38 | .sk-circle > div:nth-child(8) { -webkit-transform: rotate(210deg); transform: rotate(210deg) } 39 | .sk-circle > div:nth-child(9) { -webkit-transform: rotate(240deg); transform: rotate(240deg) } 40 | .sk-circle > div:nth-child(10) { -webkit-transform: rotate(270deg); transform: rotate(270deg) } 41 | .sk-circle > div:nth-child(11) { -webkit-transform: rotate(300deg); transform: rotate(300deg) } 42 | .sk-circle > div:nth-child(12) { -webkit-transform: rotate(330deg); transform: rotate(330deg) } 43 | 44 | .sk-circle > div:nth-child(2)::before { -webkit-animation-delay: -1.1s; animation-delay: -1.1s } 45 | .sk-circle > div:nth-child(3)::before { -webkit-animation-delay: -1.0s; animation-delay: -1.0s } 46 | .sk-circle > div:nth-child(4)::before { -webkit-animation-delay: -0.9s; animation-delay: -0.9s } 47 | .sk-circle > div:nth-child(5)::before { -webkit-animation-delay: -0.8s; animation-delay: -0.8s } 48 | .sk-circle > div:nth-child(6)::before { -webkit-animation-delay: -0.7s; animation-delay: -0.7s } 49 | .sk-circle > div:nth-child(7)::before { -webkit-animation-delay: -0.6s; animation-delay: -0.6s } 50 | .sk-circle > div:nth-child(8)::before { -webkit-animation-delay: -0.5s; animation-delay: -0.5s } 51 | .sk-circle > div:nth-child(9)::before { -webkit-animation-delay: -0.4s; animation-delay: -0.4s } 52 | .sk-circle > div:nth-child(10)::before { -webkit-animation-delay: -0.3s; animation-delay: -0.3s } 53 | .sk-circle > div:nth-child(11)::before { -webkit-animation-delay: -0.2s; animation-delay: -0.2s } 54 | .sk-circle > div:nth-child(12)::before { -webkit-animation-delay: -0.1s; animation-delay: -0.1s } 55 | 56 | @-webkit-keyframes sk-bouncedelay { 57 | 0%, 80%, 100% { -webkit-transform: scale(0.0) } 58 | 40% { -webkit-transform: scale(1.0) } 59 | } 60 | 61 | @keyframes sk-bouncedelay { 62 | 0%, 80%, 100% { 63 | -webkit-transform: scale(0.0); 64 | transform: scale(0.0); 65 | } 40% { 66 | -webkit-transform: scale(1.0); 67 | transform: scale(1.0); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /css/cube-grid.css: -------------------------------------------------------------------------------- 1 | .sk-cube-grid { 2 | width: 27px; 3 | height: 27px; 4 | } 5 | 6 | .sk-cube-grid > div { 7 | width: 33%; 8 | height: 33%; 9 | background-color: currentColor; 10 | float: left; 11 | 12 | -webkit-animation: sk-scaleDelay 1.3s infinite ease-in-out; 13 | animation: sk-scaleDelay 1.3s infinite ease-in-out; 14 | } 15 | 16 | /* 17 | * Spinner positions 18 | * 1 2 3 19 | * 4 5 6 20 | * 7 8 9 21 | */ 22 | 23 | .sk-cube-grid > div:nth-child(1) { -webkit-animation-delay: 0.2s; animation-delay: 0.2s } 24 | .sk-cube-grid > div:nth-child(2) { -webkit-animation-delay: 0.3s; animation-delay: 0.3s } 25 | .sk-cube-grid > div:nth-child(3) { -webkit-animation-delay: 0.4s; animation-delay: 0.4s } 26 | .sk-cube-grid > div:nth-child(4) { -webkit-animation-delay: 0.1s; animation-delay: 0.1s } 27 | .sk-cube-grid > div:nth-child(5) { -webkit-animation-delay: 0.2s; animation-delay: 0.2s } 28 | .sk-cube-grid > div:nth-child(6) { -webkit-animation-delay: 0.3s; animation-delay: 0.3s } 29 | .sk-cube-grid > div:nth-child(7) { -webkit-animation-delay: 0.0s; animation-delay: 0.0s } 30 | .sk-cube-grid > div:nth-child(8) { -webkit-animation-delay: 0.1s; animation-delay: 0.1s } 31 | .sk-cube-grid > div:nth-child(9) { -webkit-animation-delay: 0.2s; animation-delay: 0.2s } 32 | 33 | @-webkit-keyframes sk-scaleDelay { 34 | 0%, 70%, 100% { -webkit-transform:scale3D(1.0, 1.0, 1.0) } 35 | 35% { -webkit-transform:scale3D(0.0, 0.0, 1.0) } 36 | } 37 | 38 | @keyframes sk-scaleDelay { 39 | 0%, 70%, 100% { -webkit-transform:scale3D(1.0, 1.0, 1.0); transform:scale3D(1.0, 1.0, 1.0) } 40 | 35% { -webkit-transform:scale3D(1.0, 1.0, 1.0); transform:scale3D(0.0, 0.0, 1.0) } 41 | } 42 | -------------------------------------------------------------------------------- /css/double-bounce.css: -------------------------------------------------------------------------------- 1 | .sk-double-bounce { 2 | width: 27px; 3 | height: 27px; 4 | position: relative; 5 | } 6 | 7 | .sk-double-bounce > div { 8 | width: 100%; 9 | height: 100%; 10 | border-radius: 50%; 11 | background-color: currentColor; 12 | opacity: 0.6; 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | 17 | -webkit-animation: sk-bounce 2.0s infinite ease-in-out; 18 | animation: sk-bounce 2.0s infinite ease-in-out; 19 | } 20 | 21 | .sk-double-bounce > div:last-child { 22 | -webkit-animation-delay: -1.0s; 23 | animation-delay: -1.0s; 24 | } 25 | 26 | @-webkit-keyframes sk-bounce { 27 | 0%, 100% { -webkit-transform: scale(0.0) } 28 | 50% { -webkit-transform: scale(1.0) } 29 | } 30 | 31 | @keyframes sk-bounce { 32 | 0%, 100% { 33 | transform: scale(0.0); 34 | -webkit-transform: scale(0.0); 35 | } 50% { 36 | transform: scale(1.0); 37 | -webkit-transform: scale(1.0); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /css/fade-in.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes sk-fade-in { 2 | 0% { 3 | opacity: 0; 4 | } 5 | 50% { 6 | opacity: 0; 7 | } 8 | 100% { 9 | opacity: 1; 10 | } 11 | } 12 | 13 | @-moz-keyframes sk-fade-in { 14 | 0% { 15 | opacity: 0; 16 | } 17 | 50% { 18 | opacity: 0; 19 | } 20 | 100% { 21 | opacity: 1; 22 | } 23 | } 24 | 25 | @-ms-keyframes sk-fade-in { 26 | 0% { 27 | opacity: 0; 28 | } 29 | 50% { 30 | opacity: 0; 31 | } 32 | 100% { 33 | opacity: 1; 34 | } 35 | } 36 | 37 | @keyframes sk-fade-in { 38 | 0% { 39 | opacity: 0; 40 | } 41 | 50% { 42 | opacity: 0; 43 | } 44 | 100% { 45 | opacity: 1; 46 | } 47 | } 48 | 49 | .sk-fade-in { 50 | -webkit-animation: sk-fade-in 2s; 51 | -moz-animation: sk-fade-in 2s; 52 | -o-animation: sk-fade-in 2s; 53 | -ms-animation: sk-fade-in 2s; 54 | animation: sk-fade-in 2s; 55 | } 56 | 57 | .sk-fade-in-half-second { 58 | -webkit-animation: sk-fade-in 1s; 59 | -moz-animation: sk-fade-in 1s; 60 | -o-animation: sk-fade-in 1s; 61 | -ms-animation: sk-fade-in 1s; 62 | animation: sk-fade-in 1s; 63 | } 64 | 65 | .sk-fade-in-quarter-second { 66 | -webkit-animation: sk-fade-in 0.5s; 67 | -moz-animation: sk-fade-in 0.5s; 68 | -o-animation: sk-fade-in 0.5s; 69 | -ms-animation: sk-fade-in 0.5s; 70 | animation: sk-fade-in 0.5s; 71 | } 72 | -------------------------------------------------------------------------------- /css/fading-circle.css: -------------------------------------------------------------------------------- 1 | .sk-fading-circle { 2 | width: 22px; 3 | height: 22px; 4 | position: relative; 5 | } 6 | 7 | .sk-fading-circle .sk-circle { 8 | width: 100%; 9 | height: 100%; 10 | position: absolute; 11 | left: 0; 12 | top: 0; 13 | } 14 | 15 | .sk-fading-circle .sk-circle:before { 16 | content: ''; 17 | display: block; 18 | margin: 0 auto; 19 | width: 18%; 20 | height: 18%; 21 | background-color: #333; 22 | 23 | border-radius: 100%; 24 | -webkit-animation: sk-fadedelay 1.2s infinite ease-in-out; 25 | animation: sk-fadedelay 1.2s infinite ease-in-out; 26 | /* Prevent first frame from flickering when animation starts */ 27 | -webkit-animation-fill-mode: both; 28 | animation-fill-mode: both; 29 | } 30 | 31 | .sk-circle2 { transform: rotate(30deg); -webkit-transform: rotate(30deg) } 32 | .sk-circle3 { transform: rotate(60deg); -webkit-transform: rotate(60deg) } 33 | .sk-circle4 { transform: rotate(90deg); -webkit-transform: rotate(90deg) } 34 | .sk-circle5 { transform: rotate(120deg); -webkit-transform: rotate(120deg) } 35 | .sk-circle6 { transform: rotate(150deg); -webkit-transform: rotate(150deg) } 36 | .sk-circle7 { transform: rotate(180deg); -webkit-transform: rotate(180deg) } 37 | .sk-circle8 { transform: rotate(210deg); -webkit-transform: rotate(210deg) } 38 | .sk-circle9 { transform: rotate(240deg); -webkit-transform: rotate(240deg) } 39 | .sk-circle10 { transform: rotate(270deg); -webkit-transform: rotate(270deg) } 40 | .sk-circle11 { transform: rotate(300deg); -webkit-transform: rotate(300deg) } 41 | .sk-circle12 { transform: rotate(330deg); -webkit-transform: rotate(330deg) } 42 | 43 | .sk-circle2:before { animation-delay: -1.1s; -webkit-animation-delay: -1.1s } 44 | .sk-circle3:before { animation-delay: -1.0s; -webkit-animation-delay: -1.0s } 45 | .sk-circle4:before { animation-delay: -0.9s; -webkit-animation-delay: -0.9s } 46 | .sk-circle5:before { animation-delay: -0.8s; -webkit-animation-delay: -0.8s } 47 | .sk-circle6:before { animation-delay: -0.7s; -webkit-animation-delay: -0.7s } 48 | .sk-circle7:before { animation-delay: -0.6s; -webkit-animation-delay: -0.6s } 49 | .sk-circle8:before { animation-delay: -0.5s; -webkit-animation-delay: -0.5s } 50 | .sk-circle9:before { animation-delay: -0.4s; -webkit-animation-delay: -0.4s } 51 | .sk-circle10:before { animation-delay: -0.3s; -webkit-animation-delay: -0.3s } 52 | .sk-circle11:before { animation-delay: -0.2s; -webkit-animation-delay: -0.2s } 53 | .sk-circle12:before { animation-delay: -0.1s; -webkit-animation-delay: -0.1s } 54 | 55 | @keyframes sk-fadedelay { 56 | 0%, 39%, 100% { opacity: 0 } 57 | 40% { opacity: 0 } 58 | } 59 | 60 | @-webkit-keyframes sk-fadedelay { 61 | 0%, 39%, 100% { opacity: 0 } 62 | 40% { opacity: 1 } 63 | } 64 | -------------------------------------------------------------------------------- /css/folding-cube.css: -------------------------------------------------------------------------------- 1 | .sk-folding-cube { 2 | width: 27px; 3 | height: 27px; 4 | position: relative; 5 | 6 | -webkit-transform: rotateZ(45deg); 7 | transform: rotateZ(45deg); 8 | } 9 | 10 | .sk-folding-cube > div { 11 | background-color: initial; 12 | float: left; 13 | width: 50%; 14 | height: 50%; 15 | position: relative; 16 | 17 | -webkit-transform: scale(1.1); 18 | -ms-transform: scale(1.1); 19 | transform: scale(1.1); 20 | } 21 | .sk-folding-cube > div::before { 22 | content: ''; 23 | position: absolute; 24 | top: 0; 25 | left: 0; 26 | width: 100%; 27 | height: 100%; 28 | background-color: currentColor; 29 | 30 | -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both; 31 | animation: sk-foldCubeAngle 2.4s infinite linear both; 32 | -webkit-transform-origin: 100% 100%; 33 | -ms-transform-origin: 100% 100%; 34 | transform-origin: 100% 100%; 35 | } 36 | .sk-folding-cube > div:nth-child(2) { 37 | -webkit-transform: scale(1.1) rotateZ(90deg); 38 | transform: scale(1.1) rotateZ(90deg); 39 | } 40 | .sk-folding-cube > div:nth-child(4) { 41 | -webkit-transform: scale(1.1) rotateZ(180deg); 42 | transform: scale(1.1) rotateZ(180deg); 43 | } 44 | .sk-folding-cube > div:nth-child(3) { 45 | -webkit-transform: scale(1.1) rotateZ(270deg); 46 | transform: scale(1.1) rotateZ(270deg); 47 | } 48 | .sk-folding-cube > div:nth-child(2)::before { 49 | -webkit-animation-delay: 0.3s; 50 | animation-delay: 0.3s; 51 | } 52 | .sk-folding-cube > div:nth-child(4)::before { 53 | -webkit-animation-delay: 0.6s; 54 | animation-delay: 0.6s; 55 | } 56 | .sk-folding-cube > div:nth-child(3)::before { 57 | -webkit-animation-delay: 0.9s; 58 | animation-delay: 0.9s; 59 | } 60 | @-webkit-keyframes sk-foldCubeAngle { 61 | 0%, 10% { 62 | -webkit-transform: perspective(140px) rotateX(-180deg); 63 | transform: perspective(140px) rotateX(-180deg); 64 | opacity: 0; 65 | } 25%, 75% { 66 | -webkit-transform: perspective(140px) rotateX(0deg); 67 | transform: perspective(140px) rotateX(0deg); 68 | opacity: 1; 69 | } 90%, 100% { 70 | -webkit-transform: perspective(140px) rotateY(180deg); 71 | transform: perspective(140px) rotateY(180deg); 72 | opacity: 0; 73 | } 74 | } 75 | 76 | @keyframes sk-foldCubeAngle { 77 | 0%, 10% { 78 | -webkit-transform: perspective(140px) rotateX(-180deg); 79 | transform: perspective(140px) rotateX(-180deg); 80 | opacity: 0; 81 | } 25%, 75% { 82 | -webkit-transform: perspective(140px) rotateX(0deg); 83 | transform: perspective(140px) rotateX(0deg); 84 | opacity: 1; 85 | } 90%, 100% { 86 | -webkit-transform: perspective(140px) rotateY(180deg); 87 | transform: perspective(140px) rotateY(180deg); 88 | opacity: 0; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /css/loaders-css.css: -------------------------------------------------------------------------------- 1 | .ball-triangle-path > div, 2 | .ball-scale-ripple-multiple > div, 3 | .ball-scale-ripple > div { 4 | background-color: initial; 5 | border-color: currentColor; 6 | } 7 | 8 | .ball-clip-rotate > div { 9 | background-color: initial; 10 | border-top-color: currentColor; 11 | border-right-color: currentColor; 12 | border-left-color: currentColor; 13 | } 14 | 15 | .ball-clip-rotate-pulse > div:first-child { 16 | background-color: currentColor; 17 | } 18 | .ball-clip-rotate-pulse > div:last-child { 19 | background-color: initial; 20 | border-top-color: currentColor; 21 | border-bottom-color: currentColor; 22 | } 23 | 24 | .ball-clip-rotate-multiple > div:first-child { 25 | background-color: initial; 26 | border-right-color: currentColor; 27 | border-left-color: currentColor; 28 | } 29 | .ball-clip-rotate-multiple > div:last-child { 30 | background-color: initial; 31 | border-top-color: currentColor; 32 | border-bottom-color: currentColor; 33 | } 34 | 35 | .triangle-skew-spin > div { 36 | background-color: initial; 37 | border-bottom-color: currentColor; 38 | } 39 | 40 | .pacman > div:nth-child(1), 41 | .pacman > div:nth-child(2) { 42 | background-color: initial; 43 | border-top-color: currentColor; 44 | border-left-color: currentColor; 45 | border-bottom-color: currentColor; 46 | } 47 | 48 | .pacman > div:nth-child(3), 49 | .pacman > div:nth-child(4), 50 | .pacman > div:nth-child(5) { 51 | background-color: currentColor; 52 | } 53 | -------------------------------------------------------------------------------- /css/pulse.css: -------------------------------------------------------------------------------- 1 | .sk-pulse > div { 2 | width: 27px; 3 | height: 27px; 4 | background-color: currentColor; 5 | border-radius: 100%; 6 | 7 | -webkit-animation: sk-scaleout 1.0s infinite ease-in-out; 8 | animation: sk-scaleout 1.0s infinite ease-in-out; 9 | } 10 | 11 | @-webkit-keyframes sk-scaleout { 12 | 0% { -webkit-transform: scale(0.0) } 13 | 100% { 14 | -webkit-transform: scale(1.0); 15 | opacity: 0; 16 | } 17 | } 18 | 19 | @keyframes sk-scaleout { 20 | 0% { 21 | transform: scale(0.0); 22 | -webkit-transform: scale(0.0); 23 | } 100% { 24 | transform: scale(1.0); 25 | -webkit-transform: scale(1.0); 26 | opacity: 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /css/rotating-plane.css: -------------------------------------------------------------------------------- 1 | .sk-rotating-plane > div { 2 | width: 27px; 3 | height: 27px; 4 | background-color: currentColor; 5 | 6 | -webkit-animation: sk-rotateplane 1.2s infinite ease-in-out; 7 | animation: sk-rotateplane 1.2s infinite ease-in-out; 8 | } 9 | 10 | @-webkit-keyframes sk-rotateplane { 11 | 0% { -webkit-transform: perspective(120px) } 12 | 50% { -webkit-transform: perspective(120px) rotateY(180deg) } 13 | 100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) } 14 | } 15 | 16 | @keyframes sk-rotateplane { 17 | 0% { 18 | transform: perspective(120px) rotateX(0deg) rotateY(0deg); 19 | -webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); 20 | } 50% { 21 | transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); 22 | -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); 23 | } 100% { 24 | transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 25 | -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /css/three-bounce.css: -------------------------------------------------------------------------------- 1 | .sk-three-bounce { 2 | height: 18px; 3 | } 4 | 5 | .sk-three-bounce > div { 6 | width: 18px; 7 | height: 18px; 8 | background-color: currentColor; 9 | border-radius: 100%; 10 | display: inline-block; 11 | 12 | -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out; 13 | animation: sk-bouncedelay 1.4s infinite ease-in-out; 14 | /* Prevent first frame from flickering when animation starts */ 15 | -webkit-animation-fill-mode: both; 16 | animation-fill-mode: both; 17 | } 18 | 19 | .sk-three-bounce > div:first-child { 20 | -webkit-animation-delay: -0.32s; 21 | animation-delay: -0.32s; 22 | } 23 | 24 | .sk-three-bounce > div:nth-child(2) { 25 | -webkit-animation-delay: -0.16s; 26 | animation-delay: -0.16s; 27 | } 28 | 29 | @-webkit-keyframes sk-bouncedelay { 30 | 0%, 80%, 100% { -webkit-transform: scale(0.0) } 31 | 40% { -webkit-transform: scale(1.0) } 32 | } 33 | 34 | @keyframes sk-bouncedelay { 35 | 0%, 80%, 100% { 36 | transform: scale(0.0); 37 | -webkit-transform: scale(0.0); 38 | } 40% { 39 | transform: scale(1.0); 40 | -webkit-transform: scale(1.0); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /css/wandering-cubes.css: -------------------------------------------------------------------------------- 1 | .sk-wandering-cubes { 2 | width: 52px; 3 | height: 52px; 4 | position: relative; 5 | } 6 | 7 | .sk-wandering-cubes > div { 8 | background-color: currentColor; 9 | width: 10px; 10 | height: 10px; 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | 15 | -webkit-animation: sk-cubemove 1.8s infinite ease-in-out; 16 | animation: sk-cubemove 1.8s infinite ease-in-out; 17 | } 18 | 19 | .sk-wandering-cubes > div:last-child { 20 | -webkit-animation-delay: -0.9s; 21 | animation-delay: -0.9s; 22 | } 23 | 24 | @-webkit-keyframes sk-cubemove { 25 | 25% { -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5) } 26 | 50% { -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg) } 27 | 75% { -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5) } 28 | 100% { -webkit-transform: rotate(-360deg) } 29 | } 30 | 31 | @keyframes sk-cubemove { 32 | 25% { 33 | transform: translateX(42px) rotate(-90deg) scale(0.5); 34 | -webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); 35 | } 50% { 36 | /* Hack to make FF rotate in the right direction */ 37 | transform: translateX(42px) translateY(42px) rotate(-179deg); 38 | -webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); 39 | } 50.1% { 40 | transform: translateX(42px) translateY(42px) rotate(-180deg); 41 | -webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); 42 | } 75% { 43 | transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); 44 | -webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); 45 | } 100% { 46 | transform: rotate(-360deg); 47 | -webkit-transform: rotate(-360deg); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /css/wave.css: -------------------------------------------------------------------------------- 1 | .sk-wave { 2 | width: 30px; 3 | height: 27px; 4 | } 5 | 6 | .sk-wave > div { 7 | background-color: currentColor; 8 | height: 100%; 9 | width: 6px; 10 | display: inline-block; 11 | 12 | -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out; 13 | animation: sk-stretchdelay 1.2s infinite ease-in-out; 14 | } 15 | 16 | .sk-wave > div:nth-child(2) { 17 | -webkit-animation-delay: -1.1s; 18 | animation-delay: -1.1s; 19 | } 20 | 21 | .sk-wave > div:nth-child(3) { 22 | -webkit-animation-delay: -1.0s; 23 | animation-delay: -1.0s; 24 | } 25 | 26 | .sk-wave > div:nth-child(4) { 27 | -webkit-animation-delay: -0.9s; 28 | animation-delay: -0.9s; 29 | } 30 | 31 | .sk-wave > div:nth-child(5) { 32 | -webkit-animation-delay: -0.8s; 33 | animation-delay: -0.8s; 34 | } 35 | 36 | @-webkit-keyframes sk-stretchdelay { 37 | 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 38 | 20% { -webkit-transform: scaleY(1.0) } 39 | } 40 | 41 | @keyframes sk-stretchdelay { 42 | 0%, 40%, 100% { 43 | transform: scaleY(0.4); 44 | -webkit-transform: scaleY(0.4); 45 | } 20% { 46 | transform: scaleY(1.0); 47 | -webkit-transform: scaleY(1.0); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /css/wordpress.css: -------------------------------------------------------------------------------- 1 | .sk-wordpress > div { 2 | width: 27px; 3 | height: 27px; 4 | background-color: currentColor; 5 | display: inline-block; 6 | border-radius: 27px; 7 | position: relative; 8 | 9 | -webkit-animation: sk-inner-circle 1s linear infinite; 10 | animation: sk-inner-circle 1s linear infinite; 11 | } 12 | 13 | .sk-wordpress > div::after { 14 | content: ''; 15 | display: block; 16 | background-color: #fff; 17 | width: 8px; 18 | height: 8px; 19 | position: absolute; 20 | border-radius: 8px; 21 | top: 5px; 22 | left: 5px; 23 | } 24 | 25 | @-webkit-keyframes sk-inner-circle { 26 | 0% { -webkit-transform: rotate(0); } 27 | 100% { -webkit-transform: rotate(360deg); } 28 | } 29 | 30 | @keyframes sk-inner-circle { 31 | 0% { transform: rotate(0); -webkit-transform:rotate(0); } 32 | 100% { transform: rotate(360deg); -webkit-transform:rotate(360deg); } 33 | } 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-spinkit", 3 | "description": "A collection of loading indicators animated with CSS for React", 4 | "version": "3.0.0", 5 | "author": "Kyle Mathews ", 6 | "browserify": { 7 | "transform": [ 8 | "cssify" 9 | ] 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/KyleAMathews/react-spinkit/issues" 13 | }, 14 | "dependencies": { 15 | "classnames": "^2.2.3", 16 | "loaders.css": "^0.1.2", 17 | "object-assign": "^4.1.0", 18 | "prop-types": "^15.5.8" 19 | }, 20 | "devDependencies": { 21 | "babel-cli": "^6.11.4", 22 | "babel-core": "^6.13.2", 23 | "babel-eslint": "^6.1.2", 24 | "babel-loader": "^6.2.4", 25 | "babel-preset-es2015": "^6.13.2", 26 | "babel-preset-react": "^6.11.1", 27 | "babel-preset-stage-0": "^6.5.0", 28 | "chai": "^3.5.0", 29 | "css-loader": "^0.23.1", 30 | "cssify": "^1.0.2", 31 | "enzyme": "^2.6.0", 32 | "eslint": "^3.2.2", 33 | "eslint-config-airbnb": "^10.0.0", 34 | "eslint-plugin-import": "^1.12.0", 35 | "eslint-plugin-jsx-a11y": "^2.0.1", 36 | "eslint-plugin-react": "^6.0.0", 37 | "ignore-styles": "^5.0.1", 38 | "mkdirp": "^0.5.1", 39 | "mocha": "^3.1.2", 40 | "react": "^15.3.0", 41 | "react-addons-test-utils": "^15.4.0", 42 | "react-dom": "^15.3.0", 43 | "style-loader": "^0.13.1", 44 | "webpack": "^1.13.0" 45 | }, 46 | "homepage": "https://github.com/KyleAMathews/react-spinkit", 47 | "keywords": [ 48 | "react", 49 | "react-component", 50 | "spinkit", 51 | "spinners" 52 | ], 53 | "license": "MIT", 54 | "main": "dist/index.js", 55 | "repository": { 56 | "type": "git", 57 | "url": "https://github.com/KyleAMathews/react-spinkit.git" 58 | }, 59 | "scripts": { 60 | "test": "npm run lint && npm run mocha", 61 | "build": "babel src --out-dir dist/", 62 | "lint": "eslint --ext .js,.jsx --ignore-path .gitignore --ignore-pattern www --ignore-pattern test --ignore-pattern node_modules .", 63 | "mocha": "./node_modules/.bin/mocha mocha ./test/**/*.test.jsx --opts ./test/mocha.opts", 64 | "watch": "babel -w src --out-dir dist/" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/index.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React from 'react'; // eslint-disable-line import/no-extraneous-dependencies 3 | import cx from 'classnames'; 4 | import assign from 'object-assign'; 5 | import { allSpinners } from './spinners'; 6 | 7 | if (!process.env.REACT_SPINKIT_NO_STYLES) { 8 | /* eslint-disable global-require */ 9 | require('loaders.css'); 10 | require('../css/base.css'); 11 | require('../css/loaders-css.css'); 12 | require('../css/fade-in.css'); 13 | require('../css/chasing-dots.css'); 14 | require('../css/circle.css'); 15 | require('../css/cube-grid.css'); 16 | require('../css/double-bounce.css'); 17 | require('../css/folding-cube.css'); 18 | require('../css/pulse.css'); 19 | require('../css/rotating-plane.css'); 20 | require('../css/three-bounce.css'); 21 | require('../css/wandering-cubes.css'); 22 | require('../css/wave.css'); 23 | require('../css/wordpress.css'); 24 | /* eslint-enable global-require */ 25 | } 26 | 27 | const noFadeInWarning = 28 | "Deprecation Warning (react-spinkit): noFadeIn prop should be replaced with fadeIn='none'"; 29 | 30 | class Spinner extends React.Component { 31 | 32 | constructor(props) { 33 | if (props.noFadeIn) { 34 | console.warn(noFadeInWarning); // eslint-disable-line no-console 35 | } 36 | super(props); 37 | this.displayName = 'SpinKit'; 38 | } 39 | 40 | render() { 41 | const spinnerInfo = allSpinners[this.props.name] || allSpinners['three-bounce']; 42 | const classes = cx({ 43 | 'sk-fade-in': this.props.fadeIn === 'full' && !this.props.noFadeIn, 44 | 'sk-fade-in-half-second': this.props.fadeIn === 'half' && !this.props.noFadeIn, 45 | 'sk-fade-in-quarter-second': this.props.fadeIn === 'quarter' && !this.props.noFadeIn, 46 | 'sk-spinner': !this.props.overrideSpinnerClassName, 47 | [this.props.overrideSpinnerClassName]: !!this.props.overrideSpinnerClassName, 48 | [this.props.className]: !!this.props.className, 49 | [spinnerInfo.className || this.props.name]: true, 50 | }); 51 | 52 | const props = assign({}, this.props); 53 | delete props.name; 54 | delete props.fadeIn; 55 | delete props.noFadeIn; 56 | delete props.overrideSpinnerClassName; 57 | delete props.className; 58 | 59 | if (this.props.color) { 60 | props.style = props.style ? 61 | { ...props.style, color: this.props.color } : 62 | { color: this.props.color }; 63 | } 64 | 65 | return ( 66 |
67 | {[...Array(spinnerInfo.divCount)].map((_, idx) =>
)} 68 |
69 | ); 70 | } 71 | } 72 | 73 | Spinner.propTypes = { 74 | name: PropTypes.string.isRequired, 75 | noFadeIn: PropTypes.bool, 76 | fadeIn: PropTypes.oneOf(['full', 'half', 'quarter', 'none']), 77 | overrideSpinnerClassName: PropTypes.string, 78 | className: PropTypes.string, 79 | color: PropTypes.string, 80 | }; 81 | 82 | Spinner.defaultProps = { 83 | name: 'three-bounce', 84 | noFadeIn: false, 85 | fadeIn: 'full', 86 | overrideSpinnerClassName: '', 87 | }; 88 | 89 | module.exports = Spinner; 90 | -------------------------------------------------------------------------------- /src/spinners.js: -------------------------------------------------------------------------------- 1 | const spinkitSpinners = { 2 | circle: { className: 'sk-circle', divCount: 12 }, 3 | 'cube-grid': { className: 'sk-cube-grid', divCount: 9 }, 4 | wave: { className: 'sk-wave', divCount: 5 }, 5 | 'folding-cube': { className: 'sk-folding-cube', divCount: 4 }, 6 | 'three-bounce': { className: 'sk-three-bounce', divCount: 3 }, 7 | 'double-bounce': { className: 'sk-double-bounce', divCount: 2 }, 8 | 'wandering-cubes': { className: 'sk-wandering-cubes', divCount: 2 }, 9 | 'chasing-dots': { className: 'sk-chasing-dots', divCount: 2 }, 10 | 'rotating-plane': { className: 'sk-rotating-plane', divCount: 1 }, 11 | pulse: { className: 'sk-pulse', divCount: 1 }, 12 | wordpress: { className: 'sk-wordpress', divCount: 1 }, 13 | }; 14 | 15 | const loadersCssSpinners = { 16 | 'ball-grid-beat': { divCount: 9 }, 17 | 'ball-grid-pulse': { divCount: 9 }, 18 | 'line-spin-fade-loader': { divCount: 8 }, 19 | 'ball-spin-fade-loader': { divCount: 8 }, 20 | 'ball-pulse-rise': { divCount: 5 }, 21 | 'line-scale': { divCount: 5 }, 22 | 'line-scale-pulse-out': { divCount: 5 }, 23 | 'line-scale-pulse-out-rapid': { divCount: 5 }, 24 | pacman: { divCount: 5 }, 25 | 'line-scale-party': { divCount: 4 }, 26 | 'ball-triangle-path': { divCount: 3 }, 27 | 'ball-scale-multiple': { divCount: 3 }, 28 | 'ball-scale-ripple-multiple': { divCount: 3 }, 29 | 'ball-pulse-sync': { divCount: 3 }, 30 | 'ball-beat': { divCount: 3 }, 31 | 'ball-zig-zag': { divCount: 2 }, 32 | 'ball-zig-zag-deflect': { divCount: 2 }, 33 | 'ball-clip-rotate-pulse': { divCount: 2 }, 34 | 'ball-clip-rotate-multiple': { divCount: 2 }, 35 | 'ball-clip-rotate': { divCount: 1 }, 36 | 'ball-scale-ripple': { divCount: 1 }, 37 | 'triangle-skew-spin': { divCount: 1 }, 38 | }; 39 | 40 | module.exports = { 41 | spinkitSpinners, 42 | loadersCssSpinners, 43 | allSpinners: { 44 | ...spinkitSpinners, 45 | ...loadersCssSpinners, 46 | }, 47 | }; 48 | -------------------------------------------------------------------------------- /test/index.test.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | 3 | import React from 'react'; // eslint-disable-line import/no-extraneous-dependencies 4 | import { expect } from 'chai'; // eslint-disable-line import/no-extraneous-dependencies 5 | import { shallow } from 'enzyme'; // eslint-disable-line import/no-extraneous-dependencies 6 | 7 | import Spinner from '../src/index'; 8 | import { spinkitSpinners, loadersCssSpinners } from '../src/spinners'; 9 | 10 | describe('', () => { 11 | describe('custom classes', () => { 12 | it('should override `sk-spinner` class when overrideSpinnerClassName is set', () => { 13 | const wrapper = shallow(); 14 | 15 | expect(wrapper.find('div.sk-spinner').length).to.equal(0); 16 | expect(wrapper.find('div.sk-custom-spinner').length).to.equal(1); 17 | }); 18 | 19 | it('should add extra class when className is set', () => { 20 | const wrapper = shallow(); 21 | 22 | expect(wrapper.find('div.sk-spinner').length).to.equal(1); 23 | expect(wrapper.find('div.sk-custom-spinner').length).to.equal(1); 24 | }); 25 | }); 26 | 27 | describe('fadeIn behavior', () => { 28 | it('should apply `sk-fade-in` class by default', () => { 29 | const wrapper = shallow(); 30 | 31 | expect(wrapper.find('div.sk-fade-in').length).to.equal(1); 32 | expect(wrapper.find('div.sk-fade-in-half-second').length).to.equal(0); 33 | expect(wrapper.find('div.sk-fade-in-quarter-second').length).to.equal(0); 34 | }); 35 | 36 | it('should apply `sk-fade-in-half-second` class when `fadeIn` set to `half`', () => { 37 | const wrapper = shallow(); 38 | 39 | expect(wrapper.find('div.sk-fade-in').length).to.equal(0); 40 | expect(wrapper.find('div.sk-fade-in-half-second').length).to.equal(1); 41 | expect(wrapper.find('div.sk-fade-in-quarter-second').length).to.equal(0); 42 | }); 43 | 44 | it('should apply `sk-fade-in-quarter-second` class when `fadeIn` set to `quarter`', () => { 45 | const wrapper = shallow(); 46 | 47 | expect(wrapper.find('div.sk-fade-in').length).to.equal(0); 48 | expect(wrapper.find('div.sk-fade-in-half-second').length).to.equal(0); 49 | expect(wrapper.find('div.sk-fade-in-quarter-second').length).to.equal(1); 50 | }); 51 | 52 | it('should not apply any fadeIn classes when `fadeIn` set to `none`', () => { 53 | const wrapper = shallow(); 54 | 55 | expect(wrapper.find('div.sk-fade-in').length).to.equal(0); 56 | expect(wrapper.find('div.sk-fade-in-half-second').length).to.equal(0); 57 | expect(wrapper.find('div.sk-fade-in-quarter-second').length).to.equal(0); 58 | }); 59 | 60 | it('should not apply any fadeIn classes when `noFadeIn` set (deprecated)', () => { 61 | const wrapper = shallow(); 62 | 63 | expect(wrapper.find('div.sk-fade-in').length).to.equal(0); 64 | expect(wrapper.find('div.sk-fade-in-half-second').length).to.equal(0); 65 | expect(wrapper.find('div.sk-fade-in-quarter-second').length).to.equal(0); 66 | }); 67 | }); 68 | 69 | describe('spinkit spinners', () => { 70 | Object.keys(spinkitSpinners).forEach((spinner) => { 71 | it(`should render ${spinner} spinner`, () => { 72 | const spinnerInfo = spinkitSpinners[spinner]; 73 | const wrapper = shallow(); 74 | 75 | expect(wrapper.hasClass(spinnerInfo.className)).to.equal(true); 76 | expect(wrapper.children().length).to.equal(spinnerInfo.divCount); 77 | }); 78 | }); 79 | }); 80 | 81 | describe('loaders.css spinners', () => { 82 | Object.keys(loadersCssSpinners).forEach((spinner) => { 83 | it(`should render ${spinner} spinner`, () => { 84 | const spinnerInfo = loadersCssSpinners[spinner]; 85 | const wrapper = shallow(); 86 | 87 | expect(wrapper.hasClass(spinner)).to.equal(true); 88 | expect(wrapper.children().length).to.equal(spinnerInfo.divCount); 89 | }); 90 | }); 91 | }); 92 | }); 93 | -------------------------------------------------------------------------------- /test/mocha.opts: -------------------------------------------------------------------------------- 1 | --compilers js:babel-core/register 2 | --recursive 3 | --require ignore-styles -------------------------------------------------------------------------------- /www/.gatsby-context.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* weak */ 4 | // This file is auto-written and used by Gatsby to require 5 | // files from your pages directory. 6 | module.exports = function (callback) { 7 | var context = require.context('./pages', true, /(coffee|cjsx|ts|tsx|jsx|js|md|rmd|mkdn?|mdwn|mdown|markdown|litcoffee|ipynb|html|json|yaml|toml)$/); // eslint-disable-line 8 | if (module.hot) { 9 | module.hot.accept(context.id, function () { 10 | context = require.context('./pages', true, /(coffee|cjsx|ts|tsx|jsx|js|md|rmd|mkdn?|mdwn|mdown|markdown|litcoffee|ipynb|html|json|yaml|toml)$/); // eslint-disable-line 11 | return callback(context); 12 | }); 13 | } 14 | return callback(context); 15 | }; -------------------------------------------------------------------------------- /www/README.md: -------------------------------------------------------------------------------- 1 | # React Spinkit website 2 | 3 | This site is built using [Gatsby](https://github.com/gatsbyjs/gatsby) 4 | 5 | To run locally / develop, first run `npm install` inside this directory 6 | and then run `gatsby develop` to start a hot reloading server. 7 | -------------------------------------------------------------------------------- /www/config.toml: -------------------------------------------------------------------------------- 1 | linkPrefix = "/react-spinkit" 2 | -------------------------------------------------------------------------------- /www/html.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { prefixLink } from 'gatsby-helpers' 4 | import { GoogleFont, TypographyStyle } from 'typography-react' 5 | import typography from './utils/typography' 6 | 7 | const BUILD_TIME = new Date().getTime() 8 | 9 | module.exports = React.createClass({ 10 | render () { 11 | let css 12 | if (process.env.NODE_ENV === 'production') { 13 | css =