Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Created August 20, 2020 14:34
Show Gist options
  • Save innocenzi/5440755fad53ad23c8fddd39629058de to your computer and use it in GitHub Desktop.
Save innocenzi/5440755fad53ad23c8fddd39629058de to your computer and use it in GitHub Desktop.
Inertia flashes component
<template>
<section
:class="[
'mb-16 mx-16',
'absolute inset-x-0 bottom-0 z-50',
'flex justify-center',
'transition-opacity duration-1000',
!hasFlashes && 'opacity-0',
]"
>
<transition-group
tag="ul"
:appear="true"
class="relative w-full max-w-3xl"
enter-active-class="transition duration-100 ease-out"
enter-class="transform scale-75 opacity-0"
enter-to-class="transform scale-100 opacity-100"
leave-active-class="absolute transition duration-75 ease-in"
leave-class="transform scale-100 opacity-100"
leave-to-class="transform scale-95 opacity-0"
move-class="transition-all duration-500"
>
<li
v-for="flash of flashes"
:key="flash.id"
:class="[
'flex justify-between',
'w-full p-4 mb-4 last:mb-0',
'border md:border-none',
'rounded-md shadow-md',
alertClasses[flash.type],
]"
>
<div class="flex items-center">
<icon :icon="icons[flash.type]" class="w-6 h-6 mr-3 " />
{{ flash.message }}
</div>
<button
class="transition-transform duration-150 transform rounded hover:scale-110 focus:outline-none focus:shadow-input"
@click="hide(flash)"
>
<icon icon="plus" class="w-6 transform rotate-45" />
</button>
</li>
</transition-group>
</section>
</template>
<script>
import Icon from '@/components/Icon.vue';
export default {
components: {
Icon,
},
data: () => ({
timeout: 5000,
flashes: [],
icons: {
error: 'exclamationCircle',
success: 'checkCircle',
},
alertClasses: {
error: 'bg-surface text-on-alert-error border-on-alert-error',
success: 'bg-surface text-on-alert-success border-on-alert-success',
},
}),
computed: {
hasFlashes() {
return this.flashes.length > 0;
},
},
methods: {
hide(flash) {
this.flashes.splice(this.flashes.indexOf(flash), 1);
},
getUniqueId(flash) {
const id = Math.random()
.toString(36)
.substr(2, 9);
return `${id}_${flash.type}_${flash.message}`;
},
updateFlashes() {
let delay = 0;
Object.values(this.$page.flash).forEach((flash) => {
const item = {
id: this.getUniqueId(flash),
...flash,
};
this.flashes.push(item);
setTimeout(() => this.hide(item), this.timeout + delay);
delay += 100;
});
},
},
mounted() {
this.updateFlashes();
},
watch: {
'$page.flash': {
handler() {
this.updateFlashes();
},
deep: true,
},
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment