-
Notifications
You must be signed in to change notification settings - Fork 236
fix(menu): MenuItem focus stealing from input elements on mouseover #5732
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
Conversation
🦋 Changeset detectedLatest commit: 74f9dfc The changes in this PR will be included in the next version bump. This PR includes changesets to release 84 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 |
📚 Branch Preview🔍 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 |
castastrophe
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.
A quick first pass review; I'll validate once the test case is written up!
| `; | ||
| }; | ||
|
|
||
| export const InputsWithMenu = (): TemplateResult => { |
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 a great test case but I don't think we need a new story for it. If you wanted to replicate the behavior in a story, we could probably use the play functionality.
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's already a comprehensive test coverage for the focus behavior in packages/menu/test/menu.test.ts (lines 848-984) with the test 'does not steal focus from input elements on mouseover' that validates all the same input types and scenarios. Let me know if I am missing something here?
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.
My main thought with not adding this as a story is that it's a lot of manual instructions for the viewer of the page to complete to get the experience you're demonstrating. Maybe we defer adding any new stories until we have a chance to talk about Storybook docs more as a team?
tools/base/src/constants.ts
Outdated
| * Regular expression pattern to match Spectrum Web Components input elements. | ||
| * Used to identify components that should maintain focus during menu interactions. | ||
| */ | ||
| export const INPUT_COMPONENT_PATTERN = |
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.
@rubencarvalho Let me know what you think about this! I dig it since we do reuse this logic and it feels like a more global concept to have updated in one place.
castastrophe
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.
If you can add a manual test case to the PR description so I can do that last bit of validation, the rest of this looks really great.
@castastrophe I’ve already added a manual test case to verify this behavior with multiple input elements. Could you let me know if you’re looking to validate something different? |
|
Can you update the Image Hash for this. |
Tachometer resultsChromemenu permalinktest-basic
Firefoxmenu permalinktest-basic
|
@Rajdeepc Oh I see it now! The title was the template language so I thought it hadn't been updated. I validated and it looks great! |
|
This PR introduces a targeted hotfix to address the immediate issue while the broader, permanent solution is being tracked in #5753 |
Pull Request Test Coverage Report for Build 18379049563Details
💛 - Coveralls |
rubencarvalho
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.
Approving to unblock customers - we agreed to follow up with the removal of the focus steal on the MenuItem.
…5732) * fix(menu): added check to find focused element within root context * fix(menu): added story * fix(menu): added test * chore(menu): added changeset * fix(menu): added global const for component input pattern * fix(menu): remove delimiter from the regexp constructor * chore: skipped prod and vrt tests on the new story * chore: fix tests helpers * fix: check for cross root boundary * fix: code comments --------- Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]>
* feat(label): init field label mixin feat(label): init field label mixin * feat(textfield): updated textfiled docs to use label mixin * feat(field-label): added mixin to package exports * feat(field-label): added optional slot name for rendering label slot * docs(textfield): implemented label mixin in stories * test(textfield): added test for slotted label * feat(textfield): added default slot observer for label changes * test(textfield): added tests for slotted label * docs(number-field): updated number field docs based on text field label changes * docs(number-field): updated stories with slotted label * docs(color-field): updated docs with slotted label * feat(field-label): updated interface to include optional slot name for label * feat(combobox): added label slot to combobox * docs(combobox): added slotted label to docs * test(combobox): updates tests with slotted label * fix(combobox): fixed combobox field id for label * feat(field-label): added label slot change handler to mixin * feat(combobox): added slot change handlers * feat(field-label): hide field label if not used * feat(textfield): use field label mixin to observe slot * feat(combobox): use field label mixin to observe slot * feat(combobox): added placeholder * fix(textfield): fixed issue with detecting slot content * fix(field-label): fixed issue with slot content detection in text field * test(textfield): removed unneccessary id attribute * fix(fieldl-label): fixed mixin to allow slot naming * feat(combobox): updated combobox, stories and tests for field label mixin * fix(field-label): corrected linting issues * fix(menu): MenuItem focus stealing from input elements on mouseover (#5732) * fix(menu): added check to find focused element within root context * fix(menu): added story * fix(menu): added test * chore(menu): added changeset * fix(menu): added global const for component input pattern * fix(menu): remove delimiter from the regexp constructor * chore: skipped prod and vrt tests on the new story * chore: fix tests helpers * fix: check for cross root boundary * fix: code comments --------- Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> * fix(field-label): made field id optional for picker * fix(field-label): made field id optional for picker * feat(picker): added field label mixin to pciker and picker stories * fix(textfiled): fixed element name in warning * fix(combobox): fixed element name in warning * docs(picker): updated stories * feat(picker): added field label mizin to picker without affecting pickerBase * docs(textfield): documented default label slot * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * docs(textfield): updated docs with label examples * docs(textfield): fixed issue with tabs * test(textfield): updated test warning text to match revised warning text * docs(combobox): added label and placeholder sections to docs * docs(textfield): changed tabs label * docs(number-field): updated docs with a label section * chore(changeset): added changsets * docs(field-label): added field-label-mixin docs * Apply suggestion from @nikkimk * feat(picker): revert changes * feat(picker): revert changes * chore: updated changesets * docs(color-field): added label docs * chore: updated changesets * docs(combobox): fixed typo Co-authored-by: Casey Eickhoff <[email protected]> * docs(field-label): added JS Docs to mixin * chore: linting fixes * docs(combobox): fixed typo Co-authored-by: Casey Eickhoff <[email protected]> * chore: dropped changeset * docs(color-field): fixed typo Co-authored-by: Marissa Huysentruyt <[email protected]> * chore(combobox): fixed typo * docs(combobox): added side-aligned to story * docs(combobox): fixed typo Co-authored-by: Marissa Huysentruyt <[email protected]> * docs(combobox): fixed typo Co-authored-by: Marissa Huysentruyt <[email protected]> * docs(field-label): added links to mixin docs * docs(field-label): added code type in mixin docs Co-authored-by: Marissa Huysentruyt <[email protected]> * docs(field-label): added code type in mixin docs Co-authored-by: Marissa Huysentruyt <[email protected]> * fix(textfield): simiplified styles getter * fix(textfield): simplified attribute Co-authored-by: Rúben Carvalho <[email protected]> * fix(textfield): simplified attribute * docs(field-label): added more detail to mixin docs Co-authored-by: Rúben Carvalho <[email protected]> * docs(field-label): added more detail to field label mixin docs Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): fixed inherited styles in mixin Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): set side-aligned property to optional Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): added override to styles getter Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): field id should be required * fix(field-label): reverted styles changes to mixin * fix(textfield): fixed styles array * fix(textfield): ensure super styles are CSSResultArray --------- Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Casey Eickhoff <[email protected]> Co-authored-by: Marissa Huysentruyt <[email protected]> Co-authored-by: Rúben Carvalho <[email protected]>
* feat(label): init field label mixin feat(label): init field label mixin * feat(textfield): updated textfiled docs to use label mixin * feat(field-label): added mixin to package exports * feat(field-label): added optional slot name for rendering label slot * docs(textfield): implemented label mixin in stories * test(textfield): added test for slotted label * feat(textfield): added default slot observer for label changes * test(textfield): added tests for slotted label * docs(number-field): updated number field docs based on text field label changes * docs(number-field): updated stories with slotted label * docs(color-field): updated docs with slotted label * feat(field-label): updated interface to include optional slot name for label * feat(combobox): added label slot to combobox * docs(combobox): added slotted label to docs * test(combobox): updates tests with slotted label * fix(combobox): fixed combobox field id for label * feat(field-label): added label slot change handler to mixin * feat(combobox): added slot change handlers * feat(field-label): hide field label if not used * feat(textfield): use field label mixin to observe slot * feat(combobox): use field label mixin to observe slot * feat(combobox): added placeholder * fix(textfield): fixed issue with detecting slot content * fix(field-label): fixed issue with slot content detection in text field * test(textfield): removed unneccessary id attribute * fix(fieldl-label): fixed mixin to allow slot naming * feat(combobox): updated combobox, stories and tests for field label mixin * fix(field-label): corrected linting issues * fix(menu): MenuItem focus stealing from input elements on mouseover (#5732) * fix(menu): added check to find focused element within root context * fix(menu): added story * fix(menu): added test * chore(menu): added changeset * fix(menu): added global const for component input pattern * fix(menu): remove delimiter from the regexp constructor * chore: skipped prod and vrt tests on the new story * chore: fix tests helpers * fix: check for cross root boundary * fix: code comments --------- Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> * fix(field-label): made field id optional for picker * fix(field-label): made field id optional for picker * feat(picker): added field label mixin to pciker and picker stories * fix(textfiled): fixed element name in warning * fix(combobox): fixed element name in warning * docs(picker): updated stories * feat(picker): added field label mizin to picker without affecting pickerBase * docs(textfield): documented default label slot * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * feat(picker): reverting changes until picker is refactored * docs(textfield): updated docs with label examples * docs(textfield): fixed issue with tabs * test(textfield): updated test warning text to match revised warning text * docs(combobox): added label and placeholder sections to docs * docs(textfield): changed tabs label * docs(number-field): updated docs with a label section * chore(changeset): added changsets * docs(field-label): added field-label-mixin docs * Apply suggestion from @nikkimk * feat(picker): revert changes * feat(picker): revert changes * chore: updated changesets * docs(color-field): added label docs * chore: updated changesets * docs(combobox): fixed typo Co-authored-by: Casey Eickhoff <[email protected]> * docs(field-label): added JS Docs to mixin * chore: linting fixes * docs(combobox): fixed typo Co-authored-by: Casey Eickhoff <[email protected]> * chore: dropped changeset * docs(color-field): fixed typo Co-authored-by: Marissa Huysentruyt <[email protected]> * chore(combobox): fixed typo * docs(combobox): added side-aligned to story * docs(combobox): fixed typo Co-authored-by: Marissa Huysentruyt <[email protected]> * docs(combobox): fixed typo Co-authored-by: Marissa Huysentruyt <[email protected]> * docs(field-label): added links to mixin docs * docs(field-label): added code type in mixin docs Co-authored-by: Marissa Huysentruyt <[email protected]> * docs(field-label): added code type in mixin docs Co-authored-by: Marissa Huysentruyt <[email protected]> * fix(textfield): simiplified styles getter * fix(textfield): simplified attribute Co-authored-by: Rúben Carvalho <[email protected]> * fix(textfield): simplified attribute * docs(field-label): added more detail to mixin docs Co-authored-by: Rúben Carvalho <[email protected]> * docs(field-label): added more detail to field label mixin docs Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): fixed inherited styles in mixin Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): set side-aligned property to optional Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): added override to styles getter Co-authored-by: Rúben Carvalho <[email protected]> * fix(field-label): field id should be required * fix(field-label): reverted styles changes to mixin * fix(textfield): fixed styles array * fix(textfield): ensure super styles are CSSResultArray --------- Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Rajdeep Chandra <[email protected]> Co-authored-by: Casey Eickhoff <[email protected]> Co-authored-by: Marissa Huysentruyt <[email protected]> Co-authored-by: Rúben Carvalho <[email protected]>
Description
Fixes MenuItem focus stealing from input elements on mouseover
Solution
isInputElement()method that detects all input typesgetRootNode().activeElementfor reliable focus detection across shadow boundariestextbox,searchbox,combobox,spinbutton,slider) for generic detection/^(SP-SEARCH|SP-TEXTFIELD|SP-NUMBER-FIELD|SP-COMBOBOX|SP-COLOR-FIELD)$/)No Breaking Changes
Technical Details
Before
After
Motivation and context
MenuItem was stealing focus from input elements (searchboxes, textfields, etc.) when users hovered over menu items while typing. This created a poor user experience where:
sp-search,sp-textfield,sp-number-field,sp-combobox,sp-color-field)input,textarea,select) were also affectedRelated issue(s)
Screenshots (if appropriate)
Author's checklist
Reviewer's checklist
patch,minor, ormajorfeaturesManual review test cases
Descriptive Test Statement
Device review