Skip to content

Commit b06d6d6

Browse files
authored
Add configurable code font size override (#301)
* Add configurable code font size override - Persist a code font size override in custom theme state - Apply it to CodeMirror and the terminal - Surface the setting in the theme summary and reset flow * Add font size override for code views - Wire code block styling to a configurable font-size token - Add a settings slider to adjust and reset code editor and terminal font size
1 parent d24f841 commit b06d6d6

File tree

5 files changed

+88
-4
lines changed

5 files changed

+88
-4
lines changed

apps/web/src/components/CodeMirrorViewer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const baseExtensions: Extension[] = [
3636
EditorView.theme({
3737
"&": {
3838
height: "100%",
39-
fontSize: "12px",
39+
fontSize: "var(--font-size-code, 12px)",
4040
backgroundColor: "var(--background)",
4141
},
4242
".cm-scroller": {

apps/web/src/components/ThreadTerminalDrawer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
type ThreadTerminalGroup,
4040
} from "../types";
4141
import { readNativeApi } from "~/nativeApi";
42+
import { getStoredFontSizeOverride } from "~/lib/customTheme";
4243

4344
const MIN_DRAWER_HEIGHT = 180;
4445
const MAX_DRAWER_HEIGHT_RATIO = 0.75;
@@ -285,7 +286,7 @@ function TerminalViewport({
285286
const terminal = new Terminal({
286287
cursorBlink: true,
287288
lineHeight: 1.2,
288-
fontSize: 12,
289+
fontSize: getStoredFontSizeOverride() ?? 12,
289290
scrollback: 5_000,
290291
fontFamily: '"SF Mono", "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace',
291292
theme: terminalThemeFromApp(),

apps/web/src/index.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ label:has(> select#reasoning-effort) select {
325325
background: var(--muted);
326326
padding: 0.1rem 0.35rem;
327327
color: var(--foreground);
328-
font-size: 0.75rem;
328+
font-size: var(--font-size-code, 0.75rem);
329329
}
330330

331331
.chat-markdown pre {
@@ -342,7 +342,7 @@ label:has(> select#reasoning-effort) select {
342342
background: transparent;
343343
padding: 0;
344344
line-height: 1.5;
345-
font-size: 0.875rem;
345+
font-size: var(--font-size-code, 0.875rem);
346346
}
347347

348348
.chat-markdown .chat-markdown-codeblock {

apps/web/src/lib/customTheme.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const CUSTOM_THEME_STYLE_ID = "okcode-custom-theme-style";
7171
const CUSTOM_THEME_FONT_LINK_ID = "okcode-custom-theme-fonts";
7272
const RADIUS_OVERRIDE_KEY = "okcode:radius-override";
7373
const FONT_OVERRIDE_KEY = "okcode:font-override";
74+
const FONT_SIZE_OVERRIDE_KEY = "okcode:font-size-override";
7475
const LEGACY_BACKGROUND_STYLE_ID = "okcode-background-image-style";
7576

7677
/** System-bundled fonts that don't need to be loaded from Google Fonts. */
@@ -568,6 +569,39 @@ export function applyFontOverride(): void {
568569
}
569570
}
570571

572+
// ---------------------------------------------------------------------------
573+
// Font Size Override (applies to code editors and terminal)
574+
// ---------------------------------------------------------------------------
575+
576+
export function getStoredFontSizeOverride(): number | null {
577+
const raw = localStorage.getItem(FONT_SIZE_OVERRIDE_KEY);
578+
if (raw === null) return null;
579+
const num = Number.parseFloat(raw);
580+
return Number.isFinite(num) ? num : null;
581+
}
582+
583+
export function setStoredFontSizeOverride(px: number): void {
584+
localStorage.setItem(FONT_SIZE_OVERRIDE_KEY, String(px));
585+
if (hasDom()) {
586+
document.documentElement.style.setProperty("--font-size-code", `${px}px`);
587+
}
588+
}
589+
590+
export function clearFontSizeOverride(): void {
591+
localStorage.removeItem(FONT_SIZE_OVERRIDE_KEY);
592+
if (hasDom()) {
593+
document.documentElement.style.removeProperty("--font-size-code");
594+
}
595+
}
596+
597+
export function applyFontSizeOverride(): void {
598+
if (!hasDom()) return;
599+
const val = getStoredFontSizeOverride();
600+
if (val !== null) {
601+
document.documentElement.style.setProperty("--font-size-code", `${val}px`);
602+
}
603+
}
604+
571605
// ---------------------------------------------------------------------------
572606
// Initialization (called on module load)
573607
// ---------------------------------------------------------------------------
@@ -590,4 +624,7 @@ export function initCustomTheme(): void {
590624

591625
// Always apply font override if set
592626
applyFontOverride();
627+
628+
// Always apply font size override if set
629+
applyFontSizeOverride();
593630
}

apps/web/src/routes/_chat.settings.tsx

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ import {
5151
import {
5252
applyCustomTheme,
5353
clearFontOverride,
54+
clearFontSizeOverride,
5455
clearRadiusOverride,
5556
clearStoredCustomTheme,
5657
getStoredCustomTheme,
5758
getStoredFontOverride,
59+
getStoredFontSizeOverride,
5860
getStoredRadiusOverride,
5961
removeCustomTheme,
6062
setStoredFontOverride,
63+
setStoredFontSizeOverride,
6164
setStoredRadiusOverride,
6265
type CustomThemeData,
6366
} from "../lib/customTheme";
@@ -351,6 +354,9 @@ function SettingsRouteView() {
351354
const [fontOverride, setFontOverrideState] = useState<string>(
352355
() => getStoredFontOverride() ?? "",
353356
);
357+
const [fontSizeOverride, setFontSizeOverrideState] = useState<number | null>(() =>
358+
getStoredFontSizeOverride(),
359+
);
354360
const globalEnvironmentVariablesQuery = useQuery(globalEnvironmentVariablesQueryOptions());
355361
const activeProjectId = selectedProjectId ?? projects[0]?.id ?? null;
356362
const selectedProject = projects.find((project) => project.id === activeProjectId) ?? null;
@@ -462,6 +468,7 @@ function SettingsRouteView() {
462468
: []),
463469
...(radiusOverride !== null ? ["Border radius"] : []),
464470
...(fontOverride ? ["Font family"] : []),
471+
...(fontSizeOverride !== null ? ["Font size"] : []),
465472
];
466473

467474
const openKeybindingsFile = useCallback(() => {
@@ -610,6 +617,8 @@ function SettingsRouteView() {
610617
setRadiusOverrideState(null);
611618
clearFontOverride();
612619
setFontOverrideState("");
620+
clearFontSizeOverride();
621+
setFontSizeOverrideState(null);
613622
}
614623

615624
return (
@@ -793,6 +802,43 @@ function SettingsRouteView() {
793802
}
794803
/>
795804

805+
<SettingsRow
806+
title="Font size"
807+
description="Adjust the font size for code editors and terminal."
808+
resetAction={
809+
fontSizeOverride !== null ? (
810+
<SettingResetButton
811+
label="font size"
812+
onClick={() => {
813+
clearFontSizeOverride();
814+
setFontSizeOverrideState(null);
815+
}}
816+
/>
817+
) : null
818+
}
819+
control={
820+
<div className="flex items-center gap-2">
821+
<input
822+
type="range"
823+
min={10}
824+
max={20}
825+
step={1}
826+
value={fontSizeOverride ?? 12}
827+
onChange={(e) => {
828+
const value = Number.parseFloat(e.target.value);
829+
setFontSizeOverrideState(value);
830+
setStoredFontSizeOverride(value);
831+
}}
832+
className="h-1.5 w-24 cursor-pointer appearance-none rounded-full bg-muted accent-foreground sm:w-28"
833+
aria-label="Font size"
834+
/>
835+
<span className="w-12 text-right text-xs tabular-nums text-muted-foreground">
836+
{fontSizeOverride ?? 12}px
837+
</span>
838+
</div>
839+
}
840+
/>
841+
796842
<SettingsRow
797843
title="Font family"
798844
description="Override the UI font. Use any Google Font name."

0 commit comments

Comments
 (0)