igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,119 lines • 90 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, ContentChild, ElementRef, EventEmitter, HostBinding, Inject, Input, Optional, Output, Renderer, ViewChild } from '@angular/core';
import { fromEvent, interval } from 'rxjs';
import { debounce } from 'rxjs/operators';
import { IgxNavigationService } from '../core/navigation';
import { HammerGesturesManager } from '../core/touch';
import { IgxNavDrawerMiniTemplateDirective, IgxNavDrawerTemplateDirective } from './navigation-drawer.directives';
/** @type {?} */
let NEXT_ID = 0;
/**
* **Ignite UI for Angular Navigation Drawer** -
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/navdrawer.html)
*
* The Ignite UI Navigation Drawer is a collapsible side navigation container commonly used in combination with the Navbar.
*
* Example:
* ```html
* <igx-nav-drawer id="navigation" [isOpen]="true">
* <ng-template igxDrawer>
* <nav>
* <span igxDrawerItem [isHeader]="true">Email</span>
* <span igxDrawerItem igxRipple>Inbox</span>
* <span igxDrawerItem igxRipple>Deleted</span>
* <span igxDrawerItem igxRipple>Sent</span>
* </nav>
* </ng-template>
* </igx-nav-drawer>
* ```
*/
export class IgxNavigationDrawerComponent {
/**
* @param {?} elementRef
* @param {?} _state
* @param {?} renderer
* @param {?} _touchManager
*/
constructor(elementRef, _state, renderer, _touchManager) {
this.elementRef = elementRef;
this._state = _state;
this.renderer = renderer;
this._touchManager = _touchManager;
this.cssClass = 'igx-nav-drawer';
/**
* ID of the component
*
* ```typescript
* // get
* let myNavDrawerId = this.navdrawer.id;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer id='navdrawer'></igx-nav-drawer>
* ```
*/
this.id = `igx-nav-drawer-${NEXT_ID++}`;
/**
* Position of the Navigation Drawer. Can be "left"(default) or "right".
*
* ```typescript
* // get
* let myNavDrawerPosition = this.navdrawer.position;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [position]="'left'"></igx-nav-drawer>
* ```
*/
this.position = 'left';
/**
* Enables the use of touch gestures to manipulate the drawer:
* - swipe/pan from edge to open, swipe-toggle and pan-drag.
*
* ```typescript
* // get
* let gesturesEnabled = this.navdrawer.enableGestures;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [enableGestures]='true'></igx-nav-drawer>
* ```
*/
this.enableGestures = true;
/**
* State of the drawer.
*
* ```typescript
* // get
* let navDrawerIsOpen = this.navdrawer.isOpen;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [isOpen]='false'></igx-nav-drawer>
* ```
*/
this.isOpen = false;
/**
* When pinned the drawer is relatively positioned instead of sitting above content.
* May require additional layout styling.
*
* ```typescript
* // get
* let navDrawerIsPinned = this.navdrawer.pin;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [pin]='false'></igx-nav-drawer>
* ```
*/
this.pin = false;
/**
* Minimum device width required for automatic pin to be toggled.
* Default is 1024, can be set to a falsy value to disable this behavior.
*
* ```typescript
* // get
* let navDrawerPinTreshold = this.navdrawer.pinThreshold;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [pinTreshold]='1024'></igx-nav-drawer>
* ```
*/
this.pinThreshold = 1024;
/**
* Width of the drawer in its open state. Defaults to "280px".
*
* ```typescript
* // get
* let navDrawerWidth = this.navdrawer.width;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [width]="'228px'"></igx-nav-drawer>
* ```
*/
this.width = '280px';
/**
* Width of the drawer in its mini state. Defaults to 60px.
*
* ```typescript
* // get
* let navDrawerMiniWidth = this.navdrawer.miniWidth;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [miniWidth]="'34px'"></igx-nav-drawer>
* ```
*/
this.miniWidth = '60px';
/**
* Pinned state change output for two-way binding.
*
* ```html
* <igx-nav-drawer [(pin)]='isPinned'></igx-nav-drawer>
* ```
*/
this.pinChange = new EventEmitter(true);
/**
* Event fired as the Navigation Drawer is about to open.
*
* ```html
* <igx-nav-drawer (opening)='onOpening()'></igx-nav-drawer>
* ```
*/
this.opening = new EventEmitter();
/**
* Event fired when the Navigation Drawer has opened.
*
* ```html
* <igx-nav-drawer (opened)='onOpened()'></igx-nav-drawer>
* ```
*/
this.opened = new EventEmitter();
/**
* Event fired as the Navigation Drawer is about to close.
*
* ```html
* <igx-nav-drawer (closing)='onClosing()'></igx-nav-drawer>
* ```
*/
this.closing = new EventEmitter();
/**
* Event fired when the Navigation Drawer has closed.
*
* ```html
* <igx-nav-drawer (closed)='onClosed()'></igx-nav-drawer>
* ```
*/
this.closed = new EventEmitter();
this._gesturesAttached = false;
this._widthCache = { width: null, miniWidth: null, windowWidth: null };
this.css = {
drawer: 'igx-nav-drawer__aside',
mini: 'igx-nav-drawer__aside--mini',
overlay: 'igx-nav-drawer__overlay',
styleDummy: 'igx-nav-drawer__style-dummy'
};
/**
* Pan animation properties
*/
this._panning = false;
this._maxEdgeZone = 50;
this.checkPinThreshold = (evt) => {
/** @type {?} */
let windowWidth;
if (this.pinThreshold) {
windowWidth = this.getWindowWidth();
if (evt && this._widthCache.windowWidth === windowWidth) {
return;
}
this._widthCache.windowWidth = windowWidth;
if (!this.pin && windowWidth >= this.pinThreshold) {
this.pin = true;
this.pinChange.emit(true);
}
else if (this.pin && windowWidth < this.pinThreshold) {
this.pin = false;
this.pinChange.emit(false);
}
}
};
this.swipe = (evt) => {
// TODO: Could also force input type: http://stackoverflow.com/a/27108052
if (!this.enableGestures || evt.pointerType !== 'touch') {
return;
}
// HammerJS swipe is horizontal-only by default, don't check deltaY
/** @type {?} */
let deltaX;
/** @type {?} */
let startPosition;
if (this.position === 'right') {
// when on the right use inverse of deltaX
deltaX = -evt.deltaX;
startPosition = this.getWindowWidth() - (evt.center.x + evt.distance);
}
else {
deltaX = evt.deltaX;
startPosition = evt.center.x - evt.distance;
}
// only accept closing swipe (ignoring minEdgeZone) when the drawer is expanded:
if ((this.isOpen && deltaX < 0) ||
// positive deltaX from the edge:
(deltaX > 0 && startPosition < this.maxEdgeZone)) {
this.toggle();
}
};
this.panstart = (evt) => {
if (!this.enableGestures || this.pin || evt.pointerType !== 'touch') {
return;
}
/** @type {?} */
const startPosition = this.position === 'right' ? this.getWindowWidth() - (evt.center.x + evt.distance)
: evt.center.x - evt.distance;
// cache width during animation, flag to allow further handling
if (this.isOpen || (startPosition < this.maxEdgeZone)) {
this._panning = true;
this._panStartWidth = this.getExpectedWidth(!this.isOpen);
this._panLimit = this.getExpectedWidth(this.isOpen);
this.renderer.setElementClass(this.overlay, 'panning', true);
this.renderer.setElementClass(this.drawer, 'panning', true);
}
};
this.pan = (evt) => {
// TODO: input.deltaX = prevDelta.x + (center.x - offset.x);
// get actual delta (not total session one) from event?
// pan WILL also fire after a full swipe, only resize on flag
if (!this._panning) {
return;
}
/** @type {?} */
const right = this.position === 'right';
// when on the right use inverse of deltaX
/** @type {?} */
const deltaX = right ? -evt.deltaX : evt.deltaX;
/** @type {?} */
let visibleWidth;
/** @type {?} */
let newX;
/** @type {?} */
let percent;
visibleWidth = this._panStartWidth + deltaX;
if (this.isOpen && deltaX < 0) {
// when visibleWidth hits limit - stop animating
if (visibleWidth <= this._panLimit) {
return;
}
if (this.hasAnimateWidth) {
percent = (visibleWidth - this._panLimit) / (this._panStartWidth - this._panLimit);
newX = visibleWidth;
}
else {
percent = visibleWidth / this._panStartWidth;
newX = evt.deltaX;
}
this.setXSize(newX, percent.toPrecision(2));
}
else if (!this.isOpen && deltaX > 0) {
// when visibleWidth hits limit - stop animating
if (visibleWidth >= this._panLimit) {
return;
}
if (this.hasAnimateWidth) {
percent = (visibleWidth - this._panStartWidth) / (this._panLimit - this._panStartWidth);
newX = visibleWidth;
}
else {
percent = visibleWidth / this._panLimit;
newX = (this._panLimit - visibleWidth) * (right ? 1 : -1);
}
this.setXSize(newX, percent.toPrecision(2));
}
};
this.panEnd = (evt) => {
if (this._panning) {
/** @type {?} */
const deltaX = this.position === 'right' ? -evt.deltaX : evt.deltaX;
/** @type {?} */
const visibleWidth = this._panStartWidth + deltaX;
this.resetPan();
// check if pan brought the drawer to 50%
if (this.isOpen && visibleWidth <= this._panStartWidth / 2) {
this.close();
}
else if (!this.isOpen && visibleWidth >= this._panLimit / 2) {
this.open();
}
this._panStartWidth = null;
}
};
this.toggleOpenedEvent = (evt) => {
this.elementRef.nativeElement.removeEventListener('transitionend', this.toggleOpenedEvent, false);
this.opened.emit();
};
this.toggleClosedEvent = (evt) => {
this.elementRef.nativeElement.removeEventListener('transitionend', this.toggleClosedEvent, false);
this.closed.emit();
};
}
/**
* Returns nativeElement of the component.
*
* @hidden
* @return {?}
*/
get element() {
return this.elementRef.nativeElement;
}
/**
* @hidden
* @return {?}
*/
get template() {
if (this.miniTemplate && !this.isOpen) {
return this.miniTemplate.template;
}
else if (this.contentTemplate) {
return this.contentTemplate.template;
}
}
/**
* @hidden
* @return {?}
*/
get miniTemplate() {
return this._miniTemplate;
}
/**
* @hidden
* @param {?} v
* @return {?}
*/
set miniTemplate(v) {
if (!this.isOpen) {
this.setDrawerWidth(v ? this.miniWidth : '');
}
this._miniTemplate = v;
}
/**
* @hidden
* @return {?}
*/
get flexWidth() {
if (!this.pin) {
return '0px';
}
if (this.isOpen) {
return this.width;
}
if (this.miniTemplate && this.miniWidth) {
return this.miniWidth;
}
return '0px';
}
/**
* @hidden
* @return {?}
*/
get isPinnedRight() {
return this.pin && this.position === 'right' ? '1' : '0';
}
/**
* @hidden
* @return {?}
*/
get drawer() {
return this._drawer.nativeElement;
}
/**
* @hidden
* @return {?}
*/
get overlay() {
return this._overlay.nativeElement;
}
/**
* @hidden
* @return {?}
*/
get styleDummy() {
return this._styleDummy.nativeElement;
}
/**
* Property to decide whether to change width or translate the drawer from pan gesture.
*
* @hidden
* @return {?}
*/
get hasAnimateWidth() {
return this.pin || !!this.miniTemplate;
}
/**
* Used for touch gestures (swipe and pan).
* Defaults to 50 (in px) and is extended to at least 110% of the mini template width if available.
*
* @hidden
* @return {?}
*/
get maxEdgeZone() {
return this._maxEdgeZone;
}
/**
* Gets the Drawer width for specific state.
* Will attempt to evaluate requested state and cache.
*
*
* @hidden
* @return {?}
*/
get expectedWidth() {
return this.getExpectedWidth(false);
}
/**
* Get the Drawer mini width for specific state.
* Will attempt to evaluate requested state and cache.
*
* @hidden
* @return {?}
*/
get expectedMiniWidth() {
return this.getExpectedWidth(true);
}
/**
* @hidden
* @return {?}
*/
get touchManager() {
return this._touchManager;
}
/**
* Exposes optional navigation service
*
* @hidden
* @return {?}
*/
get state() {
return this._state;
}
/**
* @hidden
* @return {?}
*/
ngOnInit() {
// DOM and @Input()-s initialized
if (this._state) {
this._state.add(this.id, this);
}
if (this.isOpen) {
this.setDrawerWidth(this.width);
}
}
/**
* @hidden
* @return {?}
*/
ngAfterContentInit() {
// wait for template and ng-content to be ready
this.updateEdgeZone();
this.checkPinThreshold();
this.ensureEvents();
// TODO: apply platform-safe Ruler from http://plnkr.co/edit/81nWDyreYMzkunihfRgX?p=preview
// (https://github.com/angular/angular/issues/6515), blocked by https://github.com/angular/angular/issues/6904
}
/**
* @hidden
* @return {?}
*/
ngOnDestroy() {
this._touchManager.destroy();
if (this._state) {
this._state.remove(this.id);
}
if (this._resizeObserver) {
this._resizeObserver.unsubscribe();
}
}
/**
* @hidden
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
// simple settings can come from attribute set (rather than binding), make sure boolean props are converted
if (changes.enableGestures && changes.enableGestures.currentValue !== undefined) {
this.enableGestures = !!(this.enableGestures && this.enableGestures.toString() === 'true');
this.ensureEvents();
}
if (changes.pin && changes.pin.currentValue !== undefined) {
this.pin = !!(this.pin && this.pin.toString() === 'true');
if (this.pin) {
this._touchManager.destroy();
this._gesturesAttached = false;
}
else {
this.ensureEvents();
}
}
if (changes.pinThreshold) {
if (this.pinThreshold) {
this.ensureEvents();
this.checkPinThreshold();
}
}
if (changes.width && this.isOpen) {
this.setDrawerWidth(changes.width.currentValue);
}
if (changes.miniWidth) {
if (!this.isOpen) {
this.setDrawerWidth(changes.miniWidth.currentValue);
}
this.updateEdgeZone();
}
}
/**
* Toggle the open state of the Navigation Drawer.
*
* ```typescript
* this.navdrawer.toggle();
* ```
* @return {?}
*/
toggle() {
if (this.isOpen) {
this.close();
}
else {
this.open();
}
}
/**
* Open the Navigation Drawer. Has no effect if already opened.
*
* ```typescript
* this.navdrawer.open();
* ```
* @return {?}
*/
open() {
if (this._panning) {
this.resetPan();
}
if (this.isOpen) {
return;
}
this.opening.emit();
this.isOpen = true;
// TODO: Switch to animate API when available
// var animationCss = this.animate.css();
// animationCss
// .setStyles({'width':'50px'}, {'width':'400px'})
// .start(this.elementRef.nativeElement)
// .onComplete(() => animationCss.setToStyles({'width':'auto'}).start(this.elementRef.nativeElement));
this.elementRef.nativeElement.addEventListener('transitionend', this.toggleOpenedEvent, false);
this.setDrawerWidth(this.width);
}
/**
* Close the Navigation Drawer. Has no effect if already closed.
*
* ```typescript
* this.navdrawer.close();
* ```
* @return {?}
*/
close() {
if (this._panning) {
this.resetPan();
}
if (!this.isOpen) {
return;
}
this.closing.emit();
this.isOpen = false;
this.setDrawerWidth(this.miniTemplate ? this.miniWidth : '');
this.elementRef.nativeElement.addEventListener('transitionend', this.toggleClosedEvent, false);
}
/**
* @hidden
* @protected
* @param {?} value
* @return {?}
*/
set_maxEdgeZone(value) {
this._maxEdgeZone = value;
}
/**
* Get the Drawer width for specific state. Will attempt to evaluate requested state and cache.
*
* @hidden
* @protected
* @param {?=} mini
* @return {?}
*/
getExpectedWidth(mini) {
if (mini) {
if (!this.miniTemplate) {
return 0;
}
if (this.miniWidth) {
return parseFloat(this.miniWidth);
}
else {
// if (!this.isOpen) { // This WON'T work due to transition timings...
// return this.elementRef.nativeElement.children[1].offsetWidth;
// } else {
if (this._widthCache.miniWidth === null) {
// force class for width calc. TODO?
this.renderer.setElementClass(this.styleDummy, this.css.drawer, true);
this.renderer.setElementClass(this.styleDummy, this.css.mini, true);
this._widthCache.miniWidth = this.styleDummy.offsetWidth;
this.renderer.setElementClass(this.styleDummy, this.css.drawer, false);
this.renderer.setElementClass(this.styleDummy, this.css.mini, false);
}
return this._widthCache.miniWidth;
}
}
else {
if (this.width) {
return parseFloat(this.width);
}
else {
if (this._widthCache.width === null) {
// force class for width calc. TODO?
this.renderer.setElementClass(this.styleDummy, this.css.drawer, true);
this._widthCache.width = this.styleDummy.offsetWidth;
this.renderer.setElementClass(this.styleDummy, this.css.drawer, false);
}
return this._widthCache.width;
}
}
}
/**
* @private
* @return {?}
*/
getWindowWidth() {
return (window.innerWidth > 0) ? window.innerWidth : screen.width;
}
/**
* Sets the drawer width.
* @private
* @param {?} width
* @return {?}
*/
setDrawerWidth(width) {
window.requestAnimationFrame(() => {
if (this.drawer) {
this.renderer.setElementStyle(this.drawer, 'width', width);
}
});
}
/**
* Get current Drawer width.
* @private
* @return {?}
*/
getDrawerWidth() {
return this.drawer.offsetWidth;
}
/**
* @private
* @return {?}
*/
ensureEvents() {
// set listeners for swipe/pan only if needed, but just once
if (this.enableGestures && !this.pin && !this._gesturesAttached) {
// Built-in manager handler(L20887) causes endless loop and max stack exception.
// https://github.com/angular/angular/issues/6993
// Use ours for now (until beta.10):
// this.renderer.listen(document, "swipe", this.swipe);
this._touchManager.addGlobalEventListener('document', 'swipe', this.swipe);
this._gesturesAttached = true;
// this.renderer.listen(document, "panstart", this.panstart);
// this.renderer.listen(document, "pan", this.pan);
this._touchManager.addGlobalEventListener('document', 'panstart', this.panstart);
this._touchManager.addGlobalEventListener('document', 'panmove', this.pan);
this._touchManager.addGlobalEventListener('document', 'panend', this.panEnd);
}
if (!this._resizeObserver) {
this._resizeObserver = fromEvent(window, 'resize').pipe(debounce(() => interval(150)))
.subscribe((value) => {
this.checkPinThreshold(value);
});
}
}
/**
* @private
* @return {?}
*/
updateEdgeZone() {
/** @type {?} */
let maxValue;
if (this.miniTemplate) {
maxValue = Math.max(this._maxEdgeZone, this.getExpectedWidth(true) * 1.1);
this.set_maxEdgeZone(maxValue);
}
}
/**
* @private
* @return {?}
*/
resetPan() {
this._panning = false;
/* styles fail to apply when set on parent due to extra attributes, prob ng bug */
this.renderer.setElementClass(this.overlay, 'panning', false);
this.renderer.setElementClass(this.drawer, 'panning', false);
this.setXSize(0, '');
}
/**
* Sets the absolute position or width in case the drawer doesn't change position.
* @private
* @param {?} x the number pixels to translate on the X axis or the width to set. 0 width will clear the style instead.
* @param {?=} opacity optional value to apply to the overlay
* @return {?}
*/
setXSize(x, opacity) {
// Angular polyfills patches window.requestAnimationFrame, but switch to DomAdapter API (TODO)
window.requestAnimationFrame(() => {
if (this.hasAnimateWidth) {
this.renderer.setElementStyle(this.drawer, 'width', x ? Math.abs(x) + 'px' : '');
}
else {
this.renderer.setElementStyle(this.drawer, 'transform', x ? 'translate3d(' + x + 'px,0,0)' : '');
this.renderer.setElementStyle(this.drawer, '-webkit-transform', x ? 'translate3d(' + x + 'px,0,0)' : '');
}
if (opacity !== undefined) {
this.renderer.setElementStyle(this.overlay, 'opacity', opacity);
}
});
}
}
IgxNavigationDrawerComponent.decorators = [
{ type: Component, args: [{
providers: [HammerGesturesManager],
selector: 'igx-nav-drawer',
template: "<ng-template #defaultItemsTemplate>\n <div igxDrawerItem [isHeader]=\"true\">Navigation Drawer</div>\n <div igxDrawerItem> Start by adding</div>\n <div igxDrawerItem> <code><ng-template igxDrawer></code> </div>\n <div igxDrawerItem> And some items inside </div>\n <div igxDrawerItem> Style with igxDrawerItem </div>\n <div igxDrawerItem> and igxRipple directives</div>\n</ng-template>\n\n<div [hidden]=\"pin\"\n class=\"igx-nav-drawer__overlay\"\n [class.igx-nav-drawer__overlay--hidden]=\"!isOpen\"\n (click)=\"close()\" #overlay>\n</div>\n<aside role=\"navigation\"\n class=\"igx-nav-drawer__aside\"\n [class.igx-nav-drawer__aside--collapsed]=\"!miniTemplate && !isOpen\"\n [class.igx-nav-drawer__aside--mini]=\"miniTemplate && !isOpen\"\n [class.igx-nav-drawer__aside--normal]=\"!miniTemplate || isOpen\"\n [class.igx-nav-drawer__aside--pinned]=\"pin\"\n [class.igx-nav-drawer__aside--right]=\"position == 'right'\" #aside>\n\n <ng-container *ngTemplateOutlet=\"template || defaultItemsTemplate\"></ng-container>\n</aside>\n<div class=\"igx-nav-drawer__style-dummy\" #dummy></div>\n",
styles: [`
:host {
display: block;
height: 100%;
}
`]
}] }
];
/** @nocollapse */
IgxNavigationDrawerComponent.ctorParameters = () => [
{ type: ElementRef, decorators: [{ type: Inject, args: [ElementRef,] }] },
{ type: IgxNavigationService, decorators: [{ type: Optional }] },
{ type: Renderer },
{ type: HammerGesturesManager }
];
IgxNavigationDrawerComponent.propDecorators = {
cssClass: [{ type: HostBinding, args: ['class',] }],
id: [{ type: HostBinding, args: ['attr.id',] }, { type: Input }],
position: [{ type: Input }],
enableGestures: [{ type: Input }],
isOpen: [{ type: Input }],
pin: [{ type: Input }],
pinThreshold: [{ type: Input }],
width: [{ type: Input }],
miniWidth: [{ type: Input }],
pinChange: [{ type: Output }],
opening: [{ type: Output }],
opened: [{ type: Output }],
closing: [{ type: Output }],
closed: [{ type: Output }],
miniTemplate: [{ type: ContentChild, args: [IgxNavDrawerMiniTemplateDirective, { read: IgxNavDrawerMiniTemplateDirective },] }],
contentTemplate: [{ type: ContentChild, args: [IgxNavDrawerTemplateDirective, { read: IgxNavDrawerTemplateDirective },] }],
flexWidth: [{ type: HostBinding, args: ['style.flexBasis',] }],
isPinnedRight: [{ type: HostBinding, args: ['style.order',] }],
_drawer: [{ type: ViewChild, args: ['aside',] }],
_overlay: [{ type: ViewChild, args: ['overlay',] }],
_styleDummy: [{ type: ViewChild, args: ['dummy',] }]
};
if (false) {
/** @type {?} */
IgxNavigationDrawerComponent.prototype.cssClass;
/**
* ID of the component
*
* ```typescript
* // get
* let myNavDrawerId = this.navdrawer.id;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer id='navdrawer'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.id;
/**
* Position of the Navigation Drawer. Can be "left"(default) or "right".
*
* ```typescript
* // get
* let myNavDrawerPosition = this.navdrawer.position;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [position]="'left'"></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.position;
/**
* Enables the use of touch gestures to manipulate the drawer:
* - swipe/pan from edge to open, swipe-toggle and pan-drag.
*
* ```typescript
* // get
* let gesturesEnabled = this.navdrawer.enableGestures;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [enableGestures]='true'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.enableGestures;
/**
* State of the drawer.
*
* ```typescript
* // get
* let navDrawerIsOpen = this.navdrawer.isOpen;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [isOpen]='false'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.isOpen;
/**
* When pinned the drawer is relatively positioned instead of sitting above content.
* May require additional layout styling.
*
* ```typescript
* // get
* let navDrawerIsPinned = this.navdrawer.pin;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [pin]='false'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.pin;
/**
* Minimum device width required for automatic pin to be toggled.
* Default is 1024, can be set to a falsy value to disable this behavior.
*
* ```typescript
* // get
* let navDrawerPinTreshold = this.navdrawer.pinThreshold;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [pinTreshold]='1024'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.pinThreshold;
/**
* Width of the drawer in its open state. Defaults to "280px".
*
* ```typescript
* // get
* let navDrawerWidth = this.navdrawer.width;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [width]="'228px'"></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.width;
/**
* Width of the drawer in its mini state. Defaults to 60px.
*
* ```typescript
* // get
* let navDrawerMiniWidth = this.navdrawer.miniWidth;
* ```
*
* ```html
* <!--set-->
* <igx-nav-drawer [miniWidth]="'34px'"></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.miniWidth;
/**
* Pinned state change output for two-way binding.
*
* ```html
* <igx-nav-drawer [(pin)]='isPinned'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.pinChange;
/**
* Event fired as the Navigation Drawer is about to open.
*
* ```html
* <igx-nav-drawer (opening)='onOpening()'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.opening;
/**
* Event fired when the Navigation Drawer has opened.
*
* ```html
* <igx-nav-drawer (opened)='onOpened()'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.opened;
/**
* Event fired as the Navigation Drawer is about to close.
*
* ```html
* <igx-nav-drawer (closing)='onClosing()'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.closing;
/**
* Event fired when the Navigation Drawer has closed.
*
* ```html
* <igx-nav-drawer (closed)='onClosed()'></igx-nav-drawer>
* ```
* @type {?}
*/
IgxNavigationDrawerComponent.prototype.closed;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._miniTemplate;
/**
* @hidden
* @type {?}
* @protected
*/
IgxNavigationDrawerComponent.prototype.contentTemplate;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._gesturesAttached;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._widthCache;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._resizeObserver;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.css;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._drawer;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._overlay;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._styleDummy;
/**
* Pan animation properties
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._panning;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._panStartWidth;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._panLimit;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._maxEdgeZone;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.checkPinThreshold;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.swipe;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.panstart;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.pan;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.panEnd;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.toggleOpenedEvent;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.toggleClosedEvent;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype.elementRef;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._state;
/**
* @type {?}
* @protected
*/
IgxNavigationDrawerComponent.prototype.renderer;
/**
* @type {?}
* @private
*/
IgxNavigationDrawerComponent.prototype._touchManager;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdGlvbi1kcmF3ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vaWduaXRldWktYW5ndWxhci8iLCJzb3VyY2VzIjpbImxpYi9uYXZpZ2F0aW9uLWRyYXdlci9uYXZpZ2F0aW9uLWRyYXdlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFFSCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLE1BQU0sRUFDTixLQUFLLEVBSUwsUUFBUSxFQUNSLE1BQU0sRUFDTixRQUFRLEVBR1IsU0FBUyxFQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN6RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUMsT0FBTyxFQUFFLG9CQUFvQixFQUFlLE1BQU0sb0JBQW9CLENBQUM7QUFDdkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSw2QkFBNkIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOztJQUU5RyxPQUFPLEdBQUcsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0NmLE1BQU0sT0FBTyw0QkFBNEI7Ozs7Ozs7SUFvVnJDLFlBQ2dDLFVBQXNCLEVBQzlCLE1BQTRCLEVBRXRDLFFBQWtCLEVBQ3BCLGFBQW9DO1FBSmhCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDOUIsV0FBTSxHQUFOLE1BQU0sQ0FBc0I7UUFFdEMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNwQixrQkFBYSxHQUFiLGFBQWEsQ0FBdUI7UUFsVm5CLGFBQVEsR0FBRyxnQkFBZ0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7UUFnQnpDLE9BQUUsR0FBRyxrQkFBa0IsT0FBTyxFQUFFLEVBQUUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7UUFl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