From 0afea921236035da89720d877251df4aa3d647d3 Mon Sep 17 00:00:00 2001 From: psimyn Date: Wed, 21 Dec 2016 07:49:42 +1100 Subject: [PATCH] 0.1.0 --- dist-modules/Accordion/index.js | 29 +++++++++---- dist-modules/Accordion/test.js | 16 +++++++ dist-modules/AccordionItem/index.js | 24 ++++++++--- dist-modules/AccordionItem/test.js | 31 ++++++++++++++ dist-modules/index.js | 14 ++++++- dist/react-sanfona.js | 65 ++++++++++++++++++++++------- package.json | 2 +- 7 files changed, 147 insertions(+), 34 deletions(-) diff --git a/dist-modules/Accordion/index.js b/dist-modules/Accordion/index.js index cd6b422..7969c0e 100644 --- a/dist-modules/Accordion/index.js +++ b/dist-modules/Accordion/index.js @@ -45,18 +45,29 @@ var Accordion = function (_Component) { var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Accordion).call(this, props)); - var activeItems = arrayify(props.activeItems); - - // can't have multiple active items, just use the first one - if (!props.allowMultiple) activeItems = [activeItems[0]]; - - _this.state = { - activeItems: activeItems - }; + _this.updateActiveItems = _this.updateActiveItems.bind(_this); + _this.updateActiveItems(props); return _this; } _createClass(Accordion, [{ + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + this.updateActiveItems(nextProps); + } + }, { + key: 'updateActiveItems', + value: function updateActiveItems(props) { + var activeItems = arrayify(props.activeItems); + + // can't have multiple active items, just use the first one + if (!props.allowMultiple) activeItems = [activeItems[0]]; + + this.state = { + activeItems: activeItems + }; + } + }, { key: 'handleClick', value: function handleClick(index) { var newState = {}; @@ -98,7 +109,7 @@ var Accordion = function (_Component) { var children = arrayify(this.props.children); return children.map(function (item, index) { var key = _this2.props.openNextAccordionItem ? index : item.props.slug || index; - var expanded = _this2.state.activeItems.indexOf(key) !== -1; + var expanded = _this2.state.activeItems.indexOf(key) !== -1 && !item.props.disabled; return _react2.default.cloneElement(item, { expanded: expanded, diff --git a/dist-modules/Accordion/test.js b/dist-modules/Accordion/test.js index a0ccefc..2894456 100644 --- a/dist-modules/Accordion/test.js +++ b/dist-modules/Accordion/test.js @@ -75,6 +75,22 @@ describe('Accordion Test Case', function () { (0, _unexpected2.default)(items[1].props.expanded, 'to be true'); }); + it('should ignore a activeItems prop when AccordionItem disabled', function () { + var tree = _skinDeep2.default.shallowRender(_react2.default.createElement( + _index2.default, + { activeItems: 1 }, + _react2.default.createElement(_AccordionItem2.default, { title: 'First' }), + _react2.default.createElement(_AccordionItem2.default, { title: 'Second', disabled: true }) + )); + + vdom = tree.getRenderOutput(); + + items = tree.props.children; + + (0, _unexpected2.default)(items[0].props.expanded, 'to be false'); + (0, _unexpected2.default)(items[1].props.expanded, 'to be false'); + }); + it('should accept a string as active item prop', function () { var tree = _skinDeep2.default.shallowRender(_react2.default.createElement( _index2.default, diff --git a/dist-modules/AccordionItem/index.js b/dist-modules/AccordionItem/index.js index 4970071..1f78a3c 100644 --- a/dist-modules/AccordionItem/index.js +++ b/dist-modules/AccordionItem/index.js @@ -61,7 +61,7 @@ var AccordionItem = function (_Component) { _createClass(AccordionItem, [{ key: 'componentWillMount', value: function componentWillMount() { - this.uuid = _uuid2.default.v4(); + this.uuid = this.props.uuid || _uuid2.default.v4(); } }, { key: 'componentDidUpdate', @@ -86,6 +86,13 @@ var AccordionItem = function (_Component) { }, { key: 'maybeExpand', value: function maybeExpand() { + var disabled = this.props.disabled; + + + if (disabled) { + return; + } + var bodyNode = _reactDom2.default.findDOMNode(this.refs.body); var images = bodyNode.querySelectorAll('img'); @@ -101,7 +108,9 @@ var AccordionItem = function (_Component) { value: function handleExpand() { var _this2 = this; - var onExpand = this.props.onExpand; + var _props = this.props; + var onExpand = _props.onExpand; + var slug = _props.slug; this.startTransition(); @@ -112,7 +121,7 @@ var AccordionItem = function (_Component) { }); if (onExpand) { - onExpand(); + slug ? onExpand(slug) : onExpand(); } }, this.state.duration); } @@ -165,7 +174,7 @@ var AccordionItem = function (_Component) { key: 'getProps', value: function getProps() { var props = { - className: (0, _classnames2.default)('react-sanfona-item', this.props.className, { 'react-sanfona-item-expanded': this.props.expanded }, this.props.expandedClassName && _defineProperty({}, this.props.expandedClassName, this.props.expanded)), + className: (0, _classnames2.default)('react-sanfona-item', this.props.className, { 'react-sanfona-item-expanded': this.props.expanded && !this.props.disabled }, this.props.expandedClassName && _defineProperty({}, this.props.expandedClassName, this.props.expanded), { 'react-sanfona-item-disabled': this.props.disabled }, this.props.disabledClassName && _defineProperty({}, this.props.disabledClassName, this.props.disabled)), role: 'tabpanel', style: this.props.style }; @@ -187,7 +196,7 @@ var AccordionItem = function (_Component) { _react2.default.createElement(_AccordionItemTitle2.default, { className: this.props.titleClassName, title: this.props.title, - onClick: this.props.onClick, + onClick: this.props.disabled ? null : this.props.onClick, titleColor: this.props.titleColor, uuid: this.uuid }), _react2.default.createElement( @@ -225,5 +234,8 @@ AccordionItem.propTypes = { title: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.node]), expandedClassName: _react.PropTypes.string, style: _react.PropTypes.object, - titleClassName: _react.PropTypes.string + titleClassName: _react.PropTypes.string, + disabled: _react.PropTypes.bool, + disabledClassName: _react.PropTypes.string, + uuid: _react.PropTypes.string }; \ No newline at end of file diff --git a/dist-modules/AccordionItem/test.js b/dist-modules/AccordionItem/test.js index 18b61c2..225c7df 100644 --- a/dist-modules/AccordionItem/test.js +++ b/dist-modules/AccordionItem/test.js @@ -55,6 +55,16 @@ describe('AccordionItem Test Case', function () { (0, _unexpected2.default)(instance.uuid, 'not to equal', anotherInstance.uuid); }); + it('should allow custom uuid', function () { + var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(_index2.default, { uuid: 'first item' })); + var treeAlt = _skinDeep2.default.shallowRender(_react2.default.createElement(_index2.default, { uuid: 'second item' })); + + instance = tree.getMountedInstance(); + var anotherInstance = treeAlt.getMountedInstance(); + + (0, _unexpected2.default)(instance.uuid, 'to equal', "first item"); + }); + describe('aria', function () { it('should set aria-expanded to true when expanded prop is true', function () { @@ -71,4 +81,25 @@ describe('AccordionItem Test Case', function () { (0, _unexpected2.default)(vdom.props['aria-hidden'], 'to be true'); }); }); + + describe('disabled mode', function () { + + it('should be false by default', function () { + var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(_index2.default, null)); + vdom = tree.getRenderOutput(); + (0, _unexpected2.default)(vdom.props['disabled'], 'to be undefined'); + }); + + it('should have react-sanfona-item-disabled className when disabled', function () { + var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(_index2.default, { disabled: true })); + vdom = tree.getRenderOutput(); + (0, _unexpected2.default)(vdom.props['className'], 'to be', 'react-sanfona-item react-sanfona-item-disabled'); + }); + + it('should have a custom className when provided', function () { + var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(_index2.default, { disabled: true, disabledClassName: 'customDisabled' })); + vdom = tree.getRenderOutput(); + (0, _unexpected2.default)(vdom.props['className'], 'to be', 'react-sanfona-item react-sanfona-item-disabled customDisabled'); + }); + }); }); \ No newline at end of file diff --git a/dist-modules/index.js b/dist-modules/index.js index 7a0d5e7..188e12d 100644 --- a/dist-modules/index.js +++ b/dist-modules/index.js @@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.AccordionItem = exports.Accordion = undefined; +exports.AccordionItemBody = exports.AccordionItemTitle = exports.AccordionItem = exports.Accordion = undefined; var _Accordion2 = require('./Accordion'); @@ -13,7 +13,17 @@ var _AccordionItem2 = require('./AccordionItem'); var _AccordionItem3 = _interopRequireDefault(_AccordionItem2); +var _AccordionItemTitle2 = require('./AccordionItemTitle'); + +var _AccordionItemTitle3 = _interopRequireDefault(_AccordionItemTitle2); + +var _AccordionItemBody2 = require('./AccordionItemBody'); + +var _AccordionItemBody3 = _interopRequireDefault(_AccordionItemBody2); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.Accordion = _Accordion3.default; -exports.AccordionItem = _AccordionItem3.default; \ No newline at end of file +exports.AccordionItem = _AccordionItem3.default; +exports.AccordionItemTitle = _AccordionItemTitle3.default; +exports.AccordionItemBody = _AccordionItemBody3.default; \ No newline at end of file diff --git a/dist/react-sanfona.js b/dist/react-sanfona.js index 5bc724e..6aed492 100644 --- a/dist/react-sanfona.js +++ b/dist/react-sanfona.js @@ -59,7 +59,7 @@ return /******/ (function(modules) { // webpackBootstrap Object.defineProperty(exports, "__esModule", { value: true }); - exports.AccordionItem = exports.Accordion = undefined; + exports.AccordionItemBody = exports.AccordionItemTitle = exports.AccordionItem = exports.Accordion = undefined; var _Accordion2 = __webpack_require__(1); @@ -69,10 +69,20 @@ return /******/ (function(modules) { // webpackBootstrap var _AccordionItem3 = _interopRequireDefault(_AccordionItem2); + var _AccordionItemTitle2 = __webpack_require__(9); + + var _AccordionItemTitle3 = _interopRequireDefault(_AccordionItemTitle2); + + var _AccordionItemBody2 = __webpack_require__(8); + + var _AccordionItemBody3 = _interopRequireDefault(_AccordionItemBody2); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.Accordion = _Accordion3.default; exports.AccordionItem = _AccordionItem3.default; + exports.AccordionItemTitle = _AccordionItemTitle3.default; + exports.AccordionItemBody = _AccordionItemBody3.default; /***/ }, /* 1 */ @@ -125,18 +135,29 @@ return /******/ (function(modules) { // webpackBootstrap var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Accordion).call(this, props)); - var activeItems = arrayify(props.activeItems); - - // can't have multiple active items, just use the first one - if (!props.allowMultiple) activeItems = [activeItems[0]]; - - _this.state = { - activeItems: activeItems - }; + _this.updateActiveItems = _this.updateActiveItems.bind(_this); + _this.updateActiveItems(props); return _this; } _createClass(Accordion, [{ + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + this.updateActiveItems(nextProps); + } + }, { + key: 'updateActiveItems', + value: function updateActiveItems(props) { + var activeItems = arrayify(props.activeItems); + + // can't have multiple active items, just use the first one + if (!props.allowMultiple) activeItems = [activeItems[0]]; + + this.state = { + activeItems: activeItems + }; + } + }, { key: 'handleClick', value: function handleClick(index) { var newState = {}; @@ -178,7 +199,7 @@ return /******/ (function(modules) { // webpackBootstrap var children = arrayify(this.props.children); return children.map(function (item, index) { var key = _this2.props.openNextAccordionItem ? index : item.props.slug || index; - var expanded = _this2.state.activeItems.indexOf(key) !== -1; + var expanded = _this2.state.activeItems.indexOf(key) !== -1 && !item.props.disabled; return _react2.default.cloneElement(item, { expanded: expanded, @@ -353,7 +374,7 @@ return /******/ (function(modules) { // webpackBootstrap _createClass(AccordionItem, [{ key: 'componentWillMount', value: function componentWillMount() { - this.uuid = _uuid2.default.v4(); + this.uuid = this.props.uuid || _uuid2.default.v4(); } }, { key: 'componentDidUpdate', @@ -378,6 +399,13 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: 'maybeExpand', value: function maybeExpand() { + var disabled = this.props.disabled; + + + if (disabled) { + return; + } + var bodyNode = _reactDom2.default.findDOMNode(this.refs.body); var images = bodyNode.querySelectorAll('img'); @@ -393,7 +421,9 @@ return /******/ (function(modules) { // webpackBootstrap value: function handleExpand() { var _this2 = this; - var onExpand = this.props.onExpand; + var _props = this.props; + var onExpand = _props.onExpand; + var slug = _props.slug; this.startTransition(); @@ -404,7 +434,7 @@ return /******/ (function(modules) { // webpackBootstrap }); if (onExpand) { - onExpand(); + slug ? onExpand(slug) : onExpand(); } }, this.state.duration); } @@ -457,7 +487,7 @@ return /******/ (function(modules) { // webpackBootstrap key: 'getProps', value: function getProps() { var props = { - className: (0, _classnames2.default)('react-sanfona-item', this.props.className, { 'react-sanfona-item-expanded': this.props.expanded }, this.props.expandedClassName && _defineProperty({}, this.props.expandedClassName, this.props.expanded)), + className: (0, _classnames2.default)('react-sanfona-item', this.props.className, { 'react-sanfona-item-expanded': this.props.expanded && !this.props.disabled }, this.props.expandedClassName && _defineProperty({}, this.props.expandedClassName, this.props.expanded), { 'react-sanfona-item-disabled': this.props.disabled }, this.props.disabledClassName && _defineProperty({}, this.props.disabledClassName, this.props.disabled)), role: 'tabpanel', style: this.props.style }; @@ -479,7 +509,7 @@ return /******/ (function(modules) { // webpackBootstrap _react2.default.createElement(_AccordionItemTitle2.default, { className: this.props.titleClassName, title: this.props.title, - onClick: this.props.onClick, + onClick: this.props.disabled ? null : this.props.onClick, titleColor: this.props.titleColor, uuid: this.uuid }), _react2.default.createElement( @@ -517,7 +547,10 @@ return /******/ (function(modules) { // webpackBootstrap title: _react.PropTypes.oneOfType([_react.PropTypes.string, _react.PropTypes.node]), expandedClassName: _react.PropTypes.string, style: _react.PropTypes.object, - titleClassName: _react.PropTypes.string + titleClassName: _react.PropTypes.string, + disabled: _react.PropTypes.bool, + disabledClassName: _react.PropTypes.string, + uuid: _react.PropTypes.string }; /***/ }, diff --git a/package.json b/package.json index 2033155..a754743 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-sanfona", - "version": "0.0.15", + "version": "0.1.0", "description": "React accessible accordion component", "main": "./dist-modules/index.js", "scripts": {