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 @@
-