StepHandler.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
  3. /* eslint-disable react/no-unknown-property */
  4. import * as React from 'react';
  5. import classNames from 'classnames';
  6. import useMobile from "rc-util/es/hooks/useMobile";
  7. import raf from "rc-util/es/raf";
  8. /**
  9. * When click and hold on a button - the speed of auto changing the value.
  10. */
  11. var STEP_INTERVAL = 200;
  12. /**
  13. * When click and hold on a button - the delay before auto changing the value.
  14. */
  15. var STEP_DELAY = 600;
  16. export default function StepHandler(_ref) {
  17. var prefixCls = _ref.prefixCls,
  18. upNode = _ref.upNode,
  19. downNode = _ref.downNode,
  20. upDisabled = _ref.upDisabled,
  21. downDisabled = _ref.downDisabled,
  22. onStep = _ref.onStep;
  23. // ======================== Step ========================
  24. var stepTimeoutRef = React.useRef();
  25. var frameIds = React.useRef([]);
  26. var onStepRef = React.useRef();
  27. onStepRef.current = onStep;
  28. var onStopStep = function onStopStep() {
  29. clearTimeout(stepTimeoutRef.current);
  30. };
  31. // We will interval update step when hold mouse down
  32. var onStepMouseDown = function onStepMouseDown(e, up) {
  33. e.preventDefault();
  34. onStopStep();
  35. onStepRef.current(up);
  36. // Loop step for interval
  37. function loopStep() {
  38. onStepRef.current(up);
  39. stepTimeoutRef.current = setTimeout(loopStep, STEP_INTERVAL);
  40. }
  41. // First time press will wait some time to trigger loop step update
  42. stepTimeoutRef.current = setTimeout(loopStep, STEP_DELAY);
  43. };
  44. React.useEffect(function () {
  45. return function () {
  46. onStopStep();
  47. frameIds.current.forEach(function (id) {
  48. return raf.cancel(id);
  49. });
  50. };
  51. }, []);
  52. // ======================= Render =======================
  53. var isMobile = useMobile();
  54. if (isMobile) {
  55. return null;
  56. }
  57. var handlerClassName = "".concat(prefixCls, "-handler");
  58. var upClassName = classNames(handlerClassName, "".concat(handlerClassName, "-up"), _defineProperty({}, "".concat(handlerClassName, "-up-disabled"), upDisabled));
  59. var downClassName = classNames(handlerClassName, "".concat(handlerClassName, "-down"), _defineProperty({}, "".concat(handlerClassName, "-down-disabled"), downDisabled));
  60. // fix: https://github.com/ant-design/ant-design/issues/43088
  61. // In Safari, When we fire onmousedown and onmouseup events in quick succession,
  62. // there may be a problem that the onmouseup events are executed first,
  63. // resulting in a disordered program execution.
  64. // So, we need to use requestAnimationFrame to ensure that the onmouseup event is executed after the onmousedown event.
  65. var safeOnStopStep = function safeOnStopStep() {
  66. return frameIds.current.push(raf(onStopStep));
  67. };
  68. var sharedHandlerProps = {
  69. unselectable: 'on',
  70. role: 'button',
  71. onMouseUp: safeOnStopStep,
  72. onMouseLeave: safeOnStopStep
  73. };
  74. return /*#__PURE__*/React.createElement("div", {
  75. className: "".concat(handlerClassName, "-wrap")
  76. }, /*#__PURE__*/React.createElement("span", _extends({}, sharedHandlerProps, {
  77. onMouseDown: function onMouseDown(e) {
  78. onStepMouseDown(e, true);
  79. },
  80. "aria-label": "Increase Value",
  81. "aria-disabled": upDisabled,
  82. className: upClassName
  83. }), upNode || /*#__PURE__*/React.createElement("span", {
  84. unselectable: "on",
  85. className: "".concat(prefixCls, "-handler-up-inner")
  86. })), /*#__PURE__*/React.createElement("span", _extends({}, sharedHandlerProps, {
  87. onMouseDown: function onMouseDown(e) {
  88. onStepMouseDown(e, false);
  89. },
  90. "aria-label": "Decrease Value",
  91. "aria-disabled": downDisabled,
  92. className: downClassName
  93. }), downNode || /*#__PURE__*/React.createElement("span", {
  94. unselectable: "on",
  95. className: "".concat(prefixCls, "-handler-down-inner")
  96. })));
  97. }