feat: implement Shiki theme support for VS Code webview and enhance theme handling

This commit is contained in:
Bohdan Triapitsyn
2025-12-15 02:29:39 +02:00
parent 453ac9c706
commit bd25787b92
10 changed files with 467 additions and 23 deletions
+7 -1
View File
@@ -97,7 +97,13 @@ window.addEventListener('message', (event: MessageEvent) => {
}
});
type ThemeChangePayload = 'light' | 'dark' | { kind?: 'light' | 'dark' | 'high-contrast' };
type ThemeChangePayload =
| 'light'
| 'dark'
| {
kind?: 'light' | 'dark' | 'high-contrast';
shikiThemes?: { light?: Record<string, unknown>; dark?: Record<string, unknown> } | null;
};
type ThemeChangeHandler = (theme: ThemeChangePayload) => void;
let themeChangeHandler: ThemeChangeHandler | null = null;
+21 -1
View File
@@ -20,6 +20,7 @@ declare global {
connectionStatus: string;
};
__OPENCHAMBER_VSCODE_THEME__?: VSCodeThemePayload['theme'];
__OPENCHAMBER_VSCODE_SHIKI_THEMES__?: { light?: Record<string, unknown>; dark?: Record<string, unknown> } | null;
__OPENCHAMBER_CONNECTION__?: { status: ConnectionStatus; error?: string };
}
}
@@ -83,13 +84,32 @@ const emitVSCodeTheme = (preferredKind?: VSCodeThemeKind) => {
emitVSCodeTheme(window.__VSCODE_CONFIG__?.theme as VSCodeThemeKind | undefined);
const scheduleThemeRecompute = (kind?: VSCodeThemeKind) => {
// VS Code updates webview CSS variables asynchronously around theme changes.
// Re-read on the next frames so we don't snapshot the old palette.
requestAnimationFrame(() => {
emitVSCodeTheme(kind);
requestAnimationFrame(() => emitVSCodeTheme(kind));
});
};
onThemeChange((payload) => {
const kind = (typeof payload === 'string'
? payload
: typeof payload === 'object' && payload
? payload.kind
: undefined) as VSCodeThemeKind | undefined;
emitVSCodeTheme(kind);
if (typeof payload === 'object' && payload?.shikiThemes !== undefined) {
window.__OPENCHAMBER_VSCODE_SHIKI_THEMES__ = payload.shikiThemes;
window.dispatchEvent(
new CustomEvent('openchamber:vscode-shiki-themes', {
detail: { shikiThemes: payload.shikiThemes },
}),
);
}
scheduleThemeRecompute(kind);
});
const workspaceFolder = window.__VSCODE_CONFIG__?.workspaceFolder;