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

Commit fedb9a3

Browse files
Splaktarmmalerba
authored andcommitted
fix(toast): improve a11y support for $mdToast.simple(). improve docs (#11424)
move the role="alert" up a level - makes action button visible to screen readers add support for defining an actionKey to assign a hot key to an action - this enables Control-actionKey to activate the action add support for defining a dismissHint for screen readers add support for defining an actionHint for screen readers align custom toast demo with Material Design guidelines enhance custom toast demo to demonstrate an accessible custom toast Fixes #349
1 parent 5aef450 commit fedb9a3

File tree

7 files changed

+228
-94
lines changed

7 files changed

+228
-94
lines changed

src/components/toast/demoBasicUsage/script.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
angular.module('toastDemo1', ['ngMaterial'])
1+
angular.module('toastBasicDemo', ['ngMaterial'])
32

43
.controller('AppCtrl', function($scope, $mdToast) {
54
var last = {
@@ -36,7 +35,7 @@ angular.module('toastDemo1', ['ngMaterial'])
3635
$mdToast.show(
3736
$mdToast.simple()
3837
.textContent('Simple Toast!')
39-
.position(pinTo )
38+
.position(pinTo)
4039
.hideDelay(3000)
4140
);
4241
};
@@ -45,14 +44,18 @@ angular.module('toastDemo1', ['ngMaterial'])
4544
var pinTo = $scope.getToastPosition();
4645
var toast = $mdToast.simple()
4746
.textContent('Marked as read')
47+
.actionKey('z')
48+
.actionHint('Press the Control-"z" key combination to ')
4849
.action('UNDO')
50+
.dismissHint('Activate the Escape key to dismiss this toast.')
4951
.highlightAction(true)
50-
.highlightClass('md-accent')// Accent is used by default, this just demonstrates the usage.
51-
.position(pinTo);
52+
.highlightClass('md-accent') // Accent is used by default, this just demonstrates the usage.
53+
.position(pinTo)
54+
.hideDelay(0);
5255

5356
$mdToast.show(toast).then(function(response) {
54-
if ( response == 'ok' ) {
55-
alert('You clicked the \'UNDO\' action.');
57+
if (response === 'ok') {
58+
alert('You selected the \'UNDO\' action.');
5659
}
5760
});
5861
};
Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
<div ng-controller="AppCtrl" class="inset" ng-cloak style="height:300px; padding: 25px;">
2-
<div layout="row">
3-
4-
<p>
5-
Toast can have multiple actions:
6-
</p>
7-
8-
<md-button ng-click="showCustomToast()" class="md-raised" style="padding-left: 10px;padding-right: 10px;">
9-
Show Custom Toast
10-
</md-button>
11-
12-
</div>
1+
<div ng-controller="AppCtrl as ctrl" id="custom-toast-container" class="inset" ng-cloak>
2+
<span>Toast can have multiple actions:</span>
3+
<md-button ng-click="ctrl.showCustomToast()" class="md-raised">
4+
Show Custom Toast
5+
</md-button>
136
</div>
Lines changed: 95 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,100 @@
11
(function() {
2-
32
var isDlgOpen;
3+
var ACTION_RESOLVE = 'undo';
4+
var UNDO_KEY = 'z';
5+
var DIALOG_KEY = 'd';
6+
7+
angular.module('toastCustomDemo', ['ngMaterial'])
8+
.controller('AppCtrl', AppCtrl)
9+
.controller('ToastCtrl', ToastCtrl);
10+
11+
function AppCtrl($mdToast, $log) {
12+
var ctrl = this;
13+
14+
ctrl.showCustomToast = function() {
15+
$mdToast.show({
16+
hideDelay: 0,
17+
position: 'top right',
18+
controller: 'ToastCtrl',
19+
controllerAs: 'ctrl',
20+
templateUrl: 'toast-template.html'
21+
}).then(function(result) {
22+
if (result === ACTION_RESOLVE) {
23+
$log.log('Undo action triggered by button.');
24+
} else if (result === 'key') {
25+
$log.log('Undo action triggered by hot key: Control-' + UNDO_KEY + '.');
26+
} else if (result === false) {
27+
$log.log('Custom toast dismissed by Escape key.');
28+
} else {
29+
$log.log('Custom toast hidden automatically.');
30+
}
31+
}).catch(function(error) {
32+
$log.error('Custom toast failure:', error);
33+
});
34+
};
35+
}
36+
37+
function ToastCtrl($mdToast, $mdDialog, $document) {
38+
var ctrl = this;
39+
ctrl.keyListenerConfigured = false;
40+
ctrl.undoKey = UNDO_KEY;
41+
ctrl.dialogKey = DIALOG_KEY;
42+
setupActionKeyListener();
43+
44+
ctrl.closeToast = function() {
45+
if (isDlgOpen) {
46+
return;
47+
}
48+
49+
$mdToast.hide(ACTION_RESOLVE).then(function() {
50+
isDlgOpen = false;
51+
});
52+
};
53+
54+
ctrl.openMoreInfo = function(e) {
55+
if (isDlgOpen) {
56+
return;
57+
}
58+
isDlgOpen = true;
59+
60+
$mdDialog.show(
61+
$mdDialog.alert()
62+
.title('More info goes here.')
63+
.textContent('Something witty.')
64+
.ariaLabel('More info')
65+
.ok('Got it')
66+
.targetEvent(e)
67+
).then(function() {
68+
isDlgOpen = false;
69+
});
70+
};
71+
72+
/**
73+
* @param {KeyboardEvent} event
74+
*/
75+
function handleKeyDown(event) {
76+
if (event.key === 'Escape') {
77+
$mdToast.hide(false);
78+
}
79+
if (event.key === UNDO_KEY && event.ctrlKey) {
80+
$mdToast.hide('key');
81+
}
82+
if (event.key === DIALOG_KEY && event.ctrlKey) {
83+
ctrl.openMoreInfo(event);
84+
}
85+
}
86+
87+
function setupActionKeyListener() {
88+
if (!ctrl.keyListenerConfigured) {
89+
$document.on('keydown', handleKeyDown);
90+
ctrl.keyListenerConfigured = true;
91+
}
92+
}
493

5-
angular
6-
.module('toastDemo2', ['ngMaterial'])
7-
.controller('AppCtrl', function($scope, $mdToast) {
8-
$scope.showCustomToast = function() {
9-
$mdToast.show({
10-
hideDelay : 3000,
11-
position : 'top right',
12-
controller : 'ToastCtrl',
13-
templateUrl : 'toast-template.html'
14-
});
15-
};
16-
})
17-
.controller('ToastCtrl', function($scope, $mdToast, $mdDialog) {
18-
19-
$scope.closeToast = function() {
20-
if (isDlgOpen) return;
21-
22-
$mdToast
23-
.hide()
24-
.then(function() {
25-
isDlgOpen = false;
26-
});
27-
};
28-
29-
$scope.openMoreInfo = function(e) {
30-
if ( isDlgOpen ) return;
31-
isDlgOpen = true;
32-
33-
$mdDialog
34-
.show($mdDialog
35-
.alert()
36-
.title('More info goes here.')
37-
.textContent('Something witty.')
38-
.ariaLabel('More info')
39-
.ok('Got it')
40-
.targetEvent(e)
41-
)
42-
.then(function() {
43-
isDlgOpen = false;
44-
});
45-
};
46-
});
94+
function removeActionKeyListener() {
95+
$document.off('keydown');
96+
ctrl.keyListenerConfigured = false;
97+
}
98+
}
4799

48100
})();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#custom-toast-container {
2+
height: 300px;
3+
padding: 25px;
4+
5+
.md-button.md-raised {
6+
padding-left: 10px;
7+
padding-right: 10px;
8+
}
9+
}
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
<md-toast>
2-
<span class="md-toast-text" flex>Custom toast!</span>
3-
<md-button class="md-highlight" ng-click="openMoreInfo($event)">
1+
<md-toast role="alert" aria-relevant="all">
2+
<span class="md-toast-text" flex>Custom toast</span>
3+
<span class="md-visually-hidden">
4+
Press Escape to dismiss. Press Control-"{{ctrl.dialogKey}}" for
5+
</span>
6+
<md-button class="md-highlight" ng-click="ctrl.openMoreInfo($event)">
47
More info
58
</md-button>
6-
<md-button ng-click="closeToast()">
7-
Close
9+
<span class="md-visually-hidden">
10+
Press Control-"{{ctrl.undoKey}}" to
11+
</span>
12+
<md-button ng-click="ctrl.closeToast()">
13+
Undo
814
</md-button>
915
</md-toast>

0 commit comments

Comments
 (0)