@@ -14,6 +14,8 @@ export class App implements AppListener {
14
14
return App . instance ;
15
15
}
16
16
17
+ toast ( info : string ) : void { for ( const listener of this . app_listeners ) { listener . toast ( info ) ; } }
18
+
17
19
get_selected_component ( ) : Component < any , HTMLElement > | null { return this . selected_comp ; }
18
20
19
21
selected_component ( component : Component < any , HTMLElement > | null ) : void {
@@ -34,6 +36,8 @@ export class App implements AppListener {
34
36
35
37
export interface AppListener {
36
38
39
+ toast ( info : string ) : void ;
40
+
37
41
selected_component ( component : Component < any , HTMLElement > | null ) : void ;
38
42
}
39
43
@@ -140,9 +144,44 @@ export class AppComponent extends Component<App, HTMLDivElement> implements AppL
140
144
this . main . classList . add ( 'd-flex' , 'flex-column' , 'flex-grow-1' ) ;
141
145
fragment . appendChild ( this . main ) ;
142
146
147
+ // Add the toast container..
148
+ const toast_container = document . createElement ( 'div' ) ;
149
+ toast_container . classList . add ( 'toast-container' ) ;
150
+ fragment . appendChild ( toast_container ) ;
151
+
143
152
this . element . appendChild ( fragment ) ;
144
153
}
145
154
155
+ toast ( info : string ) : void {
156
+ const toast_container = this . element . querySelector ( '.toast-container' ) as HTMLDivElement ;
157
+ const toast = document . createElement ( 'div' ) ;
158
+ toast . classList . add ( 'toast' ) ;
159
+ toast . setAttribute ( 'role' , 'alert' ) ;
160
+ toast . setAttribute ( 'aria-live' , 'assertive' ) ;
161
+ toast . setAttribute ( 'aria-atomic' , 'true' ) ;
162
+ toast . setAttribute ( 'data-bs-autohide' , 'true' ) ;
163
+ toast . setAttribute ( 'data-bs-delay' , '5000' ) ;
164
+ const toast_header = document . createElement ( 'div' ) ;
165
+ toast_header . classList . add ( 'toast-header' ) ;
166
+ const toast_title = document . createElement ( 'strong' ) ;
167
+ toast_title . classList . add ( 'me-auto' ) ;
168
+ toast_title . innerText = 'Info' ;
169
+ toast_header . appendChild ( toast_title ) ;
170
+ const toast_button = document . createElement ( 'button' ) ;
171
+ toast_button . classList . add ( 'btn-close' ) ;
172
+ toast_button . setAttribute ( 'type' , 'button' ) ;
173
+ toast_button . setAttribute ( 'data-bs-dismiss' , 'toast' ) ;
174
+ toast_button . setAttribute ( 'aria-label' , 'Close' ) ;
175
+ toast_header . appendChild ( toast_button ) ;
176
+ toast . appendChild ( toast_header ) ;
177
+ const toast_body = document . createElement ( 'div' ) ;
178
+ toast_body . classList . add ( 'toast-body' ) ;
179
+ toast_body . innerText = info ;
180
+ toast . appendChild ( toast_body ) ;
181
+ toast_container . appendChild ( toast ) ;
182
+ setTimeout ( ( ) => toast . remove ( ) , 5000 ) ;
183
+ }
184
+
146
185
selected_component ( component : Component < any , HTMLElement > | null ) : void {
147
186
if ( component )
148
187
this . main . appendChild ( component . element ) ;
@@ -151,7 +190,7 @@ export class AppComponent extends Component<App, HTMLDivElement> implements AppL
151
190
connected ( info : any ) : void { }
152
191
received_message ( message : any ) : void { }
153
192
disconnected ( ) : void { }
154
- error ( error : any ) : void { }
193
+ connection_error ( error : any ) : void { }
155
194
156
195
populate_navbar ( container : HTMLDivElement ) : void { }
157
196
0 commit comments