PluginProbe
The Innovative Form Builder – IvyForms / 0.8.2
The Innovative Form Builder – IvyForms v0.8.2
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / notification / IvyNotification.vue

IvyNotification.vue in The Innovative Form Builder – IvyForms 0.8.2, at frontend/src/views/_components/notification/IvyNotification.vue

327 lines 8.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <div
3 :class="[
4 'ivyforms-notification ivyforms-flex ivyforms-align-items-center ivyforms-gap-12 ivyforms-p-8',
5 `ivyforms-notification--type-${type}`,
6 `ivyforms-notification--state-${state}`,
7 `ivyforms-notification--style-${style}`,
8 ]"
9 role="alert"
10 :aria-live="state === 'danger' ? 'assertive' : 'polite'"
11 >
12 <!-- Content -->
13 <div class="ivyforms-notification__content ivyforms-flex-1">
14 <!-- Title -->
15 <div v-if="title" class="ivyforms-notification__title ivyforms-flex ivyforms-gap-4">
16 <IvyIcon
17 v-if="showTitleIcon"
18 :name="getTitleIconName()"
19 :type="getTitleIconType()"
20 :category="getTitleIconCategory()"
21 size="s"
22 :color="getTitleIconColor()"
23 class="ivyforms-notification__title-icon"
24 />
25 <span
26 class="ivyforms-notification__title-text medium-14 ivyforms-flex-1 ivyforms-align-items-center ivyforms-mt-2"
27 >{{ title }}</span
28 >
29 </div>
30
31 <!-- Description -->
32 <div
33 v-if="description"
34 class="ivyforms-notification__description ivyforms-flex ivyforms-gap-4"
35 >
36 <IvyIcon
37 v-if="showDescriptionIcon"
38 :name="getDescriptionIconName()"
39 :type="getDescriptionIconType()"
40 :category="getDescriptionIconCategory()"
41 size="s"
42 :color="getDescriptionIconColor()"
43 class="ivyforms-notification__description-icon ivyforms-mt-2"
44 />
45 <span
46 class="ivyforms-notification__description-text regular-14 ivyforms-flex-1 ivyforms-align-items-center ivyforms-mt-2"
47 >
48 {{ description }}
49 <a
50 v-if="showLink"
51 class="ivyforms-notification__description-text__link"
52 :href="linkUrl"
53 :target="linkTarget"
54 >{{ linkText }}
55 </a>
56 </span>
57 </div>
58 </div>
59
60 <!-- Actions -->
61 <div
62 v-if="showButton || $slots.actions"
63 class="ivyforms-notification__actions ivyforms-flex ivyforms-align-items-center ivyforms-gap-4"
64 >
65 <slot name="actions">
66 <IvyButtonAction
67 v-if="showButton"
68 :priority="getButtonPriority()"
69 :type="getButtonType()"
70 size="xs"
71 @click="handleButtonClick"
72 >
73 {{ buttonLabel || getLabel('action') }}
74 </IvyButtonAction>
75 </slot>
76 </div>
77 </div>
78 </template>
79
80 <script setup lang="ts">
81 import IvyIcon from '@/views/_components/icon/IvyIcon.vue'
82 import IvyButtonAction from '@/views/_components/button/IvyButtonAction.vue'
83 import type { IconType } from '@/types/icons/icon-type'
84 import type { IconCategory } from '@/types/icons/icon-category'
85 import { useLabels } from '@/composables/useLabels'
86 import { useTheme } from '@/composables/useTheme'
87
88 const { getLabel } = useLabels()
89 const { isDark } = useTheme()
90
91 type NotificationType = 'stripe'
92 type NotificationState = 'default' | 'success' | 'danger' | 'warning' | 'upcoming' | 'pro' | 'notes'
93 type NotificationStyle = 'fill' | 'stripe'
94
95 export interface IvyNotificationProps {
96 type?: NotificationType
97 state?: NotificationState
98 style?: NotificationStyle
99 title?: string
100 description?: string
101 showIcon?: boolean
102 showTitleIcon?: boolean
103 showDescriptionIcon?: boolean
104 showButton?: boolean
105 buttonLabel?: string
106 showLink?: boolean
107 linkText?: string
108 linkUrl?: string
109 linkTarget?: '_self' | '_blank'
110 }
111
112 const props = withDefaults(defineProps<IvyNotificationProps>(), {
113 type: 'stripe',
114 state: 'default',
115 style: 'fill',
116 title: '',
117 description: '',
118 showIcon: false,
119 showTitleIcon: true,
120 showDescriptionIcon: true,
121 showButton: false,
122 buttonLabel: '',
123 showLink: false,
124 linkText: '',
125 linkUrl: '',
126 linkTarget: '_blank',
127 })
128
129 const emit = defineEmits<{
130 buttonClick: []
131 }>()
132
133 // Icon logic based on state
134 const getIconName = () => {
135 switch (props.state) {
136 case 'success':
137 case 'notes':
138 return 'check-circle'
139 case 'danger':
140 case 'warning':
141 return 'danger'
142 case 'upcoming':
143 return 'upcoming-soon-colored'
144 case 'pro':
145 return 'bolt-lightning'
146 default:
147 return 'info'
148 }
149 }
150
151 const getButtonPriority = () => {
152 switch (props.state) {
153 case 'success':
154 case 'notes':
155 return 'primary'
156 case 'danger':
157 return 'danger'
158 case 'warning':
159 return 'warning'
160 case 'upcoming':
161 case 'pro':
162 return 'secondary'
163 default:
164 return 'tertiary'
165 }
166 }
167 const getButtonType = () => {
168 switch (props.state) {
169 case 'default':
170 return 'border'
171 default:
172 return 'fill'
173 }
174 }
175
176 const getIconType = (): IconType => {
177 switch (props.state) {
178 case 'pro':
179 return 'fill'
180 case 'upcoming':
181 return isDark() ? 'outline' : 'fill'
182 default:
183 return 'fill-duo'
184 }
185 }
186
187 const getIconCategory = (): IconCategory => {
188 switch (props.state) {
189 case 'upcoming':
190 return 'promotion'
191 default:
192 return 'global'
193 }
194 }
195
196 const getIconColor = () => {
197 switch (props.state) {
198 case 'success':
199 return 'var(--map-status-success-symbol-0)'
200 case 'danger':
201 return 'var(--map-status-error-symbol-0)'
202 case 'warning':
203 return 'var(--map-status-warning-symbol-0)'
204 case 'upcoming':
205 return 'var(--map-base-purple-symbol-0)'
206 case 'pro':
207 return 'var(--map-accent-amber-symbol-0)'
208 case 'notes':
209 return 'var(--map-status-success-symbol-0)'
210 default:
211 return 'var(--map-base-dusk-symbol-0)'
212 }
213 }
214
215 // Title icon logic
216 const getTitleIconName = () => getIconName()
217 const getTitleIconType = (): IconType => getIconType()
218 const getTitleIconCategory = (): IconCategory => getIconCategory()
219 const getTitleIconColor = () => getIconColor()
220
221 // Description icon logic
222 const getDescriptionIconName = () => getIconName()
223 const getDescriptionIconType = (): IconType => getIconType()
224 const getDescriptionIconCategory = (): IconCategory => getIconCategory()
225 const getDescriptionIconColor = () => getIconColor()
226
227 // Event handlers
228 const handleButtonClick = () => {
229 emit('buttonClick')
230 }
231 </script>
232
233 <style lang="scss">
234 @use 'sass:map';
235 .ivyforms-notification {
236 border-radius: var(--Radius-radius-md, 8px);
237 position: relative;
238 transition: all 0.2s ease-in-out;
239 flex-direction: row;
240
241 &--style-fill {
242 border: none;
243 box-shadow: none;
244 }
245
246 &--style-stripe {
247 border-left: 2px solid;
248 box-shadow: none;
249 }
250
251 &__content {
252 min-width: 0;
253 }
254
255 &__title,
256 &__description {
257 align-items: center;
258
259 &-icon {
260 flex-shrink: 0;
261 }
262 }
263 &__license-banner {
264 justify-content: center;
265 .ivyforms-notification__content {
266 flex: none !important;
267 }
268 .ivyforms-notification__description {
269 align-items: center !important;
270 }
271 }
272
273 // --- State color definitions ---
274 $notification-states: (
275 default: (
276 bg: var(--map-base-dusk-o10),
277 border: var(--map-base-dusk-stroke-0),
278 text: var(--map-base-text-0),
279 ),
280 success: (
281 bg: var(--map-status-success-o10),
282 border: var(--map-status-success-stroke-0),
283 text: var(--map-status-success-symbol-0),
284 ),
285 danger: (
286 bg: var(--map-status-error-o10),
287 border: var(--map-status-error-stroke-0),
288 text: var(--map-status-error-symbol-0),
289 ),
290 warning: (
291 bg: var(--map-status-warning-o10),
292 border: var(--map-status-warning-stroke-0),
293 text: var(--map-status-warning-symbol-0),
294 ),
295 upcoming: (
296 bg: var(--map-accent-maroon-o10),
297 border: var(--map-accent-maroon-stroke-0),
298 text: var(--map-accent-maroon-fill-0),
299 ),
300 pro: (
301 bg: var(--map-accent-amber-o10),
302 border: var(--map-accent-amber-symbol-0),
303 text: var(--map-accent-amber-symbol-0),
304 ),
305 notes: (
306 bg: var(--map-status-success-o10),
307 border: var(--map-status-success-stroke-0),
308 text: var(--map-status-success-symbol-0),
309 ),
310 );
311
312 // --- Loop through states ---
313 @each $name, $colors in $notification-states {
314 &--state-#{$name} {
315 background-color: map.get($colors, bg);
316 border-left-color: map.get($colors, border);
317
318 .ivyforms-notification__title-text,
319 .ivyforms-notification__description-text,
320 .ivyforms-notification__description-text__link {
321 color: map.get($colors, text);
322 }
323 }
324 }
325 }
326 </style>
327