Skip to content

Commit

Permalink
Make requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
catepalmer committed Jan 21, 2019
1 parent 9dd08b6 commit 891f975
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 101 deletions.
146 changes: 96 additions & 50 deletions src/Accordion/Accordion.spec.tsx
Expand Up @@ -62,21 +62,60 @@ 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(
<Accordion>
<AccordionItem expanded={true}>Fake Child</AccordionItem>
<AccordionItem>Fake Child</AccordionItem>
</Accordion>,
);

const instance = wrapper.find(Provider).instance() as Provider;

expect(
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(
<Accordion allowMultipleExpanded={false}>
<AccordionItem
expanded={true}
hideBodyClassName={hideBodyClassName}
>
Fake Child
</AccordionItem>
<AccordionItem
expanded={true}
hideBodyClassName={hideBodyClassName}
>
Fake Child
</AccordionItem>
</Accordion>,
);

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(<Accordion lang="en" />);
const div = wrapper.find('div').getDOMNode();

expect(div.getAttribute('lang')).toEqual('en');
});
});

Expand Down Expand Up @@ -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;
Expand All @@ -140,7 +180,7 @@ describe('Accordion', () => {
instance.state.items.filter(
(item: Item) => item.expanded === true,
).length,
).toEqual(0);
).toEqual(1);
});
});

Expand All @@ -167,11 +207,11 @@ describe('Accordion', () => {
).toEqual(0);
});

it('pre expanded accordion', () => {
it('pre expanded accordion when allowMultipleExpanded is true', () => {
const wrapper = mount(
<Accordion>
<Accordion allowMultipleExpanded={true}>
<AccordionItem expanded={true}>Fake Child</AccordionItem>
<AccordionItem expanded={true}>Fake Child</AccordionItem>
<AccordionItem>Fake Child</AccordionItem>
</Accordion>,
);

Expand All @@ -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(
<Accordion allowMultipleExpanded={false}>
<AccordionItem
expanded={true}
hideBodyClassName={hideBodyClassName}
>
Fake Child
</AccordionItem>
<AccordionItem
expanded={true}
hideBodyClassName={hideBodyClassName}
>
Fake Child
describe('<Accordion allowZeroExpanded="false" />', () => {
const [FooTitle] = [
(): JSX.Element => <AccordionItemHeading>Foo</AccordionItemHeading>,
];

function mountAccordion(): ReactWrapper {
return mount(
<Accordion>
<AccordionItem>
<FooTitle />
</AccordionItem>
</Accordion>,
);
}

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(
<Accordion allowMultipleExpanded={true}>
<AccordionItem expanded={true}>Fake Child</AccordionItem>
<AccordionItem expanded={true}>Fake Child</AccordionItem>
describe('<Accordion allowZeroExpanded="true" />', () => {
const [FooTitle] = [
(): JSX.Element => <AccordionItemHeading>Foo</AccordionItemHeading>,
];

function mountZeroExpanded(): ReactWrapper {
return mount(
<Accordion allowZeroExpanded={true}>
<AccordionItem>
<FooTitle />
</AccordionItem>
</Accordion>,
);
}

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(<Accordion lang="en" />);
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);
});
});
39 changes: 19 additions & 20 deletions src/AccordionContainer/AccordionContainer.tsx
Expand Up @@ -102,33 +102,32 @@ export class Provider extends React.Component<ProviderProps, ProviderState> {
};

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 => {
this.setState(
(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.
Expand Down
62 changes: 31 additions & 31 deletions src/AccordionItem/AccordionItem.spec.tsx
Expand Up @@ -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 => (
<AccordionProvider>
<AccordionProvider allowZeroExpanded={true}>
<AccordionItem expanded={expanded}>
<AccordionItemHeading>
<div>Fake title</div>
Expand All @@ -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 => (
<AccordionProvider>
<AccordionItem expanded={expanded}>
<AccordionItemHeading>
<div>Fake title</div>
</AccordionItemHeading>
</AccordionItem>
<AccordionItem expanded={true}>
<AccordionItemHeading>
<div>Fake title</div>
</AccordionItemHeading>
</AccordionItem>
</AccordionProvider>
);

const wrapper = mount(<Wrapper expanded={true} />);
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 => (
<AccordionProvider>
Expand Down Expand Up @@ -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 => (
<AccordionProvider>
{showChild && (
<AccordionItem>
<AccordionItemHeading>
<div>Fake title</div>
</AccordionItemHeading>
</AccordionItem>
)}
</AccordionProvider>
);

const wrapper = mount(<Wrapper showChild={true} />);
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(
<AccordionProvider>
Expand Down

0 comments on commit 891f975

Please sign in to comment.