@kelvininc/ui-components
Version:
Kelvin UI Components
145 lines (138 loc) • 6.75 kB
JavaScript
import { p as proxyCustomElement, H, d as createEvent, h, e as Host } from './p-D6GMjtmE.js';
import { a as EComponentSize } from './p-BRgmvbuh.js';
import './p-DBphUUgi.js';
import './p-BcMhjKoS.js';
import './p-BQDwJ0uF.js';
import { d as defineCustomElement$3 } from './p-B41PGLQm.js';
import { d as defineCustomElement$2 } from './p-C2hVyKzG.js';
import { i as isEmpty } from './p-BZNGlO8m.js';
const FONT_DESCRIPTOR_SIZE_MAP = {
[EComponentSize.Small]: 'normal normal 600 12px proxima-nova',
[EComponentSize.Large]: 'normal normal 600 16px proxima-nova'
};
const TAB_ITEM_PADDING_PX = 48;
const TAB_ITEM_NOTIFICATION_DOT_WITH_MARGIN = 14;
const TAB_ITEM_ICON_WIDTH_PX = 20;
const TAB_ITEM_SMALL_ADDED_MARGIN = 32;
const calculateTabWidths = (tabs, notifications, size) => {
const measuringCanvas = document.createElement('canvas');
const font = FONT_DESCRIPTOR_SIZE_MAP[size];
const ctx = measuringCanvas.getContext('2d');
ctx.font = font;
const values = tabs.reduce((acc, { tabKey, label, icon }, idx) => {
var _a;
const previousTab = idx > 0 ? tabs[idx - 1] : undefined;
const leftOffset = previousTab ? +acc[previousTab.tabKey].width + +acc[previousTab.tabKey].left : 0;
const notificationDotWidth = ((_a = notifications[tabKey]) === null || _a === void 0 ? void 0 : _a.active) ? TAB_ITEM_NOTIFICATION_DOT_WITH_MARGIN : 0;
const iconWidth = icon ? TAB_ITEM_ICON_WIDTH_PX : 0;
const small = size === EComponentSize.Small ? TAB_ITEM_SMALL_ADDED_MARGIN : 0;
const textWidth = Math.ceil(ctx.measureText(label).width);
acc[tabKey] = {
left: `${leftOffset}`,
width: `${textWidth + TAB_ITEM_PADDING_PX + notificationDotWidth + small + iconWidth}`
};
return acc;
}, {});
return values;
};
const tabNavigationCss = "@property --rotation{syntax:\"<angle>\";initial-value:0deg;inherits:false}@keyframes rotate-border{to{--rotation:360deg}}:host{--tab-list-bg-color:\"transparent\";--tab-list-indicator-color:var(--kv-primary, #005cc7);--tab-list-divider-color:var(--kv-neutral-5, #707070);position:relative;height:34px;width:100%;display:flex;background-color:var(--tab-list-bg-color)}:host::before{content:\"\";width:100%;position:absolute;bottom:0;border-bottom:1px solid var(--tab-list-divider-color)}:host .selected-tab-indicator{height:2px;position:absolute;bottom:0;transition:all 0.3s ease-out;background:var(--tab-list-indicator-color)}";
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.notifications = {};
/** @inheritdoc */
this.size = EComponentSize.Large;
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 */
tabsChangeHandler() {
this.tabsIndicatorConfig = calculateTabWidths(this.tabs, this.notifications, this.size);
this.applySelectedTabStyling();
}
/** Watch for tab selection change and react accordingly by updating the internal states */
tabSelectionChangeHandler() {
if (isEmpty(this.tabsIndicatorConfig)) {
this.tabsIndicatorConfig = calculateTabWidths(this.tabs, this.notifications, this.size);
}
this.applySelectedTabStyling();
}
componentDidLoad() {
this.tabsIndicatorConfig = calculateTabWidths(this.tabs, this.notifications, this.size);
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(Host, { key: 'd8ab9ffa3148c8b87a67dc824e37b42f7c91d6fc' }, this.tabs.map(item => {
var _a, _b;
return (h("kv-tab-item", { key: item.tabKey, tabKey: item.tabKey, label: item.label, disabled: item.disabled, selected: item.tabKey === this.selectedTabKey, size: this.size, hasNotification: (_a = this.notifications[item.tabKey]) === null || _a === void 0 ? void 0 : _a.active, notificationColor: (_b = this.notifications[item.tabKey]) === null || _b === void 0 ? void 0 : _b.color, icon: item.icon, exportparts: "icon" }));
}), h("div", { key: '193dd35a3d8d29ecf5638dd64e0ee3f19d84a9a6', class: "selected-tab-indicator", style: this.selectedTabIndicatorConfig })));
}
static get watchers() { return {
"tabs": ["tabsChangeHandler"],
"size": ["tabsChangeHandler"],
"notifications": ["tabsChangeHandler"],
"selectedTabKey": ["tabSelectionChangeHandler"]
}; }
static get style() { return tabNavigationCss; }
}, [1, "kv-tab-navigation", {
"tabs": [16],
"selectedTabKey": [8, "selected-tab-key"],
"notifications": [16],
"size": [1],
"selectedTabIndicatorConfig": [32]
}, [[0, "tabSelected", "tabSelectionHandler"]], {
"tabs": ["tabsChangeHandler"],
"size": ["tabsChangeHandler"],
"notifications": ["tabsChangeHandler"],
"selectedTabKey": ["tabSelectionChangeHandler"]
}]);
function defineCustomElement$1() {
if (typeof customElements === "undefined") {
return;
}
const components = ["kv-tab-navigation", "kv-icon", "kv-tab-item"];
components.forEach(tagName => { switch (tagName) {
case "kv-tab-navigation":
if (!customElements.get(tagName)) {
customElements.define(tagName, KvTabNavigation$1);
}
break;
case "kv-icon":
if (!customElements.get(tagName)) {
defineCustomElement$3();
}
break;
case "kv-tab-item":
if (!customElements.get(tagName)) {
defineCustomElement$2();
}
break;
} });
}
defineCustomElement$1();
const KvTabNavigation = KvTabNavigation$1;
const defineCustomElement = defineCustomElement$1;
export { KvTabNavigation, defineCustomElement };