Skip to content

Commit

Permalink
Merge pull request #170 from springload/fix/disabled-heading
Browse files Browse the repository at this point in the history
Fix/disabled heading
  • Loading branch information
catepalmer committed Jan 25, 2019
2 parents 0d95238 + 7eca008 commit cb2e723
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 9 deletions.
12 changes: 10 additions & 2 deletions integration/wai-aria.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,16 @@ describe('WAI ARIA Spec', () => {
}
});

it('If the accordion panel associated with an accordion header is visible, and if the accordion does not permit the panel to be collapsed, the header button element has aria-disabled set to true.', () => {
// todo
it('If the accordion panel associated with an accordion header is visible, and if the accordion does not permit the panel to be collapsed, the header button element has aria-disabled set to true.', async () => {
const [firstHeadingHandle] = await evaluateHeadings();
await firstHeadingHandle.click();

const headingAriaDisabled = await page.evaluate(
heading => heading.getAttribute('aria-disabled'),
firstHeadingHandle,
);

expect(headingAriaDisabled).toEqual('true');
});

it('Optionally, each element that serves as a container for panel content has role region and aria-labelledby with a value that refers to the button that controls display of the panel.', async () => {
Expand Down
1 change: 1 addition & 0 deletions src/AccordionContainer/AccordionContainer.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ describe('Accordion', () => {
addItem: expect.anything(),
removeItem: expect.anything(),
setExpanded: expect.anything(),
isItemDisabled: expect.anything(),
});
});

Expand Down
31 changes: 25 additions & 6 deletions src/AccordionContainer/AccordionContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type AccordionContainer = {
addItem(item: Item): void;
removeItem(uuid: UUID): void;
setExpanded(uuid: UUID, expanded: boolean): void;
isItemDisabled(uuid: UUID): boolean;
};

export type ConsumerProps = {
Expand Down Expand Up @@ -62,6 +63,7 @@ export class Provider extends React.Component<ProviderProps, ProviderState> {
addItem: this.addItem,
removeItem: this.removeItem,
setExpanded: this.setExpanded,
isItemDisabled: this.isItemDisabled,
};

return {
Expand Down Expand Up @@ -106,13 +108,30 @@ export class Provider extends React.Component<ProviderProps, ProviderState> {
}));
};

setExpanded = (key: UUID, expanded: boolean): void => {
if (
!expanded &&
/*
* From the spec:
*
* “If the accordion panel associated with an accordion header is visible,
* and if the accordion does not permit the panel to be collapsed, the
* header button element has aria-disabled set to true.”
*/
isItemDisabled = (key: UUID): boolean => {
const item = this.state.items.find(
({ uuid }: Item): boolean => uuid === key,
);
const expandedItems = this.state.items.filter(
({ expanded }: Item) => expanded,
);

return (
item.expanded &&
!this.props.allowZeroExpanded &&
this.state.items.filter((item: Item) => item.expanded).length === 1
) {
// 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.
expandedItems.length === 1
);
};

setExpanded = (key: UUID, expanded: boolean): void => {
if (this.isItemDisabled(key)) {
return;
}
this.setState(
Expand Down
6 changes: 6 additions & 0 deletions src/AccordionItem/__snapshots__/AccordionItem.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exports[`AccordionItem renders correctly with allowMultipleExpanded false 1`] =
>
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down Expand Up @@ -38,6 +39,7 @@ exports[`AccordionItem renders correctly with allowMultipleExpanded true 1`] = `
>
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down Expand Up @@ -70,6 +72,7 @@ exports[`AccordionItem renders correctly with allowZeroExpanded false 1`] = `
>
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down Expand Up @@ -102,6 +105,7 @@ exports[`AccordionItem renders correctly with allowZeroExpanded true 1`] = `
>
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down Expand Up @@ -134,6 +138,7 @@ exports[`AccordionItem renders correctly with other blocks inside 1`] = `
>
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down Expand Up @@ -169,6 +174,7 @@ exports[`AccordionItem renders correctly with other blocks inside 2 1`] = `
>
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down
3 changes: 3 additions & 0 deletions src/AccordionItemHeading/AccordionItemHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type AccordionItemHeadingProps = React.HTMLAttributes<HTMLDivElement> & {
hideBodyClassName: string;
expanded: boolean;
uuid: UUID;
disabled: boolean;
setExpanded(uuid: UUID, expanded: boolean): void;
};

Expand Down Expand Up @@ -35,6 +36,7 @@ export default class AccordionItemHeading extends React.Component<
setExpanded,
expanded,
uuid,
disabled,
...rest
} = this.props;

Expand All @@ -50,6 +52,7 @@ export default class AccordionItemHeading extends React.Component<
aria-expanded={expanded}
aria-controls={ariaControls}
className={headingClassName}
aria-disabled={disabled}
onClick={this.handleClick}
role="button"
tabIndex={0}
Expand Down
4 changes: 3 additions & 1 deletion src/AccordionItemHeading/AccordionItemHeading.wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,17 @@ export default class AccordionItemHeadingWrapper extends React.Component<
}

const { uuid } = itemStore;
const { items } = accordionStore;
const { items, allowZeroExpanded, isItemDisabled } = accordionStore;
const item = items.filter(
(stateItem: Item) => stateItem.uuid === uuid,
)[0];
const disabled = isItemDisabled(uuid);

return (
<AccordionItemHeading
{...this.props}
{...item}
disabled={disabled}
setExpanded={accordionStore.setExpanded}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`AccordionItemHeading renders correctly with min params 1`] = `
<div
aria-controls="accordion__panel-0"
aria-disabled={false}
aria-expanded={false}
className="accordion__heading"
id="accordion__heading-0"
Expand Down

0 comments on commit cb2e723

Please sign in to comment.