├── src ├── Redux-accordion.css ├── redux-accordion.jsx ├── utils.js ├── redux-accordion-component │ └── js │ │ └── accordion.react.js ├── accordion.react.js └── accordionSection.react.js ├── .eslintrc ├── readme-header.jpg ├── index.js ├── .babelrc ├── main.js ├── notes.txt ├── index.html ├── compiled ├── redux-accordion.js ├── utils.js ├── redux-accordion-component │ └── js │ │ └── accordion.react.js ├── accordion.react.js └── accordionSection.react.js ├── .gitignore ├── gulpfile.bak.js ├── gulpfile.js ├── redux ├── actions.js └── reducer.js ├── LICENSE ├── webpack.config.js ├── package.json ├── README.md └── App.js /src/Redux-accordion.css: -------------------------------------------------------------------------------- 1 | /* put your css here */ 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb" 4 | } 5 | -------------------------------------------------------------------------------- /readme-header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rorykermack/redux-accordion/HEAD/readme-header.jpg -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var ReduxAccordion = require('./compiled/redux-accordion'); 2 | module.exports = ReduxAccordion; 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"], 3 | "plugins": [ 4 | ["module-alias", [ 5 | { "src": "./src", "expose": "src" } 6 | ]] 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDom from 'react-dom'; 3 | import App from './App'; 4 | 5 | ReactDom.render( 6 | , 7 | document.getElementById('app') 8 | ); 9 | -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | Build Process -> NPM 2 | 1) Uncomment compiled/ & src/ in .gitignore 3 | 1) npm run compile 4 | 2) npm publish 5 | 6 | To Test Build: $ npm pack & Install on local server (npm install /local/path/to/.tgz) 7 | -------------------------------------------------------------------------------- /src/redux-accordion.jsx: -------------------------------------------------------------------------------- 1 | import AccordionSection from './accordionSection.react'; 2 | import Accordion from './accordion.react'; 3 | 4 | module.exports = { 5 | Accordion: Accordion, 6 | AccordionSection: AccordionSection 7 | } 8 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redux-accordion 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /compiled/redux-accordion.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _accordionSection = require('./accordionSection.react'); 4 | 5 | var _accordionSection2 = _interopRequireDefault(_accordionSection); 6 | 7 | var _accordion = require('./accordion.react'); 8 | 9 | var _accordion2 = _interopRequireDefault(_accordion); 10 | 11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 12 | 13 | module.exports = { 14 | Accordion: _accordion2.default, 15 | AccordionSection: _accordionSection2.default 16 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # project specific 2 | lib/ 3 | test/ 4 | readme-header.jpg 5 | # src/ 6 | 7 | 8 | # Git 9 | .git 10 | 11 | # Logs 12 | logs 13 | *.log 14 | npm-debug.log* 15 | 16 | # Runtime data 17 | pids 18 | *.pid 19 | *.seed 20 | 21 | # Directory for instrumented libs generated by jscoverage/JSCover 22 | lib-cov 23 | 24 | # Coverage directory used by tools like istanbul 25 | coverage 26 | 27 | # nyc test coverage 28 | .nyc_output 29 | 30 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 31 | .grunt 32 | 33 | # node-waf configuration 34 | .lock-wscript 35 | 36 | # Compiled binary addons (http://nodejs.org/api/addons.html) 37 | build/Release 38 | 39 | # Dependency directories 40 | node_modules 41 | jspm_packages 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional REPL history 47 | .node_repl_history 48 | 49 | .DS_Store 50 | -------------------------------------------------------------------------------- /gulpfile.bak.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var concat = require('gulp-concat'); 3 | var rename = require('gulp-rename'); 4 | var uglify = require('gulp-uglify'); 5 | var useref = require('gulp-useref'); 6 | var sourcemaps = require('gulp-sourcemaps'); 7 | 8 | 9 | var jsFiles = 'compiled/*.js', 10 | jsDest = 'prod', 11 | bundleName = 'redux-accordion.min.js' 12 | filesToMove = [] 13 | 14 | gulp.task('scripts', function() { 15 | return gulp.src(jsFiles) 16 | .pipe(uglify()) 17 | .pipe(concat(bundleName)) 18 | .pipe(gulp.dest(jsDest)); 19 | }); 20 | 21 | gulp.task('bundle', function() { 22 | return gulp.src(jsFiles) 23 | .pipe(concat(bundleName)) 24 | .pipe(uglify()) 25 | .pipe(sourcemaps.init()) 26 | .pipe(sourcemaps.write(jsDest + '\\maps')) 27 | .pipe(gulp.dest(jsDest)) 28 | }); 29 | 30 | gulp.task('minify', function() { 31 | return gulp.src(jsFiles) 32 | .pipe(uglify()) 33 | .pipe(gulp.dest(jsDest)) 34 | }) 35 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gulpfile to make my life easier. 3 | */ 4 | 5 | var gulp = require('gulp'); 6 | var browserify = require('browserify'); 7 | var babelify = require('babelify'); 8 | var source = require('vinyl-source-stream'); 9 | var gutil = require('gulp-util'); 10 | 11 | // Lets bring es6 to es5 with this. 12 | // Babel - converts ES6 code to ES5 - however it doesn't handle imports. 13 | // Browserify - crawls your code for dependencies and packages them up 14 | // into one file. can have plugins. 15 | // Babelify - a babel plugin for browserify, to make browserify 16 | // handle es6 including imports. 17 | gulp.task('es6', function() { 18 | browserify({ 19 | entries: './index.js', 20 | debug: true 21 | }) 22 | .transform(babelify) 23 | .on('error',gutil.log) 24 | .bundle() 25 | .on('error',gutil.log) 26 | .pipe(source('bundle.js')) 27 | .pipe(gulp.dest('/cooo')); 28 | }); 29 | 30 | gulp.task('watch',function() { 31 | gulp.watch('**/*.js',['es6']) 32 | }); 33 | 34 | // gulp.task('default', ['watch']); 35 | -------------------------------------------------------------------------------- /redux/actions.js: -------------------------------------------------------------------------------- 1 | /* === Consts === */ 2 | export const REDUX_ACCORDION_SET_SECTION = 'REDUX_ACCORDION_SET_SECTION'; 3 | export const REDUX_ACCORDION_SETTINGS = 'REDUX_ACCORDION_SETTINGS'; 4 | export const REDUX_ACCORDION_SET_SECTIONS = 'REDUX_ACCORDION_SET_SECTIONS'; 5 | export const REDUX_ACCORDION_CREATE = 'REDUX_ACCORDION_CREATE'; 6 | 7 | /* --- Actions --- */ 8 | export function accordionSetActiveSection(uniqId, sectionKey) { 9 | return { 10 | type: 'REDUX_ACCORDION_SET_SECTION', 11 | payload: { 12 | uniqId: uniqId, 13 | section: sectionKey 14 | } 15 | } 16 | } 17 | export function accordionSetActiveSections(sections) { 18 | return { 19 | type: 'REDUX_ACCORDION_SET_SECTIONS', 20 | payload: sections 21 | } 22 | } 23 | export function accordionSetSettings(settings) { 24 | return { 25 | type: 'REDUX_ACCORDION_SETTINGS', 26 | payload: settings 27 | } 28 | } 29 | export function accordionCreate(settings) { 30 | return { 31 | type: 'REDUX_ACCORDION_CREATE', 32 | payload: settings 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | WTFPL – Do What the Fuck You Want to Public License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const cssnext = require('postcss-cssnext'); 2 | const precss = require('precss'); 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | entry: './main.js', 7 | output: { 8 | path: path.join(__dirname, 'dist'), 9 | filename: 'index.js', 10 | publicPath: '/dist/', 11 | }, 12 | extensions: [ 13 | "", ".js", ".jsx", 14 | ], 15 | module: { 16 | loaders: [ 17 | { 18 | test: /\.jsx?$/, 19 | exclude: /node_modules/, 20 | loader: 'babel', 21 | query: { 22 | presets: ['es2015', 'stage-0', 'react', 'react-hmre'], 23 | } 24 | }, 25 | { 26 | test: /\.css$/, 27 | loader: 'style!css!postcss' 28 | }, 29 | { 30 | test: /\.png$/, 31 | loader: 'url-loader' 32 | }, 33 | { 34 | test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, 35 | loader: "url-loader?limit=10000&minetype=application/font-woff" 36 | }, 37 | { 38 | test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, 39 | loader: "file-loader" 40 | } 41 | ] 42 | }, 43 | postcss: function() { 44 | return [ 45 | precss, 46 | cssnext 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | export function checkUndef(item) { 2 | return (typeof item !== 'undefined'); 3 | } 4 | 5 | export function toggleSection(sectionId, activeSections, singleOpen) { 6 | let present = null; 7 | let newActiveSections = activeSections; 8 | 9 | newActiveSections.map((section) => { 10 | if (section === sectionId) present = true; 11 | return true; 12 | }); 13 | 14 | if (!singleOpen) { 15 | if (present) { 16 | const pos = newActiveSections.indexOf(sectionId); 17 | newActiveSections.splice(pos, 1); 18 | } else { 19 | newActiveSections.push(sectionId); 20 | } 21 | } else { 22 | newActiveSections = [sectionId]; 23 | } 24 | 25 | return newActiveSections; 26 | } 27 | 28 | export function setupAccordion(info) { 29 | const singleOpen = (checkUndef(info.singleOpen)) ? info.singleOpen : false; 30 | const activeSections = []; 31 | const singleChild = typeof info.kids.length === 'undefined'; 32 | 33 | if (!singleChild) { 34 | info.kids.forEach((child, i) => { 35 | const { openByDefault } = child.props; 36 | if (singleOpen && activeSections.length === 0 && openByDefault) { 37 | activeSections.push(`acc-sec-${i}`); 38 | } 39 | if (!singleOpen && openByDefault) { 40 | activeSections.push(`acc-sec-${i}`); 41 | } 42 | }); 43 | } 44 | 45 | return { 46 | activeSections, 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /compiled/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | exports.checkUndef = checkUndef; 7 | exports.toggleSection = toggleSection; 8 | exports.setupAccordion = setupAccordion; 9 | function checkUndef(item) { 10 | return typeof item !== 'undefined'; 11 | } 12 | 13 | function toggleSection(sectionId, activeSections, singleOpen) { 14 | var present = null; 15 | var newActiveSections = activeSections; 16 | 17 | newActiveSections.map(function (section) { 18 | if (section === sectionId) present = true; 19 | return true; 20 | }); 21 | 22 | if (!singleOpen) { 23 | if (present) { 24 | var pos = newActiveSections.indexOf(sectionId); 25 | newActiveSections.splice(pos, 1); 26 | } else { 27 | newActiveSections.push(sectionId); 28 | } 29 | } else { 30 | newActiveSections = [sectionId]; 31 | } 32 | 33 | return newActiveSections; 34 | } 35 | 36 | function setupAccordion(info) { 37 | var singleOpen = checkUndef(info.singleOpen) ? info.singleOpen : false; 38 | var activeSections = []; 39 | var singleChild = typeof info.kids.length === 'undefined'; 40 | 41 | if (!singleChild) { 42 | info.kids.forEach(function (child, i) { 43 | var openByDefault = child.props.openByDefault; 44 | 45 | if (singleOpen && activeSections.length === 0 && openByDefault) { 46 | activeSections.push('acc-sec-' + i); 47 | } 48 | if (!singleOpen && openByDefault) { 49 | activeSections.push('acc-sec-' + i); 50 | } 51 | }); 52 | } 53 | 54 | return { 55 | activeSections: activeSections 56 | }; 57 | } -------------------------------------------------------------------------------- /src/redux-accordion-component/js/accordion.react.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes, Children } from 'react'; 2 | import Component from 'react-addons-shallow-compare'; 3 | import className from 'classnames'; 4 | import * as Utils from './utils'; 5 | 6 | export default class Accordion extends React.Component { 7 | constructor(props) { 8 | super(props); 9 | this.toggleSection = this.toggleSection.bind(this); 10 | this.state = { 11 | singleOpen: this.props.singleOpen, 12 | openByDefault: this.props.openByDefault, 13 | activeSections: [] 14 | }; 15 | } 16 | 17 | toggleSection(sectionId) { 18 | const newActive = Utils.toggleSection(sectionId, this.state.activeSections, this.state.singleOpen); 19 | this.setState({activeSections: newActive}); 20 | } 21 | 22 | componentWillMount() { 23 | const {singleOpen, openByDefault, uniqId, children} = this.props; 24 | 25 | const settings = {singleOpen: singleOpen, openByDefault: openByDefault, uniqId: uniqId, kids: children}; 26 | const initialState_sections = Utils.setupAccordion(settings).activeSections; 27 | this.setState({activeSections: initialState_sections}); 28 | } 29 | 30 | getChildrenWithProps() { 31 | const { 32 | children, 33 | uniqId, 34 | openByDefault, 35 | singleOpen} = this.props; 36 | 37 | 38 | const kids = React.Children.map(children, (child, i) => { 39 | const unqId = `acc-sec-${i}`; 40 | return React.cloneElement(child, { 41 | toggle: (acId) => this.toggleSection(acId), 42 | key: unqId, 43 | unq: unqId, 44 | active: (this.state.activeSections && this.state.activeSections.lastIndexOf(unqId) != -1) 45 | }); 46 | }); 47 | 48 | return kids; 49 | } 50 | 51 | render() { 52 | const { 53 | className: propClasses 54 | } = this.props; 55 | const childrenWithProps = this.getChildrenWithProps(); 56 | const accordionClasses = className('react-accordion', propClasses) 57 | 58 | return( 59 |
60 | {childrenWithProps} 61 |
62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/accordion.react.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import className from 'classnames'; 3 | import * as Utils from './utils'; 4 | 5 | export default class Accordion extends React.Component { 6 | 7 | // static propTypes = { 8 | // openByDefault: PropTypes.bool, 9 | // singleOpen: PropTypes.bool, 10 | // uniqId: PropTypes.string, 11 | // className: PropTypes.string, 12 | // } 13 | 14 | constructor(props) { 15 | super(props); 16 | this.toggleSection = this.toggleSection.bind(this); 17 | this.state = { 18 | singleOpen: this.props.singleOpen, 19 | openByDefault: this.props.openByDefault, 20 | activeSections: [], 21 | }; 22 | } 23 | 24 | componentWillMount() { 25 | const { 26 | singleOpen, 27 | openByDefault, 28 | uniqId, 29 | children } = this.props; 30 | 31 | const settings = { 32 | singleOpen, 33 | openByDefault, 34 | uniqId, 35 | kids: children 36 | }; 37 | 38 | const initialStateSections = Utils.setupAccordion(settings).activeSections; 39 | this.setState({ activeSections: initialStateSections }); 40 | } 41 | 42 | getChildrenWithProps() { 43 | const { 44 | children, 45 | } = this.props; 46 | 47 | 48 | const kids = React.Children.map(children, (child, i) => { 49 | const unqId = `acc-sec-${i}`; 50 | return React.cloneElement(child, { 51 | toggle: (acId) => this.toggleSection(acId), 52 | key: unqId, 53 | unq: unqId, 54 | active: (this.state.activeSections && this.state.activeSections.lastIndexOf(unqId) !== -1) 55 | }); 56 | }); 57 | 58 | return kids; 59 | } 60 | 61 | toggleSection(sectionId) { 62 | const newActive = Utils.toggleSection( 63 | sectionId, 64 | this.state.activeSections, 65 | this.state.singleOpen); 66 | 67 | this.setState({ 68 | activeSections: newActive 69 | }); 70 | } 71 | 72 | 73 | render() { 74 | const { 75 | className: propClasses, 76 | uniqId: propId 77 | } = this.props; 78 | 79 | const childrenWithProps = this.getChildrenWithProps(); 80 | const accordionClasses = className('react-accordion', propClasses); 81 | const uniqId = propId || ''; 82 | 83 | return( 84 |
85 | {childrenWithProps} 86 |
87 | ); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-accordion", 3 | "version": "1.0.73", 4 | "description": "A reusable and customisable accordion component for react/redux", 5 | "keywords": [], 6 | "main": "index.js", 7 | "url": "https://github.com/rorykermack/redux-accordion", 8 | "scripts": { 9 | "dev": "webpack-dev-server --inline --hot --port 3000", 10 | "compile": "npm-run-all --parallel compile:source compile:postcss", 11 | "compile:postcss": "postcss --use precss --use postcss-cssnext -d lib src/*.css", 12 | "compile:source": "babel src --out-dir compiled", 13 | "create-prod": "gulp scripts", 14 | "prepublish": "npm-run-all clean compile", 15 | "lint": "eslint src test --ext .jsx,.js", 16 | "clean": "rimraf lib dist", 17 | "test:watch": "mocha --watch", 18 | "test": "mocha" 19 | }, 20 | "author": "Rory Kermack ", 21 | "license": "MIT", 22 | "config": { 23 | "ghooks": { 24 | "pre-commit": "", 25 | "pre-push": "npm run clean" 26 | } 27 | }, 28 | "peerDependencies": { 29 | "react": "15.x || 16.x", 30 | "react-dom": "15.x || 16.x", 31 | "classnames": "^2.2.5" 32 | }, 33 | "devDependencies": { 34 | "babel-cli": "^6.16.0", 35 | "babel-core": "^6.17.0", 36 | "babel-eslint": "^7.0.0", 37 | "babel-loader": "^6.2.5", 38 | "babel-plugin-module-alias": "^1.6.0", 39 | "babel-preset-es2015": "^6.16.0", 40 | "babel-preset-react": "^6.16.0", 41 | "babel-preset-react-hmre": "^1.1.1", 42 | "babel-preset-stage-0": "^6.16.0", 43 | "babelify": "^7.3.0", 44 | "browserify": "^13.1.0", 45 | "css-loader": "^0.25.0", 46 | "enzyme": "^2.4.1", 47 | "eslint": "^3.7.1", 48 | "eslint-config-airbnb": "^12.0.0", 49 | "eslint-plugin-import": "^2.0.1", 50 | "eslint-plugin-jsx-a11y": "^2.2.3", 51 | "eslint-plugin-react": "^6.4.1", 52 | "expect": "^1.20.2", 53 | "expect-jsx": "^2.6.0", 54 | "file-loader": "^0.9.0", 55 | "ghooks": "^1.3.2", 56 | "gulp": "^3.9.1", 57 | "gulp-concat": "^2.6.0", 58 | "gulp-include": "^2.3.1", 59 | "gulp-rename": "^1.2.2", 60 | "gulp-sourcemaps": "^1.7.3", 61 | "gulp-uglify": "^2.0.0", 62 | "gulp-useref": "^3.1.2", 63 | "ignore-styles": "^5.0.1", 64 | "jsdom": "^9.6.0", 65 | "mocha": "^3.1.2", 66 | "npm-run-all": "^3.1.0", 67 | "postcss": "^5.2.4", 68 | "postcss-cli": "^2.6.0", 69 | "postcss-cssnext": "^2.8.0", 70 | "postcss-loader": "^0.13.0", 71 | "precss": "^1.4.0", 72 | "react-addons-test-utils": "^15.3.2", 73 | "style-loader": "^0.13.1", 74 | "url-loader": "^0.5.7", 75 | "vinyl-source-stream": "^1.1.0", 76 | "webpack": "^1.13.2", 77 | "webpack-dev-server": "^1.16.2" 78 | }, 79 | "dependencies": { 80 | "classnames": "^2.2.5", 81 | "eslint-plugin-import": "^2.0.1", 82 | "react-addons-shallow-compare": "^15.3.2", 83 | "react-dom": "^15.5.4" 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/accordionSection.react.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | import className from 'classnames'; 3 | 4 | 5 | export default class AccordionSection extends React.Component { 6 | 7 | // static propTypes = { 8 | // active: PropTypes.bool, 9 | // unq: PropTypes.string, 10 | // toggle: PropTypes.function, 11 | // title: PropTypes.string, 12 | // className: PropTypes.string 13 | // } 14 | 15 | constructor(props) { 16 | super(props); 17 | this.toggleSection = this.toggleSection.bind(this); 18 | this.state = { 19 | sectionHeight: 0, 20 | } 21 | } 22 | 23 | componentDidMount() { 24 | const { active } = this.props; 25 | if (active) this.setState({sectionHeight: this.accordionContent.scrollHeight}); 26 | } 27 | 28 | componentWillReceiveProps(nextProps) { 29 | if (nextProps.active !== this.props.active) { 30 | this.toggleOpen(nextProps.active); 31 | } 32 | } 33 | 34 | getHeight() { 35 | const { active } = this.props; 36 | return (active) ? this.accordionContent.scrollHeight : 0; 37 | } 38 | 39 | toggleSection() { 40 | const { 41 | unq, 42 | toggle 43 | } = this.props; 44 | toggle(unq); 45 | } 46 | 47 | toggleOpen(active) { 48 | const height = (active) ? `${this.accordionContent.scrollHeight}px` : 0; 49 | this.setState({ 50 | sectionHeight: height, 51 | }); 52 | } 53 | 54 | 55 | render() { 56 | const { 57 | title, 58 | children, 59 | active, 60 | className: propClasses 61 | } = this.props; 62 | 63 | const contentStyles = { 64 | height: this.state.sectionHeight, 65 | overflow: 'hidden', 66 | transition: 'height .25s ease', 67 | fontFamily: 'sans-serif', 68 | padding: 0, 69 | background: '#bdc3c7' 70 | }; 71 | 72 | const triggerStyles = { 73 | background: '#ecf0f1', 74 | padding: '5px', 75 | fontFamily: 'sans-serif', 76 | WebkitUserSelect: 'none', 77 | MozUserSelect: 'none', 78 | cursor: 'pointer', 79 | transition: 'background .25s ease' 80 | } 81 | 82 | const innerContentStyles = { 83 | padding: '5px' 84 | } 85 | 86 | const triggerClasses = className('accordion-trigger accordion-title', { 87 | active 88 | }); 89 | 90 | const contentClasses = className('accordion-content accordion-inner', { 91 | active 92 | }); 93 | 94 | 95 | 96 | return( 97 |
98 |
this.toggleSection()}> 99 | {title} 100 |
101 |
this.accordionContent = ref}> 102 |
103 | {children} 104 |
105 |
106 |
107 | ); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Redux Accordion Header Image](https://raw.githubusercontent.com/rorykermack/redux-accordion/master/readme-header.jpg) 2 | 3 | # Redux Accordion 4 | Need an accordion for your React and/or Redux project? Look no further. You can have a single or multiple instances running at one. 5 | Redux Accordion is a fully featured accordion component, built using [react/redux](https://github.com/reactjs/redux/) with ECMAScript 6. Simple to set up, simple to use and most importantly hopefully as simple as possible to maintain and build upon. 6 | 7 | ## Installation 8 | ``` 9 | npm install redux-accordion 10 | 11 | ``` 12 | 13 | ## Example 14 | ``` 15 | 18 | 19 | 21 | {*/ Content Goes Here /*} 22 | 23 | 24 | 26 | {*/ Content Goes Here /*} 27 | 28 | 29 | 30 | ``` 31 | 32 | 33 | ## Usage 34 | Redux accordion uses a redux store to manage its state. However it also has the option to use local component state. 35 | 36 | With the local component state option you can simply run ```npm install redux-accordion```, include Accordion & AccordionSection and your good to go. The second requires you to hook up the actions and reducers to your app. 37 | 38 | 39 | ## Sections: 40 | ### Accordion 41 | ``` 42 | 46 | 47 | {*/ Content Goes Here /*} 48 | 49 | 50 | ``` 51 | * You can set the uniqId if you want to apply an id to your accordion. This also specifies how this instance is referenced in the reducer (non-component version) 52 | * You can set `singleOpen={true}` if you want to limit the accordion to only open a single section at a time 53 |
54 | 55 | ### AccordionSection 56 | ``` 57 | 59 | {*/ Content Goes Here /*} 60 | 61 | ``` 62 | * The title dictates what is displayed on the accordion bar 63 | * You can set `openByDefault={true}` if you want this section to be open by default
64 | 65 | 66 | 67 | ## Installation with redux actions & stores 68 | * Clone git repo or run ```npm install redux-accordion```
69 | * Connect the actions and reducer into your app (node_modules/redux-accordion/redux)
70 | * Include Accordion & AccordionSection. 71 | * Done. Accordions for everyone :)
72 | 73 | 74 | ## Contributing 75 | Everyone brings something awesome to the party so please contribute. 76 | If you have any suggestions give a shout on twitter to [@reduxAccordion](https://twitter.com/@reduxAccordion)
77 | 1. Fork it!
78 | 2. Create your feature branch: `git checkout -b my-new-feature`
79 | 3. Commit your changes: `git commit -am 'Add some feature'`
80 | 4. Push to the branch: `git push origin my-new-feature`
81 | 5. Submit a pull request :D
82 | 83 | ## Credits 84 | Created and maintained by [@rorykermack](https://twitter.com/@rorykermack) 85 | ## License 86 | [WTFPL](http://www.wtfpl.net/) (100% Open Source) 87 | -------------------------------------------------------------------------------- /redux/reducer.js: -------------------------------------------------------------------------------- 1 | /* Redux Accordion Reducer */ 2 | import React from 'react'; 3 | import * as actions from './actions'; 4 | import {List, Record, Map} from 'immutable'; 5 | import Immutable from 'immutable'; 6 | 7 | const NewAccordion = Record({ 8 | singleOpen: false, 9 | openByDefault: false, 10 | activeSections: List() 11 | }); 12 | 13 | const InitialState = Record({ 14 | accordions: Map() 15 | }) 16 | 17 | function checkUndef(item) { 18 | return (typeof item != 'undefined'); 19 | } 20 | 21 | const initialState = new InitialState; 22 | 23 | export default function reduxAccordion(state = initialState, action) { 24 | switch (action.type) { 25 | /* Set the active section */ 26 | case actions.REDUX_ACCORDION_SET_SECTION: { 27 | let newActiveSections; 28 | const currentAccordion = state.accordions.get(action.payload.uniqId), 29 | currentActiveSections = currentAccordion.get('activeSections'), 30 | isPresent = currentActiveSections.lastIndexOf(action.payload.section); 31 | /* If section is already open */ 32 | if (isPresent === -1) { 33 | newActiveSections = (currentAccordion.singleOpen) ? new List([action.payload.section]) : currentActiveSections.push(action.payload.section); 34 | } else { 35 | newActiveSections = (currentAccordion.singleOpen) ? new List([]) : currentActiveSections.delete(isPresent); 36 | } 37 | return state.update('accordions', accordions => accordions.set(action.payload.uniqId, currentAccordion.set('activeSections', newActiveSections))); 38 | } 39 | /* Pass in all required active sections */ 40 | case actions.REDUX_ACCORDION_SET_SECTIONS: { 41 | const currentAccordion = state.accordions.get(action.payload.uniqId), 42 | currentActiveSections = currentAccordion.get('activeSections'); 43 | return state.update('accordions', accordions => accordions.set(action.payload.uniqId, currentAccordion.set('activeSections', Immutable.fromJS(action.payload)))); 44 | } 45 | /* Create a new accordion */ 46 | case actions.REDUX_ACCORDION_CREATE: { 47 | const currentSize = state.accordions.size, 48 | singleOpen = (checkUndef(action.payload.singleOpen)) ? action.payload.singleOpen : false, 49 | allOpenByDefault = (checkUndef(action.payload.openByDefault)) ? action.payload.openByDefault : false, 50 | uniqId = (checkUndef(action.payload.uniqId)) ? action.payload.uniqId : false, 51 | activeSections = []; 52 | 53 | if(!uniqId) { 54 | console.log('ERROR: Whoops, looks like you forgot to set a uniqId. E.g. "home-page-accordion" '); 55 | return false; 56 | } 57 | 58 | React.Children.map(action.payload.kids, (child, i) => { 59 | const {openByDefault} = child.props; 60 | if (allOpenByDefault && !singleOpen) { 61 | activeSections.push(`acc-sec-${i}`); 62 | } else if (openByDefault && !singleOpen) { 63 | activeSections.push(`acc-sec-${i}`); 64 | } else if (singleOpen && activeSections.length === 0) { 65 | activeSections.push(`acc-sec-${i}`); 66 | } 67 | }) 68 | 69 | 70 | const newAccordion = new NewAccordion({ 71 | singleOpen: singleOpen, 72 | openByDefault: allOpenByDefault, 73 | activeSections: new List(activeSections) 74 | }); 75 | 76 | return state.update('accordions', accordions => accordions.set(uniqId, newAccordion)); 77 | } 78 | } 79 | return state; 80 | } 81 | -------------------------------------------------------------------------------- /compiled/redux-accordion-component/js/accordion.react.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _react2 = _interopRequireDefault(_react); 12 | 13 | var _reactAddonsShallowCompare = require('react-addons-shallow-compare'); 14 | 15 | var _reactAddonsShallowCompare2 = _interopRequireDefault(_reactAddonsShallowCompare); 16 | 17 | var _classnames = require('classnames'); 18 | 19 | var _classnames2 = _interopRequireDefault(_classnames); 20 | 21 | var _utils = require('./utils'); 22 | 23 | var Utils = _interopRequireWildcard(_utils); 24 | 25 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 26 | 27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 28 | 29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 30 | 31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 32 | 33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 34 | 35 | var Accordion = function (_React$Component) { 36 | _inherits(Accordion, _React$Component); 37 | 38 | function Accordion(props) { 39 | _classCallCheck(this, Accordion); 40 | 41 | var _this = _possibleConstructorReturn(this, (Accordion.__proto__ || Object.getPrototypeOf(Accordion)).call(this, props)); 42 | 43 | _this.toggleSection = _this.toggleSection.bind(_this); 44 | _this.state = { 45 | singleOpen: _this.props.singleOpen, 46 | openByDefault: _this.props.openByDefault, 47 | activeSections: [] 48 | }; 49 | return _this; 50 | } 51 | 52 | _createClass(Accordion, [{ 53 | key: 'toggleSection', 54 | value: function toggleSection(sectionId) { 55 | var newActive = Utils.toggleSection(sectionId, this.state.activeSections, this.state.singleOpen); 56 | this.setState({ activeSections: newActive }); 57 | } 58 | }, { 59 | key: 'componentWillMount', 60 | value: function componentWillMount() { 61 | var _props = this.props, 62 | singleOpen = _props.singleOpen, 63 | openByDefault = _props.openByDefault, 64 | uniqId = _props.uniqId, 65 | children = _props.children; 66 | 67 | 68 | var settings = { singleOpen: singleOpen, openByDefault: openByDefault, uniqId: uniqId, kids: children }; 69 | var initialState_sections = Utils.setupAccordion(settings).activeSections; 70 | this.setState({ activeSections: initialState_sections }); 71 | } 72 | }, { 73 | key: 'getChildrenWithProps', 74 | value: function getChildrenWithProps() { 75 | var _this2 = this; 76 | 77 | var _props2 = this.props, 78 | children = _props2.children, 79 | uniqId = _props2.uniqId, 80 | openByDefault = _props2.openByDefault, 81 | singleOpen = _props2.singleOpen; 82 | 83 | 84 | var kids = _react2.default.Children.map(children, function (child, i) { 85 | var unqId = 'acc-sec-' + i; 86 | return _react2.default.cloneElement(child, { 87 | toggle: function toggle(acId) { 88 | return _this2.toggleSection(acId); 89 | }, 90 | key: unqId, 91 | unq: unqId, 92 | active: _this2.state.activeSections && _this2.state.activeSections.lastIndexOf(unqId) != -1 93 | }); 94 | }); 95 | 96 | return kids; 97 | } 98 | }, { 99 | key: 'render', 100 | value: function render() { 101 | var propClasses = this.props.className; 102 | 103 | var childrenWithProps = this.getChildrenWithProps(); 104 | var accordionClasses = (0, _classnames2.default)('react-accordion', propClasses); 105 | 106 | return _react2.default.createElement( 107 | 'div', 108 | { className: accordionClasses }, 109 | childrenWithProps 110 | ); 111 | } 112 | }]); 113 | 114 | return Accordion; 115 | }(_react2.default.Component); 116 | 117 | exports.default = Accordion; -------------------------------------------------------------------------------- /compiled/accordion.react.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _react2 = _interopRequireDefault(_react); 12 | 13 | var _classnames = require('classnames'); 14 | 15 | var _classnames2 = _interopRequireDefault(_classnames); 16 | 17 | var _utils = require('./utils'); 18 | 19 | var Utils = _interopRequireWildcard(_utils); 20 | 21 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 22 | 23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 24 | 25 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 26 | 27 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 28 | 29 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 30 | 31 | var Accordion = function (_React$Component) { 32 | _inherits(Accordion, _React$Component); 33 | 34 | // static propTypes = { 35 | // openByDefault: PropTypes.bool, 36 | // singleOpen: PropTypes.bool, 37 | // uniqId: PropTypes.string, 38 | // className: PropTypes.string, 39 | // } 40 | 41 | function Accordion(props) { 42 | _classCallCheck(this, Accordion); 43 | 44 | var _this = _possibleConstructorReturn(this, (Accordion.__proto__ || Object.getPrototypeOf(Accordion)).call(this, props)); 45 | 46 | _this.toggleSection = _this.toggleSection.bind(_this); 47 | _this.state = { 48 | singleOpen: _this.props.singleOpen, 49 | openByDefault: _this.props.openByDefault, 50 | activeSections: [] 51 | }; 52 | return _this; 53 | } 54 | 55 | _createClass(Accordion, [{ 56 | key: 'componentWillMount', 57 | value: function componentWillMount() { 58 | var _props = this.props, 59 | singleOpen = _props.singleOpen, 60 | openByDefault = _props.openByDefault, 61 | uniqId = _props.uniqId, 62 | children = _props.children; 63 | 64 | 65 | var settings = { 66 | singleOpen: singleOpen, 67 | openByDefault: openByDefault, 68 | uniqId: uniqId, 69 | kids: children 70 | }; 71 | 72 | var initialStateSections = Utils.setupAccordion(settings).activeSections; 73 | this.setState({ activeSections: initialStateSections }); 74 | } 75 | }, { 76 | key: 'getChildrenWithProps', 77 | value: function getChildrenWithProps() { 78 | var _this2 = this; 79 | 80 | var children = this.props.children; 81 | 82 | 83 | var kids = _react2.default.Children.map(children, function (child, i) { 84 | var unqId = 'acc-sec-' + i; 85 | return _react2.default.cloneElement(child, { 86 | toggle: function toggle(acId) { 87 | return _this2.toggleSection(acId); 88 | }, 89 | key: unqId, 90 | unq: unqId, 91 | active: _this2.state.activeSections && _this2.state.activeSections.lastIndexOf(unqId) !== -1 92 | }); 93 | }); 94 | 95 | return kids; 96 | } 97 | }, { 98 | key: 'toggleSection', 99 | value: function toggleSection(sectionId) { 100 | var newActive = Utils.toggleSection(sectionId, this.state.activeSections, this.state.singleOpen); 101 | 102 | this.setState({ 103 | activeSections: newActive 104 | }); 105 | } 106 | }, { 107 | key: 'render', 108 | value: function render() { 109 | var _props2 = this.props, 110 | propClasses = _props2.className, 111 | propId = _props2.uniqId; 112 | 113 | 114 | var childrenWithProps = this.getChildrenWithProps(); 115 | var accordionClasses = (0, _classnames2.default)('react-accordion', propClasses); 116 | var uniqId = propId || ''; 117 | 118 | return _react2.default.createElement( 119 | 'div', 120 | { className: accordionClasses, id: uniqId }, 121 | childrenWithProps 122 | ); 123 | } 124 | }]); 125 | 126 | return Accordion; 127 | }(_react2.default.Component); 128 | 129 | exports.default = Accordion; -------------------------------------------------------------------------------- /compiled/accordionSection.react.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | 7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 8 | 9 | var _react = require('react'); 10 | 11 | var _react2 = _interopRequireDefault(_react); 12 | 13 | var _classnames = require('classnames'); 14 | 15 | var _classnames2 = _interopRequireDefault(_classnames); 16 | 17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 18 | 19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 20 | 21 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } 22 | 23 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 24 | 25 | var AccordionSection = function (_React$Component) { 26 | _inherits(AccordionSection, _React$Component); 27 | 28 | // static propTypes = { 29 | // active: PropTypes.bool, 30 | // unq: PropTypes.string, 31 | // toggle: PropTypes.function, 32 | // title: PropTypes.string, 33 | // className: PropTypes.string 34 | // } 35 | 36 | function AccordionSection(props) { 37 | _classCallCheck(this, AccordionSection); 38 | 39 | var _this = _possibleConstructorReturn(this, (AccordionSection.__proto__ || Object.getPrototypeOf(AccordionSection)).call(this, props)); 40 | 41 | _this.toggleSection = _this.toggleSection.bind(_this); 42 | _this.state = { 43 | sectionHeight: 0 44 | }; 45 | return _this; 46 | } 47 | 48 | _createClass(AccordionSection, [{ 49 | key: 'componentDidMount', 50 | value: function componentDidMount() { 51 | var active = this.props.active; 52 | 53 | if (active) this.setState({ sectionHeight: this.accordionContent.scrollHeight }); 54 | } 55 | }, { 56 | key: 'componentWillReceiveProps', 57 | value: function componentWillReceiveProps(nextProps) { 58 | if (nextProps.active !== this.props.active) { 59 | this.toggleOpen(nextProps.active); 60 | } 61 | } 62 | }, { 63 | key: 'getHeight', 64 | value: function getHeight() { 65 | var active = this.props.active; 66 | 67 | return active ? this.accordionContent.scrollHeight : 0; 68 | } 69 | }, { 70 | key: 'toggleSection', 71 | value: function toggleSection() { 72 | var _props = this.props, 73 | unq = _props.unq, 74 | toggle = _props.toggle; 75 | 76 | toggle(unq); 77 | } 78 | }, { 79 | key: 'toggleOpen', 80 | value: function toggleOpen(active) { 81 | var height = active ? this.accordionContent.scrollHeight + 'px' : 0; 82 | this.setState({ 83 | sectionHeight: height 84 | }); 85 | } 86 | }, { 87 | key: 'render', 88 | value: function render() { 89 | var _this2 = this; 90 | 91 | var _props2 = this.props, 92 | title = _props2.title, 93 | children = _props2.children, 94 | active = _props2.active, 95 | propClasses = _props2.className; 96 | 97 | 98 | var contentStyles = { 99 | height: this.state.sectionHeight, 100 | overflow: 'hidden', 101 | transition: 'height .25s ease', 102 | fontFamily: 'sans-serif', 103 | padding: 0, 104 | background: '#bdc3c7' 105 | }; 106 | 107 | var triggerStyles = { 108 | background: '#ecf0f1', 109 | padding: '5px', 110 | fontFamily: 'sans-serif', 111 | WebkitUserSelect: 'none', 112 | MozUserSelect: 'none', 113 | cursor: 'pointer', 114 | transition: 'background .25s ease' 115 | }; 116 | 117 | var innerContentStyles = { 118 | padding: '5px' 119 | }; 120 | 121 | var triggerClasses = (0, _classnames2.default)('accordion-trigger accordion-title', { 122 | active: active 123 | }); 124 | 125 | var contentClasses = (0, _classnames2.default)('accordion-content accordion-inner', { 126 | active: active 127 | }); 128 | 129 | return _react2.default.createElement( 130 | 'div', 131 | { className: 'accordion-section' }, 132 | _react2.default.createElement( 133 | 'div', 134 | { className: triggerClasses, style: triggerStyles, onClick: function onClick() { 135 | return _this2.toggleSection(); 136 | } }, 137 | title 138 | ), 139 | _react2.default.createElement( 140 | 'div', 141 | { className: contentClasses, style: contentStyles, ref: function ref(_ref) { 142 | return _this2.accordionContent = _ref; 143 | } }, 144 | _react2.default.createElement( 145 | 'div', 146 | { className: 'inner-content', style: innerContentStyles }, 147 | children 148 | ) 149 | ) 150 | ); 151 | } 152 | }]); 153 | 154 | return AccordionSection; 155 | }(_react2.default.Component); 156 | 157 | exports.default = AccordionSection; -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // import ReduxAccordion from './src/Redux-accordion.jsx'; 3 | import {Accordion, AccordionSection} from './src/redux-accordion.jsx'; 4 | 5 | export default class App extends React.Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render() { 12 | return( 13 |
14 |

React Accordion Examples:

15 |

Single Open, second section open by default:

16 | 22 | 25 |
    26 |
  • item 1 (li)
  • 27 |
  • item 2 (li)
  • 28 |
  • item 3 (li)
  • 29 |
  • item 4 (li)
  • 30 |
31 |
32 | 35 |
    36 |
  • item 1 (li)
  • 37 |
  • item 2 (li)
  • 38 |
  • item 3 (li)
  • 39 |
  • item 4 (li)
  • 40 |
41 |
42 | 45 |
    46 |
  • item 1 (li)
  • 47 |
  • item 2 (li)
  • 48 |
  • item 3 (li)
  • 49 |
  • item 4 (li)
  • 50 |
51 |
52 |
53 |


54 |

Multiple Open, second & third section open by default

55 | 60 | 62 |

item 1 (paragraph)

63 |

item 2 (paragraph)

64 |

item 3 (paragraph)

65 |

item 4 (paragraph)

66 |
67 | 69 |

item 1 (paragraph)

70 |

item 2 (paragraph)

71 |

item 3 (paragraph)

72 |

item 4 (paragraph)

73 |
74 | 76 |

hello

77 |

item 1 (paragraph)

78 |

item 2 (paragraph)

79 |

item 3 (paragraph)

80 |

item 4 (paragraph)

81 |
82 | 84 |

item 1 (paragraph)

85 |

item 2 (paragraph)

86 |

item 3 (paragraph)

87 |

item 4 (paragraph)

88 |
89 |
90 |


91 |

Multiple Open, second and fourth section open by default

92 | 97 | 99 |

item 1 (paragraph)

100 |

item 2 (paragraph)

101 |

item 3 (paragraph)

102 |

item 4 (paragraph)

103 |
104 | 106 |

item 1 (paragraph)

107 |

item 2 (paragraph)

108 |

item 3 (paragraph)

109 |

item 4 (paragraph)

110 |
111 | 113 |

hello

114 |

item 1 (paragraph)

115 |

item 2 (paragraph)

116 |

item 3 (paragraph)

117 |

item 4 (paragraph)

118 |
119 | 121 |

item 1 (paragraph)

122 |

item 2 (paragraph)

123 |

item 3 (paragraph)

124 |

item 4 (paragraph)

125 |
126 |
127 |


128 |

Multiple Open, closed by default

129 | 132 | 134 |

item 1 (paragraph)

135 |

item 2 (paragraph)

136 |

item 3 (paragraph)

137 |

item 4 (paragraph)

138 |
139 | 141 |

item 1 (paragraph)

142 |

item 2 (paragraph)

143 |

item 3 (paragraph)

144 |

item 4 (paragraph)

145 |
146 | 148 |

hello

149 |

item 1 (paragraph)

150 |

item 2 (paragraph)

151 |

item 3 (paragraph)

152 |

item 4 (paragraph)

153 |
154 | 156 |

item 1 (paragraph)

157 |

item 2 (paragraph)

158 |

item 3 (paragraph)

159 |

item 4 (paragraph)

160 |
161 |
162 | 163 |

Single Item (note, singleOpen must be `false`)

164 | 165 | 168 | Testing single section 169 | 170 | 171 |
172 | ); 173 | } 174 | } 175 | --------------------------------------------------------------------------------