source: trip-planner-front/node_modules/@angular/material/fesm2015/tooltip.js@ 6c1585f

Last change on this file since 6c1585f was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 34.7 KB
Line 
1import { Overlay, OverlayModule } from '@angular/cdk/overlay';
2import { AriaDescriber, FocusMonitor, A11yModule } from '@angular/cdk/a11y';
3import { DOCUMENT, CommonModule } from '@angular/common';
4import { InjectionToken, Directive, ElementRef, ViewContainerRef, NgZone, Inject, Input, Optional, ChangeDetectorRef, Component, ViewEncapsulation, ChangeDetectionStrategy, NgModule } from '@angular/core';
5import { MatCommonModule } from '@angular/material/core';
6import { ScrollDispatcher, CdkScrollableModule } from '@angular/cdk/scrolling';
7import { Directionality } from '@angular/cdk/bidi';
8import { coerceBooleanProperty } from '@angular/cdk/coercion';
9import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes';
10import { Breakpoints, BreakpointObserver } from '@angular/cdk/layout';
11import { normalizePassiveListenerOptions, Platform } from '@angular/cdk/platform';
12import { ComponentPortal } from '@angular/cdk/portal';
13import { Subject } from 'rxjs';
14import { takeUntil, take } from 'rxjs/operators';
15import { trigger, state, style, transition, animate, keyframes } from '@angular/animations';
16
17/**
18 * @license
19 * Copyright Google LLC All Rights Reserved.
20 *
21 * Use of this source code is governed by an MIT-style license that can be
22 * found in the LICENSE file at https://angular.io/license
23 */
24/**
25 * Animations used by MatTooltip.
26 * @docs-private
27 */
28const matTooltipAnimations = {
29 /** Animation that transitions a tooltip in and out. */
30 tooltipState: trigger('state', [
31 state('initial, void, hidden', style({ opacity: 0, transform: 'scale(0)' })),
32 state('visible', style({ transform: 'scale(1)' })),
33 transition('* => visible', animate('200ms cubic-bezier(0, 0, 0.2, 1)', keyframes([
34 style({ opacity: 0, transform: 'scale(0)', offset: 0 }),
35 style({ opacity: 0.5, transform: 'scale(0.99)', offset: 0.5 }),
36 style({ opacity: 1, transform: 'scale(1)', offset: 1 })
37 ]))),
38 transition('* => hidden', animate('100ms cubic-bezier(0, 0, 0.2, 1)', style({ opacity: 0 }))),
39 ])
40};
41
42/** Time in ms to throttle repositioning after scroll events. */
43const SCROLL_THROTTLE_MS = 20;
44/**
45 * CSS class that will be attached to the overlay panel.
46 * @deprecated
47 * @breaking-change 13.0.0 remove this variable
48 */
49const TOOLTIP_PANEL_CLASS = 'mat-tooltip-panel';
50const PANEL_CLASS = 'tooltip-panel';
51/** Options used to bind passive event listeners. */
52const passiveListenerOptions = normalizePassiveListenerOptions({ passive: true });
53/**
54 * Time between the user putting the pointer on a tooltip
55 * trigger and the long press event being fired.
56 */
57const LONGPRESS_DELAY = 500;
58/**
59 * Creates an error to be thrown if the user supplied an invalid tooltip position.
60 * @docs-private
61 */
62function getMatTooltipInvalidPositionError(position) {
63 return Error(`Tooltip position "${position}" is invalid.`);
64}
65/** Injection token that determines the scroll handling while a tooltip is visible. */
66const MAT_TOOLTIP_SCROLL_STRATEGY = new InjectionToken('mat-tooltip-scroll-strategy');
67/** @docs-private */
68function MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY(overlay) {
69 return () => overlay.scrollStrategies.reposition({ scrollThrottle: SCROLL_THROTTLE_MS });
70}
71/** @docs-private */
72const MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER = {
73 provide: MAT_TOOLTIP_SCROLL_STRATEGY,
74 deps: [Overlay],
75 useFactory: MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY,
76};
77/** Injection token to be used to override the default options for `matTooltip`. */
78const MAT_TOOLTIP_DEFAULT_OPTIONS = new InjectionToken('mat-tooltip-default-options', {
79 providedIn: 'root',
80 factory: MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY
81});
82/** @docs-private */
83function MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY() {
84 return {
85 showDelay: 0,
86 hideDelay: 0,
87 touchendHideDelay: 1500,
88 };
89}
90class _MatTooltipBase {
91 constructor(_overlay, _elementRef, _scrollDispatcher, _viewContainerRef, _ngZone, _platform, _ariaDescriber, _focusMonitor, scrollStrategy, _dir, _defaultOptions, _document) {
92 this._overlay = _overlay;
93 this._elementRef = _elementRef;
94 this._scrollDispatcher = _scrollDispatcher;
95 this._viewContainerRef = _viewContainerRef;
96 this._ngZone = _ngZone;
97 this._platform = _platform;
98 this._ariaDescriber = _ariaDescriber;
99 this._focusMonitor = _focusMonitor;
100 this._dir = _dir;
101 this._defaultOptions = _defaultOptions;
102 this._position = 'below';
103 this._disabled = false;
104 this._viewInitialized = false;
105 this._pointerExitEventsInitialized = false;
106 this._viewportMargin = 8;
107 this._cssClassPrefix = 'mat';
108 /** The default delay in ms before showing the tooltip after show is called */
109 this.showDelay = this._defaultOptions.showDelay;
110 /** The default delay in ms before hiding the tooltip after hide is called */
111 this.hideDelay = this._defaultOptions.hideDelay;
112 /**
113 * How touch gestures should be handled by the tooltip. On touch devices the tooltip directive
114 * uses a long press gesture to show and hide, however it can conflict with the native browser
115 * gestures. To work around the conflict, Angular Material disables native gestures on the
116 * trigger, but that might not be desirable on particular elements (e.g. inputs and draggable
117 * elements). The different values for this option configure the touch event handling as follows:
118 * - `auto` - Enables touch gestures for all elements, but tries to avoid conflicts with native
119 * browser gestures on particular elements. In particular, it allows text selection on inputs
120 * and textareas, and preserves the native browser dragging on elements marked as `draggable`.
121 * - `on` - Enables touch gestures for all elements and disables native
122 * browser gestures with no exceptions.
123 * - `off` - Disables touch gestures. Note that this will prevent the tooltip from
124 * showing on touch devices.
125 */
126 this.touchGestures = 'auto';
127 this._message = '';
128 /** Manually-bound passive event listeners. */
129 this._passiveListeners = [];
130 /** Emits when the component is destroyed. */
131 this._destroyed = new Subject();
132 /**
133 * Handles the keydown events on the host element.
134 * Needs to be an arrow function so that we can use it in addEventListener.
135 */
136 this._handleKeydown = (event) => {
137 if (this._isTooltipVisible() && event.keyCode === ESCAPE && !hasModifierKey(event)) {
138 event.preventDefault();
139 event.stopPropagation();
140 this._ngZone.run(() => this.hide(0));
141 }
142 };
143 this._scrollStrategy = scrollStrategy;
144 this._document = _document;
145 if (_defaultOptions) {
146 if (_defaultOptions.position) {
147 this.position = _defaultOptions.position;
148 }
149 if (_defaultOptions.touchGestures) {
150 this.touchGestures = _defaultOptions.touchGestures;
151 }
152 }
153 _dir.change.pipe(takeUntil(this._destroyed)).subscribe(() => {
154 if (this._overlayRef) {
155 this._updatePosition(this._overlayRef);
156 }
157 });
158 _ngZone.runOutsideAngular(() => {
159 _elementRef.nativeElement.addEventListener('keydown', this._handleKeydown);
160 });
161 }
162 /** Allows the user to define the position of the tooltip relative to the parent element */
163 get position() { return this._position; }
164 set position(value) {
165 var _a;
166 if (value !== this._position) {
167 this._position = value;
168 if (this._overlayRef) {
169 this._updatePosition(this._overlayRef);
170 (_a = this._tooltipInstance) === null || _a === void 0 ? void 0 : _a.show(0);
171 this._overlayRef.updatePosition();
172 }
173 }
174 }
175 /** Disables the display of the tooltip. */
176 get disabled() { return this._disabled; }
177 set disabled(value) {
178 this._disabled = coerceBooleanProperty(value);
179 // If tooltip is disabled, hide immediately.
180 if (this._disabled) {
181 this.hide(0);
182 }
183 else {
184 this._setupPointerEnterEventsIfNeeded();
185 }
186 }
187 /** The message to be displayed in the tooltip */
188 get message() { return this._message; }
189 set message(value) {
190 this._ariaDescriber.removeDescription(this._elementRef.nativeElement, this._message, 'tooltip');
191 // If the message is not a string (e.g. number), convert it to a string and trim it.
192 // Must convert with `String(value)`, not `${value}`, otherwise Closure Compiler optimises
193 // away the string-conversion: https://github.com/angular/components/issues/20684
194 this._message = value != null ? String(value).trim() : '';
195 if (!this._message && this._isTooltipVisible()) {
196 this.hide(0);
197 }
198 else {
199 this._setupPointerEnterEventsIfNeeded();
200 this._updateTooltipMessage();
201 this._ngZone.runOutsideAngular(() => {
202 // The `AriaDescriber` has some functionality that avoids adding a description if it's the
203 // same as the `aria-label` of an element, however we can't know whether the tooltip trigger
204 // has a data-bound `aria-label` or when it'll be set for the first time. We can avoid the
205 // issue by deferring the description by a tick so Angular has time to set the `aria-label`.
206 Promise.resolve().then(() => {
207 this._ariaDescriber.describe(this._elementRef.nativeElement, this.message, 'tooltip');
208 });
209 });
210 }
211 }
212 /** Classes to be passed to the tooltip. Supports the same syntax as `ngClass`. */
213 get tooltipClass() { return this._tooltipClass; }
214 set tooltipClass(value) {
215 this._tooltipClass = value;
216 if (this._tooltipInstance) {
217 this._setTooltipClass(this._tooltipClass);
218 }
219 }
220 ngAfterViewInit() {
221 // This needs to happen after view init so the initial values for all inputs have been set.
222 this._viewInitialized = true;
223 this._setupPointerEnterEventsIfNeeded();
224 this._focusMonitor.monitor(this._elementRef)
225 .pipe(takeUntil(this._destroyed))
226 .subscribe(origin => {
227 // Note that the focus monitor runs outside the Angular zone.
228 if (!origin) {
229 this._ngZone.run(() => this.hide(0));
230 }
231 else if (origin === 'keyboard') {
232 this._ngZone.run(() => this.show());
233 }
234 });
235 }
236 /**
237 * Dispose the tooltip when destroyed.
238 */
239 ngOnDestroy() {
240 const nativeElement = this._elementRef.nativeElement;
241 clearTimeout(this._touchstartTimeout);
242 if (this._overlayRef) {
243 this._overlayRef.dispose();
244 this._tooltipInstance = null;
245 }
246 // Clean up the event listeners set in the constructor
247 nativeElement.removeEventListener('keydown', this._handleKeydown);
248 this._passiveListeners.forEach(([event, listener]) => {
249 nativeElement.removeEventListener(event, listener, passiveListenerOptions);
250 });
251 this._passiveListeners.length = 0;
252 this._destroyed.next();
253 this._destroyed.complete();
254 this._ariaDescriber.removeDescription(nativeElement, this.message, 'tooltip');
255 this._focusMonitor.stopMonitoring(nativeElement);
256 }
257 /** Shows the tooltip after the delay in ms, defaults to tooltip-delay-show or 0ms if no input */
258 show(delay = this.showDelay) {
259 if (this.disabled || !this.message || (this._isTooltipVisible() &&
260 !this._tooltipInstance._showTimeoutId && !this._tooltipInstance._hideTimeoutId)) {
261 return;
262 }
263 const overlayRef = this._createOverlay();
264 this._detach();
265 this._portal = this._portal ||
266 new ComponentPortal(this._tooltipComponent, this._viewContainerRef);
267 this._tooltipInstance = overlayRef.attach(this._portal).instance;
268 this._tooltipInstance.afterHidden()
269 .pipe(takeUntil(this._destroyed))
270 .subscribe(() => this._detach());
271 this._setTooltipClass(this._tooltipClass);
272 this._updateTooltipMessage();
273 this._tooltipInstance.show(delay);
274 }
275 /** Hides the tooltip after the delay in ms, defaults to tooltip-delay-hide or 0ms if no input */
276 hide(delay = this.hideDelay) {
277 if (this._tooltipInstance) {
278 this._tooltipInstance.hide(delay);
279 }
280 }
281 /** Shows/hides the tooltip */
282 toggle() {
283 this._isTooltipVisible() ? this.hide() : this.show();
284 }
285 /** Returns true if the tooltip is currently visible to the user */
286 _isTooltipVisible() {
287 return !!this._tooltipInstance && this._tooltipInstance.isVisible();
288 }
289 /** Create the overlay config and position strategy */
290 _createOverlay() {
291 if (this._overlayRef) {
292 return this._overlayRef;
293 }
294 const scrollableAncestors = this._scrollDispatcher.getAncestorScrollContainers(this._elementRef);
295 // Create connected position strategy that listens for scroll events to reposition.
296 const strategy = this._overlay.position()
297 .flexibleConnectedTo(this._elementRef)
298 .withTransformOriginOn(`.${this._cssClassPrefix}-tooltip`)
299 .withFlexibleDimensions(false)
300 .withViewportMargin(this._viewportMargin)
301 .withScrollableContainers(scrollableAncestors);
302 strategy.positionChanges.pipe(takeUntil(this._destroyed)).subscribe(change => {
303 this._updateCurrentPositionClass(change.connectionPair);
304 if (this._tooltipInstance) {
305 if (change.scrollableViewProperties.isOverlayClipped && this._tooltipInstance.isVisible()) {
306 // After position changes occur and the overlay is clipped by
307 // a parent scrollable then close the tooltip.
308 this._ngZone.run(() => this.hide(0));
309 }
310 }
311 });
312 this._overlayRef = this._overlay.create({
313 direction: this._dir,
314 positionStrategy: strategy,
315 panelClass: `${this._cssClassPrefix}-${PANEL_CLASS}`,
316 scrollStrategy: this._scrollStrategy()
317 });
318 this._updatePosition(this._overlayRef);
319 this._overlayRef.detachments()
320 .pipe(takeUntil(this._destroyed))
321 .subscribe(() => this._detach());
322 this._overlayRef.outsidePointerEvents()
323 .pipe(takeUntil(this._destroyed))
324 .subscribe(() => { var _a; return (_a = this._tooltipInstance) === null || _a === void 0 ? void 0 : _a._handleBodyInteraction(); });
325 return this._overlayRef;
326 }
327 /** Detaches the currently-attached tooltip. */
328 _detach() {
329 if (this._overlayRef && this._overlayRef.hasAttached()) {
330 this._overlayRef.detach();
331 }
332 this._tooltipInstance = null;
333 }
334 /** Updates the position of the current tooltip. */
335 _updatePosition(overlayRef) {
336 const position = overlayRef.getConfig().positionStrategy;
337 const origin = this._getOrigin();
338 const overlay = this._getOverlayPosition();
339 position.withPositions([
340 this._addOffset(Object.assign(Object.assign({}, origin.main), overlay.main)),
341 this._addOffset(Object.assign(Object.assign({}, origin.fallback), overlay.fallback))
342 ]);
343 }
344 /** Adds the configured offset to a position. Used as a hook for child classes. */
345 _addOffset(position) {
346 return position;
347 }
348 /**
349 * Returns the origin position and a fallback position based on the user's position preference.
350 * The fallback position is the inverse of the origin (e.g. `'below' -> 'above'`).
351 */
352 _getOrigin() {
353 const isLtr = !this._dir || this._dir.value == 'ltr';
354 const position = this.position;
355 let originPosition;
356 if (position == 'above' || position == 'below') {
357 originPosition = { originX: 'center', originY: position == 'above' ? 'top' : 'bottom' };
358 }
359 else if (position == 'before' ||
360 (position == 'left' && isLtr) ||
361 (position == 'right' && !isLtr)) {
362 originPosition = { originX: 'start', originY: 'center' };
363 }
364 else if (position == 'after' ||
365 (position == 'right' && isLtr) ||
366 (position == 'left' && !isLtr)) {
367 originPosition = { originX: 'end', originY: 'center' };
368 }
369 else if (typeof ngDevMode === 'undefined' || ngDevMode) {
370 throw getMatTooltipInvalidPositionError(position);
371 }
372 const { x, y } = this._invertPosition(originPosition.originX, originPosition.originY);
373 return {
374 main: originPosition,
375 fallback: { originX: x, originY: y }
376 };
377 }
378 /** Returns the overlay position and a fallback position based on the user's preference */
379 _getOverlayPosition() {
380 const isLtr = !this._dir || this._dir.value == 'ltr';
381 const position = this.position;
382 let overlayPosition;
383 if (position == 'above') {
384 overlayPosition = { overlayX: 'center', overlayY: 'bottom' };
385 }
386 else if (position == 'below') {
387 overlayPosition = { overlayX: 'center', overlayY: 'top' };
388 }
389 else if (position == 'before' ||
390 (position == 'left' && isLtr) ||
391 (position == 'right' && !isLtr)) {
392 overlayPosition = { overlayX: 'end', overlayY: 'center' };
393 }
394 else if (position == 'after' ||
395 (position == 'right' && isLtr) ||
396 (position == 'left' && !isLtr)) {
397 overlayPosition = { overlayX: 'start', overlayY: 'center' };
398 }
399 else if (typeof ngDevMode === 'undefined' || ngDevMode) {
400 throw getMatTooltipInvalidPositionError(position);
401 }
402 const { x, y } = this._invertPosition(overlayPosition.overlayX, overlayPosition.overlayY);
403 return {
404 main: overlayPosition,
405 fallback: { overlayX: x, overlayY: y }
406 };
407 }
408 /** Updates the tooltip message and repositions the overlay according to the new message length */
409 _updateTooltipMessage() {
410 // Must wait for the message to be painted to the tooltip so that the overlay can properly
411 // calculate the correct positioning based on the size of the text.
412 if (this._tooltipInstance) {
413 this._tooltipInstance.message = this.message;
414 this._tooltipInstance._markForCheck();
415 this._ngZone.onMicrotaskEmpty.pipe(take(1), takeUntil(this._destroyed)).subscribe(() => {
416 if (this._tooltipInstance) {
417 this._overlayRef.updatePosition();
418 }
419 });
420 }
421 }
422 /** Updates the tooltip class */
423 _setTooltipClass(tooltipClass) {
424 if (this._tooltipInstance) {
425 this._tooltipInstance.tooltipClass = tooltipClass;
426 this._tooltipInstance._markForCheck();
427 }
428 }
429 /** Inverts an overlay position. */
430 _invertPosition(x, y) {
431 if (this.position === 'above' || this.position === 'below') {
432 if (y === 'top') {
433 y = 'bottom';
434 }
435 else if (y === 'bottom') {
436 y = 'top';
437 }
438 }
439 else {
440 if (x === 'end') {
441 x = 'start';
442 }
443 else if (x === 'start') {
444 x = 'end';
445 }
446 }
447 return { x, y };
448 }
449 /** Updates the class on the overlay panel based on the current position of the tooltip. */
450 _updateCurrentPositionClass(connectionPair) {
451 const { overlayY, originX, originY } = connectionPair;
452 let newPosition;
453 // If the overlay is in the middle along the Y axis,
454 // it means that it's either before or after.
455 if (overlayY === 'center') {
456 // Note that since this information is used for styling, we want to
457 // resolve `start` and `end` to their real values, otherwise consumers
458 // would have to remember to do it themselves on each consumption.
459 if (this._dir && this._dir.value === 'rtl') {
460 newPosition = originX === 'end' ? 'left' : 'right';
461 }
462 else {
463 newPosition = originX === 'start' ? 'left' : 'right';
464 }
465 }
466 else {
467 newPosition = overlayY === 'bottom' && originY === 'top' ? 'above' : 'below';
468 }
469 if (newPosition !== this._currentPosition) {
470 const overlayRef = this._overlayRef;
471 if (overlayRef) {
472 const classPrefix = `${this._cssClassPrefix}-${PANEL_CLASS}-`;
473 overlayRef.removePanelClass(classPrefix + this._currentPosition);
474 overlayRef.addPanelClass(classPrefix + newPosition);
475 }
476 this._currentPosition = newPosition;
477 }
478 }
479 /** Binds the pointer events to the tooltip trigger. */
480 _setupPointerEnterEventsIfNeeded() {
481 // Optimization: Defer hooking up events if there's no message or the tooltip is disabled.
482 if (this._disabled || !this.message || !this._viewInitialized ||
483 this._passiveListeners.length) {
484 return;
485 }
486 // The mouse events shouldn't be bound on mobile devices, because they can prevent the
487 // first tap from firing its click event or can cause the tooltip to open for clicks.
488 if (this._platformSupportsMouseEvents()) {
489 this._passiveListeners
490 .push(['mouseenter', () => {
491 this._setupPointerExitEventsIfNeeded();
492 this.show();
493 }]);
494 }
495 else if (this.touchGestures !== 'off') {
496 this._disableNativeGesturesIfNecessary();
497 this._passiveListeners
498 .push(['touchstart', () => {
499 // Note that it's important that we don't `preventDefault` here,
500 // because it can prevent click events from firing on the element.
501 this._setupPointerExitEventsIfNeeded();
502 clearTimeout(this._touchstartTimeout);
503 this._touchstartTimeout = setTimeout(() => this.show(), LONGPRESS_DELAY);
504 }]);
505 }
506 this._addListeners(this._passiveListeners);
507 }
508 _setupPointerExitEventsIfNeeded() {
509 if (this._pointerExitEventsInitialized) {
510 return;
511 }
512 this._pointerExitEventsInitialized = true;
513 const exitListeners = [];
514 if (this._platformSupportsMouseEvents()) {
515 exitListeners.push(['mouseleave', () => this.hide()], ['wheel', event => this._wheelListener(event)]);
516 }
517 else if (this.touchGestures !== 'off') {
518 this._disableNativeGesturesIfNecessary();
519 const touchendListener = () => {
520 clearTimeout(this._touchstartTimeout);
521 this.hide(this._defaultOptions.touchendHideDelay);
522 };
523 exitListeners.push(['touchend', touchendListener], ['touchcancel', touchendListener]);
524 }
525 this._addListeners(exitListeners);
526 this._passiveListeners.push(...exitListeners);
527 }
528 _addListeners(listeners) {
529 listeners.forEach(([event, listener]) => {
530 this._elementRef.nativeElement.addEventListener(event, listener, passiveListenerOptions);
531 });
532 }
533 _platformSupportsMouseEvents() {
534 return !this._platform.IOS && !this._platform.ANDROID;
535 }
536 /** Listener for the `wheel` event on the element. */
537 _wheelListener(event) {
538 if (this._isTooltipVisible()) {
539 const elementUnderPointer = this._document.elementFromPoint(event.clientX, event.clientY);
540 const element = this._elementRef.nativeElement;
541 // On non-touch devices we depend on the `mouseleave` event to close the tooltip, but it
542 // won't fire if the user scrolls away using the wheel without moving their cursor. We
543 // work around it by finding the element under the user's cursor and closing the tooltip
544 // if it's not the trigger.
545 if (elementUnderPointer !== element && !element.contains(elementUnderPointer)) {
546 this.hide();
547 }
548 }
549 }
550 /** Disables the native browser gestures, based on how the tooltip has been configured. */
551 _disableNativeGesturesIfNecessary() {
552 const gestures = this.touchGestures;
553 if (gestures !== 'off') {
554 const element = this._elementRef.nativeElement;
555 const style = element.style;
556 // If gestures are set to `auto`, we don't disable text selection on inputs and
557 // textareas, because it prevents the user from typing into them on iOS Safari.
558 if (gestures === 'on' || (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA')) {
559 style.userSelect = style.msUserSelect = style.webkitUserSelect =
560 style.MozUserSelect = 'none';
561 }
562 // If we have `auto` gestures and the element uses native HTML dragging,
563 // we don't set `-webkit-user-drag` because it prevents the native behavior.
564 if (gestures === 'on' || !element.draggable) {
565 style.webkitUserDrag = 'none';
566 }
567 style.touchAction = 'none';
568 style.webkitTapHighlightColor = 'transparent';
569 }
570 }
571}
572_MatTooltipBase.decorators = [
573 { type: Directive }
574];
575_MatTooltipBase.ctorParameters = () => [
576 { type: Overlay },
577 { type: ElementRef },
578 { type: ScrollDispatcher },
579 { type: ViewContainerRef },
580 { type: NgZone },
581 { type: Platform },
582 { type: AriaDescriber },
583 { type: FocusMonitor },
584 { type: undefined },
585 { type: Directionality },
586 { type: undefined },
587 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
588];
589_MatTooltipBase.propDecorators = {
590 position: [{ type: Input, args: ['matTooltipPosition',] }],
591 disabled: [{ type: Input, args: ['matTooltipDisabled',] }],
592 showDelay: [{ type: Input, args: ['matTooltipShowDelay',] }],
593 hideDelay: [{ type: Input, args: ['matTooltipHideDelay',] }],
594 touchGestures: [{ type: Input, args: ['matTooltipTouchGestures',] }],
595 message: [{ type: Input, args: ['matTooltip',] }],
596 tooltipClass: [{ type: Input, args: ['matTooltipClass',] }]
597};
598/**
599 * Directive that attaches a material design tooltip to the host element. Animates the showing and
600 * hiding of a tooltip provided position (defaults to below the element).
601 *
602 * https://material.io/design/components/tooltips.html
603 */
604class MatTooltip extends _MatTooltipBase {
605 constructor(overlay, elementRef, scrollDispatcher, viewContainerRef, ngZone, platform, ariaDescriber, focusMonitor, scrollStrategy, dir, defaultOptions, _document) {
606 super(overlay, elementRef, scrollDispatcher, viewContainerRef, ngZone, platform, ariaDescriber, focusMonitor, scrollStrategy, dir, defaultOptions, _document);
607 this._tooltipComponent = TooltipComponent;
608 }
609}
610MatTooltip.decorators = [
611 { type: Directive, args: [{
612 selector: '[matTooltip]',
613 exportAs: 'matTooltip',
614 host: {
615 'class': 'mat-tooltip-trigger'
616 }
617 },] }
618];
619MatTooltip.ctorParameters = () => [
620 { type: Overlay },
621 { type: ElementRef },
622 { type: ScrollDispatcher },
623 { type: ViewContainerRef },
624 { type: NgZone },
625 { type: Platform },
626 { type: AriaDescriber },
627 { type: FocusMonitor },
628 { type: undefined, decorators: [{ type: Inject, args: [MAT_TOOLTIP_SCROLL_STRATEGY,] }] },
629 { type: Directionality, decorators: [{ type: Optional }] },
630 { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_TOOLTIP_DEFAULT_OPTIONS,] }] },
631 { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
632];
633class _TooltipComponentBase {
634 constructor(_changeDetectorRef) {
635 this._changeDetectorRef = _changeDetectorRef;
636 /** Property watched by the animation framework to show or hide the tooltip */
637 this._visibility = 'initial';
638 /** Whether interactions on the page should close the tooltip */
639 this._closeOnInteraction = false;
640 /** Subject for notifying that the tooltip has been hidden from the view */
641 this._onHide = new Subject();
642 }
643 /**
644 * Shows the tooltip with an animation originating from the provided origin
645 * @param delay Amount of milliseconds to the delay showing the tooltip.
646 */
647 show(delay) {
648 // Cancel the delayed hide if it is scheduled
649 clearTimeout(this._hideTimeoutId);
650 // Body interactions should cancel the tooltip if there is a delay in showing.
651 this._closeOnInteraction = true;
652 this._showTimeoutId = setTimeout(() => {
653 this._visibility = 'visible';
654 this._showTimeoutId = undefined;
655 this._onShow();
656 // Mark for check so if any parent component has set the
657 // ChangeDetectionStrategy to OnPush it will be checked anyways
658 this._markForCheck();
659 }, delay);
660 }
661 /**
662 * Begins the animation to hide the tooltip after the provided delay in ms.
663 * @param delay Amount of milliseconds to delay showing the tooltip.
664 */
665 hide(delay) {
666 // Cancel the delayed show if it is scheduled
667 clearTimeout(this._showTimeoutId);
668 this._hideTimeoutId = setTimeout(() => {
669 this._visibility = 'hidden';
670 this._hideTimeoutId = undefined;
671 // Mark for check so if any parent component has set the
672 // ChangeDetectionStrategy to OnPush it will be checked anyways
673 this._markForCheck();
674 }, delay);
675 }
676 /** Returns an observable that notifies when the tooltip has been hidden from view. */
677 afterHidden() {
678 return this._onHide;
679 }
680 /** Whether the tooltip is being displayed. */
681 isVisible() {
682 return this._visibility === 'visible';
683 }
684 ngOnDestroy() {
685 clearTimeout(this._showTimeoutId);
686 clearTimeout(this._hideTimeoutId);
687 this._onHide.complete();
688 }
689 _animationStart() {
690 this._closeOnInteraction = false;
691 }
692 _animationDone(event) {
693 const toState = event.toState;
694 if (toState === 'hidden' && !this.isVisible()) {
695 this._onHide.next();
696 }
697 if (toState === 'visible' || toState === 'hidden') {
698 this._closeOnInteraction = true;
699 }
700 }
701 /**
702 * Interactions on the HTML body should close the tooltip immediately as defined in the
703 * material design spec.
704 * https://material.io/design/components/tooltips.html#behavior
705 */
706 _handleBodyInteraction() {
707 if (this._closeOnInteraction) {
708 this.hide(0);
709 }
710 }
711 /**
712 * Marks that the tooltip needs to be checked in the next change detection run.
713 * Mainly used for rendering the initial text before positioning a tooltip, which
714 * can be problematic in components with OnPush change detection.
715 */
716 _markForCheck() {
717 this._changeDetectorRef.markForCheck();
718 }
719 /**
720 * Callback for when the timeout in this.show() gets completed.
721 * This method is only needed by the mdc-tooltip, and so it is only implemented
722 * in the mdc-tooltip, not here.
723 */
724 _onShow() { }
725}
726_TooltipComponentBase.decorators = [
727 { type: Directive }
728];
729_TooltipComponentBase.ctorParameters = () => [
730 { type: ChangeDetectorRef }
731];
732/**
733 * Internal component that wraps the tooltip's content.
734 * @docs-private
735 */
736class TooltipComponent extends _TooltipComponentBase {
737 constructor(changeDetectorRef, _breakpointObserver) {
738 super(changeDetectorRef);
739 this._breakpointObserver = _breakpointObserver;
740 /** Stream that emits whether the user has a handset-sized display. */
741 this._isHandset = this._breakpointObserver.observe(Breakpoints.Handset);
742 }
743}
744TooltipComponent.decorators = [
745 { type: Component, args: [{
746 selector: 'mat-tooltip-component',
747 template: "<div class=\"mat-tooltip\"\n [ngClass]=\"tooltipClass\"\n [class.mat-tooltip-handset]=\"(_isHandset | async)?.matches\"\n [@state]=\"_visibility\"\n (@state.start)=\"_animationStart()\"\n (@state.done)=\"_animationDone($event)\">{{message}}</div>\n",
748 encapsulation: ViewEncapsulation.None,
749 changeDetection: ChangeDetectionStrategy.OnPush,
750 animations: [matTooltipAnimations.tooltipState],
751 host: {
752 // Forces the element to have a layout in IE and Edge. This fixes issues where the element
753 // won't be rendered if the animations are disabled or there is no web animations polyfill.
754 '[style.zoom]': '_visibility === "visible" ? 1 : null',
755 'aria-hidden': 'true',
756 },
757 styles: [".mat-tooltip-panel{pointer-events:none !important}.mat-tooltip{color:#fff;border-radius:4px;margin:14px;max-width:250px;padding-left:8px;padding-right:8px;overflow:hidden;text-overflow:ellipsis}.cdk-high-contrast-active .mat-tooltip{outline:solid 1px}.mat-tooltip-handset{margin:24px;padding-left:16px;padding-right:16px}\n"]
758 },] }
759];
760TooltipComponent.ctorParameters = () => [
761 { type: ChangeDetectorRef },
762 { type: BreakpointObserver }
763];
764
765/**
766 * @license
767 * Copyright Google LLC All Rights Reserved.
768 *
769 * Use of this source code is governed by an MIT-style license that can be
770 * found in the LICENSE file at https://angular.io/license
771 */
772class MatTooltipModule {
773}
774MatTooltipModule.decorators = [
775 { type: NgModule, args: [{
776 imports: [
777 A11yModule,
778 CommonModule,
779 OverlayModule,
780 MatCommonModule,
781 ],
782 exports: [MatTooltip, TooltipComponent, MatCommonModule, CdkScrollableModule],
783 declarations: [MatTooltip, TooltipComponent],
784 entryComponents: [TooltipComponent],
785 providers: [MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER]
786 },] }
787];
788
789/**
790 * @license
791 * Copyright Google LLC All Rights Reserved.
792 *
793 * Use of this source code is governed by an MIT-style license that can be
794 * found in the LICENSE file at https://angular.io/license
795 */
796
797/**
798 * Generated bundle index. Do not edit.
799 */
800
801export { MAT_TOOLTIP_DEFAULT_OPTIONS, MAT_TOOLTIP_DEFAULT_OPTIONS_FACTORY, MAT_TOOLTIP_SCROLL_STRATEGY, MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY, MAT_TOOLTIP_SCROLL_STRATEGY_FACTORY_PROVIDER, MatTooltip, MatTooltipModule, SCROLL_THROTTLE_MS, TOOLTIP_PANEL_CLASS, TooltipComponent, _MatTooltipBase, _TooltipComponentBase, getMatTooltipInvalidPositionError, matTooltipAnimations };
802//# sourceMappingURL=tooltip.js.map
Note: See TracBrowser for help on using the repository browser.