@alyle/ui
Version:
Minimal Design, a set of components for Angular
256 lines (251 loc) • 11.4 kB
JavaScript
import * as i0 from '@angular/core';
import { InjectionToken, Input, Optional, Inject, Directive, NgModule } from '@angular/core';
import * as i1 from '@alyle/ui';
import { YPosition, StyleCollection, Positioning, LyOverlayModule } from '@alyle/ui';
import * as i3 from '@angular/cdk/platform';
import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
import { coerceNumberProperty } from '@angular/cdk/coercion';
import * as i2 from '@angular/cdk/scrolling';
/** Options used to bind passive event listeners. */
const passiveListenerOptions = normalizePassiveListenerOptions({ passive: true });
const LY_TOOLTIP_DEFAULT_OPTIONS = new InjectionToken('LY_TOOLTIP_DEFAULT_OPTIONS');
const DEFAULT_PLACEMENT = YPosition.below;
const STYLE_PRIORITY = -2;
const STYLES = (theme, ref) => {
const __ = ref.selectorsOf(STYLES);
return {
$priority: STYLE_PRIORITY,
root: () => (theme.tooltip
&& theme.tooltip.root
&& (theme.tooltip.root instanceof StyleCollection
? theme.tooltip.root.setTransformer(fn => fn(__)).css
: theme.tooltip.root(__)))
};
};
class LyTooltip {
set tooltip(val) {
this._tooltip = val;
}
get tooltip() {
return this._tooltip;
}
get showDelay() {
return this._showDelay;
}
set showDelay(value) {
this._showDelay = coerceNumberProperty(value);
}
get hideDelay() {
return this._hideDelay;
}
set hideDelay(value) {
this._hideDelay = coerceNumberProperty(value);
}
constructor(_theme, _overlay, _el, _renderer, _cd, _focusState, _defaults, ngZone, scroll, _platform) {
this._theme = _theme;
this._overlay = _overlay;
this._el = _el;
this._renderer = _renderer;
this._cd = _cd;
this._focusState = _focusState;
this._defaults = _defaults;
this._platform = _platform;
/** @docs-private */
this.classes = this._theme.renderStyleSheet(STYLES);
this._listeners = [];
this._scrollVal = 0;
this._showDelay = this._defaults?.showDelay ?? 0;
this._hideDelay = this._defaults?.hideDelay ?? 0;
if (_platform.isBrowser) {
const element = _el.nativeElement;
if (this._platformSupportsMouseEvents()) {
this._listeners.push(['mouseenter', () => this.show()]);
this._listeners.push(['mouseleave', () => this.hide()]);
}
else {
this._listeners.push(['touchstart', () => this.show()]);
this._listeners.push(['touchend', () => this.hide(this._defaults?.touchendHideDelay ?? 1500)]);
this._listeners.push(['touchcancel', () => this.hide(this._defaults?.touchendHideDelay ?? 1500)]);
}
this._addListeners(this._listeners);
this._scrollSub = scroll.scrolled().subscribe(() => {
if (this._tooltipOverlay) {
this._scrollVal++;
if (this._scrollVal > 15) {
ngZone.run(() => this.hide(0));
this._scrollVal = 0;
}
}
});
_focusState.listen(element).subscribe(ev => {
if (ev === 'keyboard') {
ngZone.run(() => this.show());
}
else if (ev == null) {
ngZone.run(() => this.hide());
}
});
}
}
ngOnInit() {
if (!this.placement && !this.xPosition && !this.yPosition) {
this.placement = DEFAULT_PLACEMENT;
}
}
ngOnDestroy() {
this.hide(0);
// Clean up the event listeners set in the constructor
this._listeners.forEach(([event, listener]) => {
this._el.nativeElement.removeEventListener(event, listener, passiveListenerOptions);
});
this._listeners.length = 0;
if (this._scrollSub) {
this._scrollSub.unsubscribe();
}
this._focusState.unlisten(this._el);
}
show(delay = this.showDelay) {
if (this._hideTimeoutId) {
clearTimeout(this._hideTimeoutId);
this._hideTimeoutId = null;
}
if (!this._platformSupportsMouseEvents()) {
this._updatePosition();
}
if (!this._tooltipOverlay && this.tooltip && !this._showTimeoutId) {
const tooltipRef = this.tooltip;
this._showTimeoutId = setTimeout(() => {
// const rect = this._el.nativeElement.getBoundingClientRect();
const tooltip = this._tooltipOverlay = this._overlay.create(tooltipRef, undefined, {
styles: {
// top: rect.y,
// left: rect.x
},
onResizeScroll: this._updatePosition.bind(this),
classes: [
this.classes.root,
this._theme.addStyle('LyTooltip', (theme) => ({
borderRadius: '4px',
fontSize: '10px',
padding: '6px 8px',
opacity: 0,
transition: `opacity ${theme.animations.curves.standard} 300ms`,
left: 0,
margin: '8px',
pointerEvents: 'all',
[theme.getBreakpoint('XSmall')]: {
padding: '8px 16px',
fontSize: '14px',
}
}), undefined, undefined, STYLE_PRIORITY)
],
hasBackdrop: false
});
this._updatePosition();
this._theme.requestAnimationFrame(() => {
this._theme.addStyle('lyTooltip:open', ({
opacity: 1,
}), tooltip.containerElement, undefined, STYLE_PRIORITY);
});
this._showTimeoutId = null;
this._markForCheck();
}, delay);
}
}
hide(delay = this.hideDelay) {
const tooltipOverlay = this._tooltipOverlay;
if (this._showTimeoutId) {
clearTimeout(this._showTimeoutId);
this._showTimeoutId = null;
}
if (!this._platformSupportsMouseEvents()) {
this._updatePosition();
}
if (tooltipOverlay && !this._hideTimeoutId) {
this._hideTimeoutId = setTimeout(() => {
this._renderer.removeClass(tooltipOverlay.containerElement, this._theme.addStyle('lyTooltip:open', null));
setTimeout(() => tooltipOverlay.destroy(), 300);
this._tooltipOverlay = null;
this._hideTimeoutId = null;
this._markForCheck();
}, delay);
}
}
toggle() {
if (this._tooltipOverlay) {
this.hide();
}
else {
this.show();
}
}
_markForCheck() {
this._cd.markForCheck();
}
_updatePosition() {
const tooltip = this._tooltipOverlay;
if (tooltip) {
const position = new Positioning(this.placement, this.xPosition, this.yPosition, this._el.nativeElement, tooltip.containerElement, this._theme.variables, 13);
tooltip.containerElement.style.transform = `translate3d(${position.x}px,${position.y}px,0)`;
}
}
_addListeners(listeners) {
listeners.forEach(([event, listener]) => {
this._el.nativeElement.addEventListener(event, listener, passiveListenerOptions);
});
}
_platformSupportsMouseEvents() {
return !this._platform.IOS && !this._platform.ANDROID;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTooltip, deps: [{ token: i1.LyTheme2 }, { token: i1.LyOverlay }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.LyFocusState }, { token: LY_TOOLTIP_DEFAULT_OPTIONS, optional: true }, { token: i0.NgZone }, { token: i2.ScrollDispatcher }, { token: i3.Platform }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.10", type: LyTooltip, isStandalone: false, selector: "[lyTooltip]", inputs: { tooltip: ["lyTooltip", "tooltip"], showDelay: ["lyTooltipShowDelay", "showDelay"], hideDelay: ["lyTooltipHideDelay", "hideDelay"], placement: ["lyTooltipPlacement", "placement"], xPosition: ["lyTooltipXPosition", "xPosition"], yPosition: ["lyTooltipYPosition", "yPosition"] }, exportAs: ["lyTooltip"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTooltip, decorators: [{
type: Directive,
args: [{
selector: '[lyTooltip]',
exportAs: 'lyTooltip',
standalone: false
}]
}], ctorParameters: () => [{ type: i1.LyTheme2 }, { type: i1.LyOverlay }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LyFocusState }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [LY_TOOLTIP_DEFAULT_OPTIONS]
}] }, { type: i0.NgZone }, { type: i2.ScrollDispatcher }, { type: i3.Platform }], propDecorators: { tooltip: [{
type: Input,
args: ['lyTooltip']
}], showDelay: [{
type: Input,
args: ['lyTooltipShowDelay']
}], hideDelay: [{
type: Input,
args: ['lyTooltipHideDelay']
}], placement: [{
type: Input,
args: ['lyTooltipPlacement']
}], xPosition: [{
type: Input,
args: ['lyTooltipXPosition']
}], yPosition: [{
type: Input,
args: ['lyTooltipYPosition']
}] } });
class LyTooltipModule {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTooltipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.10", ngImport: i0, type: LyTooltipModule, declarations: [LyTooltip], imports: [LyOverlayModule], exports: [LyTooltip] }); }
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTooltipModule, imports: [LyOverlayModule] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTooltipModule, decorators: [{
type: NgModule,
args: [{
imports: [LyOverlayModule],
declarations: [LyTooltip],
exports: [LyTooltip]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { LY_TOOLTIP_DEFAULT_OPTIONS, LyTooltip, LyTooltipModule, STYLES };
//# sourceMappingURL=alyle-ui-tooltip.mjs.map