feat(appui-tabs): add support for left/right tab action buttons and content tab action APIs

This commit is contained in:
2026-03-10 12:39:21 +00:00
parent 1795235c6d
commit 5cadd1fc7f
8 changed files with 222 additions and 41 deletions

View File

@@ -2,7 +2,7 @@ import { html, cssManager, css, DeesElement, customElement, state } from '@desig
import * as interfaces from '../../interfaces/index.js';
import type { DeesAppuiTabs } from './dees-appui-tabs.js';
// Interactive demo component for closeable tabs
// Interactive demo component for closeable tabs with action buttons
@customElement('demo-closeable-tabs')
class DemoCloseableTabs extends DeesElement {
@state()
@@ -18,24 +18,6 @@ class DemoCloseableTabs extends DeesElement {
: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;
@@ -66,17 +48,27 @@ class DemoCloseableTabs extends DeesElement {
this.tabs = this.tabs.filter(t => t.key !== tabKey);
}
private clearAll() {
const tabsEl = this.shadowRoot!.querySelector('dees-appui-tabs') as DeesAppuiTabs;
tabsEl?.clear();
this.tabs = [];
this.tabCounter = 0;
}
render() {
const rightActions: interfaces.ITabAction[] = [
{ id: 'add', iconName: 'lucide:plus', action: () => this.addTab(), tooltip: 'New Tab' },
{ id: 'clear', iconName: 'lucide:trash2', action: () => this.clearAll(), tooltip: 'Clear All Tabs' },
];
return html`
<dees-appui-tabs
.tabs=${this.tabs}
.actionsRight=${rightActions}
@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.
Click the X button on tabs to close them. Use the + button to add tabs and the trash button to clear all.
<br>Current tabs: ${this.tabs.length}
</div>
`;
@@ -232,6 +224,16 @@ export const demoFunc = () => {
{ key: 'Archived', action: () => console.log('Archived clicked') },
];
const actionsLeft: interfaces.ITabAction[] = [
{ id: 'back', iconName: 'lucide:arrowLeft', action: () => console.log('Back'), tooltip: 'Go Back' },
];
const actionsRight: interfaces.ITabAction[] = [
{ id: 'add', iconName: 'lucide:plus', action: () => console.log('Add tab'), tooltip: 'New Tab' },
{ id: 'search', iconName: 'lucide:search', action: () => console.log('Search'), tooltip: 'Search Tabs' },
{ id: 'disabled', iconName: 'lucide:lock', action: () => {}, tooltip: 'Disabled Action', disabled: true },
];
const demoContent = (text: string) => html`
<div style="padding: 24px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')};">
${text}
@@ -279,7 +281,17 @@ export const demoFunc = () => {
</div>
<div class="section">
<div class="section-title">Closeable Tabs (Browser-style)</div>
<div class="section-title">Tabs with Action Buttons</div>
<dees-appui-tabs
.tabs=${horizontalTabs}
.actionsLeft=${actionsLeft}
.actionsRight=${actionsRight}
></dees-appui-tabs>
${demoContent('Action buttons can be placed on either side of the tab bar. They remain fixed while tabs scroll. The lock icon shows a disabled action.')}
</div>
<div class="section">
<div class="section-title">Closeable Tabs with Actions</div>
<demo-closeable-tabs></demo-closeable-tabs>
</div>