diff --git a/src/Accordion/Accordion.spec.tsx b/src/Accordion/Accordion.spec.tsx
index 00e95467..25c39c0a 100644
--- a/src/Accordion/Accordion.spec.tsx
+++ b/src/Accordion/Accordion.spec.tsx
@@ -62,13 +62,13 @@ describe('Accordion', () => {
).toEqual(1);
});
- it('collapses an expanded item when its title is clicked', () => {
- const wrapper = mountAccordion();
-
- const fooTitle = wrapper.find(FooTitle);
-
- fooTitle.simulate('click'); // open
- fooTitle.simulate('click'); // close
+ it('pre expanded accordion', () => {
+ const wrapper = mount(
+
+ Fake Child
+ Fake Child
+ ,
+ );
const instance = wrapper.find(Provider).instance() as Provider;
@@ -76,7 +76,46 @@ describe('Accordion', () => {
instance.state.items.filter(
(item: Item) => item.expanded === true,
).length,
- ).toEqual(0);
+ ).toEqual(1);
+ });
+
+ it('works with multiple pre expanded accordion. Extra expands are just ignored.', () => {
+ const hideBodyClassName = 'HIDE';
+ const wrapper = mount(
+
+
+ Fake Child
+
+
+ Fake Child
+
+ ,
+ );
+
+ const instance = wrapper.find(Provider).instance() as Provider;
+
+ expect(
+ instance.state.items.filter((item: Item) => item.expanded)
+ .length,
+ ).toEqual(1);
+ expect(
+ wrapper.findWhere((item: ReactWrapper) =>
+ item.hasClass(hideBodyClassName),
+ ).length,
+ ).toEqual(1);
+ });
+
+ it('respects arbitrary user-defined props', () => {
+ const wrapper = mount();
+ const div = wrapper.find('div').getDOMNode();
+
+ expect(div.getAttribute('lang')).toEqual('en');
});
});
@@ -128,10 +167,11 @@ describe('Accordion', () => {
).toEqual(2);
});
- it('collapses an expanded item when its title is clicked', () => {
+ it('collapses an expanded item when its title is clicked and there is more than one item expanded', () => {
const wrapper = mountMultipleExpanded();
wrapper.find(FooTitle).simulate('click'); // open
+ wrapper.find(BarTitle).simulate('click'); // open
wrapper.find(FooTitle).simulate('click'); // close
const instance = wrapper.find(Provider).instance() as Provider;
@@ -140,7 +180,7 @@ describe('Accordion', () => {
instance.state.items.filter(
(item: Item) => item.expanded === true,
).length,
- ).toEqual(0);
+ ).toEqual(1);
});
});
@@ -167,11 +207,11 @@ describe('Accordion', () => {
).toEqual(0);
});
- it('pre expanded accordion', () => {
+ it('pre expanded accordion when allowMultipleExpanded is true', () => {
const wrapper = mount(
-
+
+ Fake Child
Fake Child
- Fake Child
,
);
@@ -180,60 +220,66 @@ describe('Accordion', () => {
expect(
instance.state.items.filter((item: Item) => item.expanded === true)
.length,
- ).toEqual(1);
+ ).toEqual(2);
});
+});
- it('works with multiple pre expanded accordion. Extra expands are just ignored.', () => {
- const hideBodyClassName = 'HIDE';
- const wrapper = mount(
-
-
- Fake Child
-
-
- Fake Child
+describe('', () => {
+ const [FooTitle] = [
+ (): JSX.Element => Foo,
+ ];
+
+ function mountAccordion(): ReactWrapper {
+ return mount(
+
+
+
,
);
+ }
+
+ it("doesn't collapse an expanded item when it's the only item expanded", () => {
+ const wrapper = mountAccordion();
+
+ wrapper.find(FooTitle).simulate('click'); // open
+ wrapper.find(FooTitle).simulate('click'); // close
const instance = wrapper.find(Provider).instance() as Provider;
expect(
- instance.state.items.filter((item: Item) => item.expanded).length,
- ).toEqual(1);
- expect(
- wrapper.findWhere((item: ReactWrapper) =>
- item.hasClass(hideBodyClassName),
- ).length,
+ instance.state.items.filter((item: Item) => item.expanded === true)
+ .length,
).toEqual(1);
});
+});
- it('pre expanded accordion when allowMultipleExpanded is true', () => {
- const wrapper = mount(
-
- Fake Child
- Fake Child
+describe('', () => {
+ const [FooTitle] = [
+ (): JSX.Element => Foo,
+ ];
+
+ function mountZeroExpanded(): ReactWrapper {
+ return mount(
+
+
+
+
,
);
+ }
- const instance = wrapper.find(Provider).instance() as Provider;
+ it("collapses an expanded item when its title is clicked and it's the only item open", () => {
+ const wrapper = mountZeroExpanded();
- expect(
- instance.state.items.filter((item: Item) => item.expanded === true)
- .length,
- ).toEqual(2);
- });
+ wrapper.find(FooTitle).simulate('click'); // open
+ wrapper.find(FooTitle).simulate('click'); // close
- it('respects arbitrary user-defined props', () => {
- const wrapper = mount();
- const div = wrapper.find('div').getDOMNode();
+ const provider = wrapper.find(Provider).instance() as Provider;
- expect(div.getAttribute('lang')).toEqual('en');
+ expect(
+ provider.state.items.filter((item: Item) => item.expanded === true)
+ .length,
+ ).toEqual(0);
});
});
diff --git a/src/AccordionContainer/AccordionContainer.tsx b/src/AccordionContainer/AccordionContainer.tsx
index cdfa40ff..ac6cd418 100644
--- a/src/AccordionContainer/AccordionContainer.tsx
+++ b/src/AccordionContainer/AccordionContainer.tsx
@@ -102,22 +102,9 @@ export class Provider extends React.Component {
};
removeItem = (key: UUID): void => {
- this.setState((state: ProviderState) => {
- let items: Item[];
-
- if (
- !this.props.allowZeroExpanded &&
- state.items.filter((item: Item) => item.expanded).length < 2
- ) {
- items = state.items;
- } else {
- items = state.items.filter((item: Item) => item.uuid !== key);
- }
-
- return {
- items,
- };
- });
+ this.setState((state: ProviderState) => ({
+ items: state.items.filter((item: Item) => item.uuid !== key),
+ }));
};
setExpanded = (key: UUID, expanded: boolean): void => {
@@ -125,10 +112,22 @@ export class Provider extends React.Component {
(state: ProviderState) => ({
items: state.items.map((item: Item) => {
if (item.uuid === key) {
- return {
- ...item,
- expanded,
- };
+ if (
+ !expanded &&
+ !this.props.allowZeroExpanded &&
+ state.items.filter((item_: Item) => item_.expanded)
+ .length < 2
+ ) {
+ // If this is an accordion that doesn't allow all items to be closed and the current item is the only one open, don't allow it to close.
+ return {
+ ...item,
+ };
+ } else {
+ return {
+ ...item,
+ expanded,
+ };
+ }
}
if (!this.props.allowMultipleExpanded && expanded) {
// If this is an accordion that doesn't allow multiple expansions, we might need to collapse the other expanded item.
diff --git a/src/AccordionItem/AccordionItem.spec.tsx b/src/AccordionItem/AccordionItem.spec.tsx
index 8f113d1e..81d0576f 100644
--- a/src/AccordionItem/AccordionItem.spec.tsx
+++ b/src/AccordionItem/AccordionItem.spec.tsx
@@ -216,9 +216,9 @@ describe('AccordionItem', () => {
).toEqual(1);
});
- it('can dynamically unset expanded prop', () => {
+ it('can dynamically unset expanded prop when there is only one item expanded and allowZeroExpanded is set to true', () => {
const Wrapper = ({ expanded }: { expanded: boolean }): JSX.Element => (
-
+
Fake title
@@ -240,6 +240,35 @@ describe('AccordionItem', () => {
).toEqual(0);
});
+ it('can dynamically unset expanded prop when there is more than one item expanded', () => {
+ const Wrapper = ({ expanded }: { expanded: boolean }): JSX.Element => (
+
+
+
+ Fake title
+
+
+
+
+ Fake title
+
+
+
+ );
+
+ const wrapper = mount();
+ const instance = wrapper
+ .find(AccordionProvider)
+ .instance() as AccordionProvider;
+
+ wrapper.setProps({ expanded: undefined });
+
+ expect(
+ instance.state.items.filter((item: Item) => item.expanded === true)
+ .length,
+ ).toEqual(1);
+ });
+
it('dynamically changing arbitrary props does not affect expanded state', () => {
const Wrapper = ({ className }: { className: string }): JSX.Element => (
@@ -309,35 +338,6 @@ describe('AccordionItem', () => {
expect(instance.state.items.length).toEqual(0);
});
- it("doesn't unregister itself on unmount in an accordion that doesn't allow zero items to be expanded", () => {
- const Wrapper = ({
- showChild,
- }: {
- showChild: boolean;
- }): JSX.Element => (
-
- {showChild && (
-
-
- Fake title
-
-
- )}
-
- );
-
- const wrapper = mount();
- const instance = wrapper
- .find(AccordionProvider)
- .instance() as AccordionProvider;
-
- expect(instance.state.items.length).toEqual(1);
-
- wrapper.setProps({ showChild: false });
-
- expect(instance.state.items.length).toEqual(1);
- });
-
it('respects arbitrary user-defined props', () => {
const wrapper = mount(