@postnord/web-components
Version:
PostNord Web Components
164 lines (163 loc) • 5.88 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { h } from "@stencil/core";
import { alert_exclamation_circle, alert_question_circle } from "pn-design-assets/pn-assets/icons.js";
/**
* The `pn-tooltip` can display slotted HTML content or a text `string` with the `tooltip` prop.
*
* Remember that the component is techincally a `button` element, don't put any HTML content that would be out of place in a regular button
* (no headlines, other input elements, etc...).
*/
export class PnTooltip {
constructor() {
this.downwards = false;
this.open = false;
this.deltaX = '0';
this.warning = false;
this.light = false;
this.tooltip = undefined;
}
content;
button;
openEvents = ['mouseover', 'focus'];
closeEvents = ['mouseleave', 'blur', 'touchcancel', 'touchleave'];
eventListeners = [...this.openEvents, ...this.closeEvents];
timeout;
hostElement;
openHandler() {
if (this.open)
this.checkPosition();
else
this.setTransform();
}
componentDidLoad() {
this.initTooltip();
}
setTransform() {
this.content.style.transform = `scale(${Number(this.open)}) translateX(-50%) translateX(${this.deltaX}px)`;
}
getSymbol() {
return this.warning ? alert_exclamation_circle : alert_question_circle;
}
checkPosition() {
this.content.style.transition = 'none';
this.content.style.transform = 'scale(1) translateX(-50%)';
this.downwards = false;
requestAnimationFrame(() => {
const { x, y, right } = this.content.getBoundingClientRect();
const extraMargin = 8;
this.deltaX = '0';
this.downwards = y < 0;
this.content.style.transform = '';
if (x < 0)
this.deltaX = `${x * -1 + extraMargin}`; // left edge
if (right > window.innerWidth)
this.deltaX = `${window.innerWidth - right - extraMargin}`; // right edge
requestAnimationFrame(() => {
this.content.style.transition = '';
this.setTransform();
});
});
}
initTooltip() {
this.eventListeners.forEach(name => this.button.addEventListener(name, (event) => this.toggleTooltip(event)));
}
toggleTooltip(event) {
const status = this.openEvents.includes(event.type);
let time = 500;
if (status)
time = 0;
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.open = status;
}, time);
}
render() {
return (h("button", { key: '4af82a42d7ee5bb28bcafa9d34506b04338b5a0d', class: "pn-tooltip", "data-light": this.light, "data-warning": this.warning, "data-downwards": this.downwards, "data-open": this.open, ref: el => (this.button = el) }, h("pn-icon", { key: 'a28cf981da757f7cc416975f74c4e20db571e007', icon: this.getSymbol(), "data-simple": !!this.tooltip }), h("div", { key: '891033b474703748299056f72e04035eb20ca20a', class: "pn-tooltip-content", "data-simple": !!this.tooltip, ref: el => (this.content = el) }, this.tooltip, h("div", { key: 'a91b922f39fd74940dedc27285d60bf7434213b3', hidden: !!this.tooltip }, h("slot", { key: 'eb20b28ee00fe442dff1d5fb77d887a669ef8193' })))));
}
static get is() { return "pn-tooltip"; }
static get originalStyleUrls() {
return {
"$": ["pn-tooltip.scss"]
};
}
static get styleUrls() {
return {
"$": ["pn-tooltip.css"]
};
}
static get properties() {
return {
"warning": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Apply the warning color and change the icon to `!`."
},
"attribute": "warning",
"reflect": false,
"defaultValue": "false"
},
"light": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Apply the light color if you use a dark background."
},
"attribute": "light",
"reflect": false,
"defaultValue": "false"
},
"tooltip": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": false,
"optional": true,
"docs": {
"tags": [],
"text": "Overrides the slotted content to create a small tooltip instead."
},
"attribute": "tooltip",
"reflect": false
}
};
}
static get states() {
return {
"downwards": {},
"open": {},
"deltaX": {}
};
}
static get elementRef() { return "hostElement"; }
static get watchers() {
return [{
"propName": "open",
"methodName": "openHandler"
}];
}
}
//# sourceMappingURL=pn-tooltip.js.map