index.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { __assign, __awaiter, __generator } from "tslib";
  2. import { useState } from 'functional-mini/compat';
  3. import { useDidMount, useEvent, useRef, } from 'functional-mini/component';
  4. import '../_util/assert-component2';
  5. import { mountComponent } from '../_util/component';
  6. import { useComponentEvent } from '../_util/hooks/useComponentEvent';
  7. import { useEvent as useStableCallback } from '../_util/hooks/useEvent';
  8. import { useInstanceBoundingClientRect } from '../_util/hooks/useInstanceBoundingClientRect';
  9. import { useComponentUpdateEffect } from '../_util/hooks/useLayoutEffect';
  10. import { useMixState } from '../_util/hooks/useMixState';
  11. import { TabsFunctionalProps } from './props';
  12. var Tabs = function (props) {
  13. var _a = useMixState(props.defaultCurrent, {
  14. value: props.current,
  15. }), currentValue = _a[0], _b = _a[1], isControlled = _b.isControlled, update = _b.update;
  16. var _c = useState({
  17. scrollLeft: 0,
  18. scrollTop: 0,
  19. leftFade: false,
  20. rightFade: false,
  21. }), state = _c[0], updateState = _c[1];
  22. var scrollRef = useRef({ scrollLeft: 0, scrollTop: 0 });
  23. var triggerEvent = useComponentEvent(props).triggerEvent;
  24. var updatePartState = function (part) {
  25. updateState(function (old) {
  26. return __assign(__assign({}, old), part);
  27. });
  28. };
  29. var _d = useInstanceBoundingClientRect(), getBoundingClientRectWithBuilder = _d.getBoundingClientRectWithBuilder, getBoundingClientRect = _d.getBoundingClientRect;
  30. var updateFade = useStableCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
  31. var _a, view, item;
  32. return __generator(this, function (_b) {
  33. switch (_b.label) {
  34. case 0:
  35. updatePartState({
  36. leftFade: !!scrollRef.current.scrollLeft,
  37. });
  38. return [4 /*yield*/, Promise.all([
  39. getBoundingClientRectWithBuilder(function (id) { return "#ant-tabs-bar-scroll-view".concat(id); }),
  40. getBoundingClientRectWithBuilder(function (id) { return "#ant-tabs-bar-item".concat(id, "-").concat(props.items.length - 1); }),
  41. ])];
  42. case 1:
  43. _a = _b.sent(), view = _a[0], item = _a[1];
  44. if (!item || !view) {
  45. return [2 /*return*/];
  46. }
  47. updatePartState({
  48. rightFade: item.left + item.width / 2 > view.width,
  49. });
  50. return [2 /*return*/];
  51. }
  52. });
  53. }); });
  54. var updateScroll = useStableCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
  55. var current, _a, view, item, scrollTop, needScroll_1, distance, scrollLeft, needScroll, distance;
  56. return __generator(this, function (_b) {
  57. switch (_b.label) {
  58. case 0:
  59. current = currentValue;
  60. return [4 /*yield*/, Promise.all([
  61. getBoundingClientRectWithBuilder(function (id) { return "#ant-tabs-bar-scroll-view".concat(id); }),
  62. getBoundingClientRectWithBuilder(function (id) { return "#ant-tabs-bar-item".concat(id, "-").concat(current); }),
  63. ])];
  64. case 1:
  65. _a = _b.sent(), view = _a[0], item = _a[1];
  66. if (!view || !item) {
  67. return [2 /*return*/];
  68. }
  69. if (props.direction === 'vertical') {
  70. scrollTop = scrollRef.current.scrollTop || 0;
  71. needScroll_1 = false;
  72. if (props.scrollMode === 'center') {
  73. needScroll_1 = true;
  74. scrollTop +=
  75. item.top - view.top - Math.max((view.height - item.height) / 2, 0);
  76. }
  77. else {
  78. distance = item.top - view.top;
  79. if (distance < 0) {
  80. scrollTop += distance;
  81. needScroll_1 = true;
  82. }
  83. else if (distance + item.height > view.height) {
  84. scrollTop += Math.min(distance + item.height - view.height, distance);
  85. needScroll_1 = true;
  86. }
  87. }
  88. if (needScroll_1) {
  89. if (scrollTop === state.scrollTop) {
  90. scrollTop += Math.random();
  91. }
  92. updatePartState({
  93. scrollTop: scrollTop,
  94. });
  95. }
  96. return [2 /*return*/];
  97. }
  98. scrollLeft = scrollRef.current.scrollLeft || 0;
  99. needScroll = false;
  100. if (props.scrollMode === 'center') {
  101. needScroll = true;
  102. scrollLeft +=
  103. item.left - view.left - Math.max((view.width - item.width) / 2, 0);
  104. }
  105. else {
  106. distance = item.left - view.left;
  107. if (distance < 0) {
  108. scrollLeft += distance;
  109. needScroll = true;
  110. }
  111. else if (distance + item.width > view.width) {
  112. scrollLeft += Math.min(distance + item.width - view.width, distance);
  113. needScroll = true;
  114. }
  115. }
  116. if (needScroll) {
  117. if (scrollLeft === state.scrollLeft) {
  118. scrollLeft += Math.random();
  119. }
  120. updatePartState({
  121. scrollLeft: scrollLeft,
  122. });
  123. updateFade();
  124. }
  125. return [2 /*return*/];
  126. }
  127. });
  128. }); });
  129. useEvent('onScroll', function (e) { return __awaiter(void 0, void 0, void 0, function () {
  130. return __generator(this, function (_a) {
  131. if (props.direction === 'vertical') {
  132. scrollRef.current.scrollTop = e.detail.scrollTop;
  133. return [2 /*return*/];
  134. }
  135. scrollRef.current.scrollLeft = e.detail.scrollLeft;
  136. updateFade();
  137. return [2 /*return*/];
  138. });
  139. }); });
  140. useEvent('onChange', function (e) { return __awaiter(void 0, void 0, void 0, function () {
  141. var index;
  142. return __generator(this, function (_a) {
  143. index = parseInt(e.currentTarget.dataset.index, 10);
  144. if (props.items[index].disabled) {
  145. return [2 /*return*/];
  146. }
  147. if (currentValue === index) {
  148. return [2 /*return*/];
  149. }
  150. if (!isControlled) {
  151. update(index);
  152. }
  153. triggerEvent('change', index, e);
  154. return [2 /*return*/];
  155. });
  156. }); });
  157. useDidMount(function () {
  158. updateScroll();
  159. }, []);
  160. useComponentUpdateEffect(function () {
  161. updateScroll();
  162. }, [props.items, currentValue]);
  163. return __assign({ mixin: {
  164. value: currentValue,
  165. } }, state);
  166. };
  167. mountComponent(Tabs, TabsFunctionalProps);