@mpxjs/webpack-plugin 2.10.7-beta.9 → 2.10.7

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 (40) hide show
  1. package/LICENSE +433 -0
  2. package/lib/dependencies/RecordPageConfigsMapDependency.js +1 -1
  3. package/lib/index.js +5 -6
  4. package/lib/platform/style/wx/index.js +0 -7
  5. package/lib/platform/template/wx/component-config/index.js +1 -5
  6. package/lib/platform/template/wx/component-config/movable-view.js +10 -1
  7. package/lib/platform/template/wx/index.js +2 -1
  8. package/lib/runtime/components/react/context.ts +4 -23
  9. package/lib/runtime/components/react/dist/context.js +2 -5
  10. package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
  11. package/lib/runtime/components/react/dist/mpx-button.jsx +2 -2
  12. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +9 -63
  13. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +63 -308
  14. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +15 -31
  15. package/lib/runtime/components/react/dist/mpx-swiper.jsx +27 -53
  16. package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
  17. package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
  18. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  19. package/lib/runtime/components/react/mpx-button.tsx +2 -3
  20. package/lib/runtime/components/react/mpx-movable-area.tsx +11 -98
  21. package/lib/runtime/components/react/mpx-movable-view.tsx +64 -358
  22. package/lib/runtime/components/react/mpx-scroll-view.tsx +59 -84
  23. package/lib/runtime/components/react/mpx-swiper.tsx +25 -53
  24. package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
  25. package/lib/runtime/components/react/types/global.d.ts +15 -0
  26. package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
  27. package/lib/runtime/components/web/mpx-scroll-view.vue +4 -18
  28. package/lib/template-compiler/bind-this.js +1 -2
  29. package/lib/template-compiler/compiler.js +2 -2
  30. package/package.json +4 -4
  31. package/lib/platform/template/wx/component-config/sticky-header.js +0 -23
  32. package/lib/platform/template/wx/component-config/sticky-section.js +0 -23
  33. package/lib/runtime/components/react/AsyncContainer.tsx +0 -189
  34. package/lib/runtime/components/react/dist/AsyncContainer.jsx +0 -141
  35. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +0 -117
  36. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +0 -45
  37. package/lib/runtime/components/react/mpx-sticky-header.tsx +0 -181
  38. package/lib/runtime/components/react/mpx-sticky-section.tsx +0 -96
  39. package/lib/runtime/components/web/mpx-sticky-header.vue +0 -99
  40. package/lib/runtime/components/web/mpx-sticky-section.vue +0 -15
@@ -1,5 +1,4 @@
1
1
  <script>
2
- import { computed } from 'vue'
3
2
  import getInnerListeners, { getCustomEvent } from './getInnerListeners'
4
3
  import { processSize } from '../../utils'
5
4
  import BScroll from '@better-scroll/core'
@@ -45,7 +44,6 @@
45
44
  enhanced: Boolean,
46
45
  refresherEnabled: Boolean,
47
46
  refresherTriggered: Boolean,
48
- enableSticky: Boolean,
49
47
  refresherThreshold: {
50
48
  type: Number,
51
49
  default: 45
@@ -59,12 +57,6 @@
59
57
  default: ''
60
58
  }
61
59
  },
62
- provide () {
63
- return {
64
- scrollOffset: computed(() => -this.lastY || 0),
65
- refreshVersion: computed(() => this.refreshVersion || 0)
66
- }
67
- },
68
60
  data () {
69
61
  return {
70
62
  isLoading: false,
@@ -76,8 +68,7 @@
76
68
  lastContentWidth: 0,
77
69
  lastContentHeight: 0,
78
70
  lastWrapperWidth: 0,
79
- lastWrapperHeight: 0,
80
- refreshVersion: 0
71
+ lastWrapperHeight: 0
81
72
  }
82
73
  },
83
74
  computed: {
@@ -231,9 +222,6 @@
231
222
  stop: 56
232
223
  }
233
224
  }
234
- if(this.enableSticky) {
235
- originBsOptions.useTransition = false
236
- }
237
225
  const bsOptions = Object.assign({}, originBsOptions, this.scrollOptions, { observeDOM: false })
238
226
  this.bs = new BScroll(this.$refs.wrapper, bsOptions)
239
227
  this.lastX = -this.currentX
@@ -263,7 +251,7 @@
263
251
  }
264
252
  this.lastX = x
265
253
  this.lastY = y
266
- }, this.enableSticky ? 0 : 30, {
254
+ }, 30, {
267
255
  leading: true,
268
256
  trailing: true
269
257
  }))
@@ -404,7 +392,6 @@
404
392
  this.lastContentHeight = scrollContentHeight
405
393
  this.lastWrapperWidth = scrollWrapperWidth
406
394
  this.lastWrapperHeight = scrollWrapperHeight
407
- this.refreshVersion++
408
395
  if (this.bs) this.bs.refresh()
409
396
  }
410
397
  },
@@ -471,8 +458,7 @@
471
458
  }
472
459
 
473
460
  const innerWrapper = createElement('div', {
474
- ref: 'innerWrapper',
475
- class: 'mpx-inner-wrapper'
461
+ ref: 'innerWrapper'
476
462
  }, this.$slots.default)
477
463
 
478
464
  const pullDownContent = this.refresherDefaultStyle !== 'none' ? createElement('div', {
@@ -582,4 +568,4 @@
582
568
  background: rgba(255, 255, 255, .7)
583
569
  100%
584
570
  background: rgba(255, 255, 255, .3)
585
- </style>
571
+ </style>
@@ -2,7 +2,6 @@ const babylon = require('@babel/parser')
2
2
  const traverse = require('@babel/traverse').default
3
3
  const t = require('@babel/types')
4
4
  const generate = require('@babel/generator').default
5
- const isValidIdentifierStr = require('../utils/is-valid-identifier-str')
6
5
 
7
6
  const names = 'Infinity,undefined,NaN,isFinite,isNaN,' +
8
7
  'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
@@ -42,7 +41,7 @@ function getCollectPath (path) {
42
41
  if (current.node.computed) {
43
42
  if (t.isLiteral(current.node.property)) {
44
43
  if (t.isStringLiteral(current.node.property)) {
45
- if (dangerousKeyMap[current.node.property.value] || !isValidIdentifierStr(current.node.property.value)) {
44
+ if (dangerousKeyMap[current.node.property.value]) {
46
45
  break
47
46
  }
48
47
  keyPath += `.${current.node.property.value}`
@@ -180,7 +180,7 @@ const i18nModuleName = '_i'
180
180
  const stringifyWxsPath = '~' + normalize.lib('runtime/stringify.wxs')
181
181
  const stringifyModuleName = '_s'
182
182
  const optionalChainWxsPath = '~' + normalize.lib('runtime/oc.wxs')
183
- const optionalChainWxsName = '_o'
183
+ const optionalChainWxsName = '_oc' // 改成_oc解决web下_o重名问题
184
184
 
185
185
  const tagRES = /(\{\{(?:.|\n|\r)+?\}\})(?!})/
186
186
  const tagRE = /\{\{((?:.|\n|\r)+?)\}\}(?!})/
@@ -1849,7 +1849,7 @@ function processRefReact (el, meta) {
1849
1849
  }])
1850
1850
  }
1851
1851
 
1852
- if (el.tag === 'mpx-scroll-view') {
1852
+ if (el.tag === 'mpx-scroll-view' && el.attrsMap['scroll-into-view']) {
1853
1853
  addAttrs(el, [
1854
1854
  {
1855
1855
  name: '__selectRef',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.10.7-beta.9",
3
+ "version": "2.10.7",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -28,7 +28,7 @@
28
28
  "@better-scroll/wheel": "^2.5.1",
29
29
  "@better-scroll/zoom": "^2.5.1",
30
30
  "@mpxjs/template-engine": "^2.8.7",
31
- "@mpxjs/utils": "^2.10.6 | ^2.10.6-beta.1",
31
+ "@mpxjs/utils": "^2.10.6",
32
32
  "acorn": "^8.11.3",
33
33
  "acorn-walk": "^7.2.0",
34
34
  "async": "^2.6.0",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "devDependencies": {
85
85
  "@d11/react-native-fast-image": "^8.6.12",
86
- "@mpxjs/api-proxy": "^2.10.7 | ^2.10.7-beta.1",
86
+ "@mpxjs/api-proxy": "^2.10.7",
87
87
  "@types/babel-traverse": "^6.25.4",
88
88
  "@types/babel-types": "^7.0.4",
89
89
  "@types/react": "^18.2.79",
@@ -100,5 +100,5 @@
100
100
  "engines": {
101
101
  "node": ">=14.14.0"
102
102
  },
103
- "gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0"
103
+ "gitHead": "3c56726c27464abac9cea343167d1b40933fff0d"
104
104
  }
@@ -1,23 +0,0 @@
1
- const TAG_NAME = 'sticky-header'
2
-
3
- module.exports = function ({ print }) {
4
- return {
5
- test: TAG_NAME,
6
- android (tag, { el }) {
7
- el.isBuiltIn = true
8
- return 'mpx-sticky-header'
9
- },
10
- ios (tag, { el }) {
11
- el.isBuiltIn = true
12
- return 'mpx-sticky-header'
13
- },
14
- harmony (tag, { el }) {
15
- el.isBuiltIn = true
16
- return 'mpx-sticky-header'
17
- },
18
- web (tag, { el }) {
19
- el.isBuiltIn = true
20
- return 'mpx-sticky-header'
21
- }
22
- }
23
- }
@@ -1,23 +0,0 @@
1
- const TAG_NAME = 'sticky-section'
2
-
3
- module.exports = function ({ print }) {
4
- return {
5
- test: TAG_NAME,
6
- android (tag, { el }) {
7
- el.isBuiltIn = true
8
- return 'mpx-sticky-section'
9
- },
10
- ios (tag, { el }) {
11
- el.isBuiltIn = true
12
- return 'mpx-sticky-section'
13
- },
14
- harmony (tag, { el }) {
15
- el.isBuiltIn = true
16
- return 'mpx-sticky-section'
17
- },
18
- web (tag, { el }) {
19
- el.isBuiltIn = true
20
- return 'mpx-sticky-section'
21
- }
22
- }
23
- }
@@ -1,189 +0,0 @@
1
- import { ComponentType, ReactNode, Component, Fragment, Suspense } from 'react'
2
- import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native'
3
- import FastImage from '@d11/react-native-fast-image'
4
-
5
- const styles = StyleSheet.create({
6
- container: {
7
- flex: 1,
8
- padding: 20,
9
- backgroundColor: '#fff'
10
- },
11
- loadingImage: {
12
- width: 100,
13
- height: 100,
14
- marginTop: 220,
15
- alignSelf: 'center'
16
- },
17
- buttonText: {
18
- color: '#fff',
19
- fontSize: 16,
20
- fontWeight: '500',
21
- textAlign: 'center'
22
- },
23
- errorImage: {
24
- marginTop: 80,
25
- width: 220,
26
- aspectRatio: 1,
27
- alignSelf: 'center'
28
- },
29
- errorText: {
30
- fontSize: 16,
31
- textAlign: 'center',
32
- color: '#333',
33
- marginBottom: 20
34
- },
35
- retryButton: {
36
- position: 'absolute',
37
- bottom: 54,
38
- left: 20,
39
- right: 20,
40
- backgroundColor: '#fff',
41
- paddingVertical: 15,
42
- borderRadius: 30,
43
- marginTop: 40,
44
- borderWidth: 1,
45
- borderColor: '#FF5F00'
46
- },
47
- retryButtonText: {
48
- color: '#FF5F00',
49
- fontSize: 16,
50
- fontWeight: '500',
51
- textAlign: 'center'
52
- }
53
- })
54
-
55
- type AsyncType = 'page' | 'component'
56
-
57
- interface PropsType<T extends AsyncType> {
58
- type: T
59
- props: object
60
- loading: ComponentType<unknown>
61
- fallback: ComponentType<unknown>
62
- children: (props: unknown) => ReactNode
63
- }
64
-
65
- interface StateType {
66
- hasError: boolean,
67
- key: number
68
- }
69
-
70
- interface ComponentError extends Error {
71
- request?: string
72
- type: 'timeout' | 'fail'
73
- }
74
-
75
- const DefaultLoading = () => {
76
- return (
77
- <View style={styles.container}>
78
- <FastImage
79
- style={styles.loadingImage}
80
- source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/439jiCVOtNOnEv9F2LaDs_loading.gif' }}
81
- resizeMode={FastImage.resizeMode.contain}></FastImage>
82
- </View>
83
- )
84
- }
85
-
86
- interface DefaultFallbackProps {
87
- onReload: () => void
88
- }
89
-
90
- const DefaultFallback = ({ onReload }: DefaultFallbackProps) => {
91
- return (
92
- <View style={styles.container}>
93
- <Image
94
- source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/Vak5mZvezPpKV5ZJI6P9b_drn-fallbak.png' }}
95
- style={styles.errorImage}
96
- resizeMode="contain"
97
- />
98
- <Text style={styles.errorText}>网络出了点问题,请查看网络环境</Text>
99
- <TouchableOpacity
100
- style={styles.retryButton}
101
- onPress={onReload}
102
- activeOpacity={0.7}
103
- >
104
- <Text style={styles.retryButtonText}>点击重试</Text>
105
- </TouchableOpacity>
106
- </View>
107
- )
108
- }
109
-
110
- export default class AsyncContainer extends Component<PropsType<AsyncType>, StateType> {
111
- private suspenseFallback: ReactNode
112
- private errorFallback: ReactNode
113
-
114
- constructor (props: PropsType<AsyncType>) {
115
- super(props)
116
- this.state = {
117
- hasError: false,
118
- key: 0
119
- }
120
- this.suspenseFallback = this.getSuspenseFallback()
121
- this.errorFallback = this.getErrorFallback()
122
- }
123
-
124
- // render 阶段收集到的错误
125
- static getDerivedStateFromError (error: ComponentError): StateType | undefined {
126
- if (error.name === 'ChunkLoadError') {
127
- return {
128
- hasError: true,
129
- key: 0
130
- }
131
- } else {
132
- // 被外层捕获
133
- throw error
134
- }
135
- }
136
-
137
- componentDidCatch (error: ComponentError): void {
138
- if (error.name === 'ChunkLoadError' && this.props.type === 'component') {
139
- const request = error.request || ''
140
- const subpackage = request.split('/').filter((i: string) => !!i)[0]
141
- global.onLazyLoadError({
142
- type: 'subpackage',
143
- subpackage: [subpackage],
144
- errMsg: `loadSubpackage: ${error.type}`
145
- })
146
- }
147
- }
148
-
149
- reloadPage () {
150
- this.setState((prevState) => {
151
- return {
152
- hasError: false,
153
- key: prevState.key + 1
154
- }
155
- })
156
- }
157
-
158
- getSuspenseFallback () {
159
- if (this.props.type === 'page') {
160
- const Fallback = this.props.loading || DefaultLoading
161
- return <Fallback />
162
- } else {
163
- const Fallback = this.props.loading
164
- return <Fallback {...this.props.props}></Fallback>
165
- }
166
- }
167
-
168
- getErrorFallback () {
169
- if (this.props.type === 'page') {
170
- const Fallback = this.props.fallback as ComponentType<DefaultFallbackProps> || DefaultFallback
171
- return <Fallback onReload={this.reloadPage.bind(this)}></Fallback>
172
- } else {
173
- const Fallback = this.props.loading
174
- return <Fallback {...this.props.props}></Fallback>
175
- }
176
- }
177
-
178
- render () {
179
- if (this.state.hasError) {
180
- return this.errorFallback
181
- } else {
182
- return (
183
- <Suspense fallback={this.suspenseFallback} key={this.state.key}>
184
- {this.props.children(this.props.props)}
185
- </Suspense>
186
- )
187
- }
188
- }
189
- }
@@ -1,141 +0,0 @@
1
- import { Component, Suspense } from 'react';
2
- import { View, Text, Image, StyleSheet, TouchableOpacity } from 'react-native';
3
- import FastImage from '@d11/react-native-fast-image';
4
- const styles = StyleSheet.create({
5
- container: {
6
- flex: 1,
7
- padding: 20,
8
- backgroundColor: '#fff'
9
- },
10
- loadingImage: {
11
- width: 100,
12
- height: 100,
13
- marginTop: 220,
14
- alignSelf: 'center'
15
- },
16
- buttonText: {
17
- color: '#fff',
18
- fontSize: 16,
19
- fontWeight: '500',
20
- textAlign: 'center'
21
- },
22
- errorImage: {
23
- marginTop: 80,
24
- width: 220,
25
- aspectRatio: 1,
26
- alignSelf: 'center'
27
- },
28
- errorText: {
29
- fontSize: 16,
30
- textAlign: 'center',
31
- color: '#333',
32
- marginBottom: 20
33
- },
34
- retryButton: {
35
- position: 'absolute',
36
- bottom: 54,
37
- left: 20,
38
- right: 20,
39
- backgroundColor: '#fff',
40
- paddingVertical: 15,
41
- borderRadius: 30,
42
- marginTop: 40,
43
- borderWidth: 1,
44
- borderColor: '#FF5F00'
45
- },
46
- retryButtonText: {
47
- color: '#FF5F00',
48
- fontSize: 16,
49
- fontWeight: '500',
50
- textAlign: 'center'
51
- }
52
- });
53
- const DefaultLoading = () => {
54
- return (<View style={styles.container}>
55
- <FastImage style={styles.loadingImage} source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/439jiCVOtNOnEv9F2LaDs_loading.gif' }} resizeMode={FastImage.resizeMode.contain}></FastImage>
56
- </View>);
57
- };
58
- const DefaultFallback = ({ onReload }) => {
59
- return (<View style={styles.container}>
60
- <Image source={{ uri: 'https://dpubstatic.udache.com/static/dpubimg/Vak5mZvezPpKV5ZJI6P9b_drn-fallbak.png' }} style={styles.errorImage} resizeMode="contain"/>
61
- <Text style={styles.errorText}>网络出了点问题,请查看网络环境</Text>
62
- <TouchableOpacity style={styles.retryButton} onPress={onReload} activeOpacity={0.7}>
63
- <Text style={styles.retryButtonText}>点击重试</Text>
64
- </TouchableOpacity>
65
- </View>);
66
- };
67
- export default class AsyncContainer extends Component {
68
- suspenseFallback;
69
- errorFallback;
70
- constructor(props) {
71
- super(props);
72
- this.state = {
73
- hasError: false,
74
- key: 0
75
- };
76
- this.suspenseFallback = this.getSuspenseFallback();
77
- this.errorFallback = this.getErrorFallback();
78
- }
79
- // render 阶段收集到的错误
80
- static getDerivedStateFromError(error) {
81
- if (error.name === 'ChunkLoadError') {
82
- return {
83
- hasError: true,
84
- key: 0
85
- };
86
- }
87
- else {
88
- // 被外层捕获
89
- throw error;
90
- }
91
- }
92
- componentDidCatch(error) {
93
- if (error.name === 'ChunkLoadError' && this.props.type === 'component') {
94
- const request = error.request || '';
95
- const subpackage = request.split('/').filter((i) => !!i)[0];
96
- global.onLazyLoadError({
97
- type: 'subpackage',
98
- subpackage: [subpackage],
99
- errMsg: `loadSubpackage: ${error.type}`
100
- });
101
- }
102
- }
103
- reloadPage() {
104
- this.setState((prevState) => {
105
- return {
106
- hasError: false,
107
- key: prevState.key + 1
108
- };
109
- });
110
- }
111
- getSuspenseFallback() {
112
- if (this.props.type === 'page') {
113
- const Fallback = this.props.loading || DefaultLoading;
114
- return <Fallback />;
115
- }
116
- else {
117
- const Fallback = this.props.loading;
118
- return <Fallback {...this.props.props}></Fallback>;
119
- }
120
- }
121
- getErrorFallback() {
122
- if (this.props.type === 'page') {
123
- const Fallback = this.props.fallback || DefaultFallback;
124
- return <Fallback onReload={this.reloadPage.bind(this)}></Fallback>;
125
- }
126
- else {
127
- const Fallback = this.props.loading;
128
- return <Fallback {...this.props.props}></Fallback>;
129
- }
130
- }
131
- render() {
132
- if (this.state.hasError) {
133
- return this.errorFallback;
134
- }
135
- else {
136
- return (<Suspense fallback={this.suspenseFallback} key={this.state.key}>
137
- {this.props.children(this.props.props)}
138
- </Suspense>);
139
- }
140
- }
141
- }
@@ -1,117 +0,0 @@
1
- import { useEffect, useRef, useContext, forwardRef, useMemo, createElement, useId } from 'react';
2
- import { Animated, StyleSheet, useAnimatedValue } from 'react-native';
3
- import { ScrollViewContext, StickyContext } from './context';
4
- import useNodesRef from './useNodesRef';
5
- import { splitProps, splitStyle, useTransformStyle, wrapChildren, useLayout, extendObject } from './utils';
6
- import { error } from '@mpxjs/utils';
7
- import useInnerProps, { getCustomEvent } from './getInnerListeners';
8
- const _StickyHeader = forwardRef((stickyHeaderProps = {}, ref) => {
9
- const { textProps, innerProps: props = {} } = splitProps(stickyHeaderProps);
10
- const { style, bindstickontopchange, padding = [0, 0, 0, 0], 'offset-top': offsetTop = 0, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
11
- const scrollViewContext = useContext(ScrollViewContext);
12
- const stickyContext = useContext(StickyContext);
13
- const { scrollOffset } = scrollViewContext;
14
- const { registerStickyHeader, unregisterStickyHeader } = stickyContext;
15
- const headerRef = useRef(null);
16
- const isStickOnTopRef = useRef(false);
17
- const id = useId();
18
- const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
19
- const { layoutRef, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: headerRef, onLayout });
20
- const { textStyle, innerStyle = {} } = splitStyle(normalStyle);
21
- const headerTopAnimated = useAnimatedValue(0);
22
- // harmony animatedValue 不支持通过 _value 访问
23
- const headerTopRef = useRef(0);
24
- useEffect(() => {
25
- registerStickyHeader({ key: id, updatePosition });
26
- return () => {
27
- unregisterStickyHeader(id);
28
- };
29
- }, []);
30
- function updatePosition() {
31
- if (headerRef.current) {
32
- const scrollViewRef = scrollViewContext.gestureRef;
33
- if (scrollViewRef && scrollViewRef.current) {
34
- headerRef.current.measureLayout(scrollViewRef.current, (left, top) => {
35
- Animated.timing(headerTopAnimated, {
36
- toValue: top,
37
- duration: 0,
38
- useNativeDriver: true
39
- }).start();
40
- headerTopRef.current = top;
41
- });
42
- }
43
- else {
44
- error('StickyHeader measureLayout error: scrollViewRef is not a valid native component reference');
45
- }
46
- }
47
- }
48
- function onLayout(e) {
49
- updatePosition();
50
- }
51
- useNodesRef(props, ref, headerRef, {
52
- style: normalStyle
53
- });
54
- useEffect(() => {
55
- if (!bindstickontopchange)
56
- return;
57
- const listener = scrollOffset.addListener((state) => {
58
- const currentScrollValue = state.value;
59
- const newIsStickOnTop = currentScrollValue > headerTopRef.current;
60
- if (newIsStickOnTop !== isStickOnTopRef.current) {
61
- isStickOnTopRef.current = newIsStickOnTop;
62
- bindstickontopchange(getCustomEvent('stickontopchange', {}, {
63
- detail: {
64
- isStickOnTop: newIsStickOnTop
65
- },
66
- layoutRef
67
- }, props));
68
- }
69
- });
70
- return () => {
71
- scrollOffset.removeListener(listener);
72
- };
73
- }, []);
74
- const animatedStyle = useMemo(() => {
75
- const translateY = Animated.subtract(scrollOffset, headerTopAnimated).interpolate({
76
- inputRange: [0, 1],
77
- outputRange: [0, 1],
78
- extrapolateLeft: 'clamp',
79
- extrapolateRight: 'extend'
80
- });
81
- const finalTranslateY = offsetTop === 0
82
- ? translateY
83
- : Animated.add(translateY, Animated.subtract(scrollOffset, headerTopAnimated).interpolate({
84
- inputRange: [0, 1],
85
- outputRange: [0, offsetTop],
86
- extrapolate: 'clamp'
87
- }));
88
- return {
89
- transform: [{ translateY: finalTranslateY }]
90
- };
91
- }, [scrollOffset, headerTopAnimated, offsetTop]);
92
- const innerProps = useInnerProps(extendObject({}, props, {
93
- ref: headerRef,
94
- style: extendObject({}, styles.content, innerStyle, animatedStyle, {
95
- paddingTop: padding[0] || 0,
96
- paddingRight: padding[1] || 0,
97
- paddingBottom: padding[2] || 0,
98
- paddingLeft: padding[3] || 0
99
- })
100
- }, layoutProps), [], { layoutRef });
101
- return (createElement(Animated.View, innerProps, wrapChildren(props, {
102
- hasVarDec,
103
- varContext: varContextRef.current,
104
- textStyle,
105
- textProps
106
- })));
107
- });
108
- const styles = StyleSheet.create({
109
- content: {
110
- width: '100%',
111
- zIndex: 10,
112
- // harmony 需要手动设置 relative, zIndex 才生效
113
- position: 'relative'
114
- }
115
- });
116
- _StickyHeader.displayName = 'MpxStickyHeader';
117
- export default _StickyHeader;
@@ -1,45 +0,0 @@
1
- import { useRef, forwardRef, createElement, useCallback, useMemo } from 'react';
2
- import { View } from 'react-native';
3
- import useNodesRef from './useNodesRef';
4
- import { splitProps, splitStyle, useTransformStyle, wrapChildren, useLayout, extendObject } from './utils';
5
- import { StickyContext } from './context';
6
- import useInnerProps from './getInnerListeners';
7
- const _StickySection = forwardRef((stickySectionProps = {}, ref) => {
8
- const { textProps, innerProps: props = {} } = splitProps(stickySectionProps);
9
- const { style, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
10
- const sectionRef = useRef(null);
11
- const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
12
- const { layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: sectionRef, onLayout });
13
- const { textStyle, innerStyle = {} } = splitStyle(normalStyle);
14
- const stickyHeaders = useRef(new Map());
15
- const registerStickyHeader = useCallback((item) => {
16
- stickyHeaders.current.set(item.id, item);
17
- }, []);
18
- const unregisterStickyHeader = useCallback((id) => {
19
- stickyHeaders.current.delete(id);
20
- }, []);
21
- const contextValue = useMemo(() => ({
22
- registerStickyHeader,
23
- unregisterStickyHeader
24
- }), []);
25
- useNodesRef(props, ref, sectionRef, {
26
- style: normalStyle
27
- });
28
- function onLayout() {
29
- stickyHeaders.current.forEach(item => {
30
- item.updatePosition();
31
- });
32
- }
33
- const innerProps = useInnerProps(extendObject({}, props, {
34
- style: extendObject(innerStyle, layoutStyle),
35
- ref: sectionRef
36
- }, layoutProps), [], { layoutRef });
37
- return (createElement(View, innerProps, createElement(StickyContext.Provider, { value: contextValue }, wrapChildren(props, {
38
- hasVarDec,
39
- varContext: varContextRef.current,
40
- textStyle,
41
- textProps
42
- }))));
43
- });
44
- _StickySection.displayName = 'MpxStickySection';
45
- export default _StickySection;