@mpxjs/webpack-plugin 2.9.69-beta.0 → 2.9.69-beta.1

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 (49) hide show
  1. package/lib/index.js +17 -1
  2. package/lib/platform/style/wx/index.js +18 -18
  3. package/lib/platform/template/wx/component-config/movable-view.js +8 -1
  4. package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
  5. package/lib/resolver/AddEnvPlugin.js +1 -0
  6. package/lib/resolver/AddModePlugin.js +1 -0
  7. package/lib/runtime/components/react/context.ts +8 -0
  8. package/lib/runtime/components/react/dist/context.js +2 -0
  9. package/lib/runtime/components/react/dist/getInnerListeners.js +3 -4
  10. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -1
  11. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
  12. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +21 -10
  13. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +1 -1
  14. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +10 -11
  15. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +9 -4
  16. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +25 -8
  17. package/lib/runtime/components/react/dist/mpx-swiper.jsx +150 -148
  18. package/lib/runtime/components/react/dist/mpx-view.jsx +9 -40
  19. package/lib/runtime/components/react/dist/mpx-web-view.jsx +48 -10
  20. package/lib/runtime/components/react/dist/pickerFaces.js +1 -1
  21. package/lib/runtime/components/react/dist/useAnimationHooks.js +1 -1
  22. package/lib/runtime/components/react/dist/utils.jsx +60 -2
  23. package/lib/runtime/components/react/getInnerListeners.ts +3 -5
  24. package/lib/runtime/components/react/mpx-input.tsx +1 -1
  25. package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
  26. package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
  27. package/lib/runtime/components/react/mpx-picker-view-column.tsx +177 -145
  28. package/lib/runtime/components/react/mpx-picker-view.tsx +35 -37
  29. package/lib/runtime/components/react/mpx-rich-text/index.tsx +12 -18
  30. package/lib/runtime/components/react/mpx-scroll-view.tsx +19 -10
  31. package/lib/runtime/components/react/mpx-swiper-item.tsx +38 -10
  32. package/lib/runtime/components/react/mpx-swiper.tsx +690 -0
  33. package/lib/runtime/components/react/mpx-view.tsx +11 -51
  34. package/lib/runtime/components/react/mpx-web-view.tsx +55 -11
  35. package/lib/runtime/components/react/pickerFaces.ts +15 -7
  36. package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
  37. package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
  38. package/lib/runtime/components/react/{pickerOverlay.tsx → pickerViewOverlay.tsx} +5 -3
  39. package/lib/runtime/components/react/types/global.d.ts +3 -1
  40. package/lib/runtime/components/react/useAnimationHooks.ts +1 -1
  41. package/lib/runtime/components/react/utils.tsx +72 -3
  42. package/lib/style-compiler/index.js +3 -4
  43. package/lib/style-compiler/strip-conditional-loader.js +118 -0
  44. package/lib/template-compiler/compiler.js +9 -14
  45. package/lib/utils/pre-process-json.js +5 -9
  46. package/package.json +1 -1
  47. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -527
  48. package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
  49. package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
package/lib/index.js CHANGED
@@ -54,11 +54,13 @@ const wxssLoaderPath = normalize.lib('wxss/index')
54
54
  const wxmlLoaderPath = normalize.lib('wxml/loader')
55
55
  const wxsLoaderPath = normalize.lib('wxs/loader')
56
56
  const styleCompilerPath = normalize.lib('style-compiler/index')
57
+ const styleStripConditaionalPath = normalize.lib('style-compiler/strip-conditional-loader')
57
58
  const templateCompilerPath = normalize.lib('template-compiler/index')
58
59
  const jsonCompilerPath = normalize.lib('json-compiler/index')
59
60
  const jsonThemeCompilerPath = normalize.lib('json-compiler/theme')
60
61
  const jsonPluginCompilerPath = normalize.lib('json-compiler/plugin')
61
62
  const extractorPath = normalize.lib('extractor')
63
+ const selectorPath = normalize.lib('selector')
62
64
  const async = require('async')
63
65
  const { parseQuery } = require('loader-utils')
64
66
  const stringifyLoadersAndResource = require('./utils/stringify-loaders-resource')
@@ -1775,7 +1777,7 @@ try {
1775
1777
  })
1776
1778
 
1777
1779
  const typeLoaderProcessInfo = {
1778
- styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath],
1780
+ styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath, styleStripConditaionalPath],
1779
1781
  template: ['node_modules/html-loader', wxmlLoaderPath, templateCompilerPath]
1780
1782
  }
1781
1783
 
@@ -1833,6 +1835,20 @@ try {
1833
1835
  loader: extractorPath
1834
1836
  })
1835
1837
  }
1838
+ if (type === 'styles') {
1839
+ // 判断最后一个loader是否是 selectorPath, 如果是,则在sectorPath之前插入strip-conditional
1840
+ const lastLoader = loaders[loaders.length - 1]
1841
+ if (lastLoader.loader.includes(selectorPath)) {
1842
+ loaders.splice(loaders.length - 1, 0, {
1843
+ loader: styleStripConditaionalPath
1844
+ })
1845
+ } else {
1846
+ // 在最后一个插入strip-conditional
1847
+ loaders.push({
1848
+ loader: styleStripConditaionalPath
1849
+ })
1850
+ }
1851
+ }
1836
1852
  createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
1837
1853
  }
1838
1854
  // mpxStyleOptions 为 mpx style 文件的标识,避免 Vue 文件插入 styleCompiler 后导致 vue scoped 样式隔离失效
@@ -374,11 +374,11 @@ module.exports = function getSpec ({ warn, error }) {
374
374
  // transform 转换
375
375
  const formatTransform = ({ prop, value, selector }, { mode }) => {
376
376
  // css var & 数组直接返回
377
- if (Array.isArray(value) || calcExp.test(value)) return { prop, value }
377
+ if (Array.isArray(value) || cssVariableExp.test(value)) return { prop, value }
378
378
  const values = parseValues(value)
379
379
  const transform = []
380
380
  values.forEach(item => {
381
- const match = item.match(/([/\w]+)\(([^)]+)\)/)
381
+ const match = item.match(/([/\w]+)\((.+)\)/)
382
382
  if (match && match.length >= 3) {
383
383
  let key = match[1]
384
384
  const val = match[2]
@@ -407,23 +407,23 @@ module.exports = function getSpec ({ warn, error }) {
407
407
  case 'rotate3d': // x y z angle
408
408
  case 'translate3d': // x y 支持 z不支持
409
409
  case 'scale3d': // x y 支持 z不支持
410
- {
411
- // 2 个以上的值处理
412
- key = key.replace('3d', '')
413
- const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
414
- // scale(.5) === scaleX(.5) scaleY(.5)
415
- if (vals.length === 1 && key === 'scale') {
416
- vals.push(vals[0])
417
- }
418
- const xyz = ['X', 'Y', 'Z']
419
- transform.push(...vals.map((v, index) => {
420
- if (key !== 'rotate' && index > 1) {
421
- unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode })
422
- }
423
- return { [`${key}${xyz[index] || ''}`]: v.trim() }
424
- }))
425
- break
410
+ {
411
+ // 2 个以上的值处理
412
+ key = key.replace('3d', '')
413
+ const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
414
+ // scale(.5) === scaleX(.5) scaleY(.5)
415
+ if (vals.length === 1 && key === 'scale') {
416
+ vals.push(vals[0])
426
417
  }
418
+ const xyz = ['X', 'Y', 'Z']
419
+ transform.push(...vals.map((v, index) => {
420
+ if (key !== 'rotate' && index > 1) {
421
+ unsupportedPropError({ prop: `${key}Z`, value, selector }, { mode })
422
+ }
423
+ return { [`${key}${xyz[index] || ''}`]: v.trim() }
424
+ }))
425
+ break
426
+ }
427
427
  case 'translateZ':
428
428
  case 'scaleZ':
429
429
  default:
@@ -2,6 +2,8 @@ const TAG_NAME = 'movable-view'
2
2
 
3
3
  module.exports = function ({ print }) {
4
4
  const aliEventLog = print({ platform: 'ali', tag: TAG_NAME, isError: false, type: 'event' })
5
+ const androidEventLog = print({ platform: 'android', tag: TAG_NAME, isError: false, type: 'event' })
6
+ const iosEventLog = print({ platform: 'ios', tag: TAG_NAME, isError: false, type: 'event' })
5
7
  const qaPropLog = print({ platform: 'qa', tag: TAG_NAME, isError: false })
6
8
  const androidPropLog = print({ platform: 'android', tag: TAG_NAME, isError: false })
7
9
  const iosPropLog = print({ platform: 'ios', tag: TAG_NAME, isError: false })
@@ -27,7 +29,7 @@ module.exports = function ({ print }) {
27
29
  android: androidPropLog
28
30
  },
29
31
  {
30
- test: /^(inertia|damping|animation)$/,
32
+ test: /^(damping|friction|scale|scale-min|scale-max|scale-value)$/,
31
33
  ios: iosPropLog,
32
34
  android: androidPropLog
33
35
  }
@@ -36,6 +38,11 @@ module.exports = function ({ print }) {
36
38
  {
37
39
  test: /^(htouchmove|vtouchmove)$/,
38
40
  ali: aliEventLog
41
+ },
42
+ {
43
+ test: /^(bindscale)$/,
44
+ ios: iosEventLog,
45
+ android: androidEventLog
39
46
  }
40
47
  ]
41
48
  }
@@ -53,7 +53,7 @@ module.exports = function ({ print }) {
53
53
  qa: qaPropLog
54
54
  },
55
55
  {
56
- test: /^(scroll-into-view|refresher-threshold|enable-passive|scroll-anchoring|using-sticky|fast-deceleration|enable-flex)$/,
56
+ test: /^(refresher-threshold|enable-passive|scroll-anchoring|using-sticky|fast-deceleration|enable-flex)$/,
57
57
  android: androidPropLog,
58
58
  ios: iosPropLog
59
59
  },
@@ -34,6 +34,7 @@ module.exports = class AddEnvPlugin {
34
34
  if (!extname || !matchCondition(resourcePath, this.fileConditionRules)) return callback()
35
35
  const queryObj = parseQuery(request.query || '?')
36
36
  queryObj.infix = `${queryObj.infix || ''}.${env}`
37
+ // css | stylus | less | sass 中 import file 过滤query,避免在对应的 loader 中无法读取到文件
37
38
  obj.query = stringifyQuery(queryObj)
38
39
  obj.path = addInfix(resourcePath, env, extname)
39
40
  obj.relativePath = request.relativePath && addInfix(request.relativePath, env, extname)
@@ -43,6 +43,7 @@ module.exports = class AddModePlugin {
43
43
  resolver.doResolve(target, Object.assign({}, request, obj), 'add mode: ' + mode, resolveContext, (err, result) => {
44
44
  if (defaultMode && !result) {
45
45
  queryObj.infix = `${queryInfix || ''}.${defaultMode}`
46
+ // css | stylus | less | sass 中 import file 过滤query,避免在对应的 loader 中无法读取到文件
46
47
  obj.query = stringifyQuery(queryObj)
47
48
  obj.path = addInfix(resourcePath, defaultMode, extname)
48
49
  resolver.doResolve(target, Object.assign({}, request, obj), 'add mode: ' + defaultMode, resolveContext, (err, result) => {
@@ -33,6 +33,10 @@ export interface IntersectionObserver {
33
33
  }
34
34
  }
35
35
 
36
+ export interface ScrollViewContextValue {
37
+ gestureRef: React.RefObject<any> | null
38
+ }
39
+
36
40
  export const MovableAreaContext = createContext({ width: 0, height: 0 })
37
41
 
38
42
  export const FormContext = createContext<FormContextValue | null>(null)
@@ -51,4 +55,8 @@ export const IntersectionObserverContext = createContext<IntersectionObserver |
51
55
 
52
56
  export const RouteContext = createContext<number | null>(null)
53
57
 
58
+ export const SwiperContext = createContext({})
59
+
54
60
  export const KeyboardAvoidContext = createContext<KeyboardAvoidContextValue | null>(null)
61
+
62
+ export const ScrollViewContext = createContext<ScrollViewContextValue>({ gestureRef: null })
@@ -8,4 +8,6 @@ export const PickerContext = createContext(null);
8
8
  export const VarContext = createContext({});
9
9
  export const IntersectionObserverContext = createContext(null);
10
10
  export const RouteContext = createContext(null);
11
+ export const SwiperContext = createContext({});
11
12
  export const KeyboardAvoidContext = createContext(null);
13
+ export const ScrollViewContext = createContext({ gestureRef: null });
@@ -213,7 +213,6 @@ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], r
213
213
  const eventConfig = {};
214
214
  const config = rawConfig || {
215
215
  layoutRef: { current: {} },
216
- disableTouch: false,
217
216
  disableTap: false
218
217
  };
219
218
  const removeProps = [
@@ -237,10 +236,10 @@ const useInnerProps = (props = {}, additionalProps = {}, userRemoveProps = [], r
237
236
  rawEventKeys.push(key);
238
237
  }
239
238
  }
240
- if (!rawEventKeys.length || config.disableTouch) {
241
- return omit(propsRef.current, removeProps);
242
- }
243
239
  const events = useMemo(() => {
240
+ if (!rawEventKeys.length) {
241
+ return {};
242
+ }
244
243
  const transformedEventKeys = rawEventKeys.reduce((acc, key) => {
245
244
  if (propsRef.current[key]) {
246
245
  return acc.concat(eventConfig[key]);
@@ -54,7 +54,7 @@ const keyboardTypeMap = {
54
54
  }) || ''
55
55
  };
56
56
  const Input = forwardRef((props, ref) => {
57
- const { style = {}, allowFontScaling = false, type = 'text', value, password, 'placeholder-style': placeholderStyle, disabled, maxlength = 140, 'auto-focus': autoFocus, focus, 'confirm-type': confirmType = 'done', 'confirm-hold': confirmHold = false, cursor, 'cursor-color': cursorColor, 'selection-start': selectionStart = -1, 'selection-end': selectionEnd = -1, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'adjust-position': adjustPosition = true, bindinput, bindfocus, bindblur, bindconfirm, bindselectionchange,
57
+ const { style = {}, allowFontScaling = false, type = 'text', value, password, 'placeholder-style': placeholderStyle, disabled, maxlength = 140, 'auto-focus': autoFocus, focus, 'confirm-type': confirmType = 'done', 'confirm-hold': confirmHold = false, cursor, 'cursor-color': cursorColor, 'selection-start': selectionStart = -1, 'selection-end': selectionEnd = -1, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'adjust-position': adjustPosition = false, bindinput, bindfocus, bindblur, bindconfirm, bindselectionchange,
58
58
  // private
59
59
  multiline, 'auto-height': autoHeight, bindlinechange } = props;
60
60
  const formContext = useContext(FormContext);
@@ -11,7 +11,7 @@
11
11
  * ✘ scale-min
12
12
  * ✘ scale-max
13
13
  * ✘ scale-value
14
- * animation
14
+ * animation
15
15
  * ✔ bindchange
16
16
  * ✘ bindscale
17
17
  * ✔ htouchmove
@@ -1,8 +1,7 @@
1
1
  import React, { forwardRef, useRef, useState, useMemo, useEffect, useCallback } from 'react';
2
- import { Platform, SafeAreaView, StyleSheet } from 'react-native';
2
+ import { SafeAreaView, StyleSheet } from 'react-native';
3
3
  import Reanimated, { useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated';
4
- import { vibrateShort } from '@mpxjs/api-proxy';
5
- import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious } from './utils';
4
+ import { useTransformStyle, splitStyle, splitProps, useLayout, usePrevious, isAndroid } from './utils';
6
5
  import useNodesRef from './useNodesRef';
7
6
  import PickerOverlay from './pickerViewOverlay';
8
7
  import PickerMask from './pickerViewMask';
@@ -39,13 +38,13 @@ const _PickerViewColumn = forwardRef((props, ref) => {
39
38
  setHeight,
40
39
  nodeRef: scrollViewRef
41
40
  });
42
- // console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length)
41
+ // console.log('[mpx-picker-view-column], render ---> columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'columnData=', columnData.length, 'pickerH=', pickerH, 'itemRawH=', itemRawH, 'itemHeight=', itemHeight)
43
42
  // const initialOffset = useMemo(() => ({
44
43
  // x: 0,
45
44
  // y: itemRawH * initialIndex
46
45
  // }), [itemRawH])
46
+ const paddingHeight = useMemo(() => Math.round((pickerH - itemHeight) / 2), [pickerH, itemHeight]);
47
47
  const snapToOffsets = useMemo(() => columnData.map((_, i) => i * itemRawH), [columnData, itemRawH]);
48
- const paddingHeight = useMemo(() => Math.round((pickerH - itemRawH) / 2), [pickerH, itemRawH]);
49
48
  const contentContainerStyle = useMemo(() => {
50
49
  return [{ paddingVertical: paddingHeight }];
51
50
  }, [paddingHeight]);
@@ -54,6 +53,7 @@ const _PickerViewColumn = forwardRef((props, ref) => {
54
53
  return Math.max(0, Math.min(calc, maxIndex));
55
54
  }, [itemRawH, maxIndex]);
56
55
  useEffect(() => {
56
+ // console.log('[mpx-picker-view-column], useEffect000 --->', 'columnIndex=', columnIndex, 'initialIndex=', initialIndex, 'prevIndex=', prevIndex, 'activeIndex=', activeIndex.current, 'maxIndex=', maxIndex, 'prevMaxIndex=', prevMaxIndex)
57
57
  if (!scrollViewRef.current ||
58
58
  !itemRawH ||
59
59
  touching.current ||
@@ -71,12 +71,12 @@ const _PickerViewColumn = forwardRef((props, ref) => {
71
71
  y: itemRawH * initialIndex,
72
72
  animated: false
73
73
  });
74
- }, 0);
74
+ }, isAndroid ? 200 : 0);
75
75
  activeIndex.current = initialIndex;
76
76
  }, [itemRawH, initialIndex]);
77
77
  const onContentSizeChange = (_w, h) => {
78
78
  const y = itemRawH * initialIndex;
79
- // console.log('[mpx-picker-view-column], onContentSizeChange --->', 'columnIndex=', columnIndex, '_w=', _w, 'h=', h, 'y=', y)
79
+ // console.log('[mpx-picker-view-column], onContentSizeChange --->', 'columnIndex=', columnIndex, '_w=', _w, 'h=', h, 'y=', y, 'itemRawH=', itemRawH)
80
80
  if (y <= h) {
81
81
  setTimeout(() => {
82
82
  scrollViewRef.current?.scrollTo({ x: 0, y, animated: false });
@@ -84,9 +84,13 @@ const _PickerViewColumn = forwardRef((props, ref) => {
84
84
  }
85
85
  };
86
86
  const onScrollViewLayout = (e) => {
87
+ if (isAndroid) {
88
+ return;
89
+ }
90
+ // RN iOS bug: https://github.com/facebook/react-native/issues/36135
87
91
  const { width } = e.nativeEvent.layout;
88
92
  const widthInt = Math.ceil(width);
89
- // console.log('[mpx-picker-view-column], onScrollViewLayout --->', 'columnIndex=', columnIndex, 'widthInt=', widthInt, 'scrollViewWidth=', scrollViewWidth)
93
+ // console.log('[mpx-picker-view-column], onScrollViewLayout --->', 'columnIndex=', columnIndex, 'width=', width, 'widthInt=', widthInt, 'scrollViewWidth=', scrollViewWidth)
90
94
  if (widthInt !== scrollViewWidth) {
91
95
  const maxW = maxScrollViewWidth.current;
92
96
  if (maxW !== -1 && widthInt > maxW) {
@@ -103,6 +107,7 @@ const _PickerViewColumn = forwardRef((props, ref) => {
103
107
  };
104
108
  const onItemLayout = (e) => {
105
109
  const { height: rawH } = e.nativeEvent.layout;
110
+ // console.log('[mpx-picker-view-column], onItemLayout --->', 'columnIndex=', columnIndex, 'width=', width)
106
111
  if (rawH && itemRawH !== rawH) {
107
112
  setItemRawH(rawH);
108
113
  }
@@ -137,7 +142,12 @@ const _PickerViewColumn = forwardRef((props, ref) => {
137
142
  }
138
143
  };
139
144
  const onScroll = (e) => {
140
- if (Platform.OS === 'android') {
145
+ if (isAndroid) {
146
+ return;
147
+ }
148
+ // 全局注册的震动触感 hook
149
+ const pickerVibrate = global.__mpx.config.rnConfig.pickerVibrate;
150
+ if (typeof pickerVibrate !== 'function') {
141
151
  return;
142
152
  }
143
153
  const { y } = e.nativeEvent.contentOffset;
@@ -150,7 +160,8 @@ const _PickerViewColumn = forwardRef((props, ref) => {
150
160
  index: currentId,
151
161
  y: currentId * itemRawH
152
162
  };
153
- vibrateShort({ type: 'selection' });
163
+ // vibrateShort({ type: 'selection' })
164
+ pickerVibrate();
154
165
  }
155
166
  }
156
167
  }
@@ -45,7 +45,7 @@ const _PickerView = forwardRef((props, ref) => {
45
45
  };
46
46
  const onInitialChange = (isInvalid, value) => {
47
47
  if (isInvalid || !snapActiveValueRef.current || hasDiff(snapActiveValueRef.current, value)) {
48
- console.log('[mpx-picker-view], onInitialChange-1 ===> value=', value);
48
+ console.log('[mpx-picker-view], onInitialChange ===> value=', value);
49
49
  const eventData = getCustomEvent('change', {}, { detail: { value, source: 'change' }, layoutRef });
50
50
  bindchange?.(eventData);
51
51
  snapActiveValueRef.current = value.slice();
@@ -2,10 +2,10 @@
2
2
  * ✔ nodes
3
3
  */
4
4
  import { View } from 'react-native';
5
- import { useRef, forwardRef, useState } from 'react';
5
+ import { useRef, forwardRef, useState, createElement } from 'react';
6
6
  import useInnerProps from '../getInnerListeners';
7
7
  import useNodesRef from '../useNodesRef'; // 引入辅助函数
8
- import { useTransformStyle, useLayout } from '../utils';
8
+ import { useTransformStyle, useLayout, extendObject } from '../utils';
9
9
  import { WebView } from 'react-native-webview';
10
10
  import { generateHTML } from './html';
11
11
  function jsonToHtmlStr(elements) {
@@ -44,20 +44,19 @@ const _RichText = forwardRef((props, ref) => {
44
44
  useNodesRef(props, ref, nodeRef, {
45
45
  layoutRef
46
46
  });
47
- const innerProps = useInnerProps(props, {
47
+ const innerProps = useInnerProps(props, extendObject({
48
48
  ref: nodeRef,
49
- style: { ...normalStyle, ...layoutStyle },
50
- ...layoutProps
51
- }, [], {
49
+ style: extendObject(normalStyle, layoutStyle)
50
+ }, layoutProps), [], {
52
51
  layoutRef
53
52
  });
54
53
  const html = typeof nodes === 'string' ? nodes : jsonToHtmlStr(nodes);
55
- return (<View {...innerProps}>
56
- <WebView source={{ html: generateHTML(html) }} onMessage={(event) => {
54
+ return createElement(View, innerProps, createElement(WebView, {
55
+ source: { html: generateHTML(html) },
56
+ onMessage: (event) => {
57
57
  setWebViewHeight(+event.nativeEvent.data);
58
- }}>
59
- </WebView>
60
- </View>);
58
+ }
59
+ }));
61
60
  });
62
61
  _RichText.displayName = 'mpx-rich-text';
63
62
  export default _RichText;
@@ -33,13 +33,13 @@
33
33
  */
34
34
  import { ScrollView } from 'react-native-gesture-handler';
35
35
  import { RefreshControl } from 'react-native';
36
- import { useRef, useState, useEffect, forwardRef, useContext, createElement } from 'react';
36
+ import { useRef, useState, useEffect, forwardRef, useContext, createElement, useMemo } from 'react';
37
37
  import { useAnimatedRef } from 'react-native-reanimated';
38
38
  import { warn } from '@mpxjs/utils';
39
39
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
40
40
  import useNodesRef from './useNodesRef';
41
41
  import { splitProps, splitStyle, useTransformStyle, useLayout, wrapChildren, extendObject, flatGesture } from './utils';
42
- import { IntersectionObserverContext } from './context';
42
+ import { IntersectionObserverContext, ScrollViewContext } from './context';
43
43
  const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
44
44
  const { textProps, innerProps: props = {} } = splitProps(scrollViewProps);
45
45
  const { enhanced = false, bounces = true, style = {}, binddragstart, binddragging, binddragend, bindtouchstart, bindtouchmove, bindtouchend, 'scroll-x': scrollX = false, 'scroll-y': scrollY = false, 'enable-back-to-top': enableBackToTop = false, 'enable-trigger-intersection-observer': enableTriggerIntersectionObserver = 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, 'show-scrollbar': showScrollbar = true, 'scroll-into-view': scrollIntoView = '', 'scroll-top': scrollTop = 0, 'scroll-left': scrollLeft = 0, 'refresher-triggered': refresherTriggered, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'simultaneous-handlers': originSimultaneousHandlers, 'wait-for': waitFor, __selectRef } = props;
@@ -78,6 +78,11 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
78
78
  },
79
79
  gestureRef: scrollViewRef
80
80
  });
81
+ const contextValue = useMemo(() => {
82
+ return {
83
+ gestureRef: scrollViewRef
84
+ };
85
+ }, []);
81
86
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout });
82
87
  if (scrollX && scrollY) {
83
88
  warn('scroll-x and scroll-y cannot be set to true at the same time, Mpx will use the value of scroll-y as the criterion');
@@ -342,12 +347,12 @@ const _ScrollView = forwardRef((scrollViewProps = {}, ref) => {
342
347
  onRefresh: onRefresh
343
348
  }, (refresherDefaultStyle && refresherDefaultStyle !== 'none' ? { colors: refreshColor[refresherDefaultStyle] } : null)))
344
349
  : undefined
345
- }), wrapChildren(props, {
350
+ }), createElement(ScrollViewContext.Provider, { value: contextValue }, wrapChildren(props, {
346
351
  hasVarDec,
347
352
  varContext: varContextRef.current,
348
353
  textStyle,
349
354
  textProps
350
- }));
355
+ })));
351
356
  });
352
357
  _ScrollView.displayName = 'MpxScrollView';
353
358
  export default _ScrollView;
@@ -1,10 +1,15 @@
1
- import { View } from 'react-native';
2
- import { forwardRef, useRef } from 'react';
1
+ import Animated, { useAnimatedStyle, interpolate } from 'react-native-reanimated';
2
+ import { forwardRef, useRef, useContext } from 'react';
3
3
  import useInnerProps from './getInnerListeners';
4
4
  import useNodesRef from './useNodesRef'; // 引入辅助函数
5
5
  import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils';
6
+ import { SwiperContext } from './context';
6
7
  const _SwiperItem = forwardRef((props, ref) => {
7
- const { 'enable-var': enableVar, 'external-var-context': externalVarContext, style } = props;
8
+ const { 'enable-var': enableVar, 'external-var-context': externalVarContext, style, customStyle, itemIndex } = props;
9
+ const contextValue = useContext(SwiperContext);
10
+ const offset = contextValue.offset || 0;
11
+ const step = contextValue.step || 0;
12
+ const scale = contextValue.scale || false;
8
13
  const { textProps } = splitProps(props);
9
14
  const nodeRef = useRef(null);
10
15
  const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
@@ -16,21 +21,33 @@ const _SwiperItem = forwardRef((props, ref) => {
16
21
  // 存储layout布局信息
17
22
  layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: nodeRef });
18
23
  const innerProps = useInnerProps(props, {
19
- style: { ...innerStyle, ...layoutStyle },
20
24
  ref: nodeRef,
21
25
  ...layoutProps
22
26
  }, [
23
27
  'children',
24
- 'enable-offset'
28
+ 'enable-offset',
29
+ 'style'
25
30
  ], { layoutRef });
26
- return (<View data-itemId={props['item-id']} {...innerProps}>
27
- {wrapChildren(props, {
31
+ const itemAnimatedStyle = useAnimatedStyle(() => {
32
+ if (!step.value)
33
+ return {};
34
+ const inputRange = [step.value, 0];
35
+ const outputRange = [0.7, 1];
36
+ return {
37
+ transform: [{
38
+ scale: interpolate(Math.abs(Math.abs(offset.value) - itemIndex * step.value), inputRange, outputRange)
39
+ }]
40
+ };
41
+ });
42
+ const mergeStyle = [innerStyle, layoutStyle, { width: '100%', height: '100%' }, scale ? itemAnimatedStyle : {}].concat(customStyle);
43
+ return (<Animated.View {...innerProps} style={mergeStyle} data-itemId={props['item-id']}>
44
+ {wrapChildren(props, {
28
45
  hasVarDec,
29
46
  varContext: varContextRef.current,
30
47
  textStyle,
31
48
  textProps
32
49
  })}
33
- </View>);
50
+ </Animated.View>);
34
51
  });
35
52
  _SwiperItem.displayName = 'MpxSwiperItem';
36
53
  export default _SwiperItem;