@mpxjs/webpack-plugin 2.10.18-beta.12 → 2.10.18-beta.14

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.
@@ -42,8 +42,6 @@ const wxs = require('./wxs')
42
42
  const component = require('./component')
43
43
  const fixComponentName = require('./fix-component-name')
44
44
  const rootPortal = require('./root-portal')
45
- const stickyHeader = require('./sticky-header')
46
- const stickySection = require('./sticky-section')
47
45
 
48
46
  module.exports = function getComponentConfigs ({ warn, error }) {
49
47
  /**
@@ -127,8 +125,6 @@ module.exports = function getComponentConfigs ({ warn, error }) {
127
125
  hyphenTagName({ print }),
128
126
  label({ print }),
129
127
  component(),
130
- rootPortal({ print }),
131
- stickyHeader({ print }),
132
- stickySection({ print })
128
+ rootPortal({ print })
133
129
  ]
134
130
  }
@@ -152,7 +152,7 @@
152
152
  },
153
153
  pollingDuration: {
154
154
  type: Number,
155
- value: 3000
155
+ value: 300
156
156
  },
157
157
  useListHeader: {
158
158
  type: Boolean,
@@ -0,0 +1 @@
1
+ <!-- section-list 占位文件-->
@@ -0,0 +1 @@
1
+ <!-- sticky-header 占位文件-->
@@ -0,0 +1 @@
1
+ <!-- sticky-section 占位文件-->
@@ -271,7 +271,31 @@ const Image = forwardRef((props, ref) => {
271
271
  const onImageLoad = (evt) => {
272
272
  evt.persist();
273
273
  RNImage.getSize(src, (width, height) => {
274
- bindload(getCustomEvent('load', evt, {
274
+ // iPhone 8 等设备对缓存图 getSize 偶发返回 0,用 onLoad 事件里的真实尺寸兜底
275
+ if (!width || !height) {
276
+ const nativeEvent = evt.nativeEvent;
277
+ const source = nativeEvent.source;
278
+ width = (source && source.width) || nativeEvent.width || 0;
279
+ height = (source && source.height) || nativeEvent.height || 0;
280
+ // 布局模式下用真实尺寸同步 view(此时 useEffect 里的 getSize 也没拿到尺寸)
281
+ if (isLayoutMode && width && height && !state.current.ratio) {
282
+ state.current.imageWidth = width;
283
+ state.current.imageHeight = height;
284
+ state.current.ratio = height / width;
285
+ if (isWidthFixMode
286
+ ? state.current.viewWidth
287
+ : isHeightFixMode
288
+ ? state.current.viewHeight
289
+ : state.current.viewWidth && state.current.viewHeight) {
290
+ setRatio(state.current.ratio);
291
+ setImageWidth(width);
292
+ setImageHeight(height);
293
+ setViewSize(state.current.viewWidth, state.current.viewHeight, state.current.ratio);
294
+ setLoaded(true);
295
+ }
296
+ }
297
+ }
298
+ bindload && bindload(getCustomEvent('load', evt, {
275
299
  detail: { width, height },
276
300
  layoutRef
277
301
  }, props));
@@ -327,10 +351,12 @@ const Image = forwardRef((props, ref) => {
327
351
  return renderImage(extendObject({
328
352
  source: { uri: src },
329
353
  resizeMode: resizeMode,
330
- onLoad: bindload && onImageLoad,
354
+ onLoad: onImageLoad,
331
355
  onError: binderror && onImageError,
332
356
  style: extendObject({
333
357
  transformOrigin: 'left top',
358
+ // 布局模式下尺寸未知(ratio 为 0)前先隐藏,避免按默认高度闪一下(iPhone 8 getSize 返回 0 时尤其明显)
359
+ opacity: isLayoutMode && !ratio ? 0 : 1,
334
360
  width: isCropMode ? imageWidth : '100%',
335
361
  height: isCropMode ? imageHeight : '100%'
336
362
  }, isCropMode ? modeStyle : {})
@@ -1,4 +1,5 @@
1
- import React from 'react';
1
+ /// <reference types="react" />
2
+ import { GestureHandler } from './utils';
2
3
  interface ListItem {
3
4
  isSectionHeader?: boolean;
4
5
  _originalItemIndex?: number;
@@ -39,10 +40,12 @@ interface SectionListProps {
39
40
  'refresher-enabled'?: boolean;
40
41
  'show-scrollbar'?: boolean;
41
42
  'refresher-triggered'?: boolean;
43
+ 'wait-for'?: Array<GestureHandler>;
44
+ 'simultaneous-handlers'?: Array<GestureHandler>;
42
45
  bindrefresherrefresh?: (event: any) => void;
43
46
  bindscrolltolower?: (event: any) => void;
44
47
  bindscroll?: (event: any) => void;
45
48
  [key: string]: any;
46
49
  }
47
- declare const _SectionList: React.ForwardRefExoticComponent<Omit<SectionListProps, "ref"> & React.RefAttributes<any>>;
50
+ declare const _SectionList: import("react").ForwardRefExoticComponent<Omit<SectionListProps, "ref"> & import("react").RefAttributes<any>>;
48
51
  export default _SectionList;
@@ -1,7 +1,8 @@
1
- import React, { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle, memo } from 'react';
1
+ import { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle, memo } from 'react';
2
2
  import { SectionList, RefreshControl } from 'react-native';
3
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler';
3
4
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
4
- import { extendObject, useLayout, useTransformStyle } from './utils';
5
+ import { extendObject, useLayout, useTransformStyle, flatGesture } from './utils';
5
6
  const getGeneric = (generichash, generickey) => {
6
7
  if (!generichash || !generickey)
7
8
  return null;
@@ -15,9 +16,10 @@ const getGeneric = (generichash, generickey) => {
15
16
  }));
16
17
  };
17
18
  const _SectionList = forwardRef((props = {}, ref) => {
18
- const { enhanced = false, bounces = true, scrollEventThrottle = 0, height, width, listData, generichash, style = {}, itemHeight = {}, sectionHeaderHeight = {}, listHeaderHeight = {}, listHeaderData = null, useListHeader = false, listFooterData = null, useListFooter = false, 'genericrecycle-item': genericrecycleItem, 'genericsection-header': genericsectionHeader, 'genericlist-header': genericListHeader, 'genericlist-footer': genericListFooter, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'enable-sticky': enableSticky = false, 'enable-back-to-top': enableBackToTop = false, 'end-reached-threshold': onEndReachedThreshold = 0.1, 'refresher-enabled': refresherEnabled, 'show-scrollbar': showScrollbar = true, 'refresher-triggered': refresherTriggered } = props;
19
+ const { enhanced = false, bounces = true, scrollEventThrottle = 0, height, width, listData, generichash, style = {}, itemHeight = {}, sectionHeaderHeight = {}, listHeaderHeight = {}, listHeaderData = null, useListHeader = false, listFooterData = null, useListFooter = false, 'genericrecycle-item': genericrecycleItem, 'genericsection-header': genericsectionHeader, 'genericlist-header': genericListHeader, 'genericlist-footer': genericListFooter, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'enable-sticky': enableSticky = false, 'enable-back-to-top': enableBackToTop = false, 'end-reached-threshold': onEndReachedThreshold = 0.1, 'refresher-enabled': refresherEnabled, 'show-scrollbar': showScrollbar = true, 'refresher-triggered': refresherTriggered, 'simultaneous-handlers': originSimultaneousHandlers, 'wait-for': waitFor } = props;
19
20
  const [refreshing, setRefreshing] = useState(!!refresherTriggered);
20
21
  const scrollViewRef = useRef(null);
22
+ const sectionListGestureRef = useRef();
21
23
  const indexMap = useRef({});
22
24
  const reverseIndexMap = useRef({});
23
25
  const { hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
@@ -176,13 +178,13 @@ const _SectionList = forwardRef((props = {}, ref) => {
176
178
  offset += headerHeight;
177
179
  // 添加该 section 中所有 items 的位置信息
178
180
  section.data.forEach((item, itemIndex) => {
179
- const contenteight = getItemHeight({ sectionIndex, rowIndex: itemIndex });
181
+ const contentHeight = getItemHeight({ sectionIndex, rowIndex: itemIndex });
180
182
  layouts.push({
181
- length: contenteight,
183
+ length: contentHeight,
182
184
  offset,
183
185
  index: layouts.length
184
186
  });
185
- offset += contenteight;
187
+ offset += contentHeight;
186
188
  });
187
189
  // 添加该 section 尾部位置信息
188
190
  // 因为即使 sectionList 没传 renderSectionFooter,getItemLayout 中的 index 的计算也会包含尾部节点
@@ -210,21 +212,33 @@ const _SectionList = forwardRef((props = {}, ref) => {
210
212
  onScroll: onScroll,
211
213
  onEndReached: onEndReached
212
214
  }, layoutProps);
215
+ const nativeGesture = useMemo(() => {
216
+ const simultaneousHandlers = flatGesture(originSimultaneousHandlers);
217
+ const waitForHandlers = flatGesture(waitFor);
218
+ const gesture = Gesture.Native().withRef(sectionListGestureRef);
219
+ if (simultaneousHandlers && simultaneousHandlers.length) {
220
+ gesture.simultaneousWithExternalGesture(...simultaneousHandlers);
221
+ }
222
+ if (waitForHandlers && waitForHandlers.length) {
223
+ gesture.requireExternalGestureToFail(...waitForHandlers);
224
+ }
225
+ return gesture;
226
+ }, [originSimultaneousHandlers, waitFor]);
213
227
  if (enhanced) {
214
- Object.assign(scrollAdditionalProps, {
228
+ extendObject(scrollAdditionalProps, {
215
229
  bounces
216
230
  });
217
231
  }
218
232
  if (refresherEnabled) {
219
- Object.assign(scrollAdditionalProps, {
233
+ extendObject(scrollAdditionalProps, {
220
234
  refreshing: refreshing
221
235
  });
222
236
  }
223
237
  useImperativeHandle(ref, () => {
224
- return {
225
- ...props,
238
+ return extendObject({}, props, {
239
+ gestureRef: sectionListGestureRef,
226
240
  scrollToIndex
227
- };
241
+ });
228
242
  });
229
243
  const innerProps = useInnerProps(extendObject({}, props, scrollAdditionalProps), [
230
244
  'id',
@@ -232,7 +246,9 @@ const _SectionList = forwardRef((props = {}, ref) => {
232
246
  'lower-threshold',
233
247
  'refresher-triggered',
234
248
  'refresher-enabled',
235
- 'bindrefresherrefresh'
249
+ 'bindrefresherrefresh',
250
+ 'simultaneous-handlers',
251
+ 'wait-for'
236
252
  ], { layoutRef });
237
253
  // 使用 ref 保存最新的数据,避免数据变化时组件销毁重建
238
254
  const listHeaderDataRef = useRef(listHeaderData);
@@ -272,7 +288,7 @@ const _SectionList = forwardRef((props = {}, ref) => {
272
288
  return null;
273
289
  return () => createElement(ListFooterGenericComponent, { listFooterData: listFooterDataRef.current });
274
290
  }, [useListFooter, generichash, genericListFooter]);
275
- return createElement(SectionList, extendObject({
291
+ return createElement(GestureDetector, { gesture: nativeGesture }, createElement(SectionList, extendObject({
276
292
  style: [{ height, width }, style, layoutStyle],
277
293
  sections: convertedListData,
278
294
  renderItem: renderItem,
@@ -281,12 +297,12 @@ const _SectionList = forwardRef((props = {}, ref) => {
281
297
  ListFooterComponent: useListFooter ? ListFooterComponent : null,
282
298
  renderSectionHeader: renderSectionHeader,
283
299
  refreshControl: refresherEnabled
284
- ? React.createElement(RefreshControl, {
300
+ ? createElement(RefreshControl, {
285
301
  onRefresh: onRefresh,
286
302
  refreshing: refreshing
287
303
  })
288
304
  : undefined
289
- }, innerProps));
305
+ }, innerProps)));
290
306
  });
291
307
  _SectionList.displayName = 'MpxSectionList';
292
308
  export default _SectionList;
@@ -381,7 +381,31 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
381
381
  const onImageLoad = (evt: NativeSyntheticEvent<ImageLoadEventData>) => {
382
382
  evt.persist()
383
383
  RNImage.getSize(src, (width: number, height: number) => {
384
- bindload!(
384
+ // iPhone 8 等设备对缓存图 getSize 偶发返回 0,用 onLoad 事件里的真实尺寸兜底
385
+ if (!width || !height) {
386
+ const nativeEvent = evt.nativeEvent as any
387
+ const source = nativeEvent.source
388
+ width = (source && source.width) || nativeEvent.width || 0
389
+ height = (source && source.height) || nativeEvent.height || 0
390
+ // 布局模式下用真实尺寸同步 view(此时 useEffect 里的 getSize 也没拿到尺寸)
391
+ if (isLayoutMode && width && height && !state.current.ratio) {
392
+ state.current.imageWidth = width
393
+ state.current.imageHeight = height
394
+ state.current.ratio = height / width
395
+ if (isWidthFixMode
396
+ ? state.current.viewWidth
397
+ : isHeightFixMode
398
+ ? state.current.viewHeight
399
+ : state.current.viewWidth && state.current.viewHeight) {
400
+ setRatio(state.current.ratio)
401
+ setImageWidth(width)
402
+ setImageHeight(height)
403
+ setViewSize(state.current.viewWidth!, state.current.viewHeight!, state.current.ratio)
404
+ setLoaded(true)
405
+ }
406
+ }
407
+ }
408
+ bindload && bindload!(
385
409
  getCustomEvent(
386
410
  'load',
387
411
  evt,
@@ -486,11 +510,13 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
486
510
  {
487
511
  source: { uri: src },
488
512
  resizeMode: resizeMode,
489
- onLoad: bindload && onImageLoad,
513
+ onLoad: onImageLoad,
490
514
  onError: binderror && onImageError,
491
515
  style: extendObject(
492
516
  {
493
517
  transformOrigin: 'left top',
518
+ // 布局模式下尺寸未知(ratio 为 0)前先隐藏,避免按默认高度闪一下(iPhone 8 getSize 返回 0 时尤其明显)
519
+ opacity: isLayoutMode && !ratio ? 0 : 1,
494
520
  width: isCropMode ? imageWidth : '100%',
495
521
  height: isCropMode ? imageHeight : '100%'
496
522
  },
@@ -1,7 +1,8 @@
1
- import React, { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle, useCallback, memo } from 'react'
1
+ import { forwardRef, useRef, useState, useEffect, useMemo, createElement, useImperativeHandle, memo } from 'react'
2
2
  import { SectionList, RefreshControl, NativeSyntheticEvent, NativeScrollEvent } from 'react-native'
3
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler'
3
4
  import useInnerProps, { getCustomEvent } from './getInnerListeners'
4
- import { extendObject, useLayout, useTransformStyle } from './utils'
5
+ import { extendObject, useLayout, useTransformStyle, GestureHandler, flatGesture } from './utils'
5
6
  interface ListItem {
6
7
  isSectionHeader?: boolean;
7
8
  _originalItemIndex?: number;
@@ -51,6 +52,8 @@ interface SectionListProps {
51
52
  'refresher-enabled'?: boolean;
52
53
  'show-scrollbar'?: boolean;
53
54
  'refresher-triggered'?: boolean;
55
+ 'wait-for'?: Array<GestureHandler>;
56
+ 'simultaneous-handlers'?: Array<GestureHandler>;
54
57
  bindrefresherrefresh?: (event: any) => void;
55
58
  bindscrolltolower?: (event: any) => void;
56
59
  bindscroll?: (event: any) => void;
@@ -107,12 +110,15 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
107
110
  'end-reached-threshold': onEndReachedThreshold = 0.1,
108
111
  'refresher-enabled': refresherEnabled,
109
112
  'show-scrollbar': showScrollbar = true,
110
- 'refresher-triggered': refresherTriggered
113
+ 'refresher-triggered': refresherTriggered,
114
+ 'simultaneous-handlers': originSimultaneousHandlers,
115
+ 'wait-for': waitFor
111
116
  } = props
112
117
 
113
118
  const [refreshing, setRefreshing] = useState(!!refresherTriggered)
114
119
 
115
120
  const scrollViewRef = useRef<any>(null)
121
+ const sectionListGestureRef = useRef<any>()
116
122
 
117
123
  const indexMap = useRef<{ [key: string]: string | number }>({})
118
124
 
@@ -295,13 +301,13 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
295
301
 
296
302
  // 添加该 section 中所有 items 的位置信息
297
303
  section.data.forEach((item: ListItem, itemIndex: number) => {
298
- const contenteight = getItemHeight({ sectionIndex, rowIndex: itemIndex })
304
+ const contentHeight = getItemHeight({ sectionIndex, rowIndex: itemIndex })
299
305
  layouts.push({
300
- length: contenteight,
306
+ length: contentHeight,
301
307
  offset,
302
308
  index: layouts.length
303
309
  })
304
- offset += contenteight
310
+ offset += contentHeight
305
311
  })
306
312
 
307
313
  // 添加该 section 尾部位置信息
@@ -335,22 +341,35 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
335
341
  layoutProps
336
342
  )
337
343
 
344
+ const nativeGesture = useMemo(() => {
345
+ const simultaneousHandlers = flatGesture(originSimultaneousHandlers)
346
+ const waitForHandlers = flatGesture(waitFor)
347
+ const gesture = Gesture.Native().withRef(sectionListGestureRef as any)
348
+ if (simultaneousHandlers && simultaneousHandlers.length) {
349
+ gesture.simultaneousWithExternalGesture(...simultaneousHandlers)
350
+ }
351
+ if (waitForHandlers && waitForHandlers.length) {
352
+ gesture.requireExternalGestureToFail(...waitForHandlers)
353
+ }
354
+ return gesture
355
+ }, [originSimultaneousHandlers, waitFor])
356
+
338
357
  if (enhanced) {
339
- Object.assign(scrollAdditionalProps, {
358
+ extendObject(scrollAdditionalProps, {
340
359
  bounces
341
360
  })
342
361
  }
343
362
  if (refresherEnabled) {
344
- Object.assign(scrollAdditionalProps, {
363
+ extendObject(scrollAdditionalProps, {
345
364
  refreshing: refreshing
346
365
  })
347
366
  }
348
367
 
349
368
  useImperativeHandle(ref, () => {
350
- return {
351
- ...props,
369
+ return extendObject({}, props, {
370
+ gestureRef: sectionListGestureRef,
352
371
  scrollToIndex
353
- }
372
+ })
354
373
  })
355
374
 
356
375
  const innerProps = useInnerProps(extendObject({}, props, scrollAdditionalProps), [
@@ -359,7 +378,9 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
359
378
  'lower-threshold',
360
379
  'refresher-triggered',
361
380
  'refresher-enabled',
362
- 'bindrefresherrefresh'
381
+ 'bindrefresherrefresh',
382
+ 'simultaneous-handlers',
383
+ 'wait-for'
363
384
  ], { layoutRef })
364
385
 
365
386
  // 使用 ref 保存最新的数据,避免数据变化时组件销毁重建
@@ -412,24 +433,28 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
412
433
  )
413
434
 
414
435
  return createElement(
415
- SectionList,
416
- extendObject(
417
- {
418
- style: [{ height, width }, style, layoutStyle],
419
- sections: convertedListData,
420
- renderItem: renderItem,
421
- getItemLayout: getItemLayout,
422
- ListHeaderComponent: useListHeader ? ListHeaderComponent : null,
423
- ListFooterComponent: useListFooter ? ListFooterComponent : null,
424
- renderSectionHeader: renderSectionHeader,
425
- refreshControl: refresherEnabled
426
- ? React.createElement(RefreshControl, {
427
- onRefresh: onRefresh,
428
- refreshing: refreshing
429
- })
430
- : undefined
431
- },
432
- innerProps
436
+ GestureDetector,
437
+ { gesture: nativeGesture },
438
+ createElement(
439
+ SectionList,
440
+ extendObject(
441
+ {
442
+ style: [{ height, width }, style, layoutStyle],
443
+ sections: convertedListData,
444
+ renderItem: renderItem,
445
+ getItemLayout: getItemLayout,
446
+ ListHeaderComponent: useListHeader ? ListHeaderComponent : null,
447
+ ListFooterComponent: useListFooter ? ListFooterComponent : null,
448
+ renderSectionHeader: renderSectionHeader,
449
+ refreshControl: refresherEnabled
450
+ ? createElement(RefreshControl, {
451
+ onRefresh: onRefresh,
452
+ refreshing: refreshing
453
+ })
454
+ : undefined
455
+ },
456
+ innerProps
457
+ )
433
458
  )
434
459
  )
435
460
  })
@@ -140,7 +140,7 @@ export default {
140
140
  },
141
141
  useListHeader: {
142
142
  type: Boolean,
143
- default: true
143
+ default: false
144
144
  },
145
145
  listFooterData: {
146
146
  type: Object,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.10.18-beta.12",
3
+ "version": "2.10.18-beta.14",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -1,23 +0,0 @@
1
- const TAG_NAME = 'sticky-header'
2
-
3
- module.exports = function ({ print }) {
4
- return {
5
- test: TAG_NAME,
6
- android (tag, { el }) {
7
- el.isBuiltIn = true
8
- return 'mpx-sticky-header'
9
- },
10
- ios (tag, { el }) {
11
- el.isBuiltIn = true
12
- return 'mpx-sticky-header'
13
- },
14
- harmony (tag, { el }) {
15
- el.isBuiltIn = true
16
- return 'mpx-sticky-header'
17
- },
18
- web (tag, { el }) {
19
- el.isBuiltIn = true
20
- return 'mpx-sticky-header'
21
- }
22
- }
23
- }
@@ -1,23 +0,0 @@
1
- const TAG_NAME = 'sticky-section'
2
-
3
- module.exports = function ({ print }) {
4
- return {
5
- test: TAG_NAME,
6
- android (tag, { el }) {
7
- el.isBuiltIn = true
8
- return 'mpx-sticky-section'
9
- },
10
- ios (tag, { el }) {
11
- el.isBuiltIn = true
12
- return 'mpx-sticky-section'
13
- },
14
- harmony (tag, { el }) {
15
- el.isBuiltIn = true
16
- return 'mpx-sticky-section'
17
- },
18
- web (tag, { el }) {
19
- el.isBuiltIn = true
20
- return 'mpx-sticky-section'
21
- }
22
- }
23
- }