├── 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 | 
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 |
--------------------------------------------------------------------------------