dml_frontend/components/AccessabilityBox.vue
2025-05-19 21:36:21 +02:00

276 lines
6.6 KiB
Vue

<template>
<div class="accessabilityBox" :class="[{ open },{ mobile: screenWidth < 1350, desk: screenWidth >= 1350 }]">
<div class="icon-wrapper" :class="{ open }" @click="toggleOpen">
<div class="icon">
<svg>
<use xlink:href="/assets/icons/collection.svg#accessibility"/>
</svg>
</div>
<span v-if="open">{{ $t('accessibilitySettings') }}</span>
<button v-if="open" class="close-button" @click.stop="open = false">
</button>
</div>
<transition name="slide">
<div v-if="open" class="options">
<div
class="fontsize"
:class="{ active: isLargeFont }"
@click="toggleFontsize"
>
<UIcon name="radix-icons:font-size" class="size-12" />
<p>{{ $t('changeFontSize') }}</p>
</div>
<div
class="contrast"
:class="{ active: isHighContrast }"
@click="toggleContrast"
>
<UIcon name="radix-icons:half-2" class="size-12" />
<p>{{ $t('increaseContrast') }}</p>
</div>
<div
class="greyscale"
:class="{ active: isGreyscale }"
@click="toggleGreyscale"
>
<UIcon name="radix-icons:blending-mode" class="size-12" />
<p>{{ $t('greyscale') }}</p>
</div>
<div
class="hideImages"
:class="{ active: isHideImages }"
@click="toggleHideImages"
>
<UIcon name="radix-icons:image" class="size-12" />
<p>{{ $t('hideImages') }}</p>
</div>
<div
class="borderFocus"
:class="{ active: isBorderFocus }"
@click="toggleBorderFocus"
>
<UIcon name="radix-icons:box" class="size-12" />
<p>{{ $t('borderFocus') }}</p>
</div>
<div
class="linksVisible"
:class="{ active: isLinksVisible }"
@click="toggleLinksVisible"
>
<UIcon name="radix-icons:link-1" class="size-12" />
<p>{{ $t('showLinks') }}</p>
</div>
<p class="apFooter">{{ $t('infoAccessibility') }}</p>
</div>
</transition>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useMainStore } from '@/stores/main'
const open = ref(false)
const mainStore = useMainStore()
const screenWidth = computed(() => mainStore.screenWidth)
// Schriftgröße
const isLargeFont = ref(false)
const toggleFontsize = () => {
isLargeFont.value = !isLargeFont.value
document.documentElement.style.setProperty('--text-size', isLargeFont.value ? '20px' : '16px')
}
// Kontrast
const isHighContrast = ref(false)
const toggleContrast = () => {
isHighContrast.value = !isHighContrast.value
document.body.classList.toggle('high-contrast', isHighContrast.value)
}
// Graustufen
const isGreyscale = ref(false)
const toggleGreyscale = () => {
isGreyscale.value = !isGreyscale.value
document.body.classList.toggle('greyscale', isGreyscale.value)
}
// Bilder ausblenden
const isHideImages = ref(false)
const toggleHideImages = () => {
isHideImages.value = !isHideImages.value
document.body.classList.toggle('hide-images', isHideImages.value)
}
// Fokusrahmen aktivieren
const isBorderFocus = ref(false)
const toggleBorderFocus = () => {
isBorderFocus.value = !isBorderFocus.value
document.body.classList.toggle('border-focus', isBorderFocus.value)
}
// Links hervorheben
const isLinksVisible = ref(false)
const toggleLinksVisible = () => {
isLinksVisible.value = !isLinksVisible.value
document.body.classList.toggle('show-links', isLinksVisible.value)
}
// Box öffnen/schließen
const toggleOpen = () => {
open.value = !open.value
}
</script>
<style lang="sass">
.accessabilityBox
position: relative
display: block
background: white
border: 1px solid #ccc
border-bottom-left-radius: 1rem
padding: 0
cursor: pointer
font-family: sans-serif
overflow: hidden
user-select: none
touch-action: manipulation
width: 3.5rem
height: 3.5rem
transition: all 0.4s ease
z-index: 14
&.mobile
transform-origin: bottom right
&.open
width: 100%
height: 80%
max-width: 500px
border-top-left-radius: 1rem
.icon-wrapper
width: 100%
display: flex
justify-content: center
align-items: center
background: white
border-bottom: 1px solid #ccc
transition: all 0.6s ease
height: 3.5rem
position: relative
.icon
width: 1.2rem
display: inline-block
text-align: center
svg
width: 100%
fill: $darkgrey
max-height: 1.5rem
&.open
background: $darkgrey
color: white
font-size: 1.2rem
padding: .8rem 1rem
height: 2.5rem
border-top-left-radius: 1rem
border-top-right-radius: 1rem
justify-content: flex-start
gap: 0.8rem
.main-icon
width: 2.5rem
height: 2.5rem
transition: all 0.6s ease
.close-button
position: absolute
top: 0.25rem
right: .5rem
background: white
border: none
font-size: 1.5rem
cursor: pointer
color: black
border-radius: 50%
width: 2rem
height: 2rem
display: flex
align-items: center
justify-content: center
transition: background 0.3s
&:hover
background-color: $lightgrey
.apFooter
position: absolute
bottom: -1rem
left: 0
width: 100%
background-color: $darkgrey
color: white
padding: .5rem 1rem
border-bottom-left-radius: 1rem
.options
display: flex
flex-wrap: wrap
justify-content: center
margin-bottom: 2rem
gap: 1rem
padding: 2rem
div
cursor: pointer
transition: all 0.8s ease
font-size: 1.2rem
display: flex
flex-direction: column
align-items: center
justify-content: center
width: 8rem
height: 8rem
background: white
border: 3px solid $lightgrey
border-radius: 1rem
text-align: center
p
margin-top: 0.5rem
font-size: 0.9rem
color: $darkgrey
.size-12
width: 3rem
height: 3rem
&:hover
//transform: scale(1.1)
background: $lightgrey
&.active
border-color: $pink
&:hover
background-color: white
.slide-enter-active, .slide-leave-active
transition: all 0.3s ease
.slide-enter-from, .slide-leave-to
opacity: 0
transform: translateY(-10px)
</style>