@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,125 @@
1
+ import type { Ref } from 'react';
2
+ import React, { useRef, forwardRef, useImperativeHandle } from 'react';
3
+ import { cls, componentWrapper } from '@arco-design/mobile-utils';
4
+ import { ContextLayout, CompWithGlobalContext } from '../context-provider';
5
+ import type { MaskingCommonProps, MaskingRef, OpenBaseProps } from '../masking';
6
+ import Masking from '../masking';
7
+ import { open } from './methods';
8
+
9
+ export * from './methods';
10
+
11
+ export type DirectionType = 'left' | 'right' | 'top' | 'bottom';
12
+
13
+ export interface PopupProps extends MaskingCommonProps {
14
+ /**
15
+ * 菜单滑出方向
16
+ * @en The direction the menu slides out
17
+ * @default "bottom"
18
+ */
19
+ direction?: DirectionType;
20
+ /**
21
+ * 从底部滑出的菜单内容是否适配ipx底部
22
+ * @en Whether the content of the menu that slides out from the bottom fits the bottom of ipx
23
+ * @default false
24
+ */
25
+ needBottomOffset?: boolean;
26
+ /**
27
+ * [即将废弃] 开启translateZ强制提升
28
+ * @en [To be deprecated] Enable translateZ forced promotion
29
+ * @default false
30
+ * @deprecated
31
+ */
32
+ translateZ?: boolean;
33
+ /**
34
+ * 菜单蒙层动画时长
35
+ * @en Menu mask animation duration
36
+ * @default { enter: 450, exit: 240 }
37
+ */
38
+ maskTransitionTimeout?: MaskingCommonProps['maskTransitionTimeout'];
39
+ /**
40
+ * 菜单内容动画时长
41
+ * @en Menu content animation duration
42
+ * @default { enter: 450, exit: 240 }
43
+ */
44
+ contentTransitionTimeout?: MaskingCommonProps['contentTransitionTimeout'];
45
+ /**
46
+ * 内容过渡动画类名
47
+ * @en Content transition animation classname
48
+ * @default \`slide-from-${props.direction}\`
49
+ */
50
+ contentTransitionType?: MaskingCommonProps['contentTransitionType'];
51
+ }
52
+
53
+ export interface PopupRef extends MaskingRef {}
54
+
55
+ const Popup = forwardRef((props: PopupProps, ref: Ref<PopupRef>) => {
56
+ const {
57
+ children,
58
+ maskClass,
59
+ contentClass,
60
+ contentTransitionType,
61
+ className,
62
+ direction = 'bottom',
63
+ needBottomOffset = false,
64
+ translateZ = false,
65
+ maskTransitionTimeout = { enter: 450, exit: 240 },
66
+ contentTransitionTimeout = { enter: 450, exit: 240 },
67
+ ...restProps
68
+ } = props;
69
+ const maskingRef = useRef<MaskingRef>(null);
70
+
71
+ useImperativeHandle(ref, () => maskingRef.current!);
72
+
73
+ function renderPopup({ prefixCls }) {
74
+ const prefix = `${prefixCls}-popup`;
75
+ return (
76
+ <Masking
77
+ className={cls(prefix, className)}
78
+ ref={maskingRef}
79
+ maskClass={cls(`${prefix}-mask`, { translateZ }, maskClass)}
80
+ contentTransitionType={contentTransitionType || `slide-from-${direction}`}
81
+ contentTransitionVarType="popup-slide"
82
+ contentClass={cls(
83
+ `${prefix}-content`,
84
+ direction,
85
+ {
86
+ 'need-bottom-offset': needBottomOffset,
87
+ },
88
+ { translateZ },
89
+ contentClass,
90
+ )}
91
+ maskTransitionTimeout={maskTransitionTimeout}
92
+ contentTransitionTimeout={contentTransitionTimeout}
93
+ {...restProps}
94
+ >
95
+ {children}
96
+ </Masking>
97
+ );
98
+ }
99
+
100
+ return <ContextLayout>{renderPopup}</ContextLayout>;
101
+ });
102
+
103
+ export function methodsGenerator<P extends OpenBaseProps>(Comp: React.FunctionComponent<P>) {
104
+ return {
105
+ /**
106
+ * 打开弹出层
107
+ * @desc {en} Open the popup
108
+ * @param {PopupProps} config Configuration
109
+ * @returns {{ close: () => void; update: (newConfig: PopupProps) => void; }}
110
+ */
111
+ open: open(Comp),
112
+ };
113
+ }
114
+
115
+ const PopupWithGlobalContext = CompWithGlobalContext(Popup);
116
+
117
+ /**
118
+ * 基于模态弹窗的的全屏菜单,支持各个方向。默认做了防滚动穿透处理,如果弹层内容中需要滚动,则需将滚动容器传入`getScrollContainer`属性以在未滚动到顶部或底部时释放滚动。
119
+ * @en A full-screen menu based on a modal popup, supporting all directions. By default, anti-scroll penetration processing is performed. If scrolling is required in the content of the popup layer, you need to pass the scroll container to the `getScrollContainer` property to release scrolling when it is not scrolled to the top or bottom.
120
+ * @type 反馈
121
+ * @type_en Feedback
122
+ * @name 弹出层
123
+ * @name_en Popup
124
+ */
125
+ export default componentWrapper(Popup, methodsGenerator(PopupWithGlobalContext));
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { open as maskingOpen, OpenBaseProps } from '../masking/methods';
3
+
4
+ export function open<P extends OpenBaseProps>(Component: React.FunctionComponent<P>) {
5
+ return maskingOpen(Component, 'ARCO_POPUP');
6
+ }
@@ -0,0 +1,108 @@
1
+ ### 反馈
2
+
3
+ # 可滑动弹出层 PopupSwiper
4
+
5
+ 基于弹出层(Popup)封装的具有手势关闭功能的弹出层组件,拥有 Popup 组件的其他能力。
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |percentToClose|滑动超过内容的百分之多少时关闭弹窗,范围为\[0, 1\],如果该属性和\`distanceToClose\`属性均设置,则实际计算结果更大的生效|number|0.3|
14
+ |distanceToClose|滑动超过多少px时关闭弹窗,如果该属性和\`percentToClose\`属性均设置,则实际计算结果更大的生效|number|10|
15
+ |speedToClose|手指从按下到抬起之间的滑动速度超过多少时关闭弹窗(单位为px/s),与滑动关闭距离阈值同时设置时,满足其中一个即生效|number|200|
16
+ |allowSwipeDirections|自定义可手势滑动退出的方向,可指定多个方向|DirectionType\[\]|direction 属性指定的方向性|
17
+ |exitDirection|固定弹窗退出方向,默认跟随手势滑动方向|"left" \| "right" \| "top" \| "bottom"|-|
18
+ |onTouchStart|内容面板 touchstart 事件,返回true时表示阻止本组件内部处理事件|(e: TouchEvent) =\> boolean \| void|-|
19
+ |onTouchMove|内容面板 touchmove 事件,返回true时表示阻止本组件内部处理事件|(e: TouchEvent, prevented: boolean, direction: "x" \| "y") =\> boolean \| void|-|
20
+ |onTouchEnd|内容面板 touchend / touchcancel 事件,返回true时表示阻止本组件内部处理事件|(e: TouchEvent) =\> boolean \| void|-|
21
+ |direction|菜单滑出方向|"left" \| "right" \| "top" \| "bottom"|"bottom"|
22
+ |needBottomOffset|从底部滑出的菜单内容是否适配ipx底部|boolean|false|
23
+ |translateZ|\[即将废弃\] 开启translateZ强制提升|boolean|false|
24
+ |maskTransitionTimeout|菜单蒙层动画时长|number \| \{ appear?: number; enter?: number; exit?: number; \}|{ enter: 450, exit: 240 }|
25
+ |contentTransitionTimeout|菜单内容动画时长|number \| \{ appear?: number; enter?: number; exit?: number; \}|{ enter: 450, exit: 240 }|
26
+ |contentTransitionType|内容过渡动画类名|string|\`slide-from-${props.direction}\`|
27
+ |className|自定义类名|string|-|
28
+ |maskClass|自定义蒙层类名|string|-|
29
+ |maskStyle|自定义蒙层样式|CSSProperties|-|
30
+ |contentClass|自定义内容类名|string|-|
31
+ |contentStyle|自定义内容样式|CSSProperties|-|
32
+ |visible|是否展示菜单(受控)|boolean|必填|
33
+ |close|关闭菜单方法|(e: MouseEvent\<HTMLElement, MouseEvent\>) =\> void|必填|
34
+ |maskTransitionType|蒙层过渡动画类名|string|"fade"|
35
+ |contentTransitionVarType|内容过渡动画类名变量标识|string|-|
36
+ |children|菜单内部内容|ReactNode|-|
37
+ |maskClosable|点击蒙层是否关闭菜单|boolean|true|
38
+ |animatingClosable|执行进场动画时点击蒙层是否可关闭菜单|boolean|false|
39
+ |mountOnEnter|是否在打开菜单时再加载内容|boolean|true|
40
+ |unmountOnExit|是否在退出时卸载内容|boolean|true|
41
+ |orientationDirection|transform方向,用于通过transform模拟横屏的情况|"left" \| "right" \| "top" \| "bottom"|"top"|
42
+ |preventBodyScroll|弹窗打开时是否禁止body的滚动|boolean|true|
43
+ |initialBodyOverflow|页面初始 overflow 状态,即关闭弹窗时 overflow 应该还原的状态|string|第一个全屏组件(弹窗、toast等)打开时页面overflow值|
44
+ |gestureOutOfControl|是否禁用滚动容器手势判断,禁用后交给业务方自己判断|boolean|false|
45
+ |onClose|关闭后回调(动画执行完毕)|(scene?: string) =\> void|-|
46
+ |onOpen|打开后回调(动画执行完毕)|() =\> void|-|
47
+ |onMaskClick|点击蒙层回调,maskClosable=false时也会触发|() =\> void|-|
48
+ |onPreventTouchMove|非滚动区域或滚动到顶部及底部时的触摸事件回调|(e: TouchEvent, direction: "x" \| "y") =\> void|-|
49
+ |getContainer|获取挂载容器|() =\> HTMLElement|-|
50
+ |getScrollContainer|内容内部滚动区域容器,在该容器中未滚动到顶部或底部时会释放滚动|() =\> HTMLElement \| HTMLElement\[\]|-|
51
+
52
+ > 引用/Refs
53
+
54
+ |参数|描述|类型|
55
+ |----------|-------------|------|
56
+ |dom|最外层元素 DOM|HTMLDivElement|
57
+ |mask|蒙层 DOM|HTMLDivElement|
58
+ |content|内容 DOM|HTMLDivElement|
59
+ |setCloseScene|在关闭弹窗前修改 onClose 的 scene 参数值|(scene: string) =\> void|
60
+
61
+ > 方法/Methods
62
+
63
+ |方法名|描述|类型|
64
+ |----------|-------------|------|
65
+ |open|打开弹出层|(config: string \| PopupSwiperProps) =\> \{ close: () =\> void; update: (newConfig: PopupSwiperProps) =\> void; \}|
66
+
67
+ > DirectionType
68
+
69
+ ```
70
+ "left" | "right" | "top" | "bottom"
71
+ ```
72
+
73
+ > GlobalContextParams
74
+
75
+ |参数|描述|类型|默认值|
76
+ |----------|-------------|------|------|
77
+ |prefixCls|组件类名前缀|string|"arco"|
78
+ |system|手动控制当前所在系统,传入后将直接使用传入的值,ssr场景需指定系统初始值时适用|"" \| "pc" \| "android" \| "ios"|""|
79
+ |useDarkMode|是否监听系统原生的暗黑模式变化(prefers\-color\-scheme: dark)以判断是否切为暗黑模式|boolean|false|
80
+ |isDarkMode|是否处于暗黑模式,指定后以指定的值为准|boolean|false|
81
+ |darkModeSelector|当处于暗黑模式时,body上挂载的类名,为空值时不挂载类名|string|"arco-theme-dark"|
82
+ |theme|主题变量,传入后将在线替换css变量,需设置less变量 @use\-css\-vars: 1|Record\<string, string\>|-|
83
+ |locale|国际化语言包配置|ILocale|-|
84
+ |useRtl|是否使用Rtl模式|boolean|false|
85
+ |onDarkModeChange|当系统原生暗黑模式发生变化时触发,useDarkMode=true 时有效|(isDark: boolean) =\> void|-|
86
+ |createRoot|React19 修改了 createRoot 的引入路径,导致组件内部无法直接引入(低react版本会找不到模块)。因此使用 react 19 的用户需从外部传入 createRoot 方法|CreateRootFnType|-|
87
+
88
+ > ILocale
89
+
90
+ |参数|描述|类型|
91
+ |----------|-------------|------|
92
+ |locale|语言类型|string|
93
+ |LoadMore|-|\{ loadMoreText: string; loadingText: string; noDataText: string; failLoadText: string; prepareScrollText: string; prepareClickText: string; \}|
94
+ |Picker|-|\{ okText: string; cancelText: string; \}|
95
+ |Tag|-|\{ addTag: string; \}|
96
+ |Dialog|-|\{ okText: string; cancelText: string; \}|
97
+ |SwipeLoad|-|\{ normalText: string; activeText: string; \}|
98
+ |PullRefresh|-|\{ loadingText: string; pullingText: string; finishText: string; loosingText: string; \}|
99
+ |DropdownMenu|-|\{ select: string; \}|
100
+ |Pagination|-|\{ previousPage: string; nextPage: string; \}|
101
+ |Image|-|\{ loadError: string; \}|
102
+ |ImagePicker|-|\{ loadError: string; \}|
103
+ |SearchBar|-|\{ placeholder: string; cancelBtn: string; \}|
104
+ |Stepper|-|\{ minusButtonName: string; addButtonName: string; \}|
105
+ |Keyboard|-|\{ confirm: string; \}|
106
+ |Form|-|\{ required: string; type: \{ email: string; url: string; string: string; number: string; array: string; object: string; boolean: string; \}; number: \{ min: string; max: string; equal: string; range: string; positive: string; negative: string; \}; \.\.\. 4 more \.\.\.; pickerDefaultHint: string; \}|
107
+ |NavBar|-|\{ backBtnAriaLabel: string; \}|
108
+ |Uploader|-|\{ uploadBtn: string; retryUpload: string; \}|
@@ -0,0 +1,332 @@
1
+ import React, {
2
+ useRef,
3
+ forwardRef,
4
+ Ref,
5
+ useImperativeHandle,
6
+ useCallback,
7
+ useState,
8
+ useEffect,
9
+ useMemo,
10
+ } from 'react';
11
+ import { cls, componentWrapper, nextTick } from '@arco-design/mobile-utils';
12
+ import { ContextLayout, CompWithGlobalContext } from '../context-provider';
13
+ import { OpenBaseProps } from '../masking';
14
+ import Popup, { DirectionType, PopupProps, PopupRef } from '../popup';
15
+ import { open } from './methods';
16
+ import { getStyleWithVendor, useRefState } from '../_helpers';
17
+
18
+ export interface PopupSwiperProps extends PopupProps {
19
+ /**
20
+ * 滑动超过内容的百分之多少时关闭弹窗,范围为[0, 1],如果该属性和`distanceToClose`属性均设置,则实际计算结果更大的生效
21
+ * @en Close the popup when sliding more than the percentage of the content, the range is [0, 1]. If both this property and the `distanceToClose` property are set, the larger the actual calculation result takes effect
22
+ * @default 0.3
23
+ */
24
+ percentToClose?: number;
25
+ /**
26
+ * 滑动超过多少px时关闭弹窗,如果该属性和`percentToClose`属性均设置,则实际计算结果更大的生效
27
+ * @en Close the popup when sliding more than px, if this property and the `percentToClose` property are both set, the larger the actual calculation result takes effect.
28
+ * @default 10
29
+ */
30
+ distanceToClose?: number;
31
+ /**
32
+ * 手指从按下到抬起之间的滑动速度超过多少时关闭弹窗(单位为px/s),与滑动关闭距离阈值同时设置时,满足其中一个即生效
33
+ * @en Close the popup when the finger slides between pressing and lifting (unit: px/s). When it is set at the same time as the sliding closing distance threshold, it will take effect if one of them is satisfied.
34
+ * @default 200
35
+ */
36
+ speedToClose?: number;
37
+ /**
38
+ * 自定义可手势滑动退出的方向,可指定多个方向
39
+ * @en Custom direction of the gesture swipe exit, you can specify multiple directions
40
+ * @default direction 属性指定的方向性
41
+ * @default_en The value of direction property
42
+ */
43
+ allowSwipeDirections?: DirectionType[];
44
+ /**
45
+ * 固定弹窗退出方向,默认跟随手势滑动方向
46
+ * @en Fixed the exit direction of the pop-up window, and the default sliding direction follows the gesture
47
+ */
48
+ exitDirection?: DirectionType;
49
+ /**
50
+ * 内容面板 touchstart 事件,返回true时表示阻止本组件内部处理事件
51
+ * @en The touchstart callback of content panel. When it returns true, it means that the event is prevented from being processed inside the component
52
+ */
53
+ onTouchStart?: (e: TouchEvent) => void | boolean;
54
+ /**
55
+ * 内容面板 touchmove 事件,返回true时表示阻止本组件内部处理事件
56
+ * @en The touchmove callback of content panel. When it returns true, it means that the event is prevented from being processed inside the component
57
+ */
58
+ onTouchMove?: (e: TouchEvent, prevented: boolean, direction: 'x' | 'y') => void | boolean;
59
+ /**
60
+ * 内容面板 touchend / touchcancel 事件,返回true时表示阻止本组件内部处理事件
61
+ * @en The touchend / touchcancel callback of content panel. When it returns true, it means that the event is prevented from being processed inside the component
62
+ */
63
+ onTouchEnd?: (e: TouchEvent) => void | boolean;
64
+ }
65
+
66
+ export interface PopupSwiperRef extends PopupRef {}
67
+
68
+ const PopupSwiper = forwardRef((props: PopupSwiperProps, ref: Ref<PopupSwiperRef>) => {
69
+ const {
70
+ className = '',
71
+ visible,
72
+ children,
73
+ maskStyle,
74
+ contentStyle,
75
+ direction = 'bottom',
76
+ percentToClose = 0.3,
77
+ distanceToClose = 10,
78
+ speedToClose = 200,
79
+ allowSwipeDirections,
80
+ exitDirection,
81
+ onTouchMove,
82
+ onTouchStart,
83
+ onTouchEnd,
84
+ onOpen,
85
+ onClose,
86
+ close,
87
+ maskTransitionTimeout = { enter: 450, exit: 240 },
88
+ contentTransitionTimeout = { enter: 450, exit: 240 },
89
+ ...otherProps
90
+ } = props;
91
+ const [opened, setOpened] = useState(visible);
92
+ const [distance, distanceRef, setDistance] = useRefState<{
93
+ direction: 'X' | 'Y';
94
+ value: number;
95
+ }>({
96
+ direction: 'X',
97
+ value: 0,
98
+ });
99
+ const [hasTrans, setHasTrans] = useState(false);
100
+ const popupRef = useRef<PopupRef>(null);
101
+ const touchStartXRef = useRef(0);
102
+ const touchStartYRef = useRef(0);
103
+ const touchStartTimeRef = useRef(0);
104
+ const hasTouchStartRef = useRef(false);
105
+ const getContentSize = useCallback((direc: 'X' | 'Y') => {
106
+ const contentDom = popupRef.current?.content;
107
+ const contentWidth = contentDom?.offsetWidth || 0;
108
+ const contentHeight = contentDom?.offsetHeight || 0;
109
+ const contentSize = direc === 'X' ? contentWidth : contentHeight;
110
+ return contentSize;
111
+ }, []);
112
+ const getPercent = useCallback((dis: { direction: 'X' | 'Y'; value: number }) => {
113
+ const { direction: direc, value } = dis;
114
+ const contentSize = getContentSize(direc);
115
+ return contentSize ? Math.max(0, Math.min(1, Math.abs(value) / contentSize)) : 0;
116
+ }, []);
117
+ const percent = useMemo(() => getPercent(distance), [distance]);
118
+ const allowedDirections = useMemo(
119
+ () => (allowSwipeDirections !== void 0 ? allowSwipeDirections : [direction]),
120
+ [allowSwipeDirections, direction],
121
+ );
122
+
123
+ const handleTouchStart = useCallback(
124
+ (e: TouchEvent) => {
125
+ if (onTouchStart && onTouchStart(e)) {
126
+ return;
127
+ }
128
+ setHasTrans(false);
129
+ hasTouchStartRef.current = true;
130
+ touchStartXRef.current = e.touches?.[0]?.clientX || 0;
131
+ touchStartYRef.current = e.touches?.[0]?.clientY || 0;
132
+ touchStartTimeRef.current = new Date().getTime();
133
+ },
134
+ [onTouchStart],
135
+ );
136
+
137
+ const getMovingFromDirection = useCallback(
138
+ (direc: 'X' | 'Y', disX: number, disY: number): DirectionType => {
139
+ if (direc === 'X') {
140
+ return disX > 0 ? 'right' : 'left';
141
+ }
142
+ return disY > 0 ? 'bottom' : 'top';
143
+ },
144
+ [],
145
+ );
146
+
147
+ const handleTouchMove = useCallback(
148
+ (e: TouchEvent, prevented: boolean, direc: 'x' | 'y') => {
149
+ if (onTouchMove && onTouchMove(e, prevented, direc)) {
150
+ return;
151
+ }
152
+ // 如果prevented=false说明正在滚动,则专心处理滚动事件而不处理跟手退出
153
+ if (!prevented) {
154
+ hasTouchStartRef.current = false;
155
+ }
156
+ if (!hasTouchStartRef.current || e.target === popupRef.current?.mask) {
157
+ return;
158
+ }
159
+ const touchMoveX = e.changedTouches?.[0]?.clientX || 0;
160
+ const touchMoveY = e.changedTouches?.[0]?.clientY || 0;
161
+ const disX = touchMoveX < 0 ? 0 : touchMoveX - touchStartXRef.current;
162
+ const disY = touchMoveY - touchStartYRef.current;
163
+ const fromDirec = getMovingFromDirection(direc === 'x' ? 'X' : 'Y', disX, disY);
164
+ const movingFromDirec = allowedDirections.includes(fromDirec) ? fromDirec : '';
165
+ const disDirection = exitDirection || movingFromDirec;
166
+ const direcValue = ['top', 'bottom'].includes(disDirection) ? 'Y' : 'X';
167
+ const direcRatio = ['bottom', 'right'].includes(disDirection) ? 1 : -1;
168
+ switch (movingFromDirec) {
169
+ case 'top':
170
+ case 'bottom':
171
+ setDistance({
172
+ direction: direcValue,
173
+ value: Math.abs(disY) * direcRatio,
174
+ });
175
+ break;
176
+ case 'left':
177
+ case 'right':
178
+ setDistance({
179
+ direction: direcValue,
180
+ value: Math.abs(disX) * direcRatio,
181
+ });
182
+ break;
183
+ default:
184
+ break;
185
+ }
186
+ },
187
+ [onTouchMove, allowedDirections, exitDirection],
188
+ );
189
+
190
+ const getDescDisFromDirection = useCallback((direc: 'X' | 'Y', dis: number): number => {
191
+ const fromDirec = getMovingFromDirection(direc, dis, dis);
192
+ const contentSize = getContentSize(direc);
193
+ const prefix = fromDirec === 'left' || fromDirec === 'top' ? -1 : 1;
194
+ return prefix * contentSize;
195
+ }, []);
196
+
197
+ const handleTouchEnd = useCallback(
198
+ e => {
199
+ if (onTouchEnd && onTouchEnd(e)) {
200
+ return;
201
+ }
202
+ if (!hasTouchStartRef.current) {
203
+ return;
204
+ }
205
+ hasTouchStartRef.current = false;
206
+ const touchEndTime = new Date().getTime();
207
+ const { direction: direc, value } = distanceRef.current;
208
+ const per = getPercent(distanceRef.current);
209
+ const speed = (value / (touchEndTime - touchStartTimeRef.current)) * 1000;
210
+ if (
211
+ (per > 0 && per >= percentToClose && Math.abs(value) > distanceToClose) ||
212
+ Math.abs(speed) > speedToClose
213
+ ) {
214
+ setHasTrans(false);
215
+ close(e);
216
+ nextTick(() => {
217
+ setDistance({
218
+ direction: direc,
219
+ value: getDescDisFromDirection(direc, value),
220
+ });
221
+ });
222
+ } else {
223
+ setHasTrans(true);
224
+ setDistance({
225
+ direction: 'X',
226
+ value: 0,
227
+ });
228
+ // 动画完成后需重置
229
+ // @en Reset after animation is complete
230
+ setTimeout(() => {
231
+ setHasTrans(false);
232
+ }, Math.max(typeof maskTransitionTimeout === 'number' ? maskTransitionTimeout : maskTransitionTimeout?.exit || 0, typeof contentTransitionTimeout === 'number' ? contentTransitionTimeout : contentTransitionTimeout?.exit || 0, 240));
233
+ }
234
+ touchStartTimeRef.current = 0;
235
+ },
236
+ [onTouchEnd, percentToClose, distanceToClose, speedToClose, close],
237
+ );
238
+
239
+ useImperativeHandle(ref, () => popupRef.current!);
240
+
241
+ useEffect(() => {
242
+ const contentDom = popupRef.current?.content;
243
+ if (opened && contentDom) {
244
+ contentDom.addEventListener('touchstart', handleTouchStart);
245
+ contentDom.addEventListener('touchend', handleTouchEnd);
246
+ contentDom.addEventListener('touchcancel', handleTouchEnd);
247
+ }
248
+ return () => {
249
+ const ctDom = popupRef.current?.content;
250
+ if (opened && ctDom) {
251
+ ctDom.removeEventListener('touchstart', handleTouchStart);
252
+ ctDom.removeEventListener('touchend', handleTouchEnd);
253
+ ctDom.removeEventListener('touchcancel', handleTouchEnd);
254
+ }
255
+ };
256
+ }, [opened, handleTouchStart, handleTouchEnd]);
257
+
258
+ function getContentStyle() {
259
+ const disStyle = getStyleWithVendor({
260
+ transform: distance.value
261
+ ? `translate${distance.direction}(${distance.value}px) translateZ(2px)`
262
+ : void 0,
263
+ });
264
+ return {
265
+ ...(contentStyle || {}),
266
+ ...disStyle,
267
+ };
268
+ }
269
+
270
+ return (
271
+ <ContextLayout>
272
+ {({ prefixCls }) => (
273
+ <Popup
274
+ ref={popupRef}
275
+ visible={visible}
276
+ close={close}
277
+ className={cls(`${prefixCls}-popup-swiper`, className, {
278
+ 'has-trans': hasTrans,
279
+ })}
280
+ direction={direction}
281
+ onTouchMove={handleTouchMove}
282
+ onOpen={() => {
283
+ setOpened(true);
284
+ onOpen?.();
285
+ }}
286
+ onClose={scene => {
287
+ setOpened(false);
288
+ setDistance({
289
+ direction: 'X',
290
+ value: 0,
291
+ });
292
+ onClose?.(scene);
293
+ }}
294
+ maskStyle={{
295
+ ...(maskStyle || {}),
296
+ opacity: percent ? 1 - percent : void 0,
297
+ }}
298
+ contentStyle={getContentStyle()}
299
+ maskTransitionTimeout={maskTransitionTimeout}
300
+ contentTransitionTimeout={contentTransitionTimeout}
301
+ {...otherProps}
302
+ >
303
+ {children}
304
+ </Popup>
305
+ )}
306
+ </ContextLayout>
307
+ );
308
+ });
309
+
310
+ export function methodsGenerator<P extends OpenBaseProps>(Comp: React.FunctionComponent<P>) {
311
+ return {
312
+ /**
313
+ * 打开弹出层
314
+ * @desc {en} Open the PopupSwiper
315
+ * @param {string | PopupSwiperProps} config Configuration
316
+ * @returns {{ close: () => void; update: (newConfig: PopupSwiperProps) => void; }}
317
+ */
318
+ open: open(Comp),
319
+ };
320
+ }
321
+
322
+ const PopupSwiperWithGlobalContext = CompWithGlobalContext(PopupSwiper);
323
+
324
+ /**
325
+ * 基于弹出层(Popup)封装的具有手势关闭功能的弹出层组件,拥有 Popup 组件的其他能力。
326
+ * @en The popup with gesture closing function based on the popup encapsulation, has other capabilities of the Popup component.
327
+ * @type 反馈
328
+ * @type_en Feedback
329
+ * @name 可滑动弹出层
330
+ * @name_en PopupSwiper
331
+ */
332
+ export default componentWrapper(PopupSwiper, methodsGenerator(PopupSwiperWithGlobalContext));
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { open as maskingOpen, OpenBaseProps } from '../masking/methods';
3
+
4
+ export function open<P extends OpenBaseProps>(Component: React.FunctionComponent<P>) {
5
+ return maskingOpen(Component, 'ARCO_POPUP_SWIPER');
6
+ }
@@ -0,0 +1,14 @@
1
+ ### 其他
2
+
3
+ # 自定义挂载 Portal
4
+
5
+ React.createPortal的简单封装。
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |children|被挂载的内容|ReactNode|-|
14
+ |getContainer|容器获取函数|() =\> HTMLElement|() => document.body|
@@ -0,0 +1,35 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import ReactDOM from 'react-dom';
3
+
4
+ export interface PortalProps {
5
+ /**
6
+ * 被挂载的内容
7
+ * @en Content to be mounted
8
+ */
9
+ children?: React.ReactNode;
10
+ /**
11
+ * 容器获取函数
12
+ * @en Container getter function
13
+ * @default () => document.body
14
+ */
15
+ getContainer?: () => HTMLElement;
16
+ }
17
+
18
+ /**
19
+ * React.createPortal的简单封装。
20
+ * @en Simple wrapper for React.createPortal
21
+ * @type 其他
22
+ * @type_en Others
23
+ * @name 自定义挂载
24
+ * @name_en Portal
25
+ */
26
+ export default function Portal(props: PortalProps) {
27
+ const [container, setContainer] = useState<HTMLElement>();
28
+ const { children, getContainer } = props;
29
+
30
+ useEffect(() => {
31
+ setContainer(getContainer ? getContainer() : document.body);
32
+ }, [getContainer]);
33
+
34
+ return container ? ReactDOM.createPortal(children, container) : null;
35
+ }
@@ -0,0 +1,42 @@
1
+ ### 反馈
2
+
3
+ # 进度条 Progress
4
+
5
+ 进度条组件,可根据外界传递进来的百分比进行进度展示
6
+
7
+ ======
8
+
9
+ > 属性/Props
10
+
11
+ |参数|描述|类型|默认值|
12
+ |----------|-------------|------|------|
13
+ |className|自定义类名|string|-|
14
+ |style|自定义样式|CSSProperties|-|
15
+ |percentPosition|文字显示位置|"left" \| "innerLeft" \| "right" \| "follow"|"center"|
16
+ |showPercent|是否显示进度条内部文字|boolean|true|
17
+ |percentage|进度环百分比|number|必填|
18
+ |renderPercent|进度条内部文字显示(一个函数,返回ReactNode类型,回调参数为当前进度百分比)|(percentage: number) =\> ReactNode|-|
19
+ |trackColor|轨道颜色|string|-|
20
+ |progressColor|进度条颜色|string|-|
21
+ |disabled|是否置灰|boolean|false|
22
+ |trackStroke|轨道粗细|number|一般默认为4,percentPosition=innerLeft 时为18,mode=nav时为2|
23
+ |progressStroke|进度条粗细|number|继承 trackStroke 值|
24
+ |duration|每增加step步长所需的毫秒数|number|300|
25
+ |step|步长(增加步长,以step增长)|number|1|
26
+ |filleted|进度条是否两端圆角|boolean|true|
27
+ |mountedTransition|初始化percentage时是否以动画形式过渡到目的值|boolean|true|
28
+ |mountedBezier|初始化时动画的贝塞尔曲线|BezierType|[0.34, 0.69, 0.1, 1]|
29
+ |mode|模式可选为nav或者base模式|"nav" \| "base"|"base"|
30
+ |top|距离屏幕顶部的距离(只有当mode为"nav"才有效)|number|0|
31
+
32
+ > 引用/Refs
33
+
34
+ |参数|描述|类型|
35
+ |----------|-------------|------|
36
+ |dom|最外层元素 DOM|HTMLDivElement|
37
+
38
+ > PercentPosition
39
+
40
+ ```
41
+ "left" | "innerLeft" | "right" | "follow"
42
+ ```