diff --git a/examples/simple.js b/examples/simple.js index afb8f81..6055b96 100644 --- a/examples/simple.js +++ b/examples/simple.js @@ -15,21 +15,13 @@ function random() { } class Test extends React.Component { - constructor(props) { - super(props); - this.state = this.getInitialState(); - ['onChange', 'setActivityKey', 'reRender', 'toggle'].map(fn => this[fn] = this[fn].bind(this)); + state = { + time: random(), + accordion: false, + activeKey: ['4'], } - getInitialState() { - return { - time: random(), - accordion: false, - activeKey: ['4'], - }; - } - - onChange(activeKey) { + onChange = (activeKey) => { this.setState({ activeKey, }); @@ -40,7 +32,7 @@ class Test extends React.Component { for (let i = 0, len = 3; i < len; i++) { const key = i + 1; items.push( - +

{text.repeat(this.state.time)}

); @@ -55,22 +47,35 @@ class Test extends React.Component {
); + items.push( + + + +
+ + +
+
+
+
+ ); + return items; } - setActivityKey() { + setActivityKey = () => { this.setState({ activeKey: ['2'], }); } - reRender() { + reRender = () => { this.setState({ time: random(), }); } - toggle() { + toggle = () => { this.setState({ accordion: !this.state.accordion, }); @@ -78,7 +83,7 @@ class Test extends React.Component { render() { const accordion = this.state.accordion; - const btn = accordion ? 'accordion' : 'collapse'; + const btn = accordion ? 'Mode: accordion' : 'Mode: collapse'; const activeKey = this.state.activeKey; return (
diff --git a/src/Collapse.jsx b/src/Collapse.jsx index 808cac4..85b80d2 100644 --- a/src/Collapse.jsx +++ b/src/Collapse.jsx @@ -84,6 +84,7 @@ class Collapse extends Component { prefixCls, destroyInactivePanel, openAnimation: this.state.openAnimation, + accordion, children: child.props.children, onItemClick: disabled ? null : () => this.onClickItem(key), }; @@ -102,13 +103,13 @@ class Collapse extends Component { } render() { - const { prefixCls, className, style } = this.props; + const { prefixCls, className, style, accordion } = this.props; const collapseClassName = classNames({ [prefixCls]: true, [className]: !!className, }); return ( -
+
{this.getItems()}
); diff --git a/src/Panel.jsx b/src/Panel.jsx index 185f33a..78c17ba 100644 --- a/src/Panel.jsx +++ b/src/Panel.jsx @@ -5,12 +5,19 @@ import PanelContent from './PanelContent'; import Animate from 'rc-animate'; class CollapsePanel extends Component { - handleItemClick() { + handleItemClick = () => { if (this.props.onItemClick) { this.props.onItemClick(); } } + handleKeyPress = (e) => { + e.preventDefault(); + if (e.charCode === 13 || e.charCode === 32) { + this.handleItemClick(); + } + } + render() { const { className, @@ -24,6 +31,7 @@ class CollapsePanel extends Component { showArrow, destroyInactivePanel, disabled, + accordion, forceRender, } = this.props; const headerCls = classNames(`${prefixCls}-header`, { @@ -35,12 +43,14 @@ class CollapsePanel extends Component { [`${prefixCls}-item-disabled`]: disabled, }, className); return ( -
+
{showArrow && } {header} @@ -56,6 +66,7 @@ class CollapsePanel extends Component { isActive={isActive} destroyInactivePanel={destroyInactivePanel} forceRender={forceRender} + role={accordion ? 'tabpanel' : null} > {children} @@ -86,6 +97,7 @@ CollapsePanel.propTypes = { style: PropTypes.object, destroyInactivePanel: PropTypes.bool, disabled: PropTypes.bool, + accordion: PropTypes.bool, forceRender: PropTypes.bool, }; diff --git a/src/PanelContent.jsx b/src/PanelContent.jsx index 9151c0d..0db70f7 100644 --- a/src/PanelContent.jsx +++ b/src/PanelContent.jsx @@ -12,7 +12,7 @@ class PanelContent extends Component { if (!this._isActived) { return null; } - const { prefixCls, isActive, children, destroyInactivePanel, forceRender } = this.props; + const { prefixCls, isActive, children, destroyInactivePanel, forceRender, role } = this.props; const contentCls = classnames({ [`${prefixCls}-content`]: true, [`${prefixCls}-content-active`]: isActive, @@ -23,7 +23,7 @@ class PanelContent extends Component { return (
{child}
); } @@ -35,6 +35,7 @@ PanelContent.propTypes = { children: PropTypes.any, destroyInactivePanel: PropTypes.bool, forceRender: PropTypes.bool, + role: PropTypes.string, }; export default PanelContent; diff --git a/tests/index.spec.js b/tests/index.spec.js index b716082..ca63e36 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -91,6 +91,16 @@ describe('collapse', () => { 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'); + }); }); describe('destroyInactivePanel', () => { @@ -195,6 +205,26 @@ describe('collapse', () => { }, 500); }, 500); }); + + it('should add tab role on panel title', () => { + const item = findDOMNode(collapse, 'rc-collapse-header')[0]; + expect(item.getAttribute('role')).to.eql('tab'); + }); + + it('should add tablist role on accordion', () => { + const item = findDOMNode(collapse, 'rc-collapse')[0]; + expect(item.getAttribute('role')).to.eql('tablist'); + }); + + it('should add tablist role on PanelContent', (done) => { + const header = findDOMNode(collapse, 'rc-collapse-header')[0]; + Simulate.click(header); + setTimeout(() => { + const item = findDOMNode(collapse, 'rc-collapse-content')[0]; + expect(item.getAttribute('role')).to.eql('tabpanel'); + done(); + }, 500); + }); }); describe('forceRender', () => {