-
-
Notifications
You must be signed in to change notification settings - Fork 78.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement Stacked Notifications with Auto and Manual Dismissal
- Added StackedNotificationManager class to handle creation, management, and dismissal of stacked notifications. - Notifications are displayed in a stack format with the newest at the top. - Added automatic dismissal feature with customizable timeouts. - Added manual dismissal option via a close button. - Included functionality to clear all active notifications at once.
- Loading branch information
1 parent
12a7a6d
commit 184f4c7
Showing
3 changed files
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
export class StackedNotificationManager { | ||
constructor() { | ||
this.notifications = []; | ||
this.container = this._createStackedNotificationContainer(); | ||
} | ||
|
||
_createStackedNotificationContainer() { | ||
const container = document.createElement('div'); | ||
container.className = 'stacked-notification-container'; | ||
document.body.appendChild(container); | ||
return container; | ||
} | ||
|
||
createStackedNotification(type, message, autoDismiss = true, dismissTime = 3000) { | ||
const notification = document.createElement('div'); | ||
notification.className = `stacked-notification stacked-notification-${type}`; | ||
notification.innerText = message; | ||
|
||
const closeBtn = document.createElement('button'); | ||
closeBtn.className = 'close-btn'; | ||
closeBtn.innerHTML = '×'; | ||
closeBtn.onclick = () => this.removeStackedNotification(notification); | ||
|
||
notification.appendChild(closeBtn); | ||
this.container.appendChild(notification); | ||
|
||
this.notifications.push(notification); | ||
|
||
if (autoDismiss) { | ||
setTimeout(() => { | ||
if (notification.parentNode) { | ||
this.removeStackedNotification(notification); | ||
} | ||
}, dismissTime); | ||
} | ||
} | ||
|
||
|
||
removeStackedNotification(notification) { | ||
if (notification && notification.parentNode === this.container) { | ||
this.container.removeChild(notification); | ||
this.notifications = this.notifications.filter(n => n !== notification); | ||
} | ||
} | ||
|
||
|
||
clearAllStackedNotifications() { | ||
this.notifications.forEach(notification => this.removeStackedNotification(notification)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { StackedNotificationManager } from '../../src/stackedNotification'; | ||
|
||
describe('StackedNotificationManager', () => { | ||
let stackedNotificationManager; | ||
|
||
beforeEach(() => { | ||
stackedNotificationManager = new StackedNotificationManager(); | ||
}); | ||
|
||
afterEach(() => { | ||
stackedNotificationManager.clearAllStackedNotifications(); | ||
}); | ||
|
||
it('should create a stacked notification and add it to the DOM', () => { | ||
stackedNotificationManager.createStackedNotification('success', 'Success message'); | ||
const notifications = document.querySelectorAll('.stacked-notification'); | ||
expect(notifications.length).toBe(1); | ||
expect(notifications[0].classList.contains('stacked-notification-success')).toBe(true); | ||
expect(notifications[0].innerText.includes('Success message')).toBe(true); | ||
}); | ||
|
||
it('should automatically remove the stacked notification after a certain time', (done) => { | ||
stackedNotificationManager.createStackedNotification('error', 'Error message', true, 1000); | ||
setTimeout(() => { | ||
const notifications = document.querySelectorAll('.stacked-notification'); | ||
expect(notifications.length).toBe(0); | ||
done(); | ||
}, 1500); | ||
}); | ||
|
||
it('should allow manual removal of stacked notifications', () => { | ||
stackedNotificationManager.createStackedNotification('warning', 'Warning message'); | ||
const notification = document.querySelector('.stacked-notification'); | ||
notification.querySelector('.close-btn').click(); | ||
const notifications = document.querySelectorAll('.stacked-notification'); | ||
expect(notifications.length).toBe(0); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
.stacked-notification-container { | ||
position: fixed; | ||
top: 20px; | ||
right: 20px; | ||
z-index: 1000; | ||
max-width: 300px; | ||
} | ||
|
||
.stacked-notification { | ||
background-color: #f0f0f0; | ||
border: 1px solid #ccc; | ||
padding: 10px; | ||
margin-bottom: 10px; | ||
border-radius: 5px; | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
|
||
&.stacked-notification-success { | ||
border-color: #28a745; | ||
background-color: #d4edda; | ||
} | ||
|
||
&.stacked-notification-error { | ||
border-color: #dc3545; | ||
background-color: #f8d7da; | ||
} | ||
|
||
&.stacked-notification-warning { | ||
border-color: #ffc107; | ||
background-color: #fff3cd; | ||
} | ||
} | ||
|
||
.close-btn { | ||
background: none; | ||
border: none; | ||
font-size: 16px; | ||
cursor: pointer; | ||
color: #000; | ||
} |