-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAlert.vue
125 lines (116 loc) · 3.17 KB
/
Alert.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<template>
<div :class="toast()" role="alert">
<svg
v-if="!$props.hideIcon"
xmlns="http://www.w3.org/2000/svg"
:class="icon()"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="1.5"
role="graphics-symbol"
>
<path
v-if="$props.variant == 'default'"
stroke-linecap="round"
stroke-linejoin="round"
d="M13 10V3L4 14h7v7l9-11h-7z"
/>
<path
v-if="$props.variant == 'success'"
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
<path
v-if="$props.variant == 'warn'"
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
/>
<path
v-if="$props.variant == 'info'"
stroke-linecap="round"
stroke-linejoin="round"
d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"
/>
<path
v-if="$props.variant == 'error'"
stroke-linecap="round"
stroke-linejoin="round"
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<div class="flex flex-col">
<h3 :class="title()">{{ $props.title }}</h3>
<slot />
</div>
</div>
</template>
<script lang="ts" setup>
import { tv, type VariantProps } from 'tailwind-variants'
const toastTV = tv({
slots: {
toast: 'relative flex w-full flex-row items-center gap-4 overflow-hidden rounded border text-left',
icon: '',
title: 'mb-1 font-semibold',
description: 'text-sm',
progress: 'absolute bottom-0 left-0 h-0.5 w-full overflow-hidden'
},
variants: {
variant: {
default: {
toast: 'border-primary-100 bg-primary-900 text-primary-200',
progress: 'bg-primary-400'
},
success: {
toast: 'border-emerald-100 bg-emerald-50 text-emerald-500',
progress: 'bg-emerald-400'
},
info: {
toast: 'border-cyan-100 bg-cyan-50 text-cyan-500',
progress: 'bg-cyan-400'
},
error: {
toast: 'border-red-200 bg-pink-100 text-red-500',
progress: 'bg-red-400'
},
warn: {
toast: 'border-amber-100 bg-amber-50 text-amber-500',
progress: 'bg-amber-400'
}
},
size: {
sm: {
toast: 'px-3 py-2',
icon: 'h-5 w-5'
},
md: {
toast: 'px-4 py-3',
icon: 'h-5. w-5'
},
lg: {
toast: 'px-5 py-4',
icon: 'h-6 w-6'
}
}
},
defaultVariants: {
size: 'md',
variant: 'default'
}
})
type ToastProps = VariantProps<typeof toastTV>
type Props = {
// Customization props
size?: ToastProps['size']
variant?: ToastProps['variant']
title?: string
hideIcon?: boolean
}
const props = defineProps<Props>()
const { toast, icon, title, description, progress } = toastTV({
size: props.size,
variant: props.variant
})
</script>