mirror of
https://github.com/CompassConnections/Compass.git
synced 2026-02-19 15:27:16 -05:00
Add font preference selector in settings (#28)
* Add font preference selector in settings
* Consolidate font family config into shared global constant
* Revert "Consolidate font family config into shared global constant"
This reverts commit 789ddc98e1.
* Fix
This commit is contained in:
34
web/components/font-picker.tsx
Normal file
34
web/components/font-picker.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
'use client'
|
||||
|
||||
import clsx from 'clsx'
|
||||
import {FontOption, useFontPreference} from 'web/hooks/use-font-preference'
|
||||
import {useT} from 'web/lib/locale'
|
||||
|
||||
const FONT_OPTIONS: FontOption[] = ['atkinson', 'system-sans', 'classic-serif']
|
||||
|
||||
const EN_TRANSLATIONS = {
|
||||
"atkinson": "Atkinson Hyperlegible",
|
||||
"system-sans": "Sytem Sans-serif",
|
||||
"classic-serif": "Classic Serif"
|
||||
}
|
||||
|
||||
export function FontPicker(props: { className?: string } = {}) {
|
||||
const {className} = props
|
||||
const {font, setFont} = useFontPreference()
|
||||
const t = useT()
|
||||
|
||||
return (
|
||||
<select
|
||||
id="font-picker"
|
||||
value={font}
|
||||
onChange={(e) => setFont(e.target.value as FontOption)}
|
||||
className={clsx('rounded-md border border-gray-300 px-2 py-1 text-sm bg-canvas-50', className)}
|
||||
>
|
||||
{FONT_OPTIONS.map((option) => (
|
||||
<option key={option} value={option}>
|
||||
{t(`font.${option}`, EN_TRANSLATIONS[option] ?? option)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
)
|
||||
}
|
||||
37
web/hooks/use-font-preference.ts
Normal file
37
web/hooks/use-font-preference.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {useEffect} from 'react'
|
||||
import {usePersistentLocalState} from 'web/hooks/use-persistent-local-state'
|
||||
|
||||
export type FontOption = 'atkinson' | 'system-sans' | 'classic-serif'
|
||||
|
||||
const FONT_VARIABLES: Record<FontOption, string> = {
|
||||
atkinson: '"Atkinson Hyperlegible Next", Georgia, "Times New Roman", Times, serif',
|
||||
'system-sans': '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif',
|
||||
'classic-serif': 'Georgia, "Times New Roman", Times, serif',
|
||||
}
|
||||
|
||||
export const useFontPreference = () => {
|
||||
const [font, setFontState] = usePersistentLocalState<FontOption>('atkinson', 'font-preference')
|
||||
|
||||
const setFont = (newFont: FontOption) => {
|
||||
setFontState(newFont)
|
||||
applyFontPreference(newFont)
|
||||
}
|
||||
|
||||
return {font, setFont}
|
||||
}
|
||||
|
||||
export const useFontPreferenceManager = () => {
|
||||
useEffect(() => {
|
||||
applyFontPreference(getStoredFontPreference())
|
||||
}, [])
|
||||
}
|
||||
|
||||
export const applyFontPreference = (font: FontOption) => {
|
||||
const fontFamily = FONT_VARIABLES[font] ?? FONT_VARIABLES.atkinson
|
||||
document.documentElement.style.setProperty('--font-main', fontFamily)
|
||||
}
|
||||
|
||||
const getStoredFontPreference = (): FontOption => {
|
||||
if (typeof window === 'undefined') return 'atkinson'
|
||||
return JSON.parse(localStorage.getItem('font-preference') ?? 'null') ?? 'atkinson'
|
||||
}
|
||||
@@ -1042,5 +1042,9 @@
|
||||
"more_options_user.edit_profile": "Profil bearbeiten",
|
||||
"more_options_user.profile_options": "Profiloptionen",
|
||||
"more_options_user.edit_bio": "Bio bearbeiten",
|
||||
"vote.with_priority": "mit Priorität"
|
||||
}
|
||||
"vote.with_priority": "mit Priorität",
|
||||
"settings.general.font": "Schriftart",
|
||||
"font.atkinson": "Atkinson Hyperlegible",
|
||||
"font.system-sans": "System Sans",
|
||||
"font.classic-serif": "Klassische Serifenschrift"
|
||||
}
|
||||
|
||||
@@ -1042,5 +1042,9 @@
|
||||
"more_options_user.edit_profile": "Modifier le profil",
|
||||
"more_options_user.profile_options": "Options du profil",
|
||||
"more_options_user.edit_bio": "Options de biographie",
|
||||
"vote.with_priority": "avec priorité"
|
||||
}
|
||||
"vote.with_priority": "avec priorité",
|
||||
"settings.general.font": "Police",
|
||||
"font.atkinson": "Atkinson Hyperlegible",
|
||||
"font.system-sans": "Sans-serif système",
|
||||
"font.classic-serif": "Serif classique"
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {getLocale, resetCachedLocale} from "web/lib/locale-cookie"
|
||||
import {I18nContext} from "web/lib/locale"
|
||||
import {HiddenProfilesProvider} from 'web/hooks/use-hidden-profiles'
|
||||
import {updateStatusBar} from "web/hooks/use-theme"
|
||||
import {useFontPreferenceManager} from "web/hooks/use-font-preference"
|
||||
import {DAYJS_LOCALE_IMPORTS} from "web/lib/dayjs";
|
||||
import 'web/lib/dayjs'
|
||||
|
||||
@@ -94,6 +95,7 @@ function MyApp(props: AppProps<PageProps>) {
|
||||
const {Component, pageProps} = props
|
||||
useEffect(printBuildInfo, [])
|
||||
useHasLoaded()
|
||||
useFontPreferenceManager()
|
||||
const router = useRouter()
|
||||
|
||||
const [locale, setLocaleState] = useState(getLocale())
|
||||
|
||||
@@ -19,6 +19,7 @@ import {WithPrivateUser} from "web/components/user/with-user";
|
||||
import {sendPasswordReset} from "web/lib/firebase/password";
|
||||
import {AboutSettings} from "web/components/about-settings";
|
||||
import {LanguagePicker} from "web/components/language/language-picker";
|
||||
import {FontPicker} from 'web/components/font-picker'
|
||||
import {useT} from "web/lib/locale";
|
||||
import HiddenProfilesModal from 'web/components/settings/hidden-profiles-modal'
|
||||
import {EmailVerificationButton} from "web/components/email-verification-button";
|
||||
@@ -119,6 +120,9 @@ const LoadedGeneralSettings = (props: {
|
||||
<h3>{t('settings.general.language', 'Language')}</h3>
|
||||
<LanguagePicker className={'w-fit min-w-[120px]'}/>
|
||||
|
||||
<h3>{t('settings.general.font', 'Font')}</h3>
|
||||
<FontPicker className={'w-fit min-w-[180px]'}/>
|
||||
|
||||
<h3>{t('settings.data_privacy.title', 'Data & Privacy')}</h3>
|
||||
<DataPrivacySettings/>
|
||||
|
||||
|
||||
@@ -6,4 +6,16 @@
|
||||
if (theme === 'dark' || (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
document.documentElement.classList.add('dark')
|
||||
}
|
||||
|
||||
const localFontPreference = localStorage.getItem('font-preference')
|
||||
const fontPreference = localFontPreference ? JSON.parse(localFontPreference) : 'atkinson'
|
||||
|
||||
const fontFamilies = {
|
||||
atkinson: '"Atkinson Hyperlegible Next", Georgia, "Times New Roman", Times, serif',
|
||||
'system-sans': '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, sans-serif',
|
||||
'classic-serif': 'Georgia, "Times New Roman", Times, serif',
|
||||
}
|
||||
|
||||
document.documentElement.style.setProperty('--font-main', fontFamilies[fontPreference] ?? fontFamilies.atkinson)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user