diff --git a/package.json b/package.json index 6ab592a..a4f0b55 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "classnames": "2.x", "css-animation": "1.x", "prop-types": "^15.5.6", - "rc-animate": "2.x" + "rc-animate": "2.x", + "react-is": "^16.7.0" } } diff --git a/src/Collapse.jsx b/src/Collapse.jsx index a2937b8..9dd2c83 100644 --- a/src/Collapse.jsx +++ b/src/Collapse.jsx @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import CollapsePanel from './Panel'; import openAnimationFactory from './openAnimationFactory'; import classNames from 'classnames'; +import { isFragment } from 'react-is'; function toArray(activeKey) { let currentActiveKey = activeKey; @@ -61,10 +62,11 @@ class Collapse extends Component { getItems() { const activeKey = this.state.activeKey; - const { prefixCls, accordion, destroyInactivePanel, expandIcon } = this.props; + const { prefixCls, accordion, destroyInactivePanel, expandIcon, children } = this.props; const newChildren = []; + const childList = isFragment(children) ? children.props.children : children; - Children.forEach(this.props.children, (child, index) => { + Children.forEach(childList, (child, index) => { if (!child) return; // If there is no key provide, use the panel order as default key const key = child.key || String(index); @@ -92,6 +94,14 @@ class Collapse extends Component { newChildren.push(React.cloneElement(child, props)); }); + // ref: https://github.com/ant-design/ant-design/issues/13884 + if (isFragment(children)) { + return ( + + {newChildren} + + ); + } return newChildren; } diff --git a/tests/index.spec.js b/tests/index.spec.js index 2924cb9..18377d1 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -334,4 +334,97 @@ describe('collapse', () => { }, 500); }); }); + + describe('wrapped in Fragment', () => { + let node; + let collapse; + + beforeEach((done) => { + node = document.createElement('div'); + document.body.appendChild(node); + const expandIcon = () => test>; + + ReactDOM.render( + + + first + second + third + + , node, function init() { + collapse = this; + done(); + }); + }); + + afterEach(() => { + ReactDOM.unmountComponentAtNode(node); + changeHook = null; + }); + + it('add className', () => { + const expectedClassName = 'rc-collapse-item important'; + expect(findDOMNode(collapse, 'rc-collapse-item')[2].className).to.be(expectedClassName); + }); + + it('create works', () => { + expect(findDOMNode(collapse, 'rc-collapse').length).to.be(1); + }); + + it('panel works', () => { + expect(findDOMNode(collapse, 'rc-collapse-item').length).to.be(3); + expect(findDOMNode(collapse, 'rc-collapse-content').length).to.be(0); + }); + + it('should render custom arrow icon corrctly', () => { + expect(findDOMNode(collapse, 'rc-collapse-header')[0].textContent.includes('test>')); + }); + + it('default active works', () => { + expect(findDOMNode(collapse, 'rc-collapse-item-active').length).to.be(0); + }); + + it('onChange works', (done) => { + changeHook = (d) => { + expect(d).to.eql(['2']); + done(); + }; + const header = findDOMNode(collapse, 'rc-collapse-header')[1]; + Simulate.click(header); + }); + + it('click should toggle panel state', (done) => { + const header = findDOMNode(collapse, 'rc-collapse-header')[1]; + Simulate.click(header); + setTimeout(() => { + expect(findDOMNode(collapse, 'rc-collapse-content-active').length).to.be(1); + Simulate.click(header); + setTimeout(() => { + expect(findDOMNode(collapse, 'rc-collapse-content-inactive')[0].innerHTML). + to.eql('
second
'); + expect(findDOMNode(collapse, 'rc-collapse-content-active').length).to.be(0); + done(); + }, 500); + }, 500); + }); + + it('click should not toggle disabled panel state', (done) => { + const header = findDOMNode(collapse, 'rc-collapse-header')[0]; + Simulate.click(header); + setTimeout(() => { + expect(findDOMNode(collapse, 'rc-collapse-content-active').length).to.be(0); + done(); + }, 500); + }); + + it('should not have role', () => { + const item = findDOMNode(collapse, 'rc-collapse')[0]; + expect(item.getAttribute('role')).to.eql(null); + }); + + it('should set button role on panel title', () => { + const item = findDOMNode(collapse, 'rc-collapse-header')[0]; + expect(item.getAttribute('role')).to.eql('button'); + }); + }); });