feat: storybook cases and mocks
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
<script module>
|
||||
import Providers from '$shared/lib/storybook/Providers.svelte';
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import ComparisonSlider from './ComparisonSlider.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Widgets/ComparisonSlider',
|
||||
component: ComparisonSlider,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
'A multiline text comparison slider that morphs between two fonts. Features character-level morphing, responsive layout, and performance optimization using offscreen canvas. Switch between slider mode (interactive text) and settings mode (controls panel).',
|
||||
},
|
||||
story: { inline: false },
|
||||
},
|
||||
layout: 'fullscreen',
|
||||
},
|
||||
argTypes: {
|
||||
// This component uses internal stores, so no direct props to document
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import type { UnifiedFont } from '$entities/Font';
|
||||
import { comparisonStore } from '$widgets/ComparisonSlider/model';
|
||||
|
||||
// Mock fonts for testing - using web-safe fonts that are always available
|
||||
const mockArial: UnifiedFont = {
|
||||
id: 'arial',
|
||||
name: 'Arial',
|
||||
provider: 'google',
|
||||
category: 'sans-serif',
|
||||
subsets: ['latin'],
|
||||
variants: ['400', '700'],
|
||||
styles: {
|
||||
regular: '',
|
||||
bold: '',
|
||||
},
|
||||
metadata: {
|
||||
cachedAt: Date.now(),
|
||||
version: '1.0',
|
||||
popularity: 1,
|
||||
},
|
||||
features: {
|
||||
isVariable: false,
|
||||
},
|
||||
};
|
||||
|
||||
const mockGeorgia: UnifiedFont = {
|
||||
id: 'georgia',
|
||||
name: 'Georgia',
|
||||
provider: 'google',
|
||||
category: 'serif',
|
||||
subsets: ['latin'],
|
||||
variants: ['400', '700'],
|
||||
styles: {
|
||||
regular: '',
|
||||
bold: '',
|
||||
},
|
||||
metadata: {
|
||||
cachedAt: Date.now(),
|
||||
version: '1.0',
|
||||
popularity: 2,
|
||||
},
|
||||
features: {
|
||||
isVariable: false,
|
||||
},
|
||||
};
|
||||
|
||||
const mockVerdana: UnifiedFont = {
|
||||
id: 'verdana',
|
||||
name: 'Verdana',
|
||||
provider: 'google',
|
||||
category: 'sans-serif',
|
||||
subsets: ['latin'],
|
||||
variants: ['400', '700'],
|
||||
styles: {
|
||||
regular: '',
|
||||
bold: '',
|
||||
},
|
||||
metadata: {
|
||||
cachedAt: Date.now(),
|
||||
version: '1.0',
|
||||
popularity: 3,
|
||||
},
|
||||
features: {
|
||||
isVariable: false,
|
||||
},
|
||||
};
|
||||
|
||||
const mockCourier: UnifiedFont = {
|
||||
id: 'courier-new',
|
||||
name: 'Courier New',
|
||||
provider: 'google',
|
||||
category: 'monospace',
|
||||
subsets: ['latin'],
|
||||
variants: ['400', '700'],
|
||||
styles: {
|
||||
regular: '',
|
||||
bold: '',
|
||||
},
|
||||
metadata: {
|
||||
cachedAt: Date.now(),
|
||||
version: '1.0',
|
||||
popularity: 10,
|
||||
},
|
||||
features: {
|
||||
isVariable: false,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<Story name="Default">
|
||||
{@const _ = (comparisonStore.fontA = mockArial, comparisonStore.fontB = mockGeorgia)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="Serif vs Sans-Serif">
|
||||
{@const _ = (comparisonStore.fontA = mockCourier, comparisonStore.fontB = mockVerdana)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="Loading State">
|
||||
{@const _ = (comparisonStore.fontA = undefined, comparisonStore.fontB = undefined)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="With Custom Text">
|
||||
{@const _ = (
|
||||
comparisonStore.fontA = mockArial,
|
||||
comparisonStore.fontB = mockVerdana,
|
||||
comparisonStore.text = 'Typography is the art and technique of arranging type.'
|
||||
)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="Short Text">
|
||||
{@const _ = (comparisonStore.fontA = mockGeorgia, comparisonStore.fontB = mockCourier, comparisonStore.text = 'Hello')}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="Multiline Text">
|
||||
{@const _ = (
|
||||
comparisonStore.fontA = mockArial,
|
||||
comparisonStore.fontB = mockGeorgia,
|
||||
comparisonStore.text =
|
||||
'The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. How vexingly quick daft zebras jump!'
|
||||
)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="Settings Mode">
|
||||
{@const _ = (comparisonStore.fontA = mockVerdana, comparisonStore.fontB = mockArial)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-5xl">
|
||||
<div class="mb-8 text-center">
|
||||
<p class="text-text-muted">Click the settings icon to toggle settings mode</p>
|
||||
</div>
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
|
||||
<Story name="Responsive Container">
|
||||
{@const _ = (comparisonStore.fontA = mockGeorgia, comparisonStore.fontB = mockVerdana)}
|
||||
<Providers>
|
||||
<div class="min-h-screen flex items-center justify-center p-8">
|
||||
<div class="w-full">
|
||||
<div class="mb-8 text-center">
|
||||
<p class="text-text-muted">Resize the browser to see responsive behavior</p>
|
||||
</div>
|
||||
<ComparisonSlider />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
</Story>
|
||||
102
src/widgets/FontSearch/ui/FontSearch/FontSearch.stories.svelte
Normal file
102
src/widgets/FontSearch/ui/FontSearch/FontSearch.stories.svelte
Normal file
@@ -0,0 +1,102 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import FontSearch from './FontSearch.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Widgets/FontSearch',
|
||||
component: FontSearch,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
'Primary search interface with filter panel. Provides a search input and filtering for fonts by provider, category, and subset. Filters can be toggled open/closed with an animated transition.',
|
||||
},
|
||||
story: { inline: false },
|
||||
},
|
||||
layout: 'centered',
|
||||
},
|
||||
argTypes: {
|
||||
showFilters: {
|
||||
control: 'boolean',
|
||||
description: 'Controllable flag to show/hide filters (bindable)',
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
let showFiltersDefault = $state(true);
|
||||
let showFiltersClosed = $state(false);
|
||||
let showFiltersOpen = $state(true);
|
||||
</script>
|
||||
|
||||
<Story name="Default">
|
||||
<div class="w-full max-w-2xl">
|
||||
<FontSearch bind:showFilters={showFiltersDefault} />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Filters Open">
|
||||
<div class="w-full max-w-2xl">
|
||||
<FontSearch bind:showFilters={showFiltersOpen} />
|
||||
<div class="mt-8 text-center">
|
||||
<p class="text-text-muted text-sm">Filters panel is open and visible</p>
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Filters Closed">
|
||||
<div class="w-full max-w-2xl">
|
||||
<FontSearch bind:showFilters={showFiltersClosed} />
|
||||
<div class="mt-8 text-center">
|
||||
<p class="text-text-muted text-sm">Filters panel is closed - click the slider icon to open</p>
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Full Width">
|
||||
<div class="w-full px-8">
|
||||
<FontSearch />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="In Context" tags={['!autodocs']}>
|
||||
<div class="w-full max-w-3xl p-8 space-y-6">
|
||||
<div class="text-center mb-8">
|
||||
<h1 class="text-4xl font-bold mb-2">Font Browser</h1>
|
||||
<p class="text-text-muted">Search and filter through our collection of fonts</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-background-20 rounded-2xl p-6">
|
||||
<FontSearch />
|
||||
</div>
|
||||
|
||||
<div class="mt-8 p-6 bg-background-40 rounded-xl">
|
||||
<p class="text-text-muted text-center">Font results will appear here...</p>
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="With Filters Demo">
|
||||
<div class="w-full max-w-2xl">
|
||||
<div class="mb-4 p-4 bg-background-40 rounded-lg">
|
||||
<p class="text-sm text-text-muted">
|
||||
<strong class="text-foreground">Demo Note:</strong> Click the slider icon to toggle filters. Use the
|
||||
filter categories to select options. Use the filter controls to reset or apply your selections.
|
||||
</p>
|
||||
</div>
|
||||
<FontSearch />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Responsive Behavior">
|
||||
<div class="w-full">
|
||||
<div class="mb-4 text-center">
|
||||
<p class="text-text-muted text-sm">Resize browser to see responsive layout</p>
|
||||
</div>
|
||||
<div class="px-4 sm:px-8 md:px-12">
|
||||
<FontSearch />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
@@ -0,0 +1,89 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import SampleList from './SampleList.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Widgets/SampleList',
|
||||
component: SampleList,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component:
|
||||
'Virtualized font list with pagination. Renders a list of fonts with auto-loading when scrolling near the bottom. Includes a typography menu for font setup that appears when scrolling past the middle of the viewport.',
|
||||
},
|
||||
story: { inline: false },
|
||||
},
|
||||
layout: 'fullscreen',
|
||||
},
|
||||
argTypes: {
|
||||
// This component uses internal stores, so no direct props to document
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Default">
|
||||
<div class="min-h-screen bg-background">
|
||||
<div class="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-8 text-center">
|
||||
<h1 class="text-4xl font-bold mb-2">Font Samples</h1>
|
||||
<p class="text-text-muted">Scroll to see more fonts and load additional pages</p>
|
||||
</div>
|
||||
<SampleList />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Full Page">
|
||||
<div class="min-h-screen bg-background">
|
||||
<SampleList />
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="With Typography Controls">
|
||||
<div class="min-h-screen bg-background">
|
||||
<div class="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-8 text-center">
|
||||
<h1 class="text-4xl font-bold mb-2">Typography Controls</h1>
|
||||
<p class="text-text-muted">Scroll down to see the typography menu appear</p>
|
||||
</div>
|
||||
<SampleList />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Custom Text">
|
||||
<div class="min-h-screen bg-background">
|
||||
<div class="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-8 text-center">
|
||||
<h1 class="text-4xl font-bold mb-2">Custom Sample Text</h1>
|
||||
<p class="text-text-muted">Edit the text in any card to change all samples</p>
|
||||
</div>
|
||||
<SampleList />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Pagination Info">
|
||||
<div class="min-h-screen bg-background">
|
||||
<div class="max-w-4xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-8 text-center">
|
||||
<h1 class="text-4xl font-bold mb-2">Paginated List</h1>
|
||||
<p class="text-text-muted">Fonts load automatically as you scroll</p>
|
||||
</div>
|
||||
<SampleList />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
|
||||
<Story name="Responsive Layout">
|
||||
<div class="min-h-screen bg-background">
|
||||
<div class="max-w-6xl mx-auto py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div class="mb-8 text-center">
|
||||
<h1 class="text-4xl font-bold mb-2">Responsive Sample List</h1>
|
||||
<p class="text-text-muted">Resize browser to see responsive behavior</p>
|
||||
</div>
|
||||
<SampleList />
|
||||
</div>
|
||||
</div>
|
||||
</Story>
|
||||
Reference in New Issue
Block a user