forked from cms/tibi-svelte-starter
✨ feat: add new contact form, hero, features, and richtext blocks; implement scroll-reveal action and update styles
- Introduced ContactFormBlock, FeaturesBlock, HeroBlock, and RichtextBlock components. - Implemented a scroll-reveal action for animations on element visibility. - Enhanced CSS styles for better theming and prose formatting. - Added localization support for new components and updated existing translations. - Created e2e tests for demo pages including contact form validation and navigation. - Added a video tour showcasing the demo pages and interactions.
This commit is contained in:
77
frontend/src/blocks/RichtextBlock.svelte
Normal file
77
frontend/src/blocks/RichtextBlock.svelte
Normal file
@@ -0,0 +1,77 @@
|
||||
<script lang="ts">
|
||||
import { reveal } from "../lib/actions/reveal"
|
||||
|
||||
let { block }: { block: ContentBlockEntry } = $props()
|
||||
|
||||
const paddingTop = $derived(
|
||||
block.padding?.top === "lg"
|
||||
? "pt-20"
|
||||
: block.padding?.top === "md"
|
||||
? "pt-12"
|
||||
: block.padding?.top === "sm"
|
||||
? "pt-8"
|
||||
: "pt-4"
|
||||
)
|
||||
const paddingBottom = $derived(
|
||||
block.padding?.bottom === "lg"
|
||||
? "pb-20"
|
||||
: block.padding?.bottom === "md"
|
||||
? "pb-12"
|
||||
: block.padding?.bottom === "sm"
|
||||
? "pb-8"
|
||||
: "pb-4"
|
||||
)
|
||||
|
||||
const hasImage = $derived(block.externalImageUrl || block.image)
|
||||
const imageOnRight = $derived(block.imagePosition === "right")
|
||||
const imageOnLeft = $derived(block.imagePosition === "left")
|
||||
const showImage = $derived(hasImage && (imageOnRight || imageOnLeft))
|
||||
</script>
|
||||
|
||||
<section data-block="richtext" class="richtext-section {paddingTop} {paddingBottom}" id={block.anchorId || undefined}>
|
||||
<div class="max-w-6xl mx-auto px-6">
|
||||
{#if block.tagline}
|
||||
<div use:reveal>
|
||||
<span class="inline-block text-brand-500 text-sm font-semibold tracking-widest uppercase mb-3">
|
||||
{block.tagline}
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if block.headline}
|
||||
<div use:reveal={{ delay: 100 }}>
|
||||
<h2 class="text-3xl sm:text-4xl font-display font-bold text-gray-900 mb-8">
|
||||
{block.headline}
|
||||
</h2>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if showImage}
|
||||
<!-- Layout with image -->
|
||||
<div class="grid md:grid-cols-2 gap-12 items-center" use:reveal={{ delay: 200 }}>
|
||||
<div class:order-2={imageOnLeft} class="prose max-w-none">
|
||||
{@html block.text || ""}
|
||||
</div>
|
||||
<div class:order-1={imageOnLeft} class="relative">
|
||||
<div class="rounded-2xl overflow-hidden shadow-xl shadow-brand-900/10">
|
||||
<img
|
||||
src={block.externalImageUrl || ""}
|
||||
alt={block.headline || ""}
|
||||
class="w-full h-auto object-cover aspect-4/3"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
<!-- Decorative gradient behind image -->
|
||||
<div
|
||||
class="absolute -inset-4 -z-10 rounded-3xl bg-linear-to-br from-brand-100 to-brand-50 blur-sm"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Text-only layout -->
|
||||
<div class="prose max-w-3xl" use:reveal={{ delay: 200 }}>
|
||||
{@html block.text || ""}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
Reference in New Issue
Block a user