paulnicoue/components/AppError.vue

158 lines
4 KiB
Vue
Raw Permalink Normal View History

2023-01-06 15:46:20 +01:00
<template>
<main>
<section class="error">
<Transition name="fade-in-from-bottom">
<h1 class="error__title" v-show="isVisible">{{ errorMessage }}</h1>
</Transition>
<Transition name="expand-width">
2023-03-06 11:50:54 +01:00
<div class="error__divider" aria-hidden="true" v-show="isVisible"></div>
</Transition>
<Transition name="fade-in-from-top">
<div class="error__emoticon" aria-hidden="true" v-show="isVisible">¯\(°_o)/¯</div>
</Transition>
2023-01-10 10:28:09 +01:00
<button class="error__button" @click="$emit('handleError')">
2023-03-03 12:00:04 +01:00
<span>Retourner à la page d'accueil</span>
<svg aria-hidden="true" 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">
2023-01-10 10:28:09 +01:00
<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>
</section>
2023-01-06 15:46:20 +01:00
</main>
</template>
<script setup>
// --------------------------------------------------
// DATA
// --------------------------------------------------
defineProps({
2023-01-10 10:28:09 +01:00
errorMessage: String
});
const isVisible = ref(false);
// --------------------------------------------------
// PROGRAM
// --------------------------------------------------
onMounted(() => {
isVisible.value = true;
})
// --------------------------------------------------
// FORWARDING
// --------------------------------------------------
defineEmits([
2023-01-06 15:46:20 +01:00
'handleError'
]);
</script>
2023-01-10 10:28:09 +01:00
2023-01-11 15:16:55 +01:00
<style lang="scss" scoped>
// --------------------------------------------------
2023-01-20 18:08:51 +01:00
// STYLE
2023-01-11 15:16:55 +01:00
// --------------------------------------------------
2023-01-10 10:28:09 +01:00
main {
width: 100%;
2023-02-15 12:26:30 +01:00
display: flex;
justify-content: center;
2023-01-10 10:28:09 +01:00
}
.error {
2023-02-15 12:26:30 +01:00
@include large-section;
display: grid;
grid:
'title' minmax(var(--h1-font-height), auto)
2023-03-06 11:50:54 +01:00
'divider' 1px
'emoticon' minmax(var(--h1-font-height), auto)
'.' 5rem
'button' auto
2023-02-21 11:52:22 +01:00
/ minmax(50%, auto);
place-content: center;
place-items: center;
gap: 0.5rem;
2023-01-10 10:28:09 +01:00
text-align: center;
&__title {
grid-area: title;
2023-01-10 10:28:09 +01:00
margin: 0 2rem;
}
2023-03-06 11:50:54 +01:00
&__divider {
grid-area: divider;
width: 100%;
2023-01-10 10:28:09 +01:00
height: 1px;
2023-03-06 11:50:54 +01:00
background: linear-gradient(90deg, var(--primary-color), var(--primary-accent-color-light), var(--primary-color));
2023-01-10 10:28:09 +01:00
}
&__emoticon {
grid-area: emoticon;
2023-01-10 10:28:09 +01:00
margin: 0 2rem;
2023-01-20 18:08:51 +01:00
font-family: var(--title-font-family);
2023-01-10 10:28:09 +01:00
font-size: var(--h1-font-size);
font-weight: var(--medium-font-weight);
}
&__button {
2023-02-14 17:50:36 +01:00
@include button-with-icon;
grid-area: button;
margin: 0 2rem;
}
2023-01-11 15:16:55 +01:00
}
// Transition components
2023-01-11 15:16:55 +01:00
.fade-in-from-bottom {
2023-01-10 10:28:09 +01:00
&-enter-from,
&-leave-to {
opacity: 0;
transform: translateY(0.25rem);
}
&-enter-active,
&-leave-active {
transition:
opacity 400ms ease-in-out 600ms,
transform 400ms ease-in-out 600ms;
}
}
.fade-in-from-top {
&-enter-from,
&-leave-to {
opacity: 0;
transform: translateY(-0.25rem);
}
&-enter-active,
&-leave-active {
transition:
opacity 400ms ease-in-out 600ms,
transform 400ms ease-in-out 600ms;
}
}
.expand-width {
&-enter-from,
&-leave-to {
width: 0;
}
&-enter-active,
&-leave-active {
transition: width 400ms ease-in-out 200ms;
2023-01-10 10:28:09 +01:00
}
}
</style>