Skip to content

Commit cf9eb56

Browse files
committed
Improve theme support #54
1 parent f3091d0 commit cf9eb56

5 files changed

Lines changed: 70 additions & 11 deletions

File tree

eslint.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ module.exports = {
7272
"@typescript-eslint/no-non-null-assertion": "off", // allow ! operator
7373
"@typescript-eslint/parameter-properties": "error", // no property definitions in class constructors
7474
"@typescript-eslint/no-unused-vars": ["warn", { // warn about Unused Variables
75-
"argsIgnorePattern": "^_"
75+
"argsIgnorePattern": "^_",
76+
"varsIgnorePattern": "^_"
7677
}],
7778
"@typescript-eslint/no-var-requires": "error", // use import instead of require
7879
"@typescript-eslint/prefer-for-of": "error", // prefer for-of loop over arrays

packages/vscode-messenger-devtools/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
## v0.6.0 (Jan. 2026)
44

5+
* **New:** Added data export functionality - export messenger events as JSON or CSV files
6+
* Export all events for the selected extension or only selected table rows
7+
* Files are automatically saved with timestamped filenames
8+
* JSON export preserves full event structure including parameters and metadata
9+
* CSV export includes all event properties with proper escaping for complex data
10+
* Improved dark theme support for charts and overall UI
511
* Updated to use vscode-messenger v0.6.0 with enhanced handler management capabilities
612

713
## v0.5.1 (Feb. 2025)

packages/vscode-messenger-devtools/webview-ui/src/components/react-echart.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ export interface ReactEChartsProps {
1414

1515
export type ChartData = Map<string, { notification: [number, number]; response: [number, number]; request: [number, number]; }>;
1616

17-
export function createOptions(charSeries: Array<{ name: string, data: number[] }>, yAxis: string[], legendFormat = ''): ReactEChartsProps['option'] {
17+
export function createOptions(charSeries: Array<{ name: string, data: number[] }>, yAxis: string[], legendFormat = '', theme?: 'light' | 'dark'): ReactEChartsProps['option'] {
18+
// Use VS Code theme colors for better integration
19+
// In dark theme, use a lighter gray; in light theme, use a darker gray for better contrast
20+
const legendTextColor = theme === 'dark' ? '#cccccc' : '#616161';
21+
1822
const option: ReactEChartsProps['option'] = {
1923
tooltip: {
2024
trigger: 'axis',
@@ -24,7 +28,10 @@ export function createOptions(charSeries: Array<{ name: string, data: number[] }
2428
},
2529
legend: {
2630
orient: 'horizontal',
27-
formatter: `{name}${legendFormat}`
31+
formatter: `{name}${legendFormat}`,
32+
textStyle: {
33+
color: legendTextColor
34+
}
2835
},
2936
grid: {
3037
show: true,

packages/vscode-messenger-devtools/webview-ui/src/devtools-view.tsx

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { EventTable } from './components/event-table';
1414
import { ReactECharts, collectChartData, createOptions } from './components/react-echart';
1515
import { ViewHeader } from './components/view-header';
1616
import type { DevtoolsComponentState } from './utilities/view-state';
17-
import { restoreState, storeState, vsCodeApi } from './utilities/view-state';
17+
import { restoreState, storeState, vsCodeApi, getVSCodeTheme } from './utilities/view-state';
1818

1919
type DataEvent = {
2020
extension: string;
@@ -53,6 +53,7 @@ class DevtoolsComponent extends React.Component<Record<string, any>, DevtoolsCom
5353

5454
messenger: Messenger;
5555
eventTable: EventTable;
56+
private themeObserver: MutationObserver | null = null;
5657

5758
constructor() {
5859
super({});
@@ -61,7 +62,8 @@ class DevtoolsComponent extends React.Component<Record<string, any>, DevtoolsCom
6162
selectedExtension: storedState?.selectedExtension ?? '',
6263
datasetSrc: storedState?.datasetSrc ? new Map() : new Map(),
6364
chartsShown: storedState?.chartsShown ?? false,
64-
diagramShown: storedState?.diagramShown ?? false
65+
diagramShown: storedState?.diagramShown ?? false,
66+
theme: storedState?.theme ?? getVSCodeTheme()
6567
};
6668
this.eventTable = new EventTable({ gridRowSelected: (e) => this.gridRowSelected(e) });
6769
this.messenger = new Messenger(vsCodeApi, { debugLog: true });
@@ -83,13 +85,46 @@ class DevtoolsComponent extends React.Component<Record<string, any>, DevtoolsCom
8385
return;
8486
}).catch(err => console.error(err));
8587

88+
// Set up theme change observer
89+
this.setupThemeObserver();
8690
}
8791

88-
render() {
92+
componentWillUnmount() {
93+
// Clean up theme observer
94+
if (this.themeObserver) {
95+
this.themeObserver.disconnect();
96+
this.themeObserver = null;
97+
}
98+
}
8999

100+
private setupThemeObserver() {
101+
// Watch for changes to the data-vscode-theme-kind attribute
102+
this.themeObserver = new MutationObserver((mutations) => {
103+
mutations.forEach((mutation) => {
104+
if (mutation.type === 'attributes' && mutation.attributeName === 'data-vscode-theme-kind') {
105+
const newTheme = getVSCodeTheme();
106+
if (newTheme !== this.state.theme) {
107+
// Update state with new theme - this will trigger chart re-render
108+
// and table will automatically pick up new CSS theme class
109+
this.updateState({ ...this.state, theme: newTheme }, true);
110+
}
111+
}
112+
});
113+
});
114+
115+
// Start observing
116+
this.themeObserver.observe(document.body, {
117+
attributes: true,
118+
attributeFilter: ['data-vscode-theme-kind']
119+
});
120+
121+
}
122+
123+
render() {
124+
const theme = this.state.theme;
90125
const charSeries = collectChartData(this.selectedExtensionData()?.events ?? []);
91-
const optionSize = createOptions(charSeries.series[0], charSeries.senderY, ' (chars)');
92-
const optionCount = createOptions(charSeries.series[1], charSeries.senderY);
126+
const optionSize = createOptions(charSeries.series[0], charSeries.senderY, ' (chars)', theme);
127+
const optionCount = createOptions(charSeries.series[1], charSeries.senderY, '', theme);
93128

94129
const selectedExt = this.selectedExtensionData();
95130
const updateState = (selectedId: string) => {
@@ -360,7 +395,8 @@ class DevtoolsComponent extends React.Component<Record<string, any>, DevtoolsCom
360395
if (typeof value === 'object') {
361396
try {
362397
stringValue = JSON.stringify(value);
363-
} catch (error) {
398+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
399+
} catch (_error) {
364400
stringValue = String(value);
365401
}
366402
} else {

packages/vscode-messenger-devtools/webview-ui/src/utilities/view-state.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export function storeState(uiState: DevtoolsComponentState): void {
77
selectedExtension: uiState.selectedExtension,
88
datasetSrc: [...uiState.datasetSrc],
99
chartsShown: uiState.chartsShown,
10-
diagramShown: uiState.diagramShown
10+
diagramShown: uiState.diagramShown,
11+
theme: uiState.theme
1112
});
1213
}
1314

@@ -18,15 +19,23 @@ export function restoreState(): DevtoolsComponentState | undefined {
1819
selectedExtension: stored.selectedExtension,
1920
datasetSrc: new Map(stored.datasetSrc),
2021
chartsShown: stored.chartsShown,
21-
diagramShown: stored.diagramShown
22+
diagramShown: stored.diagramShown,
23+
theme: stored.theme || getVSCodeTheme() // fallback to current theme if not stored
2224
};
2325
}
2426
return undefined;
2527
}
2628

29+
// Helper function to detect VS Code theme
30+
export function getVSCodeTheme(): 'light' | 'dark' {
31+
const themeKind = document.body.getAttribute('data-vscode-theme-kind');
32+
return themeKind?.includes('dark') ? 'dark' : 'light';
33+
}
34+
2735
export interface DevtoolsComponentState {
2836
selectedExtension: string
2937
datasetSrc: Map<string, ExtensionData>
3038
chartsShown: boolean
3139
diagramShown: boolean
40+
theme: 'light' | 'dark'
3241
}

0 commit comments

Comments
 (0)