mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
More UI Tweaks, Testing Variable Fonts for Sidebar/Tabs (#348)
* MonoFontSize type, add label font, theme vars for sidebar * fix line-height for tabs * experiment with variable label font * lato font, fix open ai fonts, fix cmdinput font
This commit is contained in:
parent
d9ca9394ac
commit
3f83441868
public/fonts
src
BIN
public/fonts/lato-bold.woff
Normal file
BIN
public/fonts/lato-bold.woff
Normal file
Binary file not shown.
BIN
public/fonts/lato-regular.woff
Normal file
BIN
public/fonts/lato-regular.woff
Normal file
Binary file not shown.
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
@import "./root.less";
|
||||
@import "./overrides.less";
|
||||
|
||||
html,
|
||||
body {
|
||||
@ -153,6 +154,12 @@ svg.icon {
|
||||
background-color: var(--scrollbar-thumb-hover-color) !important;
|
||||
}
|
||||
|
||||
.no-highlight-scrollbar {
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--scrollbar-thumb-color) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.hide-scrollbar {
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
16
src/app/overrides.less
Normal file
16
src/app/overrides.less
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
:root {
|
||||
// can put dev overrides for testing here
|
||||
|
||||
--label-font-family: "Lato", sans-serif;
|
||||
|
||||
--sidebar-font-size: 15px;
|
||||
--sidebar-font-weight: normal;
|
||||
--sidebar-highlight-font-weight: bold;
|
||||
|
||||
--screentabs-font-size: 15px;
|
||||
--screentabs-font-weight: normal;
|
||||
--screentabs-selected-font-weight: bold;
|
||||
}
|
@ -16,9 +16,15 @@
|
||||
--text-s1-font: "Martian Mono", sans-serif;
|
||||
--markdown-font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif,
|
||||
"Apple Color Emoji", "Segoe UI Emoji";
|
||||
--label-font-family: "Martian Mono", sans-serif;
|
||||
|
||||
// magic
|
||||
--screentabs-height: 38px;
|
||||
--markdown-font-size: 14px;
|
||||
|
||||
--screentabs-height: 38px; // magic
|
||||
--screentabs-line-height: 21px; // magic
|
||||
--screentabs-font-size: 12.5px;
|
||||
--screentabs-font-weight: 300;
|
||||
--screentabs-selected-font-weight: 300;
|
||||
|
||||
// global colors
|
||||
--app-accent-color: rgb(88, 193, 66);
|
||||
@ -139,6 +145,10 @@
|
||||
--sidebar-settings-color: rgb(255, 255, 255);
|
||||
--sidebar-separator-color: var(--app-border-color);
|
||||
--sidebar-highlight-color: rgba(241, 246, 243, 0.08);
|
||||
--sidebar-font-size: 12.5px;
|
||||
--sidebar-line-height: 1.5;
|
||||
--sidebar-font-weight: 300;
|
||||
--sidebar-highlight-font-weight: 300;
|
||||
|
||||
// line colors
|
||||
--line-sidebar-message-color: rgb(196, 160, 0);
|
||||
|
@ -12,6 +12,9 @@
|
||||
border-radius: var(--app-border-radius) 0 0 var(--app-border-radius);
|
||||
border-left: 1px solid var(--app-border-color);
|
||||
border-bottom: 1px solid var(--app-border-color);
|
||||
font-size: var(--sidebar-font-size);
|
||||
font-family: var(--label-font-family);
|
||||
font-weight: var(--sidebar-font-weight);
|
||||
|
||||
.title-bar-drag {
|
||||
-webkit-app-region: drag;
|
||||
@ -149,6 +152,7 @@
|
||||
.item {
|
||||
&.active {
|
||||
background-color: var(--sidebar-highlight-color);
|
||||
font-weight: var(--sidebar-highlight-font-weight);
|
||||
}
|
||||
.index {
|
||||
font-size: 10px;
|
||||
|
@ -135,6 +135,7 @@
|
||||
overflow-wrap: anywhere;
|
||||
border-color: transparent;
|
||||
border: none;
|
||||
font-family: var(--termfontfamily);
|
||||
line-height: var(--termlineheight);
|
||||
font-size: var(--termfontsize);
|
||||
border-radius: 4px 4px 0 4px; // 0 is for shelltag
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
#main .screen-tabs .screen-tab {
|
||||
border-top: 1px solid transparent;
|
||||
font-size: 12.5px;
|
||||
font-size: var(--screentabs-font-size);
|
||||
line-height: var(--screentabs-line-height);
|
||||
font-family: var(--label-font-family);
|
||||
font-weight: var(--screentabs-font-weight);
|
||||
|
||||
&:not(:hover) .status-indicator {
|
||||
.status-indicator-visible;
|
||||
@ -81,7 +84,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.screen-tabs-container {
|
||||
// #main for selectivity
|
||||
#main .screen-tabs-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@ -159,6 +163,7 @@
|
||||
&.is-active {
|
||||
border-top: none;
|
||||
opacity: 1;
|
||||
font-weight: var(--screentabs-selected-font-weight);
|
||||
}
|
||||
|
||||
&.is-archived {
|
||||
|
@ -185,7 +185,11 @@ class ScreenTabs extends React.Component<
|
||||
let activeScreenId = this.getActiveScreenId();
|
||||
const sidebarCollapsed = GlobalModel.mainSidebarModel.getCollapsed();
|
||||
return (
|
||||
<div className={cn("screen-tabs-container", { "sidebar-collapsed": sidebarCollapsed })}>
|
||||
<div
|
||||
className={cn("screen-tabs-container", {
|
||||
"sidebar-collapsed": sidebarCollapsed,
|
||||
})}
|
||||
>
|
||||
<If condition={sidebarCollapsed}>
|
||||
<div key="logo-button" className="logo-button-container">
|
||||
<div className="logo-button" onClick={this.openSidebar}>
|
||||
@ -194,7 +198,10 @@ class ScreenTabs extends React.Component<
|
||||
</div>
|
||||
</If>
|
||||
{/* Inner container ensures that hovering over the scrollbar doesn't trigger the hover effect on the tabs. This prevents weird flickering of the icons when the mouse is moved over the scrollbar. */}
|
||||
<div key="container-inner" className="screen-tabs-container-inner hideScrollbarUntillHover">
|
||||
<div
|
||||
key="container-inner"
|
||||
className="screen-tabs-container-inner no-highlight-scrollbar hideScrollbarUntillHover"
|
||||
>
|
||||
<Reorder.Group
|
||||
className="screen-tabs"
|
||||
ref={this.tabsRef}
|
||||
|
@ -7,8 +7,8 @@ import { createRoot } from "react-dom/client";
|
||||
import { sprintf } from "sprintf-js";
|
||||
import { App } from "@/app/app";
|
||||
import * as DOMPurify from "dompurify";
|
||||
import { loadFonts } from "./util/util";
|
||||
import * as textmeasure from "./util/textmeasure";
|
||||
import { loadFonts } from "@/util/fontutil";
|
||||
import * as textmeasure from "@/util/textmeasure";
|
||||
import { getApi } from "@/models";
|
||||
|
||||
// @ts-ignore
|
||||
|
@ -12,8 +12,8 @@ import {
|
||||
genMergeSimpleData,
|
||||
isModKeyPress,
|
||||
isBlank,
|
||||
loadFonts,
|
||||
} from "@/util/util";
|
||||
import { loadFonts } from "@/util/fontutil";
|
||||
import { WSControl } from "./ws";
|
||||
import { cmdStatusIsRunning } from "@/app/line/lineutil";
|
||||
import * as appconst from "@/app/appconst";
|
||||
|
@ -3,6 +3,7 @@
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
font-weight: normal;
|
||||
|
||||
.openai-role {
|
||||
color: var(--prompt-bright-green);
|
||||
@ -16,8 +17,10 @@
|
||||
}
|
||||
|
||||
.openai-content-user {
|
||||
white-space: pre;
|
||||
color: var(--app-text-color);
|
||||
font-family: var(--markdown-font);
|
||||
font-size: var(--markdown-font-size);
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.openai-content-assistant {
|
||||
|
7
src/types/custom.d.ts
vendored
7
src/types/custom.d.ts
vendored
@ -844,6 +844,13 @@ declare global {
|
||||
getContainerType(): LineContainerStrs;
|
||||
};
|
||||
|
||||
type MonoFontSize = {
|
||||
height: number;
|
||||
width: number;
|
||||
fontSize: number;
|
||||
pad: number;
|
||||
};
|
||||
|
||||
type KeyModsType = {
|
||||
meta?: boolean;
|
||||
ctrl?: boolean;
|
||||
|
118
src/util/fontutil.ts
Normal file
118
src/util/fontutil.ts
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
let isJetBrainsMonoLoaded = false;
|
||||
let isLatoFontLoaded = false;
|
||||
let isHackFontLoaded = false;
|
||||
let isBaseFontsLoaded = false;
|
||||
|
||||
function addToFontFaceSet(fontFaceSet: FontFaceSet, fontFace: FontFace) {
|
||||
// any cast to work around typing issue
|
||||
(fontFaceSet as any).add(fontFace);
|
||||
}
|
||||
|
||||
function loadJetBrainsMonoFont() {
|
||||
if (isJetBrainsMonoLoaded) {
|
||||
return;
|
||||
}
|
||||
isJetBrainsMonoLoaded = true;
|
||||
const jbmFontNormal = new FontFace("JetBrains Mono", "url('public/fonts/jetbrains-mono-v13-latin-regular.woff2')", {
|
||||
style: "normal",
|
||||
weight: "400",
|
||||
});
|
||||
const jbmFont200 = new FontFace("JetBrains Mono", "url('public/fonts/jetbrains-mono-v13-latin-200.woff2')", {
|
||||
style: "normal",
|
||||
weight: "200",
|
||||
});
|
||||
const jbmFont700 = new FontFace("JetBrains Mono", "url('public/fonts/jetbrains-mono-v13-latin-700.woff2')", {
|
||||
style: "normal",
|
||||
weight: "700",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, jbmFontNormal);
|
||||
addToFontFaceSet(document.fonts, jbmFont200);
|
||||
addToFontFaceSet(document.fonts, jbmFont700);
|
||||
jbmFontNormal.load();
|
||||
jbmFont200.load();
|
||||
jbmFont700.load();
|
||||
}
|
||||
|
||||
function loadLatoFont() {
|
||||
if (isLatoFontLoaded) {
|
||||
return;
|
||||
}
|
||||
isLatoFontLoaded = true;
|
||||
const latoFont = new FontFace("Lato", "url('public/fonts/lato-regular.woff')", {
|
||||
style: "normal",
|
||||
weight: "400",
|
||||
});
|
||||
const latoFontBold = new FontFace("Lato", "url('public/fonts/lato-bold.woff')", {
|
||||
style: "normal",
|
||||
weight: "700",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, latoFont);
|
||||
addToFontFaceSet(document.fonts, latoFontBold);
|
||||
latoFont.load();
|
||||
latoFontBold.load();
|
||||
}
|
||||
|
||||
function loadHackFont() {
|
||||
if (isHackFontLoaded) {
|
||||
return;
|
||||
}
|
||||
isHackFontLoaded = true;
|
||||
let hackRegular = new FontFace("Hack", "url('public/fonts/hack-regular.woff2')", {
|
||||
style: "normal",
|
||||
weight: "400",
|
||||
});
|
||||
let hackBold = new FontFace("Hack", "url('public/fonts/hack-bold.woff2')", {
|
||||
style: "normal",
|
||||
weight: "700",
|
||||
});
|
||||
let hackItalic = new FontFace("Hack", "url('public/fonts/hack-italic.woff2')", {
|
||||
style: "italic",
|
||||
weight: "400",
|
||||
});
|
||||
let hackBoldItalic = new FontFace("Hack", "url('public/fonts/hack-bolditalic.woff2')", {
|
||||
style: "italic",
|
||||
weight: "700",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, hackRegular);
|
||||
addToFontFaceSet(document.fonts, hackBold);
|
||||
addToFontFaceSet(document.fonts, hackItalic);
|
||||
addToFontFaceSet(document.fonts, hackBoldItalic);
|
||||
hackRegular.load();
|
||||
hackBold.load();
|
||||
hackItalic.load();
|
||||
hackBoldItalic.load();
|
||||
}
|
||||
|
||||
function loadBaseFonts() {
|
||||
if (isBaseFontsLoaded) {
|
||||
return;
|
||||
}
|
||||
isBaseFontsLoaded = true;
|
||||
let faFont = new FontFace("FontAwesome", "url(public/fonts/fontawesome-webfont-4.7.woff2)", {
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
});
|
||||
let mmFont = new FontFace("Martian Mono", "url(public/fonts/MartianMono-VariableFont_wdth,wght.ttf)", {
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, faFont);
|
||||
addToFontFaceSet(document.fonts, mmFont);
|
||||
faFont.load();
|
||||
mmFont.load();
|
||||
}
|
||||
|
||||
function loadFonts(termFont: string) {
|
||||
loadBaseFonts();
|
||||
loadLatoFont();
|
||||
loadJetBrainsMonoFont();
|
||||
if (termFont == "Hack") {
|
||||
loadHackFont();
|
||||
}
|
||||
document.documentElement.style.setProperty("--termfontfamily", '"' + termFont + '"');
|
||||
}
|
||||
|
||||
export { loadFonts };
|
@ -7,7 +7,7 @@ import { MagicLayout } from "@/app/magiclayout";
|
||||
const MinTermCols = 10;
|
||||
const MaxTermCols = 1024;
|
||||
|
||||
let MonoFontSizes: { height: number; width: number }[] = [];
|
||||
let MonoFontSizes: MonoFontSize[] = [];
|
||||
|
||||
// MonoFontSizes[8] = {height: 11, width: 4.797};
|
||||
// MonoFontSizes[9] = {height: 12, width: 5.398};
|
||||
@ -19,7 +19,7 @@ let MonoFontSizes: { height: number; width: number }[] = [];
|
||||
// MonoFontSizes[15] = {height: 20, width: 9};
|
||||
// MonoFontSizes[16] = {height: 22, width: 9.594};
|
||||
|
||||
function getMonoFontSize(fontSize: number): { height: number; width: number } {
|
||||
function getMonoFontSize(fontSize: number): MonoFontSize {
|
||||
if (MonoFontSizes[fontSize] != null) {
|
||||
return MonoFontSizes[fontSize];
|
||||
}
|
||||
@ -34,12 +34,9 @@ function clearMonoFontCache(): void {
|
||||
MonoFontSizes = [];
|
||||
}
|
||||
|
||||
function measureText(
|
||||
text: string,
|
||||
textOpts?: { pre?: boolean; mono?: boolean; fontSize?: number | string }
|
||||
): { height: number; width: number } {
|
||||
function measureText(text: string, textOpts: { pre?: boolean; mono?: boolean; fontSize: number }): MonoFontSize {
|
||||
if (textOpts == null) {
|
||||
textOpts = {};
|
||||
throw new Error("invalid textOpts passed to measureText (null)");
|
||||
}
|
||||
let textElem = document.createElement("span");
|
||||
if (textOpts.pre) {
|
||||
@ -61,9 +58,10 @@ function measureText(
|
||||
throw new Error("cannot measure text, no #measure div");
|
||||
}
|
||||
measureDiv.replaceChildren(textElem);
|
||||
let height = textElem.offsetHeight;
|
||||
let height = Math.ceil(textElem.offsetHeight);
|
||||
let width = textElem.offsetWidth;
|
||||
return { width: width, height: Math.ceil(height) };
|
||||
let pad = Math.floor(height / 2);
|
||||
return { width, height, pad, fontSize: textOpts.fontSize };
|
||||
}
|
||||
|
||||
function windowWidthToCols(width: number, fontSize: number): number {
|
||||
|
@ -242,101 +242,6 @@ function incObs(inum: mobx.IObservableValue<number>) {
|
||||
})();
|
||||
}
|
||||
|
||||
function addToFontFaceSet(fontFaceSet: FontFaceSet, fontFace: FontFace) {
|
||||
// any cast to work around typing issue
|
||||
(fontFaceSet as any).add(fontFace);
|
||||
}
|
||||
|
||||
let isJetBrainsMonoLoaded = false;
|
||||
|
||||
function loadJetBrainsMonoFont() {
|
||||
if (isJetBrainsMonoLoaded) {
|
||||
return;
|
||||
}
|
||||
isJetBrainsMonoLoaded = true;
|
||||
let jbmFontNormal = new FontFace("JetBrains Mono", "url('public/fonts/jetbrains-mono-v13-latin-regular.woff2')", {
|
||||
style: "normal",
|
||||
weight: "400",
|
||||
});
|
||||
const jbmFont200 = new FontFace("JetBrains Mono", "url('public/fonts/jetbrains-mono-v13-latin-200.woff2')", {
|
||||
style: "normal",
|
||||
weight: "200",
|
||||
});
|
||||
const jbmFont700 = new FontFace("JetBrains Mono", "url('public/fonts/jetbrains-mono-v13-latin-700.woff2')", {
|
||||
style: "normal",
|
||||
weight: "700",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, jbmFontNormal);
|
||||
addToFontFaceSet(document.fonts, jbmFont200);
|
||||
addToFontFaceSet(document.fonts, jbmFont700);
|
||||
jbmFontNormal.load();
|
||||
jbmFont200.load();
|
||||
jbmFont700.load();
|
||||
}
|
||||
|
||||
let isHackFontLoaded = false;
|
||||
|
||||
function loadHackFont() {
|
||||
if (isHackFontLoaded) {
|
||||
return;
|
||||
}
|
||||
isHackFontLoaded = true;
|
||||
let hackRegular = new FontFace("Hack", "url('public/fonts/hack-regular.woff2')", {
|
||||
style: "normal",
|
||||
weight: "400",
|
||||
});
|
||||
let hackBold = new FontFace("Hack", "url('public/fonts/hack-bold.woff2')", {
|
||||
style: "normal",
|
||||
weight: "700",
|
||||
});
|
||||
let hackItalic = new FontFace("Hack", "url('public/fonts/hack-italic.woff2')", {
|
||||
style: "italic",
|
||||
weight: "400",
|
||||
});
|
||||
let hackBoldItalic = new FontFace("Hack", "url('public/fonts/hack-bolditalic.woff2')", {
|
||||
style: "italic",
|
||||
weight: "700",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, hackRegular);
|
||||
addToFontFaceSet(document.fonts, hackBold);
|
||||
addToFontFaceSet(document.fonts, hackItalic);
|
||||
addToFontFaceSet(document.fonts, hackBoldItalic);
|
||||
hackRegular.load();
|
||||
hackBold.load();
|
||||
hackItalic.load();
|
||||
hackBoldItalic.load();
|
||||
}
|
||||
|
||||
let isBaseFontsLoaded = false;
|
||||
|
||||
function loadBaseFonts() {
|
||||
if (isBaseFontsLoaded) {
|
||||
return;
|
||||
}
|
||||
isBaseFontsLoaded = true;
|
||||
let faFont = new FontFace("FontAwesome", "url(public/fonts/fontawesome-webfont-4.7.woff2)", {
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
});
|
||||
let mmFont = new FontFace("Martian Mono", "url(public/fonts/MartianMono-VariableFont_wdth,wght.ttf)", {
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
});
|
||||
addToFontFaceSet(document.fonts, faFont);
|
||||
addToFontFaceSet(document.fonts, mmFont);
|
||||
faFont.load();
|
||||
mmFont.load();
|
||||
}
|
||||
|
||||
function loadFonts(termFont: string) {
|
||||
loadBaseFonts();
|
||||
loadJetBrainsMonoFont();
|
||||
if (termFont == "Hack") {
|
||||
loadHackFont();
|
||||
}
|
||||
document.documentElement.style.setProperty("--termfontfamily", '"' + termFont + '"');
|
||||
}
|
||||
|
||||
const DOW_STRS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
||||
|
||||
function getTodayStr(): string {
|
||||
@ -470,7 +375,6 @@ export {
|
||||
isModKeyPress,
|
||||
incObs,
|
||||
isBlank,
|
||||
loadFonts,
|
||||
getTodayStr,
|
||||
getYesterdayStr,
|
||||
getDateStr,
|
||||
|
Loading…
Reference in New Issue
Block a user