From 5a1e2e4e8541f80581893cf79c6c78f033140209 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 30 Aug 2023 12:52:17 -0400 Subject: [PATCH] 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 `` 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 --- packages/@headlessui-vue/CHANGELOG.md | 1 + .../src/components/dialog/dialog.test.ts | 43 +++++++++++++++++++ packages/@headlessui-vue/src/utils/render.ts | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/@headlessui-vue/CHANGELOG.md b/packages/@headlessui-vue/CHANGELOG.md index a5bc701a08..41e97e1b62 100644 --- a/packages/@headlessui-vue/CHANGELOG.md +++ b/packages/@headlessui-vue/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add support for `role="alertdialog"` to `` 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 ` +
{{ hasRef ? "Yes" : "No" }}
+ + + + + + `, + 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', () => { diff --git a/packages/@headlessui-vue/src/utils/render.ts b/packages/@headlessui-vue/src/utils/render.ts index 9aa634af21..10f3e123f6 100644 --- a/packages/@headlessui-vue/src/utils/render.ts +++ b/packages/@headlessui-vue/src/utils/render.ts @@ -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