UNPKG

4.37 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
4
5var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
6
7exports.__esModule = true;
8exports.default = void 0;
9
10var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
11
12var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
13
14var _querySelectorAll = _interopRequireDefault(require("dom-helpers/querySelectorAll"));
15
16var _react = _interopRequireWildcard(require("react"));
17
18var _useForceUpdate = _interopRequireDefault(require("@restart/hooks/useForceUpdate"));
19
20var _useMergedRefs = _interopRequireDefault(require("@restart/hooks/useMergedRefs"));
21
22var _NavContext = _interopRequireDefault(require("./NavContext"));
23
24var _SelectableContext = _interopRequireWildcard(require("./SelectableContext"));
25
26var _TabContext = _interopRequireDefault(require("./TabContext"));
27
28var noop = function noop() {};
29
30var AbstractNav = _react.default.forwardRef(function (_ref, ref) {
31 var _ref$as = _ref.as,
32 Component = _ref$as === void 0 ? 'ul' : _ref$as,
33 onSelect = _ref.onSelect,
34 activeKey = _ref.activeKey,
35 role = _ref.role,
36 onKeyDown = _ref.onKeyDown,
37 props = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["as", "onSelect", "activeKey", "role", "onKeyDown"]);
38 // A ref and forceUpdate for refocus, b/c we only want to trigger when needed
39 // and don't want to reset the set in the effect
40 var forceUpdate = (0, _useForceUpdate.default)();
41 var needsRefocusRef = (0, _react.useRef)(false);
42 var parentOnSelect = (0, _react.useContext)(_SelectableContext.default);
43 var tabContext = (0, _react.useContext)(_TabContext.default);
44 var getControlledId, getControllerId;
45
46 if (tabContext) {
47 role = role || 'tablist';
48 activeKey = tabContext.activeKey;
49 getControlledId = tabContext.getControlledId;
50 getControllerId = tabContext.getControllerId;
51 }
52
53 var listNode = (0, _react.useRef)(null);
54
55 var getNextActiveChild = function getNextActiveChild(offset) {
56 if (!listNode.current) return null;
57 var items = (0, _querySelectorAll.default)(listNode.current, '[data-rb-event-key]:not(.disabled)');
58 var activeChild = listNode.current.querySelector('.active');
59 var index = items.indexOf(activeChild);
60 if (index === -1) return null;
61 var nextIndex = index + offset;
62 if (nextIndex >= items.length) nextIndex = 0;
63 if (nextIndex < 0) nextIndex = items.length - 1;
64 return items[nextIndex];
65 };
66
67 var handleSelect = function handleSelect(key, event) {
68 if (key == null) return;
69 if (onSelect) onSelect(key, event);
70 if (parentOnSelect) parentOnSelect(key, event);
71 };
72
73 var handleKeyDown = function handleKeyDown(event) {
74 if (onKeyDown) onKeyDown(event);
75 var nextActiveChild;
76
77 switch (event.key) {
78 case 'ArrowLeft':
79 case 'ArrowUp':
80 nextActiveChild = getNextActiveChild(-1);
81 break;
82
83 case 'ArrowRight':
84 case 'ArrowDown':
85 nextActiveChild = getNextActiveChild(1);
86 break;
87
88 default:
89 return;
90 }
91
92 if (!nextActiveChild) return;
93 event.preventDefault();
94 handleSelect(nextActiveChild.dataset.rbEventKey, event);
95 needsRefocusRef.current = true;
96 forceUpdate();
97 };
98
99 (0, _react.useEffect)(function () {
100 if (listNode.current && needsRefocusRef.current) {
101 var activeChild = listNode.current.querySelector('[data-rb-event-key].active');
102 if (activeChild) activeChild.focus();
103 }
104
105 needsRefocusRef.current = false;
106 });
107 var mergedRef = (0, _useMergedRefs.default)(ref, listNode);
108 return _react.default.createElement(_SelectableContext.default.Provider, {
109 value: handleSelect
110 }, _react.default.createElement(_NavContext.default.Provider, {
111 value: {
112 role: role,
113 // used by NavLink to determine it's role
114 activeKey: (0, _SelectableContext.makeEventKey)(activeKey),
115 getControlledId: getControlledId || noop,
116 getControllerId: getControllerId || noop
117 }
118 }, _react.default.createElement(Component, (0, _extends2.default)({}, props, {
119 onKeyDown: handleKeyDown,
120 ref: mergedRef,
121 role: role
122 }))));
123});
124
125var _default = AbstractNav;
126exports.default = _default;
127module.exports = exports["default"];
\No newline at end of file