"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { createActiveDescendantChangeEvent: function() { return createActiveDescendantChangeEvent; }, useActiveDescendant: function() { return useActiveDescendant; } }); const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); const _reactutilities = require("@fluentui/react-utilities"); const _reacttabster = require("@fluentui/react-tabster"); const _useOptionWalker = require("./useOptionWalker"); const _constants = require("./constants"); const _scrollIntoView = require("./scrollIntoView"); const createActiveDescendantChangeEvent = (detail)=>new CustomEvent('activedescendantchange', { bubbles: true, cancelable: false, composed: true, detail }); function useActiveDescendant(options) { const { imperativeRef, matchOption: matchOptionUnstable } = options; const focusVisibleRef = _react.useRef(false); const shouldShowFocusVisibleAttrRef = _react.useRef(true); const activeIdRef = _react.useRef(null); const lastActiveIdRef = _react.useRef(null); const activeParentRef = _react.useRef(null); const attributeVisibilityRef = _react.useRef(true); const removeAttribute = _react.useCallback(()=>{ var _activeParentRef_current; (_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.removeAttribute('aria-activedescendant'); }, []); const setAttribute = _react.useCallback((id)=>{ if (id) { activeIdRef.current = id; } if (attributeVisibilityRef.current && activeIdRef.current) { var _activeParentRef_current; (_activeParentRef_current = activeParentRef.current) === null || _activeParentRef_current === void 0 ? void 0 : _activeParentRef_current.setAttribute('aria-activedescendant', activeIdRef.current); } }, []); (0, _reacttabster.useOnKeyboardNavigationChange)((isNavigatingWithKeyboard)=>{ focusVisibleRef.current = isNavigatingWithKeyboard; const active = getActiveDescendant(); if (!active) { return; } if (isNavigatingWithKeyboard && shouldShowFocusVisibleAttrRef.current) { active.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, ''); } else { active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE); } }); const matchOption = (0, _reactutilities.useEventCallback)(matchOptionUnstable); const listboxRef = _react.useRef(null); const { optionWalker, listboxCallbackRef } = (0, _useOptionWalker.useOptionWalker)({ matchOption }); const getActiveDescendant = _react.useCallback(()=>{ var _listboxRef_current; return (_listboxRef_current = listboxRef.current) === null || _listboxRef_current === void 0 ? void 0 : _listboxRef_current.querySelector(`#${activeIdRef.current}`); }, [ listboxRef ]); const setShouldShowFocusVisibleAttribute = _react.useCallback((shouldShow)=>{ shouldShowFocusVisibleAttrRef.current = shouldShow; const active = getActiveDescendant(); if (!active) { return; } if (shouldShow && focusVisibleRef.current) { active.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, ''); } else { active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE); } }, [ getActiveDescendant ]); const blurActiveDescendant = _react.useCallback(()=>{ const active = getActiveDescendant(); if (active) { active.removeAttribute(_constants.ACTIVEDESCENDANT_ATTRIBUTE); active.removeAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE); } removeAttribute(); lastActiveIdRef.current = activeIdRef.current; activeIdRef.current = null; var _active_id; return (_active_id = active === null || active === void 0 ? void 0 : active.id) !== null && _active_id !== void 0 ? _active_id : null; }, [ getActiveDescendant, removeAttribute ]); const focusActiveDescendant = _react.useCallback((nextActive)=>{ if (!nextActive) { return; } const previousActiveId = blurActiveDescendant(); (0, _scrollIntoView.scrollIntoView)(nextActive); setAttribute(nextActive.id); nextActive.setAttribute(_constants.ACTIVEDESCENDANT_ATTRIBUTE, ''); if (focusVisibleRef.current && shouldShowFocusVisibleAttrRef.current) { nextActive.setAttribute(_constants.ACTIVEDESCENDANT_FOCUSVISIBLE_ATTRIBUTE, ''); } const event = createActiveDescendantChangeEvent({ id: nextActive.id, previousId: previousActiveId }); nextActive.dispatchEvent(event); }, [ blurActiveDescendant, setAttribute ]); const controller = _react.useMemo(()=>({ first: ({ passive } = {})=>{ const first = optionWalker.first(); if (!passive) { focusActiveDescendant(first); } return first === null || first === void 0 ? void 0 : first.id; }, last: ({ passive } = {})=>{ const last = optionWalker.last(); if (!passive) { focusActiveDescendant(last); } return last === null || last === void 0 ? void 0 : last.id; }, next: ({ passive } = {})=>{ const active = getActiveDescendant(); if (!active) { return; } optionWalker.setCurrent(active); const next = optionWalker.next(); if (!passive) { focusActiveDescendant(next); } return next === null || next === void 0 ? void 0 : next.id; }, prev: ({ passive } = {})=>{ const active = getActiveDescendant(); if (!active) { return; } optionWalker.setCurrent(active); const next = optionWalker.prev(); if (!passive) { focusActiveDescendant(next); } return next === null || next === void 0 ? void 0 : next.id; }, blur: ()=>{ blurActiveDescendant(); }, active: ()=>{ var _getActiveDescendant; return (_getActiveDescendant = getActiveDescendant()) === null || _getActiveDescendant === void 0 ? void 0 : _getActiveDescendant.id; }, focus: (id)=>{ if (!listboxRef.current) { return; } const target = listboxRef.current.querySelector(`#${id}`); if (target) { focusActiveDescendant(target); } }, focusLastActive: ()=>{ if (!listboxRef.current || !lastActiveIdRef.current) { return; } const target = listboxRef.current.querySelector(`#${lastActiveIdRef.current}`); if (target) { focusActiveDescendant(target); return true; } }, find (predicate, { passive, startFrom } = {}) { const target = optionWalker.find(predicate, startFrom); if (!passive) { focusActiveDescendant(target); } return target === null || target === void 0 ? void 0 : target.id; }, scrollActiveIntoView: ()=>{ if (!listboxRef.current) { return; } const active = getActiveDescendant(); if (!active) { return; } (0, _scrollIntoView.scrollIntoView)(active); }, showAttributes () { attributeVisibilityRef.current = true; setAttribute(); }, hideAttributes () { attributeVisibilityRef.current = false; removeAttribute(); }, showFocusVisibleAttributes () { setShouldShowFocusVisibleAttribute(true); }, hideFocusVisibleAttributes () { setShouldShowFocusVisibleAttribute(false); } }), [ optionWalker, listboxRef, setAttribute, removeAttribute, focusActiveDescendant, blurActiveDescendant, getActiveDescendant, setShouldShowFocusVisibleAttribute ]); _react.useImperativeHandle(imperativeRef, ()=>controller); return { listboxRef: (0, _reactutilities.useMergedRefs)(listboxRef, listboxCallbackRef), activeParentRef, controller }; }