feat(editor): add font size adjustment in editor settings (#13549)

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
This commit is contained in:
Mau Nguyen
2025-11-15 07:57:17 -08:00
committed by GitHub
parent d90eeffe84
commit 71d682c1c0
7 changed files with 83 additions and 2 deletions
@@ -9,6 +9,7 @@ import {
type RadioItem, type RadioItem,
RowInput, RowInput,
Scrollable, Scrollable,
Slider,
Switch, Switch,
useConfirmModal, useConfirmModal,
} from '@affine/component'; } 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 (
<SettingRow
name={t['com.affine.settings.editorSettings.general.font-size.title']()}
desc={t['com.affine.settings.editorSettings.general.font-size.description']()}
>
<div className={styles.fontSizeContainer}>
<Slider
value={[settings.fontSize]}
onValueChange={onFontSizeChange}
min={12}
max={24}
step={1}
className={styles.fontSizeSlider}
/>
<span className={styles.fontSizeValue}>{settings.fontSize}px</span>
</div>
</SettingRow>
);
};
const menuContentOptions: MenuProps['contentOptions'] = { const menuContentOptions: MenuProps['contentOptions'] = {
align: 'end', align: 'end',
sideOffset: 16, sideOffset: 16,
@@ -522,6 +563,7 @@ export const General = () => {
<AISettings /> <AISettings />
<FontFamilySettings /> <FontFamilySettings />
<CustomFontFamilySettings /> <CustomFontFamilySettings />
<FontSizeSettings />
<NewDocDefaultModeSettings /> <NewDocDefaultModeSettings />
{BUILD_CONFIG.isElectron && <SpellCheckSettings />} {BUILD_CONFIG.isElectron && <SpellCheckSettings />}
{environment.isLinux && <MiddleClickPasteSettings />} {environment.isLinux && <MiddleClickPasteSettings />}
@@ -163,3 +163,21 @@ export const spellCheckSettingDescriptionButton = style({
color: cssVarV2('text/link'), color: cssVarV2('text/link'),
fontSize: 'inherit', 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',
});
@@ -1,4 +1,5 @@
import { FeatureFlagService } from '@affine/core/modules/feature-flag'; 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 { ThemeEditorService } from '@affine/core/modules/theme-editor';
import { useLiveData, useServices } from '@toeverything/infra'; import { useLiveData, useServices } from '@toeverything/infra';
import { useTheme } from 'next-themes'; import { useTheme } from 'next-themes';
@@ -7,13 +8,15 @@ import { useEffect } from 'react';
let _provided = false; let _provided = false;
export const CustomThemeModifier = () => { export const CustomThemeModifier = () => {
const { themeEditorService, featureFlagService } = useServices({ const { themeEditorService, featureFlagService, editorSettingService } = useServices({
ThemeEditorService, ThemeEditorService,
FeatureFlagService, FeatureFlagService,
EditorSettingService,
}); });
const enableThemeEditor = useLiveData( const enableThemeEditor = useLiveData(
featureFlagService.flags.enable_theme_editor.$ featureFlagService.flags.enable_theme_editor.$
); );
const settings = useLiveData(editorSettingService.editorSetting.settings$);
const { resolvedTheme } = useTheme(); const { resolvedTheme } = useTheme();
useEffect(() => { useEffect(() => {
@@ -45,5 +48,12 @@ export const CustomThemeModifier = () => {
}; };
}, [resolvedTheme, enableThemeEditor, themeEditorService]); }, [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; return null;
}; };
@@ -19,6 +19,7 @@ export const fontStyleOptions = [
const AffineEditorSettingSchema = z.object({ const AffineEditorSettingSchema = z.object({
fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'), fontFamily: z.enum(['Sans', 'Serif', 'Mono', 'Custom']).default('Sans'),
customFontFamily: z.string().default(''), customFontFamily: z.string().default(''),
fontSize: z.number().min(12).max(24).default(16),
newDocDefaultMode: z.enum(['edgeless', 'page', 'ask']).default('page'), newDocDefaultMode: z.enum(['edgeless', 'page', 'ask']).default('page'),
fullWidthLayout: z.boolean().default(false), fullWidthLayout: z.boolean().default(false),
displayDocInfo: z.boolean().default(true), displayDocInfo: z.boolean().default(true),
@@ -21,6 +21,6 @@
"sv-SE": 99, "sv-SE": 99,
"uk": 99, "uk": 99,
"ur": 2, "ur": 2,
"zh-Hans": 99, "zh-Hans": 100,
"zh-Hant": 99 "zh-Hant": 99
} }
+8
View File
@@ -5387,6 +5387,14 @@ export function useAFFiNEI18N(): {
* `Font family` * `Font family`
*/ */
["com.affine.settings.editorSettings.general.font-family.title"](): string; ["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.` * `Automatically detect and correct spelling errors.`
*/ */
@@ -1342,6 +1342,8 @@
"com.affine.settings.editorSettings.general.font-family.custom.title": "Custom font family", "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.description": "Choose your editor's font family.",
"com.affine.settings.editorSettings.general.font-family.title": "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.description": "Automatically detect and correct spelling errors.",
"com.affine.settings.editorSettings.general.spell-check.title": "Spell check", "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</1>", "com.affine.settings.editorSettings.general.spell-check.restart-hint": "Settings changed; please restart the app. <1>Restart</1>",