feat: alerts provider

This commit is contained in:
Alexandr
2022-07-27 17:16:27 +03:00
parent a7ba76d263
commit b9a0436fc7
5 changed files with 65 additions and 12 deletions

View File

@@ -5,6 +5,7 @@
<Button @click="() => add('success')" color="green">success</Button> <Button @click="() => add('success')" color="green">success</Button>
<Button @click="() => add('warning')" color="yellow">warning</Button> <Button @click="() => add('warning')" color="yellow">warning</Button>
<Button @click="() => add('danger')" color="red">danger</Button> <Button @click="() => add('danger')" color="red">danger</Button>
<Button @click="() => add('update')" color="purple">update</Button>
</div> </div>
<div class="flex"> <div class="flex">
<Button @click="remove" color="alternative">remove</Button> <Button @click="remove" color="alternative">remove</Button>
@@ -13,18 +14,34 @@
</template> </template>
<script setup> <script setup>
import { FLOWBITE_TOAST_INJECTION_KEY } from '../../../../src/components/Toast/components/ToastProvider/injection/config' import { FLOWBITE_TOAST_INJECTION_KEY } from '../../../../src/components/Toast/components/ToastProvider/injection/config'
import { inject, ref } from 'vue' import { inject, ref, shallowRef } from 'vue'
import { Button } from '../../../../src/index' import { Button } from '../../../../src/index'
import UpdateToast from './UpdateToast.vue'
const ms = ref('5000') const ms = ref('5000')
const injected = inject(FLOWBITE_TOAST_INJECTION_KEY) const injected = inject(FLOWBITE_TOAST_INJECTION_KEY)
const add = (type) => {
const addUpdate = () => {
injected.add({ injected.add({
time: parseInt(ms.value) || 0, time: parseInt(ms.value) || 0,
type: type, text: 'A new software version is available for download.',
component: shallowRef(UpdateToast),
componentProps: {
alignment: 'start',
closable: true,
},
})
}
const add = (type) => {
if(type === 'update') return addUpdate()
injected.add({
type,
time: parseInt(ms.value) || 0,
text: `${type} alert! Hello world!`, text: `${type} alert! Hello world!`,
}) })
} }
const remove = () => { const remove = () => {
injected.pop() injected.pop()

View File

@@ -0,0 +1,25 @@
<template>
<flowbite-themable theme="blue">
<toast @close="$emit('close')" v-bind="$attrs">
<template #icon>
<svg aria-hidden="true" class="w-5 h-5" fill="#ffff" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z"
clip-rule="evenodd"></path>
</svg>
</template>
<span class="mb-1 text-sm font-semibold text-gray-900 dark:text-white">Update available</span>
<div class="mb-2 text-sm font-normal">
<slot/>
</div>
<div class="grid grid-cols-2 gap-2">
<Button size="xs">Update</Button>
<Button size="xs" :color="'alternative'">Not now</Button>
</div>
</toast>
</flowbite-themable>
</template>
<script setup>
import { Toast, Button, FlowbiteThemable } from '../../../../src/index'
defineEmits(['close'])
</script>

View File

@@ -22,7 +22,7 @@ export default defineComponent({
id, id,
...toast, ...toast,
}) })
if(toast.time > 0) if (toast.time > 0)
runRemoveTimeout(id, toast.time) runRemoveTimeout(id, toast.time)
} }
@@ -32,7 +32,7 @@ export default defineComponent({
} }
const popToast = () => { const popToast = () => {
if(toasts.value.length === 0) return if (toasts.value.length === 0) return
toasts.value.pop() toasts.value.pop()
} }
@@ -63,12 +63,18 @@ export default defineComponent({
}, },
{ {
default: () => toasts.map(_toast => // rendering every toast default: () => toasts.map(_toast => // rendering every toast
h(Toast as any, { _toast.component
closable: true, ? h(_toast.component, {
type: _toast.type, key: _toast.id,
key: _toast.id, onClose: () => removeToast(_toast.id),
onClose: () => removeToast(_toast.id), ...(_toast.componentProps ? _toast.componentProps : {}),
}, () => _toast.text), }, () => _toast.text)
: h(Toast as any, {
closable: true,
type: _toast.type,
key: _toast.id,
onClose: () => removeToast(_toast.id),
}, () => _toast.text),
), ),
}, },
), ),

View File

@@ -1,9 +1,12 @@
import type { ToastType } from '@/components/Toast/types' import type { ToastType } from '@/components/Toast/types'
import type { DefineComponent } from 'vue'
export type ToastItem = { export type ToastItem = {
time: number // ms time: number // ms
type: ToastType type: ToastType
text: string text: string
component?: DefineComponent
componentProps?: Record<string, unknown>
} }
export type ToastItemWithId = ToastItem & { export type ToastItemWithId = ToastItem & {

View File

@@ -1,5 +1,7 @@
<template> <template>
<slot /> <div>
<slot />
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { PropType } from 'vue' import type { PropType } from 'vue'