feat: alert system + useToast works

This commit is contained in:
Alexandr
2022-07-28 20:22:21 +03:00
parent b9a0436fc7
commit 96036c27e8
6 changed files with 129 additions and 30 deletions

View File

@@ -1,9 +1,49 @@
.list-enter-active,
.list-leave-active {
.slide-left-enter-active,
.slide-left-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
.slide-left-enter-from,
.slide-left-leave-to {
opacity: 0;
transform: translateX(30px);
}
.slide-right-enter-active,
.slide-right-leave-active {
transition: all 0.5s ease;
}
.slide-right-enter-from,
.slide-right-leave-to {
opacity: 0;
transform: translateX(-30px);
}
.slide-top-enter-active,
.slide-top-leave-active {
transition: all 0.5s ease;
}
.slide-top-enter-from,
.slide-top-leave-to {
opacity: 0;
transform: translateY(30px);
}
.slide-bottom-enter-active,
.slide-bottom-leave-active {
transition: all 0.5s ease;
}
.slide-bottom-enter-from,
.slide-bottom-leave-to {
opacity: 0;
transform: translateY(-30px);
}
.fade-enter-active,
.fade-leave-active {
transition: all 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}

View File

@@ -1,14 +1,26 @@
<script lang="ts">
import { defineComponent, h, provide, ref, resolveComponent, TransitionGroup } from 'vue'
import { defineComponent, h, provide, ref, TransitionGroup } from 'vue'
import { FLOWBITE_TOAST_INJECTION_KEY } from '@/components/Toast/components/ToastProvider/injection/config'
import type { ToastItem, ToastItemWithId } from '@/components/Toast/components/ToastProvider/types'
import type {
ToastItem,
ToastItemWithId,
ToastTransition,
UseToastInjection,
} from '@/components/Toast/components/ToastProvider/types'
import { Toast } from '@/index'
import { useTimeoutFn } from '@vueuse/core'
import type { PropType } from 'vue'
export default defineComponent({
components: {
Toast: Toast as any,
},
props: {
transition: {
type: String as PropType<ToastTransition>,
default: 'slide-left',
},
},
setup() {
const toasts = ref<ToastItemWithId[]>([])
@@ -17,29 +29,33 @@ export default defineComponent({
}
const addToast = (toast: ToastItem) => {
const id = ((new Date()).getTime() * Math.random()).toString()
const id = parseInt(((new Date()).getTime() * Math.random()).toString()).toString()
toasts.value.push({
id,
...toast,
})
if (toast.time > 0)
runRemoveTimeout(id, toast.time)
return id
}
const popToast = () => {
if (toasts.value.length === 0) return ''
const lastId = toasts.value[toasts.value.length - 1].id
toasts.value.pop()
return lastId
}
const removeToast = (id: string) => {
const index = toasts.value.findIndex(_ => _.id === id)
toasts.value.splice(index, 1)
if(index >= 0) toasts.value.splice(index, 1)
return index >= 0
}
const popToast = () => {
if (toasts.value.length === 0) return
toasts.value.pop()
}
provide(FLOWBITE_TOAST_INJECTION_KEY, {
provide<UseToastInjection>(FLOWBITE_TOAST_INJECTION_KEY, {
add: addToast,
remove: removeToast,
pop: popToast,
remove: removeToast,
})
return {
@@ -49,6 +65,7 @@ export default defineComponent({
},
render() {
const {
$props,
$slots,
toasts,
removeToast,
@@ -57,7 +74,7 @@ export default defineComponent({
return h('div', {}, [
$slots.default ? $slots.default() : null, // rendering default slot
h(TransitionGroup, {
name: 'list',
name: $props.transition,
tag: 'div',
class: 'xl:w-1/6 md:w-1/4 sm:w-1/4 fixed top-3 right-3 flex flex-col gap-2 z-50',
},

View File

@@ -1,3 +1,29 @@
export function useToast() {
return ''
import { inject } from 'vue'
import type { ToastItem, UseToastInjection } from '@/components/Toast/components/ToastProvider/types'
import { FLOWBITE_TOAST_INJECTION_KEY } from '@/components/Toast/components/ToastProvider/injection/config'
export function useToast(): UseToastInjection {
const injection = inject<UseToastInjection | null>(FLOWBITE_TOAST_INJECTION_KEY, null)
if(injection === null) console.warn('Cannot use useToast outside <toast-provider> component. Please wrap your component with <toast-provider>')
const add = (toast: ToastItem): string => {
if(!injection) return ''
return injection?.add(toast)
}
const remove = (id: string): boolean => {
if(!injection) return false
return injection?.remove(id)
}
const pop = (): string => {
if(!injection) return ''
return injection?.pop()
}
return {
add,
remove,
pop,
}
}

View File

@@ -13,5 +13,10 @@ export type ToastItemWithId = ToastItem & {
id: string
}
export type ToastInjection = {
export type ToastTransition = 'slide-left' | 'slide-right' | 'fade' | 'slide-top' | 'slide-bottom'
export type UseToastInjection = {
add: (toast: ToastItem) => string
remove: (id: string) => boolean // true if removed, false if not found
pop: () => string // empty '' string if no toast to pop
}