111 lines
2.5 KiB
Vue
111 lines
2.5 KiB
Vue
<template>
|
|
<div class="myAccordion">
|
|
<article
|
|
v-for="(item, i) in items"
|
|
:key="i"
|
|
class="accordion-item"
|
|
>
|
|
<!-- 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></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%
|
|
|
|
.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
|
|
|
|
// 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>
|