File tree Expand file tree Collapse file tree 7 files changed +114
-5
lines changed Expand file tree Collapse file tree 7 files changed +114
-5
lines changed Original file line number Diff line number Diff line change @@ -54,6 +54,32 @@ context('Notyf', () => {
54
54
expect ( pos . top ) . to . be . greaterThan ( VIEWPORT_HEIGHT / 2 ) ;
55
55
} ) ;
56
56
} ) ;
57
+
58
+ it ( 'should pause on mouseover' , ( ) => {
59
+
60
+ setConfiguration ( { message : 'Notyf 1' } )
61
+ cy . get ( '#success-btn' ) . click ( )
62
+
63
+ setConfiguration ( { message : 'Notyf 2' } )
64
+ cy . get ( '#success-btn' ) . click ( )
65
+
66
+ setConfiguration ( { message : 'Notyf 3' } )
67
+ cy . get ( '#success-btn' ) . click ( )
68
+
69
+ cy . get ( '.notyf__toast:nth-child(2)' ) . trigger ( 'mouseover' )
70
+
71
+ cy . wait ( 2000 )
72
+
73
+ cy . get ( '.notyf' ) . children ( ) . should ( 'have.length' , 1 )
74
+
75
+ cy . get ( '.notyf__toast' ) . trigger ( 'mouseleave' )
76
+
77
+ cy . wait ( 2000 )
78
+
79
+ cy . get ( '.notyf__toast' ) . should ( 'not.be.exist' )
80
+
81
+ } )
82
+
57
83
} ) ;
58
84
59
85
describe ( 'Global custom configuration' , ( ) => {
Original file line number Diff line number Diff line change @@ -17,7 +17,7 @@ export class NotyfNotification {
17
17
this . listeners [ eventType ] = callbacks . concat ( [ cb ] ) ;
18
18
}
19
19
20
- private triggerEvent ( eventType : NotyfEvent , event ?: Event ) {
20
+ triggerEvent ( eventType : NotyfEvent , event ?: Event ) {
21
21
const callbacks = this . listeners [ eventType ] || [ ] ;
22
22
callbacks . forEach ( ( cb ) => cb ( { target : this , event } ) ) ;
23
23
}
Original file line number Diff line number Diff line change @@ -11,6 +11,8 @@ export interface INotyfPosition {
11
11
export enum NotyfEvent {
12
12
Dismiss = 'dismiss' ,
13
13
Click = 'click' ,
14
+ MouseOver = 'mouseover' ,
15
+ MouseLeave = 'mouseleave'
14
16
}
15
17
16
18
export interface INotyfIcon {
Original file line number Diff line number Diff line change 7
7
NotyfEvent ,
8
8
} from './notyf.options' ;
9
9
import { NotyfView } from './notyf.view' ;
10
+ import Timer from './utils/classes/timer' ;
10
11
11
12
/**
12
13
* Main controller class. Defines the main Notyf API.
@@ -82,12 +83,22 @@ export default class Notyf {
82
83
}
83
84
84
85
private _pushNotification ( notification : NotyfNotification ) {
85
- this . notifications . push ( notification ) ;
86
+
87
+ this . notifications . push ( notification ) ;
88
+
86
89
const duration =
87
90
notification . options . duration !== undefined ? notification . options . duration : this . options . duration ;
88
- if ( duration ) {
89
- setTimeout ( ( ) => this . _removeNotification ( notification ) , duration ) ;
90
- }
91
+
92
+ if ( ! duration ) return
93
+
94
+ const timer = new Timer ( duration ) ;
95
+
96
+ notification . on ( NotyfEvent . MouseOver , ( ) => timer . pause ( ) ) ;
97
+
98
+ notification . on ( NotyfEvent . MouseLeave , ( ) => timer . resume ( ) ) ;
99
+
100
+ timer . on ( 'finished' , ( ) => this . _removeNotification ( notification ) )
101
+
91
102
}
92
103
93
104
private _removeNotification ( notification : NotyfNotification ) {
Original file line number Diff line number Diff line change @@ -196,6 +196,14 @@ export class NotyfView {
196
196
this . events [ NotyfEvent . Click ] ?.( { target : notification , event } ) ,
197
197
) ;
198
198
199
+ notificationElem . addEventListener ( 'mouseover' , event =>
200
+ notification . triggerEvent ( NotyfEvent . MouseOver , event )
201
+ )
202
+
203
+ notificationElem . addEventListener ( 'mouseleave' , event =>
204
+ notification . triggerEvent ( NotyfEvent . MouseLeave , event )
205
+ )
206
+
199
207
// Adjust margins depending on whether its an upper or lower notification
200
208
const className = this . getYPosition ( options ) === 'top' ? 'upper' : 'lower' ;
201
209
notificationElem . classList . add ( `notyf__toast--${ className } ` ) ;
Original file line number Diff line number Diff line change
1
+ type EventCallback = ( event : any ) => void ;
2
+
3
+ export default class EventeListener {
4
+ protected listeners : Partial < Record < string , EventCallback [ ] > > = { } ;
5
+
6
+ constructor ( ) { }
7
+
8
+ public on ( eventType : string , cb : EventCallback ) {
9
+ const callbacks = this . listeners [ eventType ] || [ ] ;
10
+ this . listeners [ eventType ] = callbacks . concat ( [ cb ] ) ;
11
+ }
12
+
13
+ protected triggerEvent ( eventType : string , event ?: any ) {
14
+ const callbacks = this . listeners [ eventType ] || [ ] ;
15
+ callbacks . forEach ( ( callback : EventCallback ) => callback ( event ) ) ;
16
+ }
17
+ }
Original file line number Diff line number Diff line change
1
+ import EventListener from './eventListener' ;
2
+
3
+ export default class Timer extends EventListener {
4
+
5
+ private startTime : number = Date . now ( ) ;
6
+
7
+ private timer : ReturnType < typeof setTimeout > ;
8
+
9
+ private lastTime : number = Date . now ( ) ;
10
+
11
+ get leftTime ( ) {
12
+ return this . duration - ( this . lastTime - this . startTime ) ;
13
+ }
14
+
15
+ constructor ( public duration : number ) {
16
+ super ( ) ;
17
+
18
+ this . timer = setTimeout ( ( ) => {
19
+ this . triggerEvent ( 'finished' ) ;
20
+
21
+ this . lastTime = Date . now ( ) ;
22
+ } , duration ) ;
23
+ }
24
+
25
+ pause ( ) {
26
+ this . triggerEvent ( 'pause' ) ;
27
+
28
+ clearTimeout ( this . timer ) ;
29
+
30
+ this . lastTime = Date . now ( ) ;
31
+ }
32
+
33
+ resume ( ) {
34
+ this . triggerEvent ( 'resume' ) ;
35
+
36
+ clearTimeout ( this . timer ) ;
37
+
38
+ this . timer = setTimeout ( ( ) => {
39
+ this . triggerEvent ( 'finished' ) ;
40
+
41
+ this . lastTime = Date . now ( ) ;
42
+ } , this . leftTime ) ;
43
+ }
44
+
45
+ }
You can’t perform that action at this time.
0 commit comments