Skip to content

Commit 377485a

Browse files
committed
feat(core): Basic screen reader accessibility functionality
- Adds aria roles to the grid to allow screen readers to understand what text to read out. - Adds screen reader only css element - Allows you to make a dom element have content exclusively for a screen reader. - Adds an accessibility demo to help with testing
1 parent 94e50a5 commit 377485a

9 files changed

+132
-18
lines changed

misc/demo/grid-accessiblility.html

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<!DOCTYPE html>
2+
<html class="no-js" ng-app="test"><!--<![endif]-->
3+
<head>
4+
<meta charset="utf-8">
5+
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
6+
<title></title>
7+
<meta content="width=device-width" name="viewport">
8+
9+
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" />
10+
<link href="/dist/release/ui-grid.css" rel="stylesheet">
11+
12+
<!--<script src="https://code.jquery.com/jquery-1.11.1.js"></script>-->
13+
<script src="/lib/test/angular/1.3.16/angular.js"></script>
14+
<script src="https://code.angularjs.org/1.3.16/angular-aria.js"></script>
15+
<script src="/dist/release/ui-grid.js"></script>
16+
17+
<style>
18+
body {
19+
padding: 60px;
20+
min-height: 600px;
21+
}
22+
.grid {
23+
width: 1200px;
24+
height: 400px;
25+
}
26+
.placeholder {
27+
height: 50%;
28+
width: 50%;
29+
border: 3px solid black;
30+
background: #ccc;
31+
}
32+
</style>
33+
</head>
34+
<body ng-controller="Main">
35+
<!-- <h1>Test</h1> -->
36+
37+
<!-- <div class="row main"> -->
38+
<h2>Grid</h2>
39+
<div ui-grid="gridOptions" class="grid" ui-grid-resize-columns ui-grid-cellNav ui-grid-pagination></div>
40+
<!-- <div class="placeholder"> -->
41+
<!-- </div> -->
42+
43+
<br>
44+
<br>
45+
46+
<script>
47+
var app = angular.module('test', ['ui.grid', 'ui.grid.pinning', 'ui.grid.resizeColumns', 'ui.grid.cellNav', 'ui.grid.pagination', 'ngAria']);
48+
app.controller('Main', function($scope, $http) {
49+
$scope.gridOptions = {
50+
enableSorting: true,
51+
showGridFooter: true,
52+
enableGridMenu: true,
53+
enableFiltering: true,
54+
paginationPageSizes: [25, 50, 75, 100],
55+
paginationPageSize: 25,
56+
useExternalPagination: false,
57+
useExternalSorting: false,
58+
};
59+
$scope.gridOptions.columnDefs = [
60+
{ name:'id', width:50 },
61+
{ name:'name', width:100, pinnedLeft:true },
62+
{ name:'age', width:100, pinnedRight:true },
63+
{ name:'address.street', width:150 },
64+
{ name:'address.city', width:150 },
65+
{ name:'address.state', width:50 },
66+
{ name:'address.zip', width:50 },
67+
{ name:'company', width:100 },
68+
{ name:'email', width:100 },
69+
{ name:'phone', width:200 },
70+
{ name:'about', width:300 },
71+
{ name:'friends[0].name', displayName:'1st friend', width:150 },
72+
{ name:'friends[1].name', displayName:'2nd friend', width:150 },
73+
{ name:'friends[2].name', displayName:'3rd friend', width:150 }
74+
];
75+
76+
$http.get('https://rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
77+
.success(function(data) {
78+
$scope.gridOptions.data = data;
79+
});
80+
});
81+
</script>
82+
</body>
83+
</html>

src/less/grid.less

+15
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,18 @@
6363
height: 100%;
6464
width: 100%;
6565
}
66+
67+
// Only display content to screen readers
68+
//
69+
// See: http://a11yproject.com/posts/how-to-hide-content/
70+
71+
.ui-grid-sr-only {
72+
position: absolute;
73+
width: 1px;
74+
height: 1px;
75+
margin: -1px;
76+
padding: 0;
77+
overflow: hidden;
78+
clip: rect(0,0,0,0);
79+
border: 0;
80+
}

src/less/variables.less

+6
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@
6969
@invalidValueBorder: 1px solid rgb(252, 143, 143);
7070
@validValueBorder: 1px solid @borderColor;
7171

72+
//Pagination controls
73+
@paginationButtonColor: @headerGradientStart;
74+
@paginationButtonBackgroundColor: @headerBackgroundColor;
75+
@paginationButtonBorderColor: #ccc;
76+
77+
7278
/**
7379
* @section font library path
7480
*/

src/templates/ui-grid/ui-grid-footer.html

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<div class="ui-grid-footer-panel ui-grid-footer-aggregates-row">
1+
<div class="ui-grid-footer-panel ui-grid-footer-aggregates-row"> <!-- tfooter -->
22
<div class="ui-grid-footer ui-grid-footer-viewport">
33
<div class="ui-grid-footer-canvas">
44
<div class="ui-grid-footer-cell-wrapper" ng-style="colContainer.headerCellWrapperStyle()">
5-
<div class="ui-grid-footer-cell-row">
6-
<div ng-repeat="col in colContainer.renderedColumns track by col.uid" ui-grid-footer-cell col="col" render-index="$index" class="ui-grid-footer-cell ui-grid-clearfix"></div>
5+
<div role="row" class="ui-grid-footer-cell-row">
6+
<div role="gridcell" ng-repeat="col in colContainer.renderedColumns track by col.uid" ui-grid-footer-cell col="col" render-index="$index" class="ui-grid-footer-cell ui-grid-clearfix"></div>
77
</div>
88
</div>
99
</div>
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
<div class="ui-grid-header">
1+
<div role="rowgroup" class="ui-grid-header"> <!-- theader -->
22
<div class="ui-grid-top-panel">
33
<div class="ui-grid-header-viewport">
44
<div class="ui-grid-header-canvas">
55
<div class="ui-grid-header-cell-wrapper" ng-style="colContainer.headerCellWrapperStyle()">
6-
<div class="ui-grid-header-cell-row">
6+
<div role="row" class="ui-grid-header-cell-row">
77
<div class="ui-grid-header-cell ui-grid-clearfix" ng-repeat="col in colContainer.renderedColumns track by col.uid" ui-grid-header-cell col="col" render-index="$index"></div>
88
</div>
99
</div>
1010
</div>
11-
1211
</div>
1312
</div>
1413
</div>
+7-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid" class="ui-grid-cell" ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }" ui-grid-cell></div>
1+
<div
2+
ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid"
3+
ui-grid-one-bind-id-grid="rowRenderIndex + '-' + col.uid + '-cell'"
4+
class="ui-grid-cell"
5+
ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"
6+
role="{{col.isRowHeader ? 'rowheader' : 'gridcell'}}"
7+
ui-grid-cell></div>

src/templates/ui-grid/uiGridHeaderCell.html

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
<div ng-class="{ 'sortable': sortable }">
1+
<div role="columnheader" ng-class="{ 'sortable': sortable }" aria-labelledby="{{grid.id}}-{{col.name}}-header-text {{grid.id}}-{{col.name}}-sortdir-text" aria-sort="{{col.sort.direction == asc ? 'ascending' : ( col.sort.direction == desc ? 'descending' : (!col.sort.direction ? 'none' : 'other'))}}">
22
<!-- <div class="ui-grid-vertical-bar">&nbsp;</div> -->
3-
<div class="ui-grid-cell-contents" col-index="renderIndex" title="TOOLTIP">
4-
<span>{{ col.displayName CUSTOM_FILTERS }}</span>
3+
<div role="button" tabindex=0 class="ui-grid-cell-contents" col-index="renderIndex" title="TOOLTIP">
4+
<span id="{{grid.id}}-{{col.name}}-header-text">{{ col.displayName CUSTOM_FILTERS }}</span>
55

6-
<span ui-grid-visible="col.sort.direction" ng-class="{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }">
7-
&nbsp;
8-
</span>
6+
<span id="{{grid.id}}-{{col.name}}-sortdir-text" ui-grid-visible="col.sort.direction" aria-label="Sort direction {{col.sort.direction == asc ? 'ascending' : ( col.sort.direction == desc ? 'descending':'none')}}" ng-class="{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }">&nbsp;</span>
97
</div>
108

11-
<div class="ui-grid-column-menu-button" ng-if="grid.options.enableColumnMenus && !col.isRowHeader && col.colDef.enableColumnMenu !== false" ng-click="toggleMenu($event)" ng-class="{'ui-grid-column-menu-button-last-col': isLastCol}">
12-
<i class="ui-grid-icon-angle-down">&nbsp;</i>
9+
<div role="button" class="ui-grid-column-menu-button" ng-if="grid.options.enableColumnMenus && !col.isRowHeader && col.colDef.enableColumnMenu !== false" ng-click="toggleMenu($event)" ng-class="{'ui-grid-column-menu-button-last-col': isLastCol}" aria-label="{{col.displayName}} menu" aria-haspopup="true">
10+
<i class="ui-grid-icon-angle-down" aria-hidden="true">&nbsp;</i>
1311
</div>
1412

1513
<div ui-grid-filter></div>

src/templates/ui-grid/uiGridRenderContainer.html

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
<div class="ui-grid-render-container" ng-style="{ 'margin-left': colContainer.getMargin('left') + 'px', 'margin-right': colContainer.getMargin('right') + 'px' }">
1+
<div
2+
role="grid"
3+
ui-grid-one-bind-id-grid="'grid-container'"
4+
class="ui-grid-render-container"
5+
ng-style="{ 'margin-left': colContainer.getMargin('left') + 'px', 'margin-right': colContainer.getMargin('right') + 'px' }">
6+
<!-- All of these dom elements are replaced in place -->
27
<div ui-grid-header></div>
38
<div ui-grid-viewport></div>
49
<div ng-if="colContainer.needsHScrollbarPlaceholder()" class="ui-grid-scrollbar-placeholder" style="height:{{colContainer.grid.scrollbarHeight}}px"></div>
+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
<div class="ui-grid-viewport" ng-style="colContainer.getViewportStyle()">
1+
<div role="rowgroup"
2+
class="ui-grid-viewport"
3+
ng-style="colContainer.getViewportStyle()"><!-- tbody -->
24
<div class="ui-grid-canvas">
35
<div ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index" class="ui-grid-row" ng-style="Viewport.rowStyle(rowRenderIndex)">
4-
<div ui-grid-row="row" row-render-index="rowRenderIndex"></div>
6+
<div role="row" ui-grid-row="row" row-render-index="rowRenderIndex"></div>
57
</div>
68
</div>
79
</div>

0 commit comments

Comments
 (0)