@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,323 @@
1
+ import { cls } from '@arco-design/mobile-utils';
2
+ import React, { useRef, forwardRef, Ref, useImperativeHandle, useMemo } from 'react';
3
+ import { ContextLayout } from '../context-provider';
4
+ import { getStyleWithVendor, useGenSvgKey, useProgress } from '../_helpers';
5
+
6
+ export interface CircleProgressProps {
7
+ /**
8
+ * 自定义类名
9
+ * @en Custom classname
10
+ */
11
+ className?: string;
12
+ /**
13
+ * 自定义样式
14
+ * @en Custom stylesheet
15
+ */
16
+ style?: React.CSSProperties;
17
+ /** 文字显示位置
18
+ * @en Text display position
19
+ * @default "center"
20
+ */
21
+ percentPosition?: 'center' | 'bottom';
22
+ /**
23
+ * 是否显示圆环内部文字
24
+ * @en Whether to display the text inside the ring
25
+ * @default true
26
+ */
27
+ showPercent?: boolean;
28
+ /**
29
+ * 进度环百分比
30
+ * @en Progress ring Percentage
31
+ */
32
+ percentage: number;
33
+ /**
34
+ * 圆环内部文字显示(一个函数,返回ReactNode类型,回调参数为当前进度百分比)
35
+ * @en The text inside the ring (a function that returns the ReactNode type, and the callback parameter is the current progress percentage)
36
+ */
37
+ renderPercent?: (percentage: number) => React.ReactNode;
38
+ /**
39
+ * 轨道颜色
40
+ * @en Track color
41
+ */
42
+ trackColor?: string;
43
+ /**
44
+ * 进度环颜色
45
+ * @en progress ring color
46
+ */
47
+ progressColor?: string;
48
+ /**
49
+ * 是否置灰
50
+ * @en Whether to disable
51
+ * @default false
52
+ */
53
+ disabled?: boolean;
54
+ /**
55
+ * 轨道宽度
56
+ * @en Track width
57
+ * @default 10
58
+ */
59
+ trackStroke?: number;
60
+ /**
61
+ * 进度环宽度
62
+ * @en Progress ring width
63
+ * @default 12
64
+ */
65
+ progressStroke?: number;
66
+ /**
67
+ * 进度环渐变开始的颜色(当设置progressColorStart和progressColorEnd其中一个时,颜色会覆盖掉progressColor的颜色)
68
+ * @en The start gradient color of the progress ring (when one of progressColorStart and progressColorEnd is set, the color will override the color of progressColor)
69
+ */
70
+ progressColorStart?: string;
71
+ /**
72
+ * 进度环渐变结束的颜色
73
+ * @en The end gradient color of the progress ring
74
+ */
75
+ progressColorEnd?: string;
76
+ /**
77
+ * 每增加step步长所需的毫秒数
78
+ * @en The number of milliseconds required to increase the step size
79
+ * @default 30
80
+ */
81
+ duration?: number;
82
+ /**
83
+ * 步长(增加步长,以step增长)
84
+ * @en Step size (increase the step size, grow by step)
85
+ * @default 1
86
+ */
87
+ step?: number;
88
+ /**
89
+ * 是否逆时针增加
90
+ * @en Whether to increase counterclockwise
91
+ * @default false
92
+ */
93
+ clockwise?: boolean;
94
+ /**
95
+ * 圆环半径
96
+ * @en Ring radius
97
+ */
98
+ radius?: number;
99
+ /**
100
+ * 进度条两端是否圆角
101
+ * @en Whether the ends of the progress bar are rounded
102
+ * @default true
103
+ */
104
+ filleted?: boolean;
105
+ /**
106
+ * 初始化percentage时是否以动画形式过渡到目的值
107
+ * @en Whether to animate the transition to the destination value when initializing percentage
108
+ * @default true
109
+ */
110
+ mountedTransition?: boolean;
111
+ /**
112
+ * 进度环尺寸
113
+ * @en Progress ring size
114
+ * @default "default"
115
+ */
116
+ size?: 'mini' | 'default';
117
+ /**
118
+ * 初始化时动画的贝塞尔曲线
119
+ * @en Bezier curve of animation at initialization
120
+ * @default [0.34, 0.69, 0.1, 1]
121
+ */
122
+ mountedBezier?: [number, number, number, number];
123
+ /**
124
+ * 区分不同svg的`<def>`内容
125
+ * @en Distinguish `<def>` content of different svg
126
+ */
127
+ svgKey?: string;
128
+ }
129
+
130
+ export interface CircleProgressRef {
131
+ /**
132
+ * 最外层元素 DOM
133
+ * @en The outermost element DOM
134
+ */
135
+ dom: HTMLDivElement | null;
136
+ }
137
+
138
+ /**
139
+ * 环形进度条组件,以圆环形式表示百分比进度
140
+ * @en Annular progress bar component, representing percentage progress in the form of a circle
141
+ * @type 反馈
142
+ * @type_en Feedback
143
+ * @name 环形进度条
144
+ * @name_en CircleProgress
145
+ */
146
+ const CircleProgress = forwardRef((props: CircleProgressProps, ref: Ref<CircleProgressRef>) => {
147
+ const { size = 'default' } = props;
148
+ const {
149
+ className = '',
150
+ style,
151
+ percentPosition = 'center',
152
+ showPercent = size !== 'mini',
153
+ renderPercent,
154
+ trackColor,
155
+ progressColor,
156
+ disabled = false,
157
+ trackStroke = size === 'mini' ? 4 : 2,
158
+ progressStroke = 4,
159
+ progressColorStart,
160
+ progressColorEnd,
161
+ duration = 300,
162
+ step = 1,
163
+ clockwise = false,
164
+ radius = size === 'mini' ? 9 : 30,
165
+ filleted = size !== 'mini',
166
+ mountedTransition = true,
167
+ mountedBezier = [0.34, 0.69, 0.1, 1],
168
+ svgKey: userSetSvgKey = '',
169
+ } = props;
170
+ const domRef = useRef<HTMLDivElement | null>(null);
171
+ const maxStroke = Math.max(progressStroke, trackStroke);
172
+ const circlePos = maxStroke + radius;
173
+ const circleSize = (radius + maxStroke) * 2;
174
+ const circleLen = 2 * Math.PI * radius;
175
+ const percentage = Math.min(100, Math.max(props.percentage, 0));
176
+ const { svgKey } = useGenSvgKey(userSetSvgKey);
177
+
178
+ useImperativeHandle(ref, () => ({
179
+ dom: domRef.current,
180
+ }));
181
+
182
+ const isRenderNormal = !(Boolean(progressColorStart) && Boolean(progressColorEnd));
183
+ const [currentPercentage, transitionControl] = useProgress(
184
+ mountedTransition,
185
+ percentage,
186
+ duration,
187
+ mountedBezier,
188
+ step,
189
+ );
190
+ const color = useMemo(() => {
191
+ if (isRenderNormal) {
192
+ if (progressColorStart) {
193
+ return progressColorStart;
194
+ }
195
+ if (progressColorEnd) {
196
+ return progressColorEnd;
197
+ }
198
+ return progressColor;
199
+ }
200
+ }, [progressColorStart, progressColorEnd, progressColor]);
201
+ function renderNormalProgress() {
202
+ return (
203
+ <circle
204
+ cx={circlePos}
205
+ cy={circlePos}
206
+ r={radius}
207
+ strokeWidth={progressStroke}
208
+ className={cls('color', { disabled })}
209
+ strokeDashoffset={circleLen - (currentPercentage / 100) * circleLen || 0}
210
+ strokeDasharray={circleLen}
211
+ strokeLinecap={filleted ? 'round' : 'square'}
212
+ style={getStyleWithVendor({
213
+ transition: transitionControl
214
+ ? `stroke-dashoffset ${duration / 1000}s linear`
215
+ : '',
216
+ stroke: color,
217
+ })}
218
+ fill="none"
219
+ />
220
+ );
221
+ }
222
+ function renderLinearGradient() {
223
+ return (
224
+ <>
225
+ <defs>
226
+ <linearGradient
227
+ id={`${svgKey}-grad-circle-progress`}
228
+ x1="0%"
229
+ y1="0%"
230
+ x2="0%"
231
+ y2="100%"
232
+ >
233
+ <stop
234
+ offset="0%"
235
+ style={{ stopColor: progressColorEnd }}
236
+ className="linear-gradient-end"
237
+ />
238
+ <stop
239
+ offset="100%"
240
+ style={{ stopColor: progressColorStart }}
241
+ className="linear-gradient-start"
242
+ />
243
+ </linearGradient>
244
+ </defs>
245
+ <circle
246
+ cx={circlePos}
247
+ cy={circlePos}
248
+ r={radius}
249
+ strokeDashoffset={circleLen - (currentPercentage / 100) * circleLen || 0}
250
+ strokeDasharray={circleLen}
251
+ strokeWidth={progressStroke}
252
+ strokeLinecap={filleted ? 'round' : 'square'}
253
+ style={getStyleWithVendor({
254
+ transition: transitionControl
255
+ ? `stroke-dashoffset ${duration / 1000}s linear`
256
+ : '',
257
+ })}
258
+ className={cls({ disabled })}
259
+ stroke={`url(#${svgKey}-grad-circle-progress)`}
260
+ fill="none"
261
+ />
262
+ </>
263
+ );
264
+ }
265
+
266
+ function renderProgress() {
267
+ return isRenderNormal ? renderNormalProgress() : renderLinearGradient();
268
+ }
269
+
270
+ function renderCircleProgress({ prefixCls }) {
271
+ return (
272
+ <div
273
+ role="progressbar"
274
+ aria-valuemin={0}
275
+ aria-valuemax={100}
276
+ aria-valuenow={percentage}
277
+ className={cls(
278
+ `${prefixCls}-circle-progress`,
279
+ disabled ? `${prefixCls}-circle-progress-disabled` : '',
280
+ `${className}`,
281
+ )}
282
+ style={{ width: circleSize, height: circleSize, ...style }}
283
+ ref={domRef}
284
+ >
285
+ <svg
286
+ style={getStyleWithVendor({
287
+ transform: `rotateY(${clockwise ? 180 : 0}deg) rotateZ(-90deg)`,
288
+ })}
289
+ viewBox={`0 0 ${circleSize} ${circleSize}`}
290
+ >
291
+ <circle
292
+ cx={circlePos}
293
+ cy={circlePos}
294
+ r={radius}
295
+ style={{ stroke: trackColor }}
296
+ className={`${size === 'mini' ? 'mini' : 'track-color'}`}
297
+ strokeWidth={trackStroke}
298
+ fill="none"
299
+ />
300
+ {renderProgress()}
301
+ </svg>
302
+ {showPercent ? (
303
+ <div
304
+ className={cls(
305
+ `${prefixCls}-circle-progress-text`,
306
+ `${isRenderNormal ? 'color' : 'linear-gradient-text'}`,
307
+ `${prefixCls}-circle-progress-text-${percentPosition}`,
308
+ { disabled },
309
+ )}
310
+ style={{ color }}
311
+ >
312
+ {renderPercent !== void 0
313
+ ? renderPercent(currentPercentage)
314
+ : `${currentPercentage}%`}
315
+ </div>
316
+ ) : null}
317
+ </div>
318
+ );
319
+ }
320
+ return <ContextLayout>{renderCircleProgress}</ContextLayout>;
321
+ });
322
+
323
+ export default CircleProgress;
@@ -0,0 +1,74 @@
1
+ ### 信息展示
2
+
3
+ # 折叠面板 Collapse
4
+
5
+ 折叠面板组件,支持手风琴模式。
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |header|标题|ReactNode|-|
14
+ |value|折叠面板的唯一标识|string|必填|
15
+ |icon|折叠面板的展开图标|ReactNode|-|
16
+ |hideIcon|是否隐藏图标|boolean|false|
17
+ |disabled|是否不可展开|boolean|false|
18
+ |content|面板内容|ReactNode|必填|
19
+ |active|是否展开|boolean|-|
20
+ |defaultActive|默认展开情况|boolean|false|
21
+ |className|自定义类名|string|-|
22
+ |style|自定义样式|CSSProperties|-|
23
+ |onCollapse|可选受控,展开折叠面板时触发|(value: string) =\> void|-|
24
+ |animationTimeout|动画时间|number|-|
25
+ |animationFunction|动画函数|string|-|
26
+
27
+ > 引用/Refs
28
+
29
+ |参数|描述|类型|
30
+ |----------|-------------|------|
31
+ |dom|组件外层dom元素|HTMLDivElement|
32
+ |head|折叠面板头部元素|HTMLDivElement|
33
+ |updateLayout|手动更新组件布局(高度计算)|() =\> void|
34
+
35
+ > Collapse.Group
36
+
37
+ |参数|描述|类型|默认值|
38
+ |----------|-------------|------|------|
39
+ |className|自定义类名|string|-|
40
+ |style|自定义样式|CSSProperties|-|
41
+ |onCollapse|可选受控,展开折叠面板时触发|(value: string) =\> void|-|
42
+ |animationTimeout|动画时间|number|-|
43
+ |animationFunction|动画函数|string|-|
44
+ |useAccordion|是否使用手风琴模式|boolean|false|
45
+ |activeItems|可选受控,可传展开的item数组,或者每个item对应的状态|string\[\]|-|
46
+ |defaultActiveItems|默认状态|string\[\]|-|
47
+ |disabled|一键禁用|boolean|false|
48
+ |items|折叠面板数组|(CollapseProps & RefAttributes\<CollapseRef\>)\[\]|-|
49
+ |children|子元素,优先级高于items|ReactNode|-|
50
+ |groupKey|区分不同 group,有group 嵌套时建议传入|string|-|
51
+
52
+ > CollapseProps
53
+
54
+ |参数|描述|类型|默认值|
55
+ |----------|-------------|------|------|
56
+ |header|标题|ReactNode|-|
57
+ |value|折叠面板的唯一标识|string|必填|
58
+ |icon|折叠面板的展开图标|ReactNode|-|
59
+ |hideIcon|是否隐藏图标|boolean|false|
60
+ |disabled|是否不可展开|boolean|false|
61
+ |content|面板内容|ReactNode|必填|
62
+ |active|是否展开|boolean|-|
63
+ |defaultActive|默认展开情况|boolean|false|
64
+ |className|自定义类名|string|-|
65
+ |style|自定义样式|CSSProperties|-|
66
+ |onCollapse|可选受控,展开折叠面板时触发|(value: string) =\> void|-|
67
+ |animationTimeout|动画时间|number|-|
68
+ |animationFunction|动画函数|string|-|
69
+
70
+ > CollapseGroupRef
71
+
72
+ |参数|描述|类型|
73
+ |----------|-------------|------|
74
+ |dom|-|HTMLDivElement|
@@ -0,0 +1,183 @@
1
+ import React, {
2
+ useRef,
3
+ forwardRef,
4
+ Ref,
5
+ useImperativeHandle,
6
+ useState,
7
+ useEffect,
8
+ useContext,
9
+ } from 'react';
10
+ import { cls, convertCssDuration, nextTick } from '@arco-design/mobile-utils';
11
+ import { ContextLayout } from '../context-provider';
12
+ import { useRefState, useSameRefState, useUpdateEffect } from '../_helpers';
13
+ import IconArrowDown from '../icon/IconArrowDown';
14
+ import { CollapseProps, CollapseRef } from './type';
15
+ import { allContexts, CollapseKeyContext } from './utils';
16
+
17
+ export const Collapse = forwardRef((props: CollapseProps, ref: Ref<CollapseRef>) => {
18
+ const {
19
+ header = '',
20
+ icon,
21
+ hideIcon = false,
22
+ disabled = false,
23
+ content = null,
24
+ defaultActive = false,
25
+ value = '',
26
+ active,
27
+ animationTimeout,
28
+ animationFunction,
29
+ className = '',
30
+ style = {},
31
+ } = props;
32
+ const [innerActive, setInnerActive] = useState(defaultActive);
33
+ const [itemActive, itemActiveRef, setItemActive] = useRefState(
34
+ active === void 0 ? innerActive : active,
35
+ );
36
+ const contentHeightRef = useRef(0);
37
+ const collapseHeaderRef = useRef<HTMLDivElement>(null);
38
+ const domRef = useRef<HTMLDivElement>(null);
39
+ const contentWrapRef = useRef<HTMLDivElement>(null);
40
+ const contentRef = useRef<HTMLDivElement | null>(null);
41
+ const { key: groupKey } = useContext(CollapseKeyContext);
42
+ const CollapseContext = allContexts[groupKey] || {};
43
+ const groupContext = useContext(CollapseContext) || {};
44
+ const [opened, openedRef, setOpened] = useSameRefState(false);
45
+
46
+ useEffect(() => {
47
+ let show = false;
48
+ // 优先级: group > children
49
+ // @en Priority: group > children
50
+ if (groupContext.isGroup) {
51
+ if (active !== void 0) {
52
+ show = active;
53
+ }
54
+ if (groupContext.value) show = groupContext.value.includes(value);
55
+ } else {
56
+ show = itemActive;
57
+ }
58
+ setOpened(show);
59
+ }, [value, active, itemActive, groupContext.isGroup, groupContext.value]);
60
+
61
+ const getContentHeight = () => {
62
+ const div = contentRef.current;
63
+ return div?.getBoundingClientRect()?.height ?? 0;
64
+ };
65
+
66
+ const resetHeight = (newHeight: string) => {
67
+ if (!contentWrapRef.current) {
68
+ return;
69
+ }
70
+ contentWrapRef.current.style.height = newHeight;
71
+ const transTimeout = convertCssDuration(contentWrapRef.current, 'transitionDuration');
72
+ setTimeout(
73
+ () =>
74
+ contentWrapRef.current &&
75
+ (contentWrapRef.current.style.height = openedRef.current ? 'auto' : '0px'),
76
+ openedRef.current ? transTimeout : 20,
77
+ );
78
+ };
79
+
80
+ const toggleOpened = () => {
81
+ const height = getContentHeight();
82
+ const isBeginning = contentHeightRef.current === 0;
83
+ contentHeightRef.current = height;
84
+ if (isBeginning) {
85
+ const initHeight = opened ? 'auto' : '0px';
86
+ contentWrapRef.current && (contentWrapRef.current.style.height = initHeight);
87
+ return;
88
+ }
89
+ resetHeight(`${height}px`);
90
+ };
91
+
92
+ const updateLayout = () => {
93
+ if (!contentWrapRef.current) {
94
+ return;
95
+ }
96
+ const height = getContentHeight();
97
+ contentWrapRef.current.style.height = openedRef.current
98
+ ? `${contentHeightRef.current}px`
99
+ : '0px';
100
+ nextTick(() => {
101
+ contentHeightRef.current = height;
102
+ resetHeight(openedRef.current ? `${height}px` : '0px');
103
+ });
104
+ };
105
+
106
+ const onCollapse = (val: string) => {
107
+ if (disabled) return;
108
+ props.onCollapse && props.onCollapse(val);
109
+ if (!groupContext.isGroup) {
110
+ setInnerActive(!itemActiveRef.current);
111
+ } else {
112
+ groupContext.onCollapse(value);
113
+ }
114
+ };
115
+
116
+ useEffect(() => {
117
+ setItemActive(active === void 0 ? innerActive : active);
118
+ }, [active, innerActive]);
119
+
120
+ useImperativeHandle(ref, () => ({
121
+ dom: domRef.current,
122
+ head: collapseHeaderRef.current,
123
+ updateLayout,
124
+ }));
125
+
126
+ useEffect(() => {
127
+ toggleOpened();
128
+ }, [opened]);
129
+
130
+ useUpdateEffect(() => {
131
+ updateLayout();
132
+ }, [content]);
133
+
134
+ return (
135
+ <ContextLayout>
136
+ {({ prefixCls }) => (
137
+ <div
138
+ className={cls(`${prefixCls}-collapse-item`, className, {
139
+ disabled: disabled || groupContext.disabled,
140
+ })}
141
+ style={style}
142
+ ref={domRef}
143
+ >
144
+ <div
145
+ className={cls(`${prefixCls}-collapse-header`)}
146
+ ref={collapseHeaderRef}
147
+ onClick={() => onCollapse(value)}
148
+ >
149
+ {header}
150
+ {!hideIcon && (
151
+ <div className={cls(`${prefixCls}-collapse-icon`)}>
152
+ {icon || (
153
+ <IconArrowDown
154
+ className={`${prefixCls}-collapse-icon-arrow`}
155
+ style={{
156
+ transform: `rotate(${opened ? '180deg' : '0deg'})`,
157
+ }}
158
+ />
159
+ )}
160
+ </div>
161
+ )}
162
+ </div>
163
+ <div
164
+ className={cls(`${prefixCls}-collapse-content`)}
165
+ ref={contentWrapRef}
166
+ style={{
167
+ transitionDuration:
168
+ animationTimeout !== void 0 ? `${animationTimeout}ms` : void 0,
169
+ transitionTimingFunction: animationFunction,
170
+ }}
171
+ >
172
+ <div
173
+ className={cls(`${prefixCls}-collapse-content-container`)}
174
+ ref={contentRef}
175
+ >
176
+ {content}
177
+ </div>
178
+ </div>
179
+ </div>
180
+ )}
181
+ </ContextLayout>
182
+ );
183
+ });