@mpxjs/webpack-plugin 2.9.59 → 2.9.62
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.
- package/lib/platform/style/wx/index.js +314 -254
- package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
- package/lib/platform/template/wx/component-config/checkbox.js +8 -0
- package/lib/platform/template/wx/component-config/cover-image.js +15 -0
- package/lib/platform/template/wx/component-config/cover-view.js +9 -0
- package/lib/platform/template/wx/component-config/form.js +13 -1
- package/lib/platform/template/wx/component-config/icon.js +8 -0
- package/lib/platform/template/wx/component-config/index.js +5 -1
- package/lib/platform/template/wx/component-config/label.js +15 -0
- package/lib/platform/template/wx/component-config/movable-area.js +18 -1
- package/lib/platform/template/wx/component-config/movable-view.js +18 -1
- package/lib/platform/template/wx/component-config/navigator.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view.js +18 -2
- package/lib/platform/template/wx/component-config/picker.js +14 -1
- package/lib/platform/template/wx/component-config/radio-group.js +8 -0
- package/lib/platform/template/wx/component-config/radio.js +8 -0
- package/lib/platform/template/wx/component-config/root-portal.js +15 -0
- package/lib/platform/template/wx/component-config/switch.js +8 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -3
- package/lib/react/processScript.js +2 -0
- package/lib/runtime/components/react/context.ts +38 -0
- package/lib/runtime/components/react/dist/context.js +7 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +22 -11
- package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
- package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
- package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
- package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
- package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
- package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
- package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
- package/lib/runtime/components/react/dist/types/common.js +1 -0
- package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
- package/lib/runtime/components/react/dist/utils.js +82 -14
- package/lib/runtime/components/react/getInnerListeners.ts +25 -13
- package/lib/runtime/components/react/mpx-button.tsx +87 -67
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
- package/lib/runtime/components/react/mpx-form.tsx +89 -0
- package/lib/runtime/components/react/mpx-icon.tsx +103 -0
- package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
- package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
- package/lib/runtime/components/react/mpx-input.tsx +54 -26
- package/lib/runtime/components/react/mpx-label.tsx +115 -0
- package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
- package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
- package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
- package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
- package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
- package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
- package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
- package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
- package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
- package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
- package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-radio.tsx +246 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
- package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
- package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
- package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
- package/lib/runtime/components/react/mpx-switch.tsx +127 -0
- package/lib/runtime/components/react/mpx-text.tsx +52 -68
- package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
- package/lib/runtime/components/react/mpx-view.tsx +373 -140
- package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
- package/lib/runtime/components/react/types/common.ts +12 -0
- package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
- package/lib/runtime/components/react/types/global.d.ts +4 -0
- package/lib/runtime/components/react/useNodesRef.ts +3 -8
- package/lib/runtime/components/react/utils.ts +93 -15
- package/lib/runtime/optionProcessor.js +19 -17
- package/lib/template-compiler/compiler.js +56 -41
- package/lib/template-compiler/gen-node-react.js +7 -7
- package/package.json +6 -3
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* swiper 实现
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { Animated, View, Dimensions, Platform } from 'react-native';
|
|
5
|
+
import { forwardRef, useState, useRef, useEffect } from 'react';
|
|
6
6
|
import { getCustomEvent } from '../getInnerListeners';
|
|
7
7
|
import useNodesRef from '../useNodesRef'; // 引入辅助函数
|
|
8
8
|
/**
|
|
9
9
|
* 默认的Style类型
|
|
10
10
|
*/
|
|
11
11
|
const styles = {
|
|
12
|
+
slide: {
|
|
13
|
+
backgroundColor: 'transparent'
|
|
14
|
+
},
|
|
12
15
|
container_x: {
|
|
13
16
|
position: 'relative',
|
|
14
17
|
},
|
|
@@ -39,19 +42,27 @@ const styles = {
|
|
|
39
42
|
const _Carouse = forwardRef((props, ref) => {
|
|
40
43
|
// 默认取水平方向的width
|
|
41
44
|
const { width } = Dimensions.get('window');
|
|
42
|
-
const
|
|
45
|
+
const { styleObj } = props;
|
|
46
|
+
const newChild = Array.isArray(props.children) ? props.children.filter(child => child) : props.children;
|
|
47
|
+
const totalElements = Array.isArray(newChild) ? newChild.length : (newChild ? 1 : 0);
|
|
48
|
+
// const defaultHeight = (styleObj?.height || 150) - previousMargin - nextMargin
|
|
49
|
+
// const defaultWidth = (styleObj?.width || width || 375) - previousMargin - nextMargin
|
|
50
|
+
const defaultHeight = (styleObj?.height || 150);
|
|
51
|
+
const defaultWidth = (styleObj?.width || width || 375);
|
|
43
52
|
const dir = props.horizontal === false ? 'y' : 'x';
|
|
44
53
|
// state的offset默认值
|
|
45
|
-
const
|
|
46
|
-
|
|
54
|
+
// const initIndex = props.circular ? props.current + 1: (props.current || 0)
|
|
55
|
+
// 记录真正的下标索引, 不包括循环前后加入的索引, 游标
|
|
56
|
+
const initIndex = props.current || 0;
|
|
57
|
+
// 这里要排除超过元素个数的设置
|
|
58
|
+
const initOffsetIndex = initIndex + (props.circular && totalElements > 1 ? 1 : 0);
|
|
59
|
+
// const defaultX = (defaultWidth * initOffsetIndex + previousMargin) || 0
|
|
60
|
+
// const defaultY = (defaultHeight * initOffsetIndex + previousMargin) || 0
|
|
61
|
+
const defaultX = (defaultWidth * initOffsetIndex) || 0;
|
|
62
|
+
const defaultY = (defaultHeight * initOffsetIndex) || 0;
|
|
47
63
|
// 内部存储上一次的offset值
|
|
48
|
-
const newChild = Array.isArray(props.children) ? props.children.filter(child => child) : props.children;
|
|
49
|
-
// 默认设置为初次渲染
|
|
50
|
-
const initRenderRef = useRef(true);
|
|
51
64
|
const autoplayTimerRef = useRef(null);
|
|
52
|
-
let loopJumpTimerRef = useRef(null);
|
|
53
65
|
const { nodeRef: scrollViewRef } = useNodesRef(props, ref, {});
|
|
54
|
-
const autoplayEndRef = useRef(false);
|
|
55
66
|
// 存储layout布局信息
|
|
56
67
|
const layoutRef = useRef({});
|
|
57
68
|
// 内部存储上一次的偏移量
|
|
@@ -62,123 +73,173 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
62
73
|
},
|
|
63
74
|
isScrolling: false
|
|
64
75
|
});
|
|
76
|
+
const isDragRef = useRef(false);
|
|
65
77
|
const [state, setState] = useState({
|
|
66
78
|
children: newChild,
|
|
67
|
-
width:
|
|
79
|
+
width: defaultWidth || 375,
|
|
68
80
|
height: defaultHeight,
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
// 真正的游标索引, 从0开始
|
|
82
|
+
index: initIndex,
|
|
83
|
+
total: totalElements,
|
|
71
84
|
offset: {
|
|
72
85
|
x: dir === 'x' ? defaultX : 0,
|
|
73
86
|
y: dir === 'y' ? defaultY : 0
|
|
74
87
|
},
|
|
75
|
-
loopJump: false,
|
|
76
88
|
dir
|
|
77
89
|
});
|
|
90
|
+
/**
|
|
91
|
+
* @desc: 开启下一次自动轮播
|
|
92
|
+
*/
|
|
93
|
+
function createAutoPlay() {
|
|
94
|
+
autoplayTimerRef.current && clearTimeout(autoplayTimerRef.current);
|
|
95
|
+
autoplayTimerRef.current = setTimeout(() => {
|
|
96
|
+
startAutoPlay();
|
|
97
|
+
}, props.interval || 500);
|
|
98
|
+
}
|
|
78
99
|
useEffect(() => {
|
|
79
100
|
// 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
|
|
80
101
|
if (props.autoplay) {
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
startSwiperLoop();
|
|
102
|
+
createAutoPlay();
|
|
85
103
|
}
|
|
86
|
-
}, [props.autoplay, props.current, state.index]);
|
|
104
|
+
}, [props.autoplay, props.current, state.index, state.width, state.height]);
|
|
87
105
|
/**
|
|
88
|
-
*
|
|
106
|
+
* @desc: 更新状态: index和offset, 并响应索引变化的事件
|
|
107
|
+
* scrollViewOffset: 移动到的目标位置
|
|
89
108
|
*/
|
|
90
|
-
function updateIndex(scrollViewOffset) {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
return;
|
|
94
|
-
const step = dir === 'x' ? state.width : state.height;
|
|
95
|
-
let loopJump = false;
|
|
96
|
-
let newIndex = state.index + Math.round(diff / step);
|
|
97
|
-
// 若是循环circular
|
|
98
|
-
// 1. 当前索引-1, 初始化为最后一个索引, 且scrollView的偏移量设置为 每个元素的步长 * 一共多少个元素, 这里为什么不减一呢
|
|
99
|
-
// 2. 当前索引>total, 初始化为第一个元素,且scrollView的偏移量设置为一个元素的步长
|
|
100
|
-
if (props.circular) {
|
|
101
|
-
if (state.index <= -1) {
|
|
102
|
-
newIndex = state.total - 1;
|
|
103
|
-
scrollViewOffset[state.dir] = step * state.total;
|
|
104
|
-
loopJump = true;
|
|
105
|
-
}
|
|
106
|
-
else if (newIndex >= state.total) {
|
|
107
|
-
newIndex = 0;
|
|
108
|
-
scrollViewOffset[state.dir] = step;
|
|
109
|
-
loopJump = true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
// 存储当前的偏移量
|
|
113
|
-
internalsRef.current.offset = scrollViewOffset;
|
|
114
|
-
// 这里需不需要区分是否loop,初始化????
|
|
109
|
+
function updateIndex(scrollViewOffset, useIndex = false) {
|
|
110
|
+
const { nextIndex, nextOffset } = getNextConfig(scrollViewOffset);
|
|
111
|
+
internalsRef.current.offset = nextOffset;
|
|
115
112
|
setState((preState) => {
|
|
116
113
|
const newState = {
|
|
117
114
|
...preState,
|
|
118
|
-
index:
|
|
119
|
-
offset
|
|
120
|
-
|
|
115
|
+
index: nextIndex,
|
|
116
|
+
// offset用来指示当前scrollView的偏移量
|
|
117
|
+
offset: nextOffset,
|
|
121
118
|
};
|
|
122
119
|
return newState;
|
|
123
120
|
});
|
|
124
121
|
internalsRef.current.isScrolling = false;
|
|
125
122
|
// getCustomEvent
|
|
126
|
-
const eventData = getCustomEvent('change', {}, { detail: { current:
|
|
123
|
+
const eventData = getCustomEvent('change', {}, { detail: { current: nextIndex, source: 'touch' }, layoutRef: layoutRef });
|
|
127
124
|
props.bindchange && props.bindchange(eventData);
|
|
128
125
|
// 更新完状态之后, 开启新的loop
|
|
129
126
|
}
|
|
130
127
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* 若是circular, 到第一个再往前索引会更新为total-1, 但是视觉是展示的最后一个
|
|
128
|
+
* @desc: 获取下一个位置的索引、scrollView的contentOffset、scrollTo到的offset
|
|
129
|
+
* @desc: 包括正循环、反向循环、不循环
|
|
130
|
+
* 其中循环模式为了实现无缝链接, 会将结合contentOffset, 和 scrollTo的offset, 先scrollTo一个位置的坐标, 然后通过updateIndex设置真正的index和内容的offset,视觉上是无缝
|
|
135
131
|
*/
|
|
136
|
-
function
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
function getNextConfig(scrollViewOffset) {
|
|
133
|
+
const step = state.dir === 'x' ? state.width : state.height;
|
|
134
|
+
let currentOffset = state.offset;
|
|
135
|
+
let nextIndex = state.index + 1;
|
|
136
|
+
let nextOffset = currentOffset;
|
|
137
|
+
// autoMoveOffset scrollView 滚动到前后增加的位置
|
|
138
|
+
let autoMoveOffset = currentOffset;
|
|
139
|
+
let isBack = false;
|
|
140
|
+
let isAutoEnd = false;
|
|
141
|
+
// 如果是循环反向的
|
|
142
|
+
if (scrollViewOffset?.[state.dir] < currentOffset[state.dir]) {
|
|
143
|
+
isBack = true;
|
|
144
|
+
nextIndex = isBack ? nextIndex - 2 : nextIndex;
|
|
145
|
+
}
|
|
146
|
+
if (!props.circular) {
|
|
147
|
+
// nextIndex = isBack ? nextIndex - 2 : nextIndex
|
|
148
|
+
nextOffset = Object.assign({}, currentOffset, { [state.dir]: step * nextIndex });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
if (isBack) {
|
|
152
|
+
if (nextIndex < 0) {
|
|
153
|
+
// 反向: scollView 滚动到虚拟的位置
|
|
154
|
+
autoMoveOffset = Object.assign({}, currentOffset, { [state.dir]: 0 });
|
|
155
|
+
nextIndex = state.total - 1;
|
|
156
|
+
// 反向: 数组最后一个index
|
|
157
|
+
nextOffset = Object.assign({}, currentOffset, { [state.dir]: step * state.total }),
|
|
158
|
+
isAutoEnd = true;
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// 反向非最后一个
|
|
162
|
+
nextOffset = Object.assign({}, currentOffset, { [state.dir]: (nextIndex + 1) * step });
|
|
163
|
+
}
|
|
141
164
|
}
|
|
142
|
-
|
|
143
|
-
|
|
165
|
+
else {
|
|
166
|
+
if (nextIndex > state.total - 1) {
|
|
167
|
+
autoMoveOffset = Object.assign({}, currentOffset, { [state.dir]: step * (nextIndex + 1) });
|
|
168
|
+
nextIndex = 0;
|
|
169
|
+
nextOffset = Object.assign({}, currentOffset, { [state.dir]: step }),
|
|
170
|
+
isAutoEnd = true;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// nextIndex = nextIndex,
|
|
174
|
+
nextOffset = Object.assign({}, currentOffset, { [state.dir]: (nextIndex + 1) * step });
|
|
175
|
+
}
|
|
144
176
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
nextIndex,
|
|
180
|
+
nextOffset,
|
|
181
|
+
autoMoveOffset,
|
|
182
|
+
isAutoEnd
|
|
183
|
+
};
|
|
148
184
|
}
|
|
149
185
|
/**
|
|
150
|
-
* 开启自动轮播
|
|
151
|
-
* 每间隔interval scrollView的offset更改到下一个位置,通过onScrollEnd来获取contentOffset再计算要更新的索引index
|
|
186
|
+
* @desc: 开启自动轮播
|
|
152
187
|
*/
|
|
153
188
|
function startAutoPlay() {
|
|
154
|
-
|
|
155
|
-
|
|
189
|
+
if (state.width && isNaN(+state.width)) {
|
|
190
|
+
createAutoPlay();
|
|
156
191
|
return;
|
|
157
192
|
}
|
|
158
|
-
|
|
159
|
-
// 非循环自动播放的形式下 到最后一帧 结束自动播放
|
|
160
|
-
if (!props.circular && state.index === state.total - 1) {
|
|
161
|
-
autoplayEndRef.current = true;
|
|
193
|
+
if (!Array.isArray(state.children)) {
|
|
162
194
|
return;
|
|
163
195
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
196
|
+
const step = state.dir === 'x' ? state.width : state.height;
|
|
197
|
+
const { nextOffset, autoMoveOffset, isAutoEnd } = getNextConfig(state.offset);
|
|
198
|
+
// 这里可以scroll到下一个元素, 但是把scrollView的偏移量在设置为content,视觉效果就没了吧
|
|
199
|
+
// scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: true })
|
|
200
|
+
if (Platform.OS === 'ios') {
|
|
201
|
+
if (!isAutoEnd) {
|
|
202
|
+
scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: true });
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
if (state.dir === 'x') {
|
|
206
|
+
scrollViewRef.current?.scrollTo({ x: autoMoveOffset['x'], y: autoMoveOffset['x'], animated: true });
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
scrollViewRef.current?.scrollTo({ x: autoMoveOffset['y'], y: autoMoveOffset['y'], animated: true });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
if (!isAutoEnd) {
|
|
215
|
+
scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: true });
|
|
216
|
+
onScrollEnd({
|
|
217
|
+
nativeEvent: {
|
|
218
|
+
// @ts-ignore
|
|
219
|
+
x: +nextOffset['x'],
|
|
220
|
+
y: +nextOffset['y']
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
setTimeout(() => {
|
|
226
|
+
onScrollEnd({
|
|
227
|
+
nativeEvent: {
|
|
228
|
+
// @ts-ignore
|
|
229
|
+
x: 0,
|
|
230
|
+
y: 0
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}, 10);
|
|
234
|
+
if (state.dir === 'x') {
|
|
235
|
+
scrollViewRef.current?.scrollTo({ x: step, y: step, animated: true });
|
|
236
|
+
// scrollViewRef.current?.scrollTo({ x: autoMoveOffset['x'], y: autoMoveOffset['x'], animated: true })
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
scrollViewRef.current?.scrollTo({ x: autoMoveOffset['y'], y: autoMoveOffset['y'], animated: true });
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
182
243
|
}
|
|
183
244
|
/**
|
|
184
245
|
* 当用户开始拖动此视图时调用此函数, 更新当前在滚动态
|
|
@@ -186,10 +247,17 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
186
247
|
function onScrollBegin() {
|
|
187
248
|
internalsRef.current.isScrolling = true;
|
|
188
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* 当用户开始拖动结束
|
|
252
|
+
*/
|
|
189
253
|
function onScrollEnd(event) {
|
|
254
|
+
// 这里安卓好像没有触发onScrollEnd, 调用scrollTo的时候
|
|
255
|
+
if (totalElements === 1) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
190
258
|
internalsRef.current.isScrolling = false;
|
|
191
259
|
// 用户手动滑动更新索引后,如果开启了自动轮播等重新开始
|
|
192
|
-
updateIndex(event.nativeEvent.contentOffset);
|
|
260
|
+
updateIndex(event.nativeEvent.contentOffset, true);
|
|
193
261
|
}
|
|
194
262
|
/**
|
|
195
263
|
* 当拖拽结束时,检测是否可滚动
|
|
@@ -197,57 +265,58 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
197
265
|
function onScrollEndDrag(event) {
|
|
198
266
|
const { contentOffset } = event.nativeEvent;
|
|
199
267
|
const { index, total } = state;
|
|
268
|
+
isDragRef.current = true;
|
|
200
269
|
const internalOffset = internalsRef.current.offset;
|
|
201
270
|
const previousOffset = props.horizontal ? internalOffset.x : internalOffset.y;
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (!initRenderRef.current || state.dir === 'x')
|
|
212
|
-
return;
|
|
213
|
-
const { width, height } = event.nativeEvent.layout;
|
|
214
|
-
if (state.total > 1) {
|
|
215
|
-
internalsRef.current.offset[state.dir] = (state.dir === 'y' ? height * state.index : state.width * state.index);
|
|
216
|
-
}
|
|
217
|
-
if (!state.offset.x && !state.offset.y) {
|
|
218
|
-
state.offset = internalsRef.current.offset;
|
|
271
|
+
const moveOffset = props.horizontal ? contentOffset.x : contentOffset.y;
|
|
272
|
+
// const diff = moveOffset - previousOffset
|
|
273
|
+
/*
|
|
274
|
+
if (diff > 0 && state.index + 1 >= total) {
|
|
275
|
+
const { nextOffset } = getNextConfig(contentOffset)
|
|
276
|
+
// scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: false })
|
|
277
|
+
} else if ( diff < 0 && state.index -1 < 0) {
|
|
278
|
+
const { nextOffset } = getNextConfig(contentOffset)
|
|
279
|
+
// scrollViewRef.current?.scrollTo({ x: nextOffset['x'], y: nextOffset['y'], animated: false })
|
|
219
280
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
281
|
+
*/
|
|
282
|
+
if (previousOffset === moveOffset && (index === 0 || index === total - 1)) {
|
|
283
|
+
internalsRef.current.isScrolling = false;
|
|
223
284
|
}
|
|
224
|
-
setState((preState) => {
|
|
225
|
-
return {
|
|
226
|
-
...preState,
|
|
227
|
-
height
|
|
228
|
-
};
|
|
229
|
-
});
|
|
230
285
|
}
|
|
231
286
|
/**
|
|
232
|
-
*
|
|
287
|
+
* @desc: 水平方向时,获取元素的布局,更新, 其中如果传递100%时需要依赖measure计算元算的宽高
|
|
233
288
|
*/
|
|
234
289
|
function onWrapperLayout() {
|
|
235
290
|
if (props.enableOffset) {
|
|
236
291
|
// @ts-ignore
|
|
237
292
|
scrollViewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
|
|
238
293
|
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
|
|
294
|
+
const isWDiff = state.width !== width;
|
|
295
|
+
const isHDiff = state.height !== height;
|
|
296
|
+
if (isWDiff || isHDiff) {
|
|
297
|
+
const changeState = {
|
|
298
|
+
width: isWDiff ? width : state.width,
|
|
299
|
+
height: isHDiff ? height : state.height
|
|
300
|
+
};
|
|
301
|
+
let correctOffset = Object.assign({}, state.offset, {
|
|
302
|
+
[state.dir]: initOffsetIndex * (state.dir === 'x' ? changeState.width : changeState.height)
|
|
303
|
+
});
|
|
304
|
+
state.offset = correctOffset;
|
|
305
|
+
state.width = width;
|
|
306
|
+
state.height = height;
|
|
307
|
+
setState((preState) => {
|
|
308
|
+
return {
|
|
309
|
+
...preState,
|
|
310
|
+
offset: correctOffset,
|
|
311
|
+
width: changeState.width,
|
|
312
|
+
height: changeState.height
|
|
313
|
+
};
|
|
314
|
+
});
|
|
315
|
+
scrollViewRef.current?.scrollTo({ x: correctOffset['x'], y: correctOffset['y'], animated: false });
|
|
316
|
+
}
|
|
239
317
|
props.getInnerLayout && props.getInnerLayout(layoutRef);
|
|
240
318
|
});
|
|
241
319
|
}
|
|
242
|
-
if (state.dir === 'y')
|
|
243
|
-
return;
|
|
244
|
-
if (!state.offset.x && !state.offset.y) {
|
|
245
|
-
state.offset = internalsRef.current.offset;
|
|
246
|
-
}
|
|
247
|
-
if (!initRenderRef.current && state.total > 1) {
|
|
248
|
-
scrollViewRef.current?.scrollTo({ ...state.offset, animated: false });
|
|
249
|
-
initRenderRef.current = false;
|
|
250
|
-
}
|
|
251
320
|
}
|
|
252
321
|
function renderScrollView(pages) {
|
|
253
322
|
let scrollElementProps = {
|
|
@@ -261,9 +330,10 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
261
330
|
removeClippedSubviews: true,
|
|
262
331
|
automaticallyAdjustContentInsets: false
|
|
263
332
|
};
|
|
264
|
-
|
|
333
|
+
const layoutStyle = dir === 'x' ? { width: defaultWidth, height: defaultHeight } : { width: defaultWidth };
|
|
334
|
+
return (<Animated.ScrollView {...scrollElementProps} style={[layoutStyle]} overScrollMode="always" contentOffset={state.offset} onScrollBeginDrag={onScrollBegin} onMomentumScrollEnd={onScrollEnd} onScrollEndDrag={onScrollEndDrag}>
|
|
265
335
|
{pages}
|
|
266
|
-
</ScrollView>);
|
|
336
|
+
</Animated.ScrollView>);
|
|
267
337
|
}
|
|
268
338
|
function renderPagination() {
|
|
269
339
|
if (state.total <= 1)
|
|
@@ -303,7 +373,7 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
303
373
|
}
|
|
304
374
|
function renderPages() {
|
|
305
375
|
const { width, height, total, children } = state;
|
|
306
|
-
const { circular
|
|
376
|
+
const { circular } = props;
|
|
307
377
|
const pageStyle = { width: width, height: height };
|
|
308
378
|
if (total > 1 && Array.isArray(children)) {
|
|
309
379
|
let arrElements = [];
|
|
@@ -315,17 +385,7 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
315
385
|
pages.push('0');
|
|
316
386
|
}
|
|
317
387
|
arrElements = pages.map((page, i) => {
|
|
318
|
-
|
|
319
|
-
const extraStyle = {};
|
|
320
|
-
if (previousMargin) {
|
|
321
|
-
extraStyle.left = +previousMargin;
|
|
322
|
-
}
|
|
323
|
-
if (nextMargin && state.index === i - 1) {
|
|
324
|
-
const half = Math.floor(+nextMargin / 2);
|
|
325
|
-
extraStyle.marginLeft = -half;
|
|
326
|
-
extraStyle.paddingLeft = half;
|
|
327
|
-
}
|
|
328
|
-
return (<View style={[pageStyle2, extraStyle]} key={'page' + i} onLayout={onItemLayout}>
|
|
388
|
+
return (<View style={[pageStyle, styles.slide]} key={'page' + i}>
|
|
329
389
|
{children[+page]}
|
|
330
390
|
</View>);
|
|
331
391
|
});
|
|
@@ -337,17 +397,16 @@ const _Carouse = forwardRef((props, ref) => {
|
|
|
337
397
|
</View>);
|
|
338
398
|
}
|
|
339
399
|
}
|
|
340
|
-
const vStyle = {};
|
|
341
|
-
if (dir === 'y') {
|
|
342
|
-
vStyle.height = defaultHeight;
|
|
343
|
-
}
|
|
344
400
|
const pages = renderPages();
|
|
345
401
|
const strStyle = 'container_' + state.dir;
|
|
346
402
|
const eventProps = props.innerProps || {};
|
|
347
|
-
|
|
403
|
+
const layoutStyle = dir === 'x' ? { width: defaultWidth, height: defaultHeight } : { width: defaultWidth };
|
|
404
|
+
return (<View style={[layoutStyle]}>
|
|
405
|
+
<View style={[styles[strStyle], layoutStyle]} {...eventProps} onLayout={onWrapperLayout}>
|
|
348
406
|
{renderScrollView(pages)}
|
|
349
|
-
|
|
350
|
-
</View>
|
|
407
|
+
</View>
|
|
408
|
+
<View>{props.showsPagination && renderPagination()}</View>
|
|
409
|
+
</View>);
|
|
351
410
|
});
|
|
352
411
|
_Carouse.displayName = '_Carouse';
|
|
353
412
|
export default _Carouse;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { forwardRef, useRef } from 'react';
|
|
2
2
|
import { default as Carouse } from './carouse';
|
|
3
3
|
import useInnerProps from '../getInnerListeners';
|
|
4
4
|
import useNodesRef from '../useNodesRef'; // 引入辅助函数
|
|
@@ -13,8 +13,9 @@ import useNodesRef from '../useNodesRef'; // 引入辅助函数
|
|
|
13
13
|
* ✔ circular
|
|
14
14
|
* ✔ vertical
|
|
15
15
|
* ✘ display-multiple-items
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* ✘ previous-margin
|
|
17
|
+
* ✘ next-margin
|
|
18
|
+
* ✔ easing-function ="easeOutCubic"
|
|
18
19
|
* ✘ snap-to-edge
|
|
19
20
|
*/
|
|
20
21
|
const _SwiperWrapper = forwardRef((props, ref) => {
|
|
@@ -30,11 +31,12 @@ const _SwiperWrapper = forwardRef((props, ref) => {
|
|
|
30
31
|
dotColor: props['indicator-color'] || "rgba(0, 0, 0, .3)",
|
|
31
32
|
activeDotColor: props['indicator-active-color'] || '#000000',
|
|
32
33
|
horizontal: props.vertical !== undefined ? !props.vertical : true,
|
|
33
|
-
|
|
34
|
+
styleObj: props.style || {},
|
|
34
35
|
previousMargin: props['previous-margin'] ? parseInt(props['previous-margin']) : 0,
|
|
35
36
|
nextMargin: props['next-margin'] ? parseInt(props['next-margin']) : 0,
|
|
36
|
-
enableOffset: props['enable-offset'] ||
|
|
37
|
-
bindchange: props.bindchange
|
|
37
|
+
enableOffset: props['enable-offset'] || true,
|
|
38
|
+
bindchange: props.bindchange,
|
|
39
|
+
easingFunction: props['easing-function'] || 'default'
|
|
38
40
|
};
|
|
39
41
|
const { nodeRef } = useNodesRef(props, ref, {});
|
|
40
42
|
const innerProps = useInnerProps(props, {
|
|
@@ -49,7 +51,7 @@ const _SwiperWrapper = forwardRef((props, ref) => {
|
|
|
49
51
|
const getInnerLayout = (layout) => {
|
|
50
52
|
innerLayout.current = layout.current;
|
|
51
53
|
};
|
|
52
|
-
return <Carouse getInnerLayout={getInnerLayout} innerProps={innerProps} {...swiperProp}
|
|
54
|
+
return <Carouse getInnerLayout={getInnerLayout} innerProps={innerProps} {...swiperProp}>
|
|
53
55
|
{children}
|
|
54
56
|
</Carouse>;
|
|
55
57
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { View } from 'react-native';
|
|
2
|
-
import
|
|
2
|
+
import { forwardRef, useRef } from 'react';
|
|
3
3
|
import useInnerProps from './getInnerListeners';
|
|
4
4
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
5
5
|
const _SwiperItem = forwardRef((props, ref) => {
|
|
6
|
-
const { children, 'enable-offset': enableOffset } = props;
|
|
6
|
+
const { children, 'enable-offset': enableOffset, style } = props;
|
|
7
7
|
const layoutRef = useRef({});
|
|
8
8
|
const { nodeRef } = useNodesRef(props, ref, {});
|
|
9
9
|
const onLayout = () => {
|
|
@@ -17,7 +17,7 @@ const _SwiperItem = forwardRef((props, ref) => {
|
|
|
17
17
|
'children',
|
|
18
18
|
'enable-offset'
|
|
19
19
|
], { layoutRef });
|
|
20
|
-
return (<View ref={nodeRef} data-itemId={props['item-id']} {...innerProps}>
|
|
20
|
+
return (<View ref={nodeRef} data-itemId={props['item-id']} style={[style]} {...innerProps}>
|
|
21
21
|
{children}
|
|
22
22
|
</View>);
|
|
23
23
|
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ✔ checked
|
|
3
|
+
* ✔ type
|
|
4
|
+
* ✔ disabled
|
|
5
|
+
* ✔ color
|
|
6
|
+
*/
|
|
7
|
+
import { Switch } from 'react-native';
|
|
8
|
+
import { useRef, useEffect, forwardRef, useState, useContext } from 'react';
|
|
9
|
+
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
10
|
+
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
11
|
+
import CheckBox from './mpx-checkbox';
|
|
12
|
+
import { FormContext } from './context';
|
|
13
|
+
import { throwReactWarning } from './utils';
|
|
14
|
+
const _Switch = forwardRef((props, ref) => {
|
|
15
|
+
const { style = {}, checked = false, type = 'switch', disabled = false, color = '#04BE02', 'enable-offset': enableOffset, bindchange, catchchange, } = props;
|
|
16
|
+
const [isChecked, setIsChecked] = useState(checked);
|
|
17
|
+
const layoutRef = useRef({});
|
|
18
|
+
const changeHandler = bindchange || catchchange;
|
|
19
|
+
let formValuesMap;
|
|
20
|
+
const formContext = useContext(FormContext);
|
|
21
|
+
if (formContext) {
|
|
22
|
+
formValuesMap = formContext.formValuesMap;
|
|
23
|
+
}
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
setIsChecked(checked);
|
|
26
|
+
}, [checked]);
|
|
27
|
+
const { nodeRef } = useNodesRef(props, ref);
|
|
28
|
+
const onChange = (evt, { checked } = {}) => {
|
|
29
|
+
if (type === 'switch') {
|
|
30
|
+
setIsChecked(evt);
|
|
31
|
+
changeHandler && changeHandler(getCustomEvent('change', {}, { layoutRef, detail: { value: evt } }, props));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
setIsChecked(checked);
|
|
35
|
+
changeHandler && changeHandler(getCustomEvent('change', evt, { layoutRef, detail: { value: checked } }, props));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const resetValue = () => {
|
|
39
|
+
setIsChecked(false);
|
|
40
|
+
};
|
|
41
|
+
const getValue = () => {
|
|
42
|
+
return isChecked;
|
|
43
|
+
};
|
|
44
|
+
if (formValuesMap) {
|
|
45
|
+
if (!props.name) {
|
|
46
|
+
throwReactWarning('[Mpx runtime warn]: If a form component is used, the name attribute is required.');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
formValuesMap.set(props.name, { getValue, resetValue });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const onLayout = () => {
|
|
53
|
+
nodeRef.current?.measure?.((x, y, width, height, offsetLeft, offsetTop) => {
|
|
54
|
+
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
const innerProps = useInnerProps(props, {
|
|
58
|
+
ref: nodeRef,
|
|
59
|
+
...enableOffset ? { onLayout } : {},
|
|
60
|
+
...!disabled ? { [type === 'switch' ? 'onValueChange' : '_onChange']: onChange } : {}
|
|
61
|
+
}, [
|
|
62
|
+
'style',
|
|
63
|
+
'checked',
|
|
64
|
+
'disabled',
|
|
65
|
+
'type',
|
|
66
|
+
'color'
|
|
67
|
+
], {
|
|
68
|
+
layoutRef
|
|
69
|
+
});
|
|
70
|
+
if (type === 'checkbox') {
|
|
71
|
+
return <CheckBox {...innerProps} color={color} style={style} checked={isChecked}/>;
|
|
72
|
+
}
|
|
73
|
+
return (<Switch {...innerProps} style={style} value={isChecked} trackColor={{ false: "#FFF", true: color }} thumbColor={isChecked ? "#FFF" : "#f4f3f4"} ios_backgroundColor="#FFF"/>);
|
|
74
|
+
});
|
|
75
|
+
_Switch.displayName = 'mpx-switch';
|
|
76
|
+
export default _Switch;
|