UNPKG

@kelvininc/ui-components

Version:
154 lines (147 loc) 7.9 kB
import { H as proxyCustomElement, I as H, J as createEvent, x as ETabItemType, K as h, o as EBadgeType, z as ETagState } from './p-BP5CxQcH.js'; import { d as defineCustomElement$5 } from './p-CJTppmYq.js'; import { d as defineCustomElement$4 } from './p-DQ7v6WT-.js'; import { d as defineCustomElement$3 } from './p-Dx7sxQCt.js'; import { d as defineCustomElement$2 } from './p-hhSEa0Xf.js'; import { i as isEmpty } from './p-BZNGlO8m.js'; const TEXT_FONT_DESCRIPTION = '600 16px Proxima Nova'; const BADGE_FONT_DESCRIPTION = '400 14px Proxima Nova'; const BADGE_PADDING_PX = 8; const TAB_ITEM_PADDING_PX = 48; const TAB_ITEM_GAP_PX = 8; const TAB_ITEM_ICON_WIDTH_PX = 16; const calculatePrimaryTabWidths = async (tabs) => { await document.fonts.load(TEXT_FONT_DESCRIPTION); await document.fonts.load(BADGE_FONT_DESCRIPTION); const textMeasuringCanvas = document.createElement('canvas'); const textCtx = textMeasuringCanvas.getContext('2d'); textCtx.font = TEXT_FONT_DESCRIPTION; const badgeMeasuringCanvas = document.createElement('canvas'); const badgeCtx = badgeMeasuringCanvas.getContext('2d'); badgeCtx.font = BADGE_FONT_DESCRIPTION; const values = tabs.reduce((acc, { tabKey, label, tagIcon, badge }, idx) => { const previousTab = idx > 0 ? tabs[idx - 1] : undefined; const leftOffset = previousTab ? +acc[previousTab.tabKey].width + +acc[previousTab.tabKey].left : 0; const tagIconWidth = tagIcon ? TAB_ITEM_ICON_WIDTH_PX + TAB_ITEM_GAP_PX : 0; const textWidth = Math.round(textCtx.measureText(label).width); const badgeWidth = badge ? Math.round(badgeCtx.measureText(badge).width) + BADGE_PADDING_PX + TAB_ITEM_GAP_PX : 0; acc[tabKey] = { left: `${leftOffset}`, width: `${textWidth + TAB_ITEM_PADDING_PX + tagIconWidth + badgeWidth}` }; return acc; }, {}); return values; }; const tabNavigationCss = "@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{--tab-list-bg-color:transparent;--tab-list-indicator-color:var(--tab-primary-border-color-selected);--tab-list-divider-color:var(--tab-primary-border-color-default);--secondary-tab-list-direction:row;--secondary-items-align:center}:host .primary{position:relative;width:100%;display:flex;background-color:var(--tab-list-bg-color)}:host .primary::before{content:\"\";width:100%;position:absolute;bottom:0;border-bottom:var(--tab-primary-border-thickness-default) solid var(--tab-list-divider-color)}:host .primary .selected-tab-indicator{height:var(--tab-primary-border-thickness-strong);position:absolute;bottom:0;transition:all 0.3s ease-out;background:var(--tab-list-indicator-color)}:host .secondary{display:flex;gap:var(--spacing-xl);align-items:var(--secondary-items-align);flex-direction:var(--secondary-tab-list-direction)}:host kv-badge{--badge-height:var(--size-md)}:host kv-tag-status{--tag-status-icon-size:var(--size-md)}"; const KvTabNavigation$1 = /*@__PURE__*/ proxyCustomElement(class KvTabNavigation extends H { constructor() { super(); this.__registerHost(); this.__attachShadow(); this.tabChange = createEvent(this, "tabChange", 7); /** @inheritdoc */ this.tabs = []; /** @inheritdoc */ this.type = ETabItemType.Primary; this.tabsIndicatorConfig = {}; /** The left offset and width of the tab indicator, recalculated when the selected tab changes */ this.selectedTabIndicatorConfig = { left: '0px', width: '0px' }; } /** Listen to custom DOM event of tab selection */ tabSelectionHandler(event) { this.tabChange.emit(event.detail); } /** Watch for tabs change to calculate elements width */ async tabsChangeHandler() { if (this.type === ETabItemType.Primary) { this.tabsIndicatorConfig = await calculatePrimaryTabWidths(this.tabs); this.applySelectedTabStyling(); } } /** Watch for tab selection change and react accordingly by updating the internal states */ async tabSelectionChangeHandler() { if (this.type === ETabItemType.Secondary) return; if (isEmpty(this.tabsIndicatorConfig)) { this.tabsIndicatorConfig = await calculatePrimaryTabWidths(this.tabs); } this.applySelectedTabStyling(); } async componentDidLoad() { if (this.type === ETabItemType.Primary) { this.tabsIndicatorConfig = await calculatePrimaryTabWidths(this.tabs); this.applySelectedTabStyling(); } } applySelectedTabStyling() { if (isEmpty(this.selectedTabKey) || isEmpty(this.tabsIndicatorConfig[this.selectedTabKey])) return; const { left, width } = this.tabsIndicatorConfig[this.selectedTabKey]; this.selectedTabIndicatorConfig = { left: `${left}px`, width: `${width}px` }; } render() { return (h("div", { key: '5d92049120e60dfb35381b6caece9453c3297c79', class: { [this.type]: true } }, this.tabs.map(item => { var _a, _b; return (h("kv-tab-item", { key: item.tabKey, tabKey: item.tabKey, label: item.label, icon: item.icon, disabled: item.disabled, selected: item.tabKey === this.selectedTabKey, type: this.type, customAttributes: item.customAttributes }, (!isEmpty(item.badge) || !isEmpty(item.tagIcon)) && (h("div", { slot: "right-slot" }, !isEmpty(item.badge) && h("kv-badge", { type: (_a = item.badgeType) !== null && _a !== void 0 ? _a : EBadgeType.Secondary }, item.badge), !isEmpty(item.tagIcon) && h("kv-tag-status", { icon: item.tagIcon, state: (_b = item.tagState) !== null && _b !== void 0 ? _b : ETagState.Unknown }))))); }), this.type === ETabItemType.Primary && h("div", { key: '0d8efc09b49d09b7d3c9da1810bb82f3a99eeb0d', class: "selected-tab-indicator", style: this.selectedTabIndicatorConfig }))); } static get watchers() { return { "tabs": ["tabsChangeHandler"], "type": ["tabsChangeHandler"], "selectedTabKey": ["tabSelectionChangeHandler"] }; } static get style() { return tabNavigationCss; } }, [257, "kv-tab-navigation", { "tabs": [16], "selectedTabKey": [8, "selected-tab-key"], "type": [1], "selectedTabIndicatorConfig": [32] }, [[0, "tabSelected", "tabSelectionHandler"]], { "tabs": ["tabsChangeHandler"], "type": ["tabsChangeHandler"], "selectedTabKey": ["tabSelectionChangeHandler"] }]); function defineCustomElement$1() { if (typeof customElements === "undefined") { return; } const components = ["kv-tab-navigation", "kv-badge", "kv-icon", "kv-tab-item", "kv-tag-status"]; components.forEach(tagName => { switch (tagName) { case "kv-tab-navigation": if (!customElements.get(tagName)) { customElements.define(tagName, KvTabNavigation$1); } break; case "kv-badge": if (!customElements.get(tagName)) { defineCustomElement$5(); } break; case "kv-icon": if (!customElements.get(tagName)) { defineCustomElement$4(); } break; case "kv-tab-item": if (!customElements.get(tagName)) { defineCustomElement$3(); } break; case "kv-tag-status": if (!customElements.get(tagName)) { defineCustomElement$2(); } break; } }); } defineCustomElement$1(); const KvTabNavigation = KvTabNavigation$1; const defineCustomElement = defineCustomElement$1; export { KvTabNavigation, defineCustomElement };