import * as interfaces from '../../interfaces/index.js';
import {
DeesElement,
type TemplateResult,
property,
customElement,
html,
css,
cssManager,
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
import '../dees-appui-tabs/dees-appui-tabs.js';
import type { DeesAppuiTabs } from '../dees-appui-tabs/dees-appui-tabs.js';
import { themeDefaultStyles } from '../../00theme.js';
@customElement('dees-appui-maincontent')
export class DeesAppuiMaincontent extends DeesElement {
public static demo = () => html`
console.log('Overview') },
{ key: 'Details', iconName: 'lucide:file', action: () => console.log('Details') },
{ key: 'Settings', iconName: 'lucide:settings', action: () => console.log('Settings') },
]}
>
Main Content Area
This is where your application content goes.
`;
public static demoGroup = 'App UI';
// INSTANCE
@property({
type: Array,
})
accessor tabs: interfaces.IMenuItem[] = [
{ key: '⚠️ Please set tabs', action: () => console.warn('No tabs configured for maincontent') },
];
@property({ type: Object })
accessor selectedTab: interfaces.IMenuItem | null = null;
@property({ type: Boolean })
accessor showTabs: boolean = true;
@property({ type: Boolean })
accessor tabsAutoHide: boolean = false;
@property({ type: Number })
accessor tabsAutoHideThreshold: number = 0;
public static styles = [
themeDefaultStyles,
cssManager.defaultStyles,
css`
/* TODO: Migrate hardcoded values to --dees-* CSS variables */
:host {
color: ${cssManager.bdTheme('#333', '#fff')};
display: grid;
grid-template-rows: auto 1fr;
width: 100%;
height: 100%;
background: ${cssManager.bdTheme('#ffffff', '#161616')};
}
.maincontainer {
display: contents;
}
.topbar {
display: grid;
grid-template-rows: 1fr;
overflow: hidden;
user-select: none;
transition: grid-template-rows 0.3s ease;
}
.topbar > * {
min-height: 0;
}
.content-area {
overflow: auto;
min-height: 0;
overscroll-behavior: contain;
}
:host([notabs]) .topbar {
grid-template-rows: 0fr;
}
`,
];
public render(): TemplateResult {
return html`
this.handleTabSelect(e)}
@tab-close=${(e: CustomEvent) => this.handleTabClose(e)}
>
`;
}
private handleTabSelect(e: CustomEvent) {
this.selectedTab = e.detail.tab;
// Re-emit the event
this.dispatchEvent(new CustomEvent('tab-select', {
detail: e.detail,
bubbles: true,
composed: true
}));
}
private handleTabClose(e: CustomEvent) {
// Re-emit the event
this.dispatchEvent(new CustomEvent('tab-close', {
detail: e.detail,
bubbles: true,
composed: true
}));
}
updated(changedProperties: Map) {
super.updated(changedProperties);
if (changedProperties.has('showTabs')) {
if (this.showTabs) {
this.removeAttribute('notabs');
} else {
this.setAttribute('notabs', '');
}
}
}
async firstUpdated(_changedProperties: Map) {
await super.firstUpdated(_changedProperties);
// Apply initial notabs state
if (!this.showTabs) {
this.setAttribute('notabs', '');
}
// Tab selection is now handled by the dees-appui-tabs component
// But we need to ensure the tabs component is ready
const tabsComponent = this.shadowRoot.querySelector('dees-appui-tabs') as DeesAppuiTabs;
if (tabsComponent) {
await tabsComponent.updateComplete;
}
}
}