Skip to content

Commit

Permalink
fix(useScrollLock): initialOverflow is not working (#3798)
Browse files Browse the repository at this point in the history
  • Loading branch information
BJ0815 committed Feb 27, 2024
1 parent bd946aa commit 74e86b5
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 2 deletions.
88 changes: 88 additions & 0 deletions packages/core/useScrollLock/index.test.ts
@@ -0,0 +1,88 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { defineComponent, h } from 'vue-demi'
import { mount } from '../../.test'
import { useScrollLock } from '.'

describe('useScrollLock', () => {
let targetEl: HTMLElement

beforeEach(() => {
targetEl = document.createElement('div')
})

it('should lock the scroll', () => {
const isLock = useScrollLock(targetEl)

isLock.value = true
expect(targetEl.style.overflow).toBe('hidden')

isLock.value = false
expect(targetEl.style.overflow).toBe('')
})

it('should cache the initial overflow setting', () => {
targetEl.style.overflow = 'auto'

const isLock = useScrollLock(targetEl)

isLock.value = true
expect(targetEl.style.overflow).toBe('hidden')

isLock.value = false
expect(targetEl.style.overflow).toBe('auto')
})

it('automatically unlocks on component unmount', async () => {
const vm = mount(defineComponent({
setup() {
const isLock = useScrollLock(targetEl)

return { isLock }
},
render() {
return h('div')
},
}))

vm.isLock = true
expect(targetEl.style.overflow).toBe('hidden')

vm.unmount()
expect(targetEl.style.overflow).toBe('')
})

it('handles touchmove event on IOS devices', () => {
vi.mock('@vueuse/shared', async () => {
const actual = await vi.importActual('@vueuse/shared')
return {
...actual,
isIOS: true,
}
})

const addEventListener = vi.spyOn(targetEl, 'addEventListener')
const removeEventListener = vi.spyOn(targetEl, 'removeEventListener')
const isLock = useScrollLock(targetEl)

expect(addEventListener).toBeCalledTimes(0)

isLock.value = true
expect(addEventListener).toBeCalledTimes(1)
expect(removeEventListener).toBeCalledTimes(0)

isLock.value = false
expect(removeEventListener).toBeCalledTimes(1)
})

it('multiple instances point at the same element, will share the same initialOverflow', () => {
const isLock1 = useScrollLock(targetEl)
const isLock2 = useScrollLock(targetEl)

isLock1.value = true
isLock2.value = true
expect(targetEl.style.overflow).toBe('hidden')

isLock2.value = false
expect(targetEl.style.overflow).toBe('')
})
})
4 changes: 2 additions & 2 deletions packages/core/useScrollLock/index.ts
Expand Up @@ -58,14 +58,14 @@ export function useScrollLock(
) {
const isLocked = ref(initialState)
let stopTouchMoveListener: Fn | null = null
let initialOverflow: CSSStyleDeclaration['overflow']

watch(toRef(element), (el) => {
const target = resolveElement(toValue(el))
if (target) {
const ele = target as HTMLElement
if (!elInitialOverflow.get(ele))
elInitialOverflow.set(ele, initialOverflow)
elInitialOverflow.set(ele, ele.style.overflow)

if (isLocked.value)
ele.style.overflow = 'hidden'
}
Expand Down

0 comments on commit 74e86b5

Please sign in to comment.