Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-accessible-accordion

Package Overview
Dependencies
Maintainers
4
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-accessible-accordion - npm Package Compare versions

Comparing version 1.0.2 to 2.0.0

dist/actions/index.js

44

CHANGELOG.md

@@ -7,2 +7,46 @@ Changelog

## [[v2.0.0]](https://github.com/springload/react-accessible-accordion/releases/tag/v2.0.0)
Version 2.0 represents a total refactor, with a new context-based approach which should make this library more flexible, more maintainable and more comprehensively testable.
As this is a major release, users should expect some breaking changes - though they should be limited to the removal of the `activeItems` prop (read more below).
### Added
- Exports `resetNextId` (https://github.com/springload/react-accessible-accordion/issues/41).
### Fixed
- Defect where controlled components' props were overridden by React.Children.map (https://github.com/springload/react-accessible-accordion/issues/33).
- Defect where accordion crashed with unexpected `children` types (https://github.com/springload/react-accessible-accordion/issues/45).
- Defect where React Accessible Accordion's components could not be extended.
- Defect where the `children` of `Accordion` or `AccordionItem` could not be arbitrary.
- Defect where `AccordionItem` had to be a child of `Accordion` (as opposed to to an arbitrary-level descendant).
- Defect where `AccordionItemBody` and `AccordionItemTitle` had to be children of `AccordionItem` (as opposed to arbitrary-level descendants).
### Removed:
- 🚨 Breaking change 🚨 `activeItems` property is no longer supported.
Control at the `Accordion` level (via the `activeItems` prop) and `AccordionItem` level (via the `expanded` prop) fought against one another, and choosing which control mechanism to give preference to would have been an arbitrary decision - and whichever way we went, we would have had test cases which demonstrated unusual/unpredictable behaviour. The `activeItems` mechanism was the obvious one to remove - it was arguably the "less React-y way", and we considered it more of a convenience than a feature. Crucially though, it fought too hard against the new architecture of the library, and keeping it would have prevented us enabling lots of other new features or resolving some of the issues that our users had raised.
If you're currently using activeItems, you're upgrade path might look like this:
```diff
const items = ['Foo', 'Bar'];
const activeItems = [0];
return (
- <Accordion activeItems={activeItems} />
+ <Accordion />
{activeItems.forEach((item, i) => (
- <AccordionItem key={item}>{item}</AccordionItem>
+ <AccordionItem key={item} expanded={activeItems.includes(i)}>{item}</AccordionItem>
)}
</Accordion>
);
```
Please don't hesitate to reach out to one of the maintainers (or raise an issue) if you're having trouble upgrading - we're happy to help!
## [[v1.0.1]](https://github.com/springload/react-accessible-accordion/releases/tag/v1.0.1)

@@ -9,0 +53,0 @@

201

dist/Accordion/accordion.js

@@ -13,8 +13,10 @@ 'use strict';

var _utils = require('../utils');
var _unistore = require('unistore');
var _unistore2 = _interopRequireDefault(_unistore);
var _react3 = require('unistore/react');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -26,2 +28,4 @@

// import { isArraysEqualShallow } from '../utils';
var Accordion = function (_Component) {

@@ -41,102 +45,119 @@ _inherits(Accordion, _Component);

return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Accordion.__proto__ || Object.getPrototypeOf(Accordion)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
activeItems: _this.preExpandedItems(),
accordion: true
}, _this.renderItems = _this.renderItems.bind(_this), _temp), _possibleConstructorReturn(_this, _ret);
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Accordion.__proto__ || Object.getPrototypeOf(Accordion)).call.apply(_ref, [this].concat(args))), _this), _this.store = (0, _unistore2.default)({
accordion: 0
// onChange: this.props.onChange,
// activeItems: this.props.activeItems,
}), _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(Accordion, [{
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (!(0, _utils.isArraysEqualShallow)(nextProps.activeItems, this.state.activeItems)) {
var newActiveItems = void 0;
if (nextProps.accordion) {
newActiveItems = nextProps.activeItems.length ? [nextProps.activeItems[0]] : [];
} else {
newActiveItems = nextProps.activeItems.slice();
}
this.setState({
activeItems: newActiveItems
});
key: 'render',
nextProps.onChange(nextProps.accordion ? newActiveItems[0] : newActiveItems);
}
}
}, {
key: 'preExpandedItems',
value: function preExpandedItems() {
var _this2 = this;
var activeItems = [];
_react2.default.Children.map(this.props.children, function (item, index) {
if (item.props.expanded) {
if (_this2.props.accordion) {
if (activeItems.length === 0) activeItems.push(item.props.customKey || index);
} else {
activeItems.push(item.props.customKey || index);
}
}
});
if (activeItems.length === 0 && this.props.activeItems.length !== 0) {
activeItems = this.props.accordion ? [this.props.activeItems[0]] : this.props.activeItems.slice();
}
return activeItems;
}
}, {
key: 'handleClick',
value: function handleClick(key) {
var activeItems = this.state.activeItems;
if (this.props.accordion) {
activeItems = activeItems[0] === key ? [] : [key];
} else {
activeItems = [].concat(_toConsumableArray(activeItems));
var index = activeItems.indexOf(key);
var isActive = index > -1;
if (isActive) {
// remove active state
activeItems.splice(index, 1);
} else {
activeItems.push(key);
}
}
this.setState({
activeItems: activeItems
});
// state = {
// activeItems: this.preExpandedItems(),
// accordion: true,
// };
this.props.onChange(this.props.accordion ? activeItems[0] : activeItems);
}
}, {
key: 'renderItems',
value: function renderItems() {
var _this3 = this;
// componentWillReceiveProps(nextProps: AccordionProps) {
// if (
// !isArraysEqualShallow(nextProps.activeItems, this.state.activeItems)
// ) {
// let newActiveItems;
// if (nextProps.accordion) {
// newActiveItems = nextProps.activeItems.length
// ? [nextProps.activeItems[0]]
// : [];
// } else {
// newActiveItems = nextProps.activeItems.slice();
// }
// this.setState({
// activeItems: newActiveItems,
// });
var _props = this.props,
accordion = _props.accordion,
children = _props.children;
// nextProps.onChange(
// nextProps.accordion ? newActiveItems[0] : newActiveItems,
// );
// }
// }
// preExpandedItems() {
// let activeItems = [];
// React.Children.map(this.props.children, (item, index) => {
// if (item.props.expanded) {
// if (this.props.accordion) {
// if (activeItems.length === 0)
// activeItems.push(item.props.customKey || index);
// } else {
// activeItems.push(item.props.customKey || index);
// }
// }
// });
// if (activeItems.length === 0 && this.props.activeItems.length !== 0) {
// activeItems = this.props.accordion
// ? [this.props.activeItems[0]]
// : this.props.activeItems.slice();
// }
// return activeItems;
// }
return _react2.default.Children.map(children, function (item, index) {
var key = item.props.customKey || index;
var expanded = _this3.state.activeItems.indexOf(key) !== -1 && !item.props.disabled;
// handleClick(key: number | string) {
// let activeItems = this.state.activeItems;
// if (this.props.accordion) {
// activeItems = activeItems[0] === key ? [] : [key];
// } else {
// activeItems = [...activeItems];
// const index = activeItems.indexOf(key);
// const isActive = index > -1;
// if (isActive) {
// // remove active state
// activeItems.splice(index, 1);
// } else {
// activeItems.push(key);
// }
// }
// this.setState({
// activeItems,
// });
return _react2.default.cloneElement(item, {
disabled: item.props.disabled,
accordion: accordion,
expanded: expanded,
key: 'accordion__item-' + key,
onClick: _this3.handleClick.bind(_this3, key)
});
});
}
}, {
key: 'render',
// this.props.onChange(
// this.props.accordion ? activeItems[0] : activeItems,
// );
// }
// renderItems() {
// const { accordion, children } = this.props;
// return React.Children.map(children, (item, index) => {
// const key = item.props.customKey || index;
// const expanded =
// this.state.activeItems.indexOf(key) !== -1 &&
// !item.props.disabled;
// return React.cloneElement(item, {
// disabled: item.props.disabled,
// accordion,
// expanded,
// key: `accordion__item-${key}`,
// onClick: this.handleClick.bind(this, key),
// });
// });
// }
// renderItems = this.renderItems.bind(this);
value: function render() {
var _props2 = this.props,
className = _props2.className,
accordion = _props2.accordion;
var _props = this.props,
className = _props.className,
children = _props.children;
return _react2.default.createElement(
'div',
{ role: accordion ? 'tablist' : null, className: className },
this.renderItems()
_react3.Provider,
{ store: this.store },
_react2.default.createElement(
'div',
{ className: className },
children
)
);

@@ -143,0 +164,0 @@ }

@@ -11,2 +11,4 @@ 'use strict';

var _enzyme = require('enzyme');
var _accordion = require('./accordion');

@@ -20,2 +22,10 @@

var _accordionItemTitle = require('../AccordionItemTitle/accordion-item-title');
var _accordionItemTitle2 = _interopRequireDefault(_accordionItemTitle);
var _accordionItemBody = require('../AccordionItemBody/accordion-item-body');
var _accordionItemBody2 = _interopRequireDefault(_accordionItemBody);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -27,2 +37,9 @@

jest.mock('../AccordionItemTitle/accordion-item-title', function () {
return 'div';
});
jest.mock('../AccordionItemBody/accordion-item-body', function () {
return 'div';
});
describe('Accordion', function () {

@@ -469,2 +486,89 @@ it('renders correctly with min params', function () {

});
it('different className with the same activeItems prop', function () {
var wrapper = _reactTestRenderer2.default.create(_react2.default.createElement(
_accordion2.default,
{ activeItems: [1], className: 'test-1' },
_react2.default.createElement(
_accordionItem2.default,
null,
'Fake Child'
),
_react2.default.createElement(
_accordionItem2.default,
null,
'Fake Child'
)
));
wrapper.update(_react2.default.createElement(
_accordion2.default,
{ activeItems: [1], className: 'test-2' },
_react2.default.createElement(
_accordionItem2.default,
null,
'Fake Child'
),
_react2.default.createElement(
_accordionItem2.default,
null,
'Fake Child'
)
));
expect(wrapper).toMatchSnapshot();
});
// it('supports controlled component inside accordion', () => {
// class App extends Component<*, { value: string }> {
// constructor(props) {
// super(props);
// this.state = {
// value: '',
// };
// }
// handleChange = evt => {
// this.setState({
// value: evt.target.value,
// });
// };
// render() {
// return (
// <Accordion activeItems={[1]} id="accordion">
// <AccordionItem id="accordion-item--1">
// <AccordionItemTitle>
// {`Title One`}
// </AccordionItemTitle>
// <AccordionItemBody>
// <input
// id="controlled-input--1"
// onChange={this.handleChange}
// value={this.state.value}
// />
// </AccordionItemBody>
// </AccordionItem>
// <AccordionItem>
// <AccordionItemTitle>
// {`Title Two`}
// </AccordionItemTitle>
// <AccordionItemBody>
// {`Body Two`}
// </AccordionItemBody>
// </AccordionItem>
// </Accordion>
// );
// }
// }
// const wrapper = mount(<App />);
// const accordion = wrapper.find(Accordion);
// const input = wrapper.find('#controlled-input--1');
// const itemOne = wrapper.find('#accordion-item--1');
// expect(accordion.instance().state.activeItems).toEqual([1]);
// itemOne.simulate('click');
// expect(accordion.instance().state.activeItems).toEqual([0]);
// input.simulate('change', { value: 'foo' });
// expect(accordion.instance().state.activeItems).toEqual([0]);
// });
});

@@ -21,2 +21,8 @@ 'use strict';

var _react3 = require('unistore/react');
var _actions = require('../actions');
var _actions2 = _interopRequireDefault(_actions);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -91,2 +97,3 @@

value: function render() {
// console.log(props, 'props');
var _props2 = this.props,

@@ -103,4 +110,5 @@ className = _props2.className,

{ className: itemClassName },
this.renderChildren()
'Child'
);
//return <div className={itemClassName}>{this.renderChildren()}</div>;
}

@@ -112,2 +120,5 @@ }]);

// export default AccordionItem;
AccordionItem.defaultProps = {

@@ -120,2 +131,10 @@ accordion: true,

};
exports.default = AccordionItem;
exports.default = (0, _react3.connect)('accordion', _actions2.default)(function (_ref2) {
var accordion = _ref2.accordion,
setAccordion = _ref2.setAccordion;
return _react2.default.createElement(
'div',
null,
'Test'
);
});
{
"name": "react-accessible-accordion",
"version": "1.0.2",
"version": "2.0.0",
"description": "Accessible Accordion component for React",
"main": "dist/index.js",
"main": "dist/umd/index.js",
"jsnext:main": "dist/es/index.js",
"scripts": {

@@ -16,3 +17,3 @@ "test": "jest",

"css": "cp src/react-accessible-accordion.css dist",
"build": "npm run js -s && npm run css -s",
"build": "NODE_ENV=production rollup -c",
"start": "npm run js:watch",

@@ -31,8 +32,25 @@ "start-demo": "webpack-dev-server --config ./webpack/webpack.config.demo.js",

"presets": [
"es2015",
[
"es2015",
{
"modules": false
}
],
"react",
"stage-2"
]
],
"env": {
"test": {
"presets": [
"es2015",
"react",
"stage-2"
]
}
}
},
"jest": {
"setupFiles": [
"./src/setupTests.js"
],
"testPathIgnorePatterns": [

@@ -80,2 +98,4 @@ "/node_modules/",

"css-loader": "^0.28.7",
"enzyme": "^3.2.0",
"enzyme-adapter-react-16": "^1.1.0",
"eslint": "^4.8.0",

@@ -92,5 +112,12 @@ "eslint-config-airbnb": "^15.1.0",

"prettier": "^1.7.3",
"raf": "^3.4.0",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-test-renderer": "^16.0.0",
"rollup": "^0.56.2",
"rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^8.3.0",
"rollup-plugin-eslint": "^4.0.0",
"rollup-plugin-node-resolve": "^3.0.3",
"rollup-plugin-replace": "^2.0.0",
"style-loader": "^0.18.2",

@@ -102,3 +129,5 @@ "webpack": "^3.6.0",

"classnames": "^2.2.5",
"consecutive": "^5.0.4"
"consecutive": "^5.0.4",
"mobx": "^3.4.0",
"mobx-react": "^4.3.5"
},

@@ -105,0 +134,0 @@ "peerDependencies": {

@@ -7,3 +7,3 @@ [react-accessible-accordion](https://springload.github.io/react-accessible-accordion/) [![npm](https://img.shields.io/npm/v/react-accessible-accordion.svg?style=flat-square)](https://www.npmjs.com/package/react-accessible-accordion) [![Build Status](https://travis-ci.org/springload/react-accessible-accordion.svg?branch=master)](https://travis-ci.org/springload/react-accessible-accordion) [![Coverage Status](https://coveralls.io/repos/github/springload/react-accessible-accordion/badge.svg)](https://coveralls.io/github/springload/react-accessible-accordion) [![Dependency Status](https://david-dm.org/springload/react-accessible-accordion.svg?style=flat-square)](https://david-dm.org/springload/react-accessible-accordion) [![devDependency Status](https://david-dm.org/springload/react-accessible-accordion/dev-status.svg?style=flat-square)](https://david-dm.org/springload/react-accessible-accordion#info=devDependencies)

This is a work in progress. Feel free to contribute. [Try a demo now](https://springload.github.io/react-accessible-accordion/).
Try a demo now](https://springload.github.io/react-accessible-accordion/).

@@ -17,5 +17,3 @@ If you like accessible components, feel free to check this other repo [react-accessible-modal](https://github.com/springload/react-accessible-modal).

```sh
npm install --save react-accessible-accordion
# react-accessible-accordion's peerDependencies:
npm install --save react@^15.0.0 react-dom@^15.0.0
npm install --save react-accessible-accordion react react-dom
```

@@ -25,3 +23,3 @@

```js
```jsx
import React from 'react';

@@ -46,5 +44,3 @@ import ReactDOM from 'react-dom';

<AccordionItemBody>
<p>
Body content
</p>
<p>Body content</p>
</AccordionItemBody>

@@ -58,5 +54,3 @@ </AccordionItem>

<AccordionItemBody>
<p>
Body content
</p>
<p>Body content</p>
</AccordionItemBody>

@@ -104,8 +98,2 @@ </AccordionItem>

</tr>
<tr>
<td>activeItems</td>
<td>Array</td>
<td>[]</td>
<td>Indexes (or custom keys) to pre expand items. Can be changed dynamically. Doesn't have the priority against `AccordionItem - expanded` on first render.</td>
</tr>
</tbody>

@@ -146,8 +134,2 @@ </table>

</tr>
<tr>
<td>customKey</td>
<td>String</td>
<td></td>
<td>Custom key to be used as a reference in `Accordion - activeItems`</td>
</tr>
</tbody>

@@ -214,2 +196,15 @@ </table>

### resetNextUuid
<table class="table table-bordered table-striped">
<tbody>
<tr>
<td>Function(void)</td>
</tr>
<tr>
<td>Resets the internal counter for Accordion items' identifiers (including `id` attributes). For use in test suites and isomorphic frameworks.</td>
</tr>
</tbody>
</table>
## Accessibility

@@ -227,6 +222,6 @@

- Accordion: `tablist`
- AccordionItem: no specific role
- AccordionItemTitle: `tab`
- AccordionItemBody: `tabpanel`
* Accordion: `tablist`
* AccordionItem: no specific role
* AccordionItemTitle: `tab`
* AccordionItemBody: `tabpanel`

@@ -239,6 +234,6 @@ #### Multiple items

- Accordion: no specific role
- AccordionItem: no specific role
- AccordionItemTitle: `button`
- AccordionItemBody: no specific role
* Accordion: no specific role
* AccordionItem: no specific role
* AccordionItemTitle: `button`
* AccordionItemBody: no specific role

@@ -297,3 +292,2 @@ ## Development

# Browser support

@@ -303,10 +297,10 @@

| Browser | Device/OS | Version | Notes |
|---------|-----------|---------|-------|
| Mobile Safari | iOS | latest ||
| Chrome | Android | latest ||
| IE | Windows | 11 ||
| MS Edge | Windows | latest ||
| Chrome | Desktop | latest ||
| Firefox | Desktop | latest ||
| Safari | OSX | latest ||
| Browser | Device/OS | Version | Notes |
| ------------- | --------- | ------- | ----- |
| Mobile Safari | iOS | latest | |
| Chrome | Android | latest | |
| IE | Windows | 11 | |
| MS Edge | Windows | latest | |
| Chrome | Desktop | latest | |
| Firefox | Desktop | latest | |
| Safari | OSX | latest | |

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc