Skip to content

Commit 99057ca

Browse files
njfamirmarashagp
andcommitted
refactor(snackbar): separation of concern
Co-authored-by: arashagp <[email protected]>
1 parent 1fcbf96 commit 99057ca

File tree

2 files changed

+46
-22
lines changed

2 files changed

+46
-22
lines changed

packages/snackbar/src/lib/element.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import {LightDomMixin, LoggerMixin} from '@nexim/element';
33
import {html, LitElement, nothing, type PropertyValues, type TemplateResult} from 'lit';
44
import {customElement, property} from 'lit/decorators.js';
55

6-
import {snackbarActionButtonClickedSignal} from './handler.js';
6+
import {snackbarActionButtonClickedSignal} from './signal.js';
77
import {waitForNextFrame} from './utils.js';
88

99
declare global {
1010
interface HTMLElementTagNameMap {
11-
'snack-bar': SnackbarComponent;
11+
'snack-bar': SnackbarElement;
1212
}
1313
}
1414

1515
@customElement('snack-bar')
16-
export class SnackbarComponent extends LightDomMixin(LoggerMixin(LitElement)) {
16+
export class SnackbarElement extends LightDomMixin(LoggerMixin(LitElement)) {
1717
/**
1818
* The content to be displayed inside the snackbar.
1919
*/
@@ -52,7 +52,7 @@ export class SnackbarComponent extends LightDomMixin(LoggerMixin(LitElement)) {
5252

5353
this.removeAttribute('open');
5454

55-
await waitForTimeout(SnackbarComponent.openAndCloseAnimationDuration__);
55+
await waitForTimeout(SnackbarElement.openAndCloseAnimationDuration__);
5656
this.remove();
5757
}
5858

packages/snackbar/src/lib/handler.ts

+42-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {waitForTimeout} from '@alwatr/wait';
44

55
import {snackbarActionButtonClickedSignal, snackbarSignal} from './signal.js';
66

7+
import type {SnackbarElement} from './element.js';
78
import type {SnackbarOptions} from './type.js';
89

910
const logger = createLogger(`${__package_name__}/handler`);
@@ -19,18 +20,13 @@ let closeLastSnackbar: (() => Promise<void>) | null = null;
1920
let unsubscribeActionButtonHandler: (() => void) | null = null;
2021

2122
/**
22-
* Displays the snackbar with the given options.
23+
* Create snackbar element with given options.
2324
*
2425
* @param options - Options for configuring the snackbar.
26+
* @returns The created snackbar element.
2527
*/
26-
async function showSnackbar(options: SnackbarOptions): Promise<void> {
27-
logger.logMethodArgs?.('showSnackbar', {options});
28-
29-
// Set default duration if not provided
30-
options.duration ??= '5s';
31-
28+
function createSnackbarElement(options: SnackbarOptions): SnackbarElement {
3229
const element = document.createElement('snack-bar');
33-
3430
element.setAttribute('content', options.content);
3531

3632
if (options.addCloseButton === true) {
@@ -39,19 +35,43 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
3935

4036
if (options.action != null) {
4137
element.setAttribute('action-button-label', options.action.label);
38+
}
4239

43-
const actionButtonClickHandler = (event: {id: string}) => {
44-
if (event.id !== options.action!.id) return;
45-
logger.logOther?.('Snackbar action button clicked.', event);
40+
return element;
41+
}
4642

47-
return closeSnackbar();
48-
};
43+
/**
44+
* Handle action button click.
45+
*
46+
* @param options - Options for configuring the snackbar.
47+
* @param closeSnackbar - Function to close the snackbar.
48+
*/
49+
function handleActionButtonClick(options: SnackbarOptions, closeSnackbar: () => Promise<void>): void {
50+
const actionButtonClickHandler = (event: {id: string}) => {
51+
if (event.id !== options.action!.id) return;
52+
logger.logOther?.('Snackbar action button clicked.', event);
4953

50-
// Subscribe to the action button click
51-
unsubscribeActionButtonHandler = snackbarActionButtonClickedSignal.subscribe(actionButtonClickHandler.bind(null), {
52-
once: true,
53-
}).unsubscribe;
54-
}
54+
return closeSnackbar();
55+
};
56+
57+
// Subscribe to the action button click
58+
unsubscribeActionButtonHandler = snackbarActionButtonClickedSignal.subscribe(actionButtonClickHandler.bind(null), {
59+
once: true,
60+
}).unsubscribe;
61+
}
62+
63+
/**
64+
* Displays the snackbar with the given options.
65+
*
66+
* @param options - Options for configuring the snackbar.
67+
*/
68+
async function showSnackbar(options: SnackbarOptions): Promise<void> {
69+
logger.logMethodArgs?.('showSnackbar', {options});
70+
71+
// Set default duration if not provided
72+
options.duration ??= '5s';
73+
74+
const element = createSnackbarElement(options);
5575

5676
let closed = false;
5777
const closeSnackbar = async () => {
@@ -63,6 +83,10 @@ async function showSnackbar(options: SnackbarOptions): Promise<void> {
6383
closed = true;
6484
};
6585

86+
if (options.action != null) {
87+
handleActionButtonClick(options, closeSnackbar);
88+
}
89+
6690
// Close the last snackbar if it exists
6791
await closeLastSnackbar?.();
6892
closeLastSnackbar = closeSnackbar;

0 commit comments

Comments
 (0)