41 lines
1.3 KiB
Svelte
41 lines
1.3 KiB
Svelte
<script lang="ts">
|
|
export let timelineData: Array<{
|
|
title: string;
|
|
description: string;
|
|
duration: string;
|
|
}>;
|
|
|
|
// Track open/closed state for each entry
|
|
let openStates = timelineData.map(() => false);
|
|
|
|
function toggle(index: number) {
|
|
openStates[index] = !openStates[index];
|
|
}
|
|
|
|
toggle(0); // Open the first entry by default
|
|
</script>
|
|
|
|
<div class="flex flex-col items-center justify-center">
|
|
<div class="max-w-4xl w-full">
|
|
{#each timelineData as entry, i}
|
|
<div class="relative border-l border-gray-700 pl-8 pb-12">
|
|
{#if openStates[i]}
|
|
<div class="absolute top-0 left-[8px] text-green-400 w-4 h-4">♦</div>
|
|
{:else}
|
|
<div class="absolute top-0 left-[8px] text-green-400 w-4 h-4">⋄</div>
|
|
{/if}
|
|
<p class="text-sm opacity-70">{entry.duration}</p>
|
|
<button
|
|
class="text-2lg font-semibold text-red-400 mt-1 focus:outline-none hover:underline transition"
|
|
on:click={() => toggle(i)}
|
|
aria-expanded={openStates[i]}
|
|
>
|
|
<h3 class="text-2lg font-semibold text-red-400 mt-1">{entry.title}</h3>
|
|
</button>
|
|
{#if openStates[i]}
|
|
<p class="mt-2 whitespace-pre-line transition-all duration-300">{@html entry.description}</p>
|
|
{/if}
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
</div> |