/* @oracle/oraclejet-preact: undefined */
'use strict';

var hooks = require('preact/hooks');
var keys = require('./keys-25710458.js');
var collectionUtils = require('./collectionUtils-7ae57f89.js');

/**
 * Hook for handling Tabbable mode set provider components.
 *
 * @param rootRef - a Ref to the root element of the consuming component
 * @param keyExtractor - function to extract the key based on provided element
 * @param currentKey - current key navigation "cursor" is on
 * @param onCurrentKeyChange - optional callback to notify when the currentKey should change
 * @param keySupportsTabbable - optional callback to prevent tabbable mode from being entered on non-tabbable keys
 * @param keyComparator - optional callback to compare the equality of two keys
 * @returns isCurrentTabbableKey - callback for parent to check if key is in interactive mode
 * @returns tabbableSetProps - event handlers mode relies on
 * @returns getCurrentTabbableKey - callback to get the current tabbable key
 * @returns setCurrentTabbableKey - callback to set the current tabbable key
 */
function useTabbableModeSet(rootRef, keyExtractor, currentKey, onCurrentKeyChange, keySupportsTabbable, keyComparator) {
    // Track which row is in actionable in state
    const [currentTabbableKey, setCurrentTabbableKey] = hooks.useState();
    const keyEquals = hooks.useCallback((key1, key2) => {
        if (keyComparator) {
            return keyComparator(key1, key2);
        }
        return key1 === key2;
    }, [keyComparator]);
    const disableTabbableMode = hooks.useCallback((target, isKeyboardEvent = false) => {
        setCurrentTabbableKey(undefined);
        // handle clean-up on disabling of the mode
        if (collectionUtils.getElementContainsFunc(rootRef.current, true)(target) && isKeyboardEvent) {
            rootRef.current?.focus();
        }
    }, [rootRef, setCurrentTabbableKey]);
    const enableTabbableMode = hooks.useCallback((key) => {
        setCurrentTabbableKey(key);
        if (onCurrentKeyChange && !keyEquals(key, currentKey)) {
            onCurrentKeyChange({ value: key });
        }
    }, [currentKey, keyEquals, onCurrentKeyChange, setCurrentTabbableKey]);
    const isCurrentTabbableKey = hooks.useCallback((key) => {
        return keyEquals(key, currentTabbableKey);
    }, [currentTabbableKey, keyEquals]);
    const getCurrentTabbableKey = hooks.useCallback(() => {
        return currentTabbableKey;
    }, [currentTabbableKey]);
    const onFocus = (event) => {
        // if the root is focused while tabbable, exit tabbable mode
        if (event.target === rootRef.current) {
            if (!isCurrentTabbableKey(undefined)) {
                disableTabbableMode(event.target);
            }
        }
        else {
            const key = keyExtractor(event.target);
            if (keys.isKeyDefined(key) && !isCurrentTabbableKey(key)) {
                enableTabbableMode(key);
            }
        }
    };
    const onBlur = (event) => {
        if (!event.relatedTarget ||
            !collectionUtils.getElementContainsFunc(rootRef.current, true)(event.relatedTarget)) {
            disableTabbableMode(event.relatedTarget);
        }
    };
    const onKeyDown = hooks.useCallback((event) => {
        if (currentKey != null && (keySupportsTabbable == null || keySupportsTabbable(currentKey))) {
            if (event.key === 'F2') {
                isCurrentTabbableKey(currentKey)
                    ? disableTabbableMode(event.target, true)
                    : enableTabbableMode(currentKey);
            }
            else if (event.key === 'Esc' || event.key === 'Escape') {
                disableTabbableMode(event.target, true);
            }
        }
    }, [currentKey, disableTabbableMode, enableTabbableMode, keySupportsTabbable, isCurrentTabbableKey]);
    const tabbableSetProps = {
        onFocus,
        onBlur,
        onKeyDown
    };
    return [isCurrentTabbableKey, tabbableSetProps, getCurrentTabbableKey, setCurrentTabbableKey];
}

exports.useTabbableModeSet = useTabbableModeSet;
//# sourceMappingURL=useTabbableModeSet-a777d587.js.map
