Files
frontend-svelte/src/entities/Font/ui/FontVirtualList/FontVirtualList.stories.svelte
T
Ilia Mashkov 728380498b refactor(Font): rename fontStore and appliedFontsManager
Both names were vague or overloaded:

- fontStore / FontStore -> fontCatalogStore / FontCatalogStore
  Three font-related stores live in this slice; the new name names the
  paginated catalog specifically.

- appliedFontsManager / AppliedFontsManager -> fontLifecycleManager /
  FontLifecycleManager
  "Applied" collided with the filter-side appliedFilterStore (different
  meaning). The class actually orchestrates a load-use-evict lifecycle
  with FontBufferCache + FontEvictionPolicy + FontLoadQueue
  collaborators, so "Manager" is justified. Companion types file moved
  alongside (appliedFonts.ts -> fontLifecycle.ts).

Directories, file basenames, factory (createFontStore ->
createFontCatalogStore), and the AppliedFontsManagerDeps interface all
renamed. All consumers (ComparisonView, SampleList, FontList,
FontApplicator, FontVirtualList, FilterAndSortFonts bindings,
createFontRowSizeResolver, mocks) updated.
2026-05-24 20:00:43 +03:00

115 lines
4.2 KiB
Svelte

<script module>
import { defineMeta } from '@storybook/addon-svelte-csf';
import FontVirtualList from './FontVirtualList.svelte';
const { Story } = defineMeta({
title: 'Entities/FontVirtualList',
component: FontVirtualList,
tags: ['autodocs'],
parameters: {
docs: {
description: {
component:
'Virtualized font list backed by the `fontCatalogStore` singleton. Handles font loading registration (pin/touch) for visible items and triggers infinite scroll pagination via `fontCatalogStore.nextPage()`. Because the component reads directly from the `fontCatalogStore` singleton, stories render against a live (but empty/loading) store — no font data will appear unless the API is reachable from the Storybook host.',
},
story: { inline: false },
},
layout: 'padded',
},
argTypes: {
weight: { control: 'number', description: 'Font weight applied to visible fonts' },
itemHeight: { control: 'number', description: 'Height of each list item in pixels' },
},
});
</script>
<script lang="ts">
import type { ComponentProps } from 'svelte';
</script>
<Story
name="Loading Skeleton"
parameters={{
docs: {
description: {
story:
'Skeleton state shown while `fontCatalogStore.fonts` is empty and `fontCatalogStore.isLoading` is true. In a real session the skeleton fades out once the first page loads.',
},
},
}}
args={{ weight: 400, itemHeight: 72 }}
>
{#snippet template(args: ComponentProps<typeof FontVirtualList>)}
<div class="h-[400px] w-full">
<FontVirtualList {...args}>
{#snippet skeleton()}
<div class="flex flex-col gap-2 p-4">
{#each Array(6) as _}
<div class="h-16 animate-pulse rounded bg-neutral-200"></div>
{/each}
</div>
{/snippet}
{#snippet children({ item })}
<div class="border-b border-neutral-100 p-3">{item.name}</div>
{/snippet}
</FontVirtualList>
</div>
{/snippet}
</Story>
<Story
name="Empty State"
parameters={{
docs: {
description: {
story:
'No `skeleton` snippet provided. When `fontCatalogStore.fonts` is empty the underlying VirtualList renders its empty state directly.',
},
},
}}
args={{ weight: 400, itemHeight: 72 }}
>
{#snippet template(args: ComponentProps<typeof FontVirtualList>)}
<div class="h-[400px] w-full">
<FontVirtualList {...args}>
{#snippet children({ item })}
<div class="border-b border-neutral-100 p-3">{item.name}</div>
{/snippet}
</FontVirtualList>
</div>
{/snippet}
</Story>
<Story
name="With Item Renderer"
parameters={{
docs: {
description: {
story:
'Demonstrates how to configure a `children` snippet for item rendering. The list will be empty because `fontCatalogStore` is not populated in Storybook, but the template shows the expected slot shape: `{ item: UnifiedFont }`.',
},
},
}}
args={{ weight: 400, itemHeight: 80 }}
>
{#snippet template(args: ComponentProps<typeof FontVirtualList>)}
<div class="h-[400px] w-full">
<FontVirtualList {...args}>
{#snippet skeleton()}
<div class="flex flex-col gap-2 p-4">
{#each Array(6) as _}
<div class="h-16 animate-pulse rounded bg-neutral-200"></div>
{/each}
</div>
{/snippet}
{#snippet children({ item })}
<div class="flex items-center justify-between border-b border-neutral-100 px-4 py-3">
<span class="text-sm font-medium">{item.name}</span>
<span class="text-xs text-neutral-400">{item.category}</span>
</div>
{/snippet}
</FontVirtualList>
</div>
{/snippet}
</Story>