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