2025-12-29 23:33:38 +00:00
import { html , cssManager , css , DeesElement , customElement , state } from '@design.estate/dees-element' ;
2025-12-29 01:20:24 +00:00
import * as interfaces from '../../interfaces/index.js' ;
2025-12-29 23:33:38 +00:00
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 16 px ;
border - radius : 6px ;
cursor : pointer ;
font - size : 13px ;
transition : all 0.15 s ease ;
}
button :hover {
background : $ { cssManager . bdTheme ( 'rgba(59, 130, 246, 0.2)' , 'rgba(59, 130, 246, 0.2)' ) } ;
}
. info {
margin - top : 16px ;
padding : 12px 16 px ;
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 ) }
> < / d e e s - a p p u i - t a b s >
< 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 16 px ;
border - radius : 6px ;
cursor : pointer ;
font - size : 13px ;
transition : all 0.15 s 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 16 px ;
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 }
> < / d e e s - a p p u i - t a b s > `
}
< / 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 >
` ;
}
}
2025-12-29 01:20:24 +00:00
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 1 px 3 px 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 1 fr ;
gap : 24px ;
align - items : start ;
}
< / style >
< div class = "demo-container" >
< div class = "section" >
< div class = "section-title" > Horizontal Tabs with Animated Indicator < / div >
2025-12-29 11:30:49 +00:00
< dees - appui - tabs .tabs = $ { horizontalTabs } > < / d e e s - a p p u i - t a b s >
$ { 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.' ) }
2025-12-29 01:20:24 +00:00
< / div >
2025-12-29 23:33:38 +00:00
< div class = "section" >
< div class = "section-title" > Closeable Tabs ( Browser - style ) < / div >
< demo - closeable - tabs > < / d e m o - c l o s e a b l e - t a b s >
< / div >
< div class = "section" >
< div class = "section-title" > Auto - hide Tabs < / div >
< demo - autohide - tabs > < / d e m o - a u t o h i d e - t a b s >
< / div >
2025-12-29 01:20:24 +00:00
< div class = "section" >
< div class = "section-title" > Vertical Tabs Layout < / div >
< div class = "two-column" >
< dees - appui - tabs .tabStyle = $ { 'vertical' } .tabs = $ { verticalTabs } > < / d e e s - a p p u i - t a b s >
$ { 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 >
2025-12-29 11:30:49 +00:00
< dees - appui - tabs .showTabIndicator = $ { false } .tabs = $ { noIndicatorTabs } > < / d e e s - a p p u i - t a b s >
$ { demoContent ( 'Tabs can also be used without the animated indicator by setting showTabIndicator to false.' ) }
2025-12-29 01:20:24 +00:00
< / div >
< / div >
` ;
} ;