Skip to content

Commit

Permalink
0.0.14
Browse files Browse the repository at this point in the history
  • Loading branch information
brukh committed Aug 2, 2016
1 parent ae9d50a commit a54f8db
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 60 deletions.
32 changes: 17 additions & 15 deletions dist-modules/Accordion/index.js
Expand Up @@ -30,6 +30,13 @@ var arrayify = function arrayify(obj) {
return [].concat(obj);
};

// removes duplicate from array
var dedupeArr = function dedupeArr(arr) {
return arr.filter(function (item, index, inputArray) {
return inputArray.indexOf(item) === index;
});
};

var Accordion = function (_Component) {
_inherits(Accordion, _Component);

Expand All @@ -50,17 +57,6 @@ var Accordion = function (_Component) {
}

_createClass(Accordion, [{
key: 'componentDidMount',
value: function componentDidMount() {
var _this2 = this;

this.state.activeItems.forEach(function (index) {
if (_this2.refs['item-' + index]) {
_this2.refs['item-' + index].allowOverflow();
}
});
}
}, {
key: 'handleClick',
value: function handleClick(index) {
var newState = {};
Expand All @@ -72,6 +68,10 @@ var Accordion = function (_Component) {

if (position !== -1) {
newState.activeItems.splice(position, 1);

if (this.props.openNextAccordionItem && index !== this.props.children.length - 1) {
newState.activeItems.push(index + 1);
}
} else if (this.props.allowMultiple) {
newState.activeItems.push(index);
} else {
Expand All @@ -82,26 +82,28 @@ var Accordion = function (_Component) {
this.props.onChange(newState);
}

// removes duplicate items in activeItems array
newState.activeItems = dedupeArr(newState.activeItems);
this.setState(newState);
}
}, {
key: 'renderItems',
value: function renderItems() {
var _this3 = this;
var _this2 = this;

if (!this.props.children) {
return null;
}

var children = arrayify(this.props.children);
return children.map(function (item, index) {
var key = item.props.slug || index;
var expanded = _this3.state.activeItems.indexOf(key) !== -1;
var key = _this2.props.openNextAccordionItem ? index : item.props.slug || index;
var expanded = _this2.state.activeItems.indexOf(key) !== -1;

return _react2.default.cloneElement(item, {
expanded: expanded,
key: key,
onClick: _this3.handleClick.bind(_this3, key),
onClick: _this2.handleClick.bind(_this2, key),
ref: 'item-' + key
});
});
Expand Down
98 changes: 98 additions & 0 deletions dist-modules/Accordion/test.js
Expand Up @@ -197,4 +197,102 @@ describe('Accordion Test Case', function () {
(0, _unexpected2.default)(instance.state.activeItems, 'to equal', [1, 0]);
});
});

describe('openNextAccordionItem', function () {

it('should open next accordion item', function () {
var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(
_index2.default,
{ openNextAccordionItem: true },
_react2.default.createElement(_AccordionItem2.default, { title: 'First' }),
_react2.default.createElement(_AccordionItem2.default, { title: 'Second' })
));

instance = tree.getMountedInstance();
vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be true');
(0, _unexpected2.default)(items[1].props.expanded, 'to be false');

instance.handleClick(0);

vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be false');
(0, _unexpected2.default)(items[1].props.expanded, 'to be true');
});

it('should close last item and not open another accordion item', function () {
var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(
_index2.default,
{ openNextAccordionItem: true, activeItems: [1] },
_react2.default.createElement(_AccordionItem2.default, { title: 'First' }),
_react2.default.createElement(_AccordionItem2.default, { title: 'Second' })
));

instance = tree.getMountedInstance();
vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be false');
(0, _unexpected2.default)(items[1].props.expanded, 'to be true');

instance.handleClick(1);

vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be false');
(0, _unexpected2.default)(items[1].props.expanded, 'to be false');
});

it('should open multiple if allowMultiple present', function () {
var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(
_index2.default,
{ openNextAccordionItem: true, allowMultiple: true },
_react2.default.createElement(_AccordionItem2.default, { title: 'First' }),
_react2.default.createElement(_AccordionItem2.default, { title: 'Second' }),
_react2.default.createElement(_AccordionItem2.default, { title: 'Third' })
));

instance = tree.getMountedInstance();
vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be true');
(0, _unexpected2.default)(items[1].props.expanded, 'to be false');
(0, _unexpected2.default)(items[2].props.expanded, 'to be false');

instance.handleClick(1);
instance.handleClick(2);

vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be true');
(0, _unexpected2.default)(items[1].props.expanded, 'to be true');
(0, _unexpected2.default)(items[2].props.expanded, 'to be true');
});

it('should override slug property and assign key to index', function () {
var tree = _skinDeep2.default.shallowRender(_react2.default.createElement(
_index2.default,
{ openNextAccordionItem: true },
_react2.default.createElement(_AccordionItem2.default, { title: 'First', slug: 'first' }),
_react2.default.createElement(_AccordionItem2.default, { title: 'Second', slug: 'second' })
));

instance = tree.getMountedInstance();

instance.handleClick(0);

vdom = tree.getRenderOutput();
items = vdom.props.children;

(0, _unexpected2.default)(items[0].props.expanded, 'to be false');
(0, _unexpected2.default)(items[1].props.expanded, 'to be true');
});
});
});
112 changes: 69 additions & 43 deletions dist-modules/AccordionItem/index.js
Expand Up @@ -52,7 +52,8 @@ var AccordionItem = function (_Component) {

_this.state = {
maxHeight: props.expanded ? 'none' : 0,
overflow: props.expanded ? 'visible' : 'hidden'
overflow: props.expanded ? 'visible' : 'hidden',
duration: 300
};
return _this;
}
Expand All @@ -62,53 +63,29 @@ var AccordionItem = function (_Component) {
value: function componentWillMount() {
this.uuid = _uuid2.default.v4();
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var _this2 = this;

// allow overflow for absolute positioned elements inside
// the item body, but only after animation is complete
_reactDom2.default.findDOMNode(this).addEventListener('transitionend', function () {
if (_this2.props.expanded) _this2.allowOverflow();
});
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps) {
if (prevProps.expanded !== this.props.expanded) {
this.setMaxHeight();
if (this.props.expanded) {
this.maybeExpand();
} else {
this.handleCollapse();
}
}
}
}, {
key: 'allowOverflow',
value: function allowOverflow() {
key: 'startTransition',
value: function startTransition() {
this.setState({
maxHeight: 'none',
overflow: 'visible'
maxHeight: this.maxHeight,
overflow: 'hidden'
});
clearTimeout(this.timeout);
}
}, {
key: 'updateState',
value: function updateState(node) {
var _this3 = this;

if (!this.props.expanded) {
this.setState({
maxHeight: node.scrollHeight + 'px'
});
}

setTimeout(function () {
return _this3.setState({
maxHeight: _this3.props.expanded ? node.scrollHeight + 'px' : 0,
overflow: 'hidden'
});
}, 0);
}
}, {
key: 'setMaxHeight',
value: function setMaxHeight() {
key: 'maybeExpand',
value: function maybeExpand() {
var bodyNode = _reactDom2.default.findDOMNode(this.refs.body);
var images = bodyNode.querySelectorAll('img');

Expand All @@ -117,23 +94,64 @@ var AccordionItem = function (_Component) {
return;
}

this.updateState(bodyNode);
this.handleExpand();
}
}, {
key: 'handleExpand',
value: function handleExpand() {
var _this2 = this;

// Wait for images to load before calculating maxHeight
var onExpand = this.props.onExpand;


this.startTransition();
this.timeout = setTimeout(function () {
_this2.setState({
maxHeight: 'none',
overflow: 'visible'
});

if (onExpand) {
onExpand();
}
}, this.state.duration);
}
}, {
key: 'handleCollapse',
value: function handleCollapse() {
var _this3 = this;

var onClose = this.props.onClose;


this.startTransition();
this.timeout = setTimeout(function () {
_this3.setState({
maxHeight: 0,
overflow: 'hidden'
});

if (onClose) {
onClose();
}
}, 0);
}
}, {
key: 'preloadImages',
value: function preloadImages(node, images) {


// Wait for images to load before calculating maxHeight
value: function preloadImages(node) {
var _this4 = this;

var imagesLoaded = 0;
var images = arguments.length <= 1 || arguments[1] === undefined ? [] : arguments[1];

var imagesLoaded = 0;
var imgLoaded = function imgLoaded() {
imagesLoaded++;

if (imagesLoaded === images.length) {
_this4.updateState(node);
_this4.handleExpand();
}
};

Expand Down Expand Up @@ -174,7 +192,9 @@ var AccordionItem = function (_Component) {
uuid: this.uuid }),
_react2.default.createElement(
_AccordionItemBody2.default,
{ maxHeight: this.state.maxHeight,
{
maxHeight: this.state.maxHeight,
duration: this.state.duration,
className: this.props.bodyClassName,
overflow: this.state.overflow,
ref: 'body',
Expand All @@ -183,6 +203,12 @@ var AccordionItem = function (_Component) {
)
);
}
}, {
key: 'maxHeight',
get: function get() {
var body = _reactDom2.default.findDOMNode(this.refs.body);
return body.scrollHeight + 'px';
}
}]);

return AccordionItem;
Expand Down
3 changes: 2 additions & 1 deletion dist-modules/AccordionItemBody/index.js
Expand Up @@ -37,7 +37,7 @@ var AccordionItemBody = function (_Component) {
var style = {
maxHeight: this.props.maxHeight,
overflow: this.props.overflow,
transition: 'max-height .3s ease'
transition: 'max-height ' + this.props.duration + 'ms ease'
};

return _react2.default.createElement(
Expand All @@ -64,6 +64,7 @@ exports.default = AccordionItemBody;
AccordionItemBody.propTypes = {
className: _react.PropTypes.string,
maxHeight: _react.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.number]),
duration: _react.PropTypes.number,
overflow: _react.PropTypes.string,
uuid: _react.PropTypes.string
};
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "react-sanfona",
"version": "0.0.13",
"version": "0.0.14",
"description": "React accessible accordion component",
"main": "./dist-modules/index.js",
"scripts": {
Expand Down

0 comments on commit a54f8db

Please sign in to comment.