1
- import { nextTick , inject , defineComponent } from 'vue' ;
1
+ import { nextTick , defineComponent , getCurrentInstance , onMounted , onBeforeUnmount } from 'vue' ;
2
2
import TransitionEvents from './css-animation/Event' ;
3
3
import raf from './raf' ;
4
- import { defaultConfigProvider } from '../config-provider' ;
5
4
import { findDOMNode } from './props-util' ;
6
- let styleForPesudo ;
5
+ import useConfigInject from './hooks/useConfigInject' ;
6
+ let styleForPesudo : HTMLStyleElement ;
7
7
8
8
// Where el is the DOM element you'd like to test for visibility
9
- function isHidden ( element ) {
9
+ function isHidden ( element : HTMLElement ) {
10
10
if ( process . env . NODE_ENV === 'test' ) {
11
11
return false ;
12
12
}
13
13
return ! element || element . offsetParent === null ;
14
14
}
15
- function isNotGrey ( color ) {
15
+ function isNotGrey ( color : string ) {
16
16
// eslint-disable-next-line no-useless-escape
17
17
const match = ( color || '' ) . match ( / r g b a ? \( ( \d * ) , ( \d * ) , ( \d * ) ( , [ \. \d ] * ) ? \) / ) ;
18
18
if ( match && match [ 1 ] && match [ 2 ] && match [ 3 ] ) {
@@ -22,40 +22,51 @@ function isNotGrey(color) {
22
22
}
23
23
export default defineComponent ( {
24
24
name : 'Wave' ,
25
- props : [ 'insertExtraNode' ] ,
26
- setup ( ) {
27
- const configProvider = inject ( 'configProvider' , defaultConfigProvider ) ;
28
- return {
29
- configProvider,
30
- } ;
25
+ props : {
26
+ insertExtraNode : Boolean ,
31
27
} ,
32
- mounted ( ) {
33
- nextTick ( ( ) => {
34
- const node = findDOMNode ( this ) ;
35
- if ( node . nodeType !== 1 ) {
28
+ setup ( props , { slots, expose } ) {
29
+ const instance = getCurrentInstance ( ) ;
30
+ const { csp } = useConfigInject ( '' , props ) ;
31
+ expose ( {
32
+ csp,
33
+ } ) ;
34
+ let eventIns = null ;
35
+ let clickWaveTimeoutId = null ;
36
+ let animationStartId = null ;
37
+ let animationStart = false ;
38
+ let extraNode = null ;
39
+ let isUnmounted = false ;
40
+ const onTransitionStart = e => {
41
+ if ( isUnmounted ) return ;
42
+
43
+ const node = findDOMNode ( instance ) ;
44
+ if ( ! e || e . target !== node ) {
36
45
return ;
37
46
}
38
- this . instance = this . bindAnimationEvent ( node ) ;
39
- } ) ;
40
- } ,
41
- beforeUnmount ( ) {
42
- if ( this . instance ) {
43
- this . instance . cancel ( ) ;
44
- }
45
- if ( this . clickWaveTimeoutId ) {
46
- clearTimeout ( this . clickWaveTimeoutId ) ;
47
- }
48
- } ,
49
- methods : {
50
- onClick ( node , waveColor ) {
47
+
48
+ if ( ! animationStart ) {
49
+ resetEffect ( node ) ;
50
+ }
51
+ } ;
52
+ const onTransitionEnd = ( e : any ) => {
53
+ if ( ! e || e . animationName !== 'fadeEffect' ) {
54
+ return ;
55
+ }
56
+ resetEffect ( e . target ) ;
57
+ } ;
58
+ const getAttributeName = ( ) => {
59
+ const { insertExtraNode } = props ;
60
+ return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node' ;
61
+ } ;
62
+ const onClick = ( node : HTMLElement , waveColor : string ) => {
51
63
if ( ! node || isHidden ( node ) || node . className . indexOf ( '-leave' ) >= 0 ) {
52
64
return ;
53
65
}
54
- const { insertExtraNode } = this . $props ;
55
- this . extraNode = document . createElement ( 'div' ) ;
56
- const extraNode = this . extraNode ;
66
+ const { insertExtraNode } = props ;
67
+ extraNode = document . createElement ( 'div' ) ;
57
68
extraNode . className = 'ant-click-animating-node' ;
58
- const attributeName = this . getAttributeName ( ) ;
69
+ const attributeName = getAttributeName ( ) ;
59
70
node . removeAttribute ( attributeName ) ;
60
71
node . setAttribute ( attributeName , 'true' ) ;
61
72
// Not white or transparent or grey
@@ -69,8 +80,8 @@ export default defineComponent({
69
80
waveColor !== 'transparent'
70
81
) {
71
82
// Add nonce if CSP exist
72
- if ( this . csp && this . csp . nonce ) {
73
- styleForPesudo . nonce = this . csp . nonce ;
83
+ if ( csp . value ? .nonce ) {
84
+ styleForPesudo . nonce = csp . value . nonce ;
74
85
}
75
86
extraNode . style . borderColor = waveColor ;
76
87
styleForPesudo . innerHTML = `
@@ -84,32 +95,26 @@ export default defineComponent({
84
95
if ( insertExtraNode ) {
85
96
node . appendChild ( extraNode ) ;
86
97
}
87
- TransitionEvents . addStartEventListener ( node , this . onTransitionStart ) ;
88
- TransitionEvents . addEndEventListener ( node , this . onTransitionEnd ) ;
89
- } ,
90
- onTransitionStart ( e ) {
91
- if ( this . _ . isUnmounted ) return ;
92
-
93
- const node = findDOMNode ( this ) ;
94
- if ( ! e || e . target !== node ) {
98
+ TransitionEvents . addStartEventListener ( node , onTransitionStart ) ;
99
+ TransitionEvents . addEndEventListener ( node , onTransitionEnd ) ;
100
+ } ;
101
+ const resetEffect = ( node : HTMLElement ) => {
102
+ if ( ! node || node === extraNode || ! ( node instanceof Element ) ) {
95
103
return ;
96
104
}
97
-
98
- if ( ! this . animationStart ) {
99
- this . resetEffect ( node ) ;
105
+ const { insertExtraNode } = props ;
106
+ const attributeName = getAttributeName ( ) ;
107
+ node . setAttribute ( attributeName , 'false' ) ; // edge has bug on `removeAttribute` #14466
108
+ if ( styleForPesudo ) {
109
+ styleForPesudo . innerHTML = '' ;
100
110
}
101
- } ,
102
- onTransitionEnd ( e ) {
103
- if ( ! e || e . animationName !== 'fadeEffect' ) {
104
- return ;
111
+ if ( insertExtraNode && extraNode && node . contains ( extraNode ) ) {
112
+ node . removeChild ( extraNode ) ;
105
113
}
106
- this . resetEffect ( e . target ) ;
107
- } ,
108
- getAttributeName ( ) {
109
- const { insertExtraNode } = this . $props ;
110
- return insertExtraNode ? 'ant-click-animating' : 'ant-click-animating-without-extra-node' ;
111
- } ,
112
- bindAnimationEvent ( node ) {
114
+ TransitionEvents . removeStartEventListener ( node , onTransitionStart ) ;
115
+ TransitionEvents . removeEndEventListener ( node , onTransitionEnd ) ;
116
+ } ;
117
+ const bindAnimationEvent = ( node : HTMLElement ) => {
113
118
if (
114
119
! node ||
115
120
! node . getAttribute ||
@@ -118,57 +123,51 @@ export default defineComponent({
118
123
) {
119
124
return ;
120
125
}
121
- const onClick = e => {
126
+ const newClick = ( e : MouseEvent ) => {
122
127
// Fix radio button click twice
123
- if ( e . target . tagName === 'INPUT' || isHidden ( e . target ) ) {
128
+ if ( ( e . target as any ) . tagName === 'INPUT' || isHidden ( e . target as HTMLElement ) ) {
124
129
return ;
125
130
}
126
- this . resetEffect ( node ) ;
131
+ resetEffect ( node ) ;
127
132
// Get wave color from target
128
133
const waveColor =
129
134
getComputedStyle ( node ) . getPropertyValue ( 'border-top-color' ) || // Firefox Compatible
130
135
getComputedStyle ( node ) . getPropertyValue ( 'border-color' ) ||
131
136
getComputedStyle ( node ) . getPropertyValue ( 'background-color' ) ;
132
- this . clickWaveTimeoutId = setTimeout ( ( ) => this . onClick ( node , waveColor ) , 0 ) ;
133
- raf . cancel ( this . animationStartId ) ;
134
- this . animationStart = true ;
137
+ clickWaveTimeoutId = setTimeout ( ( ) => onClick ( node , waveColor ) , 0 ) ;
138
+ raf . cancel ( animationStartId ) ;
139
+ animationStart = true ;
135
140
136
141
// Render to trigger transition event cost 3 frames. Let's delay 10 frames to reset this.
137
- this . animationStartId = raf ( ( ) => {
138
- this . animationStart = false ;
142
+ animationStartId = raf ( ( ) => {
143
+ animationStart = false ;
139
144
} , 10 ) ;
140
145
} ;
141
- node . addEventListener ( 'click' , onClick , true ) ;
146
+ node . addEventListener ( 'click' , newClick , true ) ;
142
147
return {
143
148
cancel : ( ) => {
144
- node . removeEventListener ( 'click' , onClick , true ) ;
149
+ node . removeEventListener ( 'click' , newClick , true ) ;
145
150
} ,
146
151
} ;
147
- } ,
148
-
149
- resetEffect ( node ) {
150
- if ( ! node || node === this . extraNode || ! ( node instanceof Element ) ) {
151
- return ;
152
- }
153
- const { insertExtraNode } = this . $props ;
154
- const attributeName = this . getAttributeName ( ) ;
155
- node . setAttribute ( attributeName , 'false' ) ; // edge has bug on `removeAttribute` #14466
156
- if ( styleForPesudo ) {
157
- styleForPesudo . innerHTML = '' ;
158
- }
159
- if ( insertExtraNode && this . extraNode && node . contains ( this . extraNode ) ) {
160
- node . removeChild ( this . extraNode ) ;
152
+ } ;
153
+ onMounted ( ( ) => {
154
+ nextTick ( ( ) => {
155
+ const node = findDOMNode ( instance ) ;
156
+ if ( node . nodeType !== 1 ) {
157
+ return ;
158
+ }
159
+ eventIns = bindAnimationEvent ( node ) ;
160
+ } ) ;
161
+ } ) ;
162
+ onBeforeUnmount ( ( ) => {
163
+ if ( eventIns ) {
164
+ eventIns . cancel ( ) ;
161
165
}
162
- TransitionEvents . removeStartEventListener ( node , this . onTransitionStart ) ;
163
- TransitionEvents . removeEndEventListener ( node , this . onTransitionEnd ) ;
164
- } ,
165
- } ,
166
-
167
- render ( ) {
168
- const csp = this . configProvider . csp ;
169
- if ( csp ) {
170
- this . csp = csp ;
171
- }
172
- return this . $slots . default ?. ( ) [ 0 ] ;
166
+ clearTimeout ( clickWaveTimeoutId ) ;
167
+ isUnmounted = true ;
168
+ } ) ;
169
+ return ( ) => {
170
+ return slots . default ?.( ) [ 0 ] ;
171
+ } ;
173
172
} ,
174
173
} ) ;
0 commit comments