feat(font): 字体分为内置/链接两种来源,链接可存多套并启用

- 设置改为 font.source(builtin|custom) + current + items[]
- 每条链接含 key/name/url/family;后台可加、改、删,选一条启用
- 前端按启用的那条注入 @font-face / CSS 链接,删除当前项时退回第一条
- 校验:条数上限 20、key 唯一、url 仅 http(s):// 或 /fonts/
This commit is contained in:
2026-11-05 18:54:58 +08:00
parent 0bb4cc354a
commit 97b9d00cf3
7 changed files with 232 additions and 67 deletions
+10 -6
View File
@@ -333,7 +333,7 @@ export default function AppNext() {
show_nav: true,
},
background: cachedBackground ?? { light: '', dark: '' },
font: { url: '', family: '' },
font: { source: 'builtin', current: '', items: [] },
search: {
default: 'internal',
engines: DEFAULT_SEARCH_ENGINES.map((engine) => ({ ...engine })),
@@ -409,15 +409,19 @@ export default function AppNext() {
}
}, [scheme])
// 正文字体:空链接用内置文楷;否则注入 @font-face(字体文件)或 CSS 链接,并覆盖字体令牌
// 正文字体:内置文楷,或启用「字体链接」里存好的某一条。
// 自定义时注入 @font-face(字体文件)或 CSS 链接,并覆盖字体令牌。
useEffect(() => {
const url = site.font.url.trim()
const family = site.font.family.trim()
const root = document.documentElement
document.getElementById('stash-font-link')?.remove()
document.getElementById('stash-font-face')?.remove()
// current 指向的条目被删掉时退回第一条
const active =
site.font.items.find((item) => item.key === site.font.current) ?? site.font.items[0]
const url = site.font.source === 'custom' && active !== undefined ? active.url.trim() : ''
const family = active?.family.trim() ?? ''
if (url === '') {
root.style.removeProperty('--su-font-sans')
return
@@ -442,7 +446,7 @@ export default function AppNext() {
'--su-font-sans',
`${JSON.stringify(familyName)}, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Hiragino Sans GB', 'Microsoft YaHei', 'Source Han Sans CN', sans-serif`,
)
}, [site.font.url, site.font.family])
}, [site.font])
/** 页头的明暗切换:只写本机偏好,不需要登录;站点默认值在后台改 */
const toggleTheme = () => {