1
1
import PropTypes from './vue-types' ;
2
- import switchScrollingEffect from './switchScrollingEffect' ;
3
- import setStyle from './setStyle' ;
4
2
import Portal from './Portal' ;
5
3
import {
6
4
defineComponent ,
@@ -11,10 +9,12 @@ import {
11
9
onUpdated ,
12
10
getCurrentInstance ,
13
11
nextTick ,
12
+ computed ,
14
13
} from 'vue' ;
15
14
import canUseDom from './canUseDom' ;
16
- import ScrollLocker from '../vc-util/Dom/scrollLocker' ;
17
15
import raf from './raf' ;
16
+ import { booleanType } from './type' ;
17
+ import useScrollLocker from './hooks/useScrollLocker' ;
18
18
19
19
let openCount = 0 ;
20
20
const supportDom = canUseDom ( ) ;
@@ -24,10 +24,6 @@ export function getOpenCount() {
24
24
return process . env . NODE_ENV === 'test' ? openCount : 0 ;
25
25
}
26
26
27
- // https://github.com/ant-design/ant-design/issues/19340
28
- // https://github.com/ant-design/ant-design/issues/19332
29
- let cacheOverflow = { } ;
30
-
31
27
const getParent = ( getContainer : GetContainer ) => {
32
28
if ( ! supportDom ) {
33
29
return null ;
@@ -57,20 +53,20 @@ export default defineComponent({
57
53
forceRender : { type : Boolean , default : undefined } ,
58
54
getContainer : PropTypes . any ,
59
55
visible : { type : Boolean , default : undefined } ,
56
+ autoLock : booleanType ( ) ,
57
+ didUpdate : Function ,
60
58
} ,
61
59
62
60
setup ( props , { slots } ) {
63
61
const container = shallowRef < HTMLElement > ( ) ;
64
62
const componentRef = shallowRef ( ) ;
65
63
const rafId = shallowRef < number > ( ) ;
66
- const scrollLocker = new ScrollLocker ( {
67
- container : getParent ( props . getContainer ) as HTMLElement ,
68
- } ) ;
69
64
70
65
const removeCurrentContainer = ( ) => {
71
66
// Portal will remove from `parentNode`.
72
67
// Let's handle this again to avoid refactor issue.
73
68
container . value ?. parentNode ?. removeChild ( container . value ) ;
69
+ container . value = null ;
74
70
} ;
75
71
const attachToParent = ( force = false ) => {
76
72
if ( force || ( container . value && ! container . value . parentNode ) ) {
@@ -86,13 +82,13 @@ export default defineComponent({
86
82
return true ;
87
83
} ;
88
84
// attachToParent();
89
-
85
+ const defaultContainer = document . createElement ( 'div' ) ;
90
86
const getContainer = ( ) => {
91
87
if ( ! supportDom ) {
92
88
return null ;
93
89
}
94
90
if ( ! container . value ) {
95
- container . value = document . createElement ( 'div' ) ;
91
+ container . value = defaultContainer ;
96
92
attachToParent ( true ) ;
97
93
}
98
94
setWrapperClassName ( ) ;
@@ -108,30 +104,19 @@ export default defineComponent({
108
104
setWrapperClassName ( ) ;
109
105
attachToParent ( ) ;
110
106
} ) ;
111
- /**
112
- * Enhance ./switchScrollingEffect
113
- * 1. Simulate document body scroll bar with
114
- * 2. Record body has overflow style and recover when all of PortalWrapper invisible
115
- * 3. Disable body scroll when PortalWrapper has open
116
- *
117
- * @memberof PortalWrapper
118
- */
119
- const switchScrolling = ( ) => {
120
- if ( openCount === 1 && ! Object . keys ( cacheOverflow ) . length ) {
121
- switchScrollingEffect ( ) ;
122
- // Must be set after switchScrollingEffect
123
- cacheOverflow = setStyle ( {
124
- overflow : 'hidden' ,
125
- overflowX : 'hidden' ,
126
- overflowY : 'hidden' ,
127
- } ) ;
128
- } else if ( ! openCount ) {
129
- setStyle ( cacheOverflow ) ;
130
- cacheOverflow = { } ;
131
- switchScrollingEffect ( true ) ;
132
- }
133
- } ;
107
+
134
108
const instance = getCurrentInstance ( ) ;
109
+
110
+ useScrollLocker (
111
+ computed ( ( ) => {
112
+ return (
113
+ props . autoLock &&
114
+ props . visible &&
115
+ canUseDom ( ) &&
116
+ ( container . value === document . body || container . value === defaultContainer )
117
+ ) ;
118
+ } ) ,
119
+ ) ;
135
120
onMounted ( ( ) => {
136
121
let init = false ;
137
122
watch (
@@ -157,17 +142,6 @@ export default defineComponent({
157
142
) {
158
143
removeCurrentContainer ( ) ;
159
144
}
160
- // updateScrollLocker
161
- if (
162
- visible &&
163
- visible !== prevVisible &&
164
- supportDom &&
165
- getParent ( getContainer ) !== scrollLocker . getContainer ( )
166
- ) {
167
- scrollLocker . reLock ( {
168
- container : getParent ( getContainer ) as HTMLElement ,
169
- } ) ;
170
- }
171
145
}
172
146
init = true ;
173
147
} ,
@@ -192,22 +166,30 @@ export default defineComponent({
192
166
removeCurrentContainer ( ) ;
193
167
raf . cancel ( rafId . value ) ;
194
168
} ) ;
195
-
169
+ watch (
170
+ [ ( ) => props . visible , ( ) => props . forceRender ] ,
171
+ ( ) => {
172
+ const { forceRender, visible } = props ;
173
+ if ( visible === false && ! forceRender ) {
174
+ removeCurrentContainer ( ) ;
175
+ }
176
+ } ,
177
+ { flush : 'post' } ,
178
+ ) ;
196
179
return ( ) => {
197
180
const { forceRender, visible } = props ;
198
181
let portal = null ;
199
182
const childProps = {
200
183
getOpenCount : ( ) => openCount ,
201
184
getContainer,
202
- switchScrollingEffect : switchScrolling ,
203
- scrollLocker,
204
185
} ;
205
-
186
+ if ( visible === false && ! forceRender ) return null ;
206
187
if ( forceRender || visible || componentRef . value ) {
207
188
portal = (
208
189
< Portal
209
190
getContainer = { getContainer }
210
191
ref = { componentRef }
192
+ didUpdate = { props . didUpdate }
211
193
v-slots = { { default : ( ) => slots . default ?.( childProps ) } }
212
194
> </ Portal >
213
195
) ;
0 commit comments