10
10
v-if =" isActive"
11
11
:is =" tag"
12
12
:class =" wrapperClass"
13
- :style =" backdropStyle"
13
+ :style =" [ backdropStyle, backdropOverflowStyle] "
14
14
:aria-hidden =" !isActive"
15
15
:aria-modal =" isActive ? true : null"
16
16
:aria-labelledby =" labelledby"
30
30
<script >
31
31
import {
32
32
computed ,
33
- onBeforeMount ,
34
33
onBeforeUnmount ,
35
34
onMounted ,
36
35
provide ,
@@ -52,17 +51,6 @@ export default {
52
51
type: String ,
53
52
validator : value => [" sm" , " lg" , " xl" ].indexOf (value .toLowerCase ()) > - 1
54
53
},
55
- side: {
56
- type: Boolean ,
57
- default: false
58
- },
59
- position: {
60
- type: String
61
- },
62
- frame: {
63
- type: Boolean ,
64
- default: false
65
- },
66
54
removeBackdrop: {
67
55
type: Boolean ,
68
56
default: false
@@ -79,10 +67,6 @@ export default {
79
67
type: String ,
80
68
default: " "
81
69
},
82
- direction: {
83
- type: String ,
84
- default: " top"
85
- },
86
70
scrollable: {
87
71
type: Boolean ,
88
72
default: false
@@ -99,15 +83,22 @@ export default {
99
83
animation: {
100
84
type: Boolean ,
101
85
default: true
102
- }
86
+ },
87
+ dialogClasses: {
88
+ type: String
89
+ },
90
+ transform: String
103
91
},
104
92
emits: [" show" , " shown" , " hide" , " hidden" , " update:modelValue" ],
105
93
setup (props , { attrs, emit }) {
106
94
const root = ref (" root" );
107
95
const dialog = ref (" dialog" );
108
- const dialogTransform = ref (" translate(0, -25%)" );
96
+ const dialogTransform = ref (" " );
97
+
109
98
const isActive = ref (props .modelValue );
110
99
100
+ const thisElement = ref (null );
101
+
111
102
watchEffect (() => {
112
103
isActive .value = props .modelValue ;
113
104
if (isActive .value ) {
@@ -128,12 +119,10 @@ export default {
128
119
return [
129
120
" modal-dialog" ,
130
121
props .size && " modal-" + props .size ,
131
- props .side && " modal-side" ,
132
- props .frame && " modal-frame" ,
133
- props .position ? " modal-" + props .position : " " ,
134
122
props .centered && " modal-dialog-centered" ,
135
123
props .scrollable && " modal-dialog-scrollable" ,
136
- props .fullscreen && fullscreenClass .value
124
+ props .fullscreen && fullscreenClass .value ,
125
+ props .dialogClasses
137
126
];
138
127
});
139
128
@@ -143,6 +132,17 @@ export default {
143
132
: { " background-color" : ` rgba(0,0,0, 0.5)` };
144
133
});
145
134
135
+ // shouldOverflow with backdropOverflowStyle prevents bottom modal create additional scrollbar on show
136
+ const shouldOverflow = ref (
137
+ props .transform === " translate(0,25%)" ? false : true
138
+ );
139
+ const backdropOverflowStyle = computed (() => {
140
+ if (shouldOverflow .value ) {
141
+ return ;
142
+ }
143
+ return " overflow: hidden" ;
144
+ });
145
+
146
146
const computedContentStyle = computed (() => {
147
147
return props .bgSrc
148
148
? { " background-image" : ` url("${ props .bgSrc } ")` }
@@ -206,49 +206,48 @@ export default {
206
206
};
207
207
208
208
const enter = el => {
209
+ shouldOverflow .value =
210
+ props .transform === " translate(0,25%)" ? false : true ;
211
+
212
+ dialogTransform .value = props .transform || " translate(0, -25%)" ;
213
+
209
214
el .childNodes [0 ].style .transform = dialogTransform .value ;
210
215
el .style .opacity = 0 ;
211
216
el .style .display = " block" ;
212
217
213
218
setScrollbar ();
214
-
215
- el .style .paddingRight = ` ${ scrollbarWidth .value } px` ;
216
219
document .body .style .paddingRight = ` ${ scrollbarWidth .value } px` ;
220
+ el .style .paddingRight = ` ${ scrollbarWidth .value } px` ;
217
221
document .body .classList .add (" modal-open" );
218
222
219
223
emit (" show" , root .value );
220
224
};
221
225
const afterEnter = el => {
222
- el .style .opacity = 1 ;
223
226
el .childNodes [0 ].style .transform = " translate(0,0)" ;
227
+ el .style .opacity = 1 ;
224
228
225
229
setTimeout (() => {
230
+ shouldOverflow .value = true ;
226
231
emit (" shown" , root .value );
227
232
}, 400 );
233
+ thisElement .value = root .value ;
228
234
};
229
235
const beforeLeave = el => {
230
236
el .childNodes [0 ].style .transform = dialogTransform .value ;
231
237
el .style .opacity = 0 ;
232
- el .style .paddingRight = null ;
233
- document .body .style .paddingRight = null ;
234
- document .body .classList .remove (" modal-open" );
238
+ setTimeout (() => {
239
+ el .style .paddingRight = null ;
240
+ document .body .style .paddingRight = null ;
241
+ document .body .classList .remove (" modal-open" );
242
+ }, 200 );
235
243
236
- emit (" hide" , root .value );
244
+ emit (" hide" , thisElement .value );
237
245
};
238
246
const afterLeave = () => {
239
- emit (" hidden" , root .value );
247
+ emit (" hidden" , thisElement .value );
248
+ shouldOverflow .value = false ;
240
249
};
241
250
242
- onBeforeMount (() => {
243
- if (props .direction === " right" ) {
244
- dialogTransform .value = " translate(25%,0)" ;
245
- } else if (props .direction === " bottom" ) {
246
- dialogTransform .value = " translate(0,25%)" ;
247
- } else if (props .direction === " left" ) {
248
- dialogTransform .value = " translate(-25%,0)" ;
249
- }
250
- });
251
-
252
251
onMounted (() => {
253
252
on (window , " keyup" , handleEscKeyUp);
254
253
});
@@ -261,6 +260,7 @@ export default {
261
260
wrapperClass,
262
261
dialogClass,
263
262
backdropStyle,
263
+ backdropOverflowStyle,
264
264
computedContentStyle,
265
265
root,
266
266
dialog,
0 commit comments