import * as interfaces from '../../interfaces/index.js'; import { DeesElement, type TemplateResult, property, customElement, html, css, cssManager, } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; import { demoFunc } from './dees-appui-tabs.demo.js'; import { themeDefaultStyles } from '../../00theme.js'; @customElement('dees-appui-tabs') export class DeesAppuiTabs extends DeesElement { public static demo = demoFunc; // INSTANCE @property({ type: Array, }) accessor tabs: interfaces.IMenuItem[] = []; @property({ type: Object }) accessor selectedTab: interfaces.IMenuItem | null = null; @property({ type: Boolean }) accessor showTabIndicator: boolean = true; @property({ type: String }) accessor tabStyle: 'horizontal' | 'vertical' = 'horizontal'; public static styles = [ themeDefaultStyles, cssManager.defaultStyles, css` /* TODO: Migrate hardcoded values to --dees-* CSS variables */ :host { display: block; position: relative; width: 100%; } .tabs-wrapper { position: relative; } .tabs-wrapper.horizontal-wrapper { height: 48px; border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; box-sizing: border-box; } .tabsContainer { position: relative; user-select: none; } .tabsContainer.horizontal { display: flex; align-items: center; font-size: 14px; overflow-x: auto; scrollbar-width: none; height: 100%; padding: 0 16px; gap: 4px; } .tabsContainer.horizontal::-webkit-scrollbar { display: none; } .tabsContainer.vertical { display: flex; flex-direction: column; padding: 8px; font-size: 14px; gap: 2px; position: relative; background: ${cssManager.bdTheme('#f9fafb', '#18181b')}; border-radius: 8px; } .tab { color: ${cssManager.bdTheme('#71717a', '#71717a')}; white-space: nowrap; cursor: pointer; transition: color 0.15s ease; font-weight: 500; position: relative; z-index: 2; } .horizontal .tab { padding: 0 16px; height: 100%; display: inline-flex; align-items: center; gap: 8px; position: relative; border-radius: 6px 6px 0 0; transition: background-color 0.15s ease; } .horizontal .tab:not(:last-child)::after { content: ''; position: absolute; right: -2px; top: 50%; transform: translateY(-50%); height: 20px; width: 1px; background: ${cssManager.bdTheme('#e5e7eb', '#27272a')}; opacity: 0.5; } .horizontal .tab .tab-content { display: inline-flex; align-items: center; gap: 8px; } .vertical .tab { padding: 10px 16px; border-radius: 6px; width: 100%; display: flex; align-items: center; gap: 8px; transition: all 0.15s ease; } .tab:hover { color: ${cssManager.bdTheme('#09090b', '#fafafa')}; } .horizontal .tab:hover { background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.03)', 'rgba(255, 255, 255, 0.03)')}; } .horizontal .tab:hover::after, .horizontal .tab:hover + .tab::after { opacity: 0; } .vertical .tab:hover { background: ${cssManager.bdTheme('rgba(244, 244, 245, 0.5)', 'rgba(39, 39, 42, 0.5)')}; } .horizontal .tab.selectedTab { color: ${cssManager.bdTheme('#09090b', '#fafafa')}; } .horizontal .tab.selectedTab::after, .horizontal .tab.selectedTab + .tab::after { opacity: 0; } .vertical .tab.selectedTab { color: ${cssManager.bdTheme('#09090b', '#fafafa')}; } .tab dees-icon { font-size: 16px; } .tabIndicator { position: absolute; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); opacity: 0; } .tabIndicator.no-transition { transition: none; } .tabs-wrapper .tabIndicator { height: 3px; bottom: 0; background: ${cssManager.bdTheme('#3b82f6', '#3b82f6')}; border-radius: 3px 3px 0 0; z-index: 3; } .vertical-wrapper { position: relative; } .vertical-wrapper .tabIndicator { left: 8px; right: 8px; border-radius: 6px; background: ${cssManager.bdTheme('#ffffff', '#27272a')}; z-index: 1; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); } `, ]; public render(): TemplateResult { return html` ${this.renderTabsWrapper()} `; } private renderTabsWrapper(): TemplateResult { const isHorizontal = this.tabStyle === 'horizontal'; const wrapperClass = isHorizontal ? 'tabs-wrapper horizontal-wrapper' : 'vertical-wrapper'; const containerClass = `tabsContainer ${this.tabStyle}`; return html`