Skip to content

Commit

Permalink
feat(core): Basic screen reader accessibility functionality
Browse files Browse the repository at this point in the history
 - 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
  • Loading branch information
JLLeitschuh committed Jul 27, 2015
1 parent 94e50a5 commit 377485a
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 18 deletions.
83 changes: 83 additions & 0 deletions misc/demo/grid-accessiblility.html
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html class="no-js" ng-app="test"><!--<![endif]-->
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<title></title>
<meta content="width=device-width" name="viewport">

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" />
<link href="/dist/release/ui-grid.css" rel="stylesheet">

<!--<script src="https://code.jquery.com/jquery-1.11.1.js"></script>-->
<script src="/lib/test/angular/1.3.16/angular.js"></script>
<script src="https://code.angularjs.org/1.3.16/angular-aria.js"></script>
<script src="/dist/release/ui-grid.js"></script>

<style>
body {
padding: 60px;
min-height: 600px;
}
.grid {
width: 1200px;
height: 400px;
}
.placeholder {
height: 50%;
width: 50%;
border: 3px solid black;
background: #ccc;
}
</style>
</head>
<body ng-controller="Main">
<!-- <h1>Test</h1> -->

<!-- <div class="row main"> -->
<h2>Grid</h2>
<div ui-grid="gridOptions" class="grid" ui-grid-resize-columns ui-grid-cellNav ui-grid-pagination></div>
<!-- <div class="placeholder"> -->
<!-- </div> -->

<br>
<br>

<script>
var app = angular.module('test', ['ui.grid', 'ui.grid.pinning', 'ui.grid.resizeColumns', 'ui.grid.cellNav', 'ui.grid.pagination', 'ngAria']);
app.controller('Main', function($scope, $http) {
$scope.gridOptions = {
enableSorting: true,
showGridFooter: true,
enableGridMenu: true,
enableFiltering: true,
paginationPageSizes: [25, 50, 75, 100],
paginationPageSize: 25,
useExternalPagination: false,
useExternalSorting: false,
};
$scope.gridOptions.columnDefs = [
{ name:'id', width:50 },
{ name:'name', width:100, pinnedLeft:true },
{ name:'age', width:100, pinnedRight:true },
{ name:'address.street', width:150 },
{ name:'address.city', width:150 },
{ name:'address.state', width:50 },
{ name:'address.zip', width:50 },
{ name:'company', width:100 },
{ name:'email', width:100 },
{ name:'phone', width:200 },
{ name:'about', width:300 },
{ name:'friends[0].name', displayName:'1st friend', width:150 },
{ name:'friends[1].name', displayName:'2nd friend', width:150 },
{ name:'friends[2].name', displayName:'3rd friend', width:150 }
];

$http.get('https://rawgit.com/angular-ui/ui-grid.info/gh-pages/data/500_complex.json')
.success(function(data) {
$scope.gridOptions.data = data;
});
});
</script>
</body>
</html>
15 changes: 15 additions & 0 deletions src/less/grid.less
Expand Up @@ -63,3 +63,18 @@
height: 100%;
width: 100%;
}

// Only display content to screen readers
//
// See: http://a11yproject.com/posts/how-to-hide-content/

.ui-grid-sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
border: 0;
}
6 changes: 6 additions & 0 deletions src/less/variables.less
Expand Up @@ -69,6 +69,12 @@
@invalidValueBorder: 1px solid rgb(252, 143, 143);
@validValueBorder: 1px solid @borderColor;

//Pagination controls
@paginationButtonColor: @headerGradientStart;
@paginationButtonBackgroundColor: @headerBackgroundColor;
@paginationButtonBorderColor: #ccc;


/**
* @section font library path
*/
Expand Down
6 changes: 3 additions & 3 deletions src/templates/ui-grid/ui-grid-footer.html
@@ -1,9 +1,9 @@
<div class="ui-grid-footer-panel ui-grid-footer-aggregates-row">
<div class="ui-grid-footer-panel ui-grid-footer-aggregates-row"> <!-- tfooter -->
<div class="ui-grid-footer ui-grid-footer-viewport">
<div class="ui-grid-footer-canvas">
<div class="ui-grid-footer-cell-wrapper" ng-style="colContainer.headerCellWrapperStyle()">
<div class="ui-grid-footer-cell-row">
<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>
<div role="row" class="ui-grid-footer-cell-row">
<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>
</div>
</div>
</div>
Expand Down
5 changes: 2 additions & 3 deletions src/templates/ui-grid/ui-grid-header.html
@@ -1,14 +1,13 @@
<div class="ui-grid-header">
<div role="rowgroup" class="ui-grid-header"> <!-- theader -->
<div class="ui-grid-top-panel">
<div class="ui-grid-header-viewport">
<div class="ui-grid-header-canvas">
<div class="ui-grid-header-cell-wrapper" ng-style="colContainer.headerCellWrapperStyle()">
<div class="ui-grid-header-cell-row">
<div role="row" class="ui-grid-header-cell-row">
<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>
</div>
</div>
</div>

</div>
</div>
</div>
8 changes: 7 additions & 1 deletion src/templates/ui-grid/ui-grid-row.html
@@ -1 +1,7 @@
<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>
<div
ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.uid"
ui-grid-one-bind-id-grid="rowRenderIndex + '-' + col.uid + '-cell'"
class="ui-grid-cell"
ng-class="{ 'ui-grid-row-header-cell': col.isRowHeader }"
role="{{col.isRowHeader ? 'rowheader' : 'gridcell'}}"
ui-grid-cell></div>
14 changes: 6 additions & 8 deletions src/templates/ui-grid/uiGridHeaderCell.html
@@ -1,15 +1,13 @@
<div ng-class="{ 'sortable': sortable }">
<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'))}}">
<!-- <div class="ui-grid-vertical-bar">&nbsp;</div> -->
<div class="ui-grid-cell-contents" col-index="renderIndex" title="TOOLTIP">
<span>{{ col.displayName CUSTOM_FILTERS }}</span>
<div role="button" tabindex=0 class="ui-grid-cell-contents" col-index="renderIndex" title="TOOLTIP">
<span id="{{grid.id}}-{{col.name}}-header-text">{{ col.displayName CUSTOM_FILTERS }}</span>

<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 }">
&nbsp;
</span>
<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>
</div>

<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}">
<i class="ui-grid-icon-angle-down">&nbsp;</i>
<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">
<i class="ui-grid-icon-angle-down" aria-hidden="true">&nbsp;</i>
</div>

<div ui-grid-filter></div>
Expand Down
7 changes: 6 additions & 1 deletion src/templates/ui-grid/uiGridRenderContainer.html
@@ -1,4 +1,9 @@
<div class="ui-grid-render-container" ng-style="{ 'margin-left': colContainer.getMargin('left') + 'px', 'margin-right': colContainer.getMargin('right') + 'px' }">
<div
role="grid"
ui-grid-one-bind-id-grid="'grid-container'"
class="ui-grid-render-container"
ng-style="{ 'margin-left': colContainer.getMargin('left') + 'px', 'margin-right': colContainer.getMargin('right') + 'px' }">
<!-- All of these dom elements are replaced in place -->
<div ui-grid-header></div>
<div ui-grid-viewport></div>
<div ng-if="colContainer.needsHScrollbarPlaceholder()" class="ui-grid-scrollbar-placeholder" style="height:{{colContainer.grid.scrollbarHeight}}px"></div>
Expand Down
6 changes: 4 additions & 2 deletions src/templates/ui-grid/uiGridViewport.html
@@ -1,7 +1,9 @@
<div class="ui-grid-viewport" ng-style="colContainer.getViewportStyle()">
<div role="rowgroup"
class="ui-grid-viewport"
ng-style="colContainer.getViewportStyle()"><!-- tbody -->
<div class="ui-grid-canvas">
<div ng-repeat="(rowRenderIndex, row) in rowContainer.renderedRows track by $index" class="ui-grid-row" ng-style="Viewport.rowStyle(rowRenderIndex)">
<div ui-grid-row="row" row-render-index="rowRenderIndex"></div>
<div role="row" ui-grid-row="row" row-render-index="rowRenderIndex"></div>
</div>
</div>
</div>

0 comments on commit 377485a

Please sign in to comment.