diff --git a/frontend/src/App.tool-center.test.ts b/frontend/src/App.tool-center.test.ts index 219f6e05..88748d89 100644 --- a/frontend/src/App.tool-center.test.ts +++ b/frontend/src/App.tool-center.test.ts @@ -10,6 +10,10 @@ const appCss = readFileSync( fileURLToPath(new globalThis.URL('./App.css', import.meta.url)), 'utf8', ); +const v2ThemeCss = readFileSync( + fileURLToPath(new globalThis.URL('./v2-theme.css', import.meta.url)), + 'utf8', +); const linuxCJKFontBannerSource = readFileSync( fileURLToPath(new globalThis.URL('./components/LinuxCJKFontBanner.tsx', import.meta.url)), 'utf8', @@ -321,7 +325,7 @@ describe('tool center menu entries', () => { ['newConnection', 'handleCreateConnection();'], ['toggleAIPanel', 'toggleAIPanel();'], ['toggleLogPanel', 'handleToggleLogPanel();'], - ['toggleTheme', 'setTheme('], + ['toggleTheme', 'setThemePreference('], ['openShortcutManager', 'setIsShortcutModalOpen(true);'], ['toggleMacFullscreen', 'handleTitleBarWindowToggle({ allowMacNativeFullscreen: true });'], ['resetWindowZoom', 'handleManualResetWindowZoom();'], @@ -410,12 +414,20 @@ describe('global appearance tokens', () => { expect(appSource).toContain("setProperty('--gn-font-size-mono'"); expect(appSource).toContain("setProperty('--gn-data-table-font-size'"); expect(appSource).toContain("setProperty('--gn-sidebar-tree-font-size'"); + expect(appSource).toContain("setProperty('--gn-sidebar-rail-scale'"); expect(appSource).toContain("setProperty('--gn-control-height'"); expect(appSource).toContain("setProperty('--gn-control-height-sm'"); expect(appSource).toContain('fontFamily: resolvedUiFontFamily'); expect(appSource).toContain('fontFamilyCode: resolvedMonoFontFamily'); + expect(appSource).toContain('const effectiveSidebarRailScale = sanitizeV2SidebarRailScale(appearance.v2SidebarRailScale);'); + expect(appSource).toContain("t('app.theme.appearance.sidebar_rail_scale_title')"); + expect(appSource).toContain("t('app.theme.appearance.sidebar_rail_scale_hint')"); + expect(appSource).toContain('v2SidebarRailScale: sanitizeV2SidebarRailScale(value)'); expect(appSource).toContain("t('app.theme.data_table.font_size')"); expect(appSource).toContain("t('app.theme.data_table.sidebar_tree_font_size')"); + expect(v2ThemeCss).toContain('--gn-sidebar-rail-scale'); + expect(v2ThemeCss).toContain('font-size: calc(var(--gn-font-size-sm, 12px) * var(--gn-sidebar-rail-scale, 1));'); + expect(v2ThemeCss).toContain('width: calc(38px * var(--gn-v2-rail-scale));'); expect(appSource).toContain("const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data';"); expect(appSource).toContain("t('app.theme.data_table.table_double_click_action')"); expect(appSource).toContain("t('app.theme.data_table.table_double_click_action.open_data')"); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 7912d1bb..073f7851 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -21,7 +21,13 @@ import SecurityUpdateIntroModal from './components/SecurityUpdateIntroModal'; import SecurityUpdateProgressModal from './components/SecurityUpdateProgressModal'; import SecurityUpdateSettingsModal from './components/SecurityUpdateSettingsModal'; import LanguageSettingsPanel from './components/LanguageSettingsPanel'; -import { DEFAULT_APPEARANCE, useStore } from './store'; +import { + DEFAULT_APPEARANCE, + MAX_V2_SIDEBAR_RAIL_SCALE, + MIN_V2_SIDEBAR_RAIL_SCALE, + sanitizeV2SidebarRailScale, + useStore, +} from './store'; import { SavedConnection, SecurityUpdateIssue, SecurityUpdateStatus } from './types'; import { blurToFilter, normalizeBlurForPlatform, normalizeOpacityForPlatform, isWindowsPlatform, resolveAppearanceValues } from './utils/appearance'; import { buildFontFamilyOptions, DEFAULT_MONO_FONT_FAMILY, DEFAULT_UI_FONT_FAMILY, getLinuxCJKFontInstallHint, matchFontFamilyOption, resolveMonoFontFamily, resolveUIFontFamily, sanitizeFontFamilyInput, type FontFamilyOption, type InstalledFontFamily } from './utils/fontFamilies'; @@ -271,6 +277,7 @@ function App() { const effectiveSidebarTreeFontSize = sidebarTreeFontSizeFollowsGlobal ? effectiveFontSize : (sanitizeSidebarTreeFontSize(appearance.sidebarTreeFontSize) ?? effectiveFontSize); + const effectiveSidebarRailScale = sanitizeV2SidebarRailScale(appearance.v2SidebarRailScale); const tableDoubleClickAction = appearance.tableDoubleClickAction === 'open-design' ? 'open-design' : 'open-data'; const tabDisplaySettings = useMemo( () => sanitizeTabDisplaySettings(appearance.tabDisplay), @@ -2727,6 +2734,7 @@ function App() { document.documentElement.style.setProperty('--gn-font-size-mono', `${Math.max(10, Math.round(effectiveDataTableFontSize * 0.92))}px`); document.documentElement.style.setProperty('--gn-data-table-font-size', `${effectiveDataTableFontSize}px`); document.documentElement.style.setProperty('--gn-sidebar-tree-font-size', `${effectiveSidebarTreeFontSize}px`); + document.documentElement.style.setProperty('--gn-sidebar-rail-scale', `${effectiveSidebarRailScale}`); document.documentElement.style.setProperty('--gn-control-height', `${tokenControlHeight}px`); document.documentElement.style.setProperty('--gn-control-height-sm', `${tokenControlHeightSM}px`); }, [ @@ -2737,6 +2745,7 @@ function App() { resolvedMonoFontFamily, resolvedUiFontFamily, runtimePlatform, + effectiveSidebarRailScale, effectiveSidebarTreeFontSize, effectiveUiScale, tokenControlHeight, @@ -4693,6 +4702,27 @@ function App() { {effectiveFontSize}px + {appearance.uiVersion === 'v2' && ( +
+
{t('app.theme.appearance.sidebar_rail_scale_title')}
+
+ setAppearance({ + v2SidebarRailScale: sanitizeV2SidebarRailScale(value), + })} + style={{ flex: 1 }} + /> + {Math.round(effectiveSidebarRailScale * 100)}% +
+
+ {t('app.theme.appearance.sidebar_rail_scale_hint')} +
+
+ )}
{t('app.theme.font_family.title')}
diff --git a/frontend/src/store.test.ts b/frontend/src/store.test.ts index ca2ac8c8..c36e1c94 100644 --- a/frontend/src/store.test.ts +++ b/frontend/src/store.test.ts @@ -73,6 +73,7 @@ describe('store appearance persistence', () => { expect(appearance.v2SidebarSearchMode).toBe('command'); expect(appearance.v2CommandSearchPersistentFilterEnabled).toBe(false); expect(appearance.v2SidebarPersistedFilter).toBe(''); + expect(appearance.v2SidebarRailScale).toBe(1); expect(appearance.showDataTableVerticalBorders).toBe(false); expect(appearance.dataTableDensity).toBe('comfortable'); expect(appearance.dataTableFontSize).toBeNull(); @@ -95,12 +96,14 @@ describe('store appearance persistence', () => { showDataTableVerticalBorders: true, dataTableDensity: 'compact', tableDoubleClickAction: 'open-design', + v2SidebarRailScale: 1.55, }); const persisted = JSON.parse(storage.getItem('lite-db-storage') || '{}'); expect(persisted.state.appearance.showDataTableVerticalBorders).toBe(true); expect(persisted.state.appearance.dataTableDensity).toBe('compact'); expect(persisted.state.appearance.tableDoubleClickAction).toBe('open-design'); + expect(persisted.state.appearance.v2SidebarRailScale).toBe(1.55); vi.resetModules(); const reloaded = await importStore(); @@ -109,6 +112,7 @@ describe('store appearance persistence', () => { expect(appearance.showDataTableVerticalBorders).toBe(true); expect(appearance.dataTableDensity).toBe('compact'); expect(appearance.tableDoubleClickAction).toBe('open-design'); + expect(appearance.v2SidebarRailScale).toBe(1.55); }); it('restores query tabs from crash-recovery snapshots even when persisted tabs are missing', async () => { @@ -158,6 +162,20 @@ describe('store appearance persistence', () => { expect(useStore.getState().appearance.tableDoubleClickAction).toBe('open-data'); }); + it('sanitizes persisted v2 sidebar rail scale settings into the supported range', async () => { + storage.setItem('lite-db-storage', JSON.stringify({ + state: { + appearance: { + v2SidebarRailScale: 99, + }, + }, + version: 13, + })); + + const { useStore } = await importStore(); + expect(useStore.getState().appearance.v2SidebarRailScale).toBe(1); + }); + it('persists language preference and sanitizes unsupported persisted values', async () => { const { useStore } = await importStore(); diff --git a/frontend/src/store.ts b/frontend/src/store.ts index 59aa4f46..1f2244d6 100644 --- a/frontend/src/store.ts +++ b/frontend/src/store.ts @@ -102,12 +102,17 @@ export interface AppearanceSettings extends DataGridDisplaySettings { v2SidebarSearchMode: "command" | "filter"; v2CommandSearchPersistentFilterEnabled: boolean; v2SidebarPersistedFilter: string; + v2SidebarRailScale: number; customUIFontFamily: string | null; customMonoFontFamily: string | null; tabDisplay: TabDisplaySettings; redisDbAliases: RedisDbAliasMap; } +export const DEFAULT_V2_SIDEBAR_RAIL_SCALE = 1.0; +export const MIN_V2_SIDEBAR_RAIL_SCALE = 1.0; +export const MAX_V2_SIDEBAR_RAIL_SCALE = 1.8; + export const DEFAULT_APPEARANCE: AppearanceSettings = { uiVersion: "legacy", enabled: true, @@ -118,6 +123,7 @@ export const DEFAULT_APPEARANCE: AppearanceSettings = { v2SidebarSearchMode: "command", v2CommandSearchPersistentFilterEnabled: false, v2SidebarPersistedFilter: "", + v2SidebarRailScale: DEFAULT_V2_SIDEBAR_RAIL_SCALE, customUIFontFamily: null, customMonoFontFamily: null, tabDisplay: DEFAULT_TAB_DISPLAY_SETTINGS, @@ -153,6 +159,16 @@ const sanitizeV2SidebarPersistedFilter = (value: unknown): string => { } return value.trim().slice(0, MAX_SIDEBAR_PERSISTED_FILTER_LENGTH); }; + +export const sanitizeV2SidebarRailScale = (value: unknown): number => { + return normalizeFloatInRange( + value, + DEFAULT_V2_SIDEBAR_RAIL_SCALE, + MIN_V2_SIDEBAR_RAIL_SCALE, + MAX_V2_SIDEBAR_RAIL_SCALE, + ); +}; + const MAX_URI_LENGTH = 4096; const MAX_HOST_ENTRY_LENGTH = 512; const MAX_HOST_ENTRIES = 64; @@ -2193,6 +2209,9 @@ const sanitizeAppearance = ( v2SidebarPersistedFilter: sanitizeV2SidebarPersistedFilter( appearance.v2SidebarPersistedFilter, ), + v2SidebarRailScale: sanitizeV2SidebarRailScale( + appearance.v2SidebarRailScale, + ), customUIFontFamily: sanitizeFontFamilyInput(appearance.customUIFontFamily), customMonoFontFamily: sanitizeFontFamilyInput(appearance.customMonoFontFamily), tabDisplay: sanitizeTabDisplaySettings(appearance.tabDisplay), diff --git a/frontend/src/v2-theme.css b/frontend/src/v2-theme.css index c2f2705d..3775d9df 100644 --- a/frontend/src/v2-theme.css +++ b/frontend/src/v2-theme.css @@ -1762,6 +1762,7 @@ body[data-ui-version="v2"] .gn-v2-app-sider { } body[data-ui-version="v2"] .gn-v2-sidebar-redesign { + --gn-v2-rail-scale: calc(var(--gn-ui-scale, 1) * var(--gn-sidebar-rail-scale, 1)); width: 100%; background: var(--gn-bg-panel-2); border-right: 0.5px solid var(--gn-br-1); @@ -1769,14 +1770,14 @@ body[data-ui-version="v2"] .gn-v2-sidebar-redesign { } body[data-ui-version="v2"] .gn-v2-connection-rail { - width: calc(38px * var(--gn-ui-scale, 1)); - flex: 0 0 calc(38px * var(--gn-ui-scale, 1)); + width: calc(38px * var(--gn-v2-rail-scale)); + flex: 0 0 calc(38px * var(--gn-v2-rail-scale)); display: flex; flex-direction: column; align-items: center; justify-content: flex-start; - gap: calc(4px * var(--gn-ui-scale, 1)); - padding: calc(8px * var(--gn-ui-scale, 1)) 0; + gap: calc(4px * var(--gn-v2-rail-scale)); + padding: calc(8px * var(--gn-v2-rail-scale)) 0; border-right: 0.5px solid var(--gn-br-1); background: transparent; } @@ -1787,10 +1788,10 @@ body[data-ui-version="v2"] .gn-v2-rail-items { display: flex; flex-direction: column; align-items: center; - gap: calc(4px * var(--gn-ui-scale, 1)); + gap: calc(4px * var(--gn-v2-rail-scale)); width: 100%; box-sizing: border-box; - padding-top: calc(4px * var(--gn-ui-scale, 1)); + padding-top: calc(4px * var(--gn-v2-rail-scale)); overflow-x: hidden; overflow-y: auto; scrollbar-width: thin; @@ -1811,26 +1812,26 @@ body[data-ui-version="v2"] .gn-v2-rail-group { display: flex; flex-direction: column; align-items: center; - gap: calc(3px * var(--gn-ui-scale, 1)); + gap: calc(3px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-group + .gn-v2-rail-group { - padding-top: calc(5px * var(--gn-ui-scale, 1)); + padding-top: calc(5px * var(--gn-v2-rail-scale)); border-top: 0.5px solid var(--gn-br-1); } body[data-ui-version="v2"] .gn-v2-rail-group-header { position: relative; width: 100%; - min-height: calc(24px * var(--gn-ui-scale, 1)); + min-height: calc(24px * var(--gn-v2-rail-scale)); overflow: visible; border: none; border-radius: 0; display: flex; align-items: center; justify-content: flex-start; - gap: 4px; - padding: 0 4px 0 6px; + gap: calc(4px * var(--gn-v2-rail-scale)); + padding: 0 calc(4px * var(--gn-v2-rail-scale)) 0 calc(6px * var(--gn-v2-rail-scale)); background: transparent; color: var(--gn-fg-5); box-shadow: none; @@ -1845,7 +1846,7 @@ body[data-ui-version="v2"] .gn-v2-rail-group-chevron { position: static; display: inline-flex; color: var(--gn-fg-5); - font-size: 9px; + font-size: calc(9px * var(--gn-v2-rail-scale)); line-height: 1; transform: rotate(0deg); transition: transform 120ms ease; @@ -1870,18 +1871,18 @@ body[data-ui-version="v2"] .gn-v2-rail-group-count { position: absolute; top: -1px; right: -1px; - min-width: 16px; - height: 16px; + min-width: calc(16px * var(--gn-v2-rail-scale)); + height: calc(16px * var(--gn-v2-rail-scale)); border-radius: 999px; display: inline-flex; align-items: center; justify-content: center; - padding: 0 4px; + padding: 0 calc(4px * var(--gn-v2-rail-scale)); border: 2px solid var(--gn-bg-panel-2); background: var(--gn-accent); color: #fff; font-family: var(--gn-font-mono); - font-size: 9px; + font-size: calc(9px * var(--gn-v2-rail-scale)); font-weight: 800; line-height: 1; } @@ -1891,7 +1892,7 @@ body[data-ui-version="v2"] .gn-v2-rail-group-items { display: flex; flex-direction: column; align-items: center; - gap: calc(4px * var(--gn-ui-scale, 1)); + gap: calc(4px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-primary-actions, @@ -1900,16 +1901,16 @@ body[data-ui-version="v2"] .gn-v2-rail-secondary-actions { display: flex; flex-direction: column; align-items: center; - gap: calc(6px * var(--gn-ui-scale, 1)); + gap: calc(6px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-primary-actions { - padding-top: calc(4px * var(--gn-ui-scale, 1)); + padding-top: calc(4px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-secondary-actions { margin-top: auto; - padding-bottom: calc(4px * var(--gn-ui-scale, 1)); + padding-bottom: calc(4px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-action-group, @@ -1917,11 +1918,11 @@ body[data-ui-version="v2"] .gn-v2-rail-system-actions { display: flex; flex-direction: column; align-items: center; - gap: calc(4px * var(--gn-ui-scale, 1)); + gap: calc(4px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-action-group { - padding-bottom: calc(6px * var(--gn-ui-scale, 1)); + padding-bottom: calc(6px * var(--gn-v2-rail-scale)); border-bottom: 0.5px solid var(--gn-br-1); } @@ -1942,13 +1943,13 @@ body[data-ui-version="v2"] .gn-v2-rail-action:disabled { body[data-ui-version="v2"] .gn-v2-rail-item, body[data-ui-version="v2"] .gn-v2-rail-tool { position: relative; - width: calc(36px * var(--gn-ui-scale, 1)); - height: calc(38px * var(--gn-ui-scale, 1)); - border-radius: calc(9px * var(--gn-ui-scale, 1)); + width: calc(36px * var(--gn-v2-rail-scale)); + height: calc(38px * var(--gn-v2-rail-scale)); + border-radius: calc(9px * var(--gn-v2-rail-scale)); border: none; background: transparent; color: var(--gn-fg-4); - font-size: var(--gn-font-size-sm, 12px); + font-size: calc(var(--gn-font-size-sm, 12px) * var(--gn-sidebar-rail-scale, 1)); display: flex; align-items: center; justify-content: center; @@ -1957,9 +1958,9 @@ body[data-ui-version="v2"] .gn-v2-rail-tool { } body[data-ui-version="v2"] .gn-v2-rail-tool { - width: calc(24px * var(--gn-ui-scale, 1)); - height: calc(32px * var(--gn-ui-scale, 1)); - border-radius: calc(8px * var(--gn-ui-scale, 1)); + width: calc(24px * var(--gn-v2-rail-scale)); + height: calc(32px * var(--gn-v2-rail-scale)); + border-radius: calc(8px * var(--gn-v2-rail-scale)); justify-content: center; padding: 0; } @@ -1977,11 +1978,11 @@ body[data-ui-version="v2"] .gn-v2-rail-item.is-active { body[data-ui-version="v2"] .gn-v2-rail-active-bar { display: none; position: absolute; - left: -8px; - top: 7px; - bottom: 7px; - width: 3px; - border-radius: 3px; + left: calc(-8px * var(--gn-v2-rail-scale)); + top: calc(7px * var(--gn-v2-rail-scale)); + bottom: calc(7px * var(--gn-v2-rail-scale)); + width: calc(3px * var(--gn-v2-rail-scale)); + border-radius: calc(3px * var(--gn-v2-rail-scale)); background: var(--gn-accent); } @@ -1991,22 +1992,22 @@ body[data-ui-version="v2"] .gn-v2-rail-item.is-active .gn-v2-rail-active-bar { body[data-ui-version="v2"] .gn-v2-rail-icon { display: flex; - width: 24px; - height: 24px; + width: calc(24px * var(--gn-v2-rail-scale)); + height: calc(24px * var(--gn-v2-rail-scale)); align-items: center; justify-content: center; } body[data-ui-version="v2"] .gn-v2-rail-badge { - width: 22px; - height: 22px; - border-radius: 6px; + width: calc(22px * var(--gn-v2-rail-scale)); + height: calc(22px * var(--gn-v2-rail-scale)); + border-radius: calc(6px * var(--gn-v2-rail-scale)); display: inline-flex; align-items: center; justify-content: center; color: #fff; font-family: var(--gn-font-mono); - font-size: 9.5px; + font-size: calc(9.5px * var(--gn-sidebar-rail-scale, 1)); font-weight: 800; line-height: 1; box-shadow: inset 0 0.5px 0 rgba(255,255,255,0.3), 0 0.5px 1px rgba(0,0,0,0.2); @@ -2015,9 +2016,9 @@ body[data-ui-version="v2"] .gn-v2-rail-badge { body[data-ui-version="v2"] .gn-v2-rail-badge-wrap { position: relative; - width: 22px; - height: 22px; - flex: 0 0 22px; + width: calc(22px * var(--gn-v2-rail-scale)); + height: calc(22px * var(--gn-v2-rail-scale)); + flex: 0 0 calc(22px * var(--gn-v2-rail-scale)); } body[data-ui-version="v2"] .gn-v2-rail-fallback { @@ -2026,12 +2027,12 @@ body[data-ui-version="v2"] .gn-v2-rail-fallback { body[data-ui-version="v2"] .gn-v2-rail-status { position: absolute; - right: -2px; - bottom: -2px; - width: 8px; - height: 8px; + right: calc(-2px * var(--gn-v2-rail-scale)); + bottom: calc(-2px * var(--gn-v2-rail-scale)); + width: calc(8px * var(--gn-v2-rail-scale)); + height: calc(8px * var(--gn-v2-rail-scale)); border-radius: 50%; - border: 1.5px solid var(--gn-bg-panel); + border: calc(1.5px * var(--gn-sidebar-rail-scale, 1)) solid var(--gn-bg-panel); background: var(--gn-fg-5); } @@ -2044,16 +2045,16 @@ body[data-ui-version="v2"] .gn-v2-rail-status.is-error { } body[data-ui-version="v2"] .gn-v2-rail-create-button { - margin-top: 4px; - width: calc(40px * var(--gn-ui-scale, 1)); - height: calc(40px * var(--gn-ui-scale, 1)); + margin-top: calc(4px * var(--gn-v2-rail-scale)); + width: calc(40px * var(--gn-v2-rail-scale)); + height: calc(40px * var(--gn-v2-rail-scale)); border: 1px dashed var(--gn-br-2); - border-radius: calc(14px * var(--gn-ui-scale, 1)); + border-radius: calc(14px * var(--gn-v2-rail-scale)); display: flex; flex-direction: column; align-items: center; justify-content: center; - gap: 6px; + gap: calc(6px * var(--gn-v2-rail-scale)); padding: 0; color: var(--gn-fg-5); background: transparent; @@ -2064,9 +2065,9 @@ body[data-ui-version="v2"] .gn-v2-rail-create-button:hover { } body[data-ui-version="v2"] .gn-v2-rail-create-icon { - width: 24px; - height: 24px; - border-radius: 8px; + width: calc(24px * var(--gn-v2-rail-scale)); + height: calc(24px * var(--gn-v2-rail-scale)); + border-radius: calc(8px * var(--gn-v2-rail-scale)); display: inline-flex; align-items: center; justify-content: center; @@ -2077,13 +2078,13 @@ body[data-ui-version="v2"] .gn-v2-rail-create-icon { body[data-ui-version="v2"] .gn-v2-rail-create-label { color: var(--gn-fg-5); - font-size: 10px; + font-size: calc(10px * var(--gn-sidebar-rail-scale, 1)); line-height: 1; } body[data-ui-version="v2"] .gn-v2-object-explorer { min-width: 0; - flex: 1 1 calc(100% - 38px); + flex: 1 1 calc(100% - calc(38px * var(--gn-v2-rail-scale))); background: var(--gn-bg-panel-2); overflow: hidden; } diff --git a/shared/i18n/de-DE.json b/shared/i18n/de-DE.json index eca35794..c8ee3515 100644 --- a/shared/i18n/de-DE.json +++ b/shared/i18n/de-DE.json @@ -2678,6 +2678,8 @@ "app.theme.appearance.transparency_blur_title": "Transparenz- und Weichzeichnungseffekte", "app.theme.appearance.ui_scale_hint": "* Für kleine Bildschirme werden 85%-95% empfohlen", "app.theme.appearance.ui_scale_title": "UI-Skalierung (UI Scale)", + "app.theme.appearance.sidebar_rail_scale_hint": "Wirkt sich nur auf die linke V2-Navigationsleiste aus und vergrößert dort Buttons und Verbindungsicons für große Displays.", + "app.theme.appearance.sidebar_rail_scale_title": "Größe der linken Navigationsbuttons", "app.theme.appearance.windows_acrylic_hint": "Windows verwendet den systemeigenen Acrylic-Effekt. Die Unschärfestärke wird vom System gesteuert.", "app.theme.data_table.column_width_hint": "Der Standardmodus nutzt 200px, der kompakte Modus 140px als Standardspaltenbreite. Manuell angepasste Spaltenbreiten bleiben vorrangig erhalten.", "app.theme.data_table.column_width_mode": "Spaltenbreitenmodus der Datentabelle", diff --git a/shared/i18n/en-US.json b/shared/i18n/en-US.json index 78559f9f..3e074063 100644 --- a/shared/i18n/en-US.json +++ b/shared/i18n/en-US.json @@ -2678,6 +2678,8 @@ "app.theme.appearance.transparency_blur_title": "Transparency and Blur Effects", "app.theme.appearance.ui_scale_hint": "* Recommended for small screens: 85%-95%", "app.theme.appearance.ui_scale_title": "UI Scale (UI Scale)", + "app.theme.appearance.sidebar_rail_scale_hint": "Only affects the V2 left navigation rail. Use it to enlarge buttons and connection icons on large displays.", + "app.theme.appearance.sidebar_rail_scale_title": "Left Navigation Button Size", "app.theme.appearance.windows_acrylic_hint": "Windows uses the system Acrylic effect. Blur intensity is controlled by the system.", "app.theme.data_table.column_width_hint": "Standard mode defaults to 200px; compact mode defaults to 140px. Manually adjusted column widths are preserved first.", "app.theme.data_table.column_width_mode": "Data Table Column Width Mode", diff --git a/shared/i18n/ja-JP.json b/shared/i18n/ja-JP.json index 4defc880..11f0d328 100644 --- a/shared/i18n/ja-JP.json +++ b/shared/i18n/ja-JP.json @@ -2678,6 +2678,8 @@ "app.theme.appearance.transparency_blur_title": "透明度とぼかし効果", "app.theme.appearance.ui_scale_hint": "* 小さい画面では 85%-95% を推奨します", "app.theme.appearance.ui_scale_title": "UI スケール (UI Scale)", + "app.theme.appearance.sidebar_rail_scale_hint": "V2 左側ナビゲーションレールにのみ適用されます。大画面でボタンや接続アイコンを見やすく拡大できます。", + "app.theme.appearance.sidebar_rail_scale_title": "左側ナビゲーションボタンのサイズ", "app.theme.appearance.windows_acrylic_hint": "Windows ではシステムの Acrylic 効果を使用します。ぼかしの強さはシステムにより制御されます。", "app.theme.data_table.column_width_hint": "標準モードの既定列幅は 200px、コンパクトモードの既定列幅は 140px です。手動で調整した列幅は優先して保持されます。", "app.theme.data_table.column_width_mode": "データテーブル列幅モード", diff --git a/shared/i18n/ru-RU.json b/shared/i18n/ru-RU.json index 366713e0..9ed07a1b 100644 --- a/shared/i18n/ru-RU.json +++ b/shared/i18n/ru-RU.json @@ -2678,6 +2678,8 @@ "app.theme.appearance.transparency_blur_title": "Эффекты прозрачности и размытия", "app.theme.appearance.ui_scale_hint": "* Для небольших экранов рекомендуется 85%-95%", "app.theme.appearance.ui_scale_title": "Масштаб UI (UI Scale)", + "app.theme.appearance.sidebar_rail_scale_hint": "Влияет только на левую навигационную панель V2 и помогает увеличить кнопки и значки подключений на больших экранах.", + "app.theme.appearance.sidebar_rail_scale_title": "Размер кнопок левой навигации", "app.theme.appearance.windows_acrylic_hint": "Windows использует системный эффект Acrylic. Сила размытия управляется системой.", "app.theme.data_table.column_width_hint": "В стандартном режиме ширина столбца по умолчанию 200px; в компактном режиме 140px. Вручную измененные ширины столбцов сохраняются в приоритете.", "app.theme.data_table.column_width_mode": "Режим ширины столбцов таблицы данных", diff --git a/shared/i18n/zh-CN.json b/shared/i18n/zh-CN.json index 12bfed3c..6c933980 100644 --- a/shared/i18n/zh-CN.json +++ b/shared/i18n/zh-CN.json @@ -2678,6 +2678,8 @@ "app.theme.appearance.transparency_blur_title": "透明与模糊效果", "app.theme.appearance.ui_scale_hint": "* 建议小屏设备设置为 85%-95%", "app.theme.appearance.ui_scale_title": "界面缩放 (UI Scale)", + "app.theme.appearance.sidebar_rail_scale_hint": "仅影响 V2 左侧导航轨道,适合在大屏上放大按钮和连接图标。", + "app.theme.appearance.sidebar_rail_scale_title": "左侧导航按钮大小", "app.theme.appearance.windows_acrylic_hint": "Windows 使用系统 Acrylic 效果,模糊程度由系统控制", "app.theme.data_table.column_width_hint": "标准模式默认列宽 200px;紧凑模式默认列宽 140px。已手动拖拽调整的列宽优先保留。", "app.theme.data_table.column_width_mode": "数据表列宽模式", diff --git a/shared/i18n/zh-TW.json b/shared/i18n/zh-TW.json index 95691d19..1c418184 100644 --- a/shared/i18n/zh-TW.json +++ b/shared/i18n/zh-TW.json @@ -2678,6 +2678,8 @@ "app.theme.appearance.transparency_blur_title": "透明与模糊效果", "app.theme.appearance.ui_scale_hint": "* 建议小屏设备設定为 85%-95%", "app.theme.appearance.ui_scale_title": "界面缩放 (UI Scale)", + "app.theme.appearance.sidebar_rail_scale_hint": "僅影響 V2 左側導覽軌,適合在大螢幕上放大按鈕與連線圖示。", + "app.theme.appearance.sidebar_rail_scale_title": "左側導覽按鈕大小", "app.theme.appearance.windows_acrylic_hint": "Windows 使用系统 Acrylic 效果,模糊程度由系统控制", "app.theme.data_table.column_width_hint": "标准模式預設列宽 200px;紧凑模式預設列宽 140px。已手动拖拽调整的列宽优先保留。", "app.theme.data_table.column_width_mode": "資料表列宽模式",