Files
dees-catalog/ts_web/elements/00group-appui/dees-appui-tabs/dees-appui-tabs.demo.ts

307 lines
10 KiB
TypeScript
Raw Normal View History

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`
<dees-appui-tabs
.tabs=${this.tabs}
@tab-close=${(e: CustomEvent) => this.removeTab(e.detail.tab.key)}
></dees-appui-tabs>
<div class="controls">
<button @click=${() => this.addTab()}>+ Add New Tab</button>
</div>
<div class="info">
Click the X button on tabs to close them. The "Main" tab is not closeable.
<br>Current tabs: ${this.tabs.length}
</div>
`;
}
}
// 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`
<div class="tabs-container">
${shouldHide
? html`<span class="placeholder">Tabs hidden (${this.tabs.length} tabs ≤ threshold ${this.threshold})</span>`
: html`<dees-appui-tabs
.tabs=${this.tabs}
.autoHide=${this.autoHide}
.autoHideThreshold=${this.threshold}
></dees-appui-tabs>`
}
</div>
<div class="controls">
<button @click=${() => this.addTab()}>+ Add Tab</button>
<button class="danger" @click=${() => this.removeLastTab()}>- Remove Tab</button>
<button class="danger" @click=${() => this.clearTabs()}>Clear All</button>
<button @click=${() => { this.threshold = 0; }}>Threshold: 0</button>
<button @click=${() => { this.threshold = 1; }}>Threshold: 1</button>
<button @click=${() => { this.threshold = 2; }}>Threshold: 2</button>
</div>
<div class="info">
Auto-hide: ${this.autoHide ? 'ON' : 'OFF'} | Threshold: ${this.threshold} | Tabs: ${this.tabs.length}
<br>Tabs will hide when count threshold.
</div>
`;
}
}
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`
<div style="padding: 24px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};">
${text}
</div>
`;
return html`
<style>
.demo-container {
display: flex;
flex-direction: column;
gap: 32px;
padding: 48px;
background: ${cssManager.bdTheme('#f8f9fa', '#0a0a0a')};
min-height: 100vh;
}
.section {
background: ${cssManager.bdTheme('#ffffff', '#18181b')};
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')};
border-radius: 8px;
padding: 24px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.section-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 16px;
color: ${cssManager.bdTheme('#09090b', '#fafafa')};
}
.two-column {
display: grid;
grid-template-columns: 200px 1fr;
gap: 24px;
align-items: start;
}
</style>
<div class="demo-container">
<div class="section">
<div class="section-title">Horizontal Tabs with Animated Indicator</div>
<dees-appui-tabs .tabs=${horizontalTabs}></dees-appui-tabs>
${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.')}
</div>
<div class="section">
<div class="section-title">Closeable Tabs (Browser-style)</div>
<demo-closeable-tabs></demo-closeable-tabs>
</div>
<div class="section">
<div class="section-title">Auto-hide Tabs</div>
<demo-autohide-tabs></demo-autohide-tabs>
</div>
<div class="section">
<div class="section-title">Vertical Tabs Layout</div>
<div class="two-column">
<dees-appui-tabs .tabStyle=${'vertical'} .tabs=${verticalTabs}></dees-appui-tabs>
${demoContent('Vertical tabs work great for settings pages and navigation menus. The animated indicator smoothly transitions between selections.')}
</div>
</div>
<div class="section">
<div class="section-title">Without Indicator</div>
<dees-appui-tabs .showTabIndicator=${false} .tabs=${noIndicatorTabs}></dees-appui-tabs>
${demoContent('Tabs can also be used without the animated indicator by setting showTabIndicator to false.')}
</div>
</div>
`;
};