-
Notifications
You must be signed in to change notification settings - Fork 235
fix(menu): ipad menu item click #5901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: b2194cc The changes in this PR will be included in the next version bump. This PR includes changesets to release 78 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
3ece1a2 to
7523d6a
Compare
📚 Branch Preview Links🔍 First Generation Visual Regression Test ResultsWhen a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:
Deployed to Azure Blob Storage: If the changes are expected, update the |
| expect(el.optionsMenu.shouldSupportDragAndSelect).to.be.true; | ||
| }); | ||
|
|
||
| it('dispatches change event when menu item is clicked on touch device', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right @marissahuysentruyt I too see this error while running locally.
The menu wasn't fully ready when clicking so the test was timing out. I added a check to wait for the menu to update. What is happening here is that the menu renders asynchronously in an overlay. updateComplete ensures Lit has finished rendering and elementUpdated ensures that the DOM reflects those changes. We need these two boundaries to make sure menu is ready in the DOM for clicks.
Added a fix here
cc @iuliauta
…spectrum-web-components into iuta/menu-item-ipad-click
Rajdeepc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests look ok! el.isTouchDevice.matches is brittle though but since Playwright lacks the capability of touch device testing this is good for now.
| '@spectrum-web-components/reactive-controllers': patch | ||
| --- | ||
|
|
||
| **Added**: IS_TOUCH_DEVICE media query constant | ||
|
|
||
| - Added IS_TOUCH_DEVICE constant: '(hover: none) and (pointer: coarse)' | ||
| - Detects any touch-capable device regardless of screen size | ||
| - Unlike IS_MOBILE (max-width: 743px), this matches iPads and all tablets |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changeset is not needed. You can remove it
| **Fixed**: iPad menu item click events not working | ||
|
|
||
| - Changed from isMobile to isTouchDevice for shouldSupportDragAndSelect property | ||
| - Fixes issue where menu items in action menus on iPad/tablets would not dispatch click events | ||
| - All touch devices (including iPads with screen widths >743px) now correctly use click events instead of drag-and-select behavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| **Fixed**: iPad menu item click events not working | |
| - Changed from isMobile to isTouchDevice for shouldSupportDragAndSelect property | |
| - Fixes issue where menu items in action menus on iPad/tablets would not dispatch click events | |
| - All touch devices (including iPads with screen widths >743px) now correctly use click events instead of drag-and-select behavior | |
| **Fixed**: click events are now dispatched from menu-items on touch devices | |
| - All touch devices (including iPads with screen widths >743px) now correctly use click events instead of drag-and-select behavior |
| * so that we can test the touch device behavior. | ||
| */ | ||
| el.isTouchDevice.matches = true; | ||
| el.bindEvents(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bindEvents() might add duplicate listeners. You will loose idempotency here. Call it only once in the fixture setup or reset the environment between tests.
| const menuItem = el.querySelector( | ||
| 'sp-menu-item[value="option-2"]' | ||
| ) as MenuItem; | ||
| expect(menuItem).to.not.be.null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you query for menu item with el.querySelector you may miss items in shadow DOM. you should query the menu through el.optionsMenu (e.g. el.optionsMenu.childItems[index] or el.optionsMenu.querySelector(...)) which you already wait for with waitUntil.
| afterEach(() => { | ||
| // Reset touch device simulation. | ||
| if (el && el.isTouchDevice) { | ||
| el.isTouchDevice.matches = false; | ||
| } | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is incomplete. You have tests which also modify el.isMobile.matches in one test but don’t reset that value. Either restore the matchMedia stub in afterEach or explicitly reset both isTouchDevice and isMobile.
| expect(el.optionsMenu.shouldSupportDragAndSelect).to.be.true; | ||
| }); | ||
|
|
||
| it('dispatches change event when menu item is clicked on touch device', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right @marissahuysentruyt I too see this error while running locally.
The menu wasn't fully ready when clicking so the test was timing out. I added a check to wait for the menu to update. What is happening here is that the menu renders asynchronously in an overlay. updateComplete ensures Lit has finished rendering and elementUpdated ensures that the DOM reflects those changes. We need these two boundaries to make sure menu is ready in the DOM for clicks.
Added a fix here
cc @iuliauta

Description
Issue
Menu items (
<sp-menu-item>) in<sp-action-menu>were not registering click events on iPad devices, while the same items wrapped in<sp-menu-group>worked correctly. This issue was reported in GitHub Issue #5706.Symptoms
<sp-action-menu>don't fire click eventspointerdownandpointerupevents fire correctly<sp-menu-group>Root cause
The issue stemmed from an incorrect device detection strategy that didn't properly account for tablet devices with touch input.
Technical details
Device detection query
This query only matched devices with:
iPad devices don't match because their screen width is typically 768px-1024px.
The shouldSupportDragAndSelect flag
In
packages/picker/src/InteractionController.ts, the code set:Since iPad didn't match
IS_MOBILE,shouldSupportDragAndSelectwas set totrue.Event handling conflict
In
packages/menu/src/Menu.ts:When
shouldSupportDragAndSelect = true:handlePointerupprocesses the selection and setspointerUpTargethandleClicksees thatpointerUpTarget === event.targetand returns earlyWhy menu-group worked
When menu items are wrapped in
<sp-menu-group>, the additional DOM wrapper causes theevent.targetin the click handler to sometimes differ from thepointerUpTargetset in the pointerup handler, allowing the click to proceed.Solution
We introduced a new
IS_TOUCH_DEVICEmedia query that detects any device with touch input, regardless of screen size:This query matches:
The
PickerBaseclass now includes anisTouchDeviceproperty:The menu's
shouldSupportDragAndSelectproperty is set directly in the template when the menu is rendered:This ensures that on all touch devices (including iPads), the menu uses click events instead of the drag-and-select pattern, preventing the event handling conflict.
Motivation and context
Related issue(s)
Screenshots (if appropriate)
Author's checklist
Reviewer's checklist
patch,minor, ormajorfeaturesManual review test cases
iPad Menu Item click test
Descriptive Test Statement
Device review