From aa47bd0fdc424e1253a17a21e00775dcde641641 Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 16 Jan 2024 10:06:49 -0500 Subject: [PATCH 1/2] =?UTF-8?q?Don=E2=80=99t=20override=20explicit=20disab?= =?UTF-8?q?led=20prop=20inside=20``?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/menu/menu.test.tsx | 41 ++++++++++++++++ .../src/components/menu/menu.test.tsx | 48 ++++++++++++++++++- .../src/components/menu/menu.ts | 4 +- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/packages/@headlessui-react/src/components/menu/menu.test.tsx b/packages/@headlessui-react/src/components/menu/menu.test.tsx index 61dba9ff76..2a26ef11aa 100644 --- a/packages/@headlessui-react/src/components/menu/menu.test.tsx +++ b/packages/@headlessui-react/src/components/menu/menu.test.tsx @@ -448,6 +448,47 @@ describe('Rendering', () => { assertMenu({ state: MenuState.InvisibleUnmounted }) }) ) + + it('should not override an explicit disabled prop on MenuItems child', async () => { + render( + + Trigger + + {({ disabled }) => } + {({ disabled }) => } + + {({ disabled }) => } + + + + ) + + assertMenuButton({ + state: MenuState.InvisibleUnmounted, + }) + assertMenu({ state: MenuState.InvisibleUnmounted }) + + getMenuButton()?.focus() + + await press(Keys.Enter) + + assertMenuButton({ + state: MenuState.Visible, + }) + assertMenu({ state: MenuState.Visible }) + assertMenuItem(getMenuItems()[0], { + tag: 'button', + attributes: { 'data-focus': '' }, + }) + assertMenuItem(getMenuItems()[1], { + tag: 'button', + attributes: {}, + }) + assertMenuItem(getMenuItems()[2], { + tag: 'button', + attributes: { disabled: '' }, + }) + }) }) it('should guarantee the order of DOM nodes when performing actions', async () => { diff --git a/packages/@headlessui-vue/src/components/menu/menu.test.tsx b/packages/@headlessui-vue/src/components/menu/menu.test.tsx index 9fc698e9da..314ccdb44f 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.test.tsx +++ b/packages/@headlessui-vue/src/components/menu/menu.test.tsx @@ -686,6 +686,53 @@ describe('Rendering', () => { }) }) + it('should not override an explicit disabled prop on MenuItems child', async () => { + renderTemplate(jsx` + + Trigger + + + + + + + + + + + + + `) + + assertMenuButton({ + state: MenuState.InvisibleUnmounted, + attributes: { id: 'headlessui-menu-button-1' }, + }) + assertMenu({ state: MenuState.InvisibleUnmounted }) + + getMenuButton()?.focus() + + await press(Keys.Enter) + + assertMenuButton({ + state: MenuState.Visible, + attributes: { id: 'headlessui-menu-button-1' }, + }) + assertMenu({ state: MenuState.Visible }) + assertMenuItem(getMenuItems()[0], { + tag: 'button', + attributes: { 'data-active': 'true' }, + }) + assertMenuItem(getMenuItems()[1], { + tag: 'button', + attributes: { 'data-active': 'false' }, + }) + assertMenuItem(getMenuItems()[2], { + tag: 'button', + attributes: { 'data-active': 'false', disabled: '' }, + }) + }) + it('should yell when we render a MenuItem using a template `as` prop that contains multiple children', async () => { expect.hasAssertions() @@ -712,7 +759,6 @@ describe('Rendering', () => { 'The current component is rendering a "template".', 'However we need to passthrough the following props:', ' - aria-disabled', - ' - disabled', ' - id', ' - onClick', ' - onFocus', diff --git a/packages/@headlessui-vue/src/components/menu/menu.ts b/packages/@headlessui-vue/src/components/menu/menu.ts index 39fc6ddee2..e6fa936b90 100644 --- a/packages/@headlessui-vue/src/components/menu/menu.ts +++ b/packages/@headlessui-vue/src/components/menu/menu.ts @@ -563,16 +563,14 @@ export let MenuItem = defineComponent({ } return () => { - let { disabled } = props + let { id, disabled, ...theirProps } = props let slot = { active: active.value, disabled, close: api.closeMenu } - let { id, ...theirProps } = props let ourProps = { id, ref: internalItemRef, role: 'menuitem', tabIndex: disabled === true ? undefined : -1, 'aria-disabled': disabled === true ? true : undefined, - disabled: undefined, // Never forward the `disabled` prop onClick: handleClick, onFocus: handleFocus, onPointerenter: handleEnter, From a59af83ec64b2a73ce34a406f4fe63d43e84dd8e Mon Sep 17 00:00:00 2001 From: Jordan Pittman Date: Tue, 16 Jan 2024 15:30:17 -0500 Subject: [PATCH 2/2] Update changelog --- packages/@headlessui-vue/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/@headlessui-vue/CHANGELOG.md b/packages/@headlessui-vue/CHANGELOG.md index 278a69d020..8c5d8fc19d 100644 --- a/packages/@headlessui-vue/CHANGELOG.md +++ b/packages/@headlessui-vue/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Expose `disabled` state on `` component ([#2918](https://github.com/tailwindlabs/headlessui/pull/2918)) - Prevent default behaviour when clicking outside of a `DialogPanel` ([#2919](https://github.com/tailwindlabs/headlessui/pull/2919)) +- Don’t override explicit `disabled` prop for components inside `` ([#2929](https://github.com/tailwindlabs/headlessui/pull/2929)) ## [1.7.17] - 2024-01-08