@mpxjs/webpack-plugin 2.10.4-beta.4 → 2.10.4-beta.6

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 (72) hide show
  1. package/lib/platform/template/wx/component-config/index.js +5 -1
  2. package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
  3. package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
  4. package/lib/runtime/components/react/context.ts +12 -3
  5. package/lib/runtime/components/react/dist/context.js +4 -1
  6. package/lib/runtime/components/react/dist/event.config.js +0 -2
  7. package/lib/runtime/components/react/dist/getInnerListeners.js +127 -153
  8. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -3
  9. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +3 -4
  10. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -2
  11. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -3
  12. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
  13. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -2
  14. package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
  15. package/lib/runtime/components/react/dist/mpx-input.jsx +3 -4
  16. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -3
  17. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +2 -2
  18. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
  19. package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
  20. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +2 -2
  21. package/lib/runtime/components/react/dist/mpx-picker-view/index.jsx +2 -3
  22. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -2
  23. package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -3
  24. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +2 -2
  25. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +18 -7
  26. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +3 -2
  27. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +3 -3
  28. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +112 -0
  29. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  30. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -5
  31. package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -9
  32. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -5
  33. package/lib/runtime/components/react/dist/mpx-text.jsx +4 -7
  34. package/lib/runtime/components/react/dist/mpx-video.jsx +2 -2
  35. package/lib/runtime/components/react/dist/mpx-view.jsx +2 -2
  36. package/lib/runtime/components/react/dist/utils.jsx +12 -1
  37. package/lib/runtime/components/react/event.config.ts +1 -8
  38. package/lib/runtime/components/react/getInnerListeners.ts +146 -192
  39. package/lib/runtime/components/react/mpx-button.tsx +4 -5
  40. package/lib/runtime/components/react/mpx-canvas/index.tsx +23 -15
  41. package/lib/runtime/components/react/mpx-checkbox-group.tsx +4 -3
  42. package/lib/runtime/components/react/mpx-checkbox.tsx +8 -9
  43. package/lib/runtime/components/react/mpx-form.tsx +25 -19
  44. package/lib/runtime/components/react/mpx-icon/index.tsx +4 -3
  45. package/lib/runtime/components/react/mpx-image.tsx +4 -3
  46. package/lib/runtime/components/react/mpx-input.tsx +6 -7
  47. package/lib/runtime/components/react/mpx-label.tsx +4 -5
  48. package/lib/runtime/components/react/mpx-movable-area.tsx +22 -13
  49. package/lib/runtime/components/react/mpx-movable-view.tsx +47 -40
  50. package/lib/runtime/components/react/mpx-navigator.tsx +4 -6
  51. package/lib/runtime/components/react/mpx-picker/index.tsx +7 -4
  52. package/lib/runtime/components/react/mpx-picker-view/index.tsx +17 -14
  53. package/lib/runtime/components/react/mpx-radio-group.tsx +4 -3
  54. package/lib/runtime/components/react/mpx-radio.tsx +8 -9
  55. package/lib/runtime/components/react/mpx-rich-text/index.tsx +15 -6
  56. package/lib/runtime/components/react/mpx-scroll-view.tsx +81 -57
  57. package/lib/runtime/components/react/mpx-simple-text.tsx +10 -3
  58. package/lib/runtime/components/react/mpx-simple-view.tsx +10 -4
  59. package/lib/runtime/components/react/mpx-sticky-header.tsx +176 -0
  60. package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
  61. package/lib/runtime/components/react/mpx-swiper-item.tsx +31 -24
  62. package/lib/runtime/components/react/mpx-swiper.tsx +67 -61
  63. package/lib/runtime/components/react/mpx-switch.tsx +19 -14
  64. package/lib/runtime/components/react/mpx-text.tsx +16 -13
  65. package/lib/runtime/components/react/mpx-video.tsx +34 -33
  66. package/lib/runtime/components/react/mpx-view.tsx +15 -9
  67. package/lib/runtime/components/react/types/getInnerListeners.d.ts +65 -35
  68. package/lib/runtime/components/react/utils.tsx +12 -1
  69. package/lib/runtime/components/web/mpx-scroll-view.vue +21 -4
  70. package/lib/runtime/components/web/mpx-sticky-header.vue +91 -0
  71. package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
  72. package/package.json +1 -1
@@ -379,8 +379,10 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
379
379
  }, [src, isSvg, isLayoutMode])
380
380
 
381
381
  const innerProps = useInnerProps(
382
- props,
383
382
  extendObject(
383
+ {},
384
+ props,
385
+ layoutProps,
384
386
  {
385
387
  ref: nodeRef,
386
388
  style: extendObject(
@@ -390,8 +392,7 @@ const Image = forwardRef<HandlerRef<RNImage, ImageProps>, ImageProps>((props, re
390
392
  isHeightFixMode ? { width: fixedWidth } : {},
391
393
  isWidthFixMode ? { height: fixedHeight } : {}
392
394
  )
393
- },
394
- layoutProps
395
+ }
395
396
  ),
396
397
  [
397
398
  'src',
@@ -425,8 +425,10 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
425
425
  }, [focus])
426
426
 
427
427
  const innerProps = useInnerProps(
428
- props,
429
428
  extendObject(
429
+ {},
430
+ props,
431
+ layoutProps,
430
432
  {
431
433
  ref: nodeRef,
432
434
  style: extendObject({}, normalStyle, layoutStyle),
@@ -444,11 +446,7 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
444
446
  underlineColorAndroid: 'rgba(0,0,0,0)',
445
447
  textAlignVertical: textAlignVertical,
446
448
  placeholderTextColor: placeholderStyle?.color,
447
- multiline: !!multiline
448
- },
449
- !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType },
450
- layoutProps,
451
- {
449
+ multiline: !!multiline,
452
450
  onTouchStart,
453
451
  onFocus,
454
452
  onBlur,
@@ -456,7 +454,8 @@ const Input = forwardRef<HandlerRef<TextInput, FinalInputProps>, FinalInputProps
456
454
  onSelectionChange,
457
455
  onContentSizeChange,
458
456
  onSubmitEditing: bindconfirm && !multiline && onSubmitEditing
459
- }
457
+ },
458
+ !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }
460
459
  ),
461
460
  [
462
461
  'type',
@@ -75,14 +75,13 @@ const Label = forwardRef<HandlerRef<View, LabelProps>, LabelProps>(
75
75
  }, [])
76
76
 
77
77
  const innerProps = useInnerProps(
78
- props,
79
78
  extendObject(
80
- {
81
- ref: nodeRef,
82
- style: extendObject({}, innerStyle, layoutStyle)
83
- },
79
+ {},
80
+ props,
84
81
  layoutProps,
85
82
  {
83
+ ref: nodeRef,
84
+ style: extendObject({}, innerStyle, layoutStyle),
86
85
  bindtap: onTap
87
86
  }
88
87
  ),
@@ -10,16 +10,16 @@ import { MovableAreaContext } from './context'
10
10
  import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils'
11
11
 
12
12
  interface MovableAreaProps {
13
- style?: Record<string, any>;
14
- children: ReactNode;
15
- width?: number;
16
- height?: number;
17
- 'enable-offset'?: boolean;
13
+ style?: Record<string, any>
14
+ children: ReactNode
15
+ width?: number
16
+ height?: number
17
+ 'enable-offset'?: boolean
18
18
  'enable-var'?: boolean
19
- 'external-var-context'?: Record<string, any>;
20
- 'parent-font-size'?: number;
21
- 'parent-width'?: number;
22
- 'parent-height'?: number;
19
+ 'external-var-context'?: Record<string, any>
20
+ 'parent-font-size'?: number
21
+ 'parent-width'?: number
22
+ 'parent-height'?: number
23
23
  }
24
24
 
25
25
  const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaProps>((props: MovableAreaProps, ref): JSX.Element => {
@@ -46,10 +46,19 @@ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaP
46
46
 
47
47
  const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef })
48
48
 
49
- const innerProps = useInnerProps(props, extendObject({
50
- style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
51
- ref: movableViewRef
52
- }, layoutProps), [], { layoutRef })
49
+ const innerProps = useInnerProps(
50
+ extendObject(
51
+ {},
52
+ props,
53
+ layoutProps,
54
+ {
55
+ style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
56
+ ref: movableViewRef
57
+ }
58
+ ),
59
+ [],
60
+ { layoutRef }
61
+ )
53
62
 
54
63
  return createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(
55
64
  View,
@@ -36,39 +36,39 @@ import Animated, {
36
36
  import { collectDataset, noop } from '@mpxjs/utils'
37
37
 
38
38
  interface MovableViewProps {
39
- children: ReactNode;
40
- style?: Record<string, any>;
41
- direction: 'all' | 'vertical' | 'horizontal' | 'none';
42
- x?: number;
43
- y?: number;
44
- disabled?: boolean;
45
- animation?: boolean;
46
- id?: string;
47
- bindchange?: (event: unknown) => void;
48
- bindtouchstart?: (event: GestureTouchEvent) => void;
49
- catchtouchstart?: (event: GestureTouchEvent) => void;
50
- bindtouchmove?: (event: GestureTouchEvent) => void;
51
- catchtouchmove?: (event: GestureTouchEvent) => void;
52
- catchtouchend?: (event: GestureTouchEvent) => void;
53
- bindtouchend?: (event: GestureTouchEvent) => void;
54
- bindhtouchmove?: (event: GestureTouchEvent) => void;
55
- bindvtouchmove?: (event: GestureTouchEvent) => void;
56
- catchhtouchmove?: (event: GestureTouchEvent) => void;
57
- catchvtouchmove?: (event: GestureTouchEvent) => void;
58
- bindlongpress?: (event: GestureTouchEvent) => void;
59
- catchlongpress?: (event: GestureTouchEvent) => void;
60
- bindtap?: (event: GestureTouchEvent) => void;
61
- catchtap?: (event: GestureTouchEvent) => void;
62
- onLayout?: (event: LayoutChangeEvent) => void;
63
- 'out-of-bounds'?: boolean;
64
- 'wait-for'?: Array<GestureHandler>;
65
- 'simultaneous-handlers'?: Array<GestureHandler>;
66
- inertia?: boolean;
39
+ children: ReactNode
40
+ style?: Record<string, any>
41
+ direction: 'all' | 'vertical' | 'horizontal' | 'none'
42
+ x?: number
43
+ y?: number
44
+ disabled?: boolean
45
+ animation?: boolean
46
+ id?: string
47
+ bindchange?: (event: unknown) => void
48
+ bindtouchstart?: (event: GestureTouchEvent) => void
49
+ catchtouchstart?: (event: GestureTouchEvent) => void
50
+ bindtouchmove?: (event: GestureTouchEvent) => void
51
+ catchtouchmove?: (event: GestureTouchEvent) => void
52
+ catchtouchend?: (event: GestureTouchEvent) => void
53
+ bindtouchend?: (event: GestureTouchEvent) => void
54
+ bindhtouchmove?: (event: GestureTouchEvent) => void
55
+ bindvtouchmove?: (event: GestureTouchEvent) => void
56
+ catchhtouchmove?: (event: GestureTouchEvent) => void
57
+ catchvtouchmove?: (event: GestureTouchEvent) => void
58
+ bindlongpress?: (event: GestureTouchEvent) => void
59
+ catchlongpress?: (event: GestureTouchEvent) => void
60
+ bindtap?: (event: GestureTouchEvent) => void
61
+ catchtap?: (event: GestureTouchEvent) => void
62
+ onLayout?: (event: LayoutChangeEvent) => void
63
+ 'out-of-bounds'?: boolean
64
+ 'wait-for'?: Array<GestureHandler>
65
+ 'simultaneous-handlers'?: Array<GestureHandler>
66
+ inertia?: boolean
67
67
  'enable-var'?: boolean
68
- 'external-var-context'?: Record<string, any>;
69
- 'parent-font-size'?: number;
70
- 'parent-width'?: number;
71
- 'parent-height'?: number;
68
+ 'external-var-context'?: Record<string, any>
69
+ 'parent-font-size'?: number
70
+ 'parent-width'?: number
71
+ 'parent-height'?: number
72
72
  }
73
73
 
74
74
  const styles = StyleSheet.create({
@@ -235,7 +235,7 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
235
235
  offsetX: offsetX.value,
236
236
  offsetY: offsetY.value
237
237
  }),
238
- (currentValue: { offsetX: any; offsetY: any; }) => {
238
+ (currentValue: { offsetX: any; offsetY: any }) => {
239
239
  const { offsetX, offsetY } = currentValue
240
240
  runOnJS(handleTriggerChange)({
241
241
  x: offsetX,
@@ -342,11 +342,11 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
342
342
  props.onLayout && props.onLayout(e)
343
343
  }
344
344
 
345
- const extendEvent = useCallback((e: any, type: 'start'|'move'|'end') => {
345
+ const extendEvent = useCallback((e: any, type: 'start' | 'move' | 'end') => {
346
346
  const { y: navigationY = 0 } = navigation?.layout || {}
347
347
  const touchArr = [e.changedTouches, e.allTouches]
348
348
  touchArr.forEach(touches => {
349
- touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number ; clientX: number; clientY: number}) => {
349
+ touches && touches.forEach((item: { absoluteX: number; absoluteY: number; pageX: number; pageY: number; clientX: number; clientY: number }) => {
350
350
  item.pageX = item.absoluteX
351
351
  item.pageY = item.absoluteY - navigationY
352
352
  item.clientX = item.absoluteX
@@ -565,11 +565,18 @@ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewP
565
565
  'catchtouchend'
566
566
  ])
567
567
 
568
- const innerProps = useInnerProps(filterProps, extendObject({
569
- ref: nodeRef,
570
- onLayout: onLayout,
571
- style: [innerStyle, animatedStyles, layoutStyle]
572
- }, rewriteCatchEvent()))
568
+ const innerProps = useInnerProps(
569
+ extendObject(
570
+ {},
571
+ filterProps,
572
+ {
573
+ ref: nodeRef,
574
+ onLayout: onLayout,
575
+ style: [innerStyle, animatedStyles, layoutStyle]
576
+ },
577
+ rewriteCatchEvent()
578
+ )
579
+ )
573
580
 
574
581
  return createElement(GestureDetector, { gesture: gesture }, createElement(
575
582
  Animated.View,
@@ -7,9 +7,7 @@
7
7
  * ✔ url
8
8
  * ✔ delta
9
9
  */
10
- import { View } from 'react-native'
11
- import { useCallback, forwardRef, JSX, createElement } from 'react'
12
- import useInnerProps from './getInnerListeners'
10
+ import { useCallback, forwardRef, JSX, createElement, MutableRefObject } from 'react'
13
11
  import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
14
12
 
15
13
  import MpxView, { _ViewProps } from './mpx-view'
@@ -20,7 +18,7 @@ interface _NavigatorProps extends _ViewProps {
20
18
  delta: number
21
19
  }
22
20
 
23
- const _Navigator = forwardRef<View, _NavigatorProps>((props, ref): JSX.Element => {
21
+ const _Navigator = forwardRef<any, _NavigatorProps>((props, ref): JSX.Element => {
24
22
  const {
25
23
  children,
26
24
  'open-type': openType,
@@ -48,10 +46,10 @@ const _Navigator = forwardRef<View, _NavigatorProps>((props, ref): JSX.Element =
48
46
  }
49
47
  }, [openType, url, delta])
50
48
 
51
- const innerProps = useInnerProps(props, {
49
+ const innerProps = {
52
50
  ref,
53
51
  bindtap: handleClick
54
- })
52
+ }
55
53
 
56
54
  return createElement(MpxView, innerProps, children)
57
55
  })
@@ -134,10 +134,13 @@ const Picker = forwardRef<HandlerRef<View, PickerProps>, PickerProps>(
134
134
 
135
135
  useNodesRef<View, PickerProps>(props, ref, nodeRef)
136
136
  const innerProps = useInnerProps(
137
- props,
138
- {
139
- ref: nodeRef
140
- },
137
+ extendObject(
138
+ {},
139
+ props,
140
+ {
141
+ ref: nodeRef
142
+ }
143
+ ),
141
144
  [],
142
145
  { layoutRef: innerLayout }
143
146
  )
@@ -130,20 +130,23 @@ const _PickerView = forwardRef<HandlerRef<View, PickerViewProps>, PickerViewProp
130
130
  }
131
131
 
132
132
  const innerProps = useInnerProps(
133
- props,
134
- extendObject({
135
- ref: nodeRef,
136
- style: extendObject(
137
- {},
138
- normalStyle,
139
- layoutStyle,
140
- {
141
- position: 'relative',
142
- overflow: 'hidden'
143
- }
144
- ),
145
- layoutProps
146
- }),
133
+ extendObject(
134
+ {},
135
+ props,
136
+ layoutProps,
137
+ {
138
+ ref: nodeRef,
139
+ style: extendObject(
140
+ {},
141
+ normalStyle,
142
+ layoutStyle,
143
+ {
144
+ position: 'relative',
145
+ overflow: 'hidden'
146
+ }
147
+ )
148
+ }
149
+ ),
147
150
  [
148
151
  'enable-offset',
149
152
  'indicator-style',
@@ -141,13 +141,14 @@ const radioGroup = forwardRef<
141
141
  }, [])
142
142
 
143
143
  const innerProps = useInnerProps(
144
- props,
145
144
  extendObject(
145
+ {},
146
+ props,
147
+ layoutProps,
146
148
  {
147
149
  ref: nodeRef,
148
150
  style: extendObject({}, normalStyle, layoutStyle)
149
- },
150
- layoutProps
151
+ }
151
152
  ),
152
153
  ['name'],
153
154
  {
@@ -22,9 +22,9 @@ export interface RadioProps {
22
22
  'enable-offset'?: boolean
23
23
  'enable-var'?: boolean
24
24
  'external-var-context'?: Record<string, any>
25
- 'parent-font-size'?: number;
26
- 'parent-width'?: number;
27
- 'parent-height'?: number;
25
+ 'parent-font-size'?: number
26
+ 'parent-width'?: number
27
+ 'parent-height'?: number
28
28
  children: ReactNode
29
29
  bindtap?: (evt: NativeSyntheticEvent<TouchEvent> | unknown) => void
30
30
  }
@@ -84,7 +84,7 @@ const Radio = forwardRef<HandlerRef<View, RadioProps>, RadioProps>(
84
84
  const [isChecked, setIsChecked] = useState<boolean>(!!checked)
85
85
 
86
86
  const groupContext = useContext(RadioGroupContext)
87
- let groupValue: { [key: string]: { checked: boolean; setValue: Dispatch<SetStateAction<boolean>>; } } | undefined
87
+ let groupValue: { [key: string]: { checked: boolean; setValue: Dispatch<SetStateAction<boolean>> } } | undefined
88
88
  let notifyChange: (evt: NativeSyntheticEvent<TouchEvent>) => void | undefined
89
89
 
90
90
  const labelContext = useContext(LabelContext)
@@ -149,14 +149,13 @@ const Radio = forwardRef<HandlerRef<View, RadioProps>, RadioProps>(
149
149
  }
150
150
 
151
151
  const innerProps = useInnerProps(
152
- props,
153
152
  extendObject(
154
- {
155
- ref: nodeRef,
156
- style: extendObject({}, innerStyle, layoutStyle)
157
- },
153
+ {},
154
+ props,
158
155
  layoutProps,
159
156
  {
157
+ ref: nodeRef,
158
+ style: extendObject({}, innerStyle, layoutStyle),
160
159
  bindtap: !disabled && onTap
161
160
  }
162
161
  ),
@@ -91,12 +91,21 @@ const _RichText = forwardRef<HandlerRef<View, _RichTextProps>, _RichTextProps>((
91
91
  layoutRef
92
92
  })
93
93
 
94
- const innerProps = useInnerProps(props, extendObject({
95
- ref: nodeRef,
96
- style: extendObject(normalStyle, layoutStyle)
97
- }, layoutProps), [], {
98
- layoutRef
99
- })
94
+ const innerProps = useInnerProps(
95
+ extendObject(
96
+ {},
97
+ props,
98
+ layoutProps,
99
+ {
100
+ ref: nodeRef,
101
+ style: extendObject(normalStyle, layoutStyle)
102
+ }
103
+ ),
104
+ [],
105
+ {
106
+ layoutRef
107
+ }
108
+ )
100
109
 
101
110
  const html: string = typeof nodes === 'string' ? nodes : jsonToHtmlStr(nodes)
102
111
 
@@ -32,7 +32,7 @@
32
32
  * ✔ bindscroll
33
33
  */
34
34
  import { ScrollView, RefreshControl, Gesture, GestureDetector } from 'react-native-gesture-handler'
35
- import { View, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle } from 'react-native'
35
+ import { View, NativeSyntheticEvent, NativeScrollEvent, LayoutChangeEvent, ViewStyle, Animated as RNAnimated } from 'react-native'
36
36
  import { isValidElement, Children, JSX, ReactNode, RefObject, useRef, useState, useEffect, forwardRef, useContext, useMemo, createElement } from 'react'
37
37
  import Animated, { useAnimatedRef, useSharedValue, withTiming, useAnimatedStyle, runOnJS } from 'react-native-reanimated'
38
38
  import { warn } from '@mpxjs/utils'
@@ -46,7 +46,6 @@ interface ScrollViewProps {
46
46
  enhanced?: boolean;
47
47
  bounces?: boolean;
48
48
  style?: ViewStyle;
49
- scrollEventThrottle?: number;
50
49
  'scroll-x'?: boolean;
51
50
  'scroll-y'?: boolean;
52
51
  'enable-back-to-top'?: boolean;
@@ -70,6 +69,7 @@ interface ScrollViewProps {
70
69
  'parent-font-size'?: number;
71
70
  'parent-width'?: number;
72
71
  'parent-height'?: number;
72
+ 'enable-sticky'?: boolean;
73
73
  'wait-for'?: Array<GestureHandler>;
74
74
  'simultaneous-handlers'?: Array<GestureHandler>;
75
75
  'scroll-event-throttle'?:number;
@@ -87,26 +87,28 @@ interface ScrollViewProps {
87
87
  __selectRef?: (selector: string, nodeType: 'node' | 'component', all?: boolean) => HandlerRef<any, any>
88
88
  }
89
89
  type ScrollAdditionalProps = {
90
- pinchGestureEnabled: boolean;
91
- horizontal: boolean;
92
- onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
93
- onContentSizeChange: (width: number, height: number) => void;
94
- onLayout?: (event: LayoutChangeEvent) => void;
95
- scrollsToTop: boolean;
96
- showsHorizontalScrollIndicator: boolean;
97
- showsVerticalScrollIndicator: boolean;
98
- scrollEnabled: boolean;
99
- ref: RefObject<ScrollView>;
100
- bounces?: boolean;
101
- pagingEnabled?: boolean;
102
- style?: ViewStyle;
103
- bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent>) => void;
104
- bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
105
- bindtouchend?: (event: NativeSyntheticEvent<TouchEvent>) => void;
106
- onScrollBeginDrag?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
107
- onScrollEndDrag?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
108
- onMomentumScrollEnd?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
109
- };
90
+ pinchGestureEnabled: boolean
91
+ horizontal: boolean
92
+ onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
93
+ onContentSizeChange: (width: number, height: number) => void
94
+ onLayout?: (event: LayoutChangeEvent) => void
95
+ scrollsToTop: boolean
96
+ showsHorizontalScrollIndicator: boolean
97
+ showsVerticalScrollIndicator: boolean
98
+ scrollEnabled: boolean
99
+ ref: RefObject<ScrollView>
100
+ bounces?: boolean
101
+ pagingEnabled?: boolean
102
+ style?: ViewStyle
103
+ bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent>) => void
104
+ bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void
105
+ bindtouchend?: (event: NativeSyntheticEvent<TouchEvent>) => void
106
+ onScrollBeginDrag?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
107
+ onScrollEndDrag?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
108
+ onMomentumScrollEnd?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
109
+ }
110
+
111
+ const AnimatedScrollView = RNAnimated.createAnimatedComponent(ScrollView) as React.ComponentType<any>
110
112
 
111
113
  const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, ScrollViewProps>((scrollViewProps: ScrollViewProps = {}, ref): JSX.Element => {
112
114
  const { textProps, innerProps: props = {} } = splitProps(scrollViewProps)
@@ -144,10 +146,13 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
144
146
  'parent-height': parentHeight,
145
147
  'simultaneous-handlers': originSimultaneousHandlers,
146
148
  'wait-for': waitFor,
149
+ 'enable-sticky': enableSticky,
147
150
  'scroll-event-throttle': scrollEventThrottle = 0,
148
151
  __selectRef
149
152
  } = props
150
153
 
154
+ const scrollOffset = useRef(new RNAnimated.Value(0)).current
155
+
151
156
  const simultaneousHandlers = flatGesture(originSimultaneousHandlers)
152
157
  const waitForHandlers = flatGesture(waitFor)
153
158
 
@@ -216,14 +221,15 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
216
221
  gestureRef: scrollViewRef
217
222
  })
218
223
 
224
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
225
+
219
226
  const contextValue = useMemo(() => {
220
227
  return {
221
- gestureRef: scrollViewRef
228
+ gestureRef: scrollViewRef,
229
+ scrollOffset
222
230
  }
223
231
  }, [])
224
232
 
225
- const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout })
226
-
227
233
  const hasRefresherLayoutRef = useRef(false)
228
234
 
229
235
  // layout 完成前先隐藏,避免安卓闪烁问题
@@ -274,7 +280,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
274
280
  }
275
281
  }, [refresherTriggered])
276
282
 
277
- function scrollTo ({ top = 0, left = 0, animated = false } : { top?: number; left?: number; animated?: boolean }) {
283
+ function scrollTo ({ top = 0, left = 0, animated = false }: { top?: number; left?: number; animated?: boolean }) {
278
284
  scrollToOffset(left, top, animated)
279
285
  }
280
286
 
@@ -485,6 +491,16 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
485
491
  updateIntersection()
486
492
  }
487
493
 
494
+ const scrollHandler = RNAnimated.event(
495
+ [{ nativeEvent: { contentOffset: { y: scrollOffset } } }],
496
+ {
497
+ useNativeDriver: true,
498
+ listener: (event: NativeSyntheticEvent<NativeScrollEvent>) => {
499
+ onScroll(event)
500
+ }
501
+ }
502
+ )
503
+
488
504
  function onScrollDragStart (e: NativeSyntheticEvent<NativeScrollEvent>) {
489
505
  hasCallScrollToLower.current = false
490
506
  hasCallScrollToUpper.current = false
@@ -655,7 +671,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
655
671
  scrollEnabled: !enableScroll ? false : !!(scrollX || scrollY),
656
672
  bounces: false,
657
673
  ref: scrollViewRef,
658
- onScroll: onScroll,
674
+ onScroll: enableSticky ? scrollHandler : onScroll,
659
675
  onContentSizeChange: onContentSizeChange,
660
676
  bindtouchstart: ((enhanced && binddragstart) || bindtouchstart) && onScrollTouchStart,
661
677
  bindtouchmove: ((enhanced && binddragging) || bindtouchmove) && onScrollTouchMove,
@@ -676,39 +692,47 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
676
692
  })
677
693
  }
678
694
 
679
- const innerProps = useInnerProps(props, scrollAdditionalProps, [
680
- 'id',
681
- 'scroll-x',
682
- 'scroll-y',
683
- 'enable-back-to-top',
684
- 'enable-trigger-intersection-observer',
685
- 'paging-enabled',
686
- 'show-scrollbar',
687
- 'upper-threshold',
688
- 'lower-threshold',
689
- 'scroll-top',
690
- 'scroll-left',
691
- 'scroll-with-animation',
692
- 'refresher-triggered',
693
- 'refresher-enabled',
694
- 'refresher-default-style',
695
- 'refresher-background',
696
- 'children',
697
- 'enhanced',
698
- 'binddragstart',
699
- 'binddragging',
700
- 'binddragend',
701
- 'bindscroll',
702
- 'bindscrolltoupper',
703
- 'bindscrolltolower',
704
- 'bindrefresherrefresh'
705
- ], { layoutRef })
695
+ const innerProps = useInnerProps(
696
+ extendObject(
697
+ {},
698
+ props,
699
+ scrollAdditionalProps
700
+ ),
701
+ [
702
+ 'id',
703
+ 'scroll-x',
704
+ 'scroll-y',
705
+ 'enable-back-to-top',
706
+ 'enable-trigger-intersection-observer',
707
+ 'paging-enabled',
708
+ 'show-scrollbar',
709
+ 'upper-threshold',
710
+ 'lower-threshold',
711
+ 'scroll-top',
712
+ 'scroll-left',
713
+ 'scroll-with-animation',
714
+ 'refresher-triggered',
715
+ 'refresher-enabled',
716
+ 'refresher-default-style',
717
+ 'refresher-background',
718
+ 'children',
719
+ 'enhanced',
720
+ 'binddragstart',
721
+ 'binddragging',
722
+ 'binddragend',
723
+ 'bindscroll',
724
+ 'bindscrolltoupper',
725
+ 'bindscrolltolower',
726
+ 'bindrefresherrefresh'
727
+ ], { layoutRef })
728
+
729
+ const ScrollViewComponent = enableSticky ? AnimatedScrollView : ScrollView
706
730
 
707
731
  const withRefresherScrollView = createElement(
708
732
  GestureDetector,
709
733
  { gesture: panGesture },
710
734
  createElement(
711
- ScrollView,
735
+ ScrollViewComponent,
712
736
  innerProps,
713
737
  createElement(
714
738
  Animated.View,
@@ -736,8 +760,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
736
760
  )
737
761
 
738
762
  const commonScrollView = createElement(
739
- ScrollView,
740
- extendObject(innerProps, {
763
+ ScrollViewComponent,
764
+ extendObject({}, innerProps, {
741
765
  refreshControl: refresherEnabled
742
766
  ? createElement(RefreshControl, extendObject({
743
767
  progressBackgroundColor: refresherBackground,