import { html, cssManager, css, DeesElement, customElement, state } from '@design.estate/dees-element'; import * as interfaces from '../../interfaces/index.js'; import type { DeesAppuiTabs } from './dees-appui-tabs.js'; // Interactive demo component for closeable tabs @customElement('demo-closeable-tabs') class DemoCloseableTabs extends DeesElement { @state() accessor tabs: interfaces.IMenuItem[] = [ { key: 'Main', iconName: 'lucide:home', action: () => console.log('Main clicked') }, ]; @state() accessor tabCounter: number = 0; static styles = [ css` :host { display: block; } .controls { display: flex; gap: 8px; margin-top: 16px; } button { background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.1)')}; border: 1px solid ${cssManager.bdTheme('rgba(59, 130, 246, 0.3)', 'rgba(59, 130, 246, 0.3)')}; color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')}; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 13px; transition: all 0.15s ease; } button:hover { background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.2)', 'rgba(59, 130, 246, 0.2)')}; } .info { margin-top: 16px; padding: 12px 16px; background: ${cssManager.bdTheme('rgba(0,0,0,0.02)', 'rgba(255,255,255,0.02)')}; border-radius: 6px; font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } ` ]; private addTab() { this.tabCounter++; const tabKey = `Document ${this.tabCounter}`; this.tabs = [ ...this.tabs, { key: tabKey, iconName: 'lucide:file', action: () => console.log(`${tabKey} clicked`), closeable: true, onClose: () => this.removeTab(tabKey) } ]; } private removeTab(tabKey: string) { this.tabs = this.tabs.filter(t => t.key !== tabKey); } render() { return html` this.removeTab(e.detail.tab.key)} >
Click the X button on tabs to close them. The "Main" tab is not closeable.
Current tabs: ${this.tabs.length}
`; } } // Interactive demo for auto-hide feature @customElement('demo-autohide-tabs') class DemoAutoHideTabs extends DeesElement { @state() accessor tabs: interfaces.IMenuItem[] = [ { key: 'Tab 1', iconName: 'lucide:file', action: () => console.log('Tab 1') }, { key: 'Tab 2', iconName: 'lucide:file', action: () => console.log('Tab 2') }, ]; @state() accessor autoHide: boolean = true; @state() accessor threshold: number = 1; static styles = [ css` :host { display: block; } .tabs-container { min-height: 60px; border: 1px dashed ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: 6px; display: flex; align-items: center; justify-content: center; } .tabs-container dees-appui-tabs { width: 100%; } .placeholder { color: ${cssManager.bdTheme('#a1a1aa', '#71717a')}; font-size: 13px; font-style: italic; } .controls { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; } button { background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.1)', 'rgba(59, 130, 246, 0.1)')}; border: 1px solid ${cssManager.bdTheme('rgba(59, 130, 246, 0.3)', 'rgba(59, 130, 246, 0.3)')}; color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')}; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 13px; transition: all 0.15s ease; } button:hover { background: ${cssManager.bdTheme('rgba(59, 130, 246, 0.2)', 'rgba(59, 130, 246, 0.2)')}; } button.danger { background: ${cssManager.bdTheme('rgba(239, 68, 68, 0.1)', 'rgba(239, 68, 68, 0.1)')}; border-color: ${cssManager.bdTheme('rgba(239, 68, 68, 0.3)', 'rgba(239, 68, 68, 0.3)')}; color: ${cssManager.bdTheme('#ef4444', '#f87171')}; } button.danger:hover { background: ${cssManager.bdTheme('rgba(239, 68, 68, 0.2)', 'rgba(239, 68, 68, 0.2)')}; } .info { margin-top: 16px; padding: 12px 16px; background: ${cssManager.bdTheme('rgba(0,0,0,0.02)', 'rgba(255,255,255,0.02)')}; border-radius: 6px; font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } ` ]; private tabCounter = 2; private addTab() { this.tabCounter++; this.tabs = [...this.tabs, { key: `Tab ${this.tabCounter}`, iconName: 'lucide:file', action: () => console.log(`Tab ${this.tabCounter}`) }]; } private removeLastTab() { if (this.tabs.length > 0) { this.tabs = this.tabs.slice(0, -1); } } private clearTabs() { this.tabs = []; } render() { const shouldHide = this.autoHide && this.tabs.length <= this.threshold; return html`
${shouldHide ? html`Tabs hidden (${this.tabs.length} tabs ≤ threshold ${this.threshold})` : html`` }
Auto-hide: ${this.autoHide ? 'ON' : 'OFF'} | Threshold: ${this.threshold} | Tabs: ${this.tabs.length}
Tabs will hide when count ≤ threshold.
`; } } export const demoFunc = () => { const horizontalTabs: interfaces.IMenuItem[] = [ { key: 'Home', iconName: 'lucide:home', action: () => console.log('Home clicked') }, { key: 'Analytics Dashboard', iconName: 'lucide:lineChart', action: () => console.log('Analytics clicked') }, { key: 'Reports', iconName: 'lucide:fileText', action: () => console.log('Reports clicked') }, { key: 'User Settings', iconName: 'lucide:settings', action: () => console.log('Settings clicked') }, { key: 'Help', iconName: 'lucide:helpCircle', action: () => console.log('Help clicked') }, ]; const verticalTabs: interfaces.IMenuItem[] = [ { key: 'Profile', iconName: 'lucide:user', action: () => console.log('Profile clicked') }, { key: 'Security', iconName: 'lucide:shield', action: () => console.log('Security clicked') }, { key: 'Notifications', iconName: 'lucide:bell', action: () => console.log('Notifications clicked') }, { key: 'Integrations', iconName: 'lucide:link', action: () => console.log('Integrations clicked') }, { key: 'Advanced', iconName: 'lucide:code', action: () => console.log('Advanced clicked') }, ]; const noIndicatorTabs: interfaces.IMenuItem[] = [ { key: 'All', action: () => console.log('All clicked') }, { key: 'Active', action: () => console.log('Active clicked') }, { key: 'Completed', action: () => console.log('Completed clicked') }, { key: 'Archived', action: () => console.log('Archived clicked') }, ]; const demoContent = (text: string) => html`
${text}
`; return html`
Horizontal Tabs with Animated Indicator
${demoContent('Select a tab to see the smooth sliding animation of the indicator. The indicator automatically adjusts its width to match the tab content with minimal padding.')}
Closeable Tabs (Browser-style)
Auto-hide Tabs
Vertical Tabs Layout
${demoContent('Vertical tabs work great for settings pages and navigation menus. The animated indicator smoothly transitions between selections.')}
Without Indicator
${demoContent('Tabs can also be used without the animated indicator by setting showTabIndicator to false.')}
`; };