238 lines
9.3 KiB
JavaScript
238 lines
9.3 KiB
JavaScript
"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
|
|
};
|
|
}
|