leafer-x-tooltip
Version:
leafer tooltip plugin
2 lines (1 loc) • 5.72 kB
JavaScript
import{PointerEvent as t,LeaferEvent as e}from"@leafer-ui/core";const i="leafer-x-tooltip",o="data-lxt-id";function s(t,e){if(t)throw new Error(`[${i}]: ${e}`)}function n(t){return document.querySelector(`[${o}=${t}]`)}function r(t,e,o){let s=o;s&&o instanceof HTMLStyleElement||(s=document.createElement("style"),s.setAttribute(i,""),document.head.appendChild(s));let n="string"==typeof e?e:"";return"object"==typeof e&&Object.keys(e).forEach((t=>{var i;n+=`${i=t,i.replace(/([A-Z])/g,"-$1").toLowerCase()}: ${e[t]};`})),s.sheet?s.sheet.insertRule(`${t} { ${n} }`,0):s.appendChild(document.createTextNode(n)),s}class l{constructor(t,e){this.app=t,this.config=e,this.config.triggerType||(this.config.triggerType="hover"),this.domId=`lxt--${function(t=8){return Math.random().toString(36).slice(2,t+2)}(8)}`,this.bindEventIds=[],this.initEvent(),this.initCssClass(),this.initCreateTooltip(),this._moveTooltip=t=>this.moveTooltip(t),this._hideTooltip=()=>this.hideTooltip()}initEvent(){const i=[];let o=t.MOVE,s=this.leaferPointMove;"click"===this.config.triggerType&&(o=t.CLICK,s=this.leaferPointClick);const n=this.app.on_(o,s,this);i.push(n);const r=this.app.on_(e.VIEW_READY,this.viewReadyEvent,this);i.push(r),this.bindEventIds.push(...i)}shouldShowTooltip(t,e){if(!t||t.isLeafer||t.isApp)return this.hideTooltip(),!1;const i=(o=this.config.includeTypes,s=t.tag,!Array.isArray(o)||0===o.length||o.includes(s));var o,s;const n=function(t,e){return!!Array.isArray(t)&&0!==t.length&&t.includes(e)}(this.config.excludeTypes,t.tag),r=!this.config.shouldBegin||this.config.shouldBegin(e);return!(!i||n||!r)||(this.hideTooltip(),!1)}leaferPointMove(t){const e=t.target;this.activeNode!==e&&this.shouldShowTooltip(e,t)&&(this.activeNode=e)}leaferPointClick(t){const e=t.target;this.shouldShowTooltip(e,t)&&(this.activeNode!==e?(this.activeNode=e,this.app.view instanceof HTMLElement&&this.moveTooltip(t)):this.hideTooltip())}viewReadyEvent(){var t;this.app.view instanceof HTMLElement&&(s(void 0===(null===(t=this.app.view)||void 0===t?void 0:t.addEventListener),"leafer.view 加载失败!"),"hover"===this.config.triggerType&&(this.app.view.addEventListener("mousemove",this._moveTooltip),this.app.view.addEventListener("mouseleave",this._hideTooltip)))}initCssClass(){if(this.styleSheetElement)return;const t=document.querySelector(`.${i}`);this.styleSheetElement=t||r(`.${i}`,{border:"none",borderRadius:"6px",padding:"10px 14px",backgroundColor:"rgba(255, 255, 255, 0.95)",color:"#333",fontSize:"13px",fontWeight:"400",boxShadow:"0 3px 14px rgba(0, 0, 0, 0.15)",backdropFilter:"blur(8px)",transition:"opacity,top, left 0.2s ease-in-out"})}initCreateTooltip(){let t=n(this.domId);const e=null!==t;return e||(t=document.createElement("div")),t.setAttribute(o,this.domId),t.style.display="none",this.config.className?t.className=this.config.className:e||(t.className=i),e||document.body.appendChild(t),t}hideTooltip(){this.activeNode=null;const t=n(this.domId);t&&(t.style.display="none")}calculateTooltipPosition(e,i){const o=window.innerWidth,s=window.innerHeight,n=window.scrollX,r=window.scrollY;let l=0,h=0;e instanceof t?(l=e.origin.x+n,h=e.origin.y+r):e instanceof MouseEvent?(l=e.clientX+n,h=e.clientY+r):(l=e.x+n,h=e.y+r);const a=i.offsetWidth,d=i.offsetHeight,c=this.getOffset();let p=l+c.x,v=h+c.y;return p+a>o+n&&(p=l-a-c.x),v+d>s+r&&(v=h-d-c.y),{x:p,y:v}}getTooltipContent(){const t=typeof this.config.getContent;s("function"!==t,`getContent 为必传参数,且必须是一个函数,当前为:${t} 类型`);const e=this.config.getContent(this.activeNode);return s(null==e||""===e,"getContent 返回值不能为空"),e}moveTooltip(t){if(null===this.activeNode)return;let e=n(this.domId);e||(e=this.initCreateTooltip()),e.innerHTML=this.getTooltipContent();const{x:i,y:o}=this.calculateTooltipPosition(t,e);var s,r;s=e,r={display:"block",position:"absolute",left:`${i}px`,top:`${o}px`},requestAnimationFrame((()=>{Object.entries(r).forEach((([t,e])=>{s.style[t]=e}))}))}getDomId(){return this.domId}getOffset(){const t=this.config.offset;if("number"==typeof t)return{x:t,y:t};if(Array.isArray(t)){const[e,i]=t;return{x:e,y:i}}return"object"==typeof t?t:{x:6,y:6}}createStyleRule(t,e){r(`${t}[${o}=${this.domId}]`,e,this.styleSheetElement)}removeStyleRule(t){const e=this.styleSheetElement.sheet;if(!e)return;const i=this.findStyleRuleIndex(t);-1!==i&&e.deleteRule(i)}findStyleRuleIndex(t){const e=this.styleSheetElement.sheet;if(!e)return-1;const i=e.cssRules,s=`${t}[${o}=${this.domId}]`;for(let t=0;t<i.length;t++){if(i[t].selectorText===s)return t}return-1}addClass(t){const e=n(this.domId);e&&(Array.isArray(t)?t.forEach((t=>e.classList.add(t))):e.classList.add(t))}removeClass(t){const e=n(this.domId);e&&(Array.isArray(t)?t.forEach((t=>e.classList.remove(t))):e.classList.remove(t))}destroy(){this.app.off_(this.bindEventIds),this.bindEventIds.length=0,this.app.view instanceof HTMLElement&&(this.app.view.removeEventListener("mousemove",this._moveTooltip),this.app.view.removeEventListener("mouseleave",this._hideTooltip)),this.activeNode=null;const t=n(this.domId);t&&t.parentNode&&t.parentNode.removeChild(t)}setTriggerType(t){if(this.config.triggerType===t)return;const e=this.config.triggerType;this.app.off_(this.bindEventIds),this.bindEventIds.length=0,this.config.triggerType=t,this.initEvent(),this.app.view instanceof HTMLElement&&("click"===t&&"hover"===e?(this.app.view.removeEventListener("mousemove",this._moveTooltip),this.app.view.removeEventListener("mouseleave",this._hideTooltip)):"hover"===t&&"click"===e&&(this.app.view.addEventListener("mousemove",this._moveTooltip),this.app.view.addEventListener("mouseleave",this._hideTooltip))),this.hideTooltip()}}export{l as TooltipPlugin};