Skip to content

Commit eef2703

Browse files
committed
Mixin
1 parent b472fa1 commit eef2703

File tree

16 files changed

+810
-154
lines changed

16 files changed

+810
-154
lines changed

src/commands/showWelcome.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ export function registerShowWelcome(command: Commands) {
1313
const showWelcomeAtStartup = config.get("showWelcomeAtStartup", true);
1414

1515
const colorThemeConfig = config.get("theme.colorTheme", "auto");
16-
const colorTheme = LwcPanelManager.resolveTheme(colorThemeConfig);
16+
const { colorTheme, colorContrast } = LwcPanelManager.resolveTheme(colorThemeConfig);
1717
const panel = lwcManager.getOrCreatePanel("s-welcome", {
1818
showWelcomeAtStartup: showWelcomeAtStartup,
19-
colorTheme
19+
colorTheme,
20+
colorContrast
2021
});
2122
panel.updateTitle("SFDX Hardis Welcome");
2223

src/extension.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,12 @@ export function activate(context: vscode.ExtensionContext) {
251251

252252
const config = vscode.workspace.getConfiguration("vsCodeSfdxHardis.theme");
253253
const colorThemeConfig = config.get("colorTheme", "auto");
254-
const colorTheme = LwcPanelManager.resolveTheme(colorThemeConfig);
254+
const { colorTheme, colorContrast } = LwcPanelManager.resolveTheme(colorThemeConfig);
255255

256256
getExtensionConfigSections(context.extensionUri).then((sections) => {
257257
LwcPanelManager.getInstance(context).refreshAllPanels({
258258
colorTheme,
259-
"s-extension-config": {
260-
sections: sections,
261-
activeTabValue: "theme"
262-
}
259+
colorContrast
263260
});
264261
}).catch((err) => {
265262
Logger.log("Error refreshing panels with new theme: " + err.message);
@@ -274,12 +271,12 @@ export function activate(context: vscode.ExtensionContext) {
274271

275272
if (!colorThemeConfig || colorThemeConfig === "auto") {
276273
const lwcManager = LwcPanelManager.getInstance(context);
277-
const colorTheme = LwcPanelManager.resolveTheme(colorThemeConfig);
274+
const { colorTheme, colorContrast } = LwcPanelManager.resolveTheme(colorThemeConfig);
278275

279276
// Send theme update to all active panels
280277
lwcManager.sendMessageToAllPanels({
281278
type: "updateTheme",
282-
data: { colorTheme }
279+
data: { colorTheme, colorContrast }
283280
});
284281
}
285282
});

src/lwc-panel-manager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,10 @@ export class LwcPanelManager {
247247

248248

249249
/**
250-
* Resolve the theme string based on configuration
251-
* @returns The resolved theme string
250+
* Resolve the theme to use based on the input and VS Code's active theme
251+
* @returns An object with colorTheme and colorContrast properties
252252
*/
253-
public static resolveTheme(colorTheme: string): string {
253+
public static resolveTheme(colorTheme: string): any {
254254
return LwcUiPanel.resolveTheme(colorTheme);
255255
}
256256
}

src/themeUtils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as vscode from "vscode";
44
export class ThemeUtils {
55
public emojisInSections: boolean;
66
public menuIconType: "vscode" | "hardis";
7-
public colorTheme: "auto" | "light" | "dark" | "high-contrast";
7+
public colorTheme: "auto" | "light" | "dark" | "dark-high" | "light-high";
88
public allTopicEmojis: any;
99
public allCommandIcons: any;
1010

@@ -40,7 +40,7 @@ export class ThemeUtils {
4040
public static getThemeConfiguration(): {
4141
emojisInSections: boolean;
4242
menuIconType: "vscode" | "hardis";
43-
colorTheme: "auto" | "light" | "dark" | "high-contrast";
43+
colorTheme: "auto" | "light" | "dark" | "dark-high" | "light-high";
4444
} {
4545
const config = vscode.workspace.getConfiguration("vsCodeSfdxHardis.theme");
4646
return {

src/webviews/lwc-ui-panel.ts

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ export class LwcUiPanel {
197197
// Always add colorTheme to initialization data for consistent theme support
198198
const config = vscode.workspace.getConfiguration("vsCodeSfdxHardis.theme");
199199
const colorThemeConfig = config.get("colorTheme", "auto");
200-
data.colorTheme = LwcUiPanel.resolveTheme(colorThemeConfig);
200+
const { colorTheme, colorContrast } = LwcUiPanel.resolveTheme(colorThemeConfig);
201+
data.colorTheme = colorTheme;
202+
data.colorContrast = colorContrast;
201203

202204
this.panel.webview.postMessage({
203205
type: "initialize",
@@ -611,8 +613,7 @@ export class LwcUiPanel {
611613
* Refresh the webview HTML (useful when configuration changes, like theme)
612614
*/
613615
public refresh(data: any): void {
614-
615-
if (data?.colorTheme) { // FIXME
616+
if (data?.colorTheme) {
616617
this.sendMessage({
617618
type: "updateTheme",
618619
data
@@ -625,24 +626,40 @@ export class LwcUiPanel {
625626

626627
/**
627628
* Resolve the theme to use based on the input and VS Code's active theme
628-
* @param theme The input theme, can be "auto", "dark", "light", dark-high-contrast" or "light-high-contrast"
629-
* @returns The resolved theme string: everything but "auto"
629+
* @param theme The input theme, can be "auto", "dark", "light", "dark-high" or "light-high"
630+
* @returns An object with colorTheme and colorContrast properties
630631
*/
631-
public static resolveTheme(theme: string): string {
632-
if (theme === "auto") {
632+
public static resolveTheme(theme: string): any {
633+
const resultTheme = {
634+
colorTheme: "light",
635+
colorContrast: ""
636+
}
637+
if (!theme || theme === "auto") {
633638
const vsCodeTheme = vscode.window.activeColorTheme.kind;
634639
switch (vsCodeTheme) {
635640
case vscode.ColorThemeKind.HighContrast:
641+
resultTheme.colorTheme = "dark";
642+
resultTheme.colorContrast = "high";
643+
break;
636644
case vscode.ColorThemeKind.Dark:
637-
return "dark";
645+
resultTheme.colorTheme = "dark";
646+
break;
638647
case vscode.ColorThemeKind.HighContrastLight:
648+
resultTheme.colorTheme = "light";
649+
resultTheme.colorContrast = "high";
650+
break;
639651
case vscode.ColorThemeKind.Light:
640652
default:
641-
return "light";
653+
resultTheme.colorTheme = "light";
654+
break;
642655
}
656+
} else {
657+
const themeParts = theme.split("-", 2);
658+
resultTheme.colorTheme = themeParts[0];
659+
resultTheme.colorContrast = themeParts.length > 1 ? themeParts[1] : "";
643660
}
644661

645-
return theme;
662+
return resultTheme;
646663
}
647664

648665
private getHtmlForWebview(webview: vscode.Webview) {
@@ -672,28 +689,27 @@ export class LwcUiPanel {
672689
vscode.Uri.joinPath(this.extensionUri, "out", "assets", "styles", "global-theme.css"),
673690
);
674691

675-
// Safely serialize initialization data
676-
const initDataJson = this.initializationData
677-
? JSON.stringify(this.initializationData)
678-
.replace(/'/g, "'")
679-
.replace(/"/g, """)
680-
: "{}";
681-
682692
// Determine theme based on configuration
683693
const config = vscode.workspace.getConfiguration("vsCodeSfdxHardis.theme");
684694
const colorThemeConfig = config.get("colorTheme", "auto");
685-
const colorTheme = LwcUiPanel.resolveTheme(colorThemeConfig);
695+
const { colorTheme, colorContrast } = LwcUiPanel.resolveTheme(colorThemeConfig);
696+
const initData = this.initializationData || {};
697+
initData.colorTheme = colorTheme;
698+
initData.colorContrast = colorContrast;
699+
700+
// Safely serialize initialization data
701+
const initDataJson = JSON.stringify(initData)
702+
.replace(/'/g, "'")
703+
.replace(/"/g, """);
686704

687705
const mermaidTheme = {
688706
clusterBkg: "#EAF5FC",
689707
edgeLabelBackground: "rgba(232,232,232, 0.8)"
690708
}
691-
if (colorTheme.indexOf("dark") >= 0) {
709+
if (colorTheme == "dark") {
692710
mermaidTheme.clusterBkg = "#333";
693711
mermaidTheme.edgeLabelBackground = "rgba(77, 77, 77, 0.5)";
694712
}
695-
const colorThemeInfo = colorTheme.split('-')
696-
const colorContrast = colorThemeInfo.length > 1 ? colorThemeInfo[1] : "";
697713

698714
return `<!DOCTYPE html>
699715
<html lang="en">
@@ -713,7 +729,7 @@ export class LwcUiPanel {
713729
<!-- Global theme stylesheet: always included, handles both light and dark themes. -->
714730
<link rel="stylesheet" href="${globalThemeCssUri}">
715731
</head>
716-
<body class="slds-scope blue-back" data-theme="${colorThemeInfo[0]}" data-contrast="${colorContrast}">
732+
<body class="slds-scope blue-back" data-theme="${colorTheme}" data-contrast="${colorContrast}">
717733
<div id="app" data-lwc-id="${this.lwcId}" data-init-data="${initDataJson}"></div>
718734
719735
<script>

src/webviews/lwc-ui/index.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ function routeMessageToComponent(message) {
2222
}
2323

2424
if (message.type === "updateTheme") {
25-
const colorTheme = message.data?.colorTheme;
26-
if (colorTheme && document?.body) {
27-
const colorThemeInfo = colorTheme.split('-')
28-
document.body.setAttribute("data-theme", colorThemeInfo[0]);
29-
document.body.setAttribute("data-contrast", colorThemeInfo.length > 1 ? colorThemeInfo[1] : "" );
30-
console.log('test')
31-
console.log('test', document.getElementById("app").querySelector('div'))
32-
document.getElementById("app")?.querySelector('div')?.setAttribute("data-theme", colorThemeInfo[0]);
25+
if (message.data?.colorTheme && document?.body) {
26+
document.body.setAttribute("data-theme", message.data?.colorTheme);
27+
document.body.setAttribute("data-contrast", message.data?.colorContrast);
28+
if (typeof component.handleColorThemeMessage === "function") {
29+
component.handleColorThemeMessage(message.type, message.data);
30+
}
3331
}
3432
}
3533

@@ -149,8 +147,8 @@ document.addEventListener("DOMContentLoaded", async () => {
149147
flushPendingMessages();
150148

151149
// Avoid flash of unthemed content by applying theme early
152-
if (initData?.colorTheme && element.handleMessage) {
153-
element.handleMessage("updateTheme", { colorTheme: initData.colorTheme });
150+
if (initData?.colorTheme && element.handleColorThemeMessage) {
151+
element.handleColorThemeMessage("updateTheme", { colorTheme: initData.colorTheme, colorContrast: initData.colorContrast } );
154152
}
155153

156154
// Wait a bit for the component to fully initialize
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* eslint-disable */
2+
// LWC: ignore parsing errors for import/export, handled by LWC compiler
3+
// @ts-nocheck
4+
// eslint-env es6
5+
6+
/**
7+
* Mixin for managing color theme in LWC components
8+
* Provides colorTheme and colorContrast tracking and update handling
9+
* Usage:
10+
* import { ColorThemeMixin } from 's/colorThemeMixin';
11+
* export default class MyComponent extends ColorThemeMixin(LightningElement) {
12+
* ...
13+
* @api
14+
* handleColorThemeMessage(type, data) {
15+
* // Delegate to the mixin's implementation
16+
* if (super.handleColorThemeMessage)
17+
* super.handleColorThemeMessage(type, data);
18+
* }
19+
*/
20+
21+
export const ColorThemeMixin = (BaseClass) =>
22+
class extends BaseClass {
23+
_colorTheme;
24+
_colorContrast;
25+
get colorTheme() {
26+
return this._colorTheme || "";
27+
}
28+
set colorTheme(value) {
29+
this._colorTheme = value;
30+
}
31+
get colorContrast() {
32+
return this._colorContrast || "";
33+
}
34+
set colorContrast(value) {
35+
this._colorContrast = value;
36+
}
37+
handleColorThemeMessage(type, data) {
38+
if (type === "updateTheme" && data?.colorTheme) {
39+
this._colorTheme = data.colorTheme;
40+
this._colorContrast = data.colorContrast;
41+
}
42+
}
43+
};

0 commit comments

Comments
 (0)