| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  | import * as plugins from './00plugins.js'; | 
					
						
							|  |  |  | import * as interfaces from './interfaces/index.js'; | 
					
						
							| 
									
										
										
										
											2025-06-26 15:46:44 +00:00
										 |  |  | import { zIndexLayers } from './00zindex.js'; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   DeesElement, | 
					
						
							|  |  |  |   type TemplateResult, | 
					
						
							|  |  |  |   property, | 
					
						
							|  |  |  |   customElement, | 
					
						
							|  |  |  |   html, | 
					
						
							|  |  |  |   css, | 
					
						
							|  |  |  |   cssManager, | 
					
						
							|  |  |  | } from '@design.estate/dees-element'; | 
					
						
							|  |  |  | import { DeesContextmenu } from './dees-contextmenu.js'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * the most left menu | 
					
						
							|  |  |  |  * usually used as organization selector | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | @customElement('dees-appui-mainmenu') | 
					
						
							|  |  |  | export class DeesAppuiMainmenu extends DeesElement { | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |   public static demo = () => html`
 | 
					
						
							|  |  |  |     <dees-appui-mainmenu | 
					
						
							|  |  |  |       .tabs=${[ | 
					
						
							| 
									
										
										
										
											2025-06-27 22:55:20 +00:00
										 |  |  |         { key: 'Dashboard', iconName: 'lucide:home', action: () => console.log('Dashboard') }, | 
					
						
							|  |  |  |         { key: 'Projects', iconName: 'lucide:folder', action: () => console.log('Projects') }, | 
					
						
							|  |  |  |         { key: 'Analytics', iconName: 'lucide:lineChart', action: () => console.log('Analytics') }, | 
					
						
							|  |  |  |         { key: 'Settings', iconName: 'lucide:settings', action: () => console.log('Settings') }, | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |       ]} | 
					
						
							|  |  |  |     ></dees-appui-mainmenu> | 
					
						
							|  |  |  |   `;
 | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // INSTANCE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // INSTANCE
 | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |   @property({ type: Array }) | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |   public tabs: interfaces.ITab[] = [ | 
					
						
							| 
									
										
										
										
											2025-06-27 22:55:20 +00:00
										 |  |  |     { key: '⚠️ Please set tabs', iconName: 'lucide:alertTriangle', action: () => console.warn('No tabs configured for mainmenu') }, | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |   ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @property() | 
					
						
							|  |  |  |   public selectedTab: interfaces.ITab; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public static styles = [ | 
					
						
							|  |  |  |     cssManager.defaultStyles, | 
					
						
							|  |  |  |     css`
 | 
					
						
							|  |  |  |       .mainContainer { | 
					
						
							|  |  |  |         --menuSize: 60px; | 
					
						
							| 
									
										
										
										
											2025-06-17 08:58:47 +00:00
										 |  |  |         color: ${cssManager.bdTheme('#666', '#ccc')}; | 
					
						
							| 
									
										
										
										
											2025-06-26 15:46:44 +00:00
										 |  |  |         z-index: ${zIndexLayers.fixed.appBar}; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |         display: block; | 
					
						
							|  |  |  |         position: relative; | 
					
						
							|  |  |  |         width: var(--menuSize); | 
					
						
							|  |  |  |         height: 100%; | 
					
						
							| 
									
										
										
										
											2025-06-17 08:58:47 +00:00
										 |  |  |         background: ${cssManager.bdTheme('#f5f5f5', '#000000')}; | 
					
						
							|  |  |  |         box-shadow: ${cssManager.bdTheme('0px 0px 5px rgba(0, 0, 0, 0.1)', '0px 0px 5px rgba(0, 0, 0, 0.5)')}; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |         user-select: none; | 
					
						
							| 
									
										
										
										
											2025-06-17 08:58:47 +00:00
										 |  |  |         border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')}; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       .tabsContainer { | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       .tab { | 
					
						
							|  |  |  |         padding-top: 18px; | 
					
						
							|  |  |  |         font-size: 24px; | 
					
						
							|  |  |  |         width: var(--menuSize); | 
					
						
							|  |  |  |         height: var(--menuSize); | 
					
						
							|  |  |  |         text-align: center; | 
					
						
							|  |  |  |         transition: color 0.1s, background 0.2s; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       .tab:hover { | 
					
						
							| 
									
										
										
										
											2025-06-17 08:58:47 +00:00
										 |  |  |         background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.05)', 'rgba(255, 255, 255, 0.15)')}; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       .tab.selectedTab { | 
					
						
							| 
									
										
										
										
											2025-06-17 08:58:47 +00:00
										 |  |  |         color: ${cssManager.bdTheme('#000', '#fff')}; | 
					
						
							|  |  |  |         background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')}; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       .tabIndicator { | 
					
						
							|  |  |  |         opacity: 0; | 
					
						
							| 
									
										
										
										
											2025-06-17 08:58:47 +00:00
										 |  |  |         background: ${cssManager.bdTheme('#2196f3', '#4e729a')}; | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |         position: absolute; | 
					
						
							|  |  |  |         width: 5px; | 
					
						
							|  |  |  |         height: calc((var(--menuSize) / 3) * 2); | 
					
						
							|  |  |  |         left: 0px; | 
					
						
							|  |  |  |         top: calc(var(--menuSize) - (((var(--menuSize) / 3) * 2) / 2)); | 
					
						
							|  |  |  |         border-top-right-radius: 7px; | 
					
						
							|  |  |  |         border-bottom-right-radius: 7px; | 
					
						
							|  |  |  |         transition: all 0.1s; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public render(): TemplateResult { | 
					
						
							|  |  |  |     return html`
 | 
					
						
							|  |  |  |       <div class="mainContainer" @contextmenu=${(eventArg) => { | 
					
						
							|  |  |  |         DeesContextmenu.openContextMenuWithOptions(eventArg, [{ | 
					
						
							|  |  |  |           name: 'app settings', | 
					
						
							|  |  |  |           action: async () => {}, | 
					
						
							|  |  |  |           iconName: 'gear', | 
					
						
							|  |  |  |         }]) | 
					
						
							|  |  |  |       }}> | 
					
						
							|  |  |  |         <div class="tabsContainer"> | 
					
						
							|  |  |  |           ${this.tabs.map((tabArg) => { | 
					
						
							|  |  |  |             return html`
 | 
					
						
							|  |  |  |               <div | 
					
						
							|  |  |  |                 class="tab ${tabArg === this.selectedTab ? 'selectedTab' : null}" | 
					
						
							|  |  |  |                 @click="${() => { | 
					
						
							|  |  |  |                   this.updateTab(tabArg); | 
					
						
							|  |  |  |                 }}" | 
					
						
							|  |  |  |               > | 
					
						
							| 
									
										
										
										
											2025-06-27 22:55:20 +00:00
										 |  |  |                 <dees-icon .icon="${tabArg.iconName || ''}"></dees-icon> | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |               </div> | 
					
						
							|  |  |  |             `;
 | 
					
						
							|  |  |  |           })} | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |         <div class="tabIndicator"></div> | 
					
						
							|  |  |  |       </div> | 
					
						
							|  |  |  |     `;
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |   private updateTabIndicator() { | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |     let selectedTab = this.selectedTab; | 
					
						
							|  |  |  |     if (!selectedTab) { | 
					
						
							|  |  |  |       selectedTab = this.tabs[0]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     const tabIndex = this.tabs.indexOf(selectedTab); | 
					
						
							|  |  |  |     const selectedTabElement: HTMLElement = this.shadowRoot.querySelector( | 
					
						
							|  |  |  |       `.tabsContainer .tab:nth-child(${tabIndex + 1})` | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     if (!selectedTabElement) return; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |     const tabIndicator: HTMLElement = this.shadowRoot.querySelector('.tabIndicator'); | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |     if (!tabIndicator) return; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |     const offsetTop = selectedTabElement.offsetTop; | 
					
						
							|  |  |  |     tabIndicator.style.opacity = `1`; | 
					
						
							|  |  |  |     tabIndicator.style.top = `calc(${offsetTop}px + (var(--menuSize) / 6))`; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   updateTab(tabArg: interfaces.ITab) { | 
					
						
							|  |  |  |     this.selectedTab = tabArg; | 
					
						
							|  |  |  |     this.updateTabIndicator(); | 
					
						
							|  |  |  |     this.selectedTab.action(); | 
					
						
							| 
									
										
										
										
											2025-06-17 08:41:36 +00:00
										 |  |  |      | 
					
						
							|  |  |  |     // Emit tab-select event
 | 
					
						
							|  |  |  |     this.dispatchEvent(new CustomEvent('tab-select', { | 
					
						
							|  |  |  |       detail: { tab: tabArg }, | 
					
						
							|  |  |  |       bubbles: true, | 
					
						
							|  |  |  |       composed: true | 
					
						
							|  |  |  |     })); | 
					
						
							| 
									
										
										
										
											2024-01-24 12:18:37 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   firstUpdated() { | 
					
						
							|  |  |  |     this.updateTab(this.tabs[0]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |