diff --git a/src/entities/Font/ui/FontVirtualList/FontVirtualList.svelte b/src/entities/Font/ui/FontVirtualList/FontVirtualList.svelte index 71c530f..b2728d1 100644 --- a/src/entities/Font/ui/FontVirtualList/FontVirtualList.svelte +++ b/src/entities/Font/ui/FontVirtualList/FontVirtualList.svelte @@ -18,8 +18,8 @@ import { type FontLoadRequestConfig, type UnifiedFont, appliedFontsManager, + fontStore, } from '../../model'; -import { fontStore } from '../../model/store'; interface Props extends Omit< @@ -53,30 +53,42 @@ const isLoading = $derived( fontStore.isFetching || fontStore.isLoading, ); -function handleInternalVisibleChange(visibleItems: UnifiedFont[]) { - const configs: FontLoadRequestConfig[] = []; - - visibleItems.forEach(item => { - const url = getFontUrl(item, weight); - - if (url) { - configs.push({ - id: item.id, - name: item.name, - weight, - url, - isVariable: item.features?.isVariable, - }); - } - }); - - // Auto-register fonts with the manager - appliedFontsManager.touch(configs); +let visibleFonts = $state([]); +function handleInternalVisibleChange(items: UnifiedFont[]) { + visibleFonts = items; // Forward the call to any external listener - // onVisibleItemsChange?.(visibleItems); + onVisibleItemsChange?.(items); } +// Re-touch whenever visible set or weight changes — fixes weight-change gap +$effect(() => { + const configs: FontLoadRequestConfig[] = visibleFonts.flatMap(item => { + const url = getFontUrl(item, weight); + if (!url) return []; + return [{ id: item.id, name: item.name, weight, url, isVariable: item.features?.isVariable }]; + }); + if (configs.length > 0) { + appliedFontsManager.touch(configs); + } +}); + +// Pin visible fonts so the eviction policy never removes on-screen entries. +// Cleanup captures the snapshot values, so a weight change unpins the old +// weight before pinning the new one. +$effect(() => { + const w = weight; + const fonts = visibleFonts; + for (const f of fonts) { + appliedFontsManager.pin(f.id, w, f.features?.isVariable); + } + return () => { + for (const f of fonts) { + appliedFontsManager.unpin(f.id, w, f.features?.isVariable); + } + }; +}); + /** * Load more fonts by moving to the next page */