1
- import { AlwatrSignal , AlwatrTrigger } from '@alwatr/flux' ;
2
1
import { createLogger } from '@alwatr/logger' ;
3
- import { parseDuration , type Duration } from '@alwatr/parse-duration' ;
2
+ import { parseDuration } from '@alwatr/parse-duration' ;
4
3
import { waitForTimeout } from '@alwatr/wait' ;
5
4
6
- import type { SnackbarComponent } from './element .js' ;
5
+ import { snackbarActionButtonClickedSignal , snackbarSignal } from './signal .js' ;
7
6
8
- const logger = createLogger ( ` ${ __package_name__ } /handler` ) ;
7
+ import type { SnackbarOptions } from './type.js' ;
9
8
10
- /**
11
- * @property content - Content to be displayed in the snackbar.
12
- * @property [action] - The action button configuration.
13
- * @property action.label - The label for the action button.
14
- * @property action.handler - The handler function for the action button.
15
- * @property duration - Duration for which the snackbar is displayed. `infinite` for infinite duration.
16
- * @property addCloseButton - Whether to add a close button to the snackbar.
17
- */
18
- export type SnackbarOptions = {
19
- content : string ;
20
- action ?: {
21
- label : string ;
22
- handler : ( ) => void ;
23
- } ;
24
- duration ?: Duration ;
25
- addCloseButton ?: boolean ;
26
- } ;
9
+ const logger = createLogger ( `${ __package_name__ } /handler` ) ;
27
10
28
11
/**
29
- * Signal triggered when the snackbar action button is clicked.
30
- *
31
- * This signal is used to notify listeners that the action button
32
- * on the snackbar component has been clicked. It can be used to
33
- * perform any necessary actions in response to the button click.
34
- *
35
- * @example
36
- * snackbarActionButtonClickedSignal.addListener(() => {
37
- * console.log('Snackbar action button was clicked!');
38
- * });
12
+ * Store the function to close the last snackbar.
39
13
*/
40
- export const snackbarActionButtonClickedSignal = new AlwatrTrigger ( {
41
- name : 'snackbar-action-button-clicked' ,
42
- } ) ;
14
+ let closeLastSnackbar : ( ( ) => Promise < void > ) | null = null ;
43
15
44
16
/**
45
- * Signal for displaying the snackbar.
46
- *
47
- * @example
48
- * import {snackbarSignal} from '@nexim/snackbar';
49
- *
50
- * snackbarSignal.notify({
51
- * content: 'This is a snackbar message',
52
- * action: {
53
- * label: 'Undo',
54
- * handler: () => {
55
- * console.log('Action button clicked');
56
- * },
57
- * },
58
- * duration: '5s',
59
- * addCloseButton: true,
60
- * });
17
+ * Store the function to unsubscribe the action button handler after close or action button clicked.
61
18
*/
62
- export const snackbarSignal = new AlwatrSignal < SnackbarOptions > ( { name : 'snackbar' } ) ;
63
-
64
- // Subscribe to the snackbar signal to show the snackbar when the signal is emitted.
65
- snackbarSignal . subscribe ( ( options ) => {
66
- showSnackbar ( options ) ;
67
- } ) ;
68
-
69
- let closeLastSnackbar : ( ( ) => Promise < void > ) | null = null ;
70
19
let unsubscribeActionButtonHandler : ( ( ) => void ) | null = null ;
71
20
72
21
/**
@@ -80,7 +29,7 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
80
29
// Set default duration if not provided
81
30
options . duration ??= '5s' ;
82
31
83
- const element = document . createElement ( 'snack-bar' ) as SnackbarComponent ;
32
+ const element = document . createElement ( 'snack-bar' ) ;
84
33
85
34
element . setAttribute ( 'content' , options . content ) ;
86
35
@@ -91,13 +40,16 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
91
40
if ( options . action != null ) {
92
41
element . setAttribute ( 'action-button-label' , options . action . label ) ;
93
42
94
- // Subscribe to the action button click
95
- unsubscribeActionButtonHandler = snackbarActionButtonClickedSignal . subscribe ( ( ) => {
96
- logger . logOther ?.( 'Snackbar action button clicked.' ) ;
97
-
98
- options . action ! . handler ( ) ;
43
+ const actionButtonClickHandler = ( event : { id : string } ) => {
44
+ if ( event . id !== options . action ! . id ) return ;
45
+ logger . logOther ?.( 'Snackbar action button clicked.' , event ) ;
99
46
100
47
return closeSnackbar ( ) ;
48
+ } ;
49
+
50
+ // Subscribe to the action button click
51
+ unsubscribeActionButtonHandler = snackbarActionButtonClickedSignal . subscribe ( actionButtonClickHandler . bind ( null ) , {
52
+ once : true ,
101
53
} ) . unsubscribe ;
102
54
}
103
55
@@ -121,3 +73,8 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
121
73
waitForTimeout ( parseDuration ( options . duration ) ) . then ( closeSnackbar ) ;
122
74
}
123
75
}
76
+
77
+ // Subscribe to the snackbar signal to show the snackbar when the signal is emitted.
78
+ snackbarSignal . subscribe ( ( options ) => {
79
+ showSnackbar ( options ) ;
80
+ } ) ;
0 commit comments