@angular-mdc/web
Version:
343 lines (338 loc) • 11.5 kB
JavaScript
/**
* @license
* Copyright (c) Dominic Carretto
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/trimox/angular-mdc-web/blob/master/LICENSE
*/
import { EventEmitter, Component, ViewEncapsulation, ChangeDetectionStrategy, Input, Output, ContentChild, Directive, ElementRef, NgModule } from '@angular/core';
import { MdcMenuSurfaceBase, MdcMenuSurfaceModule } from '@angular-mdc/web/menu-surface';
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { MdcList } from '@angular-mdc/web/list';
import { closest } from '@angular-mdc/web/dom';
import { cssClasses, MDCMenuFoundation } from '@material/menu';
/**
* @fileoverview added by tsickle
* Generated from: menu/menu.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class MdcMenuSelectedEvent {
/**
* @param {?} index
* @param {?} source
*/
constructor(index, source) {
this.index = index;
this.source = source;
}
}
/** @type {?} */
let nextUniqueId = 0;
class MdcMenu extends MdcMenuSurfaceBase {
constructor() {
super(...arguments);
/**
* Emits whenever the component is destroyed.
*/
this._destroyed = new Subject();
this._uniqueId = `${cssClasses.ROOT}-${++nextUniqueId}`;
this.id = this._uniqueId;
this._wrapFocus = false;
this._closeSurfaceOnSelection = true;
this.selected = new EventEmitter();
this._menuFoundation = new MDCMenuFoundation(this._createAdapter());
}
/**
* @return {?}
*/
get wrapFocus() {
return this._wrapFocus;
}
/**
* @param {?} value
* @return {?}
*/
set wrapFocus(value) {
/** @type {?} */
const newValue = coerceBooleanProperty(value);
if (newValue !== this._wrapFocus) {
this._wrapFocus = newValue;
(/** @type {?} */ (this._list)).wrapFocus = newValue;
}
}
/**
* @return {?}
*/
get closeSurfaceOnSelection() {
return this._closeSurfaceOnSelection;
}
/**
* @param {?} value
* @return {?}
*/
set closeSurfaceOnSelection(value) {
/** @type {?} */
const newValue = coerceBooleanProperty(value);
if (newValue !== this._closeSurfaceOnSelection) {
this._closeSurfaceOnSelection = newValue;
}
}
/**
* @return {?}
*/
get defaultFocusState() {
return this._defaultFocusState;
}
/**
* @param {?} value
* @return {?}
*/
set defaultFocusState(value) {
if (value !== this._defaultFocusState) {
this._defaultFocusState = coerceNumberProperty(value, 0);
this._menuFoundation.setDefaultFocusState(this._defaultFocusState);
}
}
/**
* @private
* @return {?}
*/
_createAdapter() {
return Object.assign({
addClassToElementAtIndex: (/**
* @param {?} index
* @param {?} className
* @return {?}
*/
(index, className) => (/** @type {?} */ (this._list)).items.toArray()[index].getListItemElement().classList.add(className)),
removeClassFromElementAtIndex: (/**
* @param {?} index
* @param {?} className
* @return {?}
*/
(index, className) => (/** @type {?} */ (this._list)).items.toArray()[index].getListItemElement().classList.remove(className)),
addAttributeToElementAtIndex: (/**
* @param {?} index
* @param {?} attr
* @param {?} value
* @return {?}
*/
(index, attr, value) => (/** @type {?} */ (this._list)).items.toArray()[index].getListItemElement().setAttribute(attr, value)),
removeAttributeFromElementAtIndex: (/**
* @param {?} index
* @param {?} attr
* @return {?}
*/
(index, attr) => (/** @type {?} */ (this._list)).items.toArray()[index].getListItemElement().removeAttribute(attr)),
elementContainsClass: (/**
* @param {?} element
* @param {?} className
* @return {?}
*/
(element, className) => element.classList.contains(className)),
closeSurface: (/**
* @param {?} skipRestoreFocus
* @return {?}
*/
(skipRestoreFocus) => {
if (this.closeSurfaceOnSelection) {
this._foundation.close(skipRestoreFocus);
}
}),
getElementIndex: (/**
* @param {?} element
* @return {?}
*/
(element) => (/** @type {?} */ (this._list)).items.toArray().findIndex((/**
* @param {?} _
* @return {?}
*/
_ => _.getListItemElement() === element))),
notifySelected: (/**
* @param {?} evtData
* @return {?}
*/
(evtData) => this.selected.emit(new MdcMenuSelectedEvent(evtData.index, (/** @type {?} */ (this._list)).items.toArray()[evtData.index]))),
getMenuItemCount: (/**
* @return {?}
*/
() => (/** @type {?} */ (this._list)).items.toArray().length),
focusItemAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => (/** @type {?} */ (this._list)).items.toArray()[index].focus()),
focusListRoot: (/**
* @return {?}
*/
() => (/** @type {?} */ (this._list)).focus()),
isSelectableItemAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => !!closest((/** @type {?} */ (this._list)).items.toArray()[index].getListItemElement(), `.${cssClasses.MENU_SELECTION_GROUP}`)),
getSelectedSiblingOfItemAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => {
/** @type {?} */
const selectionGroupEl = (/** @type {?} */ (closest((/** @type {?} */ (this._list)).items.toArray()[index].getListItemElement(), `.${cssClasses.MENU_SELECTION_GROUP}`)));
/** @type {?} */
const selectedItemEl = selectionGroupEl.querySelector(`.${cssClasses.MENU_SELECTED_LIST_ITEM}`);
return selectedItemEl ? (/** @type {?} */ (this._list)).items.toArray().findIndex((/**
* @param {?} _
* @return {?}
*/
_ => _.elementRef.nativeElement === selectedItemEl)) : -1;
})
});
}
/**
* @return {?}
*/
ngAfterContentInit() {
this.initMenuSurface();
this._initList();
this.opened.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @return {?}
*/
() => this._menuFoundation.handleMenuSurfaceOpened()));
}
/**
* @return {?}
*/
ngOnDestroy() {
this._destroyed.next();
this._destroyed.complete();
this.destroyMenuSurface();
this._menuFoundation.destroy();
}
/**
* @param {?} evt
* @return {?}
*/
_handleKeydown(evt) {
this._menuFoundation.handleKeydown(evt);
}
/**
* @private
* @return {?}
*/
_initList() {
if (!this._list) {
return;
}
this._list.setRole('menu');
this._list.wrapFocus = this._wrapFocus;
this._list.setTabIndex(-1);
// When the list items change, re-subscribe
this._list.items.changes.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @return {?}
*/
() => (/** @type {?} */ (this._list)).items.forEach((/**
* @param {?} item
* @return {?}
*/
item => item.setRole('menuitem')))));
(/** @type {?} */ (this._list)).actionEvent.pipe(takeUntil(this._destroyed))
.subscribe((/**
* @param {?} event
* @return {?}
*/
(event) => this._menuFoundation.handleItemAction((/** @type {?} */ (this._list)).items.toArray()[event.index].getListItemElement())));
}
}
MdcMenu.decorators = [
{ type: Component, args: [{selector: 'mdc-menu',
exportAs: 'mdcMenu',
host: {
'[id]': 'id',
'class': 'mdc-menu mdc-menu-surface',
'(keydown)': '_handleKeydown($event)',
},
template: '<ng-content></ng-content>',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush
},] },
];
MdcMenu.propDecorators = {
id: [{ type: Input }],
wrapFocus: [{ type: Input }],
closeSurfaceOnSelection: [{ type: Input }],
defaultFocusState: [{ type: Input }],
selected: [{ type: Output }],
_list: [{ type: ContentChild, args: [MdcList, { static: false },] }]
};
/**
* @fileoverview added by tsickle
* Generated from: menu/menu-directives.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class MdcMenuSelectionGroup {
/**
* @param {?} elementRef
*/
constructor(elementRef) {
this.elementRef = elementRef;
}
}
MdcMenuSelectionGroup.decorators = [
{ type: Directive, args: [{
selector: '[mdcMenuSelectionGroup], mdc-menu-selection-group',
host: { 'class': 'mdc-menu__selection-group' },
exportAs: 'mdcMenuSelectionGroup'
},] },
];
/** @nocollapse */
MdcMenuSelectionGroup.ctorParameters = () => [
{ type: ElementRef }
];
class MdcMenuSelectionGroupIcon {
/**
* @param {?} elementRef
*/
constructor(elementRef) {
this.elementRef = elementRef;
}
}
MdcMenuSelectionGroupIcon.decorators = [
{ type: Directive, args: [{
selector: '[mdcMenuSelectionGroupIcon], mdc-menu-selection-group-icon',
host: { 'class': 'mdc-menu__selection-group-icon' },
exportAs: 'mdcMenuSelectionGroupIcon'
},] },
];
/** @nocollapse */
MdcMenuSelectionGroupIcon.ctorParameters = () => [
{ type: ElementRef }
];
/**
* @fileoverview added by tsickle
* Generated from: menu/module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @type {?} */
const MENU_DECLARATIONS = [
MdcMenu,
MdcMenuSelectionGroup,
MdcMenuSelectionGroupIcon
];
class MdcMenuModule {
}
MdcMenuModule.decorators = [
{ type: NgModule, args: [{
imports: [MdcMenuSurfaceModule],
exports: [
...MENU_DECLARATIONS,
MdcMenuSurfaceModule
],
declarations: [MENU_DECLARATIONS]
},] },
];
export { MdcMenu, MdcMenuModule, MdcMenuSelectedEvent, MdcMenuSelectionGroup, MdcMenuSelectionGroupIcon };
//# sourceMappingURL=menu.js.map