1010 v-if =" isActive"
1111 :is =" tag"
1212 :class =" wrapperClass"
13- :style =" backdropStyle"
13+ :style =" [ backdropStyle, backdropOverflowStyle] "
1414 :aria-hidden =" !isActive"
1515 :aria-modal =" isActive ? true : null"
1616 :aria-labelledby =" labelledby"
3030<script >
3131import {
3232 computed ,
33- onBeforeMount ,
3433 onBeforeUnmount ,
3534 onMounted ,
3635 provide ,
@@ -52,17 +51,6 @@ export default {
5251 type: String ,
5352 validator : value => [" sm" , " lg" , " xl" ].indexOf (value .toLowerCase ()) > - 1
5453 },
55- side: {
56- type: Boolean ,
57- default: false
58- },
59- position: {
60- type: String
61- },
62- frame: {
63- type: Boolean ,
64- default: false
65- },
6654 removeBackdrop: {
6755 type: Boolean ,
6856 default: false
@@ -79,10 +67,6 @@ export default {
7967 type: String ,
8068 default: " "
8169 },
82- direction: {
83- type: String ,
84- default: " top"
85- },
8670 scrollable: {
8771 type: Boolean ,
8872 default: false
@@ -99,15 +83,22 @@ export default {
9983 animation: {
10084 type: Boolean ,
10185 default: true
102- }
86+ },
87+ dialogClasses: {
88+ type: String
89+ },
90+ transform: String
10391 },
10492 emits: [" show" , " shown" , " hide" , " hidden" , " update:modelValue" ],
10593 setup (props , { attrs, emit }) {
10694 const root = ref (" root" );
10795 const dialog = ref (" dialog" );
108- const dialogTransform = ref (" translate(0, -25%)" );
96+ const dialogTransform = ref (" " );
97+
10998 const isActive = ref (props .modelValue );
11099
100+ const thisElement = ref (null );
101+
111102 watchEffect (() => {
112103 isActive .value = props .modelValue ;
113104 if (isActive .value ) {
@@ -128,12 +119,10 @@ export default {
128119 return [
129120 " modal-dialog" ,
130121 props .size && " modal-" + props .size ,
131- props .side && " modal-side" ,
132- props .frame && " modal-frame" ,
133- props .position ? " modal-" + props .position : " " ,
134122 props .centered && " modal-dialog-centered" ,
135123 props .scrollable && " modal-dialog-scrollable" ,
136- props .fullscreen && fullscreenClass .value
124+ props .fullscreen && fullscreenClass .value ,
125+ props .dialogClasses
137126 ];
138127 });
139128
@@ -143,6 +132,17 @@ export default {
143132 : { " background-color" : ` rgba(0,0,0, 0.5)` };
144133 });
145134
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+
146146 const computedContentStyle = computed (() => {
147147 return props .bgSrc
148148 ? { " background-image" : ` url("${ props .bgSrc } ")` }
@@ -206,49 +206,48 @@ export default {
206206 };
207207
208208 const enter = el => {
209+ shouldOverflow .value =
210+ props .transform === " translate(0,25%)" ? false : true ;
211+
212+ dialogTransform .value = props .transform || " translate(0, -25%)" ;
213+
209214 el .childNodes [0 ].style .transform = dialogTransform .value ;
210215 el .style .opacity = 0 ;
211216 el .style .display = " block" ;
212217
213218 setScrollbar ();
214-
215- el .style .paddingRight = ` ${ scrollbarWidth .value } px` ;
216219 document .body .style .paddingRight = ` ${ scrollbarWidth .value } px` ;
220+ el .style .paddingRight = ` ${ scrollbarWidth .value } px` ;
217221 document .body .classList .add (" modal-open" );
218222
219223 emit (" show" , root .value );
220224 };
221225 const afterEnter = el => {
222- el .style .opacity = 1 ;
223226 el .childNodes [0 ].style .transform = " translate(0,0)" ;
227+ el .style .opacity = 1 ;
224228
225229 setTimeout (() => {
230+ shouldOverflow .value = true ;
226231 emit (" shown" , root .value );
227232 }, 400 );
233+ thisElement .value = root .value ;
228234 };
229235 const beforeLeave = el => {
230236 el .childNodes [0 ].style .transform = dialogTransform .value ;
231237 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 );
235243
236- emit (" hide" , root .value );
244+ emit (" hide" , thisElement .value );
237245 };
238246 const afterLeave = () => {
239- emit (" hidden" , root .value );
247+ emit (" hidden" , thisElement .value );
248+ shouldOverflow .value = false ;
240249 };
241250
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-
252251 onMounted (() => {
253252 on (window , " keyup" , handleEscKeyUp);
254253 });
@@ -261,6 +260,7 @@ export default {
261260 wrapperClass,
262261 dialogClass,
263262 backdropStyle,
263+ backdropOverflowStyle,
264264 computedContentStyle,
265265 root,
266266 dialog,
0 commit comments