UNPKG

@angular-mdc/web

Version:
343 lines (338 loc) 11.5 kB
/** * @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