@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
356 lines (355 loc) • 10 kB
JavaScript
import { Component, Element, Host, Method, Prop, State, Watch, h } from "@stencil/core";
import { CSS, TOOLTIP_REFERENCE, ARIA_DESCRIBED_BY } from "./resources";
import { guid } from "../../utils/guid";
import { defaultOffsetDistance, createPopper, updatePopper, CSS as PopperCSS } from "../../utils/popper";
import { queryElementRoots } from "../../utils/dom";
export class CalciteTooltip {
constructor() {
/**
* Offset the position of the popover away from the reference element.
*/
this.offsetDistance = defaultOffsetDistance;
/**
* Offset the position of the popover along the reference element.
*/
this.offsetSkidding = 0;
/**
* Display and position the component.
*/
this.open = false;
/** Describes the type of positioning to use for the overlaid content. If your element is in a fixed container, use the 'fixed' value. */
this.overlayPositioning = "absolute";
/**
* Determines where the component will be positioned relative to the referenceElement.
*/
this.placement = "auto";
this._referenceElement = this.getReferenceElement();
this.guid = `calcite-tooltip-${guid()}`;
// --------------------------------------------------------------------------
//
// Private Methods
//
// --------------------------------------------------------------------------
this.getId = () => {
return this.el.id || this.guid;
};
this.addReferences = () => {
const { _referenceElement } = this;
if (!_referenceElement) {
return;
}
const id = this.getId();
_referenceElement.setAttribute(TOOLTIP_REFERENCE, id);
_referenceElement.setAttribute(ARIA_DESCRIBED_BY, id);
};
this.removeReferences = () => {
const { _referenceElement } = this;
if (!_referenceElement) {
return;
}
_referenceElement.removeAttribute(TOOLTIP_REFERENCE);
_referenceElement.removeAttribute(ARIA_DESCRIBED_BY);
};
this.show = () => {
this.open = true;
};
this.hide = () => {
this.open = false;
};
}
offsetDistanceOffsetHandler() {
this.reposition();
}
offsetSkiddingHandler() {
this.reposition();
}
openHandler() {
this.reposition();
}
placementHandler() {
this.reposition();
}
referenceElementHandler() {
this.removeReferences();
this._referenceElement = this.getReferenceElement();
this.addReferences();
this.createPopper();
}
// --------------------------------------------------------------------------
//
// Lifecycle
//
// --------------------------------------------------------------------------
componentDidLoad() {
this.addReferences();
this.createPopper();
}
disconnectedCallback() {
this.removeReferences();
this.destroyPopper();
}
// --------------------------------------------------------------------------
//
// Public Methods
//
// --------------------------------------------------------------------------
async reposition() {
const { popper, el, placement } = this;
const modifiers = this.getModifiers();
popper
? updatePopper({
el,
modifiers,
placement,
popper
})
: this.createPopper();
}
getReferenceElement() {
const { referenceElement, el } = this;
return ((typeof referenceElement === "string"
? queryElementRoots(el, `#${referenceElement}`)
: referenceElement) || null);
}
getModifiers() {
const { arrowEl, offsetDistance, offsetSkidding } = this;
const arrowModifier = {
name: "arrow",
enabled: true,
options: {
element: arrowEl
}
};
const offsetModifier = {
name: "offset",
enabled: true,
options: {
offset: [offsetSkidding, offsetDistance]
}
};
return [arrowModifier, offsetModifier];
}
createPopper() {
this.destroyPopper();
const { el, placement, _referenceElement: referenceEl, overlayPositioning } = this;
const modifiers = this.getModifiers();
this.popper = createPopper({
el,
modifiers,
placement,
overlayPositioning,
referenceEl
});
}
destroyPopper() {
const { popper } = this;
if (popper) {
popper.destroy();
}
this.popper = null;
}
// --------------------------------------------------------------------------
//
// Render Methods
//
// --------------------------------------------------------------------------
render() {
const { _referenceElement, label, open } = this;
const displayed = _referenceElement && open;
const hidden = !displayed;
return (h(Host, { "aria-hidden": hidden.toString(), "aria-label": label, "calcite-hydrated-hidden": hidden, id: this.getId(), role: "tooltip" },
h("div", { class: {
[PopperCSS.animation]: true,
[PopperCSS.animationActive]: displayed
} },
h("div", { class: CSS.arrow, ref: (arrowEl) => (this.arrowEl = arrowEl) }),
h("div", { class: CSS.container },
h("slot", null)))));
}
static get is() { return "calcite-tooltip"; }
static get encapsulation() { return "shadow"; }
static get originalStyleUrls() { return {
"$": ["calcite-tooltip.scss"]
}; }
static get styleUrls() { return {
"$": ["calcite-tooltip.css"]
}; }
static get properties() { return {
"label": {
"type": "string",
"mutable": false,
"complexType": {
"original": "string",
"resolved": "string",
"references": {}
},
"required": true,
"optional": false,
"docs": {
"tags": [],
"text": "Accessible name for the component"
},
"attribute": "label",
"reflect": false
},
"offsetDistance": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Offset the position of the popover away from the reference element."
},
"attribute": "offset-distance",
"reflect": true,
"defaultValue": "defaultOffsetDistance"
},
"offsetSkidding": {
"type": "number",
"mutable": false,
"complexType": {
"original": "number",
"resolved": "number",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Offset the position of the popover along the reference element."
},
"attribute": "offset-skidding",
"reflect": true,
"defaultValue": "0"
},
"open": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Display and position the component."
},
"attribute": "open",
"reflect": true,
"defaultValue": "false"
},
"overlayPositioning": {
"type": "string",
"mutable": false,
"complexType": {
"original": "OverlayPositioning",
"resolved": "\"absolute\" | \"fixed\"",
"references": {
"OverlayPositioning": {
"location": "import",
"path": "../../utils/popper"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Describes the type of positioning to use for the overlaid content. If your element is in a fixed container, use the 'fixed' value."
},
"attribute": "overlay-positioning",
"reflect": false,
"defaultValue": "\"absolute\""
},
"placement": {
"type": "string",
"mutable": false,
"complexType": {
"original": "PopperPlacement",
"resolved": "Placement | PlacementRtl | VariationRtl",
"references": {
"PopperPlacement": {
"location": "import",
"path": "../../utils/popper"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Determines where the component will be positioned relative to the referenceElement."
},
"attribute": "placement",
"reflect": true,
"defaultValue": "\"auto\""
},
"referenceElement": {
"type": "string",
"mutable": false,
"complexType": {
"original": "HTMLElement | string",
"resolved": "HTMLElement | string",
"references": {
"HTMLElement": {
"location": "global"
}
}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Reference HTMLElement used to position this component."
},
"attribute": "reference-element",
"reflect": false
}
}; }
static get states() { return {
"_referenceElement": {}
}; }
static get methods() { return {
"reposition": {
"complexType": {
"signature": "() => Promise<void>",
"parameters": [],
"references": {
"Promise": {
"location": "global"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "",
"tags": []
}
}
}; }
static get elementRef() { return "el"; }
static get watchers() { return [{
"propName": "offsetDistance",
"methodName": "offsetDistanceOffsetHandler"
}, {
"propName": "offsetSkidding",
"methodName": "offsetSkiddingHandler"
}, {
"propName": "open",
"methodName": "openHandler"
}, {
"propName": "placement",
"methodName": "placementHandler"
}, {
"propName": "referenceElement",
"methodName": "referenceElementHandler"
}]; }
}