@carbon/ibm-security
Version:
Carbon for Cloud & Cognitive IBM Security UI components
95 lines (87 loc) • 4.01 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useComponentFocus = exports.trapTabFocus = exports.keyableElements = exports.focusableElements = exports.focusFirstElement = void 0;
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireDefault(require("react"));
/**
* @file Helper methods for element focusing.
* @copyright IBM Security 2018 - 2021
*/
var focusableElements = exports.focusableElements = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), [tabindex="0"]';
var keyableElements = exports.keyableElements = 'li:not([disabled])';
var focusFirstElement = exports.focusFirstElement = function focusFirstElement(element) {
var focusable = element.querySelector(focusableElements);
if (focusable) {
focusable.focus();
}
};
var trapTabFocus = exports.trapTabFocus = function trapTabFocus(element, event) {
var focusable = element.querySelectorAll(focusableElements);
if (focusable.length > 0) {
if (event.target === focusable[0] && event.shiftKey) {
event.preventDefault();
focusable[focusable.length - 1].focus();
} else if (event.target === focusable[focusable.length - 1] && !event.shiftKey) {
event.preventDefault();
focusable[0].focus();
}
}
};
/**
* Manage the focus and blur event of an element that contains multiple focusable elements. This
* hook is useful when you want to allow users to shift keyboard focus inside component and only
* apply blur effects when the keyboard focus has completely left this component.
*
* @param {number} [timeoutDelay=10] Millisecond delay for the blur effect to take place. This
* should not be less than 10 to give the browser time to register the subsequent focus event first.
*
* @returns {{createFocusHandler: Function, createBlurHandler: Function}} Utility functions to
* create the focus and blur handlers that apply the necessary effects or state changes.
*/
var useComponentFocus = exports.useComponentFocus = function useComponentFocus() {
var timeoutDelay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
var _React$useState = _react.default.useState(undefined),
_React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
blurTimer = _React$useState2[0],
setBlurTimer = _React$useState2[1];
// Clear any timeouts before unmounting.
_react.default.useEffect(function () {
return function () {
return clearTimeout(blurTimer);
};
}, [blurTimer]);
// Clears out the current timeout and sets the new one.
var setNewBlurTimer = function setNewBlurTimer(newTimeout) {
setBlurTimer(function (currentTimeout) {
clearTimeout(currentTimeout);
return newTimeout;
});
};
// Clear out any existing timer because this focus handler call indicates that the keyboard focus
// did not leave the component invoking this hook. Then apply the provided focus side effect.
var createFocusHandler = function createFocusHandler(callback) {
return function (event) {
setNewBlurTimer(undefined);
callback(event);
};
};
// Set a short delay to allow the browser to detect the subsequent focus event which should
// determine if the keyboard focus has completely left the component invoking this hook. If the
// timeout is allowed to execute, the provided side effect is applied.
var createBlurHandler = function createBlurHandler(callback) {
return function (event) {
var newTimeout = setTimeout(function () {
return callback(event);
}, timeoutDelay);
setNewBlurTimer(newTimeout);
};
};
// Return the two functions for the consumer to implement the necessary side effects.
return {
createFocusHandler: createFocusHandler,
createBlurHandler: createBlurHandler
};
};