fix: stories errors
All checks were successful
Workflow / build (pull_request) Successful in 3m22s
Workflow / publish (pull_request) Has been skipped

This commit is contained in:
Ilia Mashkov
2026-03-02 22:45:29 +03:00
parent 87bba388dc
commit 6f65aa207e
2 changed files with 121 additions and 433 deletions

View File

@@ -56,7 +56,7 @@ let longValue = $state(
}}
>
{#snippet template(args)}
<ContentEditable bind:text={value} {...args} />
<ContentEditable {...args} />
{/snippet}
</Story>
@@ -70,7 +70,7 @@ let longValue = $state(
}}
>
{#snippet template(args)}
<ContentEditable bind:text={smallValue} {...args} />
<ContentEditable {...args} />
{/snippet}
</Story>
@@ -84,7 +84,7 @@ let longValue = $state(
}}
>
{#snippet template(args)}
<ContentEditable bind:text={largeValue} {...args} />
<ContentEditable {...args} />
{/snippet}
</Story>
@@ -98,7 +98,7 @@ let longValue = $state(
}}
>
{#snippet template(args)}
<ContentEditable bind:text={spacedValue} {...args} />
<ContentEditable {...args} />
{/snippet}
</Story>
@@ -112,6 +112,6 @@ let longValue = $state(
}}
>
{#snippet template(args)}
<ContentEditable bind:text={longValue} {...args} />
<ContentEditable {...args} />
{/snippet}
</Story>

View File

@@ -1,5 +1,4 @@
<script module>
import { cn } from '$shared/shadcn/utils/shadcn-utils';
import { defineMeta } from '@storybook/addon-svelte-csf';
import Section from './Section.svelte';
@@ -11,7 +10,7 @@ const { Story } = defineMeta({
docs: {
description: {
component:
'Page layout component with optional sticky title feature. Provides a container for page widgets with title, icon, description snippets. The title can remain fixed while scrolling through content.',
'Page layout component that provides a container for page widgets with title, optional header, description, and content snippets.',
},
story: { inline: false },
},
@@ -22,461 +21,152 @@ const { Story } = defineMeta({
control: 'text',
description: 'ID of the section',
},
title: {
control: 'text',
description: 'Section title text',
},
index: {
control: 'number',
description: 'Index of the section (used for default description)',
description: 'Index of the section',
},
stickyTitle: {
control: 'boolean',
description: 'When true, title stays fixed while scrolling through content',
},
stickyOffset: {
headerTitle: {
control: 'text',
description: 'Top offset for sticky title (e.g. "60px")',
description: 'Header title text',
},
headerSubtitle: {
control: 'text',
description: 'Header subtitle text',
},
class: {
control: 'text',
description: 'Additional CSS classes',
},
onTitleStatusChange: {
action: 'titleStatusChanged',
description: 'Callback when title visibility status changes',
},
},
});
</script>
<script lang="ts">
import ListIcon from '@lucide/svelte/icons/list';
import SearchIcon from '@lucide/svelte/icons/search';
import SettingsIcon from '@lucide/svelte/icons/settings';
</script>
{#snippet searchIcon({ className }: { className?: string })}
<SearchIcon class={className} />
{/snippet}
{#snippet welcomeTitle({ className }: { className?: string })}
<h2 class={className}>Welcome</h2>
{/snippet}
{#snippet welcomeContent({ className }: { className?: string })}
<div class={cn(className, 'min-w-128')}>
<Story name="Default">
{#snippet template()}
<Section title="Welcome" index={1}>
{#snippet content()}
<p class="text-lg text-text-muted">
This is the default section layout with a title and content area. The section uses a 2-column grid layout
with the title on the left and content on the right.
This is the default section layout with a title and content area. The section provides a container
for page widgets.
</p>
</div>
{/snippet}
{#snippet stickyTitle({ className }: { className?: string })}
<h2 class={className}>Sticky Title</h2>
{/snippet}
{#snippet stickyContent({ className }: { className?: string })}
<div class={cn(className, 'min-w-128')}>
<p class="text-lg text-text-muted mb-4">
This section has a sticky title that stays fixed while you scroll through the content. Try scrolling down to
see the effect.
</p>
<div class="space-y-4">
<p class="text-text-muted">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua.
</p>
<p class="text-text-muted">
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
<p class="text-text-muted">
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
<p class="text-text-muted">
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollim anim id est
laborum.
</p>
<p class="text-text-muted">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.
</p>
</div>
</div>
{/snippet}
{#snippet searchFontsTitle({ className }: { className?: string })}
<h2 class={className}>Search Fonts</h2>
{/snippet}
{#snippet searchFontsDescription({ className }: { className?: string })}
<span class={className}>Find your perfect typeface</span>
{/snippet}
{#snippet searchFontsContent({ className }: { className?: string })}
<div class={cn(className, 'min-w-128')}>
<p class="text-lg text-text-muted">
Use the search bar to find fonts by name, or use the filters to browse by category, subset, or provider.
</p>
</div>
{/snippet}
{#snippet longContentTitle({ className }: { className?: string })}
<h2 class={className}>Long Content</h2>
{/snippet}
{#snippet longContent({ className }: { className?: string })}
<div class={cn(className, 'min-w-128')}>
<div class="space-y-6">
<p class="text-lg text-text-muted">
This section demonstrates how the sticky title behaves with longer content. As you scroll through this
content, the title remains visible at the top of the viewport.
</p>
<div class="h-64 bg-background-40 rounded-lg flex items-center justify-center">
<span class="text-text-muted">Content block 1</span>
</div>
<p class="text-text-muted">
The sticky position is achieved using CSS position: sticky with a configurable top offset. This is
useful for long sections where you want to maintain context while scrolling.
</p>
<div class="h-64 bg-background-40 rounded-lg flex items-center justify-center">
<span class="text-text-muted">Content block 2</span>
</div>
<p class="text-text-muted">
The Intersection Observer API is used to detect when the section title scrolls out of view, triggering
the optional onTitleStatusChange callback.
</p>
<div class="h-64 bg-background-40 rounded-lg flex items-center justify-center">
<span class="text-text-muted">Content block 3</span>
</div>
</div>
</div>
{/snippet}
{#snippet minimalTitle({ className }: { className?: string })}
<h2 class={className}>Minimal Section</h2>
{/snippet}
{#snippet minimalContent({ className }: { className?: string })}
<div class={cn(className, 'min-w-128')}>
<p class="text-text-muted">
A minimal section without index, icon, or description. Just the essentials.
</p>
</div>
{/snippet}
{#snippet customTitle({ className }: { className?: string })}
<h2 class={className}>Custom Content</h2>
{/snippet}
{#snippet customDescription({ className }: { className?: string })}
<span class={className}>With interactive elements</span>
{/snippet}
{#snippet customContent({ className }: { className?: string })}
<div class={cn(className, 'min-w-128')}>
<div class="grid grid-cols-2 gap-4">
<div class="p-4 bg-background-40 rounded-lg">
<h3 class="font-semibold mb-2">Card 1</h3>
<p class="text-sm text-text-muted">Some content here</p>
</div>
<div class="p-4 bg-background-40 rounded-lg">
<h3 class="font-semibold mb-2">Card 2</h3>
<p class="text-sm text-text-muted">More content here</p>
</div>
</div>
</div>
{/snippet}
<Story
name="Default"
args={{
title: welcomeTitle,
content: welcomeContent,
}}
>
{#snippet template(args)}
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section index={1} {...args}>
{#snippet title({ className })}
<h2 class={className}>Welcome</h2>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<p class="text-lg text-text-muted">
This is the default section layout with a title and content area. The section uses a
2-column grid layout with the title on the left and content on the right.
</p>
</div>
{/snippet}
</Section>
</div>
{/snippet}
</Story>
<Story
name="With Sticky Title"
args={{
title: stickyTitle,
content: stickyContent,
}}
>
{#snippet template(args)}
<div class="h-[200vh]">
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section
id="sticky-section"
index={1}
stickyTitle={true}
stickyOffset="20px"
{...args}
>
{#snippet title({ className })}
<h2 class={className}>Sticky Title</h2>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<p class="text-lg text-text-muted mb-4">
This section has a sticky title that stays fixed while you scroll through the content.
Try scrolling down to see the effect.
<Story name="With Header">
{#snippet template()}
<Section title="Typography Settings" headerTitle="Section Header" headerSubtitle="Subtitle text" index={1}>
{#snippet content()}
<p class="text-lg text-text-muted">
This section includes a header with title and subtitle above the section title.
</p>
<div class="space-y-4">
<p class="text-text-muted">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
</p>
<p class="text-text-muted">
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip
ex ea commodo consequat.
</p>
<p class="text-text-muted">
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
</p>
<p class="text-text-muted">
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollim anim id est laborum.
</p>
<p class="text-text-muted">
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium.
</p>
</div>
</div>
{/snippet}
</Section>
</div>
</div>
{/snippet}
</Story>
<Story
name="With Icon and Description"
args={{
icon: searchIcon,
title: searchFontsTitle,
description: searchFontsDescription,
content: searchFontsContent,
}}
>
{#snippet template(args)}
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section index={1} {...args}>
{#snippet title({ className })}
<h2 class={className}>Search Fonts</h2>
<Story name="With Header Content">
{#snippet template()}
<Section title="Search Fonts" index={1}>
{#snippet headerContent()}
<button class="px-3 py-1.5 text-sm bg-background-40 rounded-lg text-text-muted">
Action
</button>
{/snippet}
{#snippet icon({ className })}
<SearchIcon class={className} />
{/snippet}
{#snippet description({ className })}
<span class={className}>Find your perfect typeface</span>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
{#snippet content()}
<p class="text-lg text-text-muted">
Use the search bar to find fonts by name, or use the filters to browse by category, subset,
or provider.
Use the search bar to find fonts by name, or use the filters to browse by category, subset, or
provider.
</p>
</div>
{/snippet}
</Section>
</div>
{/snippet}
</Story>
<Story name="Multiple Sections" tags={['!autodocs']}>
{#snippet template(args)}
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section
id="section-1"
index={1}
stickyTitle={true}
{...args}
>
{#snippet title({ className })}
<h2 class={className}>Typography</h2>
{/snippet}
{#snippet icon({ className })}
<SettingsIcon class={className} />
{/snippet}
{#snippet description({ className })}
<span class={className}>Adjust text appearance</span>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
{#snippet template()}
<div class="space-y-0">
<Section id="section-1" title="Typography" index={1}>
{#snippet content()}
<p class="text-lg text-text-muted">
Control the size, weight, and line height of your text. These settings apply across the
comparison view.
</p>
</div>
{/snippet}
</Section>
<Section
id="section-2"
index={2}
stickyTitle={true}
{...args}
>
{#snippet title({ className })}
<h2 class={className}>Font Search</h2>
{/snippet}
{#snippet icon({ className })}
<SearchIcon class={className} />
{/snippet}
{#snippet description({ className })}
<span class={className}>Browse available typefaces</span>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<Section id="section-2" title="Font Search" index={2}>
{#snippet content()}
<p class="text-lg text-text-muted">
Search through our collection of fonts from Google Fonts and Fontshare. Use filters to
narrow down your selection.
Search through our collection of fonts from Google Fonts and Fontshare. Use filters to narrow
down your selection.
</p>
</div>
{/snippet}
</Section>
<Section
id="section-3"
index={3}
stickyTitle={true}
{...args}
>
{#snippet title({ className })}
<h2 class={className}>Sample List</h2>
{/snippet}
{#snippet icon({ className })}
<ListIcon class={className} />
{/snippet}
{#snippet description({ className })}
<span class={className}>Preview font samples</span>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<Section id="section-3" title="Sample List" index={3}>
{#snippet content()}
<p class="text-lg text-text-muted">
Browse through font samples with your custom text. The list is virtualized for optimal
performance.
</p>
</div>
{/snippet}
</Section>
</div>
{/snippet}
</Story>
<Story
name="With Long Content"
args={{
title: longContentTitle,
content: longContent,
}}
>
{#snippet template(args)}
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section
index={1}
stickyTitle={true}
stickyOffset="0px"
{...args}
>
{#snippet title({ className })}
<h2 class={className}>Long Content</h2>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<Story name="With Long Content">
{#snippet template()}
<Section title="Long Content" index={1}>
{#snippet content()}
<div class="space-y-6">
<p class="text-lg text-text-muted">
This section demonstrates how the sticky title behaves with longer content. As you
scroll through this content, the title remains visible at the top of the viewport.
This section demonstrates how the component behaves with longer content.
</p>
<div class="h-64 bg-background-40 rounded-lg flex items-center justify-center">
<span class="text-text-muted">Content block 1</span>
</div>
<p class="text-text-muted">
The sticky position is achieved using CSS position: sticky with a configurable top
offset. This is useful for long sections where you want to maintain context while
scrolling.
The Section component provides a consistent layout container for page-level widgets with
configurable titles and content areas.
</p>
<div class="h-64 bg-background-40 rounded-lg flex items-center justify-center">
<span class="text-text-muted">Content block 2</span>
</div>
<p class="text-text-muted">
The Intersection Observer API is used to detect when the section title scrolls out of
view, triggering the optional onTitleStatusChange callback.
Content is passed via snippets, allowing full flexibility in what gets rendered inside.
</p>
<div class="h-64 bg-background-40 rounded-lg flex items-center justify-center">
<span class="text-text-muted">Content block 3</span>
</div>
</div>
</div>
{/snippet}
</Section>
</div>
{/snippet}
</Story>
<Story
name="Minimal"
args={{
title: minimalTitle,
content: minimalContent,
}}
>
{#snippet template(args)}
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section {...args}>
{#snippet title({ className })}
<h2 class={className}>Minimal Section</h2>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<Story name="Minimal">
{#snippet template()}
<Section title="Minimal Section">
{#snippet content()}
<p class="text-text-muted">
A minimal section without index, icon, or description. Just the essentials.
A minimal section without index or header. Just the essentials.
</p>
</div>
{/snippet}
</Section>
</div>
{/snippet}
</Story>
<Story
name="Custom Content"
args={{
title: customTitle,
description: customDescription,
content: customContent,
}}
>
{#snippet template(args)}
<div class="grid grid-cols-1 lg:grid-cols-[auto_1fr] gap-x-6 sm:gap-x-8 md:gap-x-10 lg:gap-x-12 p-8 max-w-6xl mx-auto">
<Section index={42} {...args}>
{#snippet title({ className })}
<h2 class={className}>Custom Content</h2>
{/snippet}
{#snippet description({ className })}
<span class={className}>With interactive elements</span>
{/snippet}
{#snippet content({ className })}
<div class={cn(className, 'min-w-128')}>
<Story name="Custom Content">
{#snippet template()}
<Section title="Custom Content" index={42}>
{#snippet content()}
<div class="grid grid-cols-2 gap-4">
<div class="p-4 bg-background-40 rounded-lg">
<h3 class="font-semibold mb-2">Card 1</h3>
@@ -487,9 +177,7 @@ import SettingsIcon from '@lucide/svelte/icons/settings';
<p class="text-sm text-text-muted">More content here</p>
</div>
</div>
</div>
{/snippet}
</Section>
</div>
{/snippet}
</Story>