import { styleMap } from 'lit/directives/style-map.js' import type { PropertyValues } from 'lit' import { css, html } from 'lit' import { when } from 'lit/directives/when.js' import { property, query, queryAssignedElements } from 'lit/decorators.js' import { classMap } from 'lit/directives/class-map.js' import simplebar_css from 'simplebar/dist/simplebar.css' import SimpleBar from 'simplebar' import { dispatchCustomEvent } from '../../utils/dispatchCustomEvent' import { UsBaseElement } from '../base/UsBaseElement' import { customElementIfNotExist } from '../../utils/customElementIfNotExist' import type { ITabsProps, ITabsSize, ITabsVariants } from './model/ITabsProps' import type { ITabProps } from './model/ITabProps' import vars_css from './vars.pcss' import UsTabs_css from './tabs.pcss' import './UsTab' // import '../icon/UsIcon' declare global { interface HTMLElementTagNameMap { 'us-tabs': UsTabs } } @customElementIfNotExist('us-tabs') export class UsTabs extends UsBaseElement implements ITabsProps { static styles = [ UsBaseElement.styles, css([vars_css] as TemplateStringsArray | any), css([UsTabs_css] as TemplateStringsArray | any), css([simplebar_css] as TemplateStringsArray | any), ] @property() variant: ITabsVariants = 'line' @property() size: ITabsSize = 'sm' @property() titleSidesPadding = '0' @property() titleBottomMargin = 'var(--space-inner-xl)' @property() tabContainerJustifyContent = 'unset' @property() ariaLabel = 'tabs' @property({ type: Boolean }) scrollBar = false @property({ type: Boolean }) fullTabWidth = false @property({ type: String, attribute: 'data-testid', reflect: true }) dataTestId = 'tabs' @query('[data-simplebar]') simpleBarEl: HTMLDivElement | undefined @query('nav') tabsEl: HTMLDivElement | undefined @queryAssignedElements() tabs!: Array simpleBar!: SimpleBar firstUpdated(_changedProperties: PropertyValues) { if (this.simpleBarEl && this.scrollBar) this.simpleBar = new SimpleBar(this.simpleBarEl) super.firstUpdated(_changedProperties) const currentTabIndex = this.tabs.findIndex(tab => tab.selected && !tab.disabled) if (currentTabIndex !== -1) { this.selectTab(this.tabs[currentTabIndex]) } else { const firstActiveTab = this.tabs.find(tab => !tab.disabled) if (firstActiveTab) this.selectTab(firstActiveTab) } setTimeout(() => { dispatchCustomEvent('titleHeightInit', this.tabsEl?.offsetHeight, this) }, 0) } render() { return html` ` } handleSlotChange() { this.requestUpdate() } selectTab(tabItem: ITabProps, event?: KeyboardEvent) { if (event && event.key !== 'Enter') return if (tabItem.disabled) return for (const tab of this.tabs) { if (tab === tabItem) { tab.selected = true dispatchCustomEvent('tabchange', tab.value, this, false, false) } else { tab.selected = false } } this.requestUpdate() } private _getTabsStyles() { return styleMap({ 'padding': `0 ${this.titleSidesPadding}`, 'margin-bottom': this.titleBottomMargin, }) } private _getTabsWrapperStyles() { return styleMap({ 'justify-content': this.tabContainerJustifyContent, }) } private _getTabClasses(tab: ITabProps) { return classMap({ 'us-tab': true, [`us-tab_${this.variant}`]: true, [`us-tab_${this.size}`]: true, 'us-tab_disabled': !!tab.disabled, 'us-tab_selected': tab.selected, 'us-tab_padding-without-name': !tab.name, }) } private _getTabsContainerClasses() { return classMap({ 'us-tabs__container': true, 'us-tabs__container_full': this.fullTabWidth, [`us-tabs__container_${this.variant}`]: true, }) } }