fix(fonts): load Google font previews
This commit is contained in:
parent
59550c1c07
commit
83af1453d8
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix the web font picker so Google Fonts remain available in Safari, local font access is requested on first open when supported, font sources are labeled, and Google font previews load lazily for visible rows.
|
||||
|
||||
## 0.12.0 — 2026-05-18
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@ import { FontPickerRoot } from '@open-pencil/vue'
|
|||
|
||||
import { useSelectUI } from '@/components/ui/select'
|
||||
import { usePopoverUI } from '@/components/ui/popover'
|
||||
import { listFamilies, localFontAccessState, requestLocalFontAccess } from '@/app/editor/fonts'
|
||||
import {
|
||||
listFamilies,
|
||||
loadFont,
|
||||
localFontAccessState,
|
||||
requestLocalFontAccess
|
||||
} from '@/app/editor/fonts'
|
||||
|
||||
import type { FontPickerUi } from '@open-pencil/vue'
|
||||
|
||||
|
|
@ -29,10 +34,19 @@ const ui = computed<FontPickerUi>(() => ({
|
|||
emptyAction: 'mt-2 rounded bg-accent px-2 py-1 text-xs font-medium text-white disabled:opacity-50'
|
||||
}))
|
||||
|
||||
const previewFontLoads = new Set<string>()
|
||||
|
||||
const localFontAccess = {
|
||||
state: localFontAccessState,
|
||||
load: requestLocalFontAccess
|
||||
}
|
||||
|
||||
function loadPreviewFont(family: string, source: string) {
|
||||
if (source !== 'google') return
|
||||
if (previewFontLoads.has(family)) return
|
||||
previewFontLoads.add(family)
|
||||
void loadFont(family)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -53,7 +67,11 @@ const localFontAccess = {
|
|||
</template>
|
||||
|
||||
<template #item="{ family, selected, source }">
|
||||
<div data-test-id="font-picker-item" class="flex min-w-0 flex-1 items-center gap-2">
|
||||
<div
|
||||
data-test-id="font-picker-item"
|
||||
class="flex min-w-0 flex-1 items-center gap-2"
|
||||
@vue:mounted="loadPreviewFont(family, source)"
|
||||
>
|
||||
<icon-lucide-check v-if="selected" class="size-3 shrink-0 text-accent" />
|
||||
<span v-else class="size-3 shrink-0" />
|
||||
<span class="truncate" :style="{ fontFamily: `'${family}', sans-serif` }">{{
|
||||
|
|
|
|||
|
|
@ -23,20 +23,31 @@ async function openFontPicker(page: Page) {
|
|||
|
||||
async function installGoogleFontsMock(page: Page, families = ['Inter', 'OpenPencil Google Font']) {
|
||||
await page.addInitScript((googleFamilies) => {
|
||||
const win = window as Window & { __googleFontsFetchCount?: number }
|
||||
const win = window as Window & {
|
||||
__googleFontsFetchCount?: number
|
||||
__googleFontPreviewFetchCount?: number
|
||||
}
|
||||
win.__googleFontsFetchCount = 0
|
||||
win.__googleFontPreviewFetchCount = 0
|
||||
const originalFetch = window.fetch.bind(window)
|
||||
window.fetch = async (input, init) => {
|
||||
let url: string
|
||||
if (typeof input === 'string') url = input
|
||||
else if (input instanceof URL) url = input.href
|
||||
else url = input.url
|
||||
if (url.startsWith('https://fonts.openpencil.test/')) {
|
||||
win.__googleFontPreviewFetchCount = (win.__googleFontPreviewFetchCount ?? 0) + 1
|
||||
return new Response(new ArrayBuffer(8), { status: 200 })
|
||||
}
|
||||
if (url.startsWith('https://www.googleapis.com/webfonts/v1/webfonts')) {
|
||||
if (!url.includes('family='))
|
||||
win.__googleFontsFetchCount = (win.__googleFontsFetchCount ?? 0) + 1
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
items: googleFamilies.map((family) => ({ family }))
|
||||
items: googleFamilies.map((family) => ({
|
||||
family,
|
||||
files: { regular: `https://fonts.openpencil.test/${encodeURIComponent(family)}.ttf` }
|
||||
}))
|
||||
}),
|
||||
{ status: 200, headers: { 'content-type': 'application/json' } }
|
||||
)
|
||||
|
|
@ -109,6 +120,15 @@ test('font picker lists Google fonts when local font API is unavailable', async
|
|||
await expect(
|
||||
page.getByTestId('font-picker-item').filter({ hasText: 'OpenPencil Google Font' })
|
||||
).toBeVisible()
|
||||
await expect
|
||||
.poll(() =>
|
||||
page.evaluate(
|
||||
() =>
|
||||
(window as Window & { __googleFontPreviewFetchCount?: number })
|
||||
.__googleFontPreviewFetchCount
|
||||
)
|
||||
)
|
||||
.toBeGreaterThan(0)
|
||||
await expect(page.getByText('Local fonts are not available in this browser.')).toHaveCount(0)
|
||||
})
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue