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