mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 20:19:34 +01:00
chore(toast): improve notifications
This commit is contained in:
@@ -15,30 +15,39 @@
|
||||
>
|
||||
<div class="relative overflow-hidden rounded-lg ring-1 u-ring-gray-200">
|
||||
<div class="p-4">
|
||||
<div class="flex">
|
||||
<div class="flex" :class="{ 'items-center': !description }">
|
||||
<div class="flex-shrink-0">
|
||||
<Icon :name="iconName" class="w-6 h-6" :class="iconClass" />
|
||||
</div>
|
||||
<div class="ml-3 w-0 flex-1 pt-0.5">
|
||||
<p class="text-sm font-medium leading-5 u-text-gray-900">
|
||||
<p class="text-sm font-medium u-text-gray-900">
|
||||
{{ title }}
|
||||
</p>
|
||||
<p v-if="description" class="mt-1 text-sm leading-5 u-text-gray-500">
|
||||
{{ description }}
|
||||
</p>
|
||||
<Button
|
||||
v-if="undo"
|
||||
variant="white"
|
||||
size="xs"
|
||||
class="mt-2"
|
||||
@click.stop="onUndo"
|
||||
>
|
||||
Undo
|
||||
</Button>
|
||||
|
||||
<div v-if="description" class="mt-3 flex items-center gap-7">
|
||||
<button v-if="undo" type="button" class="text-sm font-medium text-primary-500 hover:text-primary-600 dark:hover:text-primary-400 focus:outline-none" @click.stop="onUndo">
|
||||
Undo
|
||||
</button>
|
||||
<button v-if="dismiss" type="button" class="text-sm font-medium u-text-gray-700 hover:u-text-gray-500 focus:outline-none" @click.stop="onDismiss">
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-shrink-0 ml-4">
|
||||
<div class="flex-shrink-0 flex items-center ml-4">
|
||||
<div v-if="!description" class="flex items-center gap-2">
|
||||
<button v-if="undo" type="button" class="text-sm font-medium text-primary-500 hover:text-primary-600 dark:hover:text-primary-400 focus:outline-none" @click.stop="onUndo">
|
||||
Undo
|
||||
</button>
|
||||
<button v-if="dismiss" type="button" class="text-sm font-medium u-text-gray-700 hover:u-text-gray-500 focus:outline-none" @click.stop="onDismiss">
|
||||
Dismiss
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="transition duration-150 ease-in-out u-text-gray-400 focus:outline-none hover:u-text-gray-500 focus:u-text-gray-500"
|
||||
class="transition duration-150 ease-in-out u-text-gray-400 focus:outline-none hover:u-text-gray-500 focus:u-text-gray-500 ml-4"
|
||||
@click.stop="onClose"
|
||||
>
|
||||
<span class="sr-only">Close</span>
|
||||
@@ -59,8 +68,8 @@
|
||||
import { ref, computed, onMounted, onUnmounted, watchEffect } from 'vue'
|
||||
|
||||
import Icon from '../elements/Icon'
|
||||
import Button from '../elements/Button'
|
||||
import { useTimer } from '../../composables/useTimer'
|
||||
import { classNames } from '../../utils'
|
||||
|
||||
const props = defineProps({
|
||||
id: {
|
||||
@@ -69,10 +78,9 @@ const props = defineProps({
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: 'info',
|
||||
validator (value: string) {
|
||||
return ['info', 'success', 'error', 'warning'].includes(value)
|
||||
default: null,
|
||||
validator (value: string | null) {
|
||||
return [null, 'info', 'success', 'error', 'warning'].includes(value)
|
||||
}
|
||||
},
|
||||
title: {
|
||||
@@ -87,6 +95,10 @@ const props = defineProps({
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
iconClass: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
timeout: {
|
||||
type: Number,
|
||||
default: 5000
|
||||
@@ -95,6 +107,10 @@ const props = defineProps({
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
dismiss: {
|
||||
type: Function,
|
||||
default: null
|
||||
},
|
||||
callback: {
|
||||
type: Function,
|
||||
default: null
|
||||
@@ -116,12 +132,15 @@ const iconName = computed(() => {
|
||||
})
|
||||
|
||||
const iconClass = computed(() => {
|
||||
return ({
|
||||
warning: 'text-orange-400',
|
||||
info: 'text-blue-400',
|
||||
success: 'text-green-400',
|
||||
error: 'text-red-400'
|
||||
})[props.type] || 'u-text-gray-400'
|
||||
return classNames(
|
||||
({
|
||||
warning: 'text-orange-400',
|
||||
info: 'text-blue-400',
|
||||
success: 'text-green-400',
|
||||
error: 'text-red-400'
|
||||
})[props.type] || 'u-text-gray-400',
|
||||
props.iconClass
|
||||
)
|
||||
})
|
||||
|
||||
const progressBarStyle = computed(() => {
|
||||
@@ -165,6 +184,18 @@ function onUndo () {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
function onDismiss () {
|
||||
if (timer) {
|
||||
timer.stop()
|
||||
}
|
||||
|
||||
if (props.dismiss) {
|
||||
props.dismiss()
|
||||
}
|
||||
|
||||
emit('close')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (!props.timeout) {
|
||||
return
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
<div class="fixed bottom-0 right-0 flex flex-col justify-end w-full z-[55] sm:w-96">
|
||||
<div v-if="notifications.length" class="px-4 py-6 space-y-3 overflow-y-auto sm:px-6">
|
||||
<div
|
||||
v-for="(notification, index) of notifications"
|
||||
v-show="index === notifications.length - 1"
|
||||
v-for="notification of notifications"
|
||||
:key="notification.id"
|
||||
>
|
||||
<Notification
|
||||
|
||||
@@ -28,37 +28,17 @@ export default defineNuxtPlugin(() => {
|
||||
toast: {
|
||||
addNotification,
|
||||
removeNotification,
|
||||
success ({ title, description, timeout }: { title?: string, description?: string, timeout?: number } = {}) {
|
||||
addNotification({
|
||||
type: 'success',
|
||||
title,
|
||||
description,
|
||||
timeout
|
||||
})
|
||||
success (notification: Partial<ToastNotification> = {}) {
|
||||
return addNotification({ type: 'success', ...notification })
|
||||
},
|
||||
info ({ title, description, timeout }: { title?: string, description?: string, timeout?: number } = {}) {
|
||||
addNotification({
|
||||
type: 'info',
|
||||
title,
|
||||
description,
|
||||
timeout
|
||||
})
|
||||
info (notification: Partial<ToastNotification> = {}) {
|
||||
return addNotification({ type: 'info', ...notification })
|
||||
},
|
||||
warning ({ title, description, timeout }: { title?: string, description?: string, timeout?: number } = {}) {
|
||||
addNotification({
|
||||
type: 'warning',
|
||||
title,
|
||||
description,
|
||||
timeout
|
||||
})
|
||||
warning (notification: Partial<ToastNotification> = {}) {
|
||||
return addNotification({ type: 'warning', ...notification })
|
||||
},
|
||||
error ({ title = 'An error occurred!', description, timeout }: { title?: string, description?: string, timeout?: number } = {}) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
title,
|
||||
description,
|
||||
timeout
|
||||
})
|
||||
error (notification: Partial<ToastNotification>) {
|
||||
return addNotification({ type: 'error', title: 'An error occurred!', ...notification })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user