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.
423 lines • 19.1 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { Component, Directive, Input, ElementRef, ViewContainerRef, NgZone, Optional, Renderer2, ChangeDetectorRef, ViewEncapsulation, } from '@angular/core';
import { style, trigger, state, transition, animate, } from '@angular/animations';
import { Overlay, OverlayState, ComponentPortal, } from '../core';
import { Subject } from 'rxjs/Subject';
import { Dir } from '../core/rtl/dir';
import { Platform } from '../core/platform/index';
import 'rxjs/add/operator/first';
import { ScrollDispatcher } from '../core/overlay/scroll/scroll-dispatcher';
import { coerceBooleanProperty } from '../core/coercion/boolean-property';
/** Time in ms to delay before changing the tooltip visibility to hidden */
export var TOUCHEND_HIDE_DELAY = 1500;
/** Time in ms to throttle repositioning after scroll events. */
export var SCROLL_THROTTLE_MS = 20;
/** Throws an error if the user supplied an invalid tooltip position. */
export function throwMd2TooltipInvalidPositionError(position) {
throw new Error("Tooltip position \"" + position + "\" is invalid.");
}
/**
* Directive that attaches a material design tooltip to the host element. Animates the showing and
* hiding of a tooltip provided position (defaults to below the element).
*
* https://material.google.com/components/tooltips.html
*/
var Md2Tooltip = (function () {
function Md2Tooltip(_overlay, _elementRef, _scrollDispatcher, _viewContainerRef, _ngZone, _renderer, _platform, _dir) {
var _this = this;
this._overlay = _overlay;
this._elementRef = _elementRef;
this._scrollDispatcher = _scrollDispatcher;
this._viewContainerRef = _viewContainerRef;
this._ngZone = _ngZone;
this._renderer = _renderer;
this._platform = _platform;
this._dir = _dir;
this._position = 'below';
this._disabled = false;
/** The default delay in ms before showing the tooltip after show is called */
this.showDelay = 0;
/** The default delay in ms before hiding the tooltip after hide is called */
this.hideDelay = 0;
// The mouse events shouldn't be bound on iOS devices, because
// they can prevent the first tap from firing its click event.
if (!_platform.IOS) {
_renderer.listen(_elementRef.nativeElement, 'mouseenter', function () { return _this.show(); });
_renderer.listen(_elementRef.nativeElement, 'mouseleave', function () { return _this.hide(); });
}
}
Object.defineProperty(Md2Tooltip.prototype, "position", {
/** Allows the user to define the position of the tooltip relative to the parent element */
get: function () { return this._position; },
set: function (value) {
if (value !== this._position) {
this._position = value;
// TODO(andrewjs): When the overlay's position can be dynamically changed, do not destroy
// the tooltip.
if (this._tooltipInstance) {
this._disposeTooltip();
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(Md2Tooltip.prototype, "disabled", {
/** Disables the display of the tooltip. */
get: function () { return this._disabled; },
set: function (value) {
this._disabled = coerceBooleanProperty(value);
// If tooltip is disabled, hide immediately.
if (this._disabled) {
this.hide(0);
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(Md2Tooltip.prototype, "message", {
/** The message to be displayed in the tooltip */
get: function () { return this._message; },
set: function (value) {
this._message = value;
if (this._tooltipInstance) {
this._setTooltipMessage(this._message);
}
},
enumerable: true,
configurable: true
});
/**
* Dispose the tooltip when destroyed.
*/
Md2Tooltip.prototype.ngOnDestroy = function () {
if (this._tooltipInstance) {
this._disposeTooltip();
}
};
/** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */
Md2Tooltip.prototype.show = function (delay) {
if (delay === void 0) { delay = this.showDelay; }
if (this.disabled || !this._message || !this._message.trim()) {
return;
}
if (!this._tooltipInstance) {
this._createTooltip();
}
this._setTooltipMessage(this._message);
this._tooltipInstance.show(this._position, delay);
};
/** Hides the tooltip after the delay in ms, defaults to tooltip-delay-hide or 0ms if no input */
Md2Tooltip.prototype.hide = function (delay) {
if (delay === void 0) { delay = this.hideDelay; }
if (this._tooltipInstance) {
this._tooltipInstance.hide(delay);
}
};
/** Shows/hides the tooltip */
Md2Tooltip.prototype.toggle = function () {
this._isTooltipVisible() ? this.hide() : this.show();
};
/** Returns true if the tooltip is currently visible to the user */
Md2Tooltip.prototype._isTooltipVisible = function () {
return !!this._tooltipInstance && this._tooltipInstance.isVisible();
};
/** Create the tooltip to display */
Md2Tooltip.prototype._createTooltip = function () {
var _this = this;
this._createOverlay();
var portal = new ComponentPortal(Md2TooltipComponent, this._viewContainerRef);
this._tooltipInstance = this._overlayRef.attach(portal).instance;
// Dispose the overlay when finished the shown tooltip.
this._tooltipInstance.afterHidden().subscribe(function () {
// Check first if the tooltip has already been removed through this components destroy.
if (_this._tooltipInstance) {
_this._disposeTooltip();
}
});
};
/** Create the overlay config and position strategy */
Md2Tooltip.prototype._createOverlay = function () {
var _this = this;
var origin = this._getOrigin();
var position = this._getOverlayPosition();
// Create connected position strategy that listens for scroll events to reposition.
// After position changes occur and the overlay is clipped by a parent scrollable then
// close the tooltip.
var strategy = this._overlay.position().connectedTo(this._elementRef, origin, position);
strategy.withScrollableContainers(this._scrollDispatcher.getScrollContainers(this._elementRef));
strategy.onPositionChange.subscribe(function (change) {
if (change.scrollableViewProperties.isOverlayClipped &&
_this._tooltipInstance && _this._tooltipInstance.isVisible()) {
_this.hide(0);
}
});
var config = new OverlayState();
config.direction = this._dir ? this._dir.value : 'ltr';
config.positionStrategy = strategy;
config.scrollStrategy = this._overlay.scrollStrategies.reposition({
scrollThrottle: SCROLL_THROTTLE_MS
});
this._overlayRef = this._overlay.create(config);
};
/** Disposes the current tooltip and the overlay it is attached to */
Md2Tooltip.prototype._disposeTooltip = function () {
this._overlayRef.dispose();
this._overlayRef = null;
this._tooltipInstance = null;
};
/** Returns the origin position based on the user's position preference */
Md2Tooltip.prototype._getOrigin = function () {
if (this.position == 'above' || this.position == 'below') {
return { originX: 'center', originY: this.position == 'above' ? 'top' : 'bottom' };
}
var isDirectionLtr = !this._dir || this._dir.value == 'ltr';
if (this.position == 'left' ||
this.position == 'before' && isDirectionLtr ||
this.position == 'after' && !isDirectionLtr) {
return { originX: 'start', originY: 'center' };
}
if (this.position == 'right' ||
this.position == 'after' && isDirectionLtr ||
this.position == 'before' && !isDirectionLtr) {
return { originX: 'end', originY: 'center' };
}
throwMd2TooltipInvalidPositionError(this.position);
};
/** Returns the overlay position based on the user's preference */
Md2Tooltip.prototype._getOverlayPosition = function () {
if (this.position == 'above') {
return { overlayX: 'center', overlayY: 'bottom' };
}
if (this.position == 'below') {
return { overlayX: 'center', overlayY: 'top' };
}
var isLtr = !this._dir || this._dir.value == 'ltr';
if (this.position == 'left' ||
this.position == 'before' && isLtr ||
this.position == 'after' && !isLtr) {
return { overlayX: 'end', overlayY: 'center' };
}
if (this.position == 'right' ||
this.position == 'after' && isLtr ||
this.position == 'before' && !isLtr) {
return { overlayX: 'start', overlayY: 'center' };
}
throwMd2TooltipInvalidPositionError(this.position);
};
/** Updates the tooltip message and repositions the overlay according to the new message length */
Md2Tooltip.prototype._setTooltipMessage = function (message) {
var _this = this;
// Must wait for the message to be painted to the tooltip so that the overlay can properly
// calculate the correct positioning based on the size of the text.
this._tooltipInstance.message = message;
this._tooltipInstance._markForCheck();
this._ngZone.onMicrotaskEmpty.first().subscribe(function () {
if (_this._tooltipInstance) {
_this._overlayRef.updatePosition();
}
});
};
return Md2Tooltip;
}());
__decorate([
Input('tooltip-position'),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], Md2Tooltip.prototype, "position", null);
__decorate([
Input('tooltipDisabled'),
__metadata("design:type", Boolean),
__metadata("design:paramtypes", [Object])
], Md2Tooltip.prototype, "disabled", null);
__decorate([
Input('tooltip-delay'),
__metadata("design:type", Object)
], Md2Tooltip.prototype, "showDelay", void 0);
__decorate([
Input('tooltip-hide-delay'),
__metadata("design:type", Object)
], Md2Tooltip.prototype, "hideDelay", void 0);
__decorate([
Input('tooltip'),
__metadata("design:type", Object),
__metadata("design:paramtypes", [String])
], Md2Tooltip.prototype, "message", null);
Md2Tooltip = __decorate([
Directive({
selector: '[tooltip]',
host: {
'(longpress)': 'show()',
'(touchend)': 'hide(' + TOUCHEND_HIDE_DELAY + ')',
},
exportAs: 'md2Tooltip',
}),
__param(7, Optional()),
__metadata("design:paramtypes", [Overlay,
ElementRef,
ScrollDispatcher,
ViewContainerRef,
NgZone,
Renderer2,
Platform,
Dir])
], Md2Tooltip);
export { Md2Tooltip };
/**
* Internal component that wraps the tooltip's content.
* @docs-private
*/
var Md2TooltipComponent = (function () {
function Md2TooltipComponent(_dir, _changeDetectorRef) {
this._dir = _dir;
this._changeDetectorRef = _changeDetectorRef;
/** Property watched by the animation framework to show or hide the tooltip */
this._visibility = 'initial';
/** Whether interactions on the page should close the tooltip */
this._closeOnInteraction = false;
/** The transform origin used in the animation for showing and hiding the tooltip */
this._transformOrigin = 'bottom';
/** Subject for notifying that the tooltip has been hidden from the view */
this._onHide = new Subject();
}
/**
* Shows the tooltip with an animation originating from the provided origin
* @param position Position of the tooltip.
* @param delay Amount of milliseconds to the delay showing the tooltip.
*/
Md2TooltipComponent.prototype.show = function (position, delay) {
var _this = this;
// Cancel the delayed hide if it is scheduled
if (this._hideTimeoutId) {
clearTimeout(this._hideTimeoutId);
}
// Body interactions should cancel the tooltip if there is a delay in showing.
this._closeOnInteraction = true;
this._setTransformOrigin(position);
this._showTimeoutId = setTimeout(function () {
_this._visibility = 'visible';
// If this was set to true immediately, then a body click that triggers show() would
// trigger interaction and close the tooltip right after it was displayed.
_this._closeOnInteraction = false;
// Mark for check so if any parent component has set the
// ChangeDetectionStrategy to OnPush it will be checked anyways
_this._markForCheck();
setTimeout(function () { return _this._closeOnInteraction = true; }, 0);
}, delay);
};
/**
* Begins the animation to hide the tooltip after the provided delay in ms.
* @param delay Amount of milliseconds to delay showing the tooltip.
*/
Md2TooltipComponent.prototype.hide = function (delay) {
var _this = this;
// Cancel the delayed show if it is scheduled
if (this._showTimeoutId) {
clearTimeout(this._showTimeoutId);
}
this._hideTimeoutId = setTimeout(function () {
_this._visibility = 'hidden';
_this._closeOnInteraction = false;
// Mark for check so if any parent component has set the
// ChangeDetectionStrategy to OnPush it will be checked anyways
_this._markForCheck();
}, delay);
};
/**
* Returns an observable that notifies when the tooltip has been hidden from view
*/
Md2TooltipComponent.prototype.afterHidden = function () {
return this._onHide.asObservable();
};
/**
* Whether the tooltip is being displayed
*/
Md2TooltipComponent.prototype.isVisible = function () {
return this._visibility === 'visible';
};
/** Sets the tooltip transform origin according to the tooltip position */
Md2TooltipComponent.prototype._setTransformOrigin = function (value) {
var isLtr = !this._dir || this._dir.value == 'ltr';
switch (value) {
case 'before':
this._transformOrigin = isLtr ? 'right' : 'left';
break;
case 'after':
this._transformOrigin = isLtr ? 'left' : 'right';
break;
case 'left':
this._transformOrigin = 'right';
break;
case 'right':
this._transformOrigin = 'left';
break;
case 'above':
this._transformOrigin = 'bottom';
break;
case 'below':
this._transformOrigin = 'top';
break;
default: throwMd2TooltipInvalidPositionError(value);
}
};
Md2TooltipComponent.prototype._afterVisibilityAnimation = function (e) {
if (e.toState === 'hidden' && !this.isVisible()) {
this._onHide.next();
}
};
/**
* Interactions on the HTML body should close the tooltip immediately as defined in the
* material design spec.
* https://material.google.com/components/tooltips.html#tooltips-interaction
*/
Md2TooltipComponent.prototype._handleBodyInteraction = function () {
if (this._closeOnInteraction) {
this.hide(0);
}
};
/**
* Marks that the tooltip needs to be checked in the next change detection run.
* Mainly used for rendering the initial text before positioning a tooltip, which
* can be problematic in components with OnPush change detection.
*/
Md2TooltipComponent.prototype._markForCheck = function () {
this._changeDetectorRef.markForCheck();
};
return Md2TooltipComponent;
}());
Md2TooltipComponent = __decorate([
Component({selector: 'md2-tooltip',
template: "<div class=\"md2-tooltip\" [style.transform-origin]=\"_transformOrigin\" [@state]=\"_visibility\" (@state.done)=\"_afterVisibilityAnimation($event)\" [innerHTML]=\"message\"></div>",
styles: ["md2-tooltip{pointer-events:none}.md2-tooltip{color:#fff;padding:6px 8px;border-radius:2px;font-size:10px;margin:14px;max-width:250px;background:rgba(97,97,97,.9);word-wrap:break-word}.cdk-global-overlay-wrapper,.cdk-overlay-container{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:999}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:999}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:999} /*# sourceMappingURL=tooltip.css.map */ "],
animations: [
trigger('state', [
state('void', style({ transform: 'scale(0)' })),
state('initial', style({ transform: 'scale(0)' })),
state('visible', style({ transform: 'scale(1)' })),
state('hidden', style({ transform: 'scale(0)' })),
transition('* => visible', animate('150ms cubic-bezier(0.0, 0.0, 0.2, 1)')),
transition('* => hidden', animate('150ms cubic-bezier(0.4, 0.0, 1, 1)')),
])
],
host: {
'[style.zoom]': '_visibility === "visible" ? 1 : null',
'(body:click)': 'this._handleBodyInteraction()'
},
encapsulation: ViewEncapsulation.None
}),
__param(0, Optional()),
__metadata("design:paramtypes", [Dir, ChangeDetectorRef])
], Md2TooltipComponent);
export { Md2TooltipComponent };
//# sourceMappingURL=tooltip.js.map