File: /var/www/quadcode.com/src/components/accordion/Accordion.svelte
<script lang="ts">
export let title: string | undefined;
export let text: string | undefined;
export let large: boolean | undefined = false;
const Accordion = (e: MouseEvent & { currentTarget: EventTarget & HTMLDivElement }) => {
let item: HTMLElement | null | undefined = e?.currentTarget?.parentElement?.parentElement;
if (!item) {
return;
}
const list: HTMLElement | null = item.querySelector('[data-accordion="container"]');
if (!list) {
return;
}
contains(item) ? close(item, list) : open(item, list);
};
const contains = (item: HTMLElement) => {
return item.classList.contains('accordion--active');
};
const open = (item: HTMLElement, list: HTMLElement) => {
removeActive();
list.style.maxHeight = list.scrollHeight + 'px';
item.classList.add('accordion--active');
};
const close = (item: HTMLElement, list: HTMLElement) => {
list.style.maxHeight = '';
item.classList.remove('accordion--active');
};
const removeActive = () => {
let itemsActive = document.querySelectorAll('.accordion.accordion--active');
itemsActive.forEach((active) => {
const list: HTMLElement | null = active.querySelector('.accordion__list');
if (!list) {
return;
}
active.classList.remove('accordion--active');
list.style.maxHeight = '';
});
};
</script>
<div class="accordion" data-widget="accordion">
<div class="accordion__container">
<div class="accordion__btn" on:click={(e) => Accordion(e)} on:keydown={() => false} role="button" tabindex="0">
<div class="accordion__title">
<span class="accordion__title-text">{@html title ?? ''}</span>
</div>
<div class="accordion__arrow">
{#if large}
<svg width="47" height="47" viewBox="0 0 47 47" fill="none" xmlns="http://www.w3.org/2000/svg">
<line x1="23.5" y1="7" x2="23.5" y2="41" stroke="#445667" stroke-width="3"/>
<line x1="6" y1="23.5" x2="40" y2="23.5" stroke="#445667" stroke-width="3"/>
</svg>
{:else}
<svg fill="none" height="38" viewBox="0 0 38 38" width="38" xmlns="http://www.w3.org/2000/svg">
<path d="M10 19.0098H28" stroke="#313840" stroke-linecap="round" stroke-width="2" />
<path d="M19 28.0098L19 10.0098" stroke="#313840" stroke-linecap="round" stroke-width="2" />
</svg>
{/if}
</div>
</div>
<div class="accordion__list" data-accordion="container">
<div class="accordion__inner">
<p>{@html text ?? ''}</p>
</div>
</div>
</div>
</div>
<style lang="scss">
@import 'src/scss/media';
@import 'src/scss/mixins';
@import 'src/scss/variables';
.accordion {
overflow: hidden;
padding: 20px 0;
border-bottom: 1px solid $techBlue3;
will-change: transform;
@include breakpoint-down('deskS') {
padding: 16px 0;
}
&__btn {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
z-index: 1;
position: relative;
transition: 0.2s ease;
gap: 16px;
}
&__title {
color: $fontPrimary;
font-weight: 500;
font-size: 20px;
line-height: 28px;
@include breakpoint-down('deskS') {
font-size: 17px;
line-height: 24px;
}
}
&__arrow {
display: flex;
flex-shrink: 0;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
svg {
path {
transition: 0.25s ease;
}
}
}
&__list {
width: 100%;
transition: 0.35s cubic-bezier(0.4, 0, 0.2, 1);
pointer-events: none;
max-height: 0;
opacity: 0;
}
&__inner {
width: 100%;
max-width: 92%;
color: $techGrey;
padding-top: 12px;
font-size: 16px;
line-height: 1.7;
@include breakpoint-down('deskL') {
max-width: 92%;
font-size: 15px;
line-height: 1.65;
}
@include breakpoint-down('deskS') {
max-width: 100%;
font-size: 15px;
line-height: 1.6;
}
}
}
:global(.accordion--active) {
.accordion {
&__list {
opacity: 1;
pointer-events: auto;
}
&__btn {
transition: 0.2s ease;
margin-bottom: 4px;
@include breakpoint-down('deskL') {
margin-bottom: 0;
}
}
&__arrow {
transform: rotate(45deg);
svg {
path {
&:last-of-type {
visibility: hidden;
opacity: 0;
transition: 0.2s ease;
}
}
}
}
}
}
</style>