@@ -25,13 +25,17 @@ export default class App extends React.Component {
25
25
indexStarted : false ,
26
26
indexComplete : false ,
27
27
t : i18n . t ,
28
- dir : dir
28
+ dir : dir ,
29
+ scrollbarWidth : 0
29
30
} ;
30
31
31
32
this . inputRef = React . createRef ( ) ;
32
33
}
33
34
34
35
componentDidMount ( ) {
36
+ const scrollbarWidth = this . getScrollbarWidth ( ) ;
37
+ this . setState ( { scrollbarWidth} ) ;
38
+
35
39
this . initSetup ( ) ;
36
40
}
37
41
@@ -42,10 +46,19 @@ export default class App extends React.Component {
42
46
if ( this . state . showPopup ) {
43
47
/** When modal is opened, store current overflow and set as hidden */
44
48
this . bodyScroll = window . document ?. body ?. style ?. overflow ;
49
+ this . bodyMargin = window . getComputedStyle ( document . body ) . getPropertyValue ( 'margin-right' ) ;
45
50
window . document . body . style . overflow = 'hidden' ;
51
+ if ( this . state . scrollbarWidth && document . body . scrollHeight > window . innerHeight ) {
52
+ window . document . body . style . marginRight = `calc(${ this . bodyMargin } + ${ this . state . scrollbarWidth } px)` ;
53
+ }
46
54
} else {
47
55
/** When the modal is hidden, reset overflow property for body */
48
56
window . document . body . style . overflow = this . bodyScroll || '' ;
57
+ if ( ! this . bodyMargin || this . bodyMargin === '0px' ) {
58
+ window . document . body . style . marginRight = '' ;
59
+ } else {
60
+ window . document . body . style . marginRight = this . bodyMargin ;
61
+ }
49
62
}
50
63
} catch ( e ) {
51
64
/** Ignore any errors for scroll handling */
@@ -90,6 +103,23 @@ export default class App extends React.Component {
90
103
window . addEventListener ( 'hashchange' , this . hashHandler , false ) ;
91
104
}
92
105
106
+ // User for adding trailing margin to prevent layout shift when popup appears
107
+ getScrollbarWidth ( ) {
108
+ // Create a temporary div
109
+ const div = document . createElement ( 'div' ) ;
110
+ div . style . visibility = 'hidden' ;
111
+ div . style . overflow = 'scroll' ; // forcing scrollbar to appear
112
+ document . body . appendChild ( div ) ;
113
+
114
+ // Calculate the width difference
115
+ const scrollbarWidth = div . offsetWidth - div . clientWidth ;
116
+
117
+ // Clean up
118
+ document . body . removeChild ( div ) ;
119
+
120
+ return scrollbarWidth ;
121
+ }
122
+
93
123
/** Setup custom trigger buttons handling on page */
94
124
setupCustomTriggerButton ( ) {
95
125
// Handler for custom buttons
0 commit comments