1
+ const typeOrder = [ 'error' , 'warning' , 'success' , 'info' ]
2
+
3
+ /**
4
+ * Helper function to determine the order index of a notification type.
5
+ * @param {HTMLElement } notification - The notification element.
6
+ * @returns {number } - Order index of the notification type.
7
+ */
8
+ const getTypeOrderIndex = ( notification ) => {
9
+ const type = getTypeFromNotification ( notification )
10
+ return typeOrder . indexOf ( type )
11
+ }
12
+
13
+ /**
14
+ * Helper function to get the type of a notification.
15
+ * @param {HTMLElement } notification - The notification element.
16
+ * @returns {string } - Type of the notification.
17
+ */
18
+ const getTypeFromNotification = ( notification ) => {
19
+ let notificationType = ''
20
+ notification . classList . forEach ( ( cls ) => {
21
+ if ( cls . startsWith ( 'notification--' ) ) {
22
+ notificationType = cls . replace ( 'notification--' , '' )
23
+ }
24
+ } )
25
+ return notificationType
26
+ }
27
+
1
28
/**
2
- * Notification class.
29
+ * Single Notification class.
3
30
* @class
4
31
*/
5
32
export class Notification {
@@ -14,6 +41,7 @@ export class Notification {
14
41
this . node = node
15
42
16
43
this . bindEvents ( )
44
+ this . reorderNotifications ( )
17
45
}
18
46
19
47
/**
@@ -28,18 +56,23 @@ export class Notification {
28
56
* Scrolls to the notification content and sets focus.
29
57
*/
30
58
scrollToNotification ( ) {
31
- const notificationContent = this . node . querySelector (
32
- '.notification__content'
59
+ const notificationContents = Array . from (
60
+ this . node . querySelectorAll ( '.notification__content' )
33
61
)
34
62
35
- if ( notificationContent ) {
36
- // If errors are present, scroll and trigger the opened state
37
- notificationContent . scrollIntoView ( {
38
- block : 'center' ,
39
- behavior : 'smooth' ,
63
+ if ( notificationContents ) {
64
+ notificationContents . forEach ( ( content ) => {
65
+ // If errors are present, scroll and trigger the opened state
66
+ content . scrollIntoView ( {
67
+ block : 'center' ,
68
+ behavior : 'smooth' ,
69
+ } )
70
+
71
+ // Add a pause before setting focus for screen readers after DOM load
72
+ setTimeout ( ( ) => {
73
+ content . focus ( )
74
+ } , 100 )
40
75
} )
41
- // Set focus for screen readers
42
- notificationContent . focus ( )
43
76
}
44
77
}
45
78
@@ -51,8 +84,6 @@ export class Notification {
51
84
e . preventDefault ( )
52
85
this . close ( )
53
86
} )
54
-
55
- this . scrollToNotification ( )
56
87
}
57
88
58
89
/**
@@ -61,6 +92,29 @@ export class Notification {
61
92
close ( ) {
62
93
this . node . parentElement . removeChild ( this . node )
63
94
}
95
+
96
+ /**
97
+ * Reorders notifications based on type.
98
+ */
99
+ reorderNotifications ( ) {
100
+ // Get all notifications in the parent container
101
+ const notificationsContainer = document . querySelector ( '.notifications' )
102
+ const notifications = Array . from (
103
+ notificationsContainer . querySelectorAll ( Notification . selector )
104
+ )
105
+
106
+ // Sort notifications based on type order
107
+ notifications . sort ( ( a , b ) => {
108
+ const typeA = getTypeOrderIndex ( a )
109
+ const typeB = getTypeOrderIndex ( b )
110
+ return typeA - typeB
111
+ } )
112
+
113
+ // Re-append sorted notifications to parent container
114
+ notifications . forEach ( ( notification ) =>
115
+ notificationsContainer . appendChild ( notification )
116
+ )
117
+ }
64
118
}
65
119
66
120
// Start!
@@ -69,3 +123,12 @@ export class Notification {
69
123
document
70
124
. querySelectorAll ( Notification . selector )
71
125
. forEach ( ( notification ) => new Notification ( notification ) )
126
+
127
+ // Scroll to the notifications after reordering
128
+ setTimeout ( ( ) => {
129
+ const firstNotification = document . querySelector ( Notification . selector )
130
+ if ( firstNotification ) {
131
+ const instance = new Notification ( firstNotification )
132
+ instance . scrollToNotification ( )
133
+ }
134
+ } , 0 )
0 commit comments