├── .npmignore ├── src ├── index.js ├── StaggeredAnimation.test.js ├── StaggeredAnimation.js └── StaggeredAnimation.story.js ├── demo.gif ├── .babelrc ├── .storybook ├── addons.js ├── webpack.config.js └── config.js ├── .editorconfig ├── test └── setup.js ├── cfg ├── dev.js ├── base.js ├── defaults.js ├── test.js └── dist.js ├── .gitignore ├── .eslintrc ├── webpack.config.js ├── README.md ├── package.json └── dist └── index.js /.npmignore: -------------------------------------------------------------------------------- 1 | /* 2 | !dist/index.js 3 | !README.md 4 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export default from './StaggeredAnimation.js'; 2 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plemarquand/react-staggered-animation/HEAD/demo.gif -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-0", 5 | "react" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@kadira/storybook/addons'; 2 | import 'storybook-addon-specifications/register'; 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /test/setup.js: -------------------------------------------------------------------------------- 1 | /* Configure Mocha test runner, see package.json/scripts/test */ 2 | process.env.NODE_ENV = 'test'; 3 | 4 | const jsdom = require('jsdom').jsdom; 5 | 6 | // Mock out the dom so we can run tests from Node 7 | global.document = jsdom(''); 8 | global.window = document.defaultView; 9 | Object.keys(document.defaultView).forEach((property) => { 10 | if (typeof global[property] === 'undefined') { 11 | global[property] = document.defaultView[property]; 12 | } 13 | }); 14 | 15 | global.navigator = { 16 | userAgent: 'node.js' 17 | }; 18 | -------------------------------------------------------------------------------- /cfg/dev.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let webpack = require('webpack'); 4 | let baseConfig = require('./base'); 5 | let defaultSettings = require('./defaults'); 6 | 7 | let config = Object.assign({}, baseConfig, { 8 | entry: [ 9 | 'webpack-dev-server/client?http://127.0.0.1:' + defaultSettings.port, 10 | 'webpack/hot/only-dev-server', 11 | './src/index' 12 | ], 13 | cache: true, 14 | devtool: 'eval-source-map', 15 | plugins: [ 16 | new webpack.LoaderOptionsPlugin({ 17 | debug: true 18 | }), 19 | new webpack.HotModuleReplacementPlugin(), 20 | new webpack.NoEmitOnErrorsPlugin() 21 | ], 22 | module: defaultSettings.getDefaultModules() 23 | }); 24 | 25 | module.exports = config; 26 | -------------------------------------------------------------------------------- /.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/Release 24 | 25 | # Code coverage artifacts 26 | coverage 27 | 28 | # Dependency directory 29 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 30 | node_modules 31 | .tmp 32 | 33 | # IDE/Editor data 34 | .idea 35 | -------------------------------------------------------------------------------- /cfg/base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | let path = require('path'); 3 | let defaultSettings = require('./defaults'); 4 | let pkg = require('../package.json'); 5 | 6 | module.exports = { 7 | devtool: 'source-map', 8 | output: { 9 | path: path.join(__dirname, '/../dist'), 10 | filename: 'index.js', 11 | publicPath: defaultSettings.publicPath, 12 | libraryTarget: 'umd', 13 | library: pkg.name 14 | }, 15 | devServer: { 16 | contentBase: './src/', 17 | historyApiFallback: true, 18 | hot: true, 19 | port: defaultSettings.port, 20 | publicPath: defaultSettings.publicPath, 21 | noInfo: false 22 | }, 23 | resolve: { 24 | extensions: ['.js', '.jsx'], 25 | alias: { 26 | 'react/lib/ReactMount': 'react-dom/lib/ReactMount' 27 | } 28 | }, 29 | module: {} 30 | }; 31 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "plugins": [ 4 | "react" 5 | ], 6 | "parserOptions": { 7 | "ecmaVersion": 6, 8 | "sourceType": "module", 9 | "ecmaFeatures": { 10 | "jsx": true 11 | } 12 | }, 13 | "env": { 14 | "browser": true, 15 | "amd": true, 16 | "es6": true, 17 | "node": true, 18 | "mocha": true 19 | }, 20 | "rules": { 21 | "comma-dangle": 1, 22 | "quotes": [ 1, "single" ], 23 | "no-undef": 1, 24 | "global-strict": 0, 25 | "no-extra-semi": 1, 26 | "no-underscore-dangle": 0, 27 | "no-console": 1, 28 | "no-unused-vars": 1, 29 | "no-trailing-spaces": [1, { "skipBlankLines": true }], 30 | "no-unreachable": 1, 31 | "no-alert": 0, 32 | "react/jsx-uses-react": 1, 33 | "react/jsx-uses-vars": 1 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | const argv = require('minimist')(process.argv.slice(2)); 2 | const config = require('../webpack.config.js'); 3 | const OpenBrowserPlugin = require('open-browser-webpack-plugin'); 4 | 5 | module.exports = function(storybookBaseConfig) { 6 | storybookBaseConfig.module.loaders = storybookBaseConfig.module.loaders.concat([config.module.loaders]); 7 | 8 | // These externals are required to get mocha integration to work. 9 | storybookBaseConfig.externals = { 10 | 'jsdom': 'window', 11 | 'cheerio': 'window', 12 | 'react/lib/ExecutionEnvironment': true, 13 | 'react/lib/ReactContext': 'window', 14 | 'react/addons': true, 15 | 'colors': 'window' 16 | }; 17 | 18 | // storybookBaseConfig.plugins = storybookBaseConfig.plugins.concat([new OpenBrowserPlugin({ url: `http://localhost:${argv.p || 9001}/` })]); 19 | 20 | return storybookBaseConfig; 21 | }; 22 | -------------------------------------------------------------------------------- /cfg/defaults.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Function that returns default values. 3 | * Used because Object.assign does a shallow instead of a deep copy. 4 | * Using [].push will add to the base array, so a require will alter 5 | * the base array output. 6 | */ 7 | 'use strict'; 8 | 9 | const path = require('path'); 10 | const srcPath = path.join(__dirname, '/../src'); 11 | const dfltPort = 8000; 12 | 13 | /** 14 | * Get the default modules object for webpack 15 | * @return {Object} 16 | */ 17 | function getDefaultModules() { 18 | return { 19 | loaders: [ 20 | { 21 | test: /\.(js|jsx)$/, 22 | include: srcPath, 23 | loader: 'eslint-loader', 24 | enforce: 'pre' 25 | }, 26 | { 27 | test: /\.css$/, 28 | loader: 'style-loader!css-loader?modules&localIdentName=[name]_[local]' 29 | } 30 | ] 31 | }; 32 | } 33 | 34 | module.exports = { 35 | srcPath: srcPath, 36 | publicPath: '/', 37 | port: dfltPort, 38 | getDefaultModules: getDefaultModules 39 | }; 40 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const args = require('minimist')(process.argv.slice(2)); 5 | 6 | // List of allowed environments 7 | const allowedEnvs = ['dev', 'dist', 'test']; 8 | 9 | // Set the correct environment 10 | let env; 11 | if (args._.length > 0 && args._[0].indexOf('test') !== -1) { 12 | env = 'test'; 13 | } else if (args.env) { 14 | env = args.env; 15 | } else if(allowedEnvs.indexOf(args._[0]) !== -1) { 16 | env = args._[0]; 17 | } else { 18 | env = 'dev'; 19 | } 20 | process.env.REACT_WEBPACK_ENV = env; 21 | 22 | /** 23 | * Build the webpack configuration 24 | * @param {String} wantedEnv The wanted environment 25 | * @return {Object} Webpack config 26 | */ 27 | function buildConfig(wantedEnv) { 28 | let isValid = wantedEnv && wantedEnv.length > 0 && allowedEnvs.indexOf(wantedEnv) !== -1; 29 | let validEnv = isValid ? wantedEnv : 'dev'; 30 | let config = require(path.join(__dirname, 'cfg', validEnv)); 31 | return config; 32 | } 33 | 34 | module.exports = buildConfig(env); 35 | -------------------------------------------------------------------------------- /cfg/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let path = require('path'); 4 | let webpack = require('webpack'); 5 | 6 | module.exports = { 7 | devtool: 'eval', 8 | module: { 9 | loaders: [ 10 | { 11 | test: /\.(js|jsx)$/, 12 | loader: 'isparta-loader', 13 | include: [ 14 | path.join(__dirname, '/../src') 15 | ], 16 | enforce: 'pre' 17 | }, 18 | { 19 | test: /\.css$/, 20 | loader: 'style-loader!css-loader?modules&localIdentName=[name]_[local]' 21 | }, 22 | { 23 | test: /\.(js|jsx)$/, 24 | loader: 'babel-loader', 25 | include: [path.join(__dirname, '/../src')] 26 | } 27 | ] 28 | }, 29 | resolve: { 30 | extensions: [ '.js', '.jsx' ] 31 | }, 32 | plugins: [ 33 | new webpack.LoaderOptionsPlugin({ 34 | debug: true 35 | }) 36 | ], 37 | externals: { 38 | jsdom: 'window', 39 | cheerio: 'window', 40 | 'react/lib/ExecutionEnvironment': true, 41 | 'react/lib/ReactContext': 'window', 42 | 'react/addons': true, 43 | colors: 'window' 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /cfg/dist.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | let path = require('path'); 4 | let webpack = require('webpack'); 5 | 6 | let baseConfig = require('./base'); 7 | let defaultSettings = require('./defaults'); 8 | 9 | let reactExternal = { 10 | root: 'React', 11 | commonjs2: 'react', 12 | commonjs: 'react', 13 | amd: 'react' 14 | }; 15 | let reactDOMExternal = { 16 | root: 'ReactDOM', 17 | commonjs2: 'react-dom', 18 | commonjs: 'react-dom', 19 | amd: 'react-dom' 20 | }; 21 | 22 | let config = Object.assign({}, baseConfig, { 23 | entry: path.join(__dirname, '../src/index.js'), 24 | cache: false, 25 | devtool: 'sourcemap', 26 | plugins: [ 27 | new webpack.DefinePlugin({ 28 | 'process.env.NODE_ENV': '"production"' 29 | }), 30 | new webpack.optimize.UglifyJsPlugin(), 31 | new webpack.optimize.AggressiveMergingPlugin(), 32 | new webpack.NoEmitOnErrorsPlugin() 33 | ], 34 | module: defaultSettings.getDefaultModules(), 35 | externals: { 36 | 'react': reactExternal, 37 | 'react-dom': reactDOMExternal 38 | } 39 | }); 40 | 41 | // Add needed loaders to the defaults here 42 | config.module.loaders.push({ 43 | test: /\.(js|jsx)$/, 44 | loader: 'babel-loader', 45 | include: [path.join(__dirname, '/../src')] 46 | }); 47 | 48 | module.exports = config; 49 | -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import { configure, setAddon } from '@kadira/storybook'; 3 | import { specs, describe, it, beforeEach, afterEach } from 'storybook-addon-specifications'; 4 | 5 | global.describe = describe; 6 | global.it = it; 7 | global.beforeEach = beforeEach; 8 | global.afterEach = afterEach; 9 | 10 | function CSSInjector({ children, styles }) { 11 | return ( 12 |