236 lines
13 KiB
Plaintext
236 lines
13 KiB
Plaintext
component FAQAccordion {
|
|
props {
|
|
class = ""
|
|
eyebrow = ""
|
|
title = "Frequently asked questions"
|
|
description = ""
|
|
|
|
items = []
|
|
|
|
centered = true
|
|
compact = false
|
|
|
|
allowMultiple = false
|
|
defaultOpenIndex = 0
|
|
|
|
showContact = false
|
|
contactText = "Still have questions?"
|
|
contactLabel = "Contact support"
|
|
contactHref = "/support"
|
|
}
|
|
|
|
state openIndexes = defaultOpenIndex >= 0 ? [defaultOpenIndex] : []
|
|
|
|
functions {
|
|
function isOpen(index) {
|
|
return openIndexes.includes(index)
|
|
}
|
|
|
|
function toggleItem(index) {
|
|
if (isOpen(index)) {
|
|
openIndexes = openIndexes.filter(
|
|
(itemIndex) => itemIndex !== index
|
|
)
|
|
} else if (allowMultiple) {
|
|
openIndexes = [...openIndexes, index]
|
|
} else {
|
|
openIndexes = [index]
|
|
}
|
|
}
|
|
}
|
|
|
|
view {
|
|
<section
|
|
aria-labelledby="faq-accordion-title"
|
|
class="w-full px-5 sm:px-8 lg:px-10 xl:px-12 {class}"
|
|
class:py-10="compact"
|
|
class:sm:py-12="compact"
|
|
class:py-14="!compact"
|
|
class:sm:py-16="!compact"
|
|
class:lg:py-20="!compact"
|
|
class:hidden="items.length === 0"
|
|
>
|
|
<div
|
|
class="mx-auto w-full"
|
|
class:max-w-5xl="centered"
|
|
class:max-w-7xl="!centered"
|
|
>
|
|
<div
|
|
class="gap-10"
|
|
class:flex="centered"
|
|
class:flex-col="centered"
|
|
class:grid="!centered"
|
|
class:lg:grid-cols-[minmax(260px,0.7fr)_minmax(0,1.3fr)]="!centered"
|
|
class:lg:items-start="!centered"
|
|
class:lg:gap-14="!centered"
|
|
>
|
|
<!-- Heading -->
|
|
<div
|
|
class="min-w-0"
|
|
class:mx-auto="centered"
|
|
class:max-w-3xl="centered"
|
|
class:text-center="centered"
|
|
class:max-w-xl="!centered"
|
|
class:lg:sticky="!centered"
|
|
class:lg:top-24="!centered"
|
|
>
|
|
<!-- Eyebrow -->
|
|
<p
|
|
class="text-xs font-bold uppercase tracking-[0.18em] text-indigo-600 dark:text-indigo-400"
|
|
class:hidden="eyebrow === ''"
|
|
>
|
|
{eyebrow}
|
|
</p>
|
|
|
|
<!-- Title -->
|
|
<h2
|
|
id="faq-accordion-title"
|
|
class="font-bold leading-tight tracking-tight text-slate-950 dark:text-white"
|
|
class:mt-3="eyebrow !== ''"
|
|
class:text-2xl="compact"
|
|
class:sm:text-3xl="compact"
|
|
class:text-3xl="!compact"
|
|
class:sm:text-4xl="!compact"
|
|
>
|
|
{title}
|
|
</h2>
|
|
|
|
<!-- Description -->
|
|
<p
|
|
class="mt-4 text-sm leading-7 text-slate-600 dark:text-slate-400"
|
|
class:hidden="description === ''"
|
|
class:sm:text-base="!compact"
|
|
class:mx-auto="centered"
|
|
class:max-w-2xl="centered"
|
|
class:max-w-xl="!centered"
|
|
>
|
|
{description}
|
|
</p>
|
|
|
|
<!-- Contact card -->
|
|
<div
|
|
class="mt-7 rounded-2xl border border-indigo-200/80 bg-linear-to-br from-indigo-50 via-white to-violet-50 p-5 shadow-sm dark:border-indigo-500/20 dark:from-indigo-500/10 dark:via-white/[0.03] dark:to-violet-500/10"
|
|
class:hidden="!showContact"
|
|
>
|
|
<div
|
|
class="flex items-center gap-4"
|
|
class:justify-center="centered"
|
|
>
|
|
<span
|
|
class="grid h-11 w-11 shrink-0 place-items-center rounded-xl bg-white text-indigo-600 shadow-sm ring-1 ring-inset ring-indigo-200 dark:bg-white/5 dark:text-indigo-300 dark:ring-indigo-500/20"
|
|
>
|
|
<span class="icon-[lucide--messages-square] h-5 w-5" aria-hidden="true" ></span>
|
|
</span>
|
|
|
|
<div
|
|
class="min-w-0"
|
|
class:text-left="centered"
|
|
>
|
|
<p class="text-sm font-semibold text-slate-950 dark:text-white">
|
|
{contactText}
|
|
</p>
|
|
|
|
{#if contactLabel !== '' && contactHref !== ''}
|
|
<a
|
|
href="{contactHref}"
|
|
class="mt-1 inline-flex items-center gap-1.5 text-sm font-bold text-indigo-600 transition-colors duration-200 hover:text-indigo-500 dark:text-indigo-400 dark:hover:text-indigo-300"
|
|
>
|
|
{contactLabel}
|
|
|
|
<span class="icon-[lucide--arrow-right] h-4 w-4" aria-hidden="true" ></span>
|
|
</a>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Accordion -->
|
|
<div class="min-w-0">
|
|
<div class="space-y-3">
|
|
{#each items as item, index}
|
|
<article
|
|
class=" overflow-hidden rounded-2xl border transition-[border-color,background-color,box-shadow,transform] duration-300 ease-out {isOpen(index) ? 'border-indigo-200 bg-indigo-50/60 shadow-md shadow-indigo-950/5 dark:border-indigo-500/20 dark:bg-indigo-500/10' : 'border-slate-200 bg-white shadow-sm hover:-translate-y-0.5 hover:border-indigo-200 hover:bg-slate-50 dark:border-white/10 dark:bg-white/[0.03] dark:hover:border-indigo-500/20 dark:hover:bg-white/5' } "
|
|
>
|
|
<h3>
|
|
<button
|
|
type="button"
|
|
@click="toggleItem(index)"
|
|
aria-expanded="{isOpen(index)}"
|
|
aria-controls="faq-answer-{index}"
|
|
class="flex w-full items-center justify-between gap-5 text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-indigo-500"
|
|
class:px-4="compact"
|
|
class:py-4="compact"
|
|
class:px-5="!compact"
|
|
class:py-5="!compact"
|
|
class:sm:px-6="!compact"
|
|
>
|
|
<span class="flex min-w-0 items-start gap-3">
|
|
<!-- Number -->
|
|
<span
|
|
class=" mt-0.5 grid h-7 w-7 shrink-0 place-items-center rounded-lg text-xs font-bold transition-[background-color,color,transform] duration-300 ease-out {isOpen(index) ? 'bg-indigo-600 text-white' : 'bg-slate-100 text-slate-500 dark:bg-white/5 dark:text-slate-400' } "
|
|
>
|
|
{index + 1}
|
|
</span>
|
|
|
|
<!-- Question -->
|
|
<span
|
|
class="font-semibold leading-6 text-slate-950 dark:text-white"
|
|
class:text-sm="compact"
|
|
class:text-base="!compact"
|
|
>
|
|
{item.question}
|
|
</span>
|
|
</span>
|
|
|
|
<!-- Toggle icon -->
|
|
<span
|
|
class=" grid h-8 w-8 shrink-0 place-items-center rounded-lg transition-[background-color,color,transform] duration-300 ease-out {isOpen(index) ? 'bg-indigo-100 text-indigo-700 dark:bg-indigo-500/15 dark:text-indigo-300' : 'bg-slate-100 text-slate-500 dark:bg-white/5 dark:text-slate-400' } "
|
|
>
|
|
<span class=" icon-[lucide--chevron-down] h-4 w-4 transition-transform duration-300 ease-out {isOpen(index) ? 'rotate-180' : 'rotate-0'} " aria-hidden="true" ></span>
|
|
</span>
|
|
</button>
|
|
</h3>
|
|
|
|
<div
|
|
id="faq-answer-{index}"
|
|
role="region"
|
|
aria-hidden="{!isOpen(index)}"
|
|
class=" grid overflow-hidden transition-[grid-template-rows,opacity] duration-300 ease-out {isOpen(index) ? 'grid-rows-[1fr] opacity-100' : 'grid-rows-[0fr] opacity-0' } "
|
|
>
|
|
<div class="min-h-0 overflow-hidden">
|
|
<div class="border-t border-indigo-200/60 dark:border-indigo-500/15">
|
|
<div
|
|
class=" text-sm leading-7 text-slate-600 transition-[transform,opacity] duration-300 ease-out dark:text-slate-400 {compact ? 'px-4 pb-4 pt-3' : 'px-5 pb-5 pt-4 sm:px-6 sm:pb-6 sm:pt-5' } {isOpen(index) ? 'translate-y-0 opacity-100' : '-translate-y-2 opacity-0' } "
|
|
>
|
|
<p class="m-0">
|
|
{item.answer}
|
|
</p>
|
|
|
|
{#if item.linkLabel !== '' && item.href !== ''}
|
|
<a
|
|
href="{item.href}"
|
|
class=" group inline-flex items-center gap-2 text-sm font-bold text-indigo-600 transition-colors duration-200 hover:text-indigo-500 dark:text-indigo-400 dark:hover:text-indigo-300 "
|
|
>
|
|
{item.linkLabel}
|
|
|
|
<span class=" icon-[lucide--arrow-up-right] h-4 w-4 transition-transform duration-200 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 " aria-hidden="true" ></span>
|
|
</a>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tailwind safelist for utilities used by reactive class directives -->
|
|
<span class=" hidden flex flex-col grid justify-center lg:gap-14 lg:grid-cols-[minmax(260px,0.7fr)_minmax(0,1.3fr)] lg:items-start lg:py-20 lg:sticky lg:top-24 max-w-2xl max-w-3xl max-w-5xl max-w-7xl max-w-xl mt-3 mx-auto px-4 px-5 py-4 py-5 py-10 py-14 sm:px-6 sm:py-12 sm:py-16 sm:text-base sm:text-3xl sm:text-4xl text-base text-center text-left text-sm text-2xl text-3xl grid-rows-[0fr] grid-rows-[1fr] opacity-0 opacity-100 -translate-y-2 translate-y-0 rotate-0 rotate-180 " ></span>
|
|
</section>
|
|
}
|
|
}
|