md2
Version:
Angular2 based Material Design components, directives and services are Accordion, Autocomplete, Chips(Tags), Collapse, Colorpicker, Data Table, Datepicker, Dialog(Modal), Menu, Multiselect, Select, Tabs, Tags(Chips), Toast and Tooltip.
161 lines • 6.43 kB
JavaScript
import { UP_ARROW, DOWN_ARROW, TAB } from '../core';
import { Subject } from 'rxjs/Subject';
/**
* This class manages keyboard events for selectable lists. If you pass it a query list
* of items, it will set the active item correctly when arrow events occur.
*/
var ListKeyManager = (function () {
function ListKeyManager(_items) {
this._items = _items;
this._activeItemIndex = null;
this._tabOut = new Subject();
this._wrap = false;
}
/**
* Turns on wrapping mode, which ensures that the active item will wrap to
* the other end of list when there are no more items in the given direction.
*
* @returns The ListKeyManager that the method was called on.
*/
ListKeyManager.prototype.withWrap = function () {
this._wrap = true;
return this;
};
/**
* Sets the active item to the item at the index specified.
*
* @param index The index of the item to be set as active.
*/
ListKeyManager.prototype.setActiveItem = function (index) {
this._activeItemIndex = index;
this._activeItem = this._items.toArray()[index];
};
/**
* Sets the active item depending on the key event passed in.
* @param event Keyboard event to be used for determining which element should be active.
*/
ListKeyManager.prototype.onKeydown = function (event) {
switch (event.keyCode) {
case DOWN_ARROW:
this.setNextItemActive();
break;
case UP_ARROW:
this.setPreviousItemActive();
break;
case TAB:
// Note that we shouldn't prevent the default action on tab.
this._tabOut.next(null);
return;
default:
return;
}
event.preventDefault();
};
Object.defineProperty(ListKeyManager.prototype, "activeItemIndex", {
/** Returns the index of the currently active item. */
get: function () {
return this._activeItemIndex;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ListKeyManager.prototype, "activeItem", {
/** Returns the currently active item. */
get: function () {
return this._activeItem;
},
enumerable: true,
configurable: true
});
/** Sets the active item to the first enabled item in the list. */
ListKeyManager.prototype.setFirstItemActive = function () {
this._setActiveItemByIndex(0, 1);
};
/** Sets the active item to the last enabled item in the list. */
ListKeyManager.prototype.setLastItemActive = function () {
this._setActiveItemByIndex(this._items.length - 1, -1);
};
/** Sets the active item to the next enabled item in the list. */
ListKeyManager.prototype.setNextItemActive = function () {
this._activeItemIndex === null ? this.setFirstItemActive() : this._setActiveItemByDelta(1);
};
/** Sets the active item to a previous enabled item in the list. */
ListKeyManager.prototype.setPreviousItemActive = function () {
this._activeItemIndex === null && this._wrap ? this.setLastItemActive()
: this._setActiveItemByDelta(-1);
};
/**
* Allows setting of the activeItemIndex without any other effects.
* @param index The new activeItemIndex.
*/
ListKeyManager.prototype.updateActiveItemIndex = function (index) {
this._activeItemIndex = index;
};
Object.defineProperty(ListKeyManager.prototype, "tabOut", {
/**
* Observable that emits any time the TAB key is pressed, so components can react
* when focus is shifted off of the list.
*/
get: function () {
return this._tabOut.asObservable();
},
enumerable: true,
configurable: true
});
/**
* This method sets the active item, given a list of items and the delta between the
* currently active item and the new active item. It will calculate differently
* depending on whether wrap mode is turned on.
*/
ListKeyManager.prototype._setActiveItemByDelta = function (delta, items) {
if (items === void 0) { items = this._items.toArray(); }
this._wrap ? this._setActiveInWrapMode(delta, items)
: this._setActiveInDefaultMode(delta, items);
};
/**
* Sets the active item properly given "wrap" mode. In other words, it will continue to move
* down the list until it finds an item that is not disabled, and it will wrap if it
* encounters either end of the list.
*/
ListKeyManager.prototype._setActiveInWrapMode = function (delta, items) {
// when active item would leave menu, wrap to beginning or end
this._activeItemIndex =
(this._activeItemIndex + delta + items.length) % items.length;
// skip all disabled menu items recursively until an enabled one is reached
if (items[this._activeItemIndex].disabled) {
this._setActiveInWrapMode(delta, items);
}
else {
this.setActiveItem(this._activeItemIndex);
}
};
/**
* Sets the active item properly given the default mode. In other words, it will
* continue to move down the list until it finds an item that is not disabled. If
* it encounters either end of the list, it will stop and not wrap.
*/
ListKeyManager.prototype._setActiveInDefaultMode = function (delta, items) {
this._setActiveItemByIndex(this._activeItemIndex + delta, delta, items);
};
/**
* Sets the active item to the first enabled item starting at the index specified. If the
* item is disabled, it will move in the fallbackDelta direction until it either
* finds an enabled item or encounters the end of the list.
*/
ListKeyManager.prototype._setActiveItemByIndex = function (index, fallbackDelta, items) {
if (items === void 0) { items = this._items.toArray(); }
if (!items[index]) {
return;
}
while (items[index].disabled) {
index += fallbackDelta;
if (!items[index]) {
return;
}
}
this.setActiveItem(index);
};
return ListKeyManager;
}());
export { ListKeyManager };
//# sourceMappingURL=list-key-manager.js.map