feat: toast-provider and useToast initial

This commit is contained in:
Alexandr
2022-07-26 22:26:05 +03:00
parent 4cca3e63cf
commit 63c3128b3c
17 changed files with 185 additions and 9 deletions

View File

@@ -23,7 +23,7 @@
</div>
</template>
<script lang="ts" setup>
import type { ToastAlign, ToastPreset } from '@/components/Toast/types'
import type { ToastAlign, ToastType } from '@/components/Toast/types'
import type { PropType } from 'vue'
import { useToastClasses } from './composables/useToastClasses'
import { ref, toRefs } from 'vue'
@@ -32,7 +32,7 @@ import FlowbiteThemableChild
const props = defineProps({
type: {
type: String as PropType<ToastPreset>,
type: String as PropType<ToastType>,
default: 'empty',
},
alignment: {
@@ -59,5 +59,4 @@ const onClose = () => {
emit('close')
visible.value = false
}
</script>

View File

@@ -0,0 +1,9 @@
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}

View File

@@ -0,0 +1,79 @@
<script lang="ts">
import { defineComponent, h, provide, ref, resolveComponent } 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 { Toast } from '@/index'
import { useTimeoutFn } from '@vueuse/core'
export default defineComponent({
components: {
Toast: Toast as any,
},
setup() {
const toasts = ref<ToastItemWithId[]>([])
const runRemoveTimeout = (id: string, ms: number) => {
useTimeoutFn(() => removeToast(id), ms)
}
const addToast = (toast: ToastItem) => {
const id = ((new Date()).getTime() * Math.random()).toString()
toasts.value.push({
id,
...toast,
})
if(toast.time > 0)
runRemoveTimeout(id, toast.time)
}
const removeToast = (id: string) => {
const index = toasts.value.findIndex(_ => _.id === id)
toasts.value.splice(index, 1)
}
const popToast = () => {
if(toasts.value.length === 0) return
toasts.value.pop()
}
provide(FLOWBITE_TOAST_INJECTION_KEY, {
add: addToast,
remove: removeToast,
pop: popToast,
})
return {
toasts,
removeToast,
}
},
render() {
const {
$slots,
toasts,
removeToast,
} = this
return h('div', {}, [
$slots.default ? $slots.default() : null, // rendering default slot
h(resolveComponent('TransitionGroup'), {
name: 'list',
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',
},
toasts.map(_toast => // rendering every toast
h(resolveComponent('Toast'), {
closable: true,
type: _toast.type,
key: _toast.id,
onClose: () => removeToast(_toast.id),
}, _toast.text),
),
),
])
},
})
</script>
<style lang="scss" scoped src="./ToastProvider.css"></style>

View File

@@ -0,0 +1,3 @@
export function useToast() {
return ''
}

View File

@@ -0,0 +1 @@
export const FLOWBITE_TOAST_INJECTION_KEY = 'flowbite-toast-injection-key'

View File

@@ -0,0 +1,14 @@
import type { ToastType } from '@/components/Toast/types'
export type ToastItem = {
time: number // ms
type: ToastType
text: string
}
export type ToastItemWithId = ToastItem & {
id: string
}
export type ToastInjection = {
}

View File

@@ -1,6 +1,6 @@
import type { Ref } from 'vue'
import { computed } from 'vue'
import type { ToastPreset } from '@/components/Toast/types'
import type { ToastType } from '@/components/Toast/types'
import { simplifyTailwindClasses } from '@/utils/simplifyTailwindClasses'
import type { ToastAlign } from '@/components/Toast/types'
@@ -11,12 +11,12 @@ type UseToastClassesReturns = {
}
type UseToastClassesProps = {
type: Ref<ToastPreset>
type: Ref<ToastType>
divide: Ref<boolean>
alignment: Ref<ToastAlign>
}
const typeClassesMap: Record<ToastPreset, string> = {
const typeClassesMap: Record<ToastType, string> = {
danger: 'text-red-500 bg-red-100 dark:bg-red-800 dark:text-red-200',
empty: '',
success: 'text-green-500 bg-green-100 dark:bg-green-800 dark:text-green-200',

View File

@@ -1,2 +1,2 @@
export type ToastPreset = 'success' | 'warning' | 'danger' | 'empty'
export type ToastType = 'success' | 'warning' | 'danger' | 'empty'
export type ToastAlign = 'start' | 'center' | 'end'

5
src/composables.ts Normal file
View File

@@ -0,0 +1,5 @@
import { useToast } from '@/components/Toast/components/ToastProvider/composables/useToast'
export {
useToast,
}

View File

@@ -26,4 +26,7 @@ export { default as Sidebar } from './components/Sidebar/Sidebar.vue'
export { default as Table } from './components/Table/Table.vue'
export { default as Timeline } from './components/Timeline/Timeline.vue'
export { default as Toast } from './components/Toast/Toast.vue'
export { default as ToastProvider } from './components/Toast/components/ToastProvider/ToastProvider.vue'
export { default as Tooltip } from './components/Tooltip/Tooltip.vue'
export * from './composables'