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)}
>
this.addTab()}>+ Add New Tab
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` `
}
this.addTab()}>+ Add Tab
this.removeLastTab()}>- Remove Tab
this.clearTabs()}>Clear All
{ this.threshold = 0; }}>Threshold: 0
{ this.threshold = 1; }}>Threshold: 1
{ this.threshold = 2; }}>Threshold: 2
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)
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.')}
`;
};