UNPKG

@carbon/ibm-security

Version:

Carbon for Cloud & Cognitive IBM Security UI components

95 lines (87 loc) 4.01 kB
"use strict"; 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 }; };