UNPKG

@angular-mdc/web

Version:
516 lines (510 loc) 15.9 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, Directive, ChangeDetectorRef, NgZone, Optional, ElementRef, Input, Output, Component, ViewEncapsulation, ChangeDetectionStrategy, NgModule } from '@angular/core'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { Platform } from '@angular/cdk/platform'; import { Subject, fromEvent } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { MDCComponent } from '@angular-mdc/web/base'; import { Corner, MDCMenuSurfaceFoundation, util } from '@material/menu-surface'; /** * @fileoverview added by tsickle * Generated from: menu-surface/menu-surface-base.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const ANCHOR_CORNER_MAP = { topEnd: Corner.TOP_END, topStart: Corner.TOP_START, bottomEnd: Corner.BOTTOM_END, bottomStart: Corner.BOTTOM_START }; /** * @abstract */ class MdcMenuSurfaceBase extends MDCComponent { /** * @param {?} changeDetectorRef * @param {?} platform * @param {?} _ngZone * @param {?} elementRef */ constructor(changeDetectorRef, platform, _ngZone, elementRef) { super(elementRef); this.changeDetectorRef = changeDetectorRef; this.platform = platform; this._ngZone = _ngZone; this.elementRef = elementRef; /** * Emits whenever the component is destroyed. */ this._destroy = new Subject(); this._open = false; this._anchorCorner = 'topStart'; this._quickOpen = false; this._fixed = false; this._coordinates = { x: 0, y: 0 }; this._anchorMargin = {}; this._hoistToBody = false; /** * Emits an event whenever the menu surface is opened. */ this.opened = new EventEmitter(); /** * Emits an event whenever the menu surface is closed. */ this.closed = new EventEmitter(); /** * Subscription to interaction events in menu-surface. */ this._windowClickSubscription = null; } /** * @return {?} */ get open() { return this._open; } /** * @param {?} value * @return {?} */ set open(value) { /** @type {?} */ const newValue = coerceBooleanProperty(value); if (newValue !== this._open) { this._open = coerceBooleanProperty(value); if (this._open) { this._foundation.open(); } else { this._foundation.close(); } } } /** * @return {?} */ get anchorElement() { return this._anchorElement; } /** * @param {?} element * @return {?} */ set anchorElement(element) { this._anchorElement = element; } /** * @return {?} */ get anchorCorner() { return this._anchorCorner; } /** * @param {?} value * @return {?} */ set anchorCorner(value) { this._anchorCorner = (value !== null && value !== void 0 ? value : 'topStart'); this._foundation.setAnchorCorner(ANCHOR_CORNER_MAP[this._anchorCorner]); } /** * @return {?} */ get quickOpen() { return this._quickOpen; } /** * @param {?} value * @return {?} */ set quickOpen(value) { this._quickOpen = coerceBooleanProperty(value); this._foundation.setQuickOpen(this._quickOpen); } /** * @return {?} */ get fixed() { return this._fixed; } /** * @param {?} value * @return {?} */ set fixed(value) { this._fixed = coerceBooleanProperty(value); if (this._fixed) { this._getHostElement().classList.add('mdc-menu-surface--fixed'); } else { this._getHostElement().classList.remove('mdc-menu-surface--fixed'); } this._foundation.setFixedPosition(this._fixed); } /** * @return {?} */ get coordinates() { return this._coordinates; } /** * @param {?} value * @return {?} */ set coordinates(value) { this._coordinates = value; this._foundation.setAbsolutePosition(value.x, value.y); } /** * @return {?} */ get anchorMargin() { return this._anchorMargin; } /** * @param {?} value * @return {?} */ set anchorMargin(value) { this._anchorMargin = value; this._foundation.setAnchorMargin(this._anchorMargin); } /** * @return {?} */ get hoistToBody() { return this._hoistToBody; } /** * @param {?} value * @return {?} */ set hoistToBody(value) { this._hoistToBody = coerceBooleanProperty(value); if (this._hoistToBody) { this.setHoistToBody(); } } /** * @return {?} */ getDefaultFoundation() { /** @type {?} */ const adapter = { addClass: (/** * @param {?} className * @return {?} */ (className) => this._getHostElement().classList.add(className)), removeClass: (/** * @param {?} className * @return {?} */ (className) => this._getHostElement().classList.remove(className)), hasClass: (/** * @param {?} className * @return {?} */ (className) => this._getHostElement().classList.contains(className)), hasAnchor: (/** * @return {?} */ () => !!this.anchorElement), notifyClose: (/** * @return {?} */ () => { this.closed.emit(); this._deregisterWindowClickListener(); }), notifyOpen: (/** * @return {?} */ () => { this.opened.emit(); this._registerWindowClickListener(); }), isElementInContainer: (/** * @param {?} el * @return {?} */ (el) => this._getHostElement() === el || this._getHostElement().contains(el)), isRtl: (/** * @return {?} */ () => this.platform.isBrowser ? window.getComputedStyle(this._getHostElement()).getPropertyValue('direction') === 'rtl' : false), setTransformOrigin: (/** * @param {?} origin * @return {?} */ (origin) => this.platform.isBrowser ? this._getHostElement().style[(/** @type {?} */ (`${util.getTransformPropertyName(window)}-origin`))] = origin : false), isFocused: (/** * @return {?} */ () => { var _a, _b; return _b = ((_a = document) === null || _a === void 0 ? void 0 : _a.activeElement) === this._getHostElement(), (_b !== null && _b !== void 0 ? _b : false); }), saveFocus: (/** * @return {?} */ () => { var _a, _b; return this._previousFocus = (_b = (_a = document) === null || _a === void 0 ? void 0 : _a.activeElement, (_b !== null && _b !== void 0 ? _b : undefined)); }), restoreFocus: (/** * @return {?} */ () => { var _a; if (this.platform.isBrowser) { if (this._getHostElement().contains(document.activeElement)) { (_a = ((/** @type {?} */ (this._previousFocus)))) === null || _a === void 0 ? void 0 : _a.focus(); } } }), getInnerDimensions: (/** * @return {?} */ () => ({ width: this._getHostElement().offsetWidth, height: this._getHostElement().offsetHeight })), getAnchorDimensions: (/** * @return {?} */ () => this.platform.isBrowser || !this.anchorElement ? (/** @type {?} */ (this._anchorElement)).getBoundingClientRect() : { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 }), getWindowDimensions: (/** * @return {?} */ () => ({ width: this.platform.isBrowser ? window.innerWidth : 0, height: this.platform.isBrowser ? window.innerHeight : 0 })), getBodyDimensions: (/** * @return {?} */ () => ({ width: this.platform.isBrowser ? (/** @type {?} */ (document.body)).clientWidth : 0, height: this.platform.isBrowser ? (/** @type {?} */ (document.body)).clientHeight : 0 })), getWindowScroll: (/** * @return {?} */ () => ({ x: this.platform.isBrowser ? window.pageXOffset : 0, y: this.platform.isBrowser ? window.pageYOffset : 0 })), setPosition: (/** * @param {?} position * @return {?} */ (position) => { this._getHostElement().style.left = 'left' in position ? `${position.left}px` : ''; this._getHostElement().style.right = 'right' in position ? `${position.right}px` : ''; this._getHostElement().style.top = 'top' in position ? `${position.top}px` : ''; this._getHostElement().style.bottom = 'bottom' in position ? `${position.bottom}px` : ''; }), setMaxHeight: (/** * @param {?} height * @return {?} */ (height) => this._getHostElement().style.maxHeight = height) }; return new MDCMenuSurfaceFoundation(adapter); } /** * @protected * @return {?} */ initMenuSurface() { var _a; this._foundation.init(); this.anchorElement = (_a = this._getHostElement().parentElement, (_a !== null && _a !== void 0 ? _a : this.anchorElement)); this._registerKeydownListener(); } /** * @protected * @return {?} */ destroyMenuSurface() { this._destroy.next(); this._destroy.complete(); this._deregisterWindowClickListener(); // add platform check due to use of cancelAnimationFrame inside destroy() if (this.platform.isBrowser) { this._foundation.destroy(); } if (this.hoistToBody) { (/** @type {?} */ (document.body)).removeChild(this._getHostElement()); } } /** * Removes the menu-surface from it's current location and appends it to the * body to overcome any overflow:hidden issues. * @protected * @return {?} */ setHoistToBody() { if (!this.platform.isBrowser) { return; } /** @type {?} */ const parentEl = this._getHostElement().parentElement; if (parentEl) { (/** @type {?} */ (document.body)).appendChild(parentEl.removeChild(this._getHostElement())); this._foundation.setIsHoisted(true); } } /** * @private * @return {?} */ _registerKeydownListener() { fromEvent(this._getHostElement(), 'keydown') .pipe(takeUntil(this._destroy)) .subscribe((/** * @param {?} evt * @return {?} */ evt => { this._foundation.handleKeydown(evt); this._open = this._foundation.isOpen(); })); } /** * @private * @return {?} */ _registerWindowClickListener() { if (!this.platform.isBrowser) { return; } this._windowClickSubscription = this._ngZone.runOutsideAngular((/** * @return {?} */ () => fromEvent(window, 'click') .subscribe((/** * @param {?} evt * @return {?} */ evt => this._ngZone.run((/** * @return {?} */ () => { this._foundation.handleBodyClick(evt); this._open = this._foundation.isOpen(); })))))); } /** * @private * @return {?} */ _deregisterWindowClickListener() { var _a; (_a = this._windowClickSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe(); } /** * Retrieves the DOM element of the component host. * @protected * @return {?} */ _getHostElement() { return this.elementRef.nativeElement; } } MdcMenuSurfaceBase.decorators = [ { type: Directive }, ]; /** @nocollapse */ MdcMenuSurfaceBase.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: Platform }, { type: NgZone, decorators: [{ type: Optional }] }, { type: ElementRef } ]; MdcMenuSurfaceBase.propDecorators = { open: [{ type: Input }], anchorElement: [{ type: Input }], anchorCorner: [{ type: Input }], quickOpen: [{ type: Input }], fixed: [{ type: Input }], coordinates: [{ type: Input }], anchorMargin: [{ type: Input }], hoistToBody: [{ type: Input }], opened: [{ type: Output }], closed: [{ type: Output }] }; /** * @fileoverview added by tsickle * Generated from: menu-surface/menu-surface.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MdcMenuSurface extends MdcMenuSurfaceBase { /** * @return {?} */ ngOnInit() { this.initMenuSurface(); } /** * @return {?} */ ngOnDestroy() { this.destroyMenuSurface(); } } MdcMenuSurface.decorators = [ { type: Component, args: [{selector: 'mdc-menu-surface', exportAs: 'mdcMenuSurface', host: { 'class': 'mdc-menu-surface' }, template: '<ng-content></ng-content>', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush },] }, ]; /** * @fileoverview added by tsickle * Generated from: menu-surface/menu-surface-anchor.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class MdcMenuSurfaceAnchor { /** * @param {?} elementRef */ constructor(elementRef) { this.elementRef = elementRef; } } MdcMenuSurfaceAnchor.decorators = [ { type: Directive, args: [{ selector: '[mdcMenuSurfaceAnchor], mdc-menu-surface-anchor', host: { 'class': 'mdc-menu-surface--anchor' } },] }, ]; /** @nocollapse */ MdcMenuSurfaceAnchor.ctorParameters = () => [ { type: ElementRef } ]; /** * @fileoverview added by tsickle * Generated from: menu-surface/module.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const MENU_SURFACE_DECLARATIONS = [ MdcMenuSurface, MdcMenuSurfaceAnchor ]; class MdcMenuSurfaceModule { } MdcMenuSurfaceModule.decorators = [ { type: NgModule, args: [{ exports: [MENU_SURFACE_DECLARATIONS], declarations: [MENU_SURFACE_DECLARATIONS] },] }, ]; export { MdcMenuSurface, MdcMenuSurfaceAnchor, MdcMenuSurfaceBase, MdcMenuSurfaceModule }; //# sourceMappingURL=menu-surface.js.map