import '@/components/UNotification/transition.scss' import { ExtractPropTypes, watch, computed, Transition } from 'vue' import { genericComponent, propsFactory, useRender } from '@/utils' import { makeComponentProps } from '@/composables/component' import { makeTagProps } from '@/composables/tag' import { UIcon } from '@/components' import { useNotification } from '@/components' export const makeUNotificationProps = propsFactory( { ...makeComponentProps(), ...makeTagProps(), }, 'UNotification' ) export type UNotificationProps = ExtractPropTypes export type UNotificationSlots = { default: never notificationTitle: never notificationSubtitle: never notificationText: never notificationButtons: never } export const UNotification = genericComponent()({ name: 'UNotification', props: makeUNotificationProps(), setup(props, { slots }) { const $useNotification = useNotification() const isActive = computed(() => { return $useNotification.isActive.value }) const delay = computed(() => { return $useNotification?.currentNotification.value?.delay || 5000 }) const elevation = computed(() => { return ( 'shadow-' + $useNotification?.currentNotification.value?.elevation || '' ) }) const position = computed(() => { return ( $useNotification?.currentNotification.value?.position || 'bottomRight' ) }) const iconLeft = computed(() => { return $useNotification?.currentNotification.value?.iconLeft || undefined }) const iconTop = computed(() => { return $useNotification?.currentNotification.value?.iconTop || undefined }) const color = computed(() => { return ( $useNotification?.currentNotification.value?.color + '-600' || 'primary-600' ) }) const transformClasses = computed(() => { if (position.value === 'topLeft') return 'top-[24px] left-[24px]' if (position.value === 'topRight') return 'top-[24px] right-[24px]' if (position.value === 'bottomLeft') return 'bottom-[24px] left-[24px]' if (position.value === 'bottomRight') return 'bottom-[24px] right-[24px]' return '' }) const transitionName = computed(() => { if (position.value === 'topLeft' || position.value === 'bottomLeft') return 'slide-in-from-left' if (position.value === 'topRight' || position.value === 'bottomRight') return 'slide-in-from-right' return '' }) const classes = computed(() => [ `fixed w-fit p-4 bg-white rounded-lg border border-gray-100 z-50`, props.class, elevation.value, transformClasses.value, ]) const onClose = () => { $useNotification.close() } let closingTimer = 0 watch( () => isActive.value, (newIsActive) => { if (newIsActive) { closingTimer = setTimeout(() => { $useNotification.close() }, delay.value) } else { clearTimeout(closingTimer) } } ) useRender(() => ( {isActive.value ? (
xClose
{iconTop.value ? ( {iconTop.value} ) : null}
{iconLeft.value ? ( {iconLeft.value} ) : null}
{$useNotification?.currentNotification?.value?.title ? (
{$useNotification?.currentNotification?.value?.title}
) : null} {$useNotification?.currentNotification.value?.subTitle ? (
{ $useNotification?.currentNotification?.value ?.subTitle }
) : null}
{$useNotification?.currentNotification?.value?.text ? (
{$useNotification?.currentNotification?.value?.text}
) : null}
{$useNotification?.currentNotification?.value?.buttons ? (
{$useNotification?.currentNotification?.value?.buttons}
) : null}
{slots.default?.()}
) : null}
)) return {} }, }) export type UNotification = InstanceType