@mpxjs/webpack-plugin 2.9.67 → 2.9.69-beta.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 (140) hide show
  1. package/lib/index.js +13 -8
  2. package/lib/platform/json/wx/index.js +21 -8
  3. package/lib/platform/style/wx/index.js +35 -38
  4. package/lib/platform/template/wx/component-config/canvas.js +8 -0
  5. package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
  6. package/lib/platform/template/wx/component-config/index.js +1 -1
  7. package/lib/platform/template/wx/component-config/input.js +1 -1
  8. package/lib/platform/template/wx/component-config/rich-text.js +8 -0
  9. package/lib/platform/template/wx/component-config/swiper.js +1 -1
  10. package/lib/platform/template/wx/component-config/textarea.js +1 -1
  11. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  12. package/lib/react/processStyles.js +14 -4
  13. package/lib/react/processTemplate.js +3 -0
  14. package/lib/resolver/AddModePlugin.js +8 -8
  15. package/lib/runtime/components/react/context.ts +6 -0
  16. package/lib/runtime/components/react/dist/context.js +2 -0
  17. package/lib/runtime/components/react/dist/event.config.js +24 -24
  18. package/lib/runtime/components/react/dist/getInnerListeners.js +183 -174
  19. package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
  20. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  21. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  22. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  23. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  24. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  25. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  26. package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
  27. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
  28. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  29. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
  30. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
  31. package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
  32. package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
  33. package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
  34. package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
  35. package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
  36. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
  37. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +13 -13
  38. package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
  39. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
  40. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
  41. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
  42. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
  43. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
  44. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
  45. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
  46. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +160 -88
  47. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
  48. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
  49. package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
  50. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  51. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +63 -0
  52. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
  53. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +47 -41
  54. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -2
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +606 -0
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
  59. package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
  60. package/lib/runtime/components/react/dist/mpx-view.jsx +65 -61
  61. package/lib/runtime/components/react/dist/mpx-web-view.jsx +112 -35
  62. package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
  63. package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
  64. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  65. package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
  66. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -9
  67. package/lib/runtime/components/react/dist/utils.jsx +70 -23
  68. package/lib/runtime/components/react/event.config.ts +25 -26
  69. package/lib/runtime/components/react/getInnerListeners.ts +237 -199
  70. package/lib/runtime/components/react/mpx-button.tsx +104 -57
  71. package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
  72. package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
  73. package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
  74. package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
  75. package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
  76. package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
  77. package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
  78. package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
  79. package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
  80. package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
  81. package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
  82. package/lib/runtime/components/react/mpx-form.tsx +25 -28
  83. package/lib/runtime/components/react/mpx-icon.tsx +12 -17
  84. package/lib/runtime/components/react/mpx-image.tsx +436 -0
  85. package/lib/runtime/components/react/mpx-input.tsx +77 -57
  86. package/lib/runtime/components/react/mpx-label.tsx +26 -27
  87. package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
  88. package/lib/runtime/components/react/mpx-movable-view.tsx +21 -25
  89. package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
  90. package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
  91. package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
  92. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
  93. package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
  94. package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
  95. package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
  96. package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
  97. package/lib/runtime/components/react/mpx-picker-view-column.tsx +236 -104
  98. package/lib/runtime/components/react/mpx-picker-view.tsx +132 -122
  99. package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
  100. package/lib/runtime/components/react/mpx-radio.tsx +45 -54
  101. package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
  102. package/lib/runtime/components/react/mpx-rich-text/index.tsx +121 -0
  103. package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
  104. package/lib/runtime/components/react/mpx-scroll-view.tsx +72 -71
  105. package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
  106. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
  107. package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
  108. package/lib/runtime/components/react/mpx-switch.tsx +29 -23
  109. package/lib/runtime/components/react/mpx-text.tsx +14 -18
  110. package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
  111. package/lib/runtime/components/react/mpx-view.tsx +92 -76
  112. package/lib/runtime/components/react/mpx-web-view.tsx +116 -54
  113. package/lib/runtime/components/react/pickerFaces.ts +104 -0
  114. package/lib/runtime/components/react/pickerOverlay.tsx +32 -0
  115. package/lib/runtime/components/react/types/common.ts +2 -0
  116. package/lib/runtime/components/react/types/global.d.ts +5 -17
  117. package/lib/runtime/components/react/useAnimationHooks.ts +36 -11
  118. package/lib/runtime/components/react/utils.tsx +99 -28
  119. package/lib/runtime/components/web/getInnerListeners.js +6 -6
  120. package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
  121. package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
  122. package/lib/runtime/components/web/mpx-picker.vue +382 -385
  123. package/lib/runtime/components/web/mpx-web-view.vue +175 -161
  124. package/lib/runtime/optionProcessor.js +7 -38
  125. package/lib/runtime/utils.js +2 -0
  126. package/lib/style-compiler/plugins/scope-id.js +30 -2
  127. package/lib/template-compiler/bind-this.js +7 -2
  128. package/lib/template-compiler/compiler.js +79 -47
  129. package/lib/template-compiler/gen-node-react.js +3 -3
  130. package/lib/utils/pre-process-json.js +9 -5
  131. package/package.json +6 -4
  132. package/LICENSE +0 -433
  133. package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
  134. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
  135. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
  136. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
  137. package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
  138. package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
  139. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
  140. package/lib/runtime/components/web/event.js +0 -105
@@ -0,0 +1,606 @@
1
+ import { View, Dimensions } from 'react-native';
2
+ import { GestureDetector, Gesture } from 'react-native-gesture-handler';
3
+ import Animated, { useAnimatedStyle, useSharedValue, withTiming, Easing, runOnJS, useAnimatedReaction, cancelAnimation } from 'react-native-reanimated';
4
+ import React, { forwardRef, useRef, useEffect, useState } from 'react';
5
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
6
+ import useNodesRef from './useNodesRef'; // 引入辅助函数
7
+ import { useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren } from './utils';
8
+ /**
9
+ * 默认的Style类型
10
+ */
11
+ const styles = {
12
+ pagination_x: {
13
+ position: 'absolute',
14
+ bottom: 25,
15
+ left: 0,
16
+ right: 0,
17
+ flexDirection: 'row',
18
+ flex: 1,
19
+ justifyContent: 'center',
20
+ alignItems: 'center'
21
+ },
22
+ pagination_y: {
23
+ position: 'absolute',
24
+ right: 15,
25
+ top: 0,
26
+ bottom: 0,
27
+ flexDirection: 'column',
28
+ flex: 1,
29
+ justifyContent: 'center',
30
+ alignItems: 'center'
31
+ },
32
+ pagerWrapper: {
33
+ position: 'absolute',
34
+ flexDirection: 'row',
35
+ justifyContent: 'center',
36
+ alignItems: 'center'
37
+ },
38
+ swiper: {
39
+ overflow: 'scroll',
40
+ display: 'flex',
41
+ justifyContent: 'flex-start'
42
+ }
43
+ };
44
+ const dotCommonStyle = {
45
+ width: 8,
46
+ height: 8,
47
+ borderRadius: 4,
48
+ marginLeft: 3,
49
+ marginRight: 3,
50
+ marginTop: 3,
51
+ marginBottom: 3,
52
+ zIndex: 98
53
+ };
54
+ const activeDotStyle = {
55
+ zIndex: 99
56
+ };
57
+ // 默认前后补位的元素个数
58
+ const patchElementNum = 1;
59
+ const longPressRatio = 100;
60
+ const easeMap = {
61
+ default: Easing.linear,
62
+ linear: Easing.linear,
63
+ easeInCubic: Easing.in(Easing.cubic),
64
+ easeOutCubic: Easing.out(Easing.cubic),
65
+ easeInOutCubic: Easing.inOut(Easing.cubic)
66
+ };
67
+ const SwiperWrapper = forwardRef((props, ref) => {
68
+ const { 'indicator-dots': showsPagination, 'indicator-color': dotColor = 'rgba(0, 0, 0, .3)', 'indicator-active-color': activeDotColor = '#000000', 'enable-var': enableVar = false, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'external-var-context': externalVarContext, style = {} } = props;
69
+ const previousMargin = props['previous-margin'] ? parseInt(props['previous-margin']) : 0;
70
+ const nextMargin = props['next-margin'] ? parseInt(props['next-margin']) : 0;
71
+ const easeingFunc = props['easing-function'] || 'default';
72
+ const easeDuration = props.duration || 500;
73
+ const horizontal = props.vertical !== undefined ? !props.vertical : true;
74
+ const nodeRef = useRef(null);
75
+ useNodesRef(props, ref, nodeRef, {});
76
+ // 默认取水平方向的width
77
+ const { width } = Dimensions.get('window');
78
+ // 计算transfrom之类的
79
+ const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, {
80
+ enableVar,
81
+ externalVarContext,
82
+ parentFontSize,
83
+ parentWidth,
84
+ parentHeight
85
+ });
86
+ const { textStyle } = splitStyle(normalStyle);
87
+ const { textProps } = splitProps(props);
88
+ const children = Array.isArray(props.children) ? props.children.filter(child => child) : (props.children ? [props.children] : []);
89
+ const defaultHeight = (normalStyle?.height || 150);
90
+ const defaultWidth = (normalStyle?.width || width || 375);
91
+ const initWidth = typeof defaultWidth === 'number' ? defaultWidth - previousMargin - nextMargin : defaultWidth;
92
+ const initHeight = typeof defaultHeight === 'number' ? defaultHeight - previousMargin - nextMargin : defaultHeight;
93
+ const [widthState, setWidthState] = useState(initWidth);
94
+ const [heightState, setHeightState] = useState(initHeight);
95
+ const dir = useSharedValue(horizontal === false ? 'y' : 'x');
96
+ const pstep = dir.value === 'x' ? widthState : heightState;
97
+ const initStep = isNaN(pstep) ? 0 : pstep;
98
+ // 每个元素的宽度 or 高度
99
+ const step = useSharedValue(initStep);
100
+ const totalElements = useSharedValue(children.length);
101
+ // 记录选中元素的索引值
102
+ const targetIndex = useSharedValue(0);
103
+ // 记录元素的偏移量
104
+ const offset = useSharedValue(0);
105
+ const strTrans = 'translation' + dir.value.toUpperCase();
106
+ const strAbso = 'absolute' + dir.value.toUpperCase();
107
+ const strVelocity = 'velocity' + dir.value.toUpperCase();
108
+ const arrPages = renderItems();
109
+ // autoplay的状态下是否被暂停
110
+ const paused = useRef(false);
111
+ // 标识手指触摸和抬起, 起点在onBegin
112
+ const touchfinish = useSharedValue(false);
113
+ // 用户是否触发了move事件,起点在onStart, 触发move事件才会执行onEnd, 1. 移动一定会触发onStart, onTouchesMove, onEnd 2. 点击未进行操作, 会触发onTouchsUp
114
+ const isTriggerStart = useSharedValue(false);
115
+ // 记录用户点击时绝对定位坐标
116
+ const preAbsolutePos = useSharedValue(0);
117
+ const timerId = useRef(0);
118
+ // 用户点击未移动状态下,记录用户上一次操作的transtion 的 direction
119
+ const customTrans = useSharedValue(0);
120
+ const intervalTimer = props.interval || 500;
121
+ totalElements.value = children.length;
122
+ const {
123
+ // 存储layout布局信息
124
+ layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef, onLayout: onWrapperLayout });
125
+ const innerProps = useInnerProps(props, {
126
+ ref: nodeRef
127
+ }, [
128
+ 'style',
129
+ 'indicator-dots',
130
+ 'indicator-color',
131
+ 'indicator-active-color',
132
+ 'previous-margin',
133
+ 'vertical',
134
+ 'previous-margin',
135
+ 'next-margin',
136
+ 'easing-function',
137
+ 'autoplay',
138
+ 'circular',
139
+ 'interval',
140
+ 'easing-function'
141
+ ], { layoutRef: layoutRef });
142
+ function onWrapperLayout(e) {
143
+ const { width, height } = e.nativeEvent.layout;
144
+ const realWidth = dir.value === 'x' ? width - previousMargin - nextMargin : width;
145
+ const realHeight = dir.value === 'y' ? height - previousMargin - nextMargin : height;
146
+ setWidthState(realWidth);
147
+ setHeightState(realHeight);
148
+ }
149
+ const dotAnimatedStyle = useAnimatedStyle(() => {
150
+ const step = dir.value === 'x' ? widthState : heightState;
151
+ if (isNaN(+step))
152
+ return {};
153
+ const dotStep = dotCommonStyle.width + dotCommonStyle.marginRight + dotCommonStyle.marginLeft;
154
+ return {
155
+ transform: [{
156
+ translateX: targetIndex.value * dotStep
157
+ }]
158
+ };
159
+ });
160
+ function renderPagination() {
161
+ const stepValue = getStepValue();
162
+ if (totalElements.value <= 1 || isNaN(+stepValue))
163
+ return null;
164
+ const activeColor = activeDotColor || '#007aff';
165
+ const unActionColor = dotColor || 'rgba(0,0,0,.2)';
166
+ // 正常渲染所有dots
167
+ const dots = [];
168
+ for (let i = 0; i < totalElements.value; i++) {
169
+ dots.push(<View style={[dotCommonStyle, { backgroundColor: unActionColor }]} key={i}></View>);
170
+ }
171
+ return (<View pointerEvents="none" style={[styles['pagination_' + [dir.value]]]}>
172
+ <View style={[styles.pagerWrapper]}>
173
+ <Animated.View style={[
174
+ dotCommonStyle,
175
+ activeDotStyle,
176
+ {
177
+ backgroundColor: activeColor,
178
+ position: 'absolute',
179
+ left: 0
180
+ },
181
+ dotAnimatedStyle
182
+ ]}/>
183
+ {dots}
184
+ </View>
185
+ </View>);
186
+ }
187
+ function renderItems() {
188
+ const pageStyle = { width: widthState, height: heightState };
189
+ let renderChild = children.slice();
190
+ if (props.circular && totalElements.value > 1) {
191
+ // 最前面加最后一个元素
192
+ const lastChild = React.cloneElement(children[totalElements.value - 1]);
193
+ // 最后面加第一个元素
194
+ const firstChild = React.cloneElement(children[0]);
195
+ renderChild = [lastChild].concat(renderChild).concat(firstChild);
196
+ }
197
+ return renderChild.map((child, index) => {
198
+ const extraStyle = {};
199
+ const xCondition = dir.value === 'x' && typeof widthState === 'number';
200
+ const yCondition = dir.value === 'y' && typeof heightState === 'number';
201
+ if (index === 0 && (xCondition || yCondition)) {
202
+ previousMargin && dir.value === 'x' && (extraStyle.marginLeft = previousMargin);
203
+ previousMargin && dir.value === 'y' && (extraStyle.marginTop = previousMargin);
204
+ }
205
+ if (index === totalElements.value - 1 && (xCondition || yCondition)) {
206
+ nextMargin && dir.value === 'x' && (extraStyle.marginRight = nextMargin);
207
+ nextMargin && dir.value === 'y' && (extraStyle.marginBottom = nextMargin);
208
+ }
209
+ return (<Animated.View style={[
210
+ pageStyle,
211
+ extraStyle
212
+ ]} key={'page' + index}>
213
+ {child}
214
+ </Animated.View>);
215
+ });
216
+ }
217
+ function createAutoPlay() {
218
+ let targetOffset = 0;
219
+ let nextIndex = targetIndex.value;
220
+ if (!props.circular) {
221
+ // 获取下一个位置的坐标, 循环到最后一个元素,直接停止, 取消定时器
222
+ if (targetIndex.value === totalElements.value - 1) {
223
+ pauseLoop();
224
+ return;
225
+ }
226
+ nextIndex += 1;
227
+ targetOffset = -nextIndex * step.value;
228
+ offset.value = withTiming(targetOffset, {
229
+ duration: easeDuration,
230
+ easing: easeMap[easeingFunc]
231
+ }, () => {
232
+ offset.value = targetOffset;
233
+ targetIndex.value = nextIndex;
234
+ });
235
+ }
236
+ else {
237
+ // 默认向右, 向下
238
+ if (nextIndex === totalElements.value - 1) {
239
+ nextIndex = 0;
240
+ targetOffset = -(totalElements.value + patchElementNum) * step.value;
241
+ // 执行动画到下一帧
242
+ offset.value = withTiming(targetOffset, {
243
+ duration: easeDuration
244
+ }, () => {
245
+ const initOffset = -step.value * patchElementNum;
246
+ // 将开始位置设置为真正的位置
247
+ offset.value = initOffset;
248
+ targetIndex.value = nextIndex;
249
+ });
250
+ }
251
+ else {
252
+ nextIndex = targetIndex.value + 1;
253
+ targetOffset = -(nextIndex + patchElementNum) * step.value;
254
+ // 执行动画到下一帧
255
+ offset.value = withTiming(targetOffset, {
256
+ duration: easeDuration,
257
+ easing: easeMap[easeingFunc]
258
+ }, () => {
259
+ offset.value = targetOffset;
260
+ targetIndex.value = nextIndex;
261
+ });
262
+ }
263
+ }
264
+ }
265
+ function handleSwiperChange(current) {
266
+ const eventData = getCustomEvent('change', {}, { detail: { current, source: 'touch' }, layoutRef: layoutRef });
267
+ props.bindchange && props.bindchange(eventData);
268
+ }
269
+ function getStepValue() {
270
+ 'worklet';
271
+ return dir.value === 'x' ? widthState : heightState;
272
+ }
273
+ function getInitOffset() {
274
+ const stepValue = getStepValue();
275
+ if (isNaN(+stepValue))
276
+ return 0;
277
+ let targetOffset = 0;
278
+ if (props.circular && totalElements.value > 1) {
279
+ const targetIndex = (props.current || 0) + patchElementNum;
280
+ targetOffset = -stepValue * targetIndex;
281
+ }
282
+ else if (props.current && props.current > 0) {
283
+ targetOffset = -props.current * stepValue;
284
+ }
285
+ return targetOffset;
286
+ }
287
+ function loop() {
288
+ if (!paused.current) {
289
+ timerId.current = setTimeout(() => {
290
+ createAutoPlay();
291
+ loop();
292
+ }, intervalTimer);
293
+ }
294
+ }
295
+ function pauseLoop() {
296
+ paused.current = true;
297
+ clearTimeout(timerId.current);
298
+ }
299
+ function resumeLoop() {
300
+ if (props.autoplay && paused.current) {
301
+ paused.current = false;
302
+ loop();
303
+ }
304
+ }
305
+ useAnimatedReaction(() => targetIndex.value, (newIndex, preIndex) => {
306
+ // 这里必须传递函数名, 直接写()=> {}形式会报 访问了未sharedValue信息
307
+ const isInit = !preIndex && newIndex === 0;
308
+ if (!isInit && props.current !== newIndex && props.bindchange) {
309
+ runOnJS(handleSwiperChange)(newIndex);
310
+ }
311
+ });
312
+ useEffect(() => {
313
+ // 这里stepValue 有时候拿不到
314
+ const stepValue = getStepValue();
315
+ if (isNaN(+stepValue)) {
316
+ return;
317
+ }
318
+ step.value = stepValue;
319
+ const targetOffset = getInitOffset();
320
+ if (props.current !== undefined && (props.current !== targetIndex.value || (props.current === 0 && targetIndex.value > 0))) {
321
+ targetIndex.value = props.current;
322
+ offset.value = withTiming(targetOffset, {
323
+ duration: easeDuration,
324
+ easing: easeMap[easeingFunc]
325
+ }, () => {
326
+ offset.value = targetOffset;
327
+ });
328
+ }
329
+ else {
330
+ offset.value = targetOffset;
331
+ }
332
+ }, [props.current, widthState, heightState]);
333
+ useEffect(() => {
334
+ const stepValue = getStepValue();
335
+ if (isNaN(+stepValue)) {
336
+ return;
337
+ }
338
+ const targetOffset = getInitOffset();
339
+ if (props.autoplay) {
340
+ pauseLoop();
341
+ offset.value = targetOffset;
342
+ resumeLoop();
343
+ }
344
+ else {
345
+ pauseLoop();
346
+ }
347
+ return () => { pauseLoop(); };
348
+ }, [props.autoplay, widthState, heightState]);
349
+ function getTargetPosition(eventData) {
350
+ 'worklet';
351
+ // 移动的距离
352
+ const { translation } = eventData;
353
+ let resetOffsetPos = 0;
354
+ let selectedIndex = targetIndex.value;
355
+ // 是否临界点
356
+ let isCriticalItem = false;
357
+ // 真实滚动到的偏移量坐标
358
+ let moveToTargetPos = 0;
359
+ // 当前的位置
360
+ const currentOffset = offset.value;
361
+ const currentIndex = Math.abs(currentOffset) / step.value;
362
+ const moveToIndex = translation < 0 ? Math.ceil(currentIndex) : Math.floor(currentIndex);
363
+ // 实际应该定位的索引值
364
+ if (!props.circular) {
365
+ selectedIndex = moveToIndex;
366
+ moveToTargetPos = selectedIndex * step.value;
367
+ }
368
+ else {
369
+ if (moveToIndex >= totalElements.value + patchElementNum) {
370
+ selectedIndex = moveToIndex - (totalElements.value + patchElementNum);
371
+ resetOffsetPos = (selectedIndex + patchElementNum) * step.value;
372
+ moveToTargetPos = moveToIndex * step.value;
373
+ isCriticalItem = true;
374
+ }
375
+ else if (moveToIndex <= patchElementNum - 1) {
376
+ selectedIndex = moveToIndex === 0 ? totalElements.value - patchElementNum : totalElements.value - 1;
377
+ resetOffsetPos = (selectedIndex + patchElementNum) * step.value;
378
+ moveToTargetPos = moveToIndex * step.value;
379
+ isCriticalItem = true;
380
+ }
381
+ else {
382
+ selectedIndex = moveToIndex - patchElementNum;
383
+ moveToTargetPos = moveToIndex * step.value;
384
+ }
385
+ }
386
+ return {
387
+ selectedIndex,
388
+ isCriticalItem,
389
+ resetOffset: -resetOffsetPos,
390
+ targetOffset: -moveToTargetPos
391
+ };
392
+ }
393
+ function canMove(eventData) {
394
+ 'worklet';
395
+ const { translation } = eventData;
396
+ const stepValue = getStepValue();
397
+ const currentOffset = Math.abs(offset.value);
398
+ if (!props.circular) {
399
+ if (translation < 0) {
400
+ return currentOffset + Math.abs(translation) < stepValue * (totalElements.value - 1);
401
+ }
402
+ else {
403
+ return currentOffset - Math.abs(translation) > 0;
404
+ }
405
+ }
406
+ else {
407
+ return true;
408
+ }
409
+ }
410
+ function handleEnd(eventData) {
411
+ 'worklet';
412
+ const { isCriticalItem, targetOffset, resetOffset, selectedIndex } = getTargetPosition(eventData);
413
+ if (isCriticalItem) {
414
+ offset.value = withTiming(targetOffset, {
415
+ duration: easeDuration,
416
+ easing: easeMap[easeingFunc]
417
+ }, () => {
418
+ if (touchfinish.value !== false) {
419
+ targetIndex.value = selectedIndex;
420
+ offset.value = resetOffset;
421
+ runOnJS(resumeLoop)();
422
+ }
423
+ });
424
+ }
425
+ else {
426
+ offset.value = withTiming(targetOffset, {
427
+ duration: easeDuration,
428
+ easing: easeMap[easeingFunc]
429
+ }, () => {
430
+ if (touchfinish.value !== false) {
431
+ targetIndex.value = selectedIndex;
432
+ offset.value = targetOffset;
433
+ runOnJS(resumeLoop)();
434
+ }
435
+ });
436
+ }
437
+ }
438
+ function handleBack(eventData) {
439
+ 'worklet';
440
+ const { translation } = eventData;
441
+ // 向右滑动的back:trans < 0, 向左滑动的back: trans < 0
442
+ const currentOffset = Math.abs(offset.value);
443
+ const curIndex = currentOffset / step.value;
444
+ const moveToIndex = (translation < 0 ? Math.floor(curIndex) : Math.ceil(curIndex)) - patchElementNum;
445
+ const targetOffset = -(moveToIndex + patchElementNum) * step.value;
446
+ offset.value = withTiming(targetOffset, {
447
+ duration: easeDuration,
448
+ easing: easeMap[easeingFunc]
449
+ }, () => {
450
+ if (touchfinish.value !== false) {
451
+ offset.value = targetOffset;
452
+ targetIndex.value = moveToIndex;
453
+ runOnJS(resumeLoop)();
454
+ }
455
+ });
456
+ }
457
+ function handleLongPress(eventData) {
458
+ 'worklet';
459
+ const { translation } = eventData;
460
+ const currentOffset = Math.abs(offset.value);
461
+ const half = currentOffset % step.value > step.value / 2;
462
+ // 向右trans < 0, 向左trans > 0
463
+ const isExceedHalf = translation < 0 ? half : !half;
464
+ if (+translation === 0) {
465
+ runOnJS(resumeLoop)();
466
+ }
467
+ else if (isExceedHalf) {
468
+ handleEnd(eventData);
469
+ }
470
+ else {
471
+ handleBack(eventData);
472
+ }
473
+ }
474
+ function reachBoundary(eventData) {
475
+ 'worklet';
476
+ // 移动的距离
477
+ const { translation } = eventData;
478
+ const elementsLength = step.value * totalElements.value;
479
+ let isBoundary = false;
480
+ let resetOffset = 0;
481
+ // Y轴向下滚动, transDistance > 0, 向上滚动 < 0 X轴向左滚动, transDistance > 0
482
+ const currentOffset = offset.value;
483
+ const moveStep = Math.ceil(translation / elementsLength);
484
+ if (translation < 0) {
485
+ const posEnd = (totalElements.value + patchElementNum + 1) * step.value;
486
+ const posReverseEnd = (patchElementNum - 1) * step.value;
487
+ if (currentOffset < -posEnd + step.value) {
488
+ isBoundary = true;
489
+ resetOffset = Math.abs(moveStep) === 0 ? patchElementNum * step.value + translation : moveStep * elementsLength;
490
+ }
491
+ if (currentOffset > -posReverseEnd) {
492
+ isBoundary = true;
493
+ resetOffset = moveStep * elementsLength;
494
+ }
495
+ }
496
+ else if (translation > 0) {
497
+ const posEnd = (patchElementNum - 1) * step.value;
498
+ const posReverseEnd = (patchElementNum + totalElements.value) * step.value;
499
+ if (currentOffset > -posEnd) {
500
+ isBoundary = true;
501
+ resetOffset = moveStep * elementsLength + step.value + (moveStep === 1 ? translation : 0);
502
+ }
503
+ if (currentOffset < -posReverseEnd) {
504
+ isBoundary = true;
505
+ resetOffset = moveStep * elementsLength + patchElementNum * step.value;
506
+ }
507
+ }
508
+ return {
509
+ isBoundary,
510
+ resetOffset: -resetOffset
511
+ };
512
+ }
513
+ const gestureHandler = Gesture.Pan()
514
+ .onBegin((e) => {
515
+ 'worklet';
516
+ touchfinish.value = false;
517
+ cancelAnimation(offset);
518
+ runOnJS(pauseLoop)();
519
+ preAbsolutePos.value = e[strAbso];
520
+ })
521
+ .onStart(() => {
522
+ 'worklet';
523
+ isTriggerStart.value = true;
524
+ })
525
+ .onTouchesMove((e) => {
526
+ 'worklet';
527
+ const touchEventData = e.changedTouches[0];
528
+ const moveDistance = touchEventData[strAbso] - preAbsolutePos.value;
529
+ customTrans.value = moveDistance;
530
+ const eventData = {
531
+ translation: moveDistance
532
+ };
533
+ // 处理用户一直拖拽到临界点的场景, 不会执行onEnd
534
+ if (!props.circular && !canMove(eventData)) {
535
+ return;
536
+ }
537
+ const { isBoundary, resetOffset } = reachBoundary(eventData);
538
+ if (isBoundary && props.circular && !touchfinish.value) {
539
+ offset.value = resetOffset;
540
+ }
541
+ else {
542
+ offset.value = moveDistance + offset.value;
543
+ }
544
+ preAbsolutePos.value = touchEventData[strAbso];
545
+ })
546
+ .onTouchesUp((e) => {
547
+ 'worklet';
548
+ // 未触发移动不会触发onStart事件, touches事件拿到的数据只有absoluteX 和 x, 无法判断方向
549
+ if (!isTriggerStart.value) {
550
+ const eventData = {
551
+ translation: customTrans.value
552
+ };
553
+ handleLongPress(eventData);
554
+ }
555
+ isTriggerStart.value = false;
556
+ touchfinish.value = true;
557
+ })
558
+ .onEnd((e) => {
559
+ 'worklet';
560
+ const eventData = {
561
+ translation: e[strTrans]
562
+ };
563
+ if (!props.circular && !canMove(eventData) && isTriggerStart.value) {
564
+ return;
565
+ }
566
+ if (Math.abs(e[strVelocity]) < longPressRatio) {
567
+ handleLongPress(eventData);
568
+ }
569
+ else {
570
+ handleEnd(eventData);
571
+ }
572
+ });
573
+ const animatedStyles = useAnimatedStyle(() => {
574
+ if (dir.value === 'x') {
575
+ return { transform: [{ translateX: offset.value }] };
576
+ }
577
+ else {
578
+ return { transform: [{ translateY: offset.value }] };
579
+ }
580
+ });
581
+ function renderSwiper() {
582
+ return (<View style={[normalStyle, layoutStyle, styles.swiper]} {...layoutProps} {...innerProps}>
583
+ <Animated.View style={[{ flexDirection: dir.value === 'x' ? 'row' : 'column' }, animatedStyles]}>
584
+ {wrapChildren({
585
+ children: arrPages
586
+ }, {
587
+ hasVarDec,
588
+ varContext: varContextRef.current,
589
+ textStyle,
590
+ textProps
591
+ })}
592
+ </Animated.View>
593
+ {showsPagination && renderPagination()}
594
+ </View>);
595
+ }
596
+ if (totalElements.value === 1) {
597
+ return renderSwiper();
598
+ }
599
+ else {
600
+ return (<GestureDetector gesture={gestureHandler}>
601
+ {renderSwiper()}
602
+ </GestureDetector>);
603
+ }
604
+ });
605
+ SwiperWrapper.displayName = 'MpxSwiperWrapper';
606
+ export default SwiperWrapper;
@@ -5,13 +5,13 @@
5
5
  * ✔ color
6
6
  */
7
7
  import { Switch } from 'react-native';
8
- import { useRef, useEffect, forwardRef, useState, useContext } from 'react';
8
+ import { useRef, useEffect, forwardRef, useState, useContext, createElement } from 'react';
9
9
  import { warn } from '@mpxjs/utils';
10
10
  import useNodesRef from './useNodesRef'; // 引入辅助函数
11
11
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
12
12
  import CheckBox from './mpx-checkbox';
13
13
  import { FormContext } from './context';
14
- import { useTransformStyle, useLayout } from './utils';
14
+ import { useTransformStyle, useLayout, extendObject } from './utils';
15
15
  const _Switch = forwardRef((props, ref) => {
16
16
  const { style = {}, checked = false, type = 'switch', disabled = false, color = '#04BE02', 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, bindchange, catchchange } = props;
17
17
  const [isChecked, setIsChecked] = useState(checked);
@@ -32,7 +32,9 @@ const _Switch = forwardRef((props, ref) => {
32
32
  setIsChecked(checked);
33
33
  }, [checked]);
34
34
  const nodeRef = useRef(null);
35
- useNodesRef(props, ref, nodeRef);
35
+ useNodesRef(props, ref, nodeRef, {
36
+ style: normalStyle
37
+ });
36
38
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
37
39
  const onChange = (evt, { checked } = {}) => {
38
40
  if (type === 'switch') {
@@ -65,12 +67,10 @@ const _Switch = forwardRef((props, ref) => {
65
67
  }
66
68
  };
67
69
  }, []);
68
- const innerProps = useInnerProps(props, {
70
+ const innerProps = useInnerProps(props, extendObject({
69
71
  ref: nodeRef,
70
- style: { ...normalStyle, ...layoutStyle },
71
- ...layoutProps,
72
- ...!disabled ? { [type === 'switch' ? 'onValueChange' : '_onChange']: onChange } : {}
73
- }, [
72
+ style: extendObject({}, normalStyle, layoutStyle)
73
+ }, layoutProps, !disabled ? { [type === 'switch' ? 'onValueChange' : '_onChange']: onChange } : {}), [
74
74
  'checked',
75
75
  'disabled',
76
76
  'type',
@@ -79,9 +79,19 @@ const _Switch = forwardRef((props, ref) => {
79
79
  layoutRef
80
80
  });
81
81
  if (type === 'checkbox') {
82
- return <CheckBox {...innerProps} color={color} style={normalStyle} checked={isChecked}/>;
82
+ return createElement(CheckBox, extendObject({}, innerProps, {
83
+ color: color,
84
+ style: normalStyle,
85
+ checked: isChecked
86
+ }));
83
87
  }
84
- return <Switch {...innerProps} style={normalStyle} value={isChecked} trackColor={{ false: '#FFF', true: color }} thumbColor={isChecked ? '#FFF' : '#f4f3f4'} ios_backgroundColor="#FFF"/>;
88
+ return createElement(Switch, extendObject({}, innerProps, {
89
+ style: normalStyle,
90
+ value: isChecked,
91
+ trackColor: { false: '#FFF', true: color },
92
+ thumbColor: isChecked ? '#FFF' : '#f4f3f4',
93
+ ios_backgroundColor: '#FFF'
94
+ }));
85
95
  });
86
96
  _Switch.displayName = 'MpxSwitch';
87
97
  export default _Switch;