feat(headline): optionaler SectionHeader-Modus (kicker/number/action)
HeadlineBlock rendert als SectionHeader sobald kicker oder action gesetzt ist, sonst schlichte Text-Headline wie bisher (rückwärtskompatibel, opt-in). SectionHeader-Titel unterstützt jetzt \n → <br>. headline-Schema extends section_header. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,12 @@ export interface HeadlineBlockData {
|
|||||||
_slug?: string;
|
_slug?: string;
|
||||||
tag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
tag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
||||||
text?: string;
|
text?: string;
|
||||||
|
/** SectionHeader: Label über dem Titel (uppercase). Gesetzt → Headline rendert als Sektionskopf. */
|
||||||
|
kicker?: string;
|
||||||
|
/** SectionHeader: Index vor dem Kicker, z.B. "03". */
|
||||||
|
number?: string;
|
||||||
|
/** SectionHeader: CTA-Link (aufgelöst: url, linkName). */
|
||||||
|
action?: string | { url?: string; linkName?: string; newTab?: boolean };
|
||||||
align?: "left" | "center" | "right";
|
align?: "left" | "center" | "right";
|
||||||
layout?: BlockLayout;
|
layout?: BlockLayout;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,9 +51,9 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Titel -->
|
<!-- Titel (\n → harter Umbruch, wie HeadlineBlock) -->
|
||||||
<svelte:element this={tag} class="text-3xl font-bold tracking-[-0.02em] text-stein-800 lg:text-[34px]">
|
<svelte:element this={tag} class="text-3xl font-bold tracking-[-0.02em] text-stein-800 lg:text-[34px]">
|
||||||
{title}
|
{#each title.split('\n') as line, i}{#if i > 0}<br />{/if}{line}{/each}
|
||||||
</svelte:element>
|
</svelte:element>
|
||||||
|
|
||||||
{#if subtitle}
|
{#if subtitle}
|
||||||
|
|||||||
@@ -36,3 +36,15 @@ export const MitUmbruch: Story = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Sobald kicker/action gesetzt → Headline rendert als SectionHeader.
|
||||||
|
export const AlsSektionskopf: Story = {
|
||||||
|
args: {
|
||||||
|
block: {
|
||||||
|
tag: 'h2',
|
||||||
|
text: 'Wir sind keine Lobby,\nkeine Partei, keine NGO.',
|
||||||
|
kicker: 'Über uns',
|
||||||
|
action: { url: '/about', linkName: 'Mehr über uns' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getBlockLayoutClasses } from "$lib/block-layout";
|
import { getBlockLayoutClasses } from "$lib/block-layout";
|
||||||
|
import SectionHeader from "$lib/components/SectionHeader.svelte";
|
||||||
import type { HeadlineBlockData } from "$lib/block-types";
|
import type { HeadlineBlockData } from "$lib/block-types";
|
||||||
|
|
||||||
let { block }: { block: HeadlineBlockData } = $props();
|
let { block }: { block: HeadlineBlockData } = $props();
|
||||||
|
|
||||||
const layoutClasses = $derived(getBlockLayoutClasses(block.layout));
|
const layoutClasses = $derived(getBlockLayoutClasses(block.layout));
|
||||||
|
// Sektionskopf-Modus: sobald kicker ODER action gesetzt ist, rendert die
|
||||||
|
// Headline als SectionHeader. Sonst schlichte Text-Headline wie bisher.
|
||||||
|
const actionRef = $derived(
|
||||||
|
block.action && typeof block.action === "object" ? block.action : null,
|
||||||
|
);
|
||||||
|
const useSection = $derived(!!block.kicker || !!actionRef);
|
||||||
|
// SectionHeader kennt nur h1–h3; h4–h6 → h2.
|
||||||
|
const sectionTag = $derived(
|
||||||
|
block.tag === "h1" || block.tag === "h2" || block.tag === "h3" ? block.tag : "h2",
|
||||||
|
);
|
||||||
const alignClass = $derived(
|
const alignClass = $derived(
|
||||||
block.align === "center"
|
block.align === "center"
|
||||||
? "text-center"
|
? "text-center"
|
||||||
@@ -20,10 +31,21 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={layoutClasses} data-block="Headline" data-block-type="headline" data-block-slug={block._slug}>
|
<div class={layoutClasses} data-block="Headline" data-block-type="headline" data-block-slug={block._slug}>
|
||||||
|
{#if useSection}
|
||||||
|
<SectionHeader
|
||||||
|
number={block.number}
|
||||||
|
kicker={block.kicker}
|
||||||
|
title={block.text ?? ""}
|
||||||
|
tag={sectionTag}
|
||||||
|
actionLabel={actionRef?.linkName}
|
||||||
|
actionHref={actionRef?.url}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
<svelte:element
|
<svelte:element
|
||||||
this={Tag}
|
this={Tag}
|
||||||
class={alignClass}
|
class={alignClass}
|
||||||
>
|
>
|
||||||
{#each lines as line, i}{#if i > 0}<br />{/if}{line}{/each}
|
{#each lines as line, i}{#if i > 0}<br />{/if}{line}{/each}
|
||||||
</svelte:element>
|
</svelte:element>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user