diff --git a/src/widgets/ComparisonView/ui/FontList/FontList.svelte b/src/widgets/ComparisonView/ui/FontList/FontList.svelte index e8ae2b9..5b4b455 100644 --- a/src/widgets/ComparisonView/ui/FontList/FontList.svelte +++ b/src/widgets/ComparisonView/ui/FontList/FontList.svelte @@ -9,6 +9,7 @@ import { FontVirtualList, type UnifiedFont, VIRTUAL_INDEX_NOT_LOADED, + appliedFontsManager, fontStore, } from '$entities/Font'; import { getSkeletonWidth } from '$shared/lib/utils'; @@ -18,6 +19,7 @@ import { Skeleton, } from '$shared/ui'; import DotIcon from '@lucide/svelte/icons/dot'; +import { fade } from 'svelte/transition'; import { createDotCrossfade, getDotTransitionParams, @@ -71,6 +73,21 @@ function handleSelect(font: UnifiedFont) { comparisonStore.fontB = font; } } + +/** + * Returns true once the font file is loaded (or errored) and safe to render. + * Called inside the template — Svelte 5 tracks the $state reads inside + * appliedFontsManager.getFontStatus(), so each row re-renders reactively + * when its file arrives. + */ +function isFontReady(font: UnifiedFont): boolean { + const status = appliedFontsManager.getFontStatus( + font.id, + DEFAULT_FONT_WEIGHT, + font.features?.isVariable, + ); + return status === 'loaded' || status === 'error'; +}
@@ -83,77 +100,93 @@ function handleSelect(font: UnifiedFont) { {#snippet skeleton()} - {#each { length: 12 } as _, i (i)} -
-
- +
+ {#each { length: 50 } as _, index (index)} +
+
+ +
+
- -
- {/each} + {/each} +
{/snippet} {#snippet children({ item: font, index })} - {@const isSelectedA = font.id === comparisonStore.fontA?.id} - {@const isSelectedB = font.id === comparisonStore.fontB?.id} - {@const active = (side === 'A' && isSelectedA) || (side === 'B' && isSelectedB)} +
+ {#if !isFontReady(font)} +
+ + +
+ {:else} + {@const isSelectedA = font.id === comparisonStore.fontA?.id} + {@const isSelectedB = font.id === comparisonStore.fontB?.id} + {@const active = (side === 'A' && isSelectedA) || (side === 'B' && isSelectedB)} - + {#snippet icon()} + {#if active} +
+ +
+ {:else if isSelectedA || isSelectedB} + {@const isA = isSelectedA} +
+ +
+ {/if} + {/snippet} + +
+ {/if} +
{/snippet}