feature/project-redesign #28
68
src/shared/ui/SectionHeader/SectionHeader.stories.svelte
Normal file
68
src/shared/ui/SectionHeader/SectionHeader.stories.svelte
Normal file
@@ -0,0 +1,68 @@
|
||||
<script module>
|
||||
import { defineMeta } from '@storybook/addon-svelte-csf';
|
||||
import SectionHeader from './SectionHeader.svelte';
|
||||
|
||||
const { Story } = defineMeta({
|
||||
title: 'Shared/SectionHeader',
|
||||
component: SectionHeader,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: 'Numbered section heading with optional subtitle and pulse dot.',
|
||||
},
|
||||
story: { inline: false },
|
||||
},
|
||||
layout: 'centered',
|
||||
},
|
||||
argTypes: {
|
||||
index: {
|
||||
control: 'text',
|
||||
description: 'Section index/number',
|
||||
defaultValue: '1',
|
||||
},
|
||||
title: {
|
||||
control: 'text',
|
||||
description: 'Section title',
|
||||
defaultValue: 'Section Title',
|
||||
},
|
||||
subtitle: {
|
||||
control: 'text',
|
||||
description: 'Optional subtitle',
|
||||
},
|
||||
pulse: {
|
||||
control: 'boolean',
|
||||
description: 'Show pulsing dot indicator',
|
||||
defaultValue: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story
|
||||
name="Default/Basic"
|
||||
args={{ index: 1, title: 'Section Title' }}
|
||||
parameters={{ docs: { description: { story: 'Standard section header' } } }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<SectionHeader index={1} title="Section Title" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With subtitle"
|
||||
args={{ index: 1, title: 'Introduction', subtitle: 'Getting started' }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<SectionHeader index={1} title="Introduction" subtitle="Getting started" />
|
||||
{/snippet}
|
||||
</Story>
|
||||
|
||||
<Story
|
||||
name="With pulse"
|
||||
args={{ index: 1, title: 'Active Section', subtitle: 'Currently viewing', pulse: true }}
|
||||
>
|
||||
{#snippet template()}
|
||||
<SectionHeader index={1} title="Active Section" subtitle="Currently viewing" pulse={true} />
|
||||
{/snippet}
|
||||
</Story>
|
||||
43
src/shared/ui/SectionHeader/SectionHeader.svelte
Normal file
43
src/shared/ui/SectionHeader/SectionHeader.svelte
Normal file
@@ -0,0 +1,43 @@
|
||||
<!--
|
||||
Component: SectionHeader
|
||||
Numbered section heading with optional subtitle and pulse dot.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { cn } from '$shared/shadcn/utils/shadcn-utils';
|
||||
import { Label } from '$shared/ui';
|
||||
|
||||
interface Props {
|
||||
index: string | number;
|
||||
title: string;
|
||||
subtitle?: string;
|
||||
pulse?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
index,
|
||||
title,
|
||||
subtitle,
|
||||
pulse = false,
|
||||
class: className,
|
||||
}: Props = $props();
|
||||
|
||||
const indexStr = $derived(String(index).padStart(2, '0'));
|
||||
</script>
|
||||
|
||||
<div class={cn('flex items-center gap-3 md:gap-4 mb-2', className)}>
|
||||
<div class="flex items-center gap-2">
|
||||
{#if pulse}
|
||||
<span class="w-1.5 h-1.5 bg-brand rounded-full animate-pulse"></span>
|
||||
{/if}
|
||||
|
||||
<Label variant="accent" size="sm" bold>
|
||||
{indexStr} // {title}
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
{#if subtitle}
|
||||
<span class="text-neutral-300 dark:text-neutral-700 text-[0.625rem] hidden md:inline">/</span>
|
||||
<Label variant="muted" size="sm">{subtitle}</Label>
|
||||
{/if}
|
||||
</div>
|
||||
Reference in New Issue
Block a user