Skip to content

Commit 2be1eed

Browse files
authored
Fixed layout shift issue when Search popup appears (#22539)
Fix #22538 Reference #21895
1 parent 8bb2059 commit 2be1eed

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

apps/sodo-search/src/App.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,17 @@ export default class App extends React.Component {
2525
indexStarted: false,
2626
indexComplete: false,
2727
t: i18n.t,
28-
dir: dir
28+
dir: dir,
29+
scrollbarWidth: 0
2930
};
3031

3132
this.inputRef = React.createRef();
3233
}
3334

3435
componentDidMount() {
36+
const scrollbarWidth = this.getScrollbarWidth();
37+
this.setState({scrollbarWidth});
38+
3539
this.initSetup();
3640
}
3741

@@ -42,10 +46,19 @@ export default class App extends React.Component {
4246
if (this.state.showPopup) {
4347
/** When modal is opened, store current overflow and set as hidden */
4448
this.bodyScroll = window.document?.body?.style?.overflow;
49+
this.bodyMargin = window.getComputedStyle(document.body).getPropertyValue('margin-right');
4550
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+
}
4654
} else {
4755
/** When the modal is hidden, reset overflow property for body */
4856
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+
}
4962
}
5063
} catch (e) {
5164
/** Ignore any errors for scroll handling */
@@ -90,6 +103,23 @@ export default class App extends React.Component {
90103
window.addEventListener('hashchange', this.hashHandler, false);
91104
}
92105

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+
93123
/** Setup custom trigger buttons handling on page */
94124
setupCustomTriggerButton() {
95125
// Handler for custom buttons

0 commit comments

Comments
 (0)