Custom terminal fonts support (#5414)

Fixes #5132 #5133 
- bundled 7 new monospaced fonts for terminal
- fix: refresh terminal font after changing in the preferences / keep cluster iframe accessible in DOM while not active/focused
- display terminal's custom font preview with font-name in the select-box + live-preload for current `fontSize`, fix lint

* Fixes for <Input/>:
- remove duplicated error messages for sync validators
- don't propagate invalid values on change (uncontrolled components only)
- more informative error message for numeric input with min/max info
This commit is contained in:
Roman authored and GitHub committed 2022-06-06 18:03:12 +03:00
1 parent fae6bff6fb
commit 55a977554d
38 files changed
+325 -146

No files matched your search

@@ -64,16 +64,30 @@ export class Terminal {
}
}
constructor(protected readonly dependencies: TerminalDependencies, { tabId, api }: TerminalArguments) {
get fontFamily() {
return this.dependencies.terminalConfig.get().fontFamily;
}
get fontSize() {
return this.dependencies.terminalConfig.get().fontSize;
}
get theme(): Record<string/*paramName*/, string/*color*/> {
return this.dependencies.themeStore.xtermColors;
}
constructor(protected readonly dependencies: TerminalDependencies, {
tabId,
api,
}: TerminalArguments) {
this.tabId = tabId;
this.api = api;
const { fontSize, fontFamily } = this.dependencies.terminalConfig.get();
this.xterm = new XTerm({
cursorBlink: true,
cursorStyle: "bar",
fontSize,
fontFamily,
fontSize: this.fontSize,
fontFamily: this.fontFamily,
});
// enable terminal addons
this.xterm.loadAddon(this.fitAddon);
@@ -95,17 +109,11 @@ export class Terminal {
window.addEventListener("resize", this.onResize);
this.disposer.push(
reaction(() => this.dependencies.themeStore.xtermColors, colors => {
this.xterm?.setOption("theme", colors);
}, {
fireImmediately: true,
}),
reaction(() => this.dependencies.terminalConfig.get().fontSize, this.setFontSize, {
fireImmediately: true,
}),
reaction(() => this.dependencies.terminalConfig.get().fontFamily, this.setFontFamily, {
reaction(() => this.theme, colors => this.xterm.setOption("theme", colors), {
fireImmediately: true,
}),
reaction(() => this.fontSize, this.setFontSize, { fireImmediately: true }),
reaction(() => this.fontFamily, this.setFontFamily, { fireImmediately: true }),
() => onDataHandler.dispose(),
() => this.fitAddon.dispose(),
() => this.api.removeAllListeners(),
@@ -120,15 +128,14 @@ export class Terminal {
}
fit = () => {
// Since this function is debounced we need to read this value as late as possible
if (!this.xterm) {
return;
}
try {
this.fitAddon.fit();
const { cols, rows } = this.xterm;
const { cols, rows } = this.fitAddon.proposeDimensions();
// attempt to resize/fit terminal when it's not visible in DOM will crash with exception
// see: https://github.com/xtermjs/xterm.js/issues/3118
if (isNaN(cols) || isNaN(rows)) return;
this.fitAddon.fit();
this.api.sendTerminalSize(cols, rows);
} catch (error) {
// see https://github.com/lensapp/lens/issues/1891
@@ -197,12 +204,21 @@ export class Terminal {
}
};
setFontSize = (size: number) => {
this.xterm.options.fontSize = size;
setFontSize = (fontSize: number) => {
logger.info(`[TERMINAL]: set fontSize to ${fontSize}`);
this.xterm.options.fontSize = fontSize;
this.fit();
};
setFontFamily = (family: string) => {
this.xterm.options.fontFamily = family;
setFontFamily = (fontFamily: string) => {
logger.info(`[TERMINAL]: set fontFamily to ${fontFamily}`);
this.xterm.options.fontFamily = fontFamily;
this.fit();
// provide css-variable within `:root {}`
document.documentElement.style.setProperty("--font-terminal", fontFamily);
};
keyHandler = (evt: KeyboardEvent): boolean => {