refactor(font): replace fontCatalogStore singleton with lazy getFontCatalog
Swap the eagerly-constructed fontCatalogStore singleton for a lazy getFontCatalog() accessor (plus __resetFontCatalog for tests), so the InfiniteQueryObserver is created on first use rather than at module load. Update the model barrels and all consumers (FontVirtualList, SampleList, SampleListSection) to the accessor. Also extract createFontLoadRequestConfig from FontVirtualList: it resolves a font's URL for a weight and returns a 0-or-1 element array, letting callers flatMap over a list to build load requests and drop unresolvable fonts in one pass.
This commit is contained in:
@@ -10,8 +10,8 @@ import {
|
||||
createFontRowSizeResolver,
|
||||
} from '$entities/Font';
|
||||
import {
|
||||
fontCatalogStore,
|
||||
fontLifecycleManager,
|
||||
getFontCatalog,
|
||||
} from '$entities/Font/model';
|
||||
import {
|
||||
TypographyMenu,
|
||||
@@ -22,6 +22,8 @@ import { throttle } from '$shared/lib/utils';
|
||||
import { Skeleton } from '$shared/ui';
|
||||
import { layoutManager } from '../../model';
|
||||
|
||||
const fontCatalog = getFontCatalog();
|
||||
|
||||
// FontSampler chrome heights — derived from Tailwind classes in FontSampler.svelte.
|
||||
// Header: py-3 (12+12px padding) + ~32px content row ≈ 56px.
|
||||
// Only the header is counted; the mobile footer (md:hidden) is excluded because
|
||||
@@ -44,14 +46,16 @@ const SAMPLER_FALLBACK_HEIGHT = 220;
|
||||
*/
|
||||
const CHECK_POSITION_THROTTLE_MS = 100;
|
||||
|
||||
let text = $state('The quick brown fox jumps over the lazy dog...');
|
||||
const fonts = $derived(fontCatalog?.fonts);
|
||||
|
||||
let text = $state<string>('The quick brown fox jumps over the lazy dog...');
|
||||
let wrapper = $state<HTMLDivElement | null>(null);
|
||||
// Binds to the actual window height
|
||||
let innerHeight = $state(0);
|
||||
let innerHeight = $state<number>(0);
|
||||
// Is the component above the middle of the viewport?
|
||||
let isAboveMiddle = $state(false);
|
||||
let isAboveMiddle = $state<boolean>(false);
|
||||
// Inner width of the wrapper div — updated by bind:clientWidth on mount and resize.
|
||||
let containerWidth = $state(0);
|
||||
let containerWidth = $state<number>(0);
|
||||
|
||||
const checkPosition = throttle(() => {
|
||||
if (!wrapper) {
|
||||
@@ -69,7 +73,7 @@ const checkPosition = throttle(() => {
|
||||
// change triggers a full offsets recompute in createVirtualizer — no DOM snap.
|
||||
const fontRowHeight = $derived.by(() =>
|
||||
createFontRowSizeResolver({
|
||||
getFonts: () => fontCatalogStore.fonts,
|
||||
getFonts: () => fonts,
|
||||
getWeight: () => typographySettingsStore.weight,
|
||||
getPreviewText: () => text,
|
||||
getContainerWidth: () => containerWidth,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Wraps SampleList with a Section component
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { fontCatalogStore } from '$entities/Font/model';
|
||||
import { getFontCatalog } from '$entities/Font/model';
|
||||
import { NavigationWrapper } from '$features/Breadcrumb';
|
||||
import type { ResponsiveManager } from '$shared/lib';
|
||||
import { cn } from '$shared/lib';
|
||||
@@ -26,6 +26,9 @@ interface Props {
|
||||
const { index }: Props = $props();
|
||||
|
||||
const responsive = getContext<ResponsiveManager>('responsive');
|
||||
|
||||
const fontCatalog = getFontCatalog();
|
||||
const total = $derived<number>(fontCatalog?.pagination?.total);
|
||||
</script>
|
||||
|
||||
<NavigationWrapper index={2} title="Samples">
|
||||
@@ -36,7 +39,7 @@ const responsive = getContext<ResponsiveManager>('responsive');
|
||||
id="sample_set"
|
||||
title="Sample Set"
|
||||
headerTitle="visual_output"
|
||||
headerSubtitle="items_total: {fontCatalogStore.pagination.total ?? 0}"
|
||||
headerSubtitle="items_total: {total ?? 0}"
|
||||
headerAction={registerAction}
|
||||
>
|
||||
{#snippet headerContent()}
|
||||
|
||||
Reference in New Issue
Block a user