@mpxjs/webpack-plugin 2.10.2 → 2.10.3

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 (34) hide show
  1. package/lib/dependencies/RecordPageConfigsMapDependency.js +45 -0
  2. package/lib/index.js +12 -0
  3. package/lib/platform/style/wx/index.js +6 -4
  4. package/lib/platform/template/wx/component-config/view.js +12 -2
  5. package/lib/react/index.js +0 -1
  6. package/lib/react/processJSON.js +13 -2
  7. package/lib/react/processScript.js +4 -2
  8. package/lib/react/processTemplate.js +18 -3
  9. package/lib/react/script-helper.js +18 -4
  10. package/lib/runtime/components/react/dist/mpx-input.jsx +1 -11
  11. package/lib/runtime/components/react/dist/{KeyboardAvoidingView.jsx → mpx-keyboard-avoiding-view.jsx} +4 -3
  12. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +1 -2
  13. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +10 -5
  14. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +22 -0
  15. package/lib/runtime/components/react/dist/mpx-view.jsx +10 -5
  16. package/lib/runtime/components/react/dist/mpx-web-view.jsx +2 -2
  17. package/lib/runtime/components/react/dist/useAnimationHooks.js +46 -48
  18. package/lib/runtime/components/react/dist/utils.jsx +17 -7
  19. package/lib/runtime/components/react/mpx-input.tsx +1 -19
  20. package/lib/runtime/components/react/{KeyboardAvoidingView.tsx → mpx-keyboard-avoiding-view.tsx} +4 -2
  21. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +1 -2
  22. package/lib/runtime/components/react/mpx-scroll-view.tsx +13 -4
  23. package/lib/runtime/components/react/mpx-simple-view.tsx +32 -0
  24. package/lib/runtime/components/react/mpx-view.tsx +17 -10
  25. package/lib/runtime/components/react/mpx-web-view.tsx +7 -7
  26. package/lib/runtime/components/react/types/getInnerListeners.d.ts +1 -1
  27. package/lib/runtime/components/react/useAnimationHooks.ts +46 -48
  28. package/lib/runtime/components/react/utils.tsx +21 -10
  29. package/lib/runtime/optionProcessor.js +3 -2
  30. package/lib/style-compiler/index.js +8 -6
  31. package/lib/template-compiler/compiler.js +20 -12
  32. package/lib/utils/match-condition.js +14 -8
  33. package/lib/web/processJSON.js +1 -3
  34. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useMemo, useRef } from 'react';
2
2
  import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation } from 'react-native-reanimated';
3
- import { error } from '@mpxjs/utils';
3
+ import { error, hasOwn } from '@mpxjs/utils';
4
4
  // 微信 timingFunction 和 RN Easing 对应关系
5
5
  const EasingKey = {
6
6
  linear: Easing.linear,
@@ -14,20 +14,20 @@ const EasingKey = {
14
14
  const TransformInitial = {
15
15
  // matrix: 0,
16
16
  // matrix3d: 0,
17
- rotate: '0deg',
17
+ // rotate: '0deg',
18
18
  rotateX: '0deg',
19
19
  rotateY: '0deg',
20
20
  rotateZ: '0deg',
21
21
  // rotate3d:[0,0,0]
22
- scale: 1,
22
+ // scale: 1,
23
23
  // scale3d: [1, 1, 1],
24
24
  scaleX: 1,
25
25
  scaleY: 1,
26
26
  // scaleZ: 1,
27
- skew: 0,
27
+ // skew: 0,
28
28
  skewX: '0deg',
29
29
  skewY: '0deg',
30
- translate: 0,
30
+ // translate: 0,
31
31
  // translate3d: 0,
32
32
  translateX: 0,
33
33
  translateY: 0
@@ -92,23 +92,23 @@ const parseTransform = (transformStr) => {
92
92
  case 'skewX':
93
93
  case 'skewY':
94
94
  case 'perspective':
95
+ // rotate 处理成 rotateZ
96
+ key = key === 'rotate' ? 'rotateZ' : key;
95
97
  // 单个值处理
96
98
  transform.push({ [key]: global.__formatValue(val) });
97
99
  break;
98
100
  case 'matrix':
99
- case 'matrix3d':
100
101
  transform.push({ [key]: parseValues(val, ',').map(val => +val) });
101
102
  break;
102
103
  case 'translate':
103
104
  case 'scale':
104
105
  case 'skew':
105
- case 'rotate3d': // x y z angle
106
106
  case 'translate3d': // x y 支持 z不支持
107
107
  case 'scale3d': // x y 支持 z不支持
108
108
  {
109
109
  // 2 个以上的值处理
110
110
  key = key.replace('3d', '');
111
- const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3);
111
+ const vals = parseValues(val, ',').splice(0, 3);
112
112
  // scale(.5) === scaleX(.5) scaleY(.5)
113
113
  if (vals.length === 1 && key === 'scale') {
114
114
  vals.push(vals[0]);
@@ -132,6 +132,13 @@ const formatStyle = (style) => {
132
132
  transform: parseTransform(style.transform)
133
133
  });
134
134
  };
135
+ // transform 数组转对象
136
+ function getTransformObj(transforms) {
137
+ 'worklet';
138
+ return transforms.reduce((transformObj, item) => {
139
+ return Object.assign(transformObj, item);
140
+ }, {});
141
+ }
135
142
  export default function useAnimationHooks(props) {
136
143
  const { style = {}, animation, enableAnimation } = props;
137
144
  const enableStyleAnimation = enableAnimation || !!animation;
@@ -150,7 +157,9 @@ export default function useAnimationHooks(props) {
150
157
  // 记录动画key的style样式值 没有的话设置为false
151
158
  // eslint-disable-next-line react-hooks/rules-of-hooks
152
159
  const animatedKeys = useRef({});
153
- // const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
160
+ // 记录上次style map
161
+ // eslint-disable-next-line react-hooks/rules-of-hooks
162
+ const lastStyleRef = useRef({});
154
163
  // ** 全量 style prop sharedValue
155
164
  // 不能做增量的原因:
156
165
  // 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
@@ -163,6 +172,12 @@ export default function useAnimationHooks(props) {
163
172
  return valMap;
164
173
  }, {});
165
174
  }, []);
175
+ // ** style更新同步
176
+ // eslint-disable-next-line react-hooks/rules-of-hooks
177
+ useEffect(() => {
178
+ // style 更新后同步更新 lastStyleRef & shareValMap
179
+ updateStyleVal();
180
+ }, [style]);
166
181
  // ** 获取动画样式prop & 驱动动画
167
182
  // eslint-disable-next-line react-hooks/rules-of-hooks
168
183
  useEffect(() => {
@@ -175,16 +190,6 @@ export default function useAnimationHooks(props) {
175
190
  // 驱动动画
176
191
  createAnimation(keys);
177
192
  }, [id]);
178
- // 同步style更新
179
- // useEffect(() => {
180
- // Object.keys(animatedKeys.current).forEach(key => {
181
- // const originVal = getOriginalStyleVal(key, isTransform(key))
182
- // if (originVal && animatedKeys.current[key] !== originVal) {
183
- // animatedKeys.current[key] = originVal
184
- // shareValMap[key].value = originVal
185
- // }
186
- // })
187
- // }, [style])
188
193
  // ** 清空动画
189
194
  // eslint-disable-next-line react-hooks/rules-of-hooks
190
195
  useEffect(() => {
@@ -194,7 +199,7 @@ export default function useAnimationHooks(props) {
194
199
  });
195
200
  };
196
201
  }, []);
197
- // 根据 animation action 创建&驱动动画 key => wi
202
+ // 根据 animation action 创建&驱动动画
198
203
  function createAnimation(animatedKeys = []) {
199
204
  const actions = animation?.actions || [];
200
205
  const sequence = {};
@@ -251,6 +256,7 @@ export default function useAnimationHooks(props) {
251
256
  : withTiming(value, { duration, easing });
252
257
  return delay ? withDelay(delay, animation) : animation;
253
258
  }
259
+ // 获取样式初始值(prop style or 默认值)
254
260
  function getInitialVal(key, isTransform = false) {
255
261
  if (isTransform && Array.isArray(originalStyle.transform)) {
256
262
  let initialVal = InitialValue[key];
@@ -263,31 +269,12 @@ export default function useAnimationHooks(props) {
263
269
  }
264
270
  return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key];
265
271
  }
266
- // 从 prop style 中获取样式初始值 没有为undefined
267
- // function getOriginalStyleVal (key: keyof ExtendedViewStyle, isTransform = false) {
268
- // if (isTransform && Array.isArray(originalStyle.transform)) {
269
- // let initialVal = undefined // InitialValue[key]
270
- // // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
271
- // originalStyle.transform.forEach(item => {
272
- // if (item[key] !== undefined) initialVal = item[key]
273
- // })
274
- // return initialVal
275
- // }
276
- // return originalStyle[key] // === undefined ? InitialValue[key] : originalStyle[key]
277
- // }
278
- // 获取动画shareVal初始值(prop style or 默认值)
279
- // function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
280
- // const originalVal = getOriginalStyleVal(key, isTransform)
281
- // return originalVal === undefined ? InitialValue[key] : originalStyle[key]
282
- // }
283
272
  // 循环 animation actions 获取所有有动画的 style prop name
284
273
  function getAnimatedStyleKeys() {
285
274
  return (animation?.actions || []).reduce((keyMap, action) => {
286
275
  const { rules, transform } = action;
287
276
  const ruleArr = [...rules.keys(), ...transform.keys()];
288
277
  ruleArr.forEach(key => {
289
- // const originalVal = getOriginalStyleVal(key, isTransform(key))
290
- // if (!keyMap[key]) keyMap[key] = originalVal === undefined ? false : originalVal
291
278
  if (!keyMap[key])
292
279
  keyMap[key] = true;
293
280
  });
@@ -295,7 +282,7 @@ export default function useAnimationHooks(props) {
295
282
  }, animatedKeys.current);
296
283
  }
297
284
  // animated key transform 格式化
298
- function formatAnimatedKeys(keys = []) {
285
+ function formatAnimatedKeys(keys) {
299
286
  const animatedKeys = [];
300
287
  const transforms = [];
301
288
  keys.forEach(key => {
@@ -310,13 +297,24 @@ export default function useAnimationHooks(props) {
310
297
  animatedKeys.push(transforms);
311
298
  return animatedKeys;
312
299
  }
313
- // transform 数组转对象
314
- function getTransformObj() {
315
- 'worklet';
316
- const transforms = originalStyle.transform || [];
317
- return transforms.reduce((transformObj, item) => {
318
- return Object.assign(transformObj, item);
319
- }, {});
300
+ // 设置 lastShareValRef & shareValMap
301
+ function updateStyleVal() {
302
+ Object.entries(originalStyle).forEach(([key, value]) => {
303
+ if (key === 'transform') {
304
+ Object.entries(getTransformObj(value)).forEach(([key, value]) => {
305
+ if (value !== lastStyleRef.current[key]) {
306
+ lastStyleRef.current[key] = value;
307
+ shareValMap[key].value = value;
308
+ }
309
+ });
310
+ }
311
+ else if (hasOwn(shareValMap, key)) {
312
+ if (value !== lastStyleRef.current[key]) {
313
+ lastStyleRef.current[key] = value;
314
+ shareValMap[key].value = value;
315
+ }
316
+ }
317
+ });
320
318
  }
321
319
  // ** 生成动画样式
322
320
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -325,7 +323,7 @@ export default function useAnimationHooks(props) {
325
323
  return animatedStyleKeys.value.reduce((styles, key) => {
326
324
  // console.info('getAnimationStyles', key, shareValMap[key].value)
327
325
  if (Array.isArray(key)) {
328
- const transformStyle = getTransformObj();
326
+ const transformStyle = getTransformObj(originalStyle.transform || []);
329
327
  key.forEach((transformKey) => {
330
328
  transformStyle[transformKey] = shareValMap[transformKey].value;
331
329
  });
@@ -239,12 +239,8 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
239
239
  const normalStyleChangedRef = useRef(false);
240
240
  let hasVarDec = false;
241
241
  let hasVarUse = false;
242
- let hasSelfPercent = false;
243
242
  const varKeyPaths = [];
244
243
  const unoVarKeyPaths = [];
245
- const percentKeyPaths = [];
246
- const calcKeyPaths = [];
247
- const envKeyPaths = [];
248
244
  const [width, setWidth] = useState(0);
249
245
  const [height, setHeight] = useState(0);
250
246
  const navigation = useNavigation();
@@ -304,6 +300,11 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
304
300
  normalStyleChangedRef.current = !normalStyleChangedRef.current;
305
301
  }
306
302
  const memoResult = useMemo(() => {
303
+ let hasSelfPercent = false;
304
+ let hasPositionFixed = false;
305
+ const percentKeyPaths = [];
306
+ const calcKeyPaths = [];
307
+ const envKeyPaths = [];
307
308
  // transform can be memoized
308
309
  function envVisitor({ value, keyPath }) {
309
310
  if (envUseRegExp.test(value)) {
@@ -324,6 +325,12 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
324
325
  percentKeyPaths.push(keyPath.slice());
325
326
  }
326
327
  }
328
+ function transformPosition(styleObj) {
329
+ if (styleObj.position === 'fixed') {
330
+ hasPositionFixed = true;
331
+ styleObj.position = 'absolute';
332
+ }
333
+ }
327
334
  // traverse env & calc & percent
328
335
  traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor]);
329
336
  const percentConfig = {
@@ -355,11 +362,14 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
355
362
  }
356
363
  }
357
364
  });
365
+ // apply position
366
+ transformPosition(normalStyle);
358
367
  // transform number enum stringify
359
368
  transformStringify(normalStyle);
360
369
  return {
361
370
  normalStyle,
362
- hasSelfPercent
371
+ hasSelfPercent,
372
+ hasPositionFixed
363
373
  };
364
374
  }, [normalStyleChangedRef.current, width, height, parentWidth, parentHeight, parentFontSize]);
365
375
  return extendObject({
@@ -434,8 +444,8 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
434
444
  hasLayoutRef.current = true;
435
445
  if (hasSelfPercent) {
436
446
  const { width, height } = e?.nativeEvent?.layout || {};
437
- setWidth(width || 0);
438
- setHeight(height || 0);
447
+ setWidth && setWidth(width || 0);
448
+ setHeight && setHeight(height || 0);
439
449
  }
440
450
  if (enableOffset) {
441
451
  nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
@@ -324,23 +324,6 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
324
324
  )
325
325
  }
326
326
 
327
- const onKeyPress = (evt: NativeSyntheticEvent<TextInputKeyPressEventData>) => {
328
- evt.nativeEvent.key === 'Enter' &&
329
- bindconfirm!(
330
- getCustomEvent(
331
- 'confirm',
332
- evt,
333
- {
334
- detail: {
335
- value: tmpValue.current || ''
336
- },
337
- layoutRef
338
- },
339
- props
340
- )
341
- )
342
- }
343
-
344
327
  const onSubmitEditing = (evt: NativeSyntheticEvent<TextInputSubmitEditingEventData>) => {
345
328
  bindconfirm!(
346
329
  getCustomEvent(
@@ -474,8 +457,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
474
457
  onChange,
475
458
  onSelectionChange,
476
459
  onContentSizeChange,
477
- onKeyPress: bindconfirm && onKeyPress,
478
- onSubmitEditing: bindconfirm && multiline && onSubmitEditing
460
+ onSubmitEditing: bindconfirm && !multiline && onSubmitEditing
479
461
  }
480
462
  ),
481
463
  [
@@ -26,8 +26,8 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
26
26
  const gesture = useMemo(() => {
27
27
  return Gesture.Tap()
28
28
  .onEnd(() => {
29
- runOnJS(dismiss)()
30
- })
29
+ dismiss()
30
+ }).runOnJS(true)
31
31
  }, [])
32
32
 
33
33
  const animatedStyle = useAnimatedStyle(() => {
@@ -117,4 +117,6 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }: Keyboa
117
117
  )
118
118
  }
119
119
 
120
+ KeyboardAvoidingView.displayName = 'MpxKeyboardAvoidingView'
121
+
120
122
  export default KeyboardAvoidingView
@@ -1,6 +1,5 @@
1
1
  import { useState, useCallback, forwardRef, ForwardedRef, useImperativeHandle, ReactNode, ReactElement } from 'react'
2
2
  import { View, StyleSheet } from 'react-native'
3
- import { extendObject } from '../utils'
4
3
 
5
4
  export type State = {
6
5
  portals: Array<{
@@ -27,7 +26,7 @@ const _PortalManager = forwardRef((props: PortalManagerProps, ref:ForwardedRef<u
27
26
  setState((prevState) => ({
28
27
  portals: prevState.portals.map((item) => {
29
28
  if (item.key === key) {
30
- return extendObject({}, item, { children })
29
+ return Object.assign({}, item, { children })
31
30
  }
32
31
  return item
33
32
  })
@@ -70,6 +70,7 @@ interface ScrollViewProps {
70
70
  'parent-height'?: number;
71
71
  'wait-for'?: Array<GestureHandler>;
72
72
  'simultaneous-handlers'?: Array<GestureHandler>;
73
+ 'scroll-event-throttle'?:number;
73
74
  bindscrolltoupper?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
74
75
  bindscrolltolower?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
75
76
  bindscroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
@@ -140,6 +141,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
140
141
  'parent-height': parentHeight,
141
142
  'simultaneous-handlers': originSimultaneousHandlers,
142
143
  'wait-for': waitFor,
144
+ 'scroll-event-throttle': scrollEventThrottle = 0,
143
145
  __selectRef
144
146
  } = props
145
147
 
@@ -159,7 +161,6 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
159
161
  visibleLength: 0
160
162
  })
161
163
 
162
- const scrollEventThrottle = 50
163
164
  const hasCallScrollToUpper = useRef(true)
164
165
  const hasCallScrollToLower = useRef(false)
165
166
  const initialTimeout = useRef<ReturnType<typeof setTimeout> | null>(null)
@@ -202,6 +203,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
202
203
 
203
204
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
204
205
 
206
+ const lastOffset = useRef(0)
207
+
205
208
  if (scrollX && scrollY) {
206
209
  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')
207
210
  }
@@ -263,7 +266,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
263
266
  function onStartReached (e: NativeSyntheticEvent<NativeScrollEvent>) {
264
267
  const { bindscrolltoupper } = props
265
268
  const { offset } = scrollOptions.current
266
- if (bindscrolltoupper && (offset <= upperThreshold)) {
269
+ const isScrollingBackward = offset < lastOffset.current
270
+ if (bindscrolltoupper && (offset <= upperThreshold) && isScrollingBackward) {
267
271
  if (!hasCallScrollToUpper.current) {
268
272
  bindscrolltoupper(
269
273
  getCustomEvent('scrolltoupper', e, {
@@ -284,13 +288,15 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
284
288
  const { bindscrolltolower } = props
285
289
  const { contentLength, visibleLength, offset } = scrollOptions.current
286
290
  const distanceFromEnd = contentLength - visibleLength - offset
287
- if (bindscrolltolower && (distanceFromEnd < lowerThreshold)) {
291
+ const isScrollingForward = offset > lastOffset.current
292
+
293
+ if (bindscrolltolower && (distanceFromEnd < lowerThreshold) && isScrollingForward) {
288
294
  if (!hasCallScrollToLower.current) {
289
295
  hasCallScrollToLower.current = true
290
296
  bindscrolltolower(
291
297
  getCustomEvent('scrolltolower', e, {
292
298
  detail: {
293
- direction: scrollX ? 'right' : 'botttom'
299
+ direction: scrollX ? 'right' : 'bottom'
294
300
  },
295
301
  layoutRef
296
302
  }, props)
@@ -345,6 +351,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
345
351
  onStartReached(e)
346
352
  onEndReached(e)
347
353
  updateIntersection()
354
+ // 在 onStartReached、onEndReached 执行完后更新 lastOffset
355
+ lastOffset.current = scrollOptions.current.offset
348
356
  }
349
357
 
350
358
  function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
@@ -367,6 +375,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
367
375
  onStartReached(e)
368
376
  onEndReached(e)
369
377
  updateIntersection()
378
+ lastOffset.current = scrollOptions.current.offset
370
379
  }
371
380
  function updateIntersection () {
372
381
  if (enableTriggerIntersectionObserver && intersectionObservers) {
@@ -0,0 +1,32 @@
1
+ import { View, ViewProps, TextStyle } from 'react-native'
2
+ import { createElement, forwardRef, useRef } from 'react'
3
+ import useNodesRef, { HandlerRef } from './useNodesRef'
4
+ import { extendObject, splitProps, splitStyle, wrapChildren } from './utils'
5
+
6
+ const _View2 = forwardRef<HandlerRef<View, ViewProps>, ViewProps>((simpleViewProps: ViewProps, ref) => {
7
+ const nodeRef = useRef(null)
8
+
9
+ const { textProps, innerProps: props = {} } = splitProps(simpleViewProps)
10
+
11
+ const { textStyle, innerStyle = {} } = splitStyle(props.style || {})
12
+
13
+ useNodesRef(props, ref, nodeRef, {
14
+ style: innerStyle || {}
15
+ })
16
+
17
+ return createElement(View, extendObject({}, props, {
18
+ style: innerStyle,
19
+ ref: nodeRef
20
+ }), wrapChildren(
21
+ props,
22
+ {
23
+ hasVarDec: false,
24
+ textStyle: textStyle as TextStyle,
25
+ textProps
26
+ }
27
+ ))
28
+ })
29
+
30
+ _View2.displayName = 'MpxSimpleView'
31
+
32
+ export default _View2
@@ -16,6 +16,7 @@ import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wra
16
16
  import { error } from '@mpxjs/utils'
17
17
  import LinearGradient from 'react-native-linear-gradient'
18
18
  import { GestureDetector, PanGesture } from 'react-native-gesture-handler'
19
+ import Portal from './mpx-portal'
19
20
 
20
21
  export interface _ViewProps extends ViewProps {
21
22
  style?: ExtendedViewStyle
@@ -79,7 +80,7 @@ type PreImageInfo = {
79
80
  type ImageProps = {
80
81
  style: ImageStyle,
81
82
  src?: string,
82
- source?: {uri: string },
83
+ source?: { uri: string },
83
84
  colors: Array<string>,
84
85
  locations?: Array<number>
85
86
  angle?: number
@@ -483,8 +484,8 @@ function parseLinearGradient (text: string): LinearInfo | undefined {
483
484
  }
484
485
 
485
486
  function parseBgImage (text: string): {
486
- linearInfo?: LinearInfo;
487
- direction?: string;
487
+ linearInfo?: LinearInfo
488
+ direction?: string
488
489
  type?: 'image' | 'linear'
489
490
  src?: string
490
491
  } {
@@ -578,7 +579,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
578
579
  if (!src) {
579
580
  setShow(false)
580
581
  return
581
- // 一开始未出现,数据改变时出现
582
+ // 一开始未出现,数据改变时出现
582
583
  } else if (!(needLayout || needImageSize)) {
583
584
  setShow(true)
584
585
  return
@@ -602,7 +603,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
602
603
  }
603
604
  })
604
605
  }
605
- // type 添加type 处理无渐变 有渐变的场景
606
+ // type 添加type 处理无渐变 有渐变的场景
606
607
  }, [src, type])
607
608
 
608
609
  if (!type) return null
@@ -636,7 +637,7 @@ function useWrapImage (imageStyle?: ExtendedViewStyle, innerStyle?: Record<strin
636
637
  }
637
638
 
638
639
  return <View key='backgroundImage' {...needLayout ? { onLayout } : null} style={{ ...inheritStyle(innerStyle), ...StyleSheet.absoluteFillObject, overflow: 'hidden' }}>
639
- {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} /> }
640
+ {show && type === 'linear' && <LinearGradient useAngle={true} {...imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size)} />}
640
641
  {show && type === 'image' && (renderImage(imageStyleToProps(preImageInfo, sizeInfo.current as Size, layoutInfo.current as Size), enableFastImage))}
641
642
  </View>
642
643
  }
@@ -703,6 +704,7 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
703
704
  const {
704
705
  normalStyle,
705
706
  hasSelfPercent,
707
+ hasPositionFixed,
706
708
  hasVarDec,
707
709
  varContextRef,
708
710
  setWidth,
@@ -769,13 +771,18 @@ const _View = forwardRef<HandlerRef<View, _ViewProps>, _ViewProps>((viewProps, r
769
771
  enableFastImage
770
772
  })
771
773
 
772
- const BaseComponent = enableStyleAnimation
774
+ let finalComponent: JSX.Element = enableStyleAnimation
773
775
  ? createElement(Animated.View, innerProps, childNode)
774
776
  : createElement(View, innerProps, childNode)
775
777
 
776
- return enableHover
777
- ? createElement(GestureDetector, { gesture: gesture as PanGesture }, BaseComponent)
778
- : BaseComponent
778
+ if (enableHover) {
779
+ finalComponent = createElement(GestureDetector, { gesture: gesture as PanGesture }, finalComponent)
780
+ }
781
+
782
+ if (hasPositionFixed) {
783
+ finalComponent = createElement(Portal, null, finalComponent)
784
+ }
785
+ return finalComponent
779
786
  })
780
787
 
781
788
  _View.displayName = 'MpxView'
@@ -89,7 +89,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
89
89
  button: 'Reload'
90
90
  }
91
91
  }
92
- const currentErrorText = errorText[(mpx.i18n.locale as LanguageCode) || 'zh-CN']
92
+ const currentErrorText = errorText[(mpx.i18n?.locale as LanguageCode) || 'zh-CN']
93
93
 
94
94
  if (props.style) {
95
95
  warn('The web-view component does not support the style prop.')
@@ -103,11 +103,11 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
103
103
  const statusCode = useRef<string|number>('')
104
104
  const [isLoaded, setIsLoaded] = useState<boolean>(true)
105
105
  const defaultWebViewStyle = {
106
- position: 'absolute' as 'absolute' | 'relative' | 'static',
107
- left: 0 as number,
108
- right: 0 as number,
109
- top: 0 as number,
110
- bottom: 0 as number
106
+ position: 'absolute' as const,
107
+ left: 0,
108
+ right: 0,
109
+ top: 0,
110
+ bottom: 0
111
111
  }
112
112
  const canGoBack = useRef<boolean>(false)
113
113
  const isNavigateBack = useRef<boolean>(false)
@@ -329,7 +329,7 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
329
329
  }
330
330
 
331
331
  return (
332
- <Portal key={pageLoadErr ? 'error' : 'webview'}>
332
+ <Portal>
333
333
  {pageLoadErr
334
334
  ? (
335
335
  <View style={[styles.loadErrorContext, defaultWebViewStyle]}>
@@ -46,7 +46,7 @@ interface InnerRef {
46
46
  };
47
47
  }
48
48
  interface UseInnerPropsConfig {
49
- layoutRef: LayoutRef;
49
+ layoutRef?: LayoutRef;
50
50
  disableTouch?: boolean;
51
51
  disableTap?: boolean
52
52
  }