useIndicator.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import raf from "rc-util/es/raf";
  3. import React, { useEffect, useRef, useState } from 'react';
  4. var useIndicator = function useIndicator(options) {
  5. var activeTabOffset = options.activeTabOffset,
  6. horizontal = options.horizontal,
  7. rtl = options.rtl,
  8. _options$indicator = options.indicator,
  9. indicator = _options$indicator === void 0 ? {} : _options$indicator;
  10. var size = indicator.size,
  11. _indicator$align = indicator.align,
  12. align = _indicator$align === void 0 ? 'center' : _indicator$align;
  13. var _useState = useState(),
  14. _useState2 = _slicedToArray(_useState, 2),
  15. inkStyle = _useState2[0],
  16. setInkStyle = _useState2[1];
  17. var inkBarRafRef = useRef();
  18. var getLength = React.useCallback(function (origin) {
  19. if (typeof size === 'function') {
  20. return size(origin);
  21. }
  22. if (typeof size === 'number') {
  23. return size;
  24. }
  25. return origin;
  26. }, [size]);
  27. // Delay set ink style to avoid remove tab blink
  28. function cleanInkBarRaf() {
  29. raf.cancel(inkBarRafRef.current);
  30. }
  31. useEffect(function () {
  32. var newInkStyle = {};
  33. if (activeTabOffset) {
  34. if (horizontal) {
  35. newInkStyle.width = getLength(activeTabOffset.width);
  36. var key = rtl ? 'right' : 'left';
  37. if (align === 'start') {
  38. newInkStyle[key] = activeTabOffset[key];
  39. }
  40. if (align === 'center') {
  41. newInkStyle[key] = activeTabOffset[key] + activeTabOffset.width / 2;
  42. newInkStyle.transform = rtl ? 'translateX(50%)' : 'translateX(-50%)';
  43. }
  44. if (align === 'end') {
  45. newInkStyle[key] = activeTabOffset[key] + activeTabOffset.width;
  46. newInkStyle.transform = 'translateX(-100%)';
  47. }
  48. } else {
  49. newInkStyle.height = getLength(activeTabOffset.height);
  50. if (align === 'start') {
  51. newInkStyle.top = activeTabOffset.top;
  52. }
  53. if (align === 'center') {
  54. newInkStyle.top = activeTabOffset.top + activeTabOffset.height / 2;
  55. newInkStyle.transform = 'translateY(-50%)';
  56. }
  57. if (align === 'end') {
  58. newInkStyle.top = activeTabOffset.top + activeTabOffset.height;
  59. newInkStyle.transform = 'translateY(-100%)';
  60. }
  61. }
  62. }
  63. cleanInkBarRaf();
  64. inkBarRafRef.current = raf(function () {
  65. // Avoid jitter caused by tiny numerical differences
  66. // fix https://github.com/ant-design/ant-design/issues/53378
  67. var isEqual = inkStyle && newInkStyle && Object.keys(newInkStyle).every(function (key) {
  68. var newValue = newInkStyle[key];
  69. var oldValue = inkStyle[key];
  70. return typeof newValue === 'number' && typeof oldValue === 'number' ? Math.round(newValue) === Math.round(oldValue) : newValue === oldValue;
  71. });
  72. if (!isEqual) {
  73. setInkStyle(newInkStyle);
  74. }
  75. });
  76. return cleanInkBarRaf;
  77. }, [JSON.stringify(activeTabOffset), horizontal, rtl, align, getLength]);
  78. return {
  79. style: inkStyle
  80. };
  81. };
  82. export default useIndicator;