aboutsummaryrefslogtreecommitdiff
path: root/src/directives/body_scroll_lock.js
blob: 6ab20c3f18cfe2e0403cd4cda5cb0fbca3b1eba6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import * as bodyScrollLock from 'body-scroll-lock'

let previousNavPaddingRight
let previousAppBgWrapperRight

const disableBodyScroll = (el) => {
  const scrollBarGap = window.innerWidth - document.documentElement.clientWidth
  bodyScrollLock.disableBodyScroll(el, {
    reserveScrollBarGap: true
  })
  setTimeout(() => {
    // If previousNavPaddingRight is already set, don't set it again.
    if (previousNavPaddingRight === undefined) {
      const navEl = document.getElementById('nav')
      previousNavPaddingRight = window.getComputedStyle(navEl).getPropertyValue('padding-right')
      navEl.style.paddingRight = previousNavPaddingRight ? `calc(${previousNavPaddingRight} + ${scrollBarGap}px)` : `${scrollBarGap}px`
    }
    // If previousAppBgWrapeprRight is already set, don't set it again.
    if (previousAppBgWrapperRight === undefined) {
      const appBgWrapperEl = document.getElementById('app_bg_wrapper')
      previousAppBgWrapperRight = window.getComputedStyle(appBgWrapperEl).getPropertyValue('right')
      appBgWrapperEl.style.right = previousAppBgWrapperRight ? `calc(${previousAppBgWrapperRight} + ${scrollBarGap}px)` : `${scrollBarGap}px`
    }
    document.body.classList.add('scroll-locked')
  })
}

const enableBodyScroll = (el) => {
  setTimeout(() => {
    if (previousNavPaddingRight !== undefined) {
      document.getElementById('nav').style.paddingRight = previousNavPaddingRight
      // Restore previousNavPaddingRight to undefined so disableBodyScroll knows it can be set again.
      previousNavPaddingRight = undefined
    }
    if (previousAppBgWrapperRight !== undefined) {
      document.getElementById('app_bg_wrapper').style.right = previousAppBgWrapperRight
      // Restore previousAppBgWrapperRight to undefined so disableBodyScroll knows it can be set again.
      previousAppBgWrapperRight = undefined
    }
    document.body.classList.remove('scroll-locked')
  })
  bodyScrollLock.enableBodyScroll(el)
}

const directive = {
  inserted: (el, binding) => {
    if (binding.value) {
      disableBodyScroll(el)
    }
  },
  componentUpdated: (el, binding) => {
    if (binding.oldValue === binding.value) {
      return
    }

    if (binding.value) {
      disableBodyScroll(el)
    } else {
      enableBodyScroll(el)
    }
  },
  unbind: (el) => {
    enableBodyScroll(el)
  }
}

export default (Vue) => {
  Vue.directive('body-scroll-lock', directive)
}