gamebrary/src/components/Toast.vue

131 lines
2.2 KiB
Vue
Raw Normal View History

2019-01-19 05:23:14 +00:00
<template lang="html">
2019-11-08 20:34:06 +00:00
<div
:class="['toast', type, { show, 'has-image': imageUrl }]"
@click="close"
>
<img :src="imageUrl" >
<i :class="[iconName]" />
<h4>{{ message }}</h4>
</div>
2019-01-19 05:23:14 +00:00
</template>
<script>
export default {
2019-11-08 19:56:03 +00:00
data() {
return {
message: '',
imageUrl: null,
type: 'success',
timer: 2000,
show: false,
timeout: null,
toastTypes: {
success: 'fas fa-check',
warning: 'fas fa-exclamation',
error: 'fas fa-times',
},
};
},
computed: {
iconName() {
return this.toastTypes[this.type];
2019-01-19 05:23:14 +00:00
},
2019-11-08 19:56:03 +00:00
},
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
watch: {
show() {
clearTimeout(this.timeout);
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
this.timeout = setTimeout(() => {
this.close();
}, this.timer);
2019-01-19 05:23:14 +00:00
},
2019-11-08 19:56:03 +00:00
},
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
mounted() {
this.$bus.$on('TOAST', this.toast);
},
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
beforeDestroy() {
this.$bus.$off('TOAST');
},
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
methods: {
toast({ message, type, imageUrl }) {
this.timer = type === 'error'
? 5000
: 2000;
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
this.message = message || null;
this.imageUrl = imageUrl || null;
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
this.type = Object.keys(this.toastTypes).includes(type)
? type
: 'success';
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
this.show = Boolean(message);
},
2019-01-19 05:23:14 +00:00
2019-11-08 19:56:03 +00:00
close() {
this.show = false;
2019-01-19 05:23:14 +00:00
},
2019-11-08 19:56:03 +00:00
},
2019-01-19 05:23:14 +00:00
};
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
2019-11-08 20:34:06 +00:00
@import "~styles/styles";
2019-01-19 05:23:14 +00:00
2019-11-08 20:34:06 +00:00
.toast {
2019-01-19 05:23:14 +00:00
display: flex;
align-items: center;
position: fixed;
bottom: -80px;
right: $gp;
cursor: pointer;
2019-01-19 05:41:25 +00:00
max-width: 300px;
2019-01-19 05:23:14 +00:00
opacity: 0;
z-index: 1;
2019-01-19 05:23:14 +00:00
border-radius: $border-radius;
padding: $gp;
transition: all 200ms linear;
2019-10-09 16:30:07 +00:00
&.success {
2019-11-08 20:34:06 +00:00
background: var(--success-background);
color: var(--success-text-color);
2019-10-09 16:30:07 +00:00
}
&.error {
2019-11-08 20:34:06 +00:00
background: var(--danger-background);
color: var(--danger-text-color);
2019-10-09 16:30:07 +00:00
}
2019-04-06 06:15:17 +00:00
&.has-image {
2019-11-08 20:34:06 +00:00
padding: $gp / 3;
max-width: 240px;
h4 {
font-size: 12px;
}
img {
margin-right: $gp / 2;
max-width: 50px;
max-height: 50px;
}
2019-04-06 06:15:17 +00:00
}
2019-01-19 05:23:14 +00:00
i {
2019-11-08 20:34:06 +00:00
margin-right: $gp / 2;
font-size: 20px;
2019-01-19 05:23:14 +00:00
}
&.show {
2019-11-08 20:34:06 +00:00
bottom: $gp;
opacity: 1;
transition: all 200ms linear;
2019-01-19 05:23:14 +00:00
}
2019-11-08 20:34:06 +00:00
}
2019-01-19 05:26:14 +00:00
</style>