Don't overwrite user-defined template refs when rendering (#2720)

* Merge vnode refs when rendering

In some cases if we used our own ref (we do this in `<TransitionRoot>` for instance) and rendered slot children we would wipe out  user-specified refs. So we set a flag when calling `cloneVNode` to merge our refs and any user-specified refs.

* Update changelog
This commit is contained in:
Jordan Pittman
2023-08-30 12:52:17 -04:00
committed by GitHub
parent c92757dded
commit 5a1e2e4e85
3 changed files with 45 additions and 1 deletions
+1
View File
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add support for `role="alertdialog"` to `<Dialog>` component ([#2709](https://github.com/tailwindlabs/headlessui/pull/2709))
- Ensure blurring the `ComboboxInput` component closes the `Combobox` ([#2712](https://github.com/tailwindlabs/headlessui/pull/2712))
- Allow `<button>` to be in nested components in `<PopoverButton>` ([#2715](https://github.com/tailwindlabs/headlessui/pull/2715))
- Don't overwrite user-defined template refs when rendering ([#2720](https://github.com/tailwindlabs/headlessui/pull/2720))
## [1.7.16] - 2023-08-17
@@ -738,6 +738,49 @@ describe('Rendering', () => {
expect(document.documentElement.style.overflow).toBe('')
})
)
it(
'should not have a scroll lock when the transition marked as not shown',
suppressConsoleLogs(async () => {
let dialogRef = ref(null)
renderTemplate({
components: {
Dialog,
TransitionRoot,
},
template: `
<button @click="show = !show">toggle</button>
<div id="output">{{ hasRef ? "Yes" : "No" }}</div>
<TransitionRoot as="template" :show="show">
<Dialog as="div" ref="dialogRef">
<input type="text" />
</Dialog>
</TransitionRoot>
`,
setup() {
let show = ref(false)
return {
show,
dialogRef,
}
},
})
expect(dialogRef.value).toBeNull()
await click(getByText('toggle'))
await nextFrame()
expect(dialogRef.value).not.toBeNull()
await click(getByText('toggle'))
await nextFrame()
expect(dialogRef.value).toBeNull()
})
)
})
describe('DialogOverlay', () => {
+1 -1
View File
@@ -140,7 +140,7 @@ function _render({
}
let mergedProps = mergeProps(firstChild.props ?? {}, incomingProps)
let cloned = cloneVNode(firstChild, mergedProps)
let cloned = cloneVNode(firstChild, mergedProps, true)
// Explicitly override props starting with `on`. This is for event handlers, but there are
// scenario's where we set them to `undefined` explicitly (when `aria-disabled="true"` is
// happening instead of `disabled`). But cloneVNode doesn't like overriding `onXXX` props so