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

Commit 93518bb

Browse files
committed
fix(calendar): allow tabbing out when in standalone mode
- using the `md-calendar` outside of the `md-datepicker` no longer breaks the page's tab order - change one access of the global `document` to use `$document` - improve Closure types - update JSDoc for `CalendarCtrl.handleKeyEvent()` Fixes #9794
1 parent 5c455d3 commit 93518bb

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

src/components/datepicker/js/calendar.js

+24-9
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,8 @@
107107
* Controller for the mdCalendar component.
108108
* @ngInject @constructor
109109
*/
110-
function CalendarCtrl($element, $scope, $$mdDateUtil, $mdUtil,
111-
$mdConstant, $mdTheming, $$rAF, $attrs, $mdDateLocale, $filter) {
112-
110+
function CalendarCtrl($element, $scope, $$mdDateUtil, $mdUtil, $mdConstant, $mdTheming, $$rAF,
111+
$attrs, $mdDateLocale, $filter, $document) {
113112
$mdTheming($element);
114113

115114
/**
@@ -229,6 +228,12 @@
229228
*/
230229
this.scrollbarWidth = 0;
231230

231+
/**
232+
* @type {boolean} set to true if the calendar is being used "standalone" (outside of a
233+
* md-datepicker).
234+
*/
235+
this.standaloneMode = false;
236+
232237
// Unless the user specifies so, the calendar should not be a tab stop.
233238
// This is necessary because ngAria might add a tabindex to anything with an ng-model
234239
// (based on whether or not the user has turned that particular feature on/off).
@@ -245,8 +250,9 @@
245250

246251
var handleKeyElement;
247252
if ($element.parent().hasClass('md-datepicker-calendar')) {
248-
handleKeyElement = angular.element(document.body);
253+
handleKeyElement = angular.element($document[0].body);
249254
} else {
255+
this.standaloneMode = true;
250256
handleKeyElement = $element;
251257
}
252258

@@ -445,8 +451,8 @@
445451
* Normalizes the key event into an action name. The action will be broadcast
446452
* to the child controllers.
447453
* @param {KeyboardEvent} event
448-
* @returns {String} The action that should be taken, or null if the key
449-
* does not match a calendar shortcut.
454+
* @returns {string} The action that should be taken, or null if the key
455+
* does not match a calendar shortcut.
450456
*/
451457
CalendarCtrl.prototype.getActionFromKeyEvent = function(event) {
452458
var keyCode = this.keyCode;
@@ -471,8 +477,13 @@
471477
};
472478

473479
/**
474-
* Handles a key event in the calendar with the appropriate action. The action will either
475-
* be to select the focused date or to navigate to focus a new date.
480+
* Handles a key event in the calendar with the appropriate action.
481+
* The action will either
482+
* - select the focused date
483+
* - navigate to focus a new date
484+
* - emit a md-calendar-close event if in a md-datepicker panel
485+
* - emit a md-calendar-parent-action
486+
* - delegate to normal tab order if the TAB key is pressed in standalone mode
476487
* @param {KeyboardEvent} event
477488
*/
478489
CalendarCtrl.prototype.handleKeyEvent = function(event) {
@@ -481,13 +492,17 @@
481492
this.$scope.$apply(function() {
482493
// Capture escape and emit back up so that a wrapping component
483494
// (such as a date-picker) can decide to close.
484-
if (event.which === self.keyCode.ESCAPE || event.which === self.keyCode.TAB) {
495+
if (event.which === self.keyCode.ESCAPE ||
496+
(event.which === self.keyCode.TAB && !self.standaloneMode)) {
485497
self.$scope.$emit('md-calendar-close');
486498

487499
if (event.which === self.keyCode.TAB) {
488500
event.preventDefault();
489501
}
490502

503+
return;
504+
} else if (event.which === self.keyCode.TAB && self.standaloneMode) {
505+
// delegate to the normal tab order if the TAB key is pressed in standalone mode
491506
return;
492507
}
493508

0 commit comments

Comments
 (0)