@fjyueke/arco-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/README.md +85 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.js +244 -0
  4. package/metaData/components/action-sheet/doc.md +102 -0
  5. package/metaData/components/action-sheet/example/index.tsx +199 -0
  6. package/metaData/components/action-sheet/example/methods.tsx +6 -0
  7. package/metaData/components/avatar/doc.md +57 -0
  8. package/metaData/components/avatar/example/group.tsx +69 -0
  9. package/metaData/components/avatar/example/index.tsx +196 -0
  10. package/metaData/components/badge/doc.md +28 -0
  11. package/metaData/components/badge/example/index.tsx +128 -0
  12. package/metaData/components/button/doc.md +45 -0
  13. package/metaData/components/button/example/index.tsx +264 -0
  14. package/metaData/components/carousel/doc.md +89 -0
  15. package/metaData/components/carousel/example/index.tsx +1481 -0
  16. package/metaData/components/cell/doc.md +68 -0
  17. package/metaData/components/cell/example/arrow.tsx +13 -0
  18. package/metaData/components/cell/example/cell.tsx +71 -0
  19. package/metaData/components/cell/example/group.tsx +63 -0
  20. package/metaData/components/cell/example/index.tsx +19 -0
  21. package/metaData/components/checkbox/doc.md +91 -0
  22. package/metaData/components/checkbox/example/checkbox.tsx +158 -0
  23. package/metaData/components/checkbox/example/group.tsx +103 -0
  24. package/metaData/components/checkbox/example/index.tsx +25 -0
  25. package/metaData/components/circle-progress/doc.md +40 -0
  26. package/metaData/components/circle-progress/example/index.tsx +323 -0
  27. package/metaData/components/collapse/doc.md +74 -0
  28. package/metaData/components/collapse/example/collapse.tsx +183 -0
  29. package/metaData/components/collapse/example/group.tsx +136 -0
  30. package/metaData/components/collapse/example/index.tsx +16 -0
  31. package/metaData/components/collapse/example/utils.tsx +20 -0
  32. package/metaData/components/context-provider/doc.md +44 -0
  33. package/metaData/components/context-provider/example/index.tsx +208 -0
  34. package/metaData/components/count-down/doc.md +40 -0
  35. package/metaData/components/count-down/example/hooks.tsx +118 -0
  36. package/metaData/components/count-down/example/index.tsx +63 -0
  37. package/metaData/components/date-picker/doc.md +102 -0
  38. package/metaData/components/date-picker/example/index.tsx +545 -0
  39. package/metaData/components/dialog/doc.md +200 -0
  40. package/metaData/components/dialog/example/index.tsx +328 -0
  41. package/metaData/components/dialog/example/methods.tsx +56 -0
  42. package/metaData/components/divider/doc.md +25 -0
  43. package/metaData/components/divider/example/index.tsx +87 -0
  44. package/metaData/components/dropdown/doc.md +80 -0
  45. package/metaData/components/dropdown/example/dropdown.tsx +308 -0
  46. package/metaData/components/dropdown/example/index.tsx +19 -0
  47. package/metaData/components/dropdown/example/options.tsx +103 -0
  48. package/metaData/components/dropdown-menu/doc.md +91 -0
  49. package/metaData/components/dropdown-menu/example/dropdown-menu.tsx +270 -0
  50. package/metaData/components/dropdown-menu/example/index.tsx +16 -0
  51. package/metaData/components/ellipsis/doc.md +33 -0
  52. package/metaData/components/ellipsis/example/index.tsx +93 -0
  53. package/metaData/components/ellipsis/example/js-ellipsis.tsx +229 -0
  54. package/metaData/components/ellipsis/example/native-ellipsis.tsx +48 -0
  55. package/metaData/components/form/doc.md +90 -0
  56. package/metaData/components/form/example/form-item-context.tsx +8 -0
  57. package/metaData/components/form/example/form-item.tsx +378 -0
  58. package/metaData/components/form/example/index.tsx +87 -0
  59. package/metaData/components/form/example/linked-container.tsx +66 -0
  60. package/metaData/components/grid/doc.md +39 -0
  61. package/metaData/components/grid/example/index.tsx +252 -0
  62. package/metaData/components/icon/doc.md +15 -0
  63. package/metaData/components/icon/example/index.tsx +32 -0
  64. package/metaData/components/image/doc.md +62 -0
  65. package/metaData/components/image/example/index.tsx +528 -0
  66. package/metaData/components/image-picker/doc.md +116 -0
  67. package/metaData/components/image-picker/example/add-icon.tsx +14 -0
  68. package/metaData/components/image-picker/example/index.tsx +175 -0
  69. package/metaData/components/image-preview/doc.md +119 -0
  70. package/metaData/components/image-preview/example/index.tsx +1290 -0
  71. package/metaData/components/image-preview/example/methods.tsx +72 -0
  72. package/metaData/components/index-bar/doc.md +83 -0
  73. package/metaData/components/index-bar/example/group.tsx +93 -0
  74. package/metaData/components/index-bar/example/index.tsx +271 -0
  75. package/metaData/components/index-bar/example/side-bar.tsx +82 -0
  76. package/metaData/components/input/doc.md +60 -0
  77. package/metaData/components/input/example/hooks.tsx +259 -0
  78. package/metaData/components/input/example/index.tsx +134 -0
  79. package/metaData/components/input/example/props.tsx +183 -0
  80. package/metaData/components/keyboard/doc.md +73 -0
  81. package/metaData/components/keyboard/example/index.tsx +238 -0
  82. package/metaData/components/load-more/doc.md +48 -0
  83. package/metaData/components/load-more/example/index.tsx +395 -0
  84. package/metaData/components/loading/doc.md +34 -0
  85. package/metaData/components/loading/example/index.tsx +312 -0
  86. package/metaData/components/masking/doc.md +93 -0
  87. package/metaData/components/masking/example/index.tsx +410 -0
  88. package/metaData/components/masking/example/methods.tsx +88 -0
  89. package/metaData/components/nav-bar/doc.md +40 -0
  90. package/metaData/components/nav-bar/example/back-icon.tsx +28 -0
  91. package/metaData/components/nav-bar/example/index.tsx +305 -0
  92. package/metaData/components/notice-bar/doc.md +34 -0
  93. package/metaData/components/notice-bar/example/index.tsx +294 -0
  94. package/metaData/components/notify/doc.md +81 -0
  95. package/metaData/components/notify/example/index.tsx +171 -0
  96. package/metaData/components/notify/example/methods.tsx +83 -0
  97. package/metaData/components/pagination/doc.md +41 -0
  98. package/metaData/components/pagination/example/arrow.tsx +14 -0
  99. package/metaData/components/pagination/example/index.tsx +292 -0
  100. package/metaData/components/picker/doc.md +89 -0
  101. package/metaData/components/picker/example/index.tsx +217 -0
  102. package/metaData/components/picker-view/doc.md +57 -0
  103. package/metaData/components/picker-view/example/cascader.tsx +141 -0
  104. package/metaData/components/picker-view/example/index.tsx +297 -0
  105. package/metaData/components/picker-view/example/multi-picker.tsx +66 -0
  106. package/metaData/components/picker-view/example/picker-cell.tsx +416 -0
  107. package/metaData/components/popover/doc.md +144 -0
  108. package/metaData/components/popover/example/index.tsx +23 -0
  109. package/metaData/components/popover/example/menu.tsx +145 -0
  110. package/metaData/components/popover/example/popover-inner.tsx +147 -0
  111. package/metaData/components/popover/example/popover.tsx +268 -0
  112. package/metaData/components/popup/doc.md +101 -0
  113. package/metaData/components/popup/example/index.tsx +125 -0
  114. package/metaData/components/popup/example/methods.tsx +6 -0
  115. package/metaData/components/popup-swiper/doc.md +108 -0
  116. package/metaData/components/popup-swiper/example/index.tsx +332 -0
  117. package/metaData/components/popup-swiper/example/methods.tsx +6 -0
  118. package/metaData/components/portal/doc.md +14 -0
  119. package/metaData/components/portal/example/index.tsx +35 -0
  120. package/metaData/components/progress/doc.md +42 -0
  121. package/metaData/components/progress/example/index.tsx +256 -0
  122. package/metaData/components/pull-refresh/doc.md +37 -0
  123. package/metaData/components/pull-refresh/example/android-pull-refresh.tsx +260 -0
  124. package/metaData/components/pull-refresh/example/index.tsx +44 -0
  125. package/metaData/components/pull-refresh/example/ios-pull-refresh.tsx +216 -0
  126. package/metaData/components/radio/doc.md +89 -0
  127. package/metaData/components/radio/example/group.tsx +92 -0
  128. package/metaData/components/radio/example/index.tsx +25 -0
  129. package/metaData/components/radio/example/radio.tsx +22 -0
  130. package/metaData/components/rate/doc.md +33 -0
  131. package/metaData/components/rate/example/index.tsx +281 -0
  132. package/metaData/components/search-bar/doc.md +97 -0
  133. package/metaData/components/search-bar/example/association.tsx +89 -0
  134. package/metaData/components/search-bar/example/cancel-button.tsx +34 -0
  135. package/metaData/components/search-bar/example/highlight.tsx +66 -0
  136. package/metaData/components/search-bar/example/index.tsx +251 -0
  137. package/metaData/components/show-monitor/doc.md +34 -0
  138. package/metaData/components/show-monitor/example/index.tsx +646 -0
  139. package/metaData/components/skeleton/doc.md +101 -0
  140. package/metaData/components/skeleton/example/elements.tsx +290 -0
  141. package/metaData/components/skeleton/example/index.tsx +96 -0
  142. package/metaData/components/skeleton/example/skeleton-context.tsx +7 -0
  143. package/metaData/components/slider/doc.md +42 -0
  144. package/metaData/components/slider/example/index.tsx +326 -0
  145. package/metaData/components/slider/example/marks.tsx +50 -0
  146. package/metaData/components/slider/example/popover.tsx +38 -0
  147. package/metaData/components/slider/example/thumb.tsx +48 -0
  148. package/metaData/components/slider/example/useSliderIcon.tsx +38 -0
  149. package/metaData/components/slider/example/useSliderInit.tsx +170 -0
  150. package/metaData/components/stepper/doc.md +46 -0
  151. package/metaData/components/stepper/example/index.tsx +166 -0
  152. package/metaData/components/stepper/example/useButtonClick.tsx +74 -0
  153. package/metaData/components/stepper/example/useInputEvent.tsx +65 -0
  154. package/metaData/components/stepper/example/useValue.tsx +43 -0
  155. package/metaData/components/steps/doc.md +57 -0
  156. package/metaData/components/steps/example/index.tsx +123 -0
  157. package/metaData/components/steps/example/step.tsx +126 -0
  158. package/metaData/components/sticky/doc.md +45 -0
  159. package/metaData/components/sticky/example/index.tsx +430 -0
  160. package/metaData/components/swipe-action/doc.md +44 -0
  161. package/metaData/components/swipe-action/example/index.tsx +338 -0
  162. package/metaData/components/swipe-action/example/item.tsx +40 -0
  163. package/metaData/components/swipe-load/doc.md +43 -0
  164. package/metaData/components/swipe-load/example/index.tsx +339 -0
  165. package/metaData/components/swipe-load/example/type.tsx +153 -0
  166. package/metaData/components/switch/doc.md +38 -0
  167. package/metaData/components/switch/example/index.tsx +237 -0
  168. package/metaData/components/tab-bar/doc.md +57 -0
  169. package/metaData/components/tab-bar/example/index.tsx +18 -0
  170. package/metaData/components/tab-bar/example/item.tsx +74 -0
  171. package/metaData/components/tab-bar/example/tab-bar.tsx +105 -0
  172. package/metaData/components/tabs/doc.md +187 -0
  173. package/metaData/components/tabs/example/index.tsx +514 -0
  174. package/metaData/components/tabs/example/tab-cell-underline.tsx +320 -0
  175. package/metaData/components/tabs/example/tab-cell.tsx +433 -0
  176. package/metaData/components/tabs/example/tab-pane.tsx +349 -0
  177. package/metaData/components/tag/doc.md +80 -0
  178. package/metaData/components/tag/example/index.tsx +23 -0
  179. package/metaData/components/tag/example/list.tsx +97 -0
  180. package/metaData/components/tag/example/tag.tsx +85 -0
  181. package/metaData/components/textarea/doc.md +67 -0
  182. package/metaData/components/textarea/example/index.tsx +258 -0
  183. package/metaData/components/toast/doc.md +90 -0
  184. package/metaData/components/toast/example/index.tsx +335 -0
  185. package/metaData/components/toast/example/methods.tsx +87 -0
  186. package/metaData/components/transition/doc.md +19 -0
  187. package/metaData/components/transition/example/index.tsx +113 -0
  188. package/metaData/components/uploader/doc.md +82 -0
  189. package/metaData/components/uploader/example/index.tsx +208 -0
  190. package/metaData/components-index.json +242 -0
  191. package/package.json +56 -0
@@ -0,0 +1,349 @@
1
+ import React, {
2
+ useRef,
3
+ forwardRef,
4
+ Ref,
5
+ useImperativeHandle,
6
+ CSSProperties,
7
+ useState,
8
+ useEffect,
9
+ useMemo,
10
+ } from 'react';
11
+ import lodashThrottle from 'lodash.throttle';
12
+ import { cls, scrollWithAnimation, getScrollContainerRect, isSSR } from '@arco-design/mobile-utils';
13
+ import { getStyleWithVendor } from '../_helpers';
14
+ import { TabPaneProps, TabPaneRef } from './type';
15
+
16
+ const TabPane = forwardRef((props: TabPaneProps, ref: Ref<TabPaneRef>) => {
17
+ const {
18
+ prefixCls,
19
+ panes,
20
+ tabDirection,
21
+ activeIndex,
22
+ activeIndexRef,
23
+ distance,
24
+ wrapWidth,
25
+ wrapHeight,
26
+ handlePaneTouchEnd,
27
+ transitionDuration,
28
+ paneTrans,
29
+ swipeable,
30
+ lazyloadCount,
31
+ hideContentStyle,
32
+ renderHideContent,
33
+ mode,
34
+ tabPaneStyle,
35
+ tabPaneClass,
36
+ tabPaneExtra,
37
+ getScrollContainer,
38
+ scrollThrottle,
39
+ scrollOffset = 0,
40
+ goLastWhenScrollBottom,
41
+ scrollVertical,
42
+ translateZ,
43
+ fullScreen,
44
+ autoHeight,
45
+ swipeEnergySaving,
46
+ changeIndex,
47
+ onScroll,
48
+ rtlRatio,
49
+ } = props;
50
+ const domRef = useRef<HTMLDivElement | null>(null);
51
+ const panesRef = useRef<(HTMLDivElement | null)[]>([]);
52
+ const autoScrollingRef = useRef(false);
53
+ const timerRef = useRef(0);
54
+ const [shownIndexes, setShownIndexes] = useState<[number, number]>([activeIndex, activeIndex]);
55
+ const [shownActiveIndex, setShownActiveIndex] = useState(activeIndex);
56
+ const prefix = `${prefixCls}-tab-pane`;
57
+ const handleTouchEnd = swipeable ? handlePaneTouchEnd : void 0;
58
+ const [currentPaneHeight, setCurrentPaneHeight] = useState<number | string>('auto');
59
+
60
+ useImperativeHandle(ref, () => ({
61
+ dom: domRef.current,
62
+ getTransition,
63
+ scrollToIndex,
64
+ setCurrentHeight,
65
+ }));
66
+
67
+ useEffect(() => {
68
+ if (mode === 'swipe') {
69
+ setTimeout(() => {
70
+ calcShownIndexes();
71
+ }, getTransition());
72
+ }
73
+ }, [lazyloadCount, activeIndex, mode]);
74
+
75
+ const scrollHandler = useMemo(() => {
76
+ if (mode !== 'scroll') {
77
+ return () => {};
78
+ }
79
+ const handler = () => {
80
+ onScroll?.();
81
+ if (autoScrollingRef.current) {
82
+ return;
83
+ }
84
+ const container = getScrollContainer ? getScrollContainer() : window;
85
+ if (!container) return;
86
+ const { containerTop, containerBottom } = getContainerTop(container);
87
+ for (let i = 0; i < panes.length; i += 1) {
88
+ // 判断范围:-∞ ... top0 ... top1 ... top n ... ∞
89
+ // @en Judge the range: (-∞, top0, top1, ...top n, ∞)
90
+ const curPaneTop = i === 0 ? -Infinity : getRectTop(panesRef.current[i]);
91
+ const nextPaneTop =
92
+ i === panes.length - 1 ? Infinity : getRectTop(panesRef.current[i + 1]);
93
+ if (
94
+ containerTop >= curPaneTop - scrollOffset &&
95
+ containerTop < nextPaneTop - scrollOffset
96
+ ) {
97
+ changeIndex(i, 'scroll');
98
+ break;
99
+ }
100
+ }
101
+ if (goLastWhenScrollBottom) {
102
+ const lastIndex = panes.length - 1;
103
+ const curPaneBottom = getRectTop(panesRef.current[lastIndex], 'bottom');
104
+ if (containerBottom === curPaneBottom) {
105
+ changeIndex(lastIndex, 'scroll');
106
+ }
107
+ }
108
+ };
109
+ return scrollThrottle ? lodashThrottle(handler, scrollThrottle) : handler;
110
+ }, [
111
+ mode,
112
+ scrollThrottle,
113
+ getScrollContainer,
114
+ panes.length,
115
+ scrollOffset,
116
+ goLastWhenScrollBottom,
117
+ scrollVertical,
118
+ onScroll,
119
+ ]);
120
+
121
+ useEffect(() => {
122
+ const container = getScrollContainer?.() || window;
123
+ if (container && mode === 'scroll') {
124
+ container.addEventListener('scroll', scrollHandler);
125
+ }
126
+ return () => {
127
+ if (container && mode === 'scroll') {
128
+ container.removeEventListener('scroll', scrollHandler);
129
+ }
130
+ };
131
+ }, [scrollHandler]);
132
+
133
+ function setCurrentHeight() {
134
+ if (!domRef.current || !autoHeight || mode !== 'swipe' || tabDirection !== 'vertical') {
135
+ return;
136
+ }
137
+ const allPanesDom = panesRef.current;
138
+ const nowIndex = activeIndexRef.current;
139
+ const currentHeight = (allPanesDom[nowIndex] || {}).offsetHeight || 'auto';
140
+ setCurrentPaneHeight(currentHeight);
141
+ }
142
+
143
+ function calcShownIndexes() {
144
+ setShownActiveIndex(activeIndex);
145
+ if (typeof lazyloadCount === 'number') {
146
+ setShownIndexes([activeIndex - lazyloadCount, activeIndex + lazyloadCount]);
147
+ return;
148
+ }
149
+ setShownIndexes([0, Infinity]);
150
+ }
151
+
152
+ function getTransition() {
153
+ return paneTrans ? transitionDuration || 0 : 0;
154
+ }
155
+
156
+ function scrollToIndex(index: number, rightNow?: boolean) {
157
+ const container = getScrollContainer?.() || window;
158
+ const { isGlobal, scrollEle, containerTop } = getContainerTop(container);
159
+ const curPaneTop = getRectTop(panesRef.current[index]);
160
+ const topDis = curPaneTop - containerTop - scrollOffset;
161
+ const scrollAttr = scrollVertical ? 'scrollTop' : 'scrollLeft';
162
+ const scrollTop = isGlobal
163
+ ? Math.max(document.documentElement[scrollAttr], document.body[scrollAttr])
164
+ : scrollEle[scrollAttr];
165
+ const scrollSizeAttr = scrollVertical ? 'scrollHeight' : 'scrollWidth';
166
+ const sizeAttr = scrollVertical ? 'offsetHeight' : 'offsetWidth';
167
+ const maxTopDis = isGlobal
168
+ ? Math.max(document.documentElement[scrollSizeAttr], document.body[scrollSizeAttr]) -
169
+ scrollTop -
170
+ (scrollVertical ? window.innerHeight : window.innerWidth)
171
+ : scrollEle[scrollSizeAttr] - scrollTop - scrollEle[sizeAttr];
172
+ const normalizedTopDis = Math.min(maxTopDis, topDis);
173
+ clearTimeout(timerRef.current);
174
+ autoScrollingRef.current = true;
175
+ const duration = rightNow ? 0 : transitionDuration || 0;
176
+ scrollWithAnimation(
177
+ scrollTop,
178
+ scrollTop + normalizedTopDis,
179
+ top => {
180
+ if (isGlobal) {
181
+ document.documentElement[scrollAttr] = top;
182
+ document.body[scrollAttr] = top;
183
+ } else {
184
+ scrollEle[scrollAttr] = top;
185
+ }
186
+ },
187
+ duration,
188
+ );
189
+ // 在自动滚动完成后,过一小段时间再解锁,避免最后一次触发scroll还未完成时就解锁导致乱跳的情况
190
+ // @en After the automatic scrolling is completed, unlock it after a short period of time, to avoid the situation of random jumping caused by unlocking when the scroll is not completed for the last time.
191
+ const buffer = 100;
192
+ timerRef.current = window.setTimeout(() => {
193
+ autoScrollingRef.current = false;
194
+ }, duration + (scrollThrottle || 0) + buffer);
195
+ }
196
+
197
+ function getContainerTop(container: HTMLElement | Window) {
198
+ const { isGlobal, scrollEle, containerRect } = getScrollContainerRect(container);
199
+ const containerTop = Math.floor(scrollVertical ? containerRect.top : containerRect.left);
200
+ const containerBottom = Math.floor(
201
+ scrollVertical ? containerRect.bottom : containerRect.right,
202
+ );
203
+ return { isGlobal, scrollEle: scrollEle!, containerTop, containerBottom };
204
+ }
205
+
206
+ function getRectTop(ele: HTMLElement | null, attr: 'top' | 'bottom' = 'top') {
207
+ const attrMap: Record<'top' | 'bottom', string> = scrollVertical
208
+ ? { top: 'top', bottom: 'bottom' }
209
+ : { top: 'left', bottom: 'right' };
210
+ const attrKey = attrMap[attr];
211
+ const rect = ele?.getBoundingClientRect() || {};
212
+ // 消除误差
213
+ // @en Eliminate errors
214
+ return rect[attrKey] ? Math.floor(rect[attrKey]) : 0;
215
+ }
216
+
217
+ function getPaneStyle(): CSSProperties {
218
+ const commonStyle = tabPaneStyle || {};
219
+ if (mode === 'scroll') {
220
+ return commonStyle;
221
+ }
222
+ const translateStr = translateZ ? ' translateZ(0)' : '';
223
+ const translatePercentInSSR = `${
224
+ (panes.length ? 100 / panes.length : 0) * activeIndex * rtlRatio * -1
225
+ }%`;
226
+ const verticalTranslate = `${distance - wrapWidth * activeIndex * rtlRatio}px`;
227
+ const horizontalTranslate = `${distance - wrapHeight * activeIndex}px`;
228
+ const sizeStyle =
229
+ tabDirection === 'vertical'
230
+ ? {
231
+ width: `${100 * panes.length}%`,
232
+ transform: `translateX(${
233
+ isSSR() ? translatePercentInSSR : verticalTranslate
234
+ })${translateStr}`,
235
+ }
236
+ : {
237
+ height: `${100 * panes.length}%`,
238
+ transform: `translateY(${
239
+ isSSR() ? translatePercentInSSR : horizontalTranslate
240
+ })${translateStr}`,
241
+ };
242
+ const heightStyle =
243
+ currentPaneHeight && currentPaneHeight !== 'auto'
244
+ ? {
245
+ height: currentPaneHeight,
246
+ }
247
+ : {};
248
+ return getStyleWithVendor({
249
+ ...(swipeEnergySaving ? {} : sizeStyle),
250
+ transitionDuration: `${getTransition()}ms`,
251
+ ...heightStyle,
252
+ ...commonStyle,
253
+ });
254
+ }
255
+
256
+ function getEnergySavingPaneStyle(index: number): CSSProperties | undefined {
257
+ if (mode === 'scroll' || !swipeEnergySaving) {
258
+ return undefined;
259
+ }
260
+ if (index !== shownActiveIndex) {
261
+ return {
262
+ position: 'absolute',
263
+ left: '-100%',
264
+ top: '-100%',
265
+ };
266
+ }
267
+ const translateStr = translateZ ? ' translateZ(0)' : '';
268
+ const sizeStyle =
269
+ tabDirection === 'vertical'
270
+ ? {
271
+ transform: `translateX(${
272
+ distance - wrapWidth * (activeIndex - index) * rtlRatio
273
+ }px)${translateStr}`,
274
+ }
275
+ : {
276
+ transform: `translateY(${
277
+ distance - wrapHeight * (activeIndex - index)
278
+ }px)${translateStr}`,
279
+ };
280
+ return getStyleWithVendor({
281
+ ...sizeStyle,
282
+ transitionDuration: `${getTransition()}ms`,
283
+ });
284
+ }
285
+
286
+ function renderContent(pane: React.ReactNode, index: number) {
287
+ const contentProps = {
288
+ key: index,
289
+ className: cls(prefix, `mode-${mode}`, { 'full-screen': fullScreen }),
290
+ ref: r => (panesRef.current[index] = r),
291
+ };
292
+ const energySavingStyle = getEnergySavingPaneStyle(index);
293
+ // 是滚动模式或在加载范围内,直接渲染
294
+ // @en Render directly when in scroll mode or in loading scope
295
+ if (mode === 'scroll' || (index >= shownIndexes[0] && index <= shownIndexes[1])) {
296
+ return (
297
+ <div {...contentProps} style={energySavingStyle}>
298
+ {pane}
299
+ </div>
300
+ );
301
+ }
302
+ const energySavingHideStyle = {
303
+ ...energySavingStyle,
304
+ ...(hideContentStyle || {}),
305
+ };
306
+ // 不在加载范围内,视renderHideContent和hideContentStyle情况而定
307
+ // @en Not in the loading range, depending on renderHideContent and hideContentStyle
308
+ if (renderHideContent) {
309
+ return (
310
+ <div {...contentProps} style={energySavingHideStyle}>
311
+ {renderHideContent(index, pane)}
312
+ </div>
313
+ );
314
+ }
315
+ if (hideContentStyle === null) {
316
+ return <div {...contentProps} style={energySavingStyle} />;
317
+ }
318
+ return (
319
+ <div {...contentProps} style={energySavingHideStyle}>
320
+ {pane}
321
+ </div>
322
+ );
323
+ }
324
+
325
+ return (
326
+ <div
327
+ className={cls(
328
+ `${prefix}-container`,
329
+ tabDirection,
330
+ swipeEnergySaving ? `mode-${mode}-energy-saving` : `mode-${mode}`,
331
+ tabPaneClass,
332
+ { 'full-screen': fullScreen },
333
+ {
334
+ [`mode-scroll-${scrollVertical ? 'vertical' : 'horizontal'}`]:
335
+ mode === 'scroll',
336
+ },
337
+ )}
338
+ style={getPaneStyle()}
339
+ ref={domRef}
340
+ onTouchEnd={handleTouchEnd}
341
+ onTouchCancel={handleTouchEnd}
342
+ >
343
+ {panes.map((pane, index) => renderContent(pane, index))}
344
+ {tabPaneExtra ? <div className={`${prefix}-extra`}>{tabPaneExtra}</div> : null}
345
+ </div>
346
+ );
347
+ });
348
+
349
+ export default TabPane;
@@ -0,0 +1,80 @@
1
+ ### 信息展示
2
+
3
+ # 标签 Tag
4
+
5
+ 标签组件,支持标签和标签组。
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |className|自定义类名|string|-|
14
+ |style|自定义样式|CSSProperties|-|
15
+ |type|样式类型。primary表示基本类型,hollow表示空心类型,solid表示实心类型|"primary" \| "hollow" \| "solid"|"primary"|
16
+ |icon|图标内容|ReactNode|-|
17
+ |children|标签内部内容|ReactNode|-|
18
+ |size|标签尺寸|"medium" \| "large" \| "small"|"medium"|
19
+ |color|文字颜色|string|-|
20
+ |bgColor|背景颜色|string|-|
21
+ |borderColor|边框颜色|string|-|
22
+ |borderStyle|边框样式|"solid" \| "none" \| "dotted" \| "dashed"|"solid"|
23
+ |halfBorder|是否是0\.5px边框|boolean|true|
24
+ |closeable|是否有关闭按钮|boolean|-|
25
+ |closeIcon|关闭按钮内容|ReactNode|-|
26
+ |closeColor|关闭按钮颜色|string|-|
27
+ |filleted|是否圆角|boolean|-|
28
+ |onClose|点击关闭按钮回调|(e: MouseEvent\<HTMLDivElement, MouseEvent\>) =\> void|-|
29
+ |onClick|点击标签回调|(e: MouseEvent\<HTMLDivElement, MouseEvent\>) =\> void|-|
30
+
31
+ > 引用/Refs
32
+
33
+ |参数|描述|类型|
34
+ |----------|-------------|------|
35
+ |dom|最外层元素 DOM|HTMLDivElement|
36
+
37
+ > Tag.List
38
+
39
+ 标签列表,支持动态编辑标签
40
+
41
+ |参数|描述|类型|默认值|
42
+ |----------|-------------|------|------|
43
+ |list|标签列表|(TagProps & RefAttributes\<TagRef\>)\[\]|必填|
44
+ |className|自定义类名|string|-|
45
+ |style|自定义样式|CSSProperties|-|
46
+ |type|样式类型。primary表示基本类型,hollow表示空心类型,solid表示实心类型|"primary" \| "hollow" \| "solid"|-|
47
+ |showAddButton|是否展示添加标签按钮|boolean|true|
48
+ |addArea|自定义添加标签按钮|ReactNode|-|
49
+ |horizontalPadding|标签横向间距|ReactText|-|
50
+ |verticalPadding|标签纵向间距|ReactText|-|
51
+ |onAdd|点击添加标签按钮回调|(e: MouseEvent\<HTMLDivElement, MouseEvent\>) =\> void|-|
52
+ |onClose|点击标签关闭按钮回调|(index: number, e: MouseEvent\<HTMLDivElement, MouseEvent\>) =\> void|-|
53
+
54
+ > TagProps
55
+
56
+ |参数|描述|类型|默认值|
57
+ |----------|-------------|------|------|
58
+ |className|自定义类名|string|-|
59
+ |style|自定义样式|CSSProperties|-|
60
+ |type|样式类型。primary表示基本类型,hollow表示空心类型,solid表示实心类型|"primary" \| "hollow" \| "solid"|"primary"|
61
+ |icon|图标内容|ReactNode|-|
62
+ |children|标签内部内容|ReactNode|-|
63
+ |size|标签尺寸|"medium" \| "large" \| "small"|"medium"|
64
+ |color|文字颜色|string|-|
65
+ |bgColor|背景颜色|string|-|
66
+ |borderColor|边框颜色|string|-|
67
+ |borderStyle|边框样式|"solid" \| "none" \| "dotted" \| "dashed"|"solid"|
68
+ |halfBorder|是否是0\.5px边框|boolean|true|
69
+ |closeable|是否有关闭按钮|boolean|-|
70
+ |closeIcon|关闭按钮内容|ReactNode|-|
71
+ |closeColor|关闭按钮颜色|string|-|
72
+ |filleted|是否圆角|boolean|-|
73
+ |onClose|点击关闭按钮回调|(e: MouseEvent\<HTMLDivElement, MouseEvent\>) =\> void|-|
74
+ |onClick|点击标签回调|(e: MouseEvent\<HTMLDivElement, MouseEvent\>) =\> void|-|
75
+
76
+ > TagListRef
77
+
78
+ |参数|描述|类型|
79
+ |----------|-------------|------|
80
+ |dom|最外层元素 DOM|HTMLDivElement|
@@ -0,0 +1,23 @@
1
+ import { componentWrapper } from '@arco-design/mobile-utils';
2
+ import { componentGenerator } from './list';
3
+ import { Tag } from './tag';
4
+
5
+ export * from './type';
6
+
7
+ /**
8
+ * 标签列表,支持动态编辑标签
9
+ * @en Tag list, support dynamic editing of tags
10
+ */
11
+ const List = componentGenerator(Tag);
12
+
13
+ /**
14
+ * 标签组件,支持标签和标签组。
15
+ * @en Tag component, supports tags and tag groups.
16
+ * @type 信息展示
17
+ * @type_en Data Display
18
+ * @name 标签
19
+ * @name_en Tag
20
+ */
21
+ export default componentWrapper(Tag, {
22
+ List,
23
+ });
@@ -0,0 +1,97 @@
1
+ import React, { useRef, forwardRef, Ref, useImperativeHandle, CSSProperties } from 'react';
2
+ import { cls } from '@arco-design/mobile-utils';
3
+ import { ContextLayout } from '../context-provider';
4
+ import { Tag } from './tag';
5
+ import IconAdd from '../icon/IconAdd';
6
+ import { TagListProps, TagListRef, TagProps, TagRef } from './type';
7
+
8
+ export function componentGenerator<P extends TagProps = TagProps, R extends TagRef = TagRef>(
9
+ Comp: React.ForwardRefExoticComponent<P & React.RefAttributes<R>>,
10
+ ) {
11
+ return forwardRef((props: TagListProps<P>, ref: Ref<TagListRef>) => {
12
+ const {
13
+ className,
14
+ style,
15
+ list,
16
+ type,
17
+ showAddButton = true,
18
+ addArea,
19
+ horizontalPadding,
20
+ verticalPadding,
21
+ onAdd,
22
+ onClose,
23
+ } = props;
24
+ const domRef = useRef<HTMLDivElement | null>(null);
25
+
26
+ useImperativeHandle(ref, () => ({
27
+ dom: domRef.current,
28
+ }));
29
+
30
+ function getTagStyle(tag: TagProps, index: number): CSSProperties {
31
+ const baseStyle = tag.style || {};
32
+ const paddingStyle =
33
+ index === list.length - 1 && !showAddButton
34
+ ? {}
35
+ : { marginRight: horizontalPadding };
36
+ return {
37
+ ...baseStyle,
38
+ ...paddingStyle,
39
+ marginBottom: verticalPadding,
40
+ };
41
+ }
42
+
43
+ function getListStyle() {
44
+ let marginStyle: CSSProperties = {};
45
+ if (verticalPadding && typeof verticalPadding === 'string') {
46
+ marginStyle = { marginBottom: `-${verticalPadding}` };
47
+ } else if (verticalPadding && typeof verticalPadding === 'number') {
48
+ marginStyle = { marginBottom: -1 * verticalPadding };
49
+ }
50
+ return {
51
+ ...(style || {}),
52
+ ...marginStyle,
53
+ };
54
+ }
55
+
56
+ return (
57
+ <ContextLayout>
58
+ {({ prefixCls, locale }) => {
59
+ const prefix = `${prefixCls}-tag-list`;
60
+ return (
61
+ <div className={cls(prefix, className)} style={getListStyle()} ref={domRef}>
62
+ {list.map((tag, index) => (
63
+ <Comp
64
+ key={index}
65
+ {...tag}
66
+ style={getTagStyle(tag, index)}
67
+ type={type}
68
+ onClose={e => {
69
+ tag.onClose && tag.onClose(e);
70
+ onClose && onClose(index, e);
71
+ }}
72
+ />
73
+ ))}
74
+ {showAddButton ? (
75
+ <div className="tag-list-add-wrap" onClick={onAdd}>
76
+ {addArea !== void 0 ? (
77
+ addArea
78
+ ) : (
79
+ <Tag
80
+ type={type}
81
+ className="tag-list-add"
82
+ borderStyle="dashed"
83
+ icon={<IconAdd />}
84
+ style={{ marginBottom: verticalPadding }}
85
+ >
86
+ {locale?.Tag.addTag}
87
+ </Tag>
88
+ )}
89
+ </div>
90
+ ) : null}
91
+ </div>
92
+ );
93
+ }}
94
+ </ContextLayout>
95
+ );
96
+ });
97
+ }
@@ -0,0 +1,85 @@
1
+ import React, { useRef, forwardRef, Ref, useImperativeHandle, CSSProperties } from 'react';
2
+ import { cls } from '@arco-design/mobile-utils';
3
+ import { ContextLayout } from '../context-provider';
4
+ import { useSystem } from '../_helpers';
5
+ import IconClose from '../icon/IconClose';
6
+ import { TagProps, TagRef } from './type';
7
+
8
+ export const Tag = forwardRef((props: TagProps, ref: Ref<TagRef>) => {
9
+ const {
10
+ className,
11
+ style,
12
+ type = 'primary',
13
+ icon,
14
+ children,
15
+ size = 'medium',
16
+ color,
17
+ bgColor,
18
+ borderColor,
19
+ borderStyle = 'solid',
20
+ halfBorder = true,
21
+ closeable,
22
+ closeIcon,
23
+ closeColor,
24
+ filleted,
25
+ onClose,
26
+ onClick,
27
+ } = props;
28
+ const domRef = useRef<HTMLDivElement | null>(null);
29
+ const system = useSystem();
30
+
31
+ useImperativeHandle(ref, () => ({
32
+ dom: domRef.current,
33
+ }));
34
+
35
+ function getTagStyle(): CSSProperties {
36
+ return {
37
+ color,
38
+ background: bgColor,
39
+ borderColor,
40
+ borderStyle,
41
+ ...(style || {}),
42
+ };
43
+ }
44
+
45
+ return (
46
+ <ContextLayout>
47
+ {({ prefixCls }) => {
48
+ const prefix = `${prefixCls}-tag`;
49
+ return (
50
+ <div
51
+ className={cls(
52
+ prefix,
53
+ 'all-border-box',
54
+ className,
55
+ `${prefix}-${type}`,
56
+ { 'half-border': halfBorder },
57
+ system,
58
+ `size-${size}`,
59
+ { filleted },
60
+ )}
61
+ style={getTagStyle()}
62
+ ref={domRef}
63
+ onClick={onClick}
64
+ >
65
+ {icon}
66
+ <span className="tag-text">{children}</span>
67
+ {closeable ? (
68
+ <div
69
+ onClick={e => {
70
+ e.stopPropagation();
71
+ onClose && onClose(e);
72
+ }}
73
+ className="tag-close-wrap"
74
+ >
75
+ {closeIcon || (
76
+ <IconClose className="tag-close-icon" color={closeColor} />
77
+ )}
78
+ </div>
79
+ ) : null}
80
+ </div>
81
+ );
82
+ }}
83
+ </ContextLayout>
84
+ );
85
+ });