feature/project-redesign #28

Merged
ilia merged 88 commits from feature/project-redesign into main 2026-03-02 19:46:39 +00:00
2 changed files with 111 additions and 0 deletions
Showing only changes of commit 8617f2c117 - Show all commits

View 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>

View 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>