fcd61be4fa
FontApplicator and FontSampler no longer read fontLifecycleManager. They take a `status` prop (FontLoadStatus | undefined) supplied by the composing widget; FontList and SampleList resolve status once per visible row and pass it down. FSD+ dependency inversion: the entity/feature UI depends on a value, not the lifecycle store. Removes FontApplicator's value-import of the store (one step toward an inert ./ui barrel) and drops the duplicate getFontStatus read per row in FontList. FontSampler is now status-decoupled and trivially relocatable to entities/Font/ui.
92 lines
3.0 KiB
Svelte
92 lines
3.0 KiB
Svelte
<script module>
|
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
import FontApplicator from './FontApplicator.svelte';
|
|
|
|
const { Story } = defineMeta({
|
|
title: 'Entities/FontApplicator',
|
|
component: FontApplicator,
|
|
tags: ['autodocs'],
|
|
parameters: {
|
|
docs: {
|
|
description: {
|
|
component:
|
|
'Applies a font to its children based on the supplied load `status`. Renders the skeleton (or system font) until status is `loaded`/`error`, then reveals the font. The status is provided by the composing widget — the component does not read the lifecycle store itself.',
|
|
},
|
|
story: { inline: false },
|
|
},
|
|
layout: 'centered',
|
|
},
|
|
argTypes: {
|
|
status: { control: 'select', options: ['loading', 'loaded', 'error'] },
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<script lang="ts">
|
|
import { mockUnifiedFont } from '$entities/Font/testing';
|
|
import type { ComponentProps } from 'svelte';
|
|
|
|
const fontUnknown = mockUnifiedFont({ id: 'nonexistent-font-xk92z', name: 'Nonexistent Font Xk92z' });
|
|
|
|
const fontArial = mockUnifiedFont({ id: 'arial', name: 'Arial' });
|
|
|
|
const fontArialBold = mockUnifiedFont({ id: 'arial-bold', name: 'Arial' });
|
|
</script>
|
|
|
|
<Story
|
|
name="Loading State"
|
|
parameters={{
|
|
docs: {
|
|
description: {
|
|
story:
|
|
'Status is `loading`: the font file has not resolved yet, so children render in the skeleton (or system font) fallback rather than the target font.',
|
|
},
|
|
},
|
|
}}
|
|
args={{ font: fontUnknown, status: 'loading' }}
|
|
>
|
|
{#snippet template(args: ComponentProps<typeof FontApplicator>)}
|
|
<FontApplicator {...args}>
|
|
<p class="text-xl">The quick brown fox jumps over the lazy dog</p>
|
|
</FontApplicator>
|
|
{/snippet}
|
|
</Story>
|
|
|
|
<Story
|
|
name="Loaded State"
|
|
parameters={{
|
|
docs: {
|
|
description: {
|
|
story:
|
|
'Status is `loaded`: the component reveals the font, applying it to its children (Arial here, available in all browsers).',
|
|
},
|
|
},
|
|
}}
|
|
args={{ font: fontArial, status: 'loaded' }}
|
|
>
|
|
{#snippet template(args: ComponentProps<typeof FontApplicator>)}
|
|
<FontApplicator {...args}>
|
|
<p class="text-xl">The quick brown fox jumps over the lazy dog</p>
|
|
</FontApplicator>
|
|
{/snippet}
|
|
</Story>
|
|
|
|
<Story
|
|
name="Error State"
|
|
parameters={{
|
|
docs: {
|
|
description: {
|
|
story:
|
|
'Status is `error`: the font failed to load. The component still reveals (it treats `error` like `loaded` for reveal purposes) so children are not stuck behind the skeleton — they fall back to the system font.',
|
|
},
|
|
},
|
|
}}
|
|
args={{ font: fontArialBold, status: 'error' }}
|
|
>
|
|
{#snippet template(args: ComponentProps<typeof FontApplicator>)}
|
|
<FontApplicator {...args}>
|
|
<p class="text-xl">The quick brown fox jumps over the lazy dog</p>
|
|
</FontApplicator>
|
|
{/snippet}
|
|
</Story>
|