{"version":3,"sources":["website/cms-tooltip.ts"],"names":["computePosition","flip","shift","offset","arrow","parseIntOrNull","CmsTooltip","HTMLElement","visible","this","_visible","val","constructor","options","super","defaultOptions","placement","TooltipPlacement","Bottom","autoAlign","offsetFromTrigger","clickOpen","triggerSelector","addDefaultStyles","defaultStyles","setupElements","attachShadow","mode","container","document","createElement","classList","add","bodyTemplate","appendChild","firstChild","shadowRoot","id","addStyles","styles","innerHTML","connectedCallback","readOptionsFromAttributes","setTrigger","setPosition","attachEventHandlers","context","trigger","querySelector","previousElementSibling","getFloatingUiPlacementFromOptions","middleware","createMiddleware","then","style","left","comp","x","top","y","arrowX","arrowY","middlewareData","arrowSide","getFloatingUiArrowSideFromPlacement","removeAttribute","Object","assign","right","bottom","toString","push","padding","element","addEventListener","showTooltip","bind","hideTooltip","window","_hideTimeout","clearTimeout","display","setTimeout","split","getAttribute","length","hasAttribute","toLowerCase","customElements","define"],"mappings":"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","file":"cms-tooltip.js","sourcesContent":["import { computePosition, flip, shift, offset, arrow, Middleware } from \"@floating-ui/dom\";\r\nimport { Placement } from \"@floating-ui/core\";\r\nimport { parseIntOrNull } from \"../utils/number.js\";\r\n\r\n/** Attributes:\r\n * selector (string) - Specify a CSS selector for target element for this tooltip.\r\n * styles (bool) - If present, default styles are added.\r\n * placement (string) - Specify where the default placement should be. Base: top, right, bottom, left. Mods: -start, -end.\r\n * offset (number) - Specify a offset (distance) from trigger element to tooltip container in pixels.\r\n */\r\nexport class CmsTooltip extends HTMLElement {\r\n defaultOptions: ITooltipOptions = {\r\n placement: TooltipPlacement.Bottom,\r\n autoAlign: true,\r\n offsetFromTrigger: 6,\r\n clickOpen: false,\r\n triggerSelector: null,\r\n addDefaultStyles: true\r\n };\r\n\r\n options: ITooltipOptions;\r\n\r\n private _hideTimeout: number;\r\n\r\n _visible: boolean = true;\r\n\r\n get visible(){\r\n return this._visible;\r\n }\r\n set visible(val:boolean){\r\n this._visible = val;\r\n }\r\n\r\n defaultStyles = `\r\n h1, h2, h3, h4, h5 { margin: 10px 0 5px; }\r\n .container {\r\n display: none;\r\n position: absolute;\r\n border-radius: 3px;\r\n padding: 10px;\r\n background-color: #000;\r\n color: #fff;\r\n box-shadow: rgb(0 0 0 / 40%) 0 0 5px;\r\n z-index: 2;\r\n font-size: 1.2rem;\r\n }\r\n p {\r\n margin: 0 0 10px;\r\n }\r\n #arrow {\r\n content: '';\r\n position: absolute;\r\n pointer-events: none;\r\n border: 8px solid transparent;\r\n }\r\n #arrow.top{\r\n border-top: none;\r\n border-bottom-color: #000;\r\n filter: drop-shadow(0 -0.0625rem 0.0625rem rgba(0 0 0 / 20%));\r\n }\r\n #arrow.bottom{\r\n border-bottom: none;\r\n border-top-color: #000;\r\n filter: drop-shadow(0 0.0625rem 0.0625rem rgba(0 0 0 / 20%));\r\n }\r\n #arrow.right{\r\n border-right: none;\r\n border-left-color: #000;\r\n filter: drop-shadow(0.1rem 0 0.0625rem rgba(0 0 0 / 20%));\r\n }\r\n #arrow.left{\r\n border-left: none;\r\n border-right-color: #000;\r\n filter: drop-shadow(-0.1rem 0 0.0625rem rgba(0 0 0 / 20%));\r\n }\r\n hr {\r\n border: none;\r\n height: 1px;\r\n background-color: #646464;\r\n }\r\n a {\r\n color: #fff;\r\n }\r\n a:hover {\r\n text-decoration: none;\r\n }\r\n `;\r\n\r\n container: HTMLDivElement;\r\n trigger: HTMLElement;\r\n arrow: HTMLElement;\r\n\r\n constructor(options?: ITooltipOptions) {\r\n super();\r\n\r\n if (options) {\r\n this.options = { ...this.defaultOptions, ...options };\r\n }\r\n\r\n this.setupElements();\r\n }\r\n\r\n setupElements() {\r\n // Attach shadow\r\n this.attachShadow({ mode: \"open\" });\r\n\r\n // Create the main container\r\n this.container = document.createElement(\"div\");\r\n this.container.classList.add(\"container\");\r\n\r\n // Move all children to the container\r\n if (this.options && this.options.bodyTemplate){\r\n this.container.appendChild(this.options.bodyTemplate);\r\n } else {\r\n while(this.firstChild) {\r\n this.container.appendChild(this.firstChild);\r\n }\r\n }\r\n\r\n this.shadowRoot.appendChild(this.container);\r\n\r\n // Add arrow\r\n this.arrow = document.createElement(\"div\");\r\n this.arrow.id = \"arrow\";\r\n this.container.appendChild(this.arrow);\r\n }\r\n\r\n addStyles() {\r\n if (!this.options.addDefaultStyles) {\r\n return;\r\n }\r\n\r\n const styles = document.createElement(\"style\");\r\n styles.innerHTML = this.defaultStyles;\r\n this.shadowRoot.appendChild(styles);\r\n }\r\n\r\n connectedCallback() {\r\n if (!this.options) {\r\n this.readOptionsFromAttributes();\r\n }\r\n\r\n this.addStyles();\r\n this.setTrigger();\r\n this.setPosition();\r\n this.attachEventHandlers();\r\n }\r\n\r\n setTrigger() {\r\n const context = this.options.context ? this.options.context : document;\r\n if (this.options.triggerSelector) {\r\n this.trigger = context.querySelector(this.options.triggerSelector) as HTMLElement;\r\n } else {\r\n // Use sibling above\r\n this.trigger = this.previousElementSibling as HTMLElement;\r\n }\r\n }\r\n\r\n setPosition() {\r\n const placement = this.getFloatingUiPlacementFromOptions();\r\n const middleware = this.createMiddleware();\r\n\r\n computePosition(this.trigger, this.container, {\r\n placement,\r\n middleware\r\n }).then((comp) => {\r\n this.container.style.left = comp.x + \"px\";\r\n this.container.style.top = comp.y + \"px\";\r\n\r\n const {x: arrowX, y: arrowY} = comp.middlewareData.arrow;\r\n const arrowSide = this.getFloatingUiArrowSideFromPlacement(comp.placement);\r\n\r\n this.arrow.removeAttribute(\"class\");\r\n this.arrow.classList.add(arrowSide);\r\n\r\n Object.assign(this.arrow.style, {\r\n left: arrowX != null ? `${arrowX}px` : '',\r\n top: arrowY != null ? `${arrowY}px` : '',\r\n right: '',\r\n bottom: '',\r\n [arrowSide.toString()]: '-8px',\r\n });\r\n });\r\n }\r\n\r\n createMiddleware(): Middleware[] {\r\n const middleware = [offset(this.options.offsetFromTrigger)];\r\n\r\n if (this.options.autoAlign) {\r\n middleware.push(\r\n flip(),\r\n shift({padding: 5})\r\n );\r\n }\r\n\r\n middleware.push(arrow({element: this.arrow}));\r\n\r\n return middleware;\r\n }\r\n\r\n attachEventHandlers() {\r\n this.trigger.addEventListener(\"mouseenter\", this.showTooltip.bind(this));\r\n this.trigger.addEventListener(\"mouseleave\", this.hideTooltip.bind(this));\r\n this.trigger.addEventListener(\"focus\", this.showTooltip.bind(this));\r\n this.trigger.addEventListener(\"blur\", this.hideTooltip.bind(this));\r\n window.addEventListener('scroll', this.setPosition.bind(this));\r\n window.addEventListener('resize', this.setPosition.bind(this));\r\n\r\n // Add event listeners to the tooltip container\r\n this.container.addEventListener(\"mouseenter\", this.showTooltip.bind(this));\r\n this.container.addEventListener(\"mouseleave\", this.hideTooltip.bind(this));\r\n }\r\n\r\n showTooltip() {\r\n if (this._visible === true) {\r\n if (this._hideTimeout) {\r\n window.clearTimeout(this._hideTimeout);\r\n }\r\n this.container.style.display = 'block';\r\n this.setPosition();\r\n }\r\n }\r\n\r\n hideTooltip() {\r\n if (this._hideTimeout) {\r\n window.clearTimeout(this._hideTimeout);\r\n }\r\n\r\n this._hideTimeout = window.setTimeout(() => {\r\n this.container.style.display = '';\r\n } , 100);\r\n }\r\n\r\n getFloatingUiPlacementFromOptions(): Placement {\r\n return (this.options.placement?.toString() || \"bottom\") as Placement;\r\n }\r\n\r\n getFloatingUiArrowSideFromPlacement(placement: string): Placement {\r\n return {\r\n top: 'bottom',\r\n right: 'left',\r\n bottom: 'top',\r\n left: 'right',\r\n }[placement.split('-')[0]] as Placement;\r\n }\r\n\r\n readOptionsFromAttributes() {\r\n this.options = {...this.defaultOptions};\r\n\r\n const triggerSelector = this.getAttribute(\"selector\");\r\n if (triggerSelector && triggerSelector.length) {\r\n this.options.triggerSelector = triggerSelector;\r\n }\r\n\r\n const styles = this.hasAttribute(\"styles\");\r\n this.options.addDefaultStyles = styles;\r\n\r\n const placement = this.getAttribute(\"placement\");\r\n if (placement && placement.length) {\r\n this.options.placement = placement as TooltipPlacement;\r\n }\r\n\r\n const offset = this.getAttribute(\"offset\");\r\n if (offset && offset.length) {\r\n this.options.offsetFromTrigger = parseIntOrNull(offset) || 6;\r\n }\r\n\r\n if (this.hasAttribute(\"visible\")) {\r\n const visible = this.getAttribute(\"visible\");\r\n if (visible && visible.length && (visible.toLowerCase() === \"true\" || visible === \"1\")) {\r\n this._visible = true;\r\n } else {\r\n this._visible = false;\r\n }\r\n }\r\n }\r\n}\r\n\r\ninterface ITooltipOptions {\r\n placement?: TooltipPlacement;\r\n autoAlign?: boolean;\r\n offsetFromTrigger?: number;\r\n clickOpen?: boolean;\r\n triggerSelector?: string;\r\n addDefaultStyles?: boolean;\r\n context?: HTMLElement;\r\n bodyTemplate?: HTMLElement;\r\n}\r\n\r\nexport enum TooltipPlacement {\r\n Top = \"top\",\r\n TopStart = \"top-start\",\r\n TopEnd = \"top-end\",\r\n Right = \"right\",\r\n RightStart = \"right-start\",\r\n RightEnd = \"right-end\",\r\n Bottom = \"bottom\",\r\n BottomStart = \"bottom-start\",\r\n BottomEnd = \"bottom-end\",\r\n Left = \"left\",\r\n LeftStart = \"left-start\",\r\n LeftEnd = \"left-end\"\r\n}\r\n\r\ncustomElements.define('cms-tooltip', CmsTooltip);"]}