2026-04-17 18:01:24 +03:00
< 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 :
2026-05-24 20:00:43 +03:00
'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.' ,
2026-04-17 18:01:24 +03:00
},
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 :
2026-05-24 20:00:43 +03:00
'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.' ,
2026-04-17 18:01:24 +03:00
},
},
}}
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 :
2026-05-24 20:00:43 +03:00
'No `skeleton` snippet provided. When `fontCatalogStore.fonts` is empty the underlying VirtualList renders its empty state directly.' ,
2026-04-17 18:01:24 +03:00
},
},
}}
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 :
2026-05-24 20:00:43 +03:00
' 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 } `.',
2026-04-17 18:01:24 +03:00
},
},
}}
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 >