useRangeActive.js 2.7 KB

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