From 36af9dd1d2235e7f7106cf6c1775348e245fde9e Mon Sep 17 00:00:00 2001 From: Hibryda Date: Sat, 7 Mar 2026 23:23:33 +0100 Subject: [PATCH] feat(v3): redesign SettingsTab global settings with split font controls Split single font setting into separate UI font (sans-serif options) and Terminal font (monospace options), each with custom themed dropdown and size stepper (8-24px). Single-column layout with Appearance and Defaults subsections. All native handleFontFamilyChange((e.target as HTMLSelectElement).value)} - > - - {#each FONT_OPTIONS as font} - - {/each} - - - -
- -
- - handleFontSizeChange((e.target as HTMLInputElement).value)} - /> - px - + UI Font +
+ +
+ + handleUiFontSizeChange((e.target as HTMLInputElement).value)} + /> + px + +
- + Terminal Font +
+ +
+ + handleTermFontSizeChange((e.target as HTMLInputElement).value)} + /> + px + +
+
+
+
+ + +
+

Defaults

+
+
+ { defaultShell = (e.target as HTMLInputElement).value; saveGlobalSetting('default_shell', defaultShell); }} />
-
- + input { padding: 6px 10px; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); @@ -398,7 +525,27 @@ font-size: 0.8rem; } - .setting-select { + .setting-row { + display: flex; + gap: 8px; + align-items: stretch; + } + + /* Reusable custom dropdown */ + .custom-dropdown { + position: relative; + } + + .dropdown-grow { + flex: 1; + min-width: 0; + } + + .dropdown-trigger { + display: flex; + align-items: center; + gap: 8px; + width: 100%; padding: 6px 10px; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); @@ -406,12 +553,112 @@ color: var(--ctp-text); font-size: 0.8rem; cursor: pointer; + text-align: left; + height: 100%; } + .dropdown-trigger:hover { + border-color: var(--ctp-surface2); + } + + .dropdown-label { + flex: 1; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .dropdown-arrow { + color: var(--ctp-overlay0); + font-size: 0.7rem; + flex-shrink: 0; + } + + .dropdown-menu { + position: absolute; + top: calc(100% + 4px); + left: 0; + min-width: 100%; + width: max-content; + max-height: 360px; + overflow-y: auto; + background: var(--ctp-mantle); + border: 1px solid var(--ctp-surface1); + border-radius: 4px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); + z-index: 100; + padding: 4px 0; + } + + .dropdown-group-label { + padding: 6px 10px 2px; + font-size: 0.65rem; + font-weight: 700; + color: var(--ctp-overlay0); + text-transform: uppercase; + letter-spacing: 0.05em; + } + + .dropdown-option { + display: flex; + align-items: center; + gap: 8px; + width: 100%; + padding: 5px 10px; + background: transparent; + border: none; + color: var(--ctp-subtext1); + font-size: 0.8rem; + cursor: pointer; + text-align: left; + white-space: nowrap; + } + + .dropdown-option:hover { + background: var(--ctp-surface0); + color: var(--ctp-text); + } + + .dropdown-option.active { + background: var(--ctp-surface0); + color: var(--ctp-text); + font-weight: 600; + } + + .dropdown-option-label { + flex: 1; + } + + /* Theme-specific dropdown extras */ + .theme-swatch { + display: inline-block; + width: 14px; + height: 14px; + border-radius: 3px; + border: 1px solid; + flex-shrink: 0; + } + + .theme-colors { + display: flex; + gap: 3px; + flex-shrink: 0; + } + + .color-dot { + display: inline-block; + width: 8px; + height: 8px; + border-radius: 50%; + } + + /* Size control (shared by UI and Terminal font) */ .size-control { display: flex; align-items: center; - gap: 4px; + gap: 2px; + flex-shrink: 0; } .size-btn { @@ -438,8 +685,8 @@ } .size-input { - width: 48px; - padding: 4px 6px; + width: 40px; + padding: 4px 2px; background: var(--ctp-surface0); border: 1px solid var(--ctp-surface1); border-radius: 4px; @@ -455,122 +702,9 @@ } .size-unit { - font-size: 0.75rem; - color: var(--ctp-overlay0); - } - - /* Custom theme dropdown */ - .theme-dropdown { - position: relative; - } - - .theme-trigger { - display: flex; - align-items: center; - gap: 8px; - width: 100%; - padding: 4px 8px; - background: var(--ctp-base); - border: 1px solid var(--ctp-surface1); - border-radius: 3px; - color: var(--ctp-text); - font-size: 0.8rem; - cursor: pointer; - text-align: left; - } - - .theme-trigger:hover { - border-color: var(--ctp-surface2); - } - - .theme-trigger-label { - flex: 1; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .theme-arrow { - color: var(--ctp-overlay0); font-size: 0.7rem; - flex-shrink: 0; - } - - .theme-swatch { - display: inline-block; - width: 14px; - height: 14px; - border-radius: 3px; - border: 1px solid; - flex-shrink: 0; - } - - .theme-menu { - position: absolute; - top: calc(100% + 4px); - left: 0; - min-width: 280px; - max-height: 400px; - overflow-y: auto; - background: var(--ctp-mantle); - border: 1px solid var(--ctp-surface1); - border-radius: 4px; - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); - z-index: 100; - padding: 4px 0; - } - - .theme-group-label { - padding: 6px 10px 2px; - font-size: 0.65rem; - font-weight: 700; color: var(--ctp-overlay0); - text-transform: uppercase; - letter-spacing: 0.05em; - } - - .theme-option { - display: flex; - align-items: center; - gap: 8px; - width: 100%; - padding: 5px 10px; - background: transparent; - border: none; - color: var(--ctp-subtext1); - font-size: 0.8rem; - cursor: pointer; - text-align: left; - } - - .theme-option:hover { - background: var(--ctp-surface0); - color: var(--ctp-text); - } - - .theme-option.active { - background: var(--ctp-surface0); - color: var(--ctp-text); - font-weight: 600; - } - - .theme-option-label { - flex: 1; - white-space: nowrap; - } - - .theme-colors { - display: flex; - gap: 3px; - flex-shrink: 0; - } - - .color-dot { - display: inline-block; - width: 8px; - height: 8px; - border-radius: 50%; + margin-right: 2px; } /* Groups & Projects */ diff --git a/v2/src/lib/stores/theme.svelte.ts b/v2/src/lib/stores/theme.svelte.ts index c6f603c..8c32966 100644 --- a/v2/src/lib/stores/theme.svelte.ts +++ b/v2/src/lib/stores/theme.svelte.ts @@ -81,16 +81,17 @@ export async function initTheme(): Promise { // Apply saved font settings try { - const [fontFamily, fontSize] = await Promise.all([ - getSetting('font_family'), - getSetting('font_size'), + const [uiFont, uiSize, termFont, termSize] = await Promise.all([ + getSetting('ui_font_family'), + getSetting('ui_font_size'), + getSetting('term_font_family'), + getSetting('term_font_size'), ]); - if (fontFamily) { - document.documentElement.style.setProperty('--ui-font-family', `'${fontFamily}', monospace`); - } - if (fontSize) { - document.documentElement.style.setProperty('--ui-font-size', `${fontSize}px`); - } + const root = document.documentElement.style; + if (uiFont) root.setProperty('--ui-font-family', `'${uiFont}', sans-serif`); + if (uiSize) root.setProperty('--ui-font-size', `${uiSize}px`); + if (termFont) root.setProperty('--term-font-family', `'${termFont}', monospace`); + if (termSize) root.setProperty('--term-font-size', `${termSize}px`); } catch { // Font settings are optional — defaults from catppuccin.css apply } diff --git a/v2/src/lib/styles/catppuccin.css b/v2/src/lib/styles/catppuccin.css index 0ae1903..d353a29 100644 --- a/v2/src/lib/styles/catppuccin.css +++ b/v2/src/lib/styles/catppuccin.css @@ -46,6 +46,8 @@ /* Typography */ --ui-font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace; --ui-font-size: 13px; + --term-font-family: 'JetBrains Mono', 'Fira Code', 'Cascadia Code', monospace; + --term-font-size: 13px; /* Layout */ --sidebar-width: 260px;