igniteui-webcomponents
Version:
Ignite UI for Web Components is a complete library of UI components, giving you the ability to build modern web applications using encapsulation and the concept of reusable components in a dependency-free approach.
288 lines • 10 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;
};
import { html, LitElement, nothing } from 'lit';
import { property, query } from 'lit/decorators.js';
import { createRef, ref } from 'lit/directives/ref.js';
import { EaseOut } from '../../animations/easings.js';
import { addAnimationController } from '../../animations/player.js';
import { fadeOut } from '../../animations/presets/fade/index.js';
import { scaleInCenter } from '../../animations/presets/scale/index.js';
import { addThemingController } from '../../theming/theming-controller.js';
import { addInternalsController } from '../common/controllers/internals.js';
import { registerComponent } from '../common/definitions/register.js';
import { EventEmitterMixin } from '../common/mixins/event-emitter.js';
import { asNumber, isLTR } from '../common/util.js';
import IgcIconComponent from '../icon/icon.js';
import IgcPopoverComponent from '../popover/popover.js';
import { addTooltipController, TooltipRegexes } from './controller.js';
import { styles as shared } from './themes/shared/tooltip.common.css.js';
import { all } from './themes/themes.js';
import { styles } from './themes/tooltip.base.css.js';
class IgcTooltipComponent extends EventEmitterMixin(LitElement) {
static register() {
registerComponent(IgcTooltipComponent, IgcPopoverComponent, IgcIconComponent);
}
get _arrowOffset() {
if (this.placement.includes('-')) {
if (TooltipRegexes.horizontalStart.test(this.placement)) {
return -8;
}
if (TooltipRegexes.horizontalEnd.test(this.placement)) {
return 8;
}
if (TooltipRegexes.start.test(this.placement)) {
return isLTR(this) ? -8 : 8;
}
if (TooltipRegexes.end.test(this.placement)) {
return isLTR(this) ? 8 : -8;
}
}
return 0;
}
set open(value) {
this._controller.open = value;
}
get open() {
return this._controller.open;
}
set disableArrow(value) {
this.withArrow = !value;
}
get disableArrow() {
return !this.withArrow;
}
set showTriggers(value) {
this._controller.showTriggers = value;
}
get showTriggers() {
return this._controller.showTriggers;
}
set hideTriggers(value) {
this._controller.hideTriggers = value;
}
get hideTriggers() {
return this._controller.hideTriggers;
}
set showDelay(value) {
this._showDelay = Math.max(0, asNumber(value));
}
get showDelay() {
return this._showDelay;
}
set hideDelay(value) {
this._hideDelay = Math.max(0, asNumber(value));
}
get hideDelay() {
return this._hideDelay;
}
constructor() {
super();
this._internals = addInternalsController(this, {
initialARIA: {
role: 'tooltip',
ariaAtomic: 'true',
ariaLive: 'polite',
},
});
this._controller = addTooltipController(this, {
onShow: this._showOnInteraction,
onHide: this._hideOnInteraction,
onEscape: this._hideOnEscape,
});
this._containerRef = createRef();
this._player = addAnimationController(this, this._containerRef);
this._showAnimation = scaleInCenter({
duration: 150,
easing: EaseOut.Quad,
});
this._hideAnimation = fadeOut({
duration: 75,
easing: EaseOut.Sine,
});
this._autoHideDelay = 180;
this._showDelay = 200;
this._hideDelay = 300;
this.withArrow = false;
this.offset = 6;
this.placement = 'bottom';
this.message = '';
this.sticky = false;
addThemingController(this, all);
}
firstUpdated() {
if (this.open) {
this.updateComplete.then(() => {
this._player.playExclusive(this._showAnimation);
this.requestUpdate();
});
}
}
willUpdate(changedProperties) {
if (changedProperties.has('anchor')) {
this._controller.resolveAnchor(this.anchor);
}
if (changedProperties.has('sticky')) {
this._internals.setARIA({ role: this.sticky ? 'status' : 'tooltip' });
}
}
_emitEvent(name) {
return this.emitEvent(name, {
cancelable: name === 'igcOpening' || name === 'igcClosing',
});
}
async _applyTooltipState({ show, withDelay = false, withEvents = false, }) {
if (show === this.open) {
return false;
}
if (withEvents && !this._emitEvent(show ? 'igcOpening' : 'igcClosing')) {
return false;
}
const commitStateChange = async () => {
if (show) {
this.open = true;
}
this.inert = true;
const animationComplete = await this._player.playExclusive(show ? this._showAnimation : this._hideAnimation);
this.inert = false;
this.open = show;
if (animationComplete && withEvents) {
this._emitEvent(show ? 'igcOpened' : 'igcClosed');
}
return animationComplete;
};
if (withDelay) {
clearTimeout(this._timeoutId);
return new Promise(() => {
this._timeoutId = setTimeout(async () => await commitStateChange(), show ? this.showDelay : this.hideDelay);
});
}
return commitStateChange();
}
async show(target) {
if (target) {
this._stopTimeoutAndAnimation();
this._controller.setAnchor(target, true);
}
return await this._applyTooltipState({ show: true });
}
async hide() {
return await this._applyTooltipState({ show: false });
}
async toggle() {
return await (this.open ? this.hide() : this.show());
}
_showWithEvent() {
return this._applyTooltipState({
show: true,
withDelay: true,
withEvents: true,
});
}
_hideWithEvent() {
return this._applyTooltipState({
show: false,
withDelay: true,
withEvents: true,
});
}
_showOnInteraction() {
this._stopTimeoutAndAnimation();
this._showWithEvent();
}
_stopTimeoutAndAnimation() {
clearTimeout(this._timeoutId);
this._player.stopAll();
}
_setAutoHide() {
this._stopTimeoutAndAnimation();
this._timeoutId = setTimeout(this._hideWithEvent.bind(this), this._autoHideDelay);
}
_hideOnInteraction() {
if (!this.sticky) {
this._setAutoHide();
}
}
async _hideOnEscape() {
await this.hide();
this._emitEvent('igcClosed');
}
render() {
return html `
<igc-popover
.inert=${!this.open}
.placement=${this.placement}
.offset=${this.offset}
.anchor=${this._controller.anchor ?? undefined}
.arrow=${this.withArrow ? this._arrowElement : null}
.arrowOffset=${this._arrowOffset}
.shiftPadding=${8}
?open=${this.open}
flip
shift
>
<div ${ref(this._containerRef)} part="base">
<slot>${this.message}</slot>
${this.sticky
? html `
<slot name="close-button" =${this._setAutoHide}>
<igc-icon
name="input_clear"
collection="default"
aria-hidden="true"
></igc-icon>
</slot>
`
: nothing}
${this.withArrow ? html `<div id="arrow"></div>` : nothing}
</div>
</igc-popover>
`;
}
}
IgcTooltipComponent.tagName = 'igc-tooltip';
IgcTooltipComponent.styles = [styles, shared];
export default IgcTooltipComponent;
__decorate([
query('#arrow')
], IgcTooltipComponent.prototype, "_arrowElement", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcTooltipComponent.prototype, "open", null);
__decorate([
property({ type: Boolean, attribute: 'disable-arrow' })
], IgcTooltipComponent.prototype, "disableArrow", null);
__decorate([
property({ type: Boolean, reflect: true, attribute: 'with-arrow' })
], IgcTooltipComponent.prototype, "withArrow", void 0);
__decorate([
property({ type: Number })
], IgcTooltipComponent.prototype, "offset", void 0);
__decorate([
property()
], IgcTooltipComponent.prototype, "placement", void 0);
__decorate([
property()
], IgcTooltipComponent.prototype, "anchor", void 0);
__decorate([
property({ attribute: 'show-triggers' })
], IgcTooltipComponent.prototype, "showTriggers", null);
__decorate([
property({ attribute: 'hide-triggers' })
], IgcTooltipComponent.prototype, "hideTriggers", null);
__decorate([
property({ attribute: 'show-delay', type: Number })
], IgcTooltipComponent.prototype, "showDelay", null);
__decorate([
property({ attribute: 'hide-delay', type: Number })
], IgcTooltipComponent.prototype, "hideDelay", null);
__decorate([
property()
], IgcTooltipComponent.prototype, "message", void 0);
__decorate([
property({ type: Boolean, reflect: true })
], IgcTooltipComponent.prototype, "sticky", void 0);
//# sourceMappingURL=tooltip.js.map