Dashboard sipadu mbip
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AbstractNav.js 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
  3. import qsa from 'dom-helpers/query/querySelectorAll';
  4. import React, { useContext, useEffect, useRef } from 'react';
  5. import useForceUpdate from '@restart/hooks/useForceUpdate';
  6. import useMergedRefs from '@restart/hooks/useMergedRefs';
  7. import NavContext from './NavContext';
  8. import SelectableContext, { makeEventKey } from './SelectableContext';
  9. import TabContext from './TabContext';
  10. var noop = function noop() {};
  11. var AbstractNav = React.forwardRef(function (_ref, ref) {
  12. var _ref$as = _ref.as,
  13. Component = _ref$as === void 0 ? 'ul' : _ref$as,
  14. onSelect = _ref.onSelect,
  15. activeKey = _ref.activeKey,
  16. role = _ref.role,
  17. onKeyDown = _ref.onKeyDown,
  18. props = _objectWithoutPropertiesLoose(_ref, ["as", "onSelect", "activeKey", "role", "onKeyDown"]);
  19. // A ref and forceUpdate for refocus, b/c we only want to trigger when needed
  20. // and don't want to reset the set in the effect
  21. var forceUpdate = useForceUpdate();
  22. var needsRefocusRef = useRef(false);
  23. var parentOnSelect = useContext(SelectableContext);
  24. var tabContext = useContext(TabContext);
  25. var getControlledId, getControllerId;
  26. if (tabContext) {
  27. role = role || 'tablist';
  28. activeKey = tabContext.activeKey;
  29. getControlledId = tabContext.getControlledId;
  30. getControllerId = tabContext.getControllerId;
  31. }
  32. var listNode = useRef(null);
  33. var getNextActiveChild = function getNextActiveChild(offset) {
  34. if (!listNode.current) return null;
  35. var items = qsa(listNode.current, '[data-rb-event-key]:not(.disabled)');
  36. var activeChild = listNode.current.querySelector('.active');
  37. var index = items.indexOf(activeChild);
  38. if (index === -1) return null;
  39. var nextIndex = index + offset;
  40. if (nextIndex >= items.length) nextIndex = 0;
  41. if (nextIndex < 0) nextIndex = items.length - 1;
  42. return items[nextIndex];
  43. };
  44. var handleSelect = function handleSelect(key, event) {
  45. if (key == null) return;
  46. if (onSelect) onSelect(key, event);
  47. if (parentOnSelect) parentOnSelect(key, event);
  48. };
  49. var handleKeyDown = function handleKeyDown(event) {
  50. if (onKeyDown) onKeyDown(event);
  51. var nextActiveChild;
  52. switch (event.key) {
  53. case 'ArrowLeft':
  54. case 'ArrowUp':
  55. nextActiveChild = getNextActiveChild(-1);
  56. break;
  57. case 'ArrowRight':
  58. case 'ArrowDown':
  59. nextActiveChild = getNextActiveChild(1);
  60. break;
  61. default:
  62. return;
  63. }
  64. if (!nextActiveChild) return;
  65. event.preventDefault();
  66. handleSelect(nextActiveChild.dataset.rbEventKey, event);
  67. needsRefocusRef.current = true;
  68. forceUpdate();
  69. };
  70. useEffect(function () {
  71. if (listNode.current && needsRefocusRef.current) {
  72. var activeChild = listNode.current.querySelector('[data-rb-event-key].active');
  73. if (activeChild) activeChild.focus();
  74. }
  75. needsRefocusRef.current = false;
  76. });
  77. var mergedRef = useMergedRefs(ref, listNode);
  78. return React.createElement(SelectableContext.Provider, {
  79. value: handleSelect
  80. }, React.createElement(NavContext.Provider, {
  81. value: {
  82. role: role,
  83. // used by NavLink to determine it's role
  84. activeKey: makeEventKey(activeKey),
  85. getControlledId: getControlledId || noop,
  86. getControllerId: getControllerId || noop
  87. }
  88. }, React.createElement(Component, _extends({}, props, {
  89. onKeyDown: handleKeyDown,
  90. ref: mergedRef,
  91. role: role
  92. }))));
  93. });
  94. export default AbstractNav;