Files
NetMesh/infrastructure/config/uiFonts.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

191 lines
4.3 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* UI Fonts Configuration
* Includes general-purpose fonts suitable for application interface
*/
export interface UIFont {
id: string;
name: string;
family: string;
}
export type UiPlatform = 'darwin' | 'win32' | 'linux';
/**
* Bundled Noto Color Emoji subset (regional indicators U+1F1E61F1FF).
* Windows system fonts omit flag glyphs and show ISO country codes instead —
* see #1589, #1604.
*/
export const WINDOWS_FLAG_EMOJI_FONT = '"Noto Color Emoji Flags"';
/**
* Windows bundles UI fonts via @font-face. Their regional-indicator glyphs
* render as separate letters instead of composed flag emoji unless a color
* emoji font is consulted first — see #1589.
*/
export const WINDOWS_UI_EMOJI_FONTS = WINDOWS_FLAG_EMOJI_FONT;
/**
* Fallback fonts for CJK (Chinese, Japanese, Korean) support
*/
const CJK_FALLBACK_FONTS = [
'"PingFang SC"',
'"Hiragino Sans GB"',
'"Microsoft YaHei UI"',
'"Microsoft YaHei"',
'"Noto Sans CJK SC"',
'"Source Han Sans SC"',
'sans-serif',
];
const CJK_FALLBACK_STACK = CJK_FALLBACK_FONTS.join(', ');
export const withUiCjkFallback = (family: string) => {
const trimmed = family.trim();
// Avoid double-appending if a custom stack already includes one of these fonts.
if (CJK_FALLBACK_FONTS.some((f) => trimmed.includes(f.replace(/"/g, '')))) {
return trimmed;
}
return `${trimmed}, ${CJK_FALLBACK_STACK}`;
};
export function detectUiPlatform(userAgent: string): UiPlatform {
if (/Win/i.test(userAgent)) return 'win32';
if (/Mac|iPod|iPhone|iPad/i.test(userAgent)) return 'darwin';
return 'linux';
}
export function withWindowsEmojiFallback(
family: string,
platform: UiPlatform = typeof navigator !== 'undefined'
? detectUiPlatform(navigator.userAgent)
: 'linux',
): string {
if (platform !== 'win32') return family;
const trimmed = family.trim();
if (trimmed.includes('Noto Color Emoji Flags') || trimmed.includes('Segoe UI Emoji')) {
return trimmed;
}
return `${WINDOWS_UI_EMOJI_FONTS}, ${trimmed}, "Segoe UI Emoji", "Segoe UI Symbol"`;
}
const BASE_UI_FONTS: UIFont[] = [
{
id: 'mona-sans',
name: 'Mona Sans',
family: '"Mona Sans", system-ui',
},
{
id: 'space-grotesk',
name: 'Space Grotesk',
family: '"Space Grotesk", system-ui',
},
{
id: 'system-ui',
name: 'System UI',
family: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial',
},
{
id: 'inter',
name: 'Inter',
family: '"Inter", system-ui',
},
{
id: 'roboto',
name: 'Roboto',
family: '"Roboto", system-ui',
},
{
id: 'open-sans',
name: 'Open Sans',
family: '"Open Sans", system-ui',
},
{
id: 'lato',
name: 'Lato',
family: '"Lato", system-ui',
},
{
id: 'nunito',
name: 'Nunito',
family: '"Nunito", system-ui',
},
{
id: 'poppins',
name: 'Poppins',
family: '"Poppins", system-ui',
},
{
id: 'source-sans-pro',
name: 'Source Sans Pro',
family: '"Source Sans Pro", system-ui',
},
{
id: 'ubuntu',
name: 'Ubuntu',
family: '"Ubuntu", system-ui',
},
{
id: 'noto-sans',
name: 'Noto Sans',
family: '"Noto Sans", system-ui',
},
{
id: 'work-sans',
name: 'Work Sans',
family: '"Work Sans", system-ui',
},
{
id: 'dm-sans',
name: 'DM Sans',
family: '"DM Sans", system-ui',
},
{
id: 'montserrat',
name: 'Montserrat',
family: '"Montserrat", system-ui',
},
{
id: 'raleway',
name: 'Raleway',
family: '"Raleway", system-ui',
},
{
id: 'quicksand',
name: 'Quicksand',
family: '"Quicksand", system-ui',
},
{
id: 'ibm-plex-sans',
name: 'IBM Plex Sans',
family: '"IBM Plex Sans", system-ui',
},
{
id: 'outfit',
name: 'Outfit',
family: '"Outfit", system-ui',
},
{
id: 'plus-jakarta-sans',
name: 'Plus Jakarta Sans',
family: '"Plus Jakarta Sans", system-ui',
},
{
id: 'segoe-ui',
name: 'Segoe UI',
family: '"Segoe UI", system-ui',
},
{
id: 'sf-pro',
name: 'SF Pro',
family: '-apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui',
},
];
export const UI_FONTS: UIFont[] = BASE_UI_FONTS.map((font) => ({
...font,
family: withUiCjkFallback(font.family),
}));
export const DEFAULT_UI_FONT_ID = 'mona-sans';