diff --git a/CHANGELOG.md b/CHANGELOG.md
index bbfb6daf648..aae3e0ce6df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
- Fixed content in `EuiFilterButton` when `numFilters` is not passed ([#5012](https://github.com/elastic/eui/pull/5012))
- Fixed default value of `outsideClickCloses` prop of `EuiFlyout` ([#5027](https://github.com/elastic/eui/pull/5027))
+- Fixed `EuiSelectable`'s double click bug ([#5021](https://github.com/elastic/eui/pull/5021))
## [`37.2.0`](https://github.com/elastic/eui/tree/v37.2.0)
diff --git a/src/components/selectable/__snapshots__/selectable.test.tsx.snap b/src/components/selectable/__snapshots__/selectable.test.tsx.snap
index 96a0b54fd75..35ce39017b3 100644
--- a/src/components/selectable/__snapshots__/selectable.test.tsx.snap
+++ b/src/components/selectable/__snapshots__/selectable.test.tsx.snap
@@ -54,3 +54,43 @@ exports[`EuiSelectable props singleSelection 1`] = `
class="euiSelectable"
/>
`;
+
+exports[`EuiSelectable should not reset the activeOptionIndex nor isFocused when EuiSelectable is blurred in favour of its popover 1`] = `
+Object {
+ "activeOptionIndex": 0,
+ "isFocused": true,
+ "searchValue": "",
+ "visibleOptions": Array [
+ Object {
+ "data-test-subj": "titanOption",
+ "label": "Titan",
+ },
+ Object {
+ "label": "Enceladus",
+ },
+ Object {
+ "label": "Pandora is one of Saturn's moons, named for a Titaness of Greek mythology",
+ },
+ ],
+}
+`;
+
+exports[`EuiSelectable should not reset the activeOptionIndex nor isFocused when EuiSelectable is blurred in favour of its popover 2`] = `
+Object {
+ "activeOptionIndex": 0,
+ "isFocused": true,
+ "searchValue": "",
+ "visibleOptions": Array [
+ Object {
+ "data-test-subj": "titanOption",
+ "label": "Titan",
+ },
+ Object {
+ "label": "Enceladus",
+ },
+ Object {
+ "label": "Pandora is one of Saturn's moons, named for a Titaness of Greek mythology",
+ },
+ ],
+}
+`;
diff --git a/src/components/selectable/selectable.test.tsx b/src/components/selectable/selectable.test.tsx
index ef63c131616..3eda2107cb6 100644
--- a/src/components/selectable/selectable.test.tsx
+++ b/src/components/selectable/selectable.test.tsx
@@ -36,6 +36,31 @@ describe('EuiSelectable', () => {
expect(component).toMatchSnapshot();
});
+ test('should not reset the activeOptionIndex nor isFocused when EuiSelectable is blurred in favour of its popover', () => {
+ const component = mount(
+
+ {(list, search) => (
+ <>
+ {list}
+ {search}
+ >
+ )}
+
+ );
+
+ component.setState({
+ activeOptionIndex: 0,
+ isFocused: true,
+ });
+ expect(component.state()).toMatchSnapshot();
+
+ component.find('.euiSelectable').simulate('blur', {
+ relatedTarget: { firstChild: { id: 'generated-id_listbox' } },
+ });
+ component.update();
+ expect(component.state()).toMatchSnapshot();
+ });
+
describe('props', () => {
test('searchable', () => {
const component = render();
diff --git a/src/components/selectable/selectable.tsx b/src/components/selectable/selectable.tsx
index 409522a777d..d33c7e6698e 100644
--- a/src/components/selectable/selectable.tsx
+++ b/src/components/selectable/selectable.tsx
@@ -330,7 +330,12 @@ export class EuiSelectable extends Component<
onContainerBlur = (e: React.FocusEvent) => {
// Ignore blur events when moving from search to option to avoid activeOptionIndex conflicts
- if (this.containerRef.current!.contains(e.relatedTarget as Node)) return;
+ if (
+ ((e.relatedTarget as Node)?.firstChild as HTMLElement)?.id ===
+ this.rootId('listbox')
+ ) {
+ return;
+ }
this.setState({
activeOptionIndex: undefined,