Skip to content

Commit 5c7a729

Browse files
authored
fix(app-layout): sidebar scroll container padding (#1166)
* fix(app-layout): sidebar scroll container padding * chore: comment
1 parent e1d6a1d commit 5c7a729

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

packages/core/app-layout/src/components/sidebar/AppSidebar.vue

+48-1
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,59 @@ watch(focusTrapEnabled, async (enabled: boolean) => {
301301
}
302302
}, { immediate: true })
303303
304-
onMounted(() => {
304+
// If the user is on a Mac, we may need to add extra padding to the sidebar scroll container
305+
const scrollbarExtraPadding = ref<string>('0px')
306+
307+
/**
308+
* Determine the width of the user's scrollbar, if on a Mac, based on the `Appearance > Show scroll bars` setting.
309+
* If the width equals zero, add 8px of extra padding to the .sidebar-content-container.
310+
* This isn't great and I hate it, but it works ¯\_(ツ)_/¯
311+
*/
312+
const getScrollbarWidth = (): void => {
313+
// @ts-ignore Determine if the user is on MacOS
314+
const isMac = /Mac|iPhone|iPod|iPad/i.test(navigator?.platform) || /macOS|Mac|iPhone|iPod|iPad/i.test(navigator?.userAgentData?.platform)
315+
316+
if (!isMac) {
317+
return
318+
}
319+
320+
const outerElement = document.createElement('div')
321+
outerElement.style.visibility = 'hidden'
322+
outerElement.style.width = '100px'
323+
document.body.appendChild(outerElement)
324+
325+
const widthNoScroll = outerElement.offsetWidth
326+
// force scrollbar
327+
outerElement.style.overflow = 'scroll'
328+
329+
// add inner element
330+
const innerElement = document.createElement('div')
331+
innerElement.style.width = '100%'
332+
outerElement.appendChild(innerElement)
333+
334+
const widthWithScroll = innerElement.offsetWidth
335+
336+
// remove inner elements
337+
outerElement.parentNode && outerElement.parentNode.removeChild(outerElement)
338+
339+
const scrollbarWidth = widthNoScroll - widthWithScroll
340+
341+
if (scrollbarWidth === 0) {
342+
scrollbarExtraPadding.value = '8px'
343+
}
344+
}
345+
346+
onMounted(async () => {
305347
// Set the window width once the component mounts
306348
windowWidth.value = window?.innerWidth
307349
// Automatically close the sidebar if the window is resized
308350
window.addEventListener('resize', debouncedResizeHandler)
309351
// Disable mobile sidebar transitions when the window is resized
310352
window.addEventListener('resize', disableTransitions)
353+
354+
await nextTick()
355+
// Adjust the sidebar padding
356+
getScrollbarWidth()
311357
})
312358
313359
onBeforeUnmount(() => {
@@ -368,6 +414,7 @@ onBeforeUnmount(() => {
368414
overflow-x: hidden;
369415
// Must use `scroll` so that the scrollbar width is always accounted for. Cannot use `overlay` here as it breaks in Firefox.
370416
overflow-y: scroll;
417+
padding-right: v-bind('scrollbarExtraPadding');
371418
padding-top: $sidebar-header-spacing;
372419
position: relative;
373420
width: 100%;

0 commit comments

Comments
 (0)