@mpxjs/webpack-plugin 2.10.15-4 → 2.10.15-prelease.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 (45) hide show
  1. package/lib/dependencies/DynamicEntryDependency.js +1 -1
  2. package/lib/dependencies/ImportDependency.js +102 -0
  3. package/lib/{retry-runtime-module.js → dependencies/RetryRuntimeModule.js} +1 -1
  4. package/lib/index.js +13 -15
  5. package/lib/platform/template/wx/component-config/progress.js +12 -0
  6. package/lib/platform/template/wx/component-config/slider.js +12 -0
  7. package/lib/platform/template/wx/component-config/unsupported.js +1 -1
  8. package/lib/platform/template/wx/index.js +3 -1
  9. package/lib/resolver/AddEnvPlugin.js +13 -0
  10. package/lib/resolver/AddModePlugin.js +18 -0
  11. package/lib/runtime/components/react/dist/getInnerListeners.js +35 -21
  12. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +102 -34
  13. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +3 -5
  14. package/lib/runtime/components/react/dist/mpx-progress.jsx +163 -0
  15. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +51 -9
  16. package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
  17. package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -16
  18. package/lib/runtime/components/react/dist/mpx-view.jsx +7 -10
  19. package/lib/runtime/components/react/dist/mpx-web-view.jsx +20 -1
  20. package/lib/runtime/components/react/getInnerListeners.ts +41 -22
  21. package/lib/runtime/components/react/mpx-movable-view.tsx +156 -48
  22. package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +4 -8
  23. package/lib/runtime/components/react/mpx-progress.tsx +259 -0
  24. package/lib/runtime/components/react/mpx-scroll-view.tsx +54 -9
  25. package/lib/runtime/components/react/mpx-slider.tsx +444 -0
  26. package/lib/runtime/components/react/mpx-swiper.tsx +9 -16
  27. package/lib/runtime/components/react/mpx-view.tsx +7 -10
  28. package/lib/runtime/components/react/mpx-web-view.tsx +22 -1
  29. package/lib/runtime/components/react/types/getInnerListeners.d.ts +7 -2
  30. package/lib/runtime/components/web/mpx-input.vue +14 -0
  31. package/lib/runtime/components/web/mpx-movable-area.vue +43 -19
  32. package/lib/runtime/components/web/mpx-movable-view.vue +93 -3
  33. package/lib/runtime/components/web/mpx-scroll-view.vue +7 -1
  34. package/lib/runtime/components/web/mpx-swiper.vue +1 -2
  35. package/lib/runtime/components/web/mpx-video.vue +12 -1
  36. package/lib/runtime/components/web/mpx-web-view.vue +3 -3
  37. package/lib/runtime/optionProcessor.js +3 -1
  38. package/lib/runtime/optionProcessorReact.js +4 -2
  39. package/lib/template-compiler/compiler.js +69 -35
  40. package/lib/utils/chain-assign.js +47 -0
  41. package/lib/utils/check-core-version-match.js +75 -15
  42. package/lib/wxs/pre-loader.js +5 -5
  43. package/lib/wxss/utils.js +1 -1
  44. package/package.json +3 -2
  45. package/lib/dependencies/ImportDependencyTemplate.js +0 -50
@@ -0,0 +1,259 @@
1
+ /**
2
+ * ✔ percent 进度百分比 0-100
3
+ * ✘ show-info 在进度条右侧显示百分比
4
+ * ✘ border-radius 圆角大小
5
+ * ✘ font-size 右侧百分比字体大小
6
+ * ✔ stroke-width 进度条线的宽度
7
+ * ✔ color 进度条颜色(请使用activeColor)
8
+ * ✔ activeColor 已选择的进度条的颜色
9
+ * ✔ backgroundColor 未选择的进度条的颜色
10
+ * ✔ active 进度条从左往右的动画
11
+ * ✔ active-mode backwards: 动画从头播;forwards:动画从上次结束点接着播
12
+ * ✔ duration 进度增加1%所需毫秒数
13
+ * ✔ bindactiveend 动画完成事件
14
+ */
15
+ import {
16
+ JSX,
17
+ useRef,
18
+ forwardRef,
19
+ useEffect,
20
+ useState,
21
+ createElement,
22
+ ForwardedRef
23
+ } from 'react'
24
+ import {
25
+ View,
26
+ ViewStyle
27
+ } from 'react-native'
28
+ import Animated, {
29
+ useSharedValue,
30
+ useAnimatedStyle,
31
+ withTiming,
32
+ Easing,
33
+ runOnJS
34
+ } from 'react-native-reanimated'
35
+
36
+ import useInnerProps from './getInnerListeners'
37
+ import useNodesRef, { HandlerRef } from './useNodesRef'
38
+ import { useLayout, useTransformStyle, extendObject, useRunOnJSCallback } from './utils'
39
+ import Portal from './mpx-portal'
40
+
41
+ export interface ProgressProps {
42
+ percent?: number
43
+ 'stroke-width'?: number | string
44
+ color?: string
45
+ activeColor?: string
46
+ backgroundColor?: string
47
+ active?: boolean
48
+ 'active-mode'?: 'backwards' | 'forwards'
49
+ duration?: number
50
+ bindactiveend?: (event: any) => void
51
+ style?: ViewStyle & Record<string, any>
52
+ 'enable-offset'?: boolean
53
+ 'enable-var'?: boolean
54
+ 'external-var-context'?: Record<string, any>
55
+ 'parent-font-size'?: number
56
+ 'parent-width'?: number
57
+ 'parent-height'?: number
58
+ }
59
+
60
+ const Progress = forwardRef<
61
+ HandlerRef<View, ProgressProps>,
62
+ ProgressProps
63
+ >((props: ProgressProps, ref: ForwardedRef<HandlerRef<View, ProgressProps>>): JSX.Element => {
64
+ const {
65
+ percent = 0,
66
+ 'stroke-width': strokeWidth = 6,
67
+ color,
68
+ activeColor = color || '#09BB07',
69
+ backgroundColor = '#EBEBEB',
70
+ active = false,
71
+ 'active-mode': activeMode = 'backwards',
72
+ duration = 30,
73
+ style = {},
74
+ 'enable-var': enableVar,
75
+ 'external-var-context': externalVarContext,
76
+ 'parent-font-size': parentFontSize,
77
+ 'parent-width': parentWidth,
78
+ 'parent-height': parentHeight
79
+ } = props
80
+
81
+ const nodeRef = useRef(null)
82
+ const propsRef = useRef(props)
83
+ propsRef.current = props
84
+
85
+ // 进度值状态
86
+ const [lastPercent, setLastPercent] = useState(0)
87
+ const progressWidth = useSharedValue(0)
88
+
89
+ const {
90
+ normalStyle,
91
+ hasSelfPercent,
92
+ setWidth,
93
+ setHeight,
94
+ hasPositionFixed
95
+ } = useTransformStyle(style, {
96
+ enableVar,
97
+ externalVarContext,
98
+ parentFontSize,
99
+ parentWidth,
100
+ parentHeight
101
+ })
102
+
103
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({
104
+ props,
105
+ hasSelfPercent,
106
+ setWidth,
107
+ setHeight,
108
+ nodeRef
109
+ })
110
+
111
+ useNodesRef(props, ref, nodeRef, {
112
+ style: normalStyle
113
+ })
114
+
115
+ // 使用 useRunOnJSCallback 处理动画回调
116
+ const runOnJSCallbackRef = useRef({
117
+ triggerActiveEnd: (percent: number) => {
118
+ const currentProps = propsRef.current
119
+ if (currentProps.bindactiveend) {
120
+ currentProps.bindactiveend({
121
+ type: 'activeend',
122
+ detail: {
123
+ percent: percent
124
+ }
125
+ })
126
+ }
127
+ }
128
+ })
129
+ const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
130
+
131
+ // 进度条动画函数
132
+ const startProgressAnimation = (targetPercent: number, startPercent: number, animationDuration: number, onFinished?: () => void) => {
133
+ // 根据 active-mode 设置起始位置
134
+ progressWidth.value = startPercent
135
+ progressWidth.value = withTiming(
136
+ targetPercent,
137
+ {
138
+ duration: animationDuration,
139
+ easing: Easing.linear
140
+ },
141
+ (finished) => {
142
+ if (finished && onFinished) {
143
+ // 在动画回调中,执行传入的worklet函数
144
+ onFinished()
145
+ }
146
+ }
147
+ )
148
+ }
149
+
150
+ // 进度变化时的动画效果
151
+ useEffect(() => {
152
+ const targetPercent = Math.max(0, Math.min(100, percent))
153
+ if (active) {
154
+ // 根据 active-mode 确定起始位置
155
+ let startPercent
156
+ if (activeMode === 'backwards') {
157
+ startPercent = 0
158
+ } else {
159
+ // forwards 模式:使用上次记录的百分比作为起始位置
160
+ startPercent = lastPercent
161
+ }
162
+
163
+ // 计算动画持续时间
164
+ const percentDiff = Math.abs(targetPercent - startPercent)
165
+ const animationDuration = percentDiff * duration
166
+
167
+ // 执行动画
168
+ startProgressAnimation(targetPercent, startPercent, animationDuration, () => {
169
+ 'worklet'
170
+ // 在worklet函数内部执行runOnJS调用runOnJSCallback
171
+ runOnJS(runOnJSCallback)('triggerActiveEnd', targetPercent)
172
+ })
173
+ } else {
174
+ progressWidth.value = targetPercent
175
+ }
176
+
177
+ setLastPercent(targetPercent)
178
+ }, [percent, active, activeMode, duration])
179
+
180
+ // 初始化时设置进度值
181
+ useEffect(() => {
182
+ if (!active) {
183
+ progressWidth.value = Math.max(0, Math.min(100, percent))
184
+ }
185
+ }, [])
186
+
187
+ // 进度条动画样式
188
+ const animatedProgressStyle = useAnimatedStyle(() => {
189
+ return {
190
+ width: `${progressWidth.value}%`
191
+ }
192
+ })
193
+
194
+ // 确保数值类型正确
195
+ const strokeWidthNum = typeof strokeWidth === 'number' ? strokeWidth : parseInt(strokeWidth as string, 10) || 6
196
+
197
+ // 容器样式
198
+ const containerStyle: ViewStyle = extendObject({} as ViewStyle, {
199
+ flexDirection: 'row' as const,
200
+ alignItems: 'center' as const,
201
+ width: '100%',
202
+ minHeight: Math.max(strokeWidthNum, 20)
203
+ }, normalStyle, layoutStyle)
204
+
205
+ // 进度条背景样式
206
+ const progressBgStyle: ViewStyle = {
207
+ width: '100%',
208
+ height: strokeWidthNum,
209
+ backgroundColor,
210
+ overflow: 'hidden'
211
+ }
212
+
213
+ // 进度条填充样式
214
+ const progressFillStyle: ViewStyle = {
215
+ height: '100%',
216
+ backgroundColor: activeColor
217
+ }
218
+
219
+ const innerProps = useInnerProps(
220
+ extendObject({}, props, layoutProps, {
221
+ ref: nodeRef
222
+ }),
223
+ [
224
+ 'percent',
225
+ 'stroke-width',
226
+ 'color',
227
+ 'activeColor',
228
+ 'backgroundColor',
229
+ 'active',
230
+ 'active-mode',
231
+ 'duration',
232
+ 'bindactiveend'
233
+ ],
234
+ { layoutRef }
235
+ )
236
+
237
+ const progressComponent = createElement(
238
+ View,
239
+ extendObject({}, innerProps, { style: containerStyle }),
240
+ // 进度条背景
241
+ createElement(
242
+ View,
243
+ { style: progressBgStyle },
244
+ // 进度条填充
245
+ createElement(Animated.View, {
246
+ style: [progressFillStyle, animatedProgressStyle]
247
+ })
248
+ )
249
+ )
250
+
251
+ if (hasPositionFixed) {
252
+ return createElement(Portal, null, progressComponent)
253
+ }
254
+
255
+ return progressComponent
256
+ })
257
+
258
+ Progress.displayName = 'MpxProgress'
259
+ export default Progress
@@ -194,6 +194,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
194
194
  white: ['#fff']
195
195
  }
196
196
 
197
+ const isContentSizeChange = useRef(false)
198
+
197
199
  const { refresherContent, otherContent } = getRefresherContent(props.children)
198
200
  const hasRefresher = refresherContent && refresherEnabled
199
201
 
@@ -211,6 +213,18 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
211
213
 
212
214
  const scrollViewRef = useRef<ScrollView>(null)
213
215
 
216
+ const propsRef = useRef(props)
217
+ const refresherStateRef = useRef({
218
+ hasRefresher,
219
+ refresherTriggered
220
+ })
221
+
222
+ propsRef.current = props
223
+ refresherStateRef.current = {
224
+ hasRefresher,
225
+ refresherTriggered
226
+ }
227
+
214
228
  const runOnJSCallbackRef = useRef({
215
229
  setEnableScroll,
216
230
  setScrollBounces,
@@ -367,7 +381,22 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
367
381
  }
368
382
 
369
383
  function onContentSizeChange (width: number, height: number) {
370
- scrollOptions.current.contentLength = selectLength({ height, width })
384
+ isContentSizeChange.current = true
385
+ const newContentLength = selectLength({ height, width })
386
+ const oldContentLength = scrollOptions.current.contentLength
387
+ scrollOptions.current.contentLength = newContentLength
388
+ // 内容高度变化时,Animated.event 的映射可能会有不生效的场景,所以需要手动设置一下 scrollOffset 的值
389
+ if (enableSticky && (__mpx_mode__ === 'android' || __mpx_mode__ === 'ios')) {
390
+ // 当内容变少时,检查当前滚动位置是否超出新的内容范围
391
+ if (newContentLength < oldContentLength) {
392
+ const { visibleLength, offset } = scrollOptions.current
393
+ const maxOffset = Math.max(0, newContentLength - visibleLength)
394
+ // 如果当前滚动位置超出了新的内容范围,调整滚动offset
395
+ if (offset > maxOffset && scrollY) {
396
+ scrollOffset.setValue(maxOffset)
397
+ }
398
+ }
399
+ }
371
400
  }
372
401
 
373
402
  function onLayout (e: LayoutChangeEvent) {
@@ -390,8 +419,9 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
390
419
 
391
420
  function onScroll (e: NativeSyntheticEvent<NativeScrollEvent>) {
392
421
  const { bindscroll } = props
393
- const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset
394
- const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize
422
+ const { contentOffset, layoutMeasurement, contentSize } = e.nativeEvent
423
+ const { x: scrollLeft, y: scrollTop } = contentOffset
424
+ const { width: scrollWidth, height: scrollHeight } = contentSize
395
425
  isAtTop.value = scrollTop <= 0
396
426
  bindscroll &&
397
427
  bindscroll(
@@ -402,7 +432,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
402
432
  scrollHeight,
403
433
  scrollWidth,
404
434
  deltaX: scrollLeft - scrollOptions.current.scrollLeft,
405
- deltaY: scrollTop - scrollOptions.current.scrollTop
435
+ deltaY: scrollTop - scrollOptions.current.scrollTop,
436
+ layoutMeasurement
406
437
  },
407
438
  layoutRef
408
439
  }, props)
@@ -417,8 +448,9 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
417
448
 
418
449
  function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
419
450
  const { bindscrollend } = props
420
- const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset
421
- const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize
451
+ const { contentOffset, layoutMeasurement, contentSize } = e.nativeEvent
452
+ const { x: scrollLeft, y: scrollTop } = contentOffset
453
+ const { width: scrollWidth, height: scrollHeight } = contentSize
422
454
  isAtTop.value = scrollTop <= 0
423
455
  bindscrollend &&
424
456
  bindscrollend(
@@ -427,7 +459,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
427
459
  scrollLeft,
428
460
  scrollTop,
429
461
  scrollHeight,
430
- scrollWidth
462
+ scrollWidth,
463
+ layoutMeasurement
431
464
  },
432
465
  layoutRef
433
466
  }, props)
@@ -482,6 +515,16 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
482
515
  {
483
516
  useNativeDriver: true,
484
517
  listener: (event: NativeSyntheticEvent<NativeScrollEvent>) => {
518
+ const y = event.nativeEvent.contentOffset.y || 0
519
+ // 内容高度变化时,鸿蒙中 listener 回调通过scrollOffset.__getValue获取值一直等于event.nativeEvent.contentOffset.y,值是正确的,但是无法触发 sticky 动画执行,所以需要手动再 set 一次
520
+ if (__mpx_mode__ === 'harmony') {
521
+ if (isContentSizeChange.current) {
522
+ scrollOffset.setValue(y)
523
+ setTimeout(() => {
524
+ isContentSizeChange.current = false
525
+ }, 100)
526
+ }
527
+ }
485
528
  onScroll(event)
486
529
  }
487
530
  }
@@ -524,6 +567,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
524
567
 
525
568
  // 处理刷新
526
569
  function onRefresh () {
570
+ const { hasRefresher, refresherTriggered } = refresherStateRef.current
527
571
  if (hasRefresher && refresherTriggered === undefined) {
528
572
  // 处理使用了自定义刷新组件,又没设置 refresherTriggered 的情况
529
573
  setRefreshing(true)
@@ -535,10 +579,10 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
535
579
  }
536
580
  }, 500)
537
581
  }
538
- const { bindrefresherrefresh } = props
582
+ const { bindrefresherrefresh } = propsRef.current
539
583
  bindrefresherrefresh &&
540
584
  bindrefresherrefresh(
541
- getCustomEvent('refresherrefresh', {}, { layoutRef }, props)
585
+ getCustomEvent('refresherrefresh', {}, { layoutRef }, propsRef.current)
542
586
  )
543
587
  }
544
588
 
@@ -689,6 +733,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
689
733
  showsVerticalScrollIndicator: scrollY && showScrollbar,
690
734
  scrollEnabled: !enableScroll ? false : !!(scrollX || scrollY),
691
735
  bounces: false,
736
+ overScrollMode: 'never',
692
737
  ref: scrollViewRef,
693
738
  onScroll: enableSticky ? scrollHandler : onScroll,
694
739
  onContentSizeChange: onContentSizeChange,