paulnicoue/components/AppError.vue

122 lines
3.5 KiB
Vue
Raw Normal View History

2023-01-06 15:46:20 +01:00
<template>
<main>
2023-01-10 10:28:09 +01:00
<div class="error">
<h1 class="error__title">{{ errorMessage }}</h1>
<div class="error__separator" aria-hidden="true"></div>
<div class="error__emoticon" aria-hidden="true">¯\(°_o)/¯</div>
<button class="error__button" @click="$emit('handleError')">
<span class="error__button-text">Retourner à la page d'accueil</span>
<svg class="error__button-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg">
<path d="M 2 8.7 L 12 1 L 22 8.7 L 22 20.8 C 22 22.016 21.006 23 19.778 23 L 4.222 23 C 2.995 23 2 22.016 2 20.8 L 2 8.7 Z"/>
<polyline points="8.667 23 8.667 12 15.333 12 15.333 23"/>
</svg>
</button>
</div>
2023-01-06 15:46:20 +01:00
</main>
</template>
<script setup>
// --------------------------------------------------
// DATA
// --------------------------------------------------
2023-01-10 10:28:09 +01:00
const props = defineProps({
errorMessage: String
});
2023-01-06 15:46:20 +01:00
const emit = defineEmits([
'handleError'
]);
</script>
2023-01-10 10:28:09 +01:00
<style lang="scss">
main {
padding: 4rem 2rem;
}
.error {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-width: 30vw;
text-align: center;
&__title {
opacity: 0;
margin: 0 2rem;
animation: fade-in-from-bottom 400ms ease-in-out 600ms forwards;
}
&__separator {
width: 0;
height: 1px;
margin: 0.5rem 0;
background-color: var(--accent-color);
animation: expand-width 400ms ease-in-out 200ms forwards;
}
&__emoticon {
opacity: 0;
margin: 0 2rem;
font-size: var(--h1-font-size);
font-weight: var(--medium-font-weight);
animation: fade-in-from-top 400ms ease-in-out 600ms forwards;
}
&__button {
margin: 6rem 0 0 0;
&-icon {
display: none;
}
}
@media screen and (min-width: 48rem) {
&__button {
display: flex;
justify-content: center;
align-items: center;
&-text {
transform: translateX(calc((0.8rem + var(--small-icon-size)) / 2));
transition: transform 200ms ease-in-out;
}
&-icon {
display: inherit;
flex-shrink: 0;
opacity: 0;
width: var(--small-icon-size);
height: var(--small-icon-size);
margin: 0 0 0 0.8rem;
transform: translateX(calc((0.8rem + var(--small-icon-size)) / 2));
transition:
opacity 200ms ease-in-out,
transform 200ms ease-in-out;
}
&:hover,
&:focus,
&:active {
.error__button-text {
transform: translateX(0);
}
.error__button-icon {
opacity: 1;
transform: translateX(0);
}
}
}
}
}
</style>