@react-md/menu
Version:
Create menus that auto-position themselves within the viewport and adhere to the accessibility guidelines
75 lines • 2.99 kB
JavaScript
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMenuKeyDown = void 0;
var react_1 = require("react");
var utils_1 = require("@react-md/utils");
/**
* This hook allows for the keyboard movement within a menu. It'll make sure
* that the arrow keys and typing letters can correctly focus menu items. In
* addition, it'll automatically swap to the left and right arrow keys if the
* menu is displayed horizontally.
*/
function useMenuKeyDown(_a) {
var menu = _a.menu, onKeyDown = _a.onKeyDown, onRequestClose = _a.onRequestClose, portalled = _a.portalled, horizontal = _a.horizontal, defaultFocus = _a.defaultFocus;
var _b = react_1.useState(0), focusedIndex = _b[0], setFocusedIndex = _b[1];
var items = react_1.useMemo(function () {
if (!menu) {
return [];
}
return utils_1.getFocusableElements(menu, true);
}, [menu]);
react_1.useEffect(function () {
if (!menu) {
return;
}
if (defaultFocus === "last") {
setFocusedIndex(items.length - 1);
}
else {
setFocusedIndex(0);
}
// only want to trigger this on initial menu mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [menu]);
return utils_1.useKeyboardMovement(__assign(__assign({}, (horizontal
? utils_1.MovementPresets.HORIZONTAL_MENU
: utils_1.MovementPresets.VERTICAL_MENU)), { focusedIndex: focusedIndex,
onChange: function (_a) {
var index = _a.index;
setFocusedIndex(index);
if (items[index]) {
items[index].focus();
}
}, items: items.map(function (item) { return utils_1.extractTextContent(item); }), onKeyDown: function (event) {
if (onKeyDown) {
onKeyDown(event);
}
if (event.key === "Escape") {
event.stopPropagation();
onRequestClose();
}
else if (event.key === "Tab") {
if (portalled) {
// have to prevent default tab behavior since tab order is ruined when
// something is portalled. this will make it interact the same as if
// it was an escape keypress. it's too much work to try to emulate a
// real tab here
event.preventDefault();
}
onRequestClose();
}
} }))[1];
}
exports.useMenuKeyDown = useMenuKeyDown;
//# sourceMappingURL=useMenuKeyDown.js.map