Phase out Skeleton UI in FAQ Accordion
This commit is contained in:
@@ -1,26 +1,47 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { FAQ } from '$lib/schemas';
|
import type { FAQ } from '$lib/schemas';
|
||||||
import { Accordion } from '@skeletonlabs/skeleton-svelte';
|
|
||||||
import { slide } from 'svelte/transition';
|
import { slide } from 'svelte/transition';
|
||||||
|
|
||||||
// Variable to be included into the component
|
// Variable to be included into the component
|
||||||
let { entries }: { entries: FAQ[] } = $props();
|
let { entries }: { entries: FAQ[] } = $props();
|
||||||
|
|
||||||
|
// Track which items are open (supports multiple)
|
||||||
|
let openItems = $state<Set<number>>(new Set());
|
||||||
|
|
||||||
|
function toggleItem(index: number) {
|
||||||
|
const newSet = new Set(openItems);
|
||||||
|
if (newSet.has(index)) {
|
||||||
|
newSet.delete(index);
|
||||||
|
} else {
|
||||||
|
newSet.add(index);
|
||||||
|
}
|
||||||
|
openItems = newSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOpen(index: number): boolean {
|
||||||
|
return openItems.has(index);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Accordion multiple class="space-y-3">
|
<div class="space-y-3">
|
||||||
{#each entries as entry, index}
|
{#each entries as entry, index}
|
||||||
<Accordion.Item
|
<div
|
||||||
value={index.toString()}
|
class="border-ecsess-300 rounded-md border-2 transition-colors duration-200"
|
||||||
class="border-ecsess-300 hover:bg-ecsess-500/30 rounded-md border-2 transition-colors duration-200"
|
|
||||||
>
|
>
|
||||||
<!-- Question -->
|
<!-- Question -->
|
||||||
<Accordion.ItemTrigger
|
<button
|
||||||
class="flex w-full items-center gap-3 px-3 py-2 text-left text-lg font-bold"
|
type="button"
|
||||||
|
onclick={() => toggleItem(index)}
|
||||||
|
class="flex w-full bg-ecsess-600/20 items-center gap-3 px-3 py-2 text-left text-lg font-bold hover:bg-ecsess-500/40 transition-colors duration-200 {isOpen(index)
|
||||||
|
? 'rounded-t-md'
|
||||||
|
: 'rounded-md'}"
|
||||||
>
|
>
|
||||||
{entry.question}
|
{entry.question}
|
||||||
<Accordion.ItemIndicator class="group ml-auto">
|
<span class="ml-auto">
|
||||||
<svg
|
<svg
|
||||||
class="size-5 shrink-0 transition-transform duration-200 group-data-[state=open]:rotate-90"
|
class="size-5 shrink-0 transition-transform duration-200 {isOpen(index)
|
||||||
|
? 'rotate-90'
|
||||||
|
: ''}"
|
||||||
width="20"
|
width="20"
|
||||||
height="20"
|
height="20"
|
||||||
fill="none"
|
fill="none"
|
||||||
@@ -29,28 +50,24 @@
|
|||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
><path d="M9 5l7 7-7 7" />
|
>
|
||||||
|
<path d="M9 5l7 7-7 7" />
|
||||||
</svg>
|
</svg>
|
||||||
</Accordion.ItemIndicator>
|
</span>
|
||||||
</Accordion.ItemTrigger>
|
</button>
|
||||||
|
|
||||||
<!-- Panel -->
|
<!-- Panel -->
|
||||||
<Accordion.ItemContent class="border-t-ecsess-300 bg-ecsess-400/50 h-fit overflow-hidden">
|
{#if isOpen(index)}
|
||||||
{#snippet element(attributes)}
|
|
||||||
{#if !attributes.hidden}
|
|
||||||
<div
|
<div
|
||||||
{...attributes}
|
class="border-t-ecsess-300 bg-transparent h-fit overflow-hidden border-t-2 px-4 py-3
|
||||||
class="border-t-ecsess-300 overflow-hidden border-t-2 px-4 py-3
|
|
||||||
text-base leading-relaxed transition-all duration-200"
|
text-base leading-relaxed transition-all duration-200"
|
||||||
transition:slide={{ duration: 200 }}
|
transition:slide={{ duration: 200 }}
|
||||||
>
|
>
|
||||||
{entry.answer}
|
{entry.answer}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/snippet}
|
</div>
|
||||||
</Accordion.ItemContent>
|
|
||||||
</Accordion.Item>
|
|
||||||
{/each}
|
{/each}
|
||||||
</Accordion>
|
</div>
|
||||||
|
|
||||||
<!-- -->
|
<!-- -->
|
||||||
|
|||||||
Reference in New Issue
Block a user