diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx index 931a5dc10..8034c9d45 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/general.tsx @@ -9,6 +9,7 @@ import { type RadioItem, RowInput, Scrollable, + Slider, Switch, useConfirmModal, } from '@affine/component'; @@ -308,6 +309,46 @@ const CustomFontFamilySettings = () => { ); }; +const FontSizeSettings = () => { + const t = useI18n(); + const { editorSettingService } = useServices({ EditorSettingService }); + const settings = useLiveData(editorSettingService.editorSetting.settings$); + + const onFontSizeChange = useCallback( + (fontSize: number[]) => { + const size = fontSize[0]; + editorSettingService.editorSetting.set('fontSize', size); + // Update CSS variable immediately + document.documentElement.style.setProperty('--affine-font-base', `${size}px`); + }, + [editorSettingService.editorSetting] + ); + + // Apply current font size to CSS variable on mount + useEffect(() => { + document.documentElement.style.setProperty('--affine-font-base', `${settings.fontSize}px`); + }, [settings.fontSize]); + + return ( + +
+ + {settings.fontSize}px +
+
+ ); +}; + const menuContentOptions: MenuProps['contentOptions'] = { align: 'end', sideOffset: 16, @@ -522,6 +563,7 @@ export const General = () => { + {BUILD_CONFIG.isElectron && } {environment.isLinux && } diff --git a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/style.css.ts b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/style.css.ts index e2b47528b..0b2fa552c 100644 --- a/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/style.css.ts +++ b/packages/frontend/core/src/desktop/dialogs/setting/general-setting/editor/style.css.ts @@ -163,3 +163,21 @@ export const spellCheckSettingDescriptionButton = style({ color: cssVarV2('text/link'), fontSize: 'inherit', }); + +export const fontSizeContainer = style({ + display: 'flex', + alignItems: 'center', + gap: '12px', + width: '250px', +}); + +export const fontSizeSlider = style({ + flex: 1, +}); + +export const fontSizeValue = style({ + fontSize: cssVar('fontSm'), + color: cssVarV2('text/secondary'), + minWidth: '40px', + textAlign: 'right', +}); diff --git a/packages/frontend/core/src/desktop/pages/root/custom-theme/index.tsx b/packages/frontend/core/src/desktop/pages/root/custom-theme/index.tsx index f3922872b..0551957c3 100644 --- a/packages/frontend/core/src/desktop/pages/root/custom-theme/index.tsx +++ b/packages/frontend/core/src/desktop/pages/root/custom-theme/index.tsx @@ -1,4 +1,5 @@ import { FeatureFlagService } from '@affine/core/modules/feature-flag'; +import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { ThemeEditorService } from '@affine/core/modules/theme-editor'; import { useLiveData, useServices } from '@toeverything/infra'; import { useTheme } from 'next-themes'; @@ -7,13 +8,15 @@ import { useEffect } from 'react'; let _provided = false; export const CustomThemeModifier = () => { - const { themeEditorService, featureFlagService } = useServices({ + const { themeEditorService, featureFlagService, editorSettingService } = useServices({ ThemeEditorService, FeatureFlagService, + EditorSettingService, }); const enableThemeEditor = useLiveData( featureFlagService.flags.enable_theme_editor.$ ); + const settings = useLiveData(editorSettingService.editorSetting.settings$); const { resolvedTheme } = useTheme(); useEffect(() => { @@ -45,5 +48,12 @@ export const CustomThemeModifier = () => { }; }, [resolvedTheme, enableThemeEditor, themeEditorService]); + // Apply font size CSS variable when settings change + useEffect(() => { + if (settings.fontSize) { + document.documentElement.style.setProperty('--affine-font-base', `${settings.fontSize}px`); + } + }, [settings.fontSize]); + return null; }; diff --git a/packages/frontend/core/src/modules/editor-setting/schema.ts b/packages/frontend/core/src/modules/editor-setting/schema.ts index 9a36d735a..b7ff0e65d 100644 --- a/packages/frontend/core/src/modules/editor-setting/schema.ts +++ b/packages/frontend/core/src/modules/editor-setting/schema.ts @@ -19,6 +19,7 @@ export const fontStyleOptions = [ const AffineEditorSettingSchema = z.object({ fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'), customFontFamily: z.string().default(''), + fontSize: z.number().min(12).max(24).default(16), newDocDefaultMode: z.enum(['edgeless', 'page', 'ask']).default('page'), fullWidthLayout: z.boolean().default(false), displayDocInfo: z.boolean().default(true), diff --git a/packages/frontend/i18n/src/i18n-completenesses.json b/packages/frontend/i18n/src/i18n-completenesses.json index 136ce7f59..d7d63f8c9 100644 --- a/packages/frontend/i18n/src/i18n-completenesses.json +++ b/packages/frontend/i18n/src/i18n-completenesses.json @@ -21,6 +21,6 @@ "sv-SE": 99, "uk": 99, "ur": 2, - "zh-Hans": 99, + "zh-Hans": 100, "zh-Hant": 99 } diff --git a/packages/frontend/i18n/src/i18n.gen.ts b/packages/frontend/i18n/src/i18n.gen.ts index 7d24bf615..a08c534eb 100644 --- a/packages/frontend/i18n/src/i18n.gen.ts +++ b/packages/frontend/i18n/src/i18n.gen.ts @@ -5387,6 +5387,14 @@ export function useAFFiNEI18N(): { * `Font family` */ ["com.affine.settings.editorSettings.general.font-family.title"](): string; + /** + * `Adjust the base font size for better readability.` + */ + ["com.affine.settings.editorSettings.general.font-size.description"](): string; + /** + * `Font size` + */ + ["com.affine.settings.editorSettings.general.font-size.title"](): string; /** * `Automatically detect and correct spelling errors.` */ diff --git a/packages/frontend/i18n/src/resources/en.json b/packages/frontend/i18n/src/resources/en.json index 8c7dec9ee..e76f64e7a 100644 --- a/packages/frontend/i18n/src/resources/en.json +++ b/packages/frontend/i18n/src/resources/en.json @@ -1342,6 +1342,8 @@ "com.affine.settings.editorSettings.general.font-family.custom.title": "Custom font family", "com.affine.settings.editorSettings.general.font-family.description": "Choose your editor's font family.", "com.affine.settings.editorSettings.general.font-family.title": "Font family", + "com.affine.settings.editorSettings.general.font-size.description": "Adjust the base font size for better readability.", + "com.affine.settings.editorSettings.general.font-size.title": "Font size", "com.affine.settings.editorSettings.general.spell-check.description": "Automatically detect and correct spelling errors.", "com.affine.settings.editorSettings.general.spell-check.title": "Spell check", "com.affine.settings.editorSettings.general.spell-check.restart-hint": "Settings changed; please restart the app. <1>Restart",