dml_frontend/components/Accordion.vue
2025-06-03 09:18:45 +02:00

134 lines
3.0 KiB
Vue

<template>
<div class="myAccordion">
<article
v-for="(item, i) in items"
:key="i"
class="accordion-item"
:class="{ open: openIndex === i }"
>
<!-- Header --------------------------------------------------->
<button
class="accordion-header"
:aria-expanded="openIndex === i"
@click="toggle(i)"
>
<span class="accordion-title">{{ item.title }}</span>
<!-- Toggle-Icon (2 Striche) -->
<span class="accordion-toggle" :class="{ open: openIndex === i }">
<span/><span/>
</span>
</button>
<!-- Content --------------------------------------------------->
<transition name="accordion">
<div
v-if="openIndex === i"
class="accordion-content"
v-html="item.html"
/>
</transition>
</article>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{ items: { title: string; html: string }[] }>()
const openIndex = ref<number | null>(null)
const toggle = (i: number) =>
(openIndex.value = openIndex.value === i ? null : i)
</script>
<style lang="sass">
.myAccordion
.accordion-item
border-bottom: 1px solid $lightgrey
width: 100%
transition: .8s
&.open
background-image: linear-gradient(to right, $lightgrey, white)
padding: 1rem
.accordion-header
background: transparent
font-size: 120%
&:hover
background: transparent
.accordion-header
all: unset
width: 100%
display: flex
justify-content: space-between
align-items: center
padding: 1.2rem 1rem 1.2rem 1rem
background: #fff
cursor: pointer
border: 0
font: inherit
text-align: left
font-family: 'Mainfont-Bold'
&:hover
background: linear-gradient(to left, white 1%, lighten($lightgrey, 2%) 80%, white 100%)
// Icon
.accordion-toggle
position: relative
width: 20px
height: 20px
flex-shrink: 0
display: flex
justify-content: center
align-items: center
span
position: absolute
width: 16px
height: 2px
background: #333
transition: transform .25s
&:first-child
transform: rotate(90deg) // horizontale Linie wird senkrecht
&.open
span:first-child
transform: rotate(45deg)
span:last-child
transform: rotate(-45deg)
// Content
.accordion-content
padding: 0 1rem 1rem
h3
font-size: 1rem
margin: 1.2rem 0 .6rem 0
p
font-size: 1rem
ul
li
line-height: 140%
margin-bottom: 1rem
// simple height-fade transition
.accordion-enter-from,
.accordion-leave-to
max-height: 0
opacity: 0
.accordion-enter-active,
.accordion-leave-active
transition: all .25s ease
.accordion-enter-to,
.accordion-leave-from
max-height: 500px // ausreichend groß
opacity: 1
</style>