@@ -120,10 +120,11 @@ function getOrCreateToastContainer() {
120120 return container ;
121121}
122122
123- // Create the toast element and show it in the toast container
123+ // Set the toast element's properties
124124function createToast ( alertState ) {
125125 const toast = document . createElement ( "div" ) ;
126126 toast . className = "toast align-items-center border-0 shadow rounded overflow-hidden" ;
127+ toast . className += ` ${ alertState . bgColor } ` ;
127128 toast . dataset . toastType = alertState . type ;
128129 toast . dataset . bsAutohide = String ( alertState . autohide ) ;
129130 toast . dataset . bsDelay = String ( alertState . delay ) ;
@@ -132,51 +133,42 @@ function createToast(alertState) {
132133 toast . setAttribute ( "aria-atomic" , alertState . ariaAtomic ) ;
133134
134135 const content = document . createElement ( "div" ) ;
135- content . className = `toast-content ${ alertState . className } ` ;
136+ content . className = "d-flex flex-column" ;
137+ const header = document . createElement ( "div" ) ;
138+ header . className = `toast-header ${ alertState . bgColor } ` ;
136139
137- const layout = document . createElement ( "div" ) ;
138- layout . className = "d-flex align-items-start p-3" ;
139-
140- const body = document . createElement ( "div" ) ;
141- body . className = "d-flex flex-grow-1 gap-2" ;
142-
143- // Add icon if it is not empty
144140 if ( alertState . icon !== "" ) {
145141 const icon = document . createElement ( "i" ) ;
146- icon . className = `${ alertState . icon } mt-1` ;
142+ icon . className = `${ alertState . icon } me-2 mt-1` ;
147143 icon . setAttribute ( "aria-hidden" , "true" ) ;
148- body . append ( icon ) ;
144+ header . append ( icon ) ;
149145 }
150146
151- const text = document . createElement ( "div" ) ;
152- text . className = "toast-text flex-grow-1" ;
153-
154- // Add title and message to the toast
155147 const title = document . createElement ( "strong" ) ;
156- title . className = "d-block " ;
148+ title . className = "me-auto " ;
157149 // Title is already escaped in showAlert() function, so we can safely set it as innerHTML
158150 title . innerHTML = alertState . title ;
159151
160- const message = document . createElement ( "div" ) ;
161- message . className = "toast-message" ;
162- message . style . whiteSpace = "pre-line" ;
163- message . style . overflowWrap = "anywhere" ;
164- // Title is already escaped in showAlert() function, so we can safely set it as innerHTML
165- message . innerHTML = alertState . message ;
166-
167- text . append ( title , message ) ;
168- body . append ( text ) ;
169- layout . append ( body ) ;
170-
171- // Add close button to the toast
172152 const closeButton = document . createElement ( "button" ) ;
173153 closeButton . type = "button" ;
174- closeButton . className = `${ alertState . closeButtonClass } ms-2 mt-1 ` ;
154+ closeButton . className = `${ alertState . closeButtonClass } ms-2 mb-auto ` ;
175155 closeButton . dataset . bsDismiss = "toast" ;
176156 closeButton . setAttribute ( "aria-label" , "Close" ) ;
177- layout . append ( closeButton ) ;
178157
179- content . append ( layout ) ;
158+ header . append ( title , closeButton ) ;
159+
160+ const body = document . createElement ( "div" ) ;
161+ body . className = "toast-body" ;
162+
163+ const message = document . createElement ( "div" ) ;
164+ message . className = "toast-message flex-grow-1" ;
165+ message . style . whiteSpace = "pre-line" ;
166+ message . style . overflowWrap = "anywhere" ;
167+ // Message is already escaped in showAlert() function, so we can safely set it as innerHTML
168+ message . innerHTML = alertState . message ;
169+
170+ body . append ( message ) ;
171+ content . append ( header , body ) ;
180172 toast . append ( content ) ;
181173
182174 return toast ;
@@ -189,7 +181,7 @@ function showAlert(type, icon, title, message) {
189181 message : escapeHtml ( message ) ,
190182 icon,
191183 type,
192- className : "" ,
184+ bgColor : "" ,
193185 animation : true ,
194186 delay : 5000 , // default value
195187 autohide : true ,
@@ -202,16 +194,16 @@ function showAlert(type, icon, title, message) {
202194 switch ( type ) {
203195 case "info" :
204196 alertState . icon = icon !== null && icon . length > 0 ? icon : "fas fa-clock" ;
205- alertState . className = "text-bg-info" ;
197+ alertState . bgColor = "text-bg-info" ;
206198 break ;
207199 case "success" :
208- alertState . className = "text-bg-success" ;
200+ alertState . bgColor = "text-bg-success" ;
209201 alertState . closeButtonClass += " btn-close-white" ;
210202 break ;
211203 case "warning" :
212204 alertState . icon = "fas fa-exclamation-triangle" ;
213205 alertState . delay *= 2 ;
214- alertState . className = "text-bg-warning" ;
206+ alertState . bgColor = "text-bg-warning" ;
215207 break ;
216208 case "error" :
217209 alertState . icon = "fas fa-times" ;
@@ -220,7 +212,7 @@ function showAlert(type, icon, title, message) {
220212 }
221213
222214 alertState . delay *= 2 ;
223- alertState . className = "text-bg-danger" ;
215+ alertState . bgColor = "text-bg-danger" ;
224216 alertState . role = "alert" ;
225217 alertState . live = "assertive" ;
226218 alertState . closeButtonClass += " btn-close-white" ;
@@ -248,15 +240,22 @@ function showAlert(type, icon, title, message) {
248240 return ;
249241 }
250242
243+ // Get or create the toast container and create a new toast element
251244 const container = getOrCreateToastContainer ( ) ;
252245 const toastElement = createToast ( alertState ) ;
253- const toastInstance = new bootstrap . Toast ( toastElement ) ;
254-
255- toastElement . addEventListener ( "hidden.bs.toast" , ( ) => {
256- toastElement . remove ( ) ;
257- toastInstance . dispose ( ) ;
258- } ) ;
246+ const toastInstance = bootstrap . Toast . getOrCreateInstance ( toastElement ) ;
247+
248+ // Remove the toast element from the DOM when it is hidden, and dispose of the Bootstrap toast instance to free up resources
249+ toastElement . addEventListener (
250+ "hidden.bs.toast" ,
251+ ( ) => {
252+ toastElement . remove ( ) ;
253+ toastInstance . dispose ( ) ;
254+ } ,
255+ { once : true }
256+ ) ;
259257
258+ // Prepend the toast element to the container so that new toasts appear at the top
260259 container . prepend ( toastElement ) ;
261260 toastInstance . show ( ) ;
262261 return toastInstance ;
0 commit comments