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