feat(terminal): add dynamic bright/dark theming for terminal components and terminal preview

This commit is contained in:
2025-12-31 14:01:42 +00:00
parent 62de004350
commit d0bd4027bb
7 changed files with 109 additions and 33 deletions

View File

@@ -55,6 +55,7 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
private fitAddon: FitAddon | null = null;
private lastLineCount: number = 0;
private resizeObserver: ResizeObserver | null = null;
private terminalThemeSubscription: any = null;
public static styles = [
themeDefaultStyles,
@@ -69,8 +70,8 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
height: 100%;
border-radius: 8px;
overflow: hidden;
background: #000000;
border: 1px solid hsl(0 0% 20%);
background: ${cssManager.bdTheme('#ffffff', '#000000')};
border: 1px solid ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(0 0% 20%)')};
display: flex;
flex-direction: column;
}
@@ -80,20 +81,20 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
align-items: center;
gap: 8px;
padding: 8px 12px;
background: hsl(0 0% 10%);
background: ${cssManager.bdTheme('hsl(0 0% 96%)', 'hsl(0 0% 10%)')};
font-size: 12px;
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
color: hsl(0 0% 60%);
border-bottom: 1px solid hsl(0 0% 20%);
color: ${cssManager.bdTheme('hsl(0 0% 40%)', 'hsl(0 0% 60%)')};
border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 85%)', 'hsl(0 0% 20%)')};
flex-shrink: 0;
}
.terminal-header-icon {
color: hsl(0 0% 50%);
color: ${cssManager.bdTheme('hsl(0 0% 50%)', 'hsl(0 0% 50%)')};
}
.terminal-header-command {
color: hsl(0 0% 80%);
color: ${cssManager.bdTheme('hsl(0 0% 20%)', 'hsl(0 0% 80%)')};
font-weight: 500;
}
@@ -148,8 +149,8 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
}
.xterm .composition-view {
background: #000000;
color: #fff;
background: ${cssManager.bdTheme('#ffffff', '#000000')};
color: ${cssManager.bdTheme('#333333', '#ffffff')};
display: none;
position: absolute;
white-space: nowrap;
@@ -161,7 +162,7 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
}
.xterm .xterm-viewport {
background-color: #000000;
background-color: ${cssManager.bdTheme('#ffffff', '#000000')};
overflow-y: scroll;
cursor: default;
position: absolute;
@@ -243,16 +244,16 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
}
.xterm .xterm-viewport::-webkit-scrollbar-track {
background: hsl(0 0% 8%);
background: ${cssManager.bdTheme('hsl(0 0% 96%)', 'hsl(0 0% 8%)')};
}
.xterm .xterm-viewport::-webkit-scrollbar-thumb {
background: hsl(0 0% 25%);
background: ${cssManager.bdTheme('hsl(0 0% 80%)', 'hsl(0 0% 25%)')};
border-radius: 4px;
}
.xterm .xterm-viewport::-webkit-scrollbar-thumb:hover {
background: hsl(0 0% 35%);
background: ${cssManager.bdTheme('hsl(0 0% 70%)', 'hsl(0 0% 35%)')};
}
`,
];
@@ -271,6 +272,27 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
`;
}
/**
* Get terminal theme colors based on bright/dark mode
*/
private getTerminalTheme(isBright: boolean) {
return isBright
? {
background: '#ffffff',
foreground: '#333333',
cursor: '#333333',
cursorAccent: '#ffffff',
selectionBackground: 'rgba(0, 0, 0, 0.2)',
}
: {
background: '#000000',
foreground: '#cccccc',
cursor: '#cccccc',
cursorAccent: '#000000',
selectionBackground: 'rgba(255, 255, 255, 0.2)',
};
}
public async firstUpdated(
_changedProperties: Map<string | number | symbol, unknown>
): Promise<void> {
@@ -279,6 +301,10 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
const container = this.shadowRoot?.getElementById('xterm-container');
if (!container) return;
// Get current theme from domtools
const domtoolsInstance = await this.domtoolsPromise;
const isBright = domtoolsInstance.themeManager.goBrightBoolean;
// Create xterm terminal in read-only mode
this.terminal = new Terminal({
convertEol: true,
@@ -286,13 +312,17 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
disableStdin: true,
fontSize: 12,
fontFamily: "'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace",
theme: {
background: '#000000',
foreground: '#cccccc',
},
theme: this.getTerminalTheme(isBright),
scrollback: 1000,
});
// Subscribe to theme changes
this.terminalThemeSubscription = domtoolsInstance.themeManager.themeObservable.subscribe((goBright: boolean) => {
if (this.terminal) {
this.terminal.options.theme = this.getTerminalTheme(goBright);
}
});
this.fitAddon = new FitAddon();
this.terminal.loadAddon(this.fitAddon);
this.terminal.open(container);
@@ -334,6 +364,10 @@ export class DeesWorkspaceTerminalPreview extends DeesElement {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
if (this.terminalThemeSubscription) {
this.terminalThemeSubscription.unsubscribe();
this.terminalThemeSubscription = null;
}
if (this.terminal) {
this.terminal.dispose();
this.terminal = null;