UNPKG

@kelvininc/ui-components

Version:
331 lines (321 loc) 15 kB
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-BOTigrTZ.js'; import { o as offset, b as shift, c as arrow, h as hide, d as computePosition, e as autoUpdate, a as autoPlacement } from './floating-ui.dom-CJTtq_QG.js'; import { b as DEFAULT_PORTAL_Z_INDEX, c as TOOLTIP_Z_INDEX } from './config-DfTrc9q6.js'; import { m as mergeComputePositionConfigs } from './floating-ui.helper-BoQ1sJsH.js'; import { i as isNil } from './isNil-DjSNdVAB.js'; import { b as getCollapsedElement } from './utils-Douu2-ri.js'; import { a as getClassMap } from './css-class.helper-DCOsOAOy.js'; import { i as isEmpty } from './isEmpty-DYR6-7ab.js'; import './wizard.types-COrzvkrr.js'; import './_baseMerge-ECDD_Loo.js'; import './identity-CK4jS9_E.js'; import './isObject-Dkd2PDJ-.js'; import './_setToArray-WfAeX5vN.js'; const PORTAL_Z_INDEX = { hidden: -1, show: DEFAULT_PORTAL_Z_INDEX }; const OFFSET_WITH_ARROW = 10; const STATIC_SIDE_OFFSET = '-5px'; const getArrowElementPositionConfig = (x, y, placement) => { const staticSide = { top: 'bottom', right: 'left', bottom: 'top', left: 'right' }[placement.split('-')[0]]; return { left: x != null ? `${x}px` : '', top: y != null ? `${y}px` : '', right: '', bottom: '', [staticSide]: STATIC_SIDE_OFFSET, transform: 'rotate(45deg)' }; }; const DEFAULT_OFFSET = 5; const DEFAULT_SHIFT_CONFIG = { padding: 5 }; const portalCss = "@property --rotation{syntax:\"<angle>\";initial-value:0deg;inherits:false}@keyframes rotate-border{to{--rotation:360deg}}kv-dropdown-base:not(.hydrated)>[slot=list]{display:none}:host{--portal-arrow-color:var(--tooltip-background-default)}.portal-container{visibility:hidden;opacity:0}.portal-container--visible{visibility:visible;opacity:1}.portal-container--visible.portal-container--animated{transition:opacity 0.3s linear}.portal-container .portal-arrow{position:absolute;background:var(--portal-arrow-color);width:10px;height:10px}"; const KvPortal = class { constructor(hostRef) { registerInstance(this, hostRef); this.elementAppend = createEvent(this, "elementAppend", 7); /** @inheritdoc */ this.portalId = 'kv-portal'; /** @inheritdoc */ this.show = false; /** @inheritdoc */ this.autoUpdate = true; /** @inheritdoc */ this.animated = false; /** @inheritdoc */ this.withArrow = false; /** @inheritdoc */ this.delay = 0; /** @inheritdoc */ this.zIndex = PORTAL_Z_INDEX.show; this.visible = false; this.moved = false; this.getPortalArrowElement = () => { return this.element.shadowRoot.querySelector('#portal-arrow'); }; this.getMiddlewareConfig = () => { const arrowElement = this.getPortalArrowElement(); const offSet = this.withArrow ? OFFSET_WITH_ARROW : DEFAULT_OFFSET; const middleware = [offset(offSet), shift(DEFAULT_SHIFT_CONFIG)]; if (this.withArrow) middleware.push(arrow({ element: arrowElement, padding: 5 })); middleware.push(hide({ padding: 15 })); return middleware; }; this.getOptions = () => { const middleware = this.getMiddlewareConfig(); return mergeComputePositionConfigs({ middleware }, this.options); }; } showWatch(newValue) { if (newValue) { this.showPortalContent(); } else { this.hidePortalContent(); } } referenceWatch() { if (this.show) { this.showPortalContent(); } } getClosestThemedAncestor() { let current = this.element; while (current) { const themed = current.closest('[data-theme]'); if (themed) return themed; const root = current.getRootNode(); current = root instanceof ShadowRoot ? root.host : null; } return null; } createPortal() { this.portal = document.createElement('div'); this.portal.setAttribute('id', this.portalId); this.portal.style.zIndex = `${PORTAL_Z_INDEX.hidden}`; this.portal.style.position = 'absolute'; // Inherit data-theme from nearest themed ancestor so portal // content resolves the correct design token values. // Traverse shadow DOM boundaries since the portal may be // rendered inside another component's shadow tree (e.g. tooltip). const themedAncestor = this.getClosestThemedAncestor(); const theme = themedAncestor === null || themedAncestor === void 0 ? void 0 : themedAncestor.getAttribute('data-theme'); if (theme) { this.portal.setAttribute('data-theme', theme); } document.body.prepend(this.portal); } moveElementToPortal() { this.portal.appendChild(this.element); this.elementAppend.emit(this.element); } updatePosition() { computePosition(this.reference, this.portal, this.getOptions()).then(({ x, y, placement, middlewareData }) => { if (this.autoUpdate) { const { referenceHidden } = middlewareData.hide; if (this.show) { this.visible = !referenceHidden; this.portal.style.zIndex = referenceHidden ? `${PORTAL_Z_INDEX.hidden}` : `${this.zIndex}`; } } Object.assign(this.portal.style, { left: `${x}px`, top: `${y}px` }); if (this.withArrow) { const { x: arrowX, y: arrowY } = middlewareData.arrow; Object.assign(this.getPortalArrowElement().style, Object.assign({}, getArrowElementPositionConfig(arrowX, arrowY, placement))); } }); } calculatePosition() { if (!this.reference || !this.portal) { return; } if (this.autoUpdate) { this.closeAutoUpdate = autoUpdate(this.reference, this.portal, () => this.updatePosition()); } else { this.updatePosition(); } } showPortalContent() { if (!this.portal) return; this.portal.style.zIndex = `${this.zIndex}`; if (this.delay) { this.timeoutId = window.setTimeout(() => { this.visible = true; this.calculatePosition(); }, this.delay); } else { this.visible = true; this.calculatePosition(); } } hidePortalContent() { this.visible = false; this.portal.style.zIndex = `${PORTAL_Z_INDEX.hidden}`; if (this.timeoutId) { window.clearTimeout(this.timeoutId); this.timeoutId = undefined; } if (!isNil(this.closeAutoUpdate)) { this.closeAutoUpdate(); } } componentWillLoad() { this.createPortal(); } componentDidLoad() { this.moveElementToPortal(); if (this.show) { this.showPortalContent(); } } disconnectedCallback() { var _a; this.moved ? (_a = this.portal) === null || _a === void 0 ? void 0 : _a.remove() : (this.moved = true); } render() { return (h(Host, { key: 'edcd8472eb044ae6d4475cb1f8e63151b831157c' }, h("div", { key: '1ba1eb8760e0104a688235c34a5b3ee6e59fca0b', class: { 'portal-container': true, 'portal-container--animated': this.animated, 'portal-container--visible': this.visible } }, h("slot", { key: '94ed2ad8e45ac3e9287bb5d1dd40eeccfd7fde57' }), this.withArrow && h("div", { key: '04806f60effcb03f57fd7d5344000e9ba3922582', id: "portal-arrow", class: "portal-arrow" })))); } get element() { return getElement(this); } static get watchers() { return { "show": ["showWatch"], "reference": ["referenceWatch"] }; } }; KvPortal.style = portalCss; const DEFAULT_POSITION_CONFIG = { strategy: 'fixed', middleware: [offset(5), shift({ padding: 5 })] }; const DEFAULT_HIDE_DELAY = 1000; const DEFAULT_DELAY_CONFIG = 1000; const DEFAULT_AUTO_PLACEMENT_CONFIG = { padding: 5 }; const isElementCollapsed = (element) => { const collapsedElement = getCollapsedElement(Array.from(element.childNodes)); if (collapsedElement !== undefined) { const range = new Range(); range.selectNodeContents(collapsedElement); const { width: rectWidth } = range.getBoundingClientRect(); const { clientWidth: collapsedWidth } = collapsedElement; // once rectWidth comes as a real value and collapsedWidth as a rounded value, this calculation was incorrect. if (collapsedWidth >= Math.round(rectWidth)) return false; } return true; }; const KvTooltip = class { constructor(hostRef) { registerInstance(this, hostRef); /** @inheritdoc */ this.text = ''; /** @inheritdoc */ this.options = DEFAULT_POSITION_CONFIG; /** @inheritdoc */ this.disabled = false; /** @inheritdoc */ this.contentElement = null; /** @inheritdoc */ this.truncate = false; /** @inheritdoc */ this.delay = DEFAULT_DELAY_CONFIG; /** @inheritdoc */ this.hideDelay = DEFAULT_HIDE_DELAY; /** @inheritdoc */ this.withArrow = false; /** @inheritdoc */ this.customClass = ''; this.showTooltip = false; this.hoverContent = false; this.hoverTooltip = false; this.getContentElement = () => { var _a; return (_a = this.contentElement) !== null && _a !== void 0 ? _a : this.tooltipContent; }; this.getOptions = () => { const placement = isEmpty(this.allowedPositions) ? this.position : undefined; const middleware = []; if (!isEmpty(this.allowedPositions) && isEmpty(placement)) { middleware.push(autoPlacement(Object.assign(Object.assign({}, DEFAULT_AUTO_PLACEMENT_CONFIG), { allowedPlacements: this.allowedPositions }))); } return mergeComputePositionConfigs({ placement, middleware }, this.options); }; this.hideTooltipHandler = (delay) => { if (delay) { setTimeout(() => { if (!this.hoverContent && !this.hoverTooltip) { this.showTooltip = false; } }, delay); return; } this.showTooltip = false; }; this.getTooltipSlotElement = () => { return this.el.querySelector('[slot="tooltip-text"]'); }; this.showTooltipHandler = () => { if (this.disabled || (this.truncate && !isElementCollapsed(this.el))) return; this.showTooltip = true; }; } disconnectedCallback() { this.showTooltip = false; } render() { const tooltipSlotElement = this.getTooltipSlotElement(); return (h(Host, { key: '8cb12be614c78d1bcf039d1b2199763d97735ee7' }, h("div", { key: '8de03a96446c4b1b84918df22059710f506bf117', id: "content", part: "content", ref: el => (this.tooltipContent = el), onMouseOver: () => { this.showTooltipHandler(); this.hoverContent = true; }, onMouseOut: () => { this.hoverContent = false; this.hideTooltipHandler(!isEmpty(tooltipSlotElement) ? this.hideDelay : undefined); }, onBlur: () => { this.hoverContent = false; this.hideTooltipHandler(!isEmpty(tooltipSlotElement) ? this.hideDelay : undefined); }, onClick: () => { this.hoverContent = false; this.hideTooltipHandler(); } }, h("slot", { key: 'adab3af0dbba69f4edbc50e708bfc272d9c59fb3' })), h("div", { key: 'e54dcd487a1b667861d556c176836603eb543b90', style: { display: 'none' } }, h("slot", { key: 'd12f4a5caa826634666eab65b2e04828764ca9ca', name: "tooltip-text" })), this.showTooltip && (!isEmpty(this.text) || !isEmpty(tooltipSlotElement)) && (h("kv-portal", { key: 'aee9fbd2781db2a074c93450f34646d357bd6a7c', zIndex: TOOLTIP_Z_INDEX, show: true, delay: this.delay, withArrow: this.withArrow, animated: true, reference: this.getContentElement(), options: this.getOptions() }, h("kv-tooltip-text", { key: '20b1f2e5f44b0c1b5da1d16a6f4f041a4457ae0c', class: Object.assign({}, getClassMap(this.customClass)), text: this.text, style: this.customStyle, onMouseOver: () => { this.hoverTooltip = true; this.showTooltipHandler(); }, onMouseOut: () => { this.hoverTooltip = false; this.hideTooltipHandler(); }, onBlur: () => { this.hoverTooltip = false; this.hideTooltipHandler(); } }, tooltipSlotElement && h("div", { key: 'b4178ca3ede4d6c087eed3f8989909aee5d51c87', innerHTML: tooltipSlotElement.innerHTML })))))); } get el() { return getElement(this); } }; const tooltipTextCss = "@property --rotation{syntax:\"<angle>\";initial-value:0deg;inherits:false}@keyframes rotate-border{to{--rotation:360deg}}kv-dropdown-base:not(.hydrated)>[slot=list]{display:none}:host{--container-white-space:normal;--container-width:fit-content;--container-max-width:280px;--container-background-color:var(--tooltip-background-default)}.tooltip-container{height:fit-content;width:var(--container-width);max-width:var(--container-max-width);display:inline-block;word-wrap:break-word;background-color:var(--container-background-color);user-select:none;border-radius:var(--tooltip-radius-default);padding:var(--tooltip-padding-y-default) var(--tooltip-padding-x-default);white-space:var(--container-white-space)}.tooltip-container .tooltip-text{font-family:Proxima Nova;font-weight:600;font-size:14px;line-height:20px;letter-spacing:0;color:var(--tooltip-text-default)}"; const KvTooltipText = class { constructor(hostRef) { registerInstance(this, hostRef); /** @inheritdoc */ this.text = ''; } render() { return (h(Host, { key: '70840ea0de71d12ce34b657f0fdf9d2a940f6332' }, h("div", { key: '4ff2b2e412cb5d3531548915b4885f9eb109524f', class: "tooltip-container", part: "tooltip-container" }, this.text && h("div", { key: 'af8d1f527dbc20d141c1e00ff58f5ebbd320014b', class: "tooltip-text" }, this.text), h("div", { key: 'e5a8a93fc9d3c37615c10e060cb6cc4026dd3b71', class: "tooltip-slot", part: "tooltip-slot-content" }, h("slot", { key: '0e011fc72a7b96a2a4324e1715f679092f11473b' }))))); } }; KvTooltipText.style = tooltipTextCss; export { KvPortal as kv_portal, KvTooltip as kv_tooltip, KvTooltipText as kv_tooltip_text };