diff --git a/demo/views/demo-all.dust b/demo/views/demo-all.dust index 91f3d6cd5687..754e083fa047 100644 --- a/demo/views/demo-all.dust +++ b/demo/views/demo-all.dust @@ -79,7 +79,7 @@ {/links} -
+
{?links} {#links} {?items} diff --git a/src/components/dropdown/dropdown.js b/src/components/dropdown/dropdown.js index 841aee6ed9e6..ce4f91d7d112 100644 --- a/src/components/dropdown/dropdown.js +++ b/src/components/dropdown/dropdown.js @@ -1,10 +1,11 @@ import mixin from '../../globals/js/misc/mixin'; import createComponent from '../../globals/js/mixins/create-component'; import initComponentBySearch from '../../globals/js/mixins/init-component-by-search'; +import trackBlur from '../../globals/js/mixins/track-blur'; import eventMatches from '../../globals/js/misc/event-matches'; import on from '../../globals/js/misc/on'; -class Dropdown extends mixin(createComponent, initComponentBySearch) { +class Dropdown extends mixin(createComponent, initComponentBySearch, trackBlur) { /** * A selector with drop downs. * @extends CreateComponent @@ -28,8 +29,6 @@ class Dropdown extends mixin(createComponent, initComponentBySearch) { */ this.hDocumentClick = on(this.element.ownerDocument, 'click', (event) => { this._toggle(event); }); - this._setCloseOnBlur(); - this.element.addEventListener('keydown', (event) => { this._handleKeyDown(event); }); this.element.addEventListener('click', (event) => { const item = eventMatches(event, this.options.selectorItem); @@ -162,16 +161,10 @@ class Dropdown extends mixin(createComponent, initComponentBySearch) { } /** - * Sets an event handler to document for "close on blur" behavior. + * Closes the dropdown menu if this component loses focus. */ - _setCloseOnBlur() { - const hasFocusin = 'onfocusin' in window; - const focusinEventName = hasFocusin ? 'focusin' : 'focus'; - this.hFocusIn = on(this.element.ownerDocument, focusinEventName, (event) => { - if (!this.element.contains(event.target)) { - this.element.classList.remove('bx--dropdown--open'); - } - }, !hasFocusin); + handleBlur() { + this.element.classList.remove('bx--dropdown--open'); } /** diff --git a/src/components/floating-menu/floating-menu.js b/src/components/floating-menu/floating-menu.js index b575a11d8b3c..7ace648cc684 100644 --- a/src/components/floating-menu/floating-menu.js +++ b/src/components/floating-menu/floating-menu.js @@ -1,9 +1,11 @@ import mixin from '../../globals/js/misc/mixin'; import createComponent from '../../globals/js/mixins/create-component'; import eventedShowHideState from '../../globals/js/mixins/evented-show-hide-state'; +import trackBlur from '../../globals/js/mixins/track-blur'; +import getLaunchingDetails from '../../globals/js/misc/get-launching-details'; import optimizedResize from '../../globals/js/misc/resize'; -class FloatingMenu extends mixin(createComponent, eventedShowHideState) { +class FloatingMenu extends mixin(createComponent, eventedShowHideState, trackBlur) { /** * Floating menu. * @extends CreateComponent @@ -41,6 +43,18 @@ class FloatingMenu extends mixin(createComponent, eventedShowHideState) { } } + /** + * Focuses back on the trigger button if this component loses focus. + */ + handleBlur(event) { + if (this.element.classList.contains(this.options.classShown)) { + this.changeState('hidden', getLaunchingDetails(event)); + if (this.element.contains(event.relatedTarget) && event.target !== this.options.refNode) { + this.options.refNode.focus(); + } + } + } + /** * @private * @returns {Element} The element that this menu should be placed to. @@ -162,6 +176,7 @@ class FloatingMenu extends mixin(createComponent, eventedShowHideState) { } this._getContainer().appendChild(this.element); this._place(); + (this.element.querySelector(this.options.selectorPrimaryFocus) || this.element).focus(); } if (state === 'hidden' && this.hResize) { this.hResize.release(); @@ -180,6 +195,7 @@ class FloatingMenu extends mixin(createComponent, eventedShowHideState) { static options = { selectorContainer: '[data-floating-menu-container]', + selectorPrimaryFocus: '[data-floating-menu-primary-focus]', attribDirection: 'data-floating-menu-direction', classShown: '', // Should be provided from options arg in constructor classRefShown: '', // Should be provided from options arg in constructor diff --git a/src/components/overflow-menu/overflow-menu.html b/src/components/overflow-menu/overflow-menu.html index 7cff1911feab..8ba9d414e2bb 100644 --- a/src/components/overflow-menu/overflow-menu.html +++ b/src/components/overflow-menu/overflow-menu.html @@ -4,9 +4,9 @@ -