@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.
- package/LICENSE +433 -0
- package/lib/dependencies/RecordPageConfigsMapDependency.js +1 -1
- package/lib/index.js +5 -6
- package/lib/platform/style/wx/index.js +0 -7
- package/lib/platform/template/wx/component-config/index.js +1 -5
- package/lib/platform/template/wx/component-config/movable-view.js +10 -1
- package/lib/platform/template/wx/index.js +2 -1
- package/lib/runtime/components/react/context.ts +4 -23
- package/lib/runtime/components/react/dist/context.js +2 -5
- package/lib/runtime/components/react/dist/getInnerListeners.js +1 -1
- package/lib/runtime/components/react/dist/mpx-button.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +9 -63
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +63 -308
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +15 -31
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +27 -53
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +14 -28
- package/lib/runtime/components/react/dist/useAnimationHooks.js +2 -87
- package/lib/runtime/components/react/getInnerListeners.ts +1 -1
- package/lib/runtime/components/react/mpx-button.tsx +2 -3
- package/lib/runtime/components/react/mpx-movable-area.tsx +11 -98
- package/lib/runtime/components/react/mpx-movable-view.tsx +64 -358
- package/lib/runtime/components/react/mpx-scroll-view.tsx +59 -84
- package/lib/runtime/components/react/mpx-swiper.tsx +25 -53
- package/lib/runtime/components/react/mpx-web-view.tsx +13 -33
- package/lib/runtime/components/react/types/global.d.ts +15 -0
- package/lib/runtime/components/react/useAnimationHooks.ts +2 -85
- package/lib/runtime/components/web/mpx-scroll-view.vue +4 -18
- package/lib/template-compiler/bind-this.js +1 -2
- package/lib/template-compiler/compiler.js +2 -2
- package/package.json +4 -4
- package/lib/platform/template/wx/component-config/sticky-header.js +0 -23
- package/lib/platform/template/wx/component-config/sticky-section.js +0 -23
- package/lib/runtime/components/react/AsyncContainer.tsx +0 -189
- package/lib/runtime/components/react/dist/AsyncContainer.jsx +0 -141
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +0 -117
- package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +0 -45
- package/lib/runtime/components/react/mpx-sticky-header.tsx +0 -181
- package/lib/runtime/components/react/mpx-sticky-section.tsx +0 -96
- package/lib/runtime/components/web/mpx-sticky-header.vue +0 -99
- 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
|
-
},
|
|
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]
|
|
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
|
|
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
|
|
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
|
|
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": "
|
|
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;
|