Skip to content

Commit 9edce6c

Browse files
Merge pull request #55 from springload/feature/respect-arbitrary-props
Feature/respect arbitrary props
2 parents 28c23dc + 4ca313c commit 9edce6c

File tree

9 files changed

+77
-44
lines changed

9 files changed

+77
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,10 @@
1111

1212
### Changed
1313

14+
* Update all React components to accept arbitrary HTMLDivElement props (eg. 'lang', 'role' etc).
1415
* Upgrade all dev-dependencies except the eslint configs.
1516
* Replace snapshot tests with explicit assertions in AccordionItemBody and AccordionItemTitle.
1617
* Add specific assertions to tests in accordionStore.
17-
18-
## [[v2.0.1]](https://github.com/springload/react-accessible-accordion/releases/tag/v2.0.1)
19-
20-
### Changed
21-
2218
* Minor syntax change in AccordionItemBody
2319

2420
## [[v2.0.0]](https://github.com/springload/react-accessible-accordion/releases/tag/v2.0.0)

src/Accordion/accordion.js

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
// @flow
22

3-
import React, { Component, type Node } from 'react';
3+
import React, { Component, type ElementProps } from 'react';
44
import { Provider } from 'mobx-react';
55
import { createAccordionStore } from '../accordionStore/accordionStore';
66

7-
type AccordionProps = {
7+
type AccordionProps = ElementProps<'div'> & {
88
accordion: boolean,
9-
children: Node,
10-
className: string,
119
onChange: Function,
1210
};
1311

@@ -25,14 +23,12 @@ class Accordion extends Component<AccordionProps, *> {
2523
});
2624

2725
render() {
28-
const { className, children } = this.props;
26+
const { accordion: accordionProp, onChange, ...rest } = this.props;
2927
const { accordion } = this.accordionStore;
3028

3129
return (
3230
<Provider accordionStore={this.accordionStore}>
33-
<div role={accordion ? 'tablist' : null} className={className}>
34-
{children}
35-
</div>
31+
<div role={accordion ? 'tablist' : null} {...rest} />
3632
</Provider>
3733
);
3834
}

src/Accordion/accordion.spec.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,10 @@ describe('Accordion', () => {
206206
.length,
207207
).toEqual(2);
208208
});
209+
210+
it('respects arbitrary user-defined props', () => {
211+
const wrapper = mount(<Accordion lang="en" />);
212+
213+
expect(wrapper.find('div').instance().lang).toEqual('en');
214+
});
209215
});

src/AccordionItem/accordion-item.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22

33
import React, { Component } from 'react';
4-
import type { Node } from 'react';
4+
import type { ElementProps } from 'react';
55
import { inject, observer, Provider } from 'mobx-react';
66
import consecutive from 'consecutive';
77
import classNames from 'classnames';
@@ -12,9 +12,7 @@ export function resetNextUuid() {
1212
nextUuid = consecutive();
1313
}
1414

15-
type AccordionItemProps = {
16-
children: Node,
17-
className: string,
15+
type AccordionItemProps = ElementProps<'div'> & {
1816
hideBodyClassName: string,
1917
accordionStore: Store,
2018
disabled: boolean,
@@ -59,8 +57,10 @@ class AccordionItem extends Component<AccordionItemProps, *> {
5957
const {
6058
className,
6159
hideBodyClassName,
62-
children,
6360
accordionStore,
61+
disabled,
62+
expanded: expandedProp,
63+
...rest
6464
} = this.props;
6565

6666
const currentItem = accordionStore.items.find(
@@ -78,9 +78,8 @@ class AccordionItem extends Component<AccordionItemProps, *> {
7878
className={classNames(className, {
7979
[hideBodyClassName]: !expanded && hideBodyClassName,
8080
})}
81-
>
82-
{children}
83-
</div>
81+
{...rest}
82+
/>
8483
</Provider>
8584
);
8685
}

src/AccordionItem/accordion-item.spec.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ describe('AccordionItem', () => {
131131
const tree = renderer
132132
.create(
133133
<Provider accordionStore={accordionStore}>
134-
<AccordionItem accordion={false}>
134+
<AccordionItem>
135135
<AccordionItemTitle>
136136
<div>Fake title</div>
137137
</AccordionItemTitle>
@@ -150,7 +150,7 @@ describe('AccordionItem', () => {
150150
const tree = renderer
151151
.create(
152152
<Provider accordionStore={accordionStore}>
153-
<AccordionItem accordion={false}>
153+
<AccordionItem>
154154
<AccordionItemTitle>
155155
<div>Fake title</div>
156156
</AccordionItemTitle>
@@ -301,4 +301,14 @@ describe('AccordionItem', () => {
301301

302302
expect(accordionStore.items.length).toEqual(0);
303303
});
304+
305+
it('respects arbitrary user-defined props', () => {
306+
const wrapper = mount(
307+
<Provider accordionStore={accordionStore}>
308+
<AccordionItem lang="en" />
309+
</Provider>,
310+
);
311+
312+
expect(wrapper.find('div').instance().lang).toEqual('en');
313+
});
304314
});

src/AccordionItemBody/accordion-item-body.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// @flow
22

3-
import React from 'react';
4-
import type { Node } from 'react';
3+
import React, { type ElementProps } from 'react';
54
import classNames from 'classnames';
65
import { inject, observer } from 'mobx-react';
76
import { type Store } from '../accordionStore/accordionStore';
@@ -11,16 +10,20 @@ const defaultProps = {
1110
hideBodyClassName: 'accordion__body--hidden',
1211
};
1312

14-
type AccordionItemBodyProps = {
15-
children: Node,
16-
className: string,
13+
type AccordionItemBodyProps = ElementProps<'div'> & {
1714
hideBodyClassName: string,
1815
accordionStore: Store,
1916
uuid: string | number,
2017
};
2118

2219
const AccordionItemBody = (props: AccordionItemBodyProps) => {
23-
const { uuid, children, className, hideBodyClassName } = props;
20+
const {
21+
accordionStore,
22+
uuid,
23+
className,
24+
hideBodyClassName,
25+
...rest
26+
} = props;
2427
const { items, accordion } = props.accordionStore;
2528
const foundItem = items.find(item => item.uuid === uuid);
2629
if (!foundItem) return null;
@@ -41,9 +44,8 @@ const AccordionItemBody = (props: AccordionItemBodyProps) => {
4144
aria-hidden={ariaHidden}
4245
aria-labelledby={ariaLabelledby}
4346
role={role}
44-
>
45-
{children}
46-
</div>
47+
{...rest}
48+
/>
4749
);
4850
};
4951

src/AccordionItemBody/accordion-item-body.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,13 @@ describe('AccordionItemBody', () => {
7070
wrapper.findWhere(item => item.className === className).length,
7171
).toEqual(0);
7272
});
73+
74+
it('respects arbitrary user-defined props', () => {
75+
const wrapper = mount(
76+
<Provider accordionStore={accordionStore} uuid={uuid}>
77+
<AccordionItemBody lang="en" />
78+
</Provider>,
79+
);
80+
expect(wrapper.find('div').instance().lang).toEqual('en');
81+
});
7382
});

src/AccordionItemTitle/accordion-item-title.js

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
// @flow
22

3-
import React, { Component } from 'react';
4-
import type { Node } from 'react';
3+
import React, { Component, type ElementProps } from 'react';
54
import classNames from 'classnames';
65
import { inject, observer } from 'mobx-react';
76
import { type Store } from '../accordionStore/accordionStore';
87

9-
type AccordionItemTitleProps = {
10-
children: Node,
11-
className: string,
8+
type AccordionItemTitleProps = ElementProps<'div'> & {
129
hideBodyClassName: string,
1310
accordionStore: Store,
1411
uuid: string | number,
@@ -57,7 +54,13 @@ class AccordionItemTitle extends Component<
5754

5855
render() {
5956
const { items, accordion } = this.props.accordionStore;
60-
const { uuid, children, className, hideBodyClassName } = this.props;
57+
const {
58+
uuid,
59+
className,
60+
hideBodyClassName,
61+
accordionStore,
62+
...rest
63+
} = this.props;
6164
const foundItem = items.find(item => item.uuid === uuid);
6265
if (!foundItem) return null;
6366

@@ -82,9 +85,8 @@ class AccordionItemTitle extends Component<
8285
tabIndex="0" // eslint-disable-line jsx-a11y/no-noninteractive-tabindex
8386
onKeyPress={this.handleKeyPress}
8487
disabled={disabled}
85-
>
86-
{children}
87-
</div>
88+
{...rest}
89+
/>
8890
);
8991
}
9092
return (
@@ -98,9 +100,8 @@ class AccordionItemTitle extends Component<
98100
tabIndex="0" // eslint-disable-line jsx-a11y/no-noninteractive-tabindex
99101
onKeyPress={this.handleKeyPress}
100102
disabled={disabled}
101-
>
102-
{children}
103-
</div>
103+
{...rest}
104+
/>
104105
);
105106
}
106107
}

src/AccordionItemTitle/accordion-item-title.spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,18 @@ describe('AccordionItemTitle', () => {
149149
wrapper.findWhere(item => item.className === className).length,
150150
).toEqual(0);
151151
});
152+
153+
it('respects arbitrary user-defined props', () => {
154+
const wrapper = mount(
155+
<AccordionItemTitle
156+
accordionStore={accordionStore}
157+
uuid="item-one-uuid"
158+
lang="en"
159+
>
160+
Fake Title
161+
</AccordionItemTitle>,
162+
);
163+
164+
expect(wrapper.find('div').instance().lang).toEqual('en');
165+
});
152166
});

0 commit comments

Comments
 (0)