feat: Refactor theming in app components to use dynamic CSS variables

This commit is contained in:
Juergen Kunz
2025-06-17 08:58:47 +00:00
parent 5b4319432c
commit cd3c7c8e63
9 changed files with 68 additions and 150 deletions

View File

@ -22,15 +22,15 @@ export class DeesAppuiActivitylog extends DeesElement {
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
:host { :host {
color: #fff; color: ${cssManager.bdTheme('#333', '#fff')};
position: relative; position: relative;
display: block; display: block;
width: 100%; width: 100%;
max-width: 300px; max-width: 300px;
height: 100%; height: 100%;
background: #111c28; background: ${cssManager.bdTheme('#f8f8f8', '#111c28')};
font-family: 'Intel One Mono', sans-serif; font-family: 'Intel One Mono', sans-serif;
border-left: 1px solid #202020; border-left: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
cursor: default; cursor: default;
} }
.maincontainer { .maincontainer {
@ -47,7 +47,8 @@ export class DeesAppuiActivitylog extends DeesElement {
height: 32px; height: 32px;
width: 100%; width: 100%;
padding: 0px 12px 0px 12px; padding: 0px 12px 0px 12px;
background: #0e151f; background: ${cssManager.bdTheme('#ffffff', '#0e151f')};
border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
} }
.topbar .heading { .topbar .heading {
@ -57,6 +58,7 @@ export class DeesAppuiActivitylog extends DeesElement {
font-weight: 500; font-weight: 500;
font-size: 14px; font-size: 14px;
font-family: 'Geist Sans', sans-serif; font-family: 'Geist Sans', sans-serif;
color: ${cssManager.bdTheme('#666', '#ccc')};
} }
.activityContainer { .activityContainer {
@ -73,7 +75,7 @@ export class DeesAppuiActivitylog extends DeesElement {
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
padding-top: 16px; padding-top: 16px;
color: #888 color: ${cssManager.bdTheme('#666', '#888')}
} }
.streamingIndicator.bottom { .streamingIndicator.bottom {
@ -85,19 +87,19 @@ export class DeesAppuiActivitylog extends DeesElement {
min-height: 30px; min-height: 30px;
font-size: 12px; font-size: 12px;
padding: 8px 16px; padding: 8px 16px;
border-bottom: 1px dotted #ffffff20; border-bottom: 1px dotted ${cssManager.bdTheme('#00000020', '#ffffff20')};
} }
.activityentry:last-of-type { .activityentry:last-of-type {
border-bottom: 1px solid #ffffff00; border-bottom: 1px solid transparent;
} }
.activityentry:hover { .activityentry:hover {
background: #00000080; background: ${cssManager.bdTheme('#00000005', '#00000080')};
} }
.timestamp { .timestamp {
color: #ff8787; color: ${cssManager.bdTheme('#e57373', '#ff8787')};
} }
.searchbox { .searchbox {
@ -105,10 +107,11 @@ export class DeesAppuiActivitylog extends DeesElement {
bottom: 0px; bottom: 0px;
width: 100%; width: 100%;
height: 40px; height: 40px;
background: #0e151f; background: ${cssManager.bdTheme('#ffffff', '#0e151f')};
border-top: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
} }
.searchbox input { .searchbox input {
color: #fff; color: ${cssManager.bdTheme('#333', '#fff')};
background: none; background: none;
width: 100%; width: 100%;
height: 40px; height: 40px;
@ -127,7 +130,10 @@ export class DeesAppuiActivitylog extends DeesElement {
width: 100%; width: 100%;
height: 32px; height: 32px;
bottom: 40px; bottom: 40px;
background: linear-gradient(180deg, #111c2800 0%, #0e151f 100%); background: ${cssManager.bdTheme(
'linear-gradient(180deg, #f8f8f800 0%, #ffffff 100%)',
'linear-gradient(180deg, #111c2800 0%, #0e151f 100%)'
)};
pointer-events: none; pointer-events: none;
} }
.topShadow { .topShadow {
@ -135,7 +141,10 @@ export class DeesAppuiActivitylog extends DeesElement {
width: 100%; width: 100%;
height: 32px; height: 32px;
top: 32px; top: 32px;
background: linear-gradient(0deg, #111c2800 0%, #0e151f 100%); background: ${cssManager.bdTheme(
'linear-gradient(0deg, #f8f8f800 0%, #ffffff 100%)',
'linear-gradient(0deg, #111c2800 0%, #0e151f 100%)'
)};
pointer-events: none; pointer-events: none;
} }
`, `,

View File

@ -71,15 +71,6 @@ export const demoFunc = () => {
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => { <dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => {
const appbar = elementArg.querySelector('#appbar') as DeesAppuiBar; const appbar = elementArg.querySelector('#appbar') as DeesAppuiBar;
// Set up theme toggle
const themeButtons = elementArg.querySelectorAll('.theme-toggle dees-button');
themeButtons[0].addEventListener('click', () => {
appbar.theme = 'dark';
});
themeButtons[1].addEventListener('click', () => {
appbar.theme = 'light';
});
// Set up status toggle // Set up status toggle
const statusButtons = elementArg.querySelectorAll('.status-toggle dees-button'); const statusButtons = elementArg.querySelectorAll('.status-toggle dees-button');
statusButtons[0].addEventListener('click', () => { statusButtons[0].addEventListener('click', () => {

View File

@ -40,8 +40,6 @@ export class DeesAppuiBar extends DeesElement {
@property({ type: Boolean }) @property({ type: Boolean })
public showWindowControls: boolean = true; public showWindowControls: boolean = true;
@property({ type: String })
public theme: 'light' | 'dark' = 'dark';
@property({ type: Object }) @property({ type: Object })
public user?: { public user?: {
@ -72,21 +70,15 @@ export class DeesAppuiBar extends DeesElement {
:host { :host {
/* CSS Variables for theming */ /* CSS Variables for theming */
--appbar-height: 40px; --appbar-height: 40px;
--appbar-bg: var(--dees-color-appbar-bg, #000000);
--appbar-text: var(--dees-color-appbar-text, #ffffff80);
--appbar-text-hover: var(--dees-color-appbar-text-hover, #ffffff);
--appbar-border: var(--dees-color-appbar-border, #202020);
--appbar-hover: var(--dees-color-appbar-hover, #ffffff20);
--appbar-active: var(--dees-color-appbar-active, #ffffff30);
--appbar-font-size: 12px; --appbar-font-size: 12px;
display: block; display: block;
position: relative; position: relative;
width: 100%; width: 100%;
height: var(--appbar-height); height: var(--appbar-height);
border-bottom: 1px solid var(--appbar-border); border-bottom: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
background: var(--appbar-bg); background: ${cssManager.bdTheme('#ffffff', '#000000')};
color: var(--appbar-text); color: ${cssManager.bdTheme('#00000080', '#ffffff80')};
font-size: var(--appbar-font-size); font-size: var(--appbar-font-size);
display: grid; display: grid;
grid-template-columns: ${cssManager.cssGridColumns(3, 20)}; grid-template-columns: ${cssManager.cssGridColumns(3, 20)};
@ -94,16 +86,6 @@ export class DeesAppuiBar extends DeesElement {
user-select: none; user-select: none;
} }
/* Light theme */
:host([theme="light"]) {
--appbar-bg: #ffffff;
--appbar-text: #00000080;
--appbar-text-hover: #000000;
--appbar-border: #e0e0e0;
--appbar-hover: #00000010;
--appbar-active: #00000020;
}
.menus { .menus {
display: flex; display: flex;
align-items: center; align-items: center;
@ -134,13 +116,13 @@ export class DeesAppuiBar extends DeesElement {
} }
.menuItem:hover { .menuItem:hover {
background: var(--appbar-hover); background: ${cssManager.bdTheme('#00000010', '#ffffff20')};
color: var(--appbar-text-hover); color: ${cssManager.bdTheme('#000000', '#ffffff')};
} }
.menuItem.active { .menuItem.active {
background: var(--appbar-active); background: ${cssManager.bdTheme('#00000020', '#ffffff30')};
color: var(--appbar-text-hover); color: ${cssManager.bdTheme('#000000', '#ffffff')};
} }
.menuItem[disabled] { .menuItem[disabled] {
@ -150,7 +132,7 @@ export class DeesAppuiBar extends DeesElement {
} }
.menuItem:focus-visible { .menuItem:focus-visible {
box-shadow: 0 0 0 2px var(--appbar-text); box-shadow: 0 0 0 2px ${cssManager.bdTheme('#00000080', '#ffffff80')};
} }
@ -160,10 +142,10 @@ export class DeesAppuiBar extends DeesElement {
top: 100%; top: 100%;
left: 0; left: 0;
min-width: 200px; min-width: 200px;
background: var(--appbar-bg); background: ${cssManager.bdTheme('#ffffff', '#000000')};
border: 1px solid var(--appbar-border); border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
border-radius: 4px; border-radius: 4px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); box-shadow: ${cssManager.bdTheme('0 4px 12px rgba(0, 0, 0, 0.15)', '0 4px 12px rgba(0, 0, 0, 0.3)')};
margin-top: 4px; margin-top: 4px;
z-index: 1000; z-index: 1000;
opacity: 0; opacity: 0;
@ -189,12 +171,12 @@ export class DeesAppuiBar extends DeesElement {
.dropdown-item:hover, .dropdown-item:hover,
.dropdown-item.focused { .dropdown-item.focused {
background: var(--appbar-hover); background: ${cssManager.bdTheme('#00000010', '#ffffff20')};
} }
.dropdown-divider { .dropdown-divider {
height: 1px; height: 1px;
background: var(--appbar-border); background: ${cssManager.bdTheme('#e0e0e0', '#202020')};
margin: 4px 0; margin: 4px 0;
} }
@ -223,13 +205,13 @@ export class DeesAppuiBar extends DeesElement {
} }
.breadcrumb-item { .breadcrumb-item {
color: var(--appbar-text); color: ${cssManager.bdTheme('#00000080', '#ffffff80')};
cursor: pointer; cursor: pointer;
transition: color 0.2s; transition: color 0.2s;
} }
.breadcrumb-item:hover { .breadcrumb-item:hover {
color: var(--appbar-text-hover); color: ${cssManager.bdTheme('#000000', '#ffffff')};
} }
.breadcrumb-separator { .breadcrumb-separator {
@ -267,7 +249,7 @@ export class DeesAppuiBar extends DeesElement {
} }
.user-info:hover { .user-info:hover {
background: var(--appbar-hover); background: ${cssManager.bdTheme('#00000010', '#ffffff20')};
} }
.user-avatar { .user-avatar {
@ -275,7 +257,7 @@ export class DeesAppuiBar extends DeesElement {
width: 24px; width: 24px;
height: 24px; height: 24px;
border-radius: 50%; border-radius: 50%;
background: var(--appbar-active); background: ${cssManager.bdTheme('#00000020', '#ffffff30')};
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -297,7 +279,7 @@ export class DeesAppuiBar extends DeesElement {
width: 8px; width: 8px;
height: 8px; height: 8px;
border-radius: 50%; border-radius: 50%;
border: 2px solid var(--appbar-bg); border: 2px solid ${cssManager.bdTheme('#ffffff', '#000000')};
} }
.user-status.online { .user-status.online {

View File

@ -87,38 +87,7 @@ export const demoFunc = () => {
]; ];
return html` return html`
<dees-demowrapper .runAfterRender=${async (elementArg: HTMLElement) => { <dees-demowrapper>
const appuiBase = elementArg.querySelector('dees-appui-base') as DeesAppuiBase;
// Add event listeners for theme toggle
const themeButtons = elementArg.querySelectorAll('.theme-toggle dees-button');
themeButtons[0].addEventListener('click', () => {
if (appuiBase.appbar) {
appuiBase.appbar.theme = 'dark';
}
});
themeButtons[1].addEventListener('click', () => {
if (appuiBase.appbar) {
appuiBase.appbar.theme = 'light';
}
});
// Update breadcrumbs dynamically
const updateBreadcrumbs = (path: string) => {
if (appuiBase.appbar) {
appuiBase.appbar.breadcrumbs = path;
}
};
// Simulate navigation
setTimeout(() => {
updateBreadcrumbs('Dashboard > Overview');
}, 2000);
setTimeout(() => {
updateBreadcrumbs('Dashboard > Projects > my-app > src > index.ts');
}, 4000);
}}>
<style> <style>
${css` ${css`
.demo-container { .demo-container {
@ -128,28 +97,6 @@ export const demoFunc = () => {
overflow: hidden; overflow: hidden;
} }
.controls {
position: absolute;
bottom: 20px;
right: 20px;
z-index: 1000;
background: rgba(0, 0, 0, 0.8);
padding: 16px;
border-radius: 8px;
display: flex;
gap: 12px;
}
.control-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.control-group label {
font-size: 12px;
color: #888;
}
`} `}
</style> </style>
@ -157,7 +104,6 @@ export const demoFunc = () => {
<dees-appui-base <dees-appui-base
.appbarMenuItems=${menuItems} .appbarMenuItems=${menuItems}
.appbarBreadcrumbs=${'Dashboard'} .appbarBreadcrumbs=${'Dashboard'}
.appbarTheme=${'dark'}
.appbarUser=${{ .appbarUser=${{
name: 'Jane Smith', name: 'Jane Smith',
status: 'online' as 'online' | 'offline' | 'busy' | 'away' status: 'online' as 'online' | 'offline' | 'busy' | 'away'
@ -187,16 +133,6 @@ export const demoFunc = () => {
</ul> </ul>
</div> </div>
</dees-appui-base> </dees-appui-base>
<div class="controls">
<div class="control-group">
<label>Theme</label>
<dees-button-group class="theme-toggle">
<dees-button>Dark</dees-button>
<dees-button>Light</dees-button>
</dees-button-group>
</div>
</div>
</div> </div>
</dees-demowrapper> </dees-demowrapper>
`; `;

View File

@ -40,8 +40,6 @@ export class DeesAppuiBase extends DeesElement {
@property({ type: Boolean }) @property({ type: Boolean })
public appbarShowWindowControls: boolean = true; public appbarShowWindowControls: boolean = true;
@property({ type: String })
public appbarTheme: 'light' | 'dark' = 'dark';
@property({ type: Object }) @property({ type: Object })
public appbarUser?: { public appbarUser?: {
@ -94,7 +92,7 @@ export class DeesAppuiBase extends DeesElement {
position: absolute; position: absolute;
height: 100%; height: 100%;
width: 100%; width: 100%;
background: var(--dees-color-appui-background, #1a1a1a); background: ${cssManager.bdTheme('#f0f0f0', '#1a1a1a')};
} }
.maingrid { .maingrid {
position: absolute; position: absolute;
@ -116,7 +114,6 @@ export class DeesAppuiBase extends DeesElement {
.breadcrumbs=${this.appbarBreadcrumbs} .breadcrumbs=${this.appbarBreadcrumbs}
.breadcrumbSeparator=${this.appbarBreadcrumbSeparator} .breadcrumbSeparator=${this.appbarBreadcrumbSeparator}
.showWindowControls=${this.appbarShowWindowControls} .showWindowControls=${this.appbarShowWindowControls}
.theme=${this.appbarTheme}
.user=${this.appbarUser} .user=${this.appbarUser}
.showSearch=${this.appbarShowSearch} .showSearch=${this.appbarShowSearch}
@menu-select=${(e: CustomEvent) => this.handleAppbarMenuSelect(e)} @menu-select=${(e: CustomEvent) => this.handleAppbarMenuSelect(e)}

View File

@ -46,12 +46,12 @@ export class DeesAppuiMaincontent extends DeesElement {
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
:host { :host {
color: #fff; color: ${cssManager.bdTheme('#333', '#fff')};
display: block; display: block;
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative; position: relative;
background: #161616; background: ${cssManager.bdTheme('#ffffff', '#161616')};
} }
.maincontainer { .maincontainer {
position: absolute; position: absolute;

View File

@ -45,16 +45,16 @@ export class DeesAppuiMainmenu extends DeesElement {
css` css`
.mainContainer { .mainContainer {
--menuSize: 60px; --menuSize: 60px;
color: #ccc; color: ${cssManager.bdTheme('#666', '#ccc')};
z-index: 10; z-index: 10;
display: block; display: block;
position: relative; position: relative;
width: var(--menuSize); width: var(--menuSize);
height: 100%; height: 100%;
background: #000000; background: ${cssManager.bdTheme('#f5f5f5', '#000000')};
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5); box-shadow: ${cssManager.bdTheme('0px 0px 5px rgba(0, 0, 0, 0.1)', '0px 0px 5px rgba(0, 0, 0, 0.5)')};
user-select: none; user-select: none;
border-right: 1px solid #202020; border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#202020')};
} }
.tabsContainer { .tabsContainer {
@ -70,17 +70,17 @@ export class DeesAppuiMainmenu extends DeesElement {
} }
.tab:hover { .tab:hover {
background: rgba(255, 255, 255, 0.15); background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.05)', 'rgba(255, 255, 255, 0.15)')};
} }
.tab.selectedTab { .tab.selectedTab {
color: #fff; color: ${cssManager.bdTheme('#000', '#fff')};
background: rgba(255, 255, 255, 0.1); background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')};
} }
.tabIndicator { .tabIndicator {
opacity: 0; opacity: 0;
background: #4e729a; background: ${cssManager.bdTheme('#2196f3', '#4e729a')};
position: absolute; position: absolute;
width: 5px; width: 5px;
height: calc((var(--menuSize) / 3) * 2); height: calc((var(--menuSize) / 3) * 2);

View File

@ -44,14 +44,14 @@ export class DeesAppuiMainselector extends DeesElement {
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
:host { :host {
color: #fff; color: ${cssManager.bdTheme('#333', '#fff')};
position: relative; position: relative;
display: block; display: block;
width: 100%; width: 100%;
max-width: 300px; max-width: 300px;
height: 100%; height: 100%;
background: #000000; background: ${cssManager.bdTheme('#fafafa', '#000000')};
border-right: 1px solid #222222; border-right: 1px solid ${cssManager.bdTheme('#e0e0e0', '#222222')};
} }
.maincontainer { .maincontainer {
position: absolute; position: absolute;
@ -74,6 +74,7 @@ export class DeesAppuiMainselector extends DeesElement {
font-family: 'Geist Sans', sans-serif; font-family: 'Geist Sans', sans-serif;
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 14px;
color: ${cssManager.bdTheme('#666', '#ccc')};
} }
.selectionOptions { .selectionOptions {
@ -92,7 +93,7 @@ export class DeesAppuiMainselector extends DeesElement {
margin-right: 16px; margin-right: 16px;
padding-top: 8px; padding-top: 8px;
padding-bottom: 8px; padding-bottom: 8px;
border-top: 1px dotted #303030; border-top: 1px dotted ${cssManager.bdTheme('#e0e0e0', '#303030')};
border-left: 0px solid rgba(0, 0, 0, 0); border-left: 0px solid rgba(0, 0, 0, 0);
transition: all 0.1s; transition: all 0.1s;
} }
@ -100,6 +101,7 @@ export class DeesAppuiMainselector extends DeesElement {
.selectionOptions .selectionOption:hover { .selectionOptions .selectionOption:hover {
border-left: 2px solid #26a69a50; border-left: 2px solid #26a69a50;
padding-left: 8px; padding-left: 8px;
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.02)', 'rgba(255, 255, 255, 0.02)')};
} }
.selectionOptions .selectionOption:first-child { .selectionOptions .selectionOption:first-child {
@ -109,6 +111,7 @@ export class DeesAppuiMainselector extends DeesElement {
.selectionOptions .selectionOption.selectedOption { .selectionOptions .selectionOption.selectedOption {
border-left: 4px solid #26a69a; border-left: 4px solid #26a69a;
padding-left: 10px; padding-left: 10px;
background: ${cssManager.bdTheme('rgba(38, 166, 154, 0.05)', 'rgba(38, 166, 154, 0.1)')};
} }
`, `,
]; ];

View File

@ -50,7 +50,7 @@ export class DeesAppuiTabs extends DeesElement {
.tabs-wrapper { .tabs-wrapper {
position: relative; position: relative;
background: #000000; background: ${cssManager.bdTheme('#f5f5f5', '#000000')};
height: 56px; height: 56px;
} }
@ -76,7 +76,7 @@ export class DeesAppuiTabs extends DeesElement {
} }
.tab { .tab {
color: #a0a0a0; color: ${cssManager.bdTheme('#666', '#a0a0a0')};
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
transition: color 0.1s; transition: color 0.1s;
@ -99,20 +99,20 @@ export class DeesAppuiTabs extends DeesElement {
} }
.tab:hover { .tab:hover {
color: #ffffff; color: ${cssManager.bdTheme('#000', '#ffffff')};
} }
.vertical .tab:hover { .vertical .tab:hover {
background: rgba(255, 255, 255, 0.05); background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.05)', 'rgba(255, 255, 255, 0.05)')};
} }
.tab.selectedTab { .tab.selectedTab {
color: #e0e0e0; color: ${cssManager.bdTheme('#333', '#e0e0e0')};
} }
.vertical .tab.selectedTab { .vertical .tab.selectedTab {
background: rgba(255, 255, 255, 0.1); background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')};
color: #ffffff; color: ${cssManager.bdTheme('#000', '#ffffff')};
} }
.tab dees-icon { .tab dees-icon {
@ -126,11 +126,11 @@ export class DeesAppuiTabs extends DeesElement {
bottom: 0px; bottom: 0px;
height: 40px; height: 40px;
width: 40px; width: 40px;
background: #161616; background: ${cssManager.bdTheme('#ffffff', '#161616')};
transition: all 0.1s; transition: all 0.1s;
border-top-left-radius: 8px; border-top-left-radius: 8px;
border-top-right-radius: 8px; border-top-right-radius: 8px;
border-top: 1px solid #444444; border-top: 1px solid ${cssManager.bdTheme('#e0e0e0', '#444444')};
} }
.vertical .tabIndicator { .vertical .tabIndicator {