1
1
import BButtonClose from '../button/button-close'
2
2
import { getComponentConfig } from '../../utils/config'
3
+ import { requestAF } from '../../utils/dom'
3
4
4
5
const NAME = 'BAlert'
5
6
@@ -36,62 +37,58 @@ export default {
36
37
data ( ) {
37
38
return {
38
39
countDownTimerId : null ,
39
- dismissed : false
40
- }
41
- } ,
42
- computed : {
43
- classObject ( ) {
44
- return [ 'alert' , this . alertVariant , this . dismissible ? 'alert-dismissible' : '' ]
45
- } ,
46
- alertVariant ( ) {
47
- const variant = this . variant
48
- return `alert-${ variant } `
49
- } ,
50
- localShow ( ) {
51
- return ! this . dismissed && ( this . countDownTimerId || this . show )
40
+ dismissed : false ,
41
+ localShow : this . show ,
42
+ showClass : this . fade && this . show
52
43
}
53
44
} ,
54
45
watch : {
55
- show ( ) {
56
- this . showChanged ( )
46
+ show ( newVal ) {
47
+ this . showChanged ( newVal )
48
+ } ,
49
+ dismissed ( newVal ) {
50
+ if ( newVal ) {
51
+ this . localShow = false
52
+ this . $emit ( 'dismissed' )
53
+ }
57
54
}
58
55
} ,
59
56
mounted ( ) {
60
- this . showChanged ( )
57
+ this . showChanged ( this . show )
61
58
} ,
62
59
destroyed /* istanbul ignore next */ ( ) {
63
60
this . clearCounter ( )
64
61
} ,
65
62
methods : {
66
63
dismiss ( ) {
67
64
this . clearCounter ( )
68
- this . dismissed = true
69
- this . $emit ( 'dismissed' )
70
- this . $emit ( 'input' , false )
71
65
if ( typeof this . show === 'number' ) {
72
66
this . $emit ( 'dismiss-count-down' , 0 )
73
67
this . $emit ( 'input' , 0 )
74
68
} else {
75
69
this . $emit ( 'input' , false )
76
70
}
71
+ this . dismissed = true
77
72
} ,
78
73
clearCounter ( ) {
79
74
if ( this . countDownTimerId ) {
80
75
clearInterval ( this . countDownTimerId )
81
76
this . countDownTimerId = null
82
77
}
83
78
} ,
84
- showChanged ( ) {
79
+ showChanged ( show ) {
85
80
// Reset counter status
86
81
this . clearCounter ( )
87
82
// Reset dismiss status
88
83
this . dismissed = false
84
+ // Set localShow state
85
+ this . localShow = Boolean ( show )
89
86
// No timer for boolean values
90
- if ( this . show === true || this . show === false || this . show === null || this . show === 0 ) {
87
+ if ( show === true || show === false || show === null || show === 0 ) {
91
88
return
92
89
}
93
90
// Start counter (ensure we have an integer value)
94
- let dismissCountDown = parseInt ( this . show , 10 ) || 1
91
+ let dismissCountDown = parseInt ( show , 10 ) || 1
95
92
this . countDownTimerId = setInterval ( ( ) => {
96
93
if ( dismissCountDown < 1 ) {
97
94
this . dismiss ( )
@@ -101,30 +98,66 @@ export default {
101
98
this . $emit ( 'dismiss-count-down' , dismissCountDown )
102
99
this . $emit ( 'input' , dismissCountDown )
103
100
} , 1000 )
101
+ } ,
102
+ onBeforeEnter ( ) {
103
+ if ( this . fade ) {
104
+ // Add show class one frame after inserted, to make transitions work
105
+ requestAF ( ( ) => {
106
+ this . showClass = true
107
+ } )
108
+ }
109
+ } ,
110
+ onBeforeLeave ( ) /* istanbul ignore next: does not appear to be called in vue-test-utils */ {
111
+ this . showClass = false
104
112
}
105
113
} ,
106
114
render ( h ) {
107
- if ( ! this . localShow ) {
108
- // If not showing, render placeholder
109
- return h ( false )
110
- }
111
- let dismissBtn = h ( false )
112
- if ( this . dismissible ) {
113
- // Add dismiss button
114
- dismissBtn = h (
115
- 'b-button-close' ,
116
- { attrs : { 'aria-label' : this . dismissLabel } , on : { click : this . dismiss } } ,
117
- [ this . $slots . dismiss ]
115
+ const $slots = this . $slots
116
+ let $alert = h ( false )
117
+ if ( this . localShow ) {
118
+ let $dismissBtn = h ( false )
119
+ if ( this . dismissible ) {
120
+ $dismissBtn = h (
121
+ 'b-button-close' ,
122
+ { attrs : { 'aria-label' : this . dismissLabel } , on : { click : this . dismiss } } ,
123
+ [ $slots . dismiss ]
124
+ )
125
+ }
126
+ $alert = h (
127
+ 'div' ,
128
+ {
129
+ staticClass : 'alert' ,
130
+ class : {
131
+ fade : this . fade ,
132
+ show : this . showClass ,
133
+ 'alert-dismissible' : this . dismissible ,
134
+ [ `alert-${ this . variant } ` ] : this . variant
135
+ } ,
136
+ attrs : { role : 'alert' , 'aria-live' : 'polite' , 'aria-atomic' : true }
137
+ } ,
138
+ [ $dismissBtn , $slots . default ]
118
139
)
140
+ $alert = [ $alert ]
119
141
}
120
- const alert = h (
121
- 'div ' ,
142
+ return h (
143
+ 'transition ' ,
122
144
{
123
- class : this . classObject ,
124
- attrs : { role : 'alert' , 'aria-live' : 'polite' , 'aria-atomic' : true }
145
+ props : {
146
+ mode : 'out-in' ,
147
+ // Disable use of built-in transition classes
148
+ 'enter-class' : '' ,
149
+ 'enter-active-class' : '' ,
150
+ 'enter-to-class' : '' ,
151
+ 'leave-class' : 'show' ,
152
+ 'leave-active-class' : '' ,
153
+ 'leave-to-class' : ''
154
+ } ,
155
+ on : {
156
+ beforeEnter : this . onBeforeEnter ,
157
+ beforeLeave : this . onBeforeLeave
158
+ }
125
159
} ,
126
- [ dismissBtn , this . $slots . default ]
160
+ $alert
127
161
)
128
- return ! this . fade ? alert : h ( 'transition' , { props : { name : 'fade' , appear : true } } , [ alert ] )
129
162
}
130
163
}
0 commit comments