Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

feat(accordion): use appropriate aria tags for accessibility #5338

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/accordion/accordion.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
}
}
};

var id = 'accordiongroup-' + scope.$id + '-' + Math.floor(Math.random() * 10000);
scope.headingId = id + '-tab';
scope.panelId = id + '-panel';
}
};
})
Expand Down
26 changes: 26 additions & 0 deletions src/accordion/test/accordion.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ describe('uib-accordion', function() {
$templateCache = _$templateCache_;
}));

it('should be a tablist', function() {
element = $compile('<uib-accordion></uib-accordion>')(scope);
scope.$digest();
expect(element.html()).toContain('role="tablist"');
});

it('should expose the controller on the view', function() {
$templateCache.put('uib/template/accordion/accordion.html', '<div>{{accordion.text}}</div>');

Expand Down Expand Up @@ -150,6 +156,9 @@ describe('uib-accordion', function() {
describe('uib-accordion-group', function() {
var scope, $compile;
var element, groups;
var findGroupHeading = function(index) {
return groups.eq(index).find('.panel-heading').eq(0);
};
var findGroupLink = function(index) {
return groups.eq(index).find('.accordion-toggle').eq(0);
};
Expand Down Expand Up @@ -177,6 +186,7 @@ describe('uib-accordion', function() {

describe('with static panels', function() {
beforeEach(function() {
spyOn(Math, 'random').and.returnValue(0.1);
var tpl =
'<uib-accordion>' +
'<uib-accordion-group heading="title 1">Content 1</uib-accordion-group>' +
Expand Down Expand Up @@ -204,20 +214,26 @@ describe('uib-accordion', function() {
findGroupLink(0).click();
scope.$digest();
expect(findGroupBody(0).scope().isOpen).toBe(true);
expect(findGroupHeading(0).html()).toContain('aria-expanded="true"');

findGroupLink(1).click();
scope.$digest();
expect(findGroupBody(0).scope().isOpen).toBe(false);
expect(findGroupHeading(0).html()).toContain('aria-expanded="false"');
expect(findGroupBody(1).scope().isOpen).toBe(true);
expect(findGroupHeading(1).html()).toContain('aria-expanded="true"');
});

it('should toggle element on click', function() {
findGroupLink(0).click();
scope.$digest();
expect(findGroupBody(0).scope().isOpen).toBe(true);
expect(groups.eq(0).html()).toContain('aria-hidden="false"');

findGroupLink(0).click();
scope.$digest();
expect(findGroupBody(0).scope().isOpen).toBe(false);
expect(groups.eq(0).html()).toContain('aria-hidden="true"');
});

it('should add, by default, "panel-open" when opened', function() {
Expand Down Expand Up @@ -256,6 +272,16 @@ describe('uib-accordion', function() {

expect(group).not.toHaveClass('panel-open');
});

it('should generate an Id for the heading', function() {
var groupScope = findGroupBody(0).scope();
expect(groupScope.headingId).toEqual('accordiongroup-' + groupScope.$id + '-1000-tab');
});

it('should generate an Id for the panel', function() {
var groupScope = findGroupBody(0).scope();
expect(groupScope.panelId).toEqual('accordiongroup-' + groupScope.$id + '-1000-panel');
});
});

describe('with open-class attribute', function() {
Expand Down
8 changes: 4 additions & 4 deletions template/accordion/accordion-group.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div class="panel" ng-class="panelClass || 'panel-default'">
<div class="panel-heading" ng-keypress="toggleOpen($event)">
<div role="tab" id="{{::headingId}}" aria-selected="{{isOpen}}" class="panel-heading" ng-keypress="toggleOpen($event)">
<h4 class="panel-title">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
<a role="button" data-toggle="collapse" href aria-expanded="{{isOpen}}" aria-controls="{{::panelId}}" tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading"><span ng-class="{'text-muted': isDisabled}">{{heading}}</span></a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" ng-transclude></div>
<div id="{{::panelId}}" aria-labelledby="{{::headingId}}" aria-hidden="{{!isOpen}}" role="tabpanel" class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" ng-transclude></div>
</div>
</div>
2 changes: 1 addition & 1 deletion template/accordion/accordion.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<div class="panel-group" ng-transclude></div>
<div role="tablist" class="panel-group" ng-transclude></div>