Skip to content

Commit

Permalink
Don't scroll lock when a Transition + Dialog is mounted but hidden (#…
Browse files Browse the repository at this point in the history
…1681)

* Refer to context for initial Transition Tree state

* Update changelog
  • Loading branch information
thecrypticace authored Jul 15, 2022
1 parent 6d13e79 commit 5af3bd4
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Close `Menu` component when using `tab` key ([#1673](https://github.com/tailwindlabs/headlessui/pull/1673))
- Resync input when display value changes ([#1679](https://github.com/tailwindlabs/headlessui/pull/1679))
- Ensure controlled `Tabs` don't change automagically ([#1680](https://github.com/tailwindlabs/headlessui/pull/1680))
- Don't scroll lock when a Transition + Dialog is mounted but hidden ([#1681](https://github.com/tailwindlabs/headlessui/pull/1681))

## [1.6.6] - 2022-07-07

Expand Down
40 changes: 39 additions & 1 deletion packages/@headlessui-react/src/components/dialog/dialog.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { createElement, useRef, useState } from 'react'
import React, { createElement, useRef, useState, Fragment } from 'react'
import { render } from '@testing-library/react'

import { Dialog } from './dialog'
Expand Down Expand Up @@ -270,6 +270,44 @@ describe('Rendering', () => {
expect(document.documentElement.style.overflow).toBe('hidden')
})
)

it(
'should wait to add a scroll lock to the html tag when unmount is false in a Transition',
suppressConsoleLogs(async () => {
function Example() {
let [isOpen, setIsOpen] = useState(false)

return (
<>
<button id="trigger" onClick={() => setIsOpen((v) => !v)}>
Trigger
</button>

<Transition as={Fragment} show={isOpen} unmount={false}>
<Dialog onClose={() => setIsOpen(false)} unmount={false}>
<input id="a" type="text" />
<input id="b" type="text" />
<input id="c" type="text" />
</Dialog>
</Transition>
</>
)
}

render(<Example />)

// No overflow yet
expect(document.documentElement.style.overflow).toBe('')

let btn = document.getElementById('trigger')

// Open the dialog
await click(btn)

// Expect overflow
expect(document.documentElement.style.overflow).toBe('hidden')
})
)
})

describe('Dialog.Overlay', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,10 +209,12 @@ let TransitionChild = forwardRefWithAs(function TransitionChild<
} = props as typeof props
let container = useRef<HTMLElement | null>(null)
let transitionRef = useSyncRefs(container, ref)
let [state, setState] = useState(TreeStates.Visible)
let strategy = rest.unmount ? RenderStrategy.Unmount : RenderStrategy.Hidden

let { show, appear, initial } = useTransitionContext()

let [state, setState] = useState(show ? TreeStates.Visible : TreeStates.Hidden)

let { register, unregister } = useParentNesting()
let prevShow = useRef<boolean | null>(null)

Expand Down
51 changes: 51 additions & 0 deletions packages/@headlessui-vue/src/components/dialog/dialog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,57 @@ describe('Rendering', () => {
expect(document.documentElement.style.overflow).toBe('hidden')
})
)

it(
'should wait to add a scroll lock to the html tag when unmount is false in a Transition',
suppressConsoleLogs(async () => {
renderTemplate({
components: {
Dialog,
TransitionRoot,
},

template: `
<div>
<button id="trigger" @click="toggleOpen">
Trigger
</button>
<TransitionRoot :show="isOpen" :unmount="false">
<Dialog @close="setIsOpen" :unmount="false">
<input id="a" type="text" />
<input id="b" type="text" />
<input id="c" type="text" />
</Dialog>
</TransitionRoot>
</div>
`,
setup() {
let isOpen = ref(false)
return {
isOpen,
setIsOpen(value: boolean) {
isOpen.value = value
},
toggleOpen() {
isOpen.value = !isOpen.value
},
}
},
})

// No overflow yet
expect(document.documentElement.style.overflow).toBe('')

let btn = document.getElementById('trigger')

// Open the dialog
await click(btn)

// Expect overflow
expect(document.documentElement.style.overflow).toBe('hidden')
})
)
})

describe('DialogOverlay', () => {
Expand Down

0 comments on commit 5af3bd4

Please sign in to comment.