@mpxjs/webpack-plugin 2.9.55 → 2.9.57

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 (31) hide show
  1. package/lib/index.js +2 -0
  2. package/lib/json-compiler/index.js +2 -1
  3. package/lib/platform/json/wx/index.js +0 -1
  4. package/lib/runtime/base.styl +27 -0
  5. package/lib/runtime/components/react/dist/event.config.js +27 -0
  6. package/lib/runtime/components/react/dist/getInnerListeners.js +230 -0
  7. package/lib/runtime/components/react/dist/mpx-button.jsx +270 -0
  8. package/lib/runtime/components/react/dist/mpx-image/index.jsx +229 -0
  9. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +6 -0
  10. package/lib/runtime/components/react/dist/mpx-input.jsx +203 -0
  11. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +294 -0
  12. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +353 -0
  13. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +57 -0
  14. package/lib/runtime/components/react/dist/mpx-swiper/type.js +1 -0
  15. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +25 -0
  16. package/lib/runtime/components/react/dist/mpx-text.jsx +67 -0
  17. package/lib/runtime/components/react/dist/mpx-textarea.jsx +27 -0
  18. package/lib/runtime/components/react/dist/mpx-view.jsx +307 -0
  19. package/lib/runtime/components/react/dist/types/getInnerListeners.js +1 -0
  20. package/lib/runtime/components/react/dist/useNodesRef.js +25 -0
  21. package/lib/runtime/components/react/dist/utils.js +80 -0
  22. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  23. package/lib/runtime/components/react/mpx-button.tsx +1 -2
  24. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -1
  25. package/lib/runtime/components/react/{getInnerListeners.type.ts → types/getInnerListeners.ts} +2 -2
  26. package/lib/runtime/components/react/types/global.d.ts +15 -0
  27. package/lib/runtime/optionProcessor.js +27 -1
  28. package/lib/template-compiler/compiler.js +72 -25
  29. package/lib/template-compiler/index.js +2 -1
  30. package/lib/web/processTemplate.js +1 -1
  31. package/package.json +7 -4
@@ -0,0 +1,294 @@
1
+ /**
2
+ * ✔ scroll-x
3
+ * ✔ scroll-y
4
+ * ✔ upper-threshold
5
+ * ✔ lower-threshold
6
+ * ✔ scroll-top
7
+ * ✔ scroll-left
8
+ * ✘ scroll-into-view
9
+ * ✔ scroll-with-animation
10
+ * ✔ enable-back-to-top
11
+ * ✘ enable-passive
12
+ * ✔ refresher-enabled
13
+ * ✘ refresher-threshold
14
+ * ✔ refresher-default-style(仅 android 支持)
15
+ * ✔ refresher-background(仅 android 支持)
16
+ * ✔ refresher-triggered
17
+ * ✘ enable-flex(scroll-x,rn 默认支持)
18
+ * ✘ scroll-anchoring
19
+ * ✔ paging-enabled
20
+ * ✘ using-sticky
21
+ * ✔ show-scrollbar
22
+ * ✘ fast-deceleration
23
+ * ✔ binddragstart
24
+ * ✔ binddragging
25
+ * ✔ binddragend
26
+ * ✔ bindrefresherrefresh
27
+ * ✘ bindrefresherpulling
28
+ * ✘ bindrefresherrestore
29
+ * ✘ bindrefresherabort
30
+ * ✔ bindscrolltoupper
31
+ * ✔ bindscrolltolower
32
+ * ✔ bindscroll
33
+ */
34
+ import { ScrollView, RefreshControl } from 'react-native';
35
+ import React, { useRef, useState, useEffect, forwardRef } from 'react';
36
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
37
+ import useNodesRef from './useNodesRef';
38
+ const _ScrollView = forwardRef((props = {}, ref) => {
39
+ const { children, enhanced = false, bounces = true, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'paging-enabled': pagingEnabled = false, 'upper-threshold': upperThreshold = 50, 'lower-threshold': lowerThreshold = 50, 'scroll-with-animation': scrollWithAnimation, 'refresher-enabled': refresherEnabled, 'refresher-default-style': refresherDefaultStyle, 'refresher-background': refresherBackground, 'enable-offset': enableOffset, 'show-scrollbar': showScrollbar = true } = props;
40
+ const [snapScrollTop, setSnapScrollTop] = useState(0);
41
+ const [snapScrollLeft, setSnapScrollLeft] = useState(0);
42
+ const [refreshing, setRefreshing] = useState(true);
43
+ const [scrollEnabled, setScrollEnabled] = useState(true);
44
+ const layoutRef = useRef({});
45
+ const scrollOptions = useRef({
46
+ contentLength: 0,
47
+ offset: 0,
48
+ scrollLeft: 0,
49
+ scrollTop: 0,
50
+ visibleLength: 0,
51
+ });
52
+ const scrollEventThrottle = 50;
53
+ const hasCallScrollToUpper = useRef(true);
54
+ const hasCallScrollToLower = useRef(false);
55
+ const initialTimeout = useRef(null);
56
+ const { nodeRef: scrollViewRef } = useNodesRef(props, ref, {
57
+ scrollOffset: scrollOptions,
58
+ node: {
59
+ scrollEnabled,
60
+ bounces,
61
+ showScrollbar,
62
+ pagingEnabled,
63
+ fastDeceleration: false,
64
+ decelerationDisabled: false,
65
+ scrollTo: scrollToOffset
66
+ }
67
+ });
68
+ useEffect(() => {
69
+ if (snapScrollTop !== props['scroll-top'] ||
70
+ snapScrollLeft !== props['scroll-left']) {
71
+ setSnapScrollTop(props['scroll-top'] || 0);
72
+ setSnapScrollLeft(props['scroll-left'] || 0);
73
+ }
74
+ }, [props['scroll-top'], props['scroll-left']]);
75
+ useEffect(() => {
76
+ if (refreshing !== props['refresher-triggered']) {
77
+ setRefreshing(!!props['refresher-triggered']);
78
+ }
79
+ }, [props['refresher-triggered']]);
80
+ useEffect(() => {
81
+ if (!props['scroll-x'] && !props['scroll-y']) {
82
+ setScrollEnabled(false);
83
+ }
84
+ else {
85
+ setScrollEnabled(true);
86
+ }
87
+ }, [props['scroll-x'], props['scroll-y']]);
88
+ useEffect(() => {
89
+ if (snapScrollTop || snapScrollLeft) {
90
+ initialTimeout.current = setTimeout(() => {
91
+ scrollToOffset(snapScrollLeft, snapScrollTop);
92
+ }, 0);
93
+ }
94
+ return () => {
95
+ initialTimeout.current && clearTimeout(initialTimeout.current);
96
+ };
97
+ }, [snapScrollTop, snapScrollLeft]);
98
+ function selectLength(size) {
99
+ return !scrollX ? size.height : size.width;
100
+ }
101
+ function selectOffset(position) {
102
+ return !scrollX ? position.y : position.x;
103
+ }
104
+ function onStartReached(e) {
105
+ const { bindscrolltoupper } = props;
106
+ const { offset } = scrollOptions.current;
107
+ if (bindscrolltoupper && (offset <= upperThreshold)) {
108
+ if (!hasCallScrollToUpper.current) {
109
+ bindscrolltoupper(getCustomEvent('scrolltoupper', e, {
110
+ detail: {
111
+ direction: scrollX ? 'left' : 'top',
112
+ },
113
+ layoutRef
114
+ }, props));
115
+ hasCallScrollToUpper.current = true;
116
+ }
117
+ }
118
+ else {
119
+ hasCallScrollToUpper.current = false;
120
+ }
121
+ }
122
+ function onEndReached(e) {
123
+ const { bindscrolltolower } = props;
124
+ const { contentLength, visibleLength, offset } = scrollOptions.current;
125
+ const distanceFromEnd = contentLength - visibleLength - offset;
126
+ if (bindscrolltolower && (distanceFromEnd < lowerThreshold)) {
127
+ if (!hasCallScrollToLower.current) {
128
+ hasCallScrollToLower.current = true;
129
+ bindscrolltolower(getCustomEvent('scrolltolower', e, {
130
+ detail: {
131
+ direction: scrollX ? 'right' : 'botttom',
132
+ },
133
+ layoutRef
134
+ }, props));
135
+ }
136
+ }
137
+ else {
138
+ hasCallScrollToLower.current = false;
139
+ }
140
+ }
141
+ function onContentSizeChange(width, height) {
142
+ scrollOptions.current.contentLength = selectLength({ height, width });
143
+ }
144
+ function onLayout(e) {
145
+ scrollOptions.current.visibleLength = selectLength(e.nativeEvent.layout);
146
+ if (enableOffset) {
147
+ scrollViewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
148
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
149
+ });
150
+ }
151
+ }
152
+ function onScroll(e) {
153
+ const { bindscroll } = props;
154
+ const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset;
155
+ const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize;
156
+ bindscroll &&
157
+ bindscroll(getCustomEvent('scroll', e, {
158
+ detail: {
159
+ scrollLeft,
160
+ scrollTop,
161
+ scrollHeight,
162
+ scrollWidth,
163
+ deltaX: scrollLeft - scrollOptions.current.scrollLeft,
164
+ deltaY: scrollTop - scrollOptions.current.scrollTop,
165
+ },
166
+ layoutRef
167
+ }, props));
168
+ const visibleLength = selectLength(e.nativeEvent.layoutMeasurement);
169
+ const contentLength = selectLength(e.nativeEvent.contentSize);
170
+ const offset = selectOffset(e.nativeEvent.contentOffset);
171
+ scrollOptions.current = {
172
+ ...scrollOptions.current,
173
+ contentLength,
174
+ offset,
175
+ scrollLeft,
176
+ scrollTop,
177
+ visibleLength,
178
+ };
179
+ onStartReached(e);
180
+ onEndReached(e);
181
+ }
182
+ function scrollToOffset(x = 0, y = 0) {
183
+ if (scrollViewRef.current) {
184
+ scrollViewRef.current.scrollTo({ x, y, animated: !!scrollWithAnimation });
185
+ scrollOptions.current.scrollLeft = x;
186
+ scrollOptions.current.scrollTop = y;
187
+ }
188
+ }
189
+ function onRefresh() {
190
+ const { bindrefresherrefresh } = props;
191
+ bindrefresherrefresh &&
192
+ bindrefresherrefresh(getCustomEvent('refresherrefresh', {}, { layoutRef }, props));
193
+ }
194
+ function onScrollTouchStart(e) {
195
+ const { binddragstart, bindtouchstart, enhanced } = props;
196
+ bindtouchstart && bindtouchstart(e);
197
+ if (enhanced) {
198
+ binddragstart &&
199
+ binddragstart(getCustomEvent('dragstart', e, {
200
+ detail: {
201
+ scrollLeft: scrollOptions.current.scrollLeft || 0,
202
+ scrollTop: scrollOptions.current.scrollTop || 0,
203
+ },
204
+ layoutRef
205
+ }, props));
206
+ }
207
+ }
208
+ function onScrollTouchMove(e) {
209
+ const { binddragging, bindtouchmove, enhanced } = props;
210
+ bindtouchmove && bindtouchmove(e);
211
+ if (enhanced) {
212
+ binddragging &&
213
+ binddragging(getCustomEvent('dragging', e, {
214
+ detail: {
215
+ scrollLeft: scrollOptions.current.scrollLeft || 0,
216
+ scrollTop: scrollOptions.current.scrollTop || 0,
217
+ },
218
+ layoutRef
219
+ }, props));
220
+ }
221
+ }
222
+ function onScrollTouchEnd(e) {
223
+ const { binddragend, bindtouchend, enhanced } = props;
224
+ bindtouchend && bindtouchend(e);
225
+ if (enhanced) {
226
+ binddragend &&
227
+ binddragend(getCustomEvent('dragend', e, {
228
+ detail: {
229
+ scrollLeft: scrollOptions.current.scrollLeft || 0,
230
+ scrollTop: scrollOptions.current.scrollTop || 0,
231
+ },
232
+ layoutRef
233
+ }, props));
234
+ }
235
+ }
236
+ let scrollAdditionalProps = {
237
+ pinchGestureEnabled: false,
238
+ horizontal: scrollX || !scrollY,
239
+ scrollEventThrottle: scrollEventThrottle,
240
+ scrollsToTop: enableBackToTop,
241
+ showsHorizontalScrollIndicator: scrollX && showScrollbar,
242
+ showsVerticalScrollIndicator: scrollY && showScrollbar,
243
+ scrollEnabled: scrollEnabled,
244
+ ref: scrollViewRef,
245
+ onScroll: onScroll,
246
+ onContentSizeChange: onContentSizeChange,
247
+ bindtouchstart: onScrollTouchStart,
248
+ bindtouchend: onScrollTouchEnd,
249
+ bindtouchmove: onScrollTouchMove,
250
+ onLayout
251
+ };
252
+ if (enhanced) {
253
+ scrollAdditionalProps = {
254
+ ...scrollAdditionalProps,
255
+ bounces,
256
+ pagingEnabled,
257
+ };
258
+ }
259
+ const innerProps = useInnerProps(props, scrollAdditionalProps, [
260
+ 'enable-offset',
261
+ 'scroll-x',
262
+ 'scroll-y',
263
+ 'enable-back-to-top',
264
+ 'paging-enabled',
265
+ 'show-scrollbar',
266
+ 'upper-threshold',
267
+ 'lower-threshold',
268
+ 'scroll-top',
269
+ 'scroll-left',
270
+ 'scroll-with-animation',
271
+ 'refresher-triggered',
272
+ 'refresher-enabled',
273
+ 'refresher-default-style',
274
+ 'refresher-background',
275
+ 'children',
276
+ 'enhanced',
277
+ 'binddragstart',
278
+ 'binddragging',
279
+ 'binddragend',
280
+ 'bindscroll',
281
+ 'bindscrolltoupper',
282
+ 'bindscrolltolower',
283
+ 'bindrefresherrefresh'
284
+ ], { layoutRef });
285
+ const refreshColor = {
286
+ 'black': ['#000'],
287
+ 'white': ['#fff']
288
+ };
289
+ return (<ScrollView {...innerProps} refreshControl={refresherEnabled ? (<RefreshControl progressBackgroundColor={refresherBackground} refreshing={refreshing} onRefresh={onRefresh} {...(refresherDefaultStyle && refresherDefaultStyle !== 'none' ? { colors: refreshColor[refresherDefaultStyle] } : {})}/>) : undefined}>
290
+ {children}
291
+ </ScrollView>);
292
+ });
293
+ _ScrollView.displayName = 'mpx-scroll-view';
294
+ export default _ScrollView;
@@ -0,0 +1,353 @@
1
+ /**
2
+ * swiper 实现
3
+ */
4
+ import { View, ScrollView, Dimensions } from 'react-native';
5
+ import React, { forwardRef, useState, useRef, useEffect } from 'react';
6
+ import { getCustomEvent } from '../getInnerListeners';
7
+ import useNodesRef from '../useNodesRef'; // 引入辅助函数
8
+ /**
9
+ * 默认的Style类型
10
+ */
11
+ const styles = {
12
+ container_x: {
13
+ position: 'relative',
14
+ },
15
+ container_y: {
16
+ position: 'relative',
17
+ },
18
+ pagination_x: {
19
+ position: 'absolute',
20
+ bottom: 25,
21
+ left: 0,
22
+ right: 0,
23
+ flexDirection: 'row',
24
+ flex: 1,
25
+ justifyContent: 'center',
26
+ alignItems: 'center',
27
+ },
28
+ pagination_y: {
29
+ position: 'absolute',
30
+ right: 15,
31
+ top: 0,
32
+ bottom: 0,
33
+ flexDirection: 'column',
34
+ flex: 1,
35
+ justifyContent: 'center',
36
+ alignItems: 'center',
37
+ }
38
+ };
39
+ const _Carouse = forwardRef((props, ref) => {
40
+ // 默认取水平方向的width
41
+ const { width } = Dimensions.get('window');
42
+ const defaultHeight = 150;
43
+ const dir = props.horizontal === false ? 'y' : 'x';
44
+ // state的offset默认值
45
+ const defaultX = width * (props.circular ? props.current + 1 : props.current) || 0;
46
+ const defaultY = defaultHeight * (props.circular ? props.current + 1 : props.current) || 0;
47
+ // 内部存储上一次的offset值
48
+ const newChild = Array.isArray(props.children) ? props.children.filter(child => child) : props.children;
49
+ // 默认设置为初次渲染
50
+ const initRenderRef = useRef(true);
51
+ const autoplayTimerRef = useRef(null);
52
+ let loopJumpTimerRef = useRef(null);
53
+ const { nodeRef: scrollViewRef } = useNodesRef(props, ref, {});
54
+ const autoplayEndRef = useRef(false);
55
+ // 存储layout布局信息
56
+ const layoutRef = useRef({});
57
+ // 内部存储上一次的偏移量
58
+ const internalsRef = useRef({
59
+ offset: {
60
+ x: defaultX || 0,
61
+ y: defaultY || 0
62
+ },
63
+ isScrolling: false
64
+ });
65
+ const [state, setState] = useState({
66
+ children: newChild,
67
+ width: width || 375,
68
+ height: defaultHeight,
69
+ index: 0,
70
+ total: Array.isArray(newChild) ? newChild.length : (newChild ? 1 : 0),
71
+ offset: {
72
+ x: dir === 'x' ? defaultX : 0,
73
+ y: dir === 'y' ? defaultY : 0
74
+ },
75
+ loopJump: false,
76
+ dir
77
+ });
78
+ useEffect(() => {
79
+ // 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
80
+ if (props.autoplay) {
81
+ startAutoPlay();
82
+ }
83
+ else {
84
+ startSwiperLoop();
85
+ }
86
+ }, [props.autoplay, props.current, state.index]);
87
+ /**
88
+ * 更新index,以视图的offset计算当前的索引
89
+ */
90
+ function updateIndex(scrollViewOffset) {
91
+ const diff = scrollViewOffset[dir] - internalsRef.current.offset[state.dir];
92
+ if (!diff)
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,初始化????
115
+ setState((preState) => {
116
+ const newState = {
117
+ ...preState,
118
+ index: newIndex,
119
+ offset: scrollViewOffset,
120
+ loopJump
121
+ };
122
+ return newState;
123
+ });
124
+ internalsRef.current.isScrolling = false;
125
+ // getCustomEvent
126
+ const eventData = getCustomEvent('change', {}, { detail: { current: newIndex, source: 'touch' }, layoutRef: layoutRef });
127
+ props.bindchange && props.bindchange(eventData);
128
+ // 更新完状态之后, 开启新的loop
129
+ }
130
+ /**
131
+ * 用户手动点击播放
132
+ * 触发scrollView的onScrollEnd事件 => 然后更新索引 => 通过useEffect事件 => startSwiperLoop => 主动更新scrollView到指定的位置
133
+ * 若是circular, 到最后一个索引会更新为0,但是视觉要scrollView到下一个
134
+ * 若是circular, 到第一个再往前索引会更新为total-1, 但是视觉是展示的最后一个
135
+ */
136
+ function startSwiperLoop() {
137
+ loopJumpTimerRef.current = setTimeout(() => {
138
+ let offset = { x: 0, y: 0, animated: false };
139
+ if (state.index > 0) {
140
+ offset = props.horizontal ? { x: state.width * state.index, y: 0, animated: false } : { x: 0, y: state.height * state.index, animated: false };
141
+ }
142
+ if (props.circular) {
143
+ offset = props.horizontal ? { x: state.width * (state.index + 1), y: 0, animated: false } : { x: 0, y: state.height * (state.index + 1), animated: false };
144
+ }
145
+ scrollViewRef.current?.scrollTo(offset);
146
+ internalsRef.current.offset = offset;
147
+ }, props.duration || 500);
148
+ }
149
+ /**
150
+ * 开启自动轮播
151
+ * 每间隔interval scrollView的offset更改到下一个位置,通过onScrollEnd来获取contentOffset再计算要更新的索引index
152
+ */
153
+ function startAutoPlay() {
154
+ // 已经开启过autopaly则不重新创建
155
+ if (!Array.isArray(state.children) || !props.autoplay || internalsRef.current.isScrolling || autoplayEndRef.current) {
156
+ return;
157
+ }
158
+ autoplayTimerRef.current && clearTimeout(autoplayTimerRef.current);
159
+ // 非循环自动播放的形式下 到最后一帧 结束自动播放
160
+ if (!props.circular && state.index === state.total - 1) {
161
+ autoplayEndRef.current = true;
162
+ return;
163
+ }
164
+ // 开启自动播放
165
+ autoplayTimerRef.current = setTimeout(() => {
166
+ if (state.total < 2)
167
+ return;
168
+ const nexStep = 1;
169
+ const toIndex = (props.circular ? 1 : 0) + nexStep + state.index;
170
+ let x = 0;
171
+ let y = 0;
172
+ if (state.dir === 'x')
173
+ x = toIndex * state.width;
174
+ if (state.dir === 'y')
175
+ y = toIndex * state.height;
176
+ // animated会影响切换的offset,先改为false
177
+ scrollViewRef.current?.scrollTo({ x, y, animated: false });
178
+ internalsRef.current.isScrolling = true;
179
+ autoplayEndRef.current = false;
180
+ updateIndex({ x, y });
181
+ }, props.interval || 5000);
182
+ }
183
+ /**
184
+ * 当用户开始拖动此视图时调用此函数, 更新当前在滚动态
185
+ */
186
+ function onScrollBegin() {
187
+ internalsRef.current.isScrolling = true;
188
+ }
189
+ function onScrollEnd(event) {
190
+ internalsRef.current.isScrolling = false;
191
+ // 用户手动滑动更新索引后,如果开启了自动轮播等重新开始
192
+ updateIndex(event.nativeEvent.contentOffset);
193
+ }
194
+ /**
195
+ * 当拖拽结束时,检测是否可滚动
196
+ */
197
+ function onScrollEndDrag(event) {
198
+ const { contentOffset } = event.nativeEvent;
199
+ const { index, total } = state;
200
+ const internalOffset = internalsRef.current.offset;
201
+ const previousOffset = props.horizontal ? internalOffset.x : internalOffset.y;
202
+ const newOffset = props.horizontal ? contentOffset.x : contentOffset.y;
203
+ if (previousOffset === newOffset && (index === 0 || index === total - 1)) {
204
+ internalsRef.current.isScrolling = false;
205
+ }
206
+ }
207
+ /**
208
+ * 垂直方向时,获取单个元素的布局,更新
209
+ */
210
+ function onItemLayout(event) {
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;
219
+ }
220
+ if (initRenderRef.current && state.total > 1) {
221
+ scrollViewRef.current?.scrollTo({ ...internalsRef.current.offset, animated: false });
222
+ initRenderRef.current = false;
223
+ }
224
+ setState((preState) => {
225
+ return {
226
+ ...preState,
227
+ height
228
+ };
229
+ });
230
+ }
231
+ /**
232
+ * 水平方向时,获取单个元素的布局,更新
233
+ */
234
+ function onWrapperLayout() {
235
+ if (props.enableOffset) {
236
+ // @ts-ignore
237
+ scrollViewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
238
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
239
+ props.getInnerLayout && props.getInnerLayout(layoutRef);
240
+ });
241
+ }
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
+ }
252
+ function renderScrollView(pages) {
253
+ let scrollElementProps = {
254
+ ref: scrollViewRef,
255
+ horizontal: props.horizontal,
256
+ pagingEnabled: true,
257
+ showsHorizontalScrollIndicator: false,
258
+ showsVerticalScrollIndicator: false,
259
+ bounces: false,
260
+ scrollsToTop: false,
261
+ removeClippedSubviews: true,
262
+ automaticallyAdjustContentInsets: false
263
+ };
264
+ return (<ScrollView {...scrollElementProps} overScrollMode="always" contentOffset={state.offset} onScrollBeginDrag={onScrollBegin} onMomentumScrollEnd={onScrollEnd} onScrollEndDrag={onScrollEndDrag}>
265
+ {pages}
266
+ </ScrollView>);
267
+ }
268
+ function renderPagination() {
269
+ if (state.total <= 1)
270
+ return null;
271
+ let dots = [];
272
+ const activeDotStyle = [{
273
+ backgroundColor: props.activeDotColor || '#007aff',
274
+ width: 8,
275
+ height: 8,
276
+ borderRadius: 4,
277
+ marginLeft: 3,
278
+ marginRight: 3,
279
+ marginTop: 3,
280
+ marginBottom: 3
281
+ }];
282
+ const dotStyle = [{
283
+ backgroundColor: props.dotColor || 'rgba(0,0,0,.2)',
284
+ width: 8,
285
+ height: 8,
286
+ borderRadius: 4,
287
+ marginLeft: 3,
288
+ marginRight: 3,
289
+ marginTop: 3,
290
+ marginBottom: 3
291
+ }];
292
+ for (let i = 0; i < state.total; i++) {
293
+ if (i === state.index) {
294
+ dots.push(<View style={activeDotStyle} key={i}></View>);
295
+ }
296
+ else {
297
+ dots.push(<View style={dotStyle} key={i}></View>);
298
+ }
299
+ }
300
+ return (<View pointerEvents="none" style={[styles['pagination_' + state.dir]]}>
301
+ {dots}
302
+ </View>);
303
+ }
304
+ function renderPages() {
305
+ const { width, height, total, children } = state;
306
+ const { circular, previousMargin, nextMargin, innerProps } = props;
307
+ const pageStyle = { width: width, height: height };
308
+ if (total > 1 && Array.isArray(children)) {
309
+ let arrElements = [];
310
+ // pages = ["2", "0", "1", "2", "0"]
311
+ let pages = Array.isArray(children) && Object.keys(children) || [];
312
+ /* 无限循环的时候 */
313
+ if (circular) {
314
+ pages.unshift(total - 1 + '');
315
+ pages.push('0');
316
+ }
317
+ arrElements = pages.map((page, i) => {
318
+ let pageStyle2 = { width: width, height: height };
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}>
329
+ {children[+page]}
330
+ </View>);
331
+ });
332
+ return arrElements;
333
+ }
334
+ else {
335
+ return (<View style={pageStyle} key={0}>
336
+ {children}
337
+ </View>);
338
+ }
339
+ }
340
+ const vStyle = {};
341
+ if (dir === 'y') {
342
+ vStyle.height = defaultHeight;
343
+ }
344
+ const pages = renderPages();
345
+ const strStyle = 'container_' + state.dir;
346
+ const eventProps = props.innerProps || {};
347
+ return (<View style={[styles[strStyle], vStyle]} {...eventProps} onLayout={onWrapperLayout}>
348
+ {renderScrollView(pages)}
349
+ {props.showsPagination && renderPagination()}
350
+ </View>);
351
+ });
352
+ _Carouse.displayName = '_Carouse';
353
+ export default _Carouse;