-
Notifications
You must be signed in to change notification settings - Fork 842
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
[EuiSelectable] Disable arrow key navigation on non-search/listbox children #6631
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
419843c
[REVERT ME] Test custom interactive child within EuiSelectable
cee-chen 480dbb9
Prevent all keys (not just enter/esc) from working if focus is not on…
cee-chen 1413d9e
Smooth out focus/active option behavior when focusing/blurring to non…
cee-chen d9ef9e7
changelog
cee-chen 80e0402
Revert "[REVERT ME] Test custom interactive child within EuiSelectable"
cee-chen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import React, { | |
ReactElement, | ||
KeyboardEvent, | ||
MouseEvent, | ||
FocusEvent, | ||
} from 'react'; | ||
import classNames from 'classnames'; | ||
import { CommonProps, ExclusiveUnion } from '../common'; | ||
|
@@ -280,14 +281,25 @@ export class EuiSelectable<T = {}> extends Component< | |
} | ||
} | ||
|
||
isFocusOnSearchOrListBox = (target: EventTarget | null) => { | ||
const searchHasFocus = this.props.searchable && target === this.inputRef; | ||
|
||
const listBox = this.optionsListRef.current?.listBoxRef?.parentElement; | ||
const listBoxContainsFocus = | ||
target instanceof Node && listBox?.contains(target); | ||
const listBoxHasFocus = target === listBox || listBoxContainsFocus; | ||
|
||
return searchHasFocus || listBoxHasFocus; | ||
}; | ||
|
||
onMouseDown = () => { | ||
// Bypass onFocus when a click event originates from this.containerRef. | ||
// Prevents onFocus from scrolling away from a clicked option and negating the selection event. | ||
// https://github.com/elastic/eui/issues/4147 | ||
this.preventOnFocus = true; | ||
}; | ||
|
||
onFocus = () => { | ||
onFocus = (event?: FocusEvent) => { | ||
if (this.preventOnFocus) { | ||
this.preventOnFocus = false; | ||
return; | ||
|
@@ -300,6 +312,10 @@ export class EuiSelectable<T = {}> extends Component< | |
return; | ||
} | ||
|
||
if (event && !this.isFocusOnSearchOrListBox(event.target)) { | ||
return; | ||
} | ||
|
||
const firstSelected = this.state.visibleOptions.findIndex( | ||
(option) => option.checked && !option.disabled && !option.isGroupLabel | ||
); | ||
|
@@ -319,6 +335,15 @@ export class EuiSelectable<T = {}> extends Component< | |
onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => { | ||
const optionsList = this.optionsListRef.current; | ||
|
||
// Check if the user is interacting with something other than the | ||
// searchbox or selection list. If so, the user may be attempting to | ||
// interact with the search clear button or a totally custom button, | ||
// and listbox keyboard navigation/selection should not be triggered. | ||
if (!this.isFocusOnSearchOrListBox(event.target)) { | ||
this.setState({ activeOptionIndex: undefined, isFocused: false }); | ||
return; | ||
} | ||
|
||
switch (event.key) { | ||
case keys.ARROW_UP: | ||
event.preventDefault(); | ||
|
@@ -343,19 +368,6 @@ export class EuiSelectable<T = {}> extends Component< | |
if (event.target === this.inputRef && event.key === keys.SPACE) { | ||
return; | ||
} | ||
// Check if the user is interacting with something other than the | ||
// searchbox or selection list. If not, the user is attempting to | ||
// interact with an internal button such as the clear button, | ||
// and the event should not be altered. | ||
if ( | ||
!( | ||
event.target === this.inputRef || | ||
event.target === | ||
this.optionsListRef.current?.listBoxRef?.parentElement | ||
) | ||
) { | ||
return; | ||
} | ||
} | ||
event.preventDefault(); | ||
event.stopPropagation(); | ||
|
@@ -443,9 +455,7 @@ export class EuiSelectable<T = {}> extends Component< | |
|
||
onContainerBlur = (e: React.FocusEvent) => { | ||
// Ignore blur events when moving from search to option to avoid activeOptionIndex conflicts | ||
if ( | ||
((e.relatedTarget as Node)?.firstChild as HTMLElement)?.id === this.listId | ||
) { | ||
if (this.isFocusOnSearchOrListBox(e.relatedTarget)) { | ||
Comment on lines
-446
to
+458
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The goal of this change was just DRYness, I tested the 'double click' bug fixed/reported in #5021 fairly thoroughly in Chrome in |
||
return; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
**Bug fixes** | ||
|
||
- Fixed `EuiSelectable` to no longer show active selection state or respond to the Up/Down arrow keys when focus is inside the selectable container, but not on the searchbox or listbox. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
[Attaching to a random line for threading]
@miukimiu, @1Copenut - should non-searchable EuiSelectable's have this slightly-but-not-really visible focus ring around the listbox? (Note: this is happening on production, not just this PR)
Above screenshot is from FF, but it's happening on Chrome/Edge/Safari as well.
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.
Tested in Chrome. I think it shouldn't have the visible focus ring around the listbox. It doesn't look good.
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.
Thanks! I'll open up a follow-up issue for this since it's already happening in production: #6633