Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
feat(tabs): add accessibility links between tabs and content
Browse files Browse the repository at this point in the history
Additionally, the static tabs demo now has aria links between tabs and
content.
  • Loading branch information
Marcy Sutton authored and ajoslin committed Nov 8, 2014
1 parent ab81a22 commit 5d3bab5
Show file tree
Hide file tree
Showing 23 changed files with 632 additions and 521 deletions.
7 changes: 6 additions & 1 deletion config/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ module.exports = function(config) {
'bower_components/hammerjs/hammer.js',
'config/test-utils.js',
'src/core/**/*.js',

// We are explicit like this because we don't want to put
// demos in the tests, and Karma doesn't support advanced
// globbing.
'src/components/*/*.js',
'src/components/tabs/js/*.js',
'src/services/*.js',
'src/services/*/*.js' // Don't put demos in the tests
'src/services/*/*.js',
],

port: 9876,
Expand Down
21 changes: 21 additions & 0 deletions config/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,24 @@ var TestUtil = {
});
}
};

beforeEach(function() {

this.addMatchers({
// toHaveClass matcher from angularjs test helpers
toHaveClass: function(clazz) {
this.message = function() {
return "Expected '" + angular.mock.dump(this.actual) +
(this.isNot ? ' not' : '') + " to have class '" + clazz + "'.";
};
var classes = clazz.trim().split(/\s+/);
for (var i=0; i<classes.length; ++i) {
if (!angular.element(this.actual).hasClass(classes[i])) {
return false;
}
}
return true;
}
});

});
2 changes: 1 addition & 1 deletion src/components/slider/slider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('md-slider', function() {

beforeEach(TestUtil.mockRaf);
beforeEach(module('ngAria'));
beforeEach(module('material.components.slider','material.decorators'));
beforeEach(module('material.components.slider'));

it('should set model on press', inject(function($compile, $rootScope, $timeout) {
var slider = $compile('<md-slider ng-model="value" min="0" max="100">')($rootScope);
Expand Down
1 change: 0 additions & 1 deletion src/components/sticky/sticky.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
angular.module('material.components.sticky', [
'material.core',
'material.components.content',
'material.decorators',
'material.animations'
])
.factory('$mdSticky', [
Expand Down
2 changes: 2 additions & 0 deletions src/components/tabs/_tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ md-tabs {
width: $tabs-paginator-width;
min-height: 100%;
cursor: pointer;
border: none;
background-color: transparent;
background-repeat: no-repeat;
background-position: center center;

Expand Down
53 changes: 26 additions & 27 deletions src/components/tabs/demoDynamicTabs/index.html
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
<div ng-controller="AppCtrl" class="sample">

<md-tabs selected="selectedIndex">
<md-tab ng-repeat="tab in tabs"
on-select="onTabSelected(tab)"
on-deselect="announceDeselected(tab)"
ng-disabled="tab.disabled"
label="{{tab.title}}">
<md-tabs selected="selectedIndex">
<md-tab ng-repeat="tab in tabs"
on-select="announceSelected(tab)"
on-deselect="announceDeselected(tab)"
ng-disabled="tab.disabled"
label="{{tab.title}}">

<div ng-class="tab.style" layout="vertical" layout-fill layout-align="center center">
<div flex ng-bind="tab.content" class="tab-text"></div>
<md-button class="remove-tab md-warn"
ng-click="removeTab( tab )">Remove Tab
</md-button>
</div>
</md-tab>
</md-tabs>
<div class="demo-tab tab{{$index%4}}" layout="vertical" layout-fill layout-align="space-around center">
<div ng-bind="tab.content"></div>
<md-button class="md-warn" ng-click="removeTab( tab )">
Remove Tab
</md-button>
</div>
</md-tab>
</md-tabs>

<form ng-submit="addTab(tTitle,tContent)" flex>
<div layout="vertical" layout-sm="horizontal" layout-padding layout-align="left center">
<md-text-float label="Active Index" ng-model="selectedIndex" disabled></md-text-float>
<md-text-float label="Active Title" ng-model="tabs[selectedIndex].title"></md-text-float>
<md-text-float label="Active Content" ng-model="tabs[selectedIndex].content" class="long"></md-text-float>
</div>
<div layout="vertical" layout-sm="horizontal" layout-padding layout-align="left center">
<span class="title">Add a new Tab:</span>
<md-text-float label="Label" ng-model="tTitle"></md-text-float>
<md-text-float label="Content" ng-model="tContent" ></md-text-float>
<md-button class="add-tab md-primary" type="submit" style="max-height: 40px" >Add Tab</md-button>
</div>
</form>
<form ng-submit="addTab(tTitle,tContent)" flex>
<div layout="vertical" layout-sm="horizontal" layout-padding layout-align="left center">
<md-text-float label="Active Index" ng-model="selectedIndex" disabled></md-text-float>
<md-text-float label="Active Title" ng-model="tabs[selectedIndex].title"></md-text-float>
</div>
<div layout="vertical" layout-sm="horizontal" layout-padding layout-align="left center">
<span class="title">Add a new Tab:</span>
<md-text-float label="Label" ng-model="tTitle"></md-text-float>
<md-text-float label="Content" ng-model="tContent" ></md-text-float>
<md-button class="add-tab md-primary" type="submit" style="max-height: 40px" >Add Tab</md-button>
</div>
</form>


</div>
44 changes: 14 additions & 30 deletions src/components/tabs/demoDynamicTabs/script.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
angular.module('tabsDemo2', ['ngMaterial'])
.controller('AppCtrl', function ($scope, $interpolate) {
.controller('AppCtrl', function ($scope) {
var tabs = [
{ title: 'Polymer', active: true, content: "Polymer practices are great!", style:"tab1"},
{ title: 'Material Design', active: false, content: "Material Design practices are better!", style:"tab2" },
{ title: 'Angular', active: false, content: "AngularJS practices are the best!", style:"tab3" },
{ title: 'NodeJS', active: false, disabled: false, content: "NodeJS practices are amazing!" ,style:"tab4" }
{ title: 'One', content: "Tabs will become paginated if there isn't enough room for them."},
{ title: 'Two', content: "You can swipe left and right on a mobile device to change tabs."},
{ title: 'Three', content: "You can bind the selected tab via the selected attribute on the md-tabs element."},
{ title: 'Four', content: "If you set the selected tab binding to -1, it will leave no tab selected."},
{ title: 'Five', content: "If you remove a tab, it will try to select a new one."},
{ title: 'Six', content: "There's an ink bar that follows the selected tab, you can turn it off if you want."},
{ title: 'Seven', content: "If you set ng-disabled on a tab, it becomes unselectable. If the currently selected tab becomes disabled, it will try to select the next tab."},
{ title: 'Eight', content: "If you look at the source, you're using tabs to look at a demo for tabs. Recursion!"},
{ title: 'Nine', content: "If you set md-theme=\"green\" on the md-tabs element, you'll get green tabs."},
{ title: 'Ten', content: "If you're still reading this, you should just go check out the API docs for tabs!"}
];

$scope.tabs = tabs;
$scope.predicate = "title";
$scope.reversed = true;
$scope.selectedIndex = 2;
$scope.allowDisable = true;

$scope.onTabSelected = onTabSelected;
$scope.announceSelected = announceSelected;
$scope.announceDeselected = announceDeselected;

$scope.addTab = function (title, view) {
var style = tabs[(tabs.length % 4)].style;
view = view || title + " Content View";
tabs.push({ title: title, content: view, active: false, disabled: false, style:style});
tabs.push({ title: title, content: view, disabled: false, style:style});
};

$scope.removeTab = function (tab) {
Expand All @@ -32,29 +33,12 @@ angular.module('tabsDemo2', ['ngMaterial'])
}
};

$scope.submit = function ($event) {
if ($event.which !== 13) return;
if ($scope.tTitle) {
$scope.addTab($scope.tTitle, $scope.tContent);
}
};

// **********************************************************
// Private Methods
// **********************************************************

function onTabSelected(tab) {
$scope.selectedIndex = this.$index;

$scope.announceSelected(tab);
}

function announceDeselected(tab) {
$scope.farewell = $interpolate("Goodbye {{title}}!")(tab);
$scope.farewell = 'Goodbye ' + tab.title + '!';
}

function announceSelected(tab) {
$scope.greeting = $interpolate("Hello {{title}}!")(tab);
$scope.greeting = 'Hello ' + tab.title + '!';
}

});
Expand Down
43 changes: 16 additions & 27 deletions src/components/tabs/demoDynamicTabs/style.css
Original file line number Diff line number Diff line change
@@ -1,38 +1,27 @@

.remove-tab {
margin-bottom: 40px;
margin-bottom: 40px;
}

md-tabs .md-view {
background: #EEE;
.md-button {
display:block;
}

.tab-text {
padding-top: 32px;
margin-bottom: 32px;
.demo-tab {
height: 300px;
text-align: center;
}


.md-button {
display:block;
.tab0 {
background-color: #E3F2FD;
}


.tab1 {
background-color: #abd6e4;
height:300px;
background-color: #E1F5FE;
}
.tab2 {
background-color: #94caa6;
height:300px;
background-color: #E0F7FA;
}
.tab3 {
background-color: #c4b5a2;
height:300px;
}
.tab4 {
background-color: #e3cde8;
height:300px;
background-color: #E0F2F1;
}

.title {
Expand All @@ -46,22 +35,22 @@ md-tabs .md-view {


[layout-align] > * {
margin-left: 8px;
margin-left: 8px;
}

form > [layout] > * {
margin-left: 8px;
}

.long > input {
width: 264px;
width: 264px;
}

.md-button {
max-height: 30px;
max-height: 30px;
}

.md-button.add-tab {
margin-top:20px;
max-height:30px !important;
margin-top:20px;
max-height:30px !important;
}
102 changes: 0 additions & 102 deletions src/components/tabs/demoPagination/index.html

This file was deleted.

Loading

0 comments on commit 5d3bab5

Please sign in to comment.