104 lines
2.2 KiB
Svelte
104 lines
2.2 KiB
Svelte
<!--
|
|
Component: Section
|
|
Provides a container for a page widget with snippets for a title
|
|
-->
|
|
<script lang="ts">
|
|
import { type Snippet } from 'svelte';
|
|
import { cubicOut } from 'svelte/easing';
|
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
import {
|
|
type FlyParams,
|
|
fly,
|
|
} from 'svelte/transition';
|
|
import SectionHeader from './SectionHeader/SectionHeader.svelte';
|
|
import SectionTitle from './SectionTitle/SectionTitle.svelte';
|
|
|
|
interface Props extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
/**
|
|
* Section ID
|
|
*/
|
|
id?: string;
|
|
/**
|
|
* CSS classes
|
|
*/
|
|
class?: string;
|
|
/**
|
|
* Section title
|
|
*/
|
|
title: string;
|
|
/**
|
|
* Breadcrumb title
|
|
*/
|
|
breadcrumbTitle?: string;
|
|
/**
|
|
* Description snippet
|
|
*/
|
|
description?: Snippet<[{ className?: string }]>;
|
|
/**
|
|
* Header title
|
|
*/
|
|
headerTitle?: string;
|
|
/**
|
|
* Header subtitle
|
|
*/
|
|
headerSubtitle?: string;
|
|
/**
|
|
* Header action callback
|
|
*/
|
|
headerAction?: (node: HTMLElement) => void;
|
|
/**
|
|
* Section index
|
|
*/
|
|
index?: number;
|
|
/**
|
|
* Content snippet
|
|
*/
|
|
content?: Snippet<[{ className?: string }]>;
|
|
/**
|
|
* Header content snippet
|
|
*/
|
|
headerContent?: Snippet<[{ className?: string }]>;
|
|
}
|
|
|
|
let {
|
|
class: className,
|
|
title,
|
|
headerTitle,
|
|
headerSubtitle,
|
|
headerContent,
|
|
headerAction = () => {},
|
|
index = 0,
|
|
id,
|
|
content,
|
|
}: Props = $props();
|
|
|
|
const flyParams: FlyParams = {
|
|
y: 0,
|
|
x: -50,
|
|
duration: 300,
|
|
easing: cubicOut,
|
|
opacity: 0.2,
|
|
};
|
|
</script>
|
|
|
|
<section
|
|
{id}
|
|
class="w-full max-w-7xl mx-auto px-4 md:px-6 py-8 md:py-16 {className}"
|
|
in:fly={flyParams}
|
|
out:fly={flyParams}
|
|
>
|
|
<div
|
|
use:headerAction
|
|
class="flex flex-col md:flex-row md:items-end justify-between mb-8 md:mb-12 gap-4 md:gap-6"
|
|
>
|
|
<div>
|
|
{#if headerTitle}
|
|
<SectionHeader title={headerTitle} subtitle={headerSubtitle} {index} />
|
|
{/if}
|
|
<SectionTitle text={title} />
|
|
</div>
|
|
{@render headerContent?.({})}
|
|
</div>
|
|
{@render content?.({})}
|
|
</section>
|