From ee19582891ecacd1d32347d518bd47e14edba9d4 Mon Sep 17 00:00:00 2001 From: plusk-dev Date: Fri, 23 Oct 2026 15:32:18 +0530 Subject: [PATCH 1/3] Fix sf pro font in settings -> appearance -> font --- apps/web/src/appearanceFonts.ts | 19 +++++++++++++++++++ .../components/settings/FontFamilyPicker.tsx | 18 +++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/apps/web/src/appearanceFonts.ts b/apps/web/src/appearanceFonts.ts index c816836ae8aed..a66ab5ac5edac 100644 --- a/apps/web/src/appearanceFonts.ts +++ b/apps/web/src/appearanceFonts.ts @@ -274,6 +274,25 @@ function resolveGenericFamilyLabel(generic: string): string | null { return null; } +/** + * CSS family name that actually renders a given (possibly synthetic) font + * label. Labels like "SF Pro" are produced for the macOS system UI face, but + * "SF Pro" is not a resolvable CSS family name, so an element styled with it + * falls back to the browser default (usually a serif). Map such labels to a + * resolvable family so previews and dropdown rows render in the right face. + */ +export function displayFontFamily(family: string): string { + const trimmed = family.trim(); + if (trimmed.length === 0) return ""; + // Strip quotes only for the synthetic-label comparison; keep the original + // trimmed value for output and normalize it through cssFontFamilies. + const unquoted = trimmed.replace(/^(['"])(.*)\1$/, "$2").trim(); + const lower = unquoted.toLowerCase(); + if (lower === "sf pro") return "-apple-system, BlinkMacSystemFont, system-ui, sans-serif"; + if (lower === "sf mono") return '"SF Mono", "SFMono-Regular", ui-monospace, monospace'; + return cssFontFamilies(trimmed) ?? trimmed; +} + export function resolveDefaultFamilyLabel(stack: string): string | null { for (const raw of stack.split(",")) { const family = raw.trim().replace(/^(['"])(.*)\1$/, "$2"); diff --git a/apps/web/src/components/settings/FontFamilyPicker.tsx b/apps/web/src/components/settings/FontFamilyPicker.tsx index 449b263f62947..ba3f3b1c5c7bb 100644 --- a/apps/web/src/components/settings/FontFamilyPicker.tsx +++ b/apps/web/src/components/settings/FontFamilyPicker.tsx @@ -1,7 +1,11 @@ import { LegendList, type LegendListRef } from "@legendapp/list/react"; import { CheckIcon } from "lucide-react"; import { useEffect, useRef, useState, useSyncExternalStore } from "react"; -import { isMonospaceFamily, queryInstalledFontFamilies } from "../../appearanceFonts"; +import { + displayFontFamily, + isMonospaceFamily, + queryInstalledFontFamilies, +} from "../../appearanceFonts"; import { Combobox, ComboboxEmpty, @@ -153,7 +157,7 @@ export function FontFamilyPicker({ return (
- + {family} @@ -185,7 +189,15 @@ export function FontFamilyPicker({ }} > }> - {selectedFamily.length === 0 ? defaultFamily : selectedFamily} + + {selectedFamily.length === 0 ? defaultFamily : selectedFamily} + Date: Mon, 26 Oct 2026 20:14:07 +0000 Subject: [PATCH 2/3] fix(web): keep font picker previews scoped to dropdown rows --- apps/web/src/appearanceFonts.ts | 25 +++++++------------ .../components/settings/FontFamilyPicker.tsx | 10 +------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/apps/web/src/appearanceFonts.ts b/apps/web/src/appearanceFonts.ts index cea0f07566471..5c01f340a7e35 100644 --- a/apps/web/src/appearanceFonts.ts +++ b/apps/web/src/appearanceFonts.ts @@ -259,23 +259,16 @@ function resolveGenericFamilyLabel(generic: string): string | null { return null; } -/** - * CSS family name that actually renders a given (possibly synthetic) font - * label. Labels like "SF Pro" are produced for the macOS system UI face, but - * "SF Pro" is not a resolvable CSS family name, so an element styled with it - * falls back to the browser default (usually a serif). Map such labels to a - * resolvable family so previews and dropdown rows render in the right face. - */ +// Synthetic Apple labels are not necessarily available as named CSS families. export function displayFontFamily(family: string): string { - const trimmed = family.trim(); - if (trimmed.length === 0) return ""; - // Strip quotes only for the synthetic-label comparison; keep the original - // trimmed value for output and normalize it through cssFontFamilies. - const unquoted = trimmed.replace(/^(['"])(.*)\1$/, "$2").trim(); - const lower = unquoted.toLowerCase(); - if (lower === "sf pro") return "-apple-system, BlinkMacSystemFont, system-ui, sans-serif"; - if (lower === "sf mono") return '"SF Mono", "SFMono-Regular", ui-monospace, monospace'; - return cssFontFamilies(trimmed) ?? trimmed; + const label = family + .trim() + .replace(/^(['"])(.*)\1$/, "$2") + .trim() + .toLowerCase(); + if (label === "sf pro") return DEFAULT_SANS_FONT_STACK; + if (label === "sf mono") return DEFAULT_CODE_FONT_STACK; + return cssFontFamilies(family) ?? ""; } export function resolveDefaultFamilyLabel(stack: string): string | null { diff --git a/apps/web/src/components/settings/FontFamilyPicker.tsx b/apps/web/src/components/settings/FontFamilyPicker.tsx index 29967d5e56792..24d293d5569b5 100644 --- a/apps/web/src/components/settings/FontFamilyPicker.tsx +++ b/apps/web/src/components/settings/FontFamilyPicker.tsx @@ -183,15 +183,7 @@ export function FontFamilyPicker({ }} > }> - - {selectedFamily.length === 0 ? defaultFamily : selectedFamily} - + {selectedFamily.length === 0 ? defaultFamily : selectedFamily} Date: Mon, 26 Oct 2026 20:16:07 +0000 Subject: [PATCH 3/3] fix(web): preserve installed SF Pro in font previews --- apps/web/src/appearanceFonts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/appearanceFonts.ts b/apps/web/src/appearanceFonts.ts index 5c01f340a7e35..f90827c42b851 100644 --- a/apps/web/src/appearanceFonts.ts +++ b/apps/web/src/appearanceFonts.ts @@ -266,7 +266,7 @@ export function displayFontFamily(family: string): string { .replace(/^(['"])(.*)\1$/, "$2") .trim() .toLowerCase(); - if (label === "sf pro") return DEFAULT_SANS_FONT_STACK; + if (label === "sf pro") return appearanceFontStack(family, DEFAULT_SANS_FONT_STACK); if (label === "sf mono") return DEFAULT_CODE_FONT_STACK; return cssFontFamilies(family) ?? ""; }