useRangeActive.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = useRangeActive;
  8. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  9. var React = _interopRequireWildcard(require("react"));
  10. var _useLockEffect = _interopRequireDefault(require("./useLockEffect"));
  11. /**
  12. * When user first focus one input, any submit will trigger focus another one.
  13. * When second time focus one input, submit will not trigger focus again.
  14. * When click outside to close the panel, trigger event if it can trigger onChange.
  15. */
  16. function useRangeActive(disabled) {
  17. var empty = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  18. var mergedOpen = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  19. var _React$useState = React.useState(0),
  20. _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
  21. activeIndex = _React$useState2[0],
  22. setActiveIndex = _React$useState2[1];
  23. var _React$useState3 = React.useState(false),
  24. _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
  25. focused = _React$useState4[0],
  26. setFocused = _React$useState4[1];
  27. var activeListRef = React.useRef([]);
  28. var submitIndexRef = React.useRef(null);
  29. var lastOperationRef = React.useRef(null);
  30. var updateSubmitIndex = function updateSubmitIndex(index) {
  31. submitIndexRef.current = index;
  32. };
  33. var hasActiveSubmitValue = function hasActiveSubmitValue(index) {
  34. return submitIndexRef.current === index;
  35. };
  36. var triggerFocus = function triggerFocus(nextFocus) {
  37. setFocused(nextFocus);
  38. };
  39. // ============================= Record =============================
  40. var lastOperation = function lastOperation(type) {
  41. if (type) {
  42. lastOperationRef.current = type;
  43. }
  44. return lastOperationRef.current;
  45. };
  46. // ============================ Strategy ============================
  47. // Trigger when input enter or input blur or panel close
  48. var nextActiveIndex = function nextActiveIndex(nextValue) {
  49. var list = activeListRef.current;
  50. var filledActiveSet = new Set(list.filter(function (index) {
  51. return nextValue[index] || empty[index];
  52. }));
  53. var nextIndex = list[list.length - 1] === 0 ? 1 : 0;
  54. if (filledActiveSet.size >= 2 || disabled[nextIndex]) {
  55. return null;
  56. }
  57. return nextIndex;
  58. };
  59. // ============================= Effect =============================
  60. // Wait in case it's from the click outside to blur
  61. (0, _useLockEffect.default)(focused || mergedOpen, function () {
  62. if (!focused) {
  63. activeListRef.current = [];
  64. updateSubmitIndex(null);
  65. }
  66. });
  67. React.useEffect(function () {
  68. if (focused) {
  69. activeListRef.current.push(activeIndex);
  70. }
  71. }, [focused, activeIndex]);
  72. return [focused, triggerFocus, lastOperation, activeIndex, setActiveIndex, nextActiveIndex, activeListRef.current, updateSubmitIndex, hasActiveSubmitValue];
  73. }