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

Commit

Permalink
fix(tabs): do not focus until pagination transition is done
Browse files Browse the repository at this point in the history
Closes #781
  • Loading branch information
ajoslin committed Dec 3, 2014
1 parent 57a7b57 commit bb9bc82
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 19 deletions.
24 changes: 12 additions & 12 deletions src/components/tabs/js/paginationDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function TabPaginationDirective($mdConstant, $window, $$rAF, $$q, $timeout) {

// TODO allow configuration of TAB_MIN_WIDTH
// Must match tab min-width rule in _tabs.scss
var TAB_MIN_WIDTH = 8 * 12;
var TAB_MIN_WIDTH = 8 * 12;
// Must match (2 * width of paginators) in scss
var PAGINATORS_WIDTH = (8 * 4) * 2;

Expand All @@ -35,25 +35,25 @@ function TabPaginationDirective($mdConstant, $window, $$rAF, $$q, $timeout) {
scope.$on('$mdTabsChanged', debouncedUpdatePagination);
angular.element($window).on('resize', debouncedUpdatePagination);

// Listen to focus events bubbling up from md-tab elements
tabsParent.on('focusin', onTabsFocusIn);

scope.$on('$destroy', function() {
angular.element($window).off('resize', debouncedUpdatePagination);
tabsParent.off('focusin', onTabsFocusIn);
});

scope.$watch(tabsCtrl.selected, onSelectedTabChange);
scope.$watch(function() {
return tabsCtrl.tabToFocus;
}, onTabFocus);

// Allows pagination through focus change.
function onTabsFocusIn(ev) {
if (!state.active) return;
// Make sure we don't focus an element on the next page
// before it's in view
function onTabFocus(tab) {
if (!tab) return;

var tab = angular.element(ev.target).controller('mdTab');
var pageIndex = getPageForTab(tab);
if (pageIndex !== state.page) {
// If the focused element is on a new page, don't focus yet.
tab.element.blur();
if (!state.active || pageIndex === state.page) {
tab.element.focus();
} else {
// Go to the new page, wait for the page transition to end, then focus.
setPage(pageIndex).then(function() {
tab.element.focus();
Expand Down Expand Up @@ -116,7 +116,7 @@ function TabPaginationDirective($mdConstant, $window, $$rAF, $$q, $timeout) {
state.pagesCount = Math.ceil((TAB_MIN_WIDTH * tabsCtrl.count()) / tabsWidth);
state.itemsPerPage = Math.max(1, Math.floor(tabsCtrl.count() / state.pagesCount));
state.tabWidth = tabsWidth / state.itemsPerPage;

tabsParent.css('width', state.tabWidth * tabsCtrl.count() + 'px');
tabs.css('width', state.tabWidth + 'px');

Expand Down
15 changes: 8 additions & 7 deletions src/components/tabs/js/tabItemDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,23 @@ function MdTabDirective($mdInkRipple, $compile, $mdAria, $mdUtil, $mdConstant) {
function defaultClickListener() {
scope.$apply(function() {
tabsCtrl.select(tabItemCtrl);
tabItemCtrl.element.focus();
tabsCtrl.focus(tabItemCtrl);
});
}
function keydownListener(ev) {
if (ev.keyCode == $mdConstant.KEY_CODE.SPACE || ev.keyCode == $mdConstant.KEY_CODE.ENTER ) {
// Fire the click handler to do normal selection if space is pressed
element.triggerHandler('click');
ev.preventDefault();

} else if (ev.keyCode === $mdConstant.KEY_CODE.LEFT_ARROW) {
var previous = tabsCtrl.previous(tabItemCtrl);
previous && previous.element.focus();

scope.$evalAsync(function() {
tabsCtrl.focus(tabsCtrl.previous(tabItemCtrl));
console.log('pressing back');
});
} else if (ev.keyCode === $mdConstant.KEY_CODE.RIGHT_ARROW) {
var next = tabsCtrl.next(tabItemCtrl);
next && next.element.focus();
scope.$evalAsync(function() {
tabsCtrl.focus(tabsCtrl.next(tabItemCtrl));
});
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/components/tabs/js/tabsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ function MdTabsController($scope, $element, $mdUtil) {

// Properties
self.$element = $element;
self.scope = $scope;
// The section containing the tab content $elements
self.contentArea = angular.element($element[0].querySelector('.md-tabs-content'));

Expand All @@ -25,6 +26,7 @@ function MdTabsController($scope, $element, $mdUtil) {
self.remove = remove;
self.move = move;
self.select = select;
self.focus = focus;
self.deselect = deselect;

self.next = next;
Expand Down Expand Up @@ -99,6 +101,11 @@ function MdTabsController($scope, $element, $mdUtil) {
tab.onSelect();
}

function focus(tab) {
// this variable is $watch'd by pagination
self.tabToFocus = tab;
}

function deselect(tab) {
if (!tab || !tab.isSelected) return;
if (!tabsList.contains(tab)) return;
Expand Down

0 comments on commit bb9bc82

Please sign in to comment.