Skip to content

Commit 1fcbf96

Browse files
njfamirmarashagp
andcommitted
refactor(snackbar): separation files and remove function action button handler params
Co-authored-by: arashagp <[email protected]>
1 parent 395bd9c commit 1fcbf96

File tree

3 files changed

+79
-64
lines changed

3 files changed

+79
-64
lines changed

packages/snackbar/src/lib/handler.ts

+21-64
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,21 @@
1-
import {AlwatrSignal, AlwatrTrigger} from '@alwatr/flux';
21
import {createLogger} from '@alwatr/logger';
3-
import {parseDuration, type Duration} from '@alwatr/parse-duration';
2+
import {parseDuration} from '@alwatr/parse-duration';
43
import {waitForTimeout} from '@alwatr/wait';
54

6-
import type {SnackbarComponent} from './element.js';
5+
import {snackbarActionButtonClickedSignal, snackbarSignal} from './signal.js';
76

8-
const logger = createLogger(`${__package_name__}/handler`);
7+
import type {SnackbarOptions} from './type.js';
98

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`);
2710

2811
/**
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.
3913
*/
40-
export const snackbarActionButtonClickedSignal = new AlwatrTrigger({
41-
name: 'snackbar-action-button-clicked',
42-
});
14+
let closeLastSnackbar: (() => Promise<void>) | null = null;
4315

4416
/**
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.
6118
*/
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;
7019
let unsubscribeActionButtonHandler: (() => void) | null = null;
7120

7221
/**
@@ -80,7 +29,7 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
8029
// Set default duration if not provided
8130
options.duration ??= '5s';
8231

83-
const element = document.createElement('snack-bar') as SnackbarComponent;
32+
const element = document.createElement('snack-bar');
8433

8534
element.setAttribute('content', options.content);
8635

@@ -91,13 +40,16 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
9140
if (options.action != null) {
9241
element.setAttribute('action-button-label', options.action.label);
9342

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);
9946

10047
return closeSnackbar();
48+
};
49+
50+
// Subscribe to the action button click
51+
unsubscribeActionButtonHandler = snackbarActionButtonClickedSignal.subscribe(actionButtonClickHandler.bind(null), {
52+
once: true,
10153
}).unsubscribe;
10254
}
10355

@@ -121,3 +73,8 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
12173
waitForTimeout(parseDuration(options.duration)).then(closeSnackbar);
12274
}
12375
}
76+
77+
// Subscribe to the snackbar signal to show the snackbar when the signal is emitted.
78+
snackbarSignal.subscribe((options) => {
79+
showSnackbar(options);
80+
});

packages/snackbar/src/lib/signal.ts

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {AlwatrSignal} from '@alwatr/flux';
2+
3+
import type {SnackbarOptions} from './type.js';
4+
5+
/**
6+
* Signal triggered when the snackbar action button is clicked.
7+
*
8+
* This signal is used to notify listeners that the action button
9+
* on the snackbar component has been clicked. It can be used to
10+
* perform any necessary actions in response to the button click.
11+
*
12+
* @example
13+
* snackbarActionButtonClickedSignal.addListener(() => {
14+
* console.log('Snackbar action button was clicked!');
15+
* });
16+
*/
17+
export const snackbarActionButtonClickedSignal = /* @__PURE__ */ new AlwatrSignal<{id: string}>({
18+
name: 'snackbar-action-button-clicked',
19+
});
20+
21+
/**
22+
* Signal for displaying the snackbar.
23+
*
24+
* @example
25+
* import {snackbarSignal} from '@nexim/snackbar';
26+
*
27+
* snackbarSignal.notify({
28+
* content: 'This is a snackbar message',
29+
* action: {
30+
* label: 'Undo',
31+
* handler: () => {
32+
* console.log('Action button clicked');
33+
* },
34+
* },
35+
* duration: '5s',
36+
* addCloseButton: true,
37+
* });
38+
*/
39+
export const snackbarSignal = /* @__PURE__ */ new AlwatrSignal<SnackbarOptions>({name: 'snackbar'});

packages/snackbar/src/lib/type.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type {Duration} from '@alwatr/parse-duration';
2+
3+
/**
4+
* @property content - Content to be displayed in the snackbar.
5+
* @property [action] - The action button configuration.
6+
* @property action.label - The label for the action button.
7+
* @property action.handler - The handler function for the action button.
8+
* @property duration - Duration for which the snackbar is displayed. `infinite` for infinite duration.
9+
* @property addCloseButton - Whether to add a close button to the snackbar.
10+
*/
11+
export type SnackbarOptions = {
12+
content: string;
13+
action?: {
14+
id: string;
15+
label: string;
16+
};
17+
duration?: Duration | 'infinite';
18+
addCloseButton?: boolean;
19+
};

0 commit comments

Comments
 (0)