From 20a224aaa4cd13539cd366d03d277d6e983caccb Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Wed, 4 Oct 2023 13:39:26 -0400 Subject: [PATCH] Fix state data attribute in Vue (#2787) * Add tests * Fix state data attribute in Vue --- .../@headlessui-vue/src/utils/render.test.ts | 49 ++++++++++++++++++- packages/@headlessui-vue/src/utils/render.ts | 3 +- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/@headlessui-vue/src/utils/render.test.ts b/packages/@headlessui-vue/src/utils/render.test.ts index a4f152315..24f9f1fa0 100644 --- a/packages/@headlessui-vue/src/utils/render.test.ts +++ b/packages/@headlessui-vue/src/utils/render.test.ts @@ -6,9 +6,21 @@ import { render } from './render' let Dummy = defineComponent({ props: { as: { type: [Object, String], default: 'div' }, + slot: { type: Object, default: () => ({}) }, }, setup(props, { attrs, slots }) { - return () => render({ theirProps: props, ourProps: {}, slots, attrs, slot: {}, name: 'Dummy' }) + return () => { + let { slot, ...rest } = props + + return render({ + theirProps: rest, + ourProps: {}, + slots, + attrs, + slot, + name: 'Dummy', + }) + } }, }) @@ -120,3 +132,38 @@ describe('Validation', () => { expect(document.getElementById('result')).toHaveAttribute('data-test', '123') }) }) + +describe('State Data Attributes', () => { + it('as=element', () => { + renderTemplate({ + template: html` + +
test
+
+ `, + }) + + expect(document.getElementById('result')).toHaveAttribute( + 'data-headlessui-state', + 'active selected' + ) + }) + + it('as=template', () => { + renderTemplate({ + template: html` + +
test
+
+ `, + }) + + expect(document.getElementById('result')).toHaveClass('abc') + + // NOTE: Removing class="abc" causes this assertion to fail + expect(document.getElementById('result')).toHaveAttribute( + 'data-headlessui-state', + 'active selected' + ) + }) +}) diff --git a/packages/@headlessui-vue/src/utils/render.ts b/packages/@headlessui-vue/src/utils/render.ts index 6896a51e5..9d4d8cd0a 100644 --- a/packages/@headlessui-vue/src/utils/render.ts +++ b/packages/@headlessui-vue/src/utils/render.ts @@ -139,7 +139,7 @@ function _render({ ) } - let mergedProps = mergeProps(firstChild.props ?? {}, incomingProps) + let mergedProps = mergeProps(firstChild.props ?? {}, incomingProps, dataAttributes) 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 @@ -155,6 +155,7 @@ function _render({ } if (Array.isArray(children) && children.length === 1) { + // TODO: Do we need to cloneVNode + dataAttributes here? return children[0] }