diff --git a/src/components/context_menu/__snapshots__/context_menu_panel.test.js.snap b/src/components/context_menu/__snapshots__/context_menu_panel.test.js.snap index ff0f3034929..2fbd9f164b9 100644 --- a/src/components/context_menu/__snapshots__/context_menu_panel.test.js.snap +++ b/src/components/context_menu/__snapshots__/context_menu_panel.test.js.snap @@ -1,5 +1,322 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`EuiContextMenu is rendered 1`] = ` +
+`; + +exports[`EuiContextMenu props panels and initialPanelId allows you to click the title button to go back to the previous panel 1`] = ` +
+
+ +
+
+ 2 +
+
+
+
+`; + +exports[`EuiContextMenu props panels and initialPanelId allows you to click the title button to go back to the previous panel 2`] = ` +
+
+ +
+
+ 2 +
+
+
+
+ +
+ + + +
+
+
+`; + +exports[`EuiContextMenu props panels and initialPanelId renders the referenced panel 1`] = ` +
+
+ +
+
+ 2 +
+
+
+
+`; + exports[`EuiContextMenuPanel is rendered 1`] = `
new Promise(resolve => { +export const tick = (ms = 0) => new Promise(resolve => { setTimeout(resolve, ms); }); diff --git a/src/components/context_menu/context_menu_panel.js b/src/components/context_menu/context_menu_panel.js index f68dd942671..9932cfedfad 100644 --- a/src/components/context_menu/context_menu_panel.js +++ b/src/components/context_menu/context_menu_panel.js @@ -154,47 +154,50 @@ export class EuiContextMenuPanel extends Component { }; updateFocus() { - // If this panel has lost focus, then none of its content should be focused. - if (!this.props.hasFocus) { - if (this.panel.contains(document.activeElement)) { - document.activeElement.blur(); + // Give positioning time to render before focus is applied. Otherwise page jumps. + requestAnimationFrame(() => { + // If this panel has lost focus, then none of its content should be focused. + if (!this.props.hasFocus) { + if (this.panel.contains(document.activeElement)) { + document.activeElement.blur(); + } + return; } - return; - } - - // Setting focus while transitioning causes the animation to glitch, so we have to wait - // until it's finished before we focus anything. - if (this.state.isTransitioning) { - return; - } - // If there aren't any items then this is probably a form or something. - if (!this.state.menuItems.length) { - // If we've already focused on something inside the panel, everything's fine. - if (this.panel.contains(document.activeElement)) { + // Setting focus while transitioning causes the animation to glitch, so we have to wait + // until it's finished before we focus anything. + if (this.state.isTransitioning) { return; } - // Otherwise let's focus the first tabbable item and expedite input from the user. - if (this.content) { - const tabbableItems = tabbable(this.content); - if (tabbableItems.length) { - tabbableItems[0].focus(); + // If there aren't any items then this is probably a form or something. + if (!this.state.menuItems.length) { + // If we've already focused on something inside the panel, everything's fine. + if (this.panel.contains(document.activeElement)) { + return; + } + + // Otherwise let's focus the first tabbable item and expedite input from the user. + if (this.content) { + const tabbableItems = tabbable(this.content); + if (tabbableItems.length) { + tabbableItems[0].focus(); + } } + return; } - return; - } - // If an item is focused, focus it. - if (this.state.focusedItemIndex !== undefined) { - this.state.menuItems[this.state.focusedItemIndex].focus(); - return; - } + // If an item is focused, focus it. + if (this.state.focusedItemIndex !== undefined) { + this.state.menuItems[this.state.focusedItemIndex].focus(); + return; + } - // Focus on the panel as a last resort. - if (!this.panel.contains(document.activeElement)) { - this.panel.focus(); - } + // Focus on the panel as a last resort. + if (!this.panel.contains(document.activeElement)) { + this.panel.focus(); + } + }); } onTransitionComplete = () => { diff --git a/src/components/context_menu/context_menu_panel.test.js b/src/components/context_menu/context_menu_panel.test.js index 35dab1f7479..04d33fa2287 100644 --- a/src/components/context_menu/context_menu_panel.test.js +++ b/src/components/context_menu/context_menu_panel.test.js @@ -11,6 +11,8 @@ import { EuiContextMenuItem, } from './context_menu_item'; +import { tick } from './context_menu.test'; + import { keyCodes } from '../../services'; const items = [ @@ -162,7 +164,7 @@ describe('EuiContextMenuPanel', () => { }); describe('initialFocusedItemIndex', () => { - it('sets focus on the item occupying that index', () => { + it('sets focus on the item occupying that index', async () => { const component = mount( { /> ); + await tick(20); + expect(findTestSubject(component, 'itemB').getDOMNode()).toBe(document.activeElement); }); }); @@ -269,13 +273,15 @@ describe('EuiContextMenuPanel', () => { describe('behavior', () => { describe('focus', () => { - it('is set on the first focusable element by default if there are no items and hasFocus is true', () => { + it('is set on the first focusable element by default if there are no items and hasFocus is true', async () => { const component = mount(