@mpxjs/webpack-plugin 2.9.67 → 2.9.69-beta.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.
- package/lib/index.js +30 -9
- package/lib/platform/json/wx/index.js +21 -8
- package/lib/platform/style/wx/index.js +51 -54
- package/lib/platform/template/wx/component-config/canvas.js +8 -0
- package/lib/platform/template/wx/component-config/fix-component-name.js +15 -12
- package/lib/platform/template/wx/component-config/index.js +1 -1
- package/lib/platform/template/wx/component-config/input.js +1 -1
- package/lib/platform/template/wx/component-config/movable-view.js +8 -1
- package/lib/platform/template/wx/component-config/rich-text.js +8 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +1 -1
- package/lib/platform/template/wx/component-config/swiper.js +1 -1
- package/lib/platform/template/wx/component-config/textarea.js +1 -1
- package/lib/platform/template/wx/component-config/unsupported.js +1 -1
- package/lib/react/processStyles.js +14 -4
- package/lib/react/processTemplate.js +3 -0
- package/lib/resolver/AddEnvPlugin.js +1 -0
- package/lib/resolver/AddModePlugin.js +9 -8
- package/lib/runtime/components/react/context.ts +14 -0
- package/lib/runtime/components/react/dist/context.js +4 -0
- package/lib/runtime/components/react/dist/event.config.js +24 -24
- package/lib/runtime/components/react/dist/getInnerListeners.js +183 -175
- package/lib/runtime/components/react/dist/mpx-button.jsx +77 -49
- package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
- package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
- package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
- package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
- package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
- package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
- package/lib/runtime/components/react/dist/mpx-canvas/html.js +343 -0
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +232 -0
- package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
- package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
- package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
- package/lib/runtime/components/react/dist/mpx-image.jsx +291 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
- package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +14 -14
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -15
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +171 -88
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +80 -121
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
- package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
- package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +62 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +6 -4
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +53 -42
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +28 -9
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +608 -0
- package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
- package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
- package/lib/runtime/components/react/dist/mpx-view.jsx +67 -94
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +152 -37
- package/lib/runtime/components/react/dist/pickerFaces.js +81 -0
- package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
- package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
- package/lib/runtime/components/react/dist/pickerViewOverlay.jsx +23 -0
- package/lib/runtime/components/react/dist/useAnimationHooks.js +36 -10
- package/lib/runtime/components/react/dist/utils.jsx +129 -24
- package/lib/runtime/components/react/event.config.ts +25 -26
- package/lib/runtime/components/react/getInnerListeners.ts +238 -202
- package/lib/runtime/components/react/mpx-button.tsx +104 -57
- package/lib/runtime/components/react/mpx-canvas/Bus.ts +70 -0
- package/lib/runtime/components/react/mpx-canvas/CanvasGradient.ts +18 -0
- package/lib/runtime/components/react/mpx-canvas/CanvasRenderingContext2D.ts +87 -0
- package/lib/runtime/components/react/mpx-canvas/Image.ts +102 -0
- package/lib/runtime/components/react/mpx-canvas/ImageData.ts +23 -0
- package/lib/runtime/components/react/mpx-canvas/constructorsRegistry.ts +38 -0
- package/lib/runtime/components/react/mpx-canvas/html.ts +343 -0
- package/lib/runtime/components/react/mpx-canvas/index.tsx +296 -0
- package/lib/runtime/components/react/mpx-canvas/utils.tsx +150 -0
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +28 -25
- package/lib/runtime/components/react/mpx-checkbox.tsx +48 -49
- package/lib/runtime/components/react/mpx-form.tsx +25 -28
- package/lib/runtime/components/react/mpx-icon.tsx +12 -17
- package/lib/runtime/components/react/mpx-image.tsx +436 -0
- package/lib/runtime/components/react/mpx-input.tsx +77 -57
- package/lib/runtime/components/react/mpx-label.tsx +26 -27
- package/lib/runtime/components/react/mpx-movable-area.tsx +18 -23
- package/lib/runtime/components/react/mpx-movable-view.tsx +22 -26
- package/lib/runtime/components/react/mpx-navigator.tsx +2 -8
- package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
- package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
- package/lib/runtime/components/react/mpx-picker-view-column-item.tsx +88 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +276 -112
- package/lib/runtime/components/react/mpx-picker-view.tsx +137 -129
- package/lib/runtime/components/react/mpx-radio-group.tsx +24 -27
- package/lib/runtime/components/react/mpx-radio.tsx +45 -54
- package/lib/runtime/components/react/mpx-rich-text/html.ts +40 -0
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +115 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +3 -5
- package/lib/runtime/components/react/mpx-scroll-view.tsx +83 -73
- package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
- package/lib/runtime/components/react/mpx-swiper-item.tsx +41 -12
- package/lib/runtime/components/react/mpx-swiper.tsx +690 -0
- package/lib/runtime/components/react/mpx-switch.tsx +29 -23
- package/lib/runtime/components/react/mpx-text.tsx +14 -18
- package/lib/runtime/components/react/mpx-textarea.tsx +11 -10
- package/lib/runtime/components/react/mpx-view.tsx +93 -117
- package/lib/runtime/components/react/mpx-web-view.tsx +162 -56
- package/lib/runtime/components/react/pickerFaces.ts +112 -0
- package/lib/runtime/components/react/pickerVIewContext.ts +18 -0
- package/lib/runtime/components/react/pickerViewMask.tsx +30 -0
- package/lib/runtime/components/react/pickerViewOverlay.tsx +34 -0
- package/lib/runtime/components/react/types/common.ts +2 -0
- package/lib/runtime/components/react/types/global.d.ts +7 -17
- package/lib/runtime/components/react/useAnimationHooks.ts +37 -12
- package/lib/runtime/components/react/utils.tsx +169 -29
- package/lib/runtime/components/web/getInnerListeners.js +6 -6
- package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
- package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
- package/lib/runtime/components/web/mpx-picker.vue +382 -385
- package/lib/runtime/components/web/mpx-web-view.vue +175 -161
- package/lib/runtime/optionProcessor.js +7 -38
- package/lib/runtime/utils.js +2 -0
- package/lib/style-compiler/index.js +3 -4
- package/lib/style-compiler/plugins/scope-id.js +30 -2
- package/lib/style-compiler/strip-conditional-loader.js +118 -0
- package/lib/template-compiler/bind-this.js +7 -2
- package/lib/template-compiler/compiler.js +66 -39
- package/lib/template-compiler/gen-node-react.js +3 -3
- package/package.json +6 -4
- package/LICENSE +0 -433
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
- package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
- package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
- package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +0 -525
- package/lib/runtime/components/react/mpx-swiper/index.tsx +0 -80
- package/lib/runtime/components/react/mpx-swiper/type.ts +0 -87
- package/lib/runtime/components/web/event.js +0 -105
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { forwardRef, JSX,
|
|
2
|
-
import {
|
|
1
|
+
import { forwardRef, JSX, useRef, useContext, useMemo, createElement, useCallback, useEffect } from 'react'
|
|
2
|
+
import { warn, getFocusedNavigation, isFunction } from '@mpxjs/utils'
|
|
3
3
|
import { Portal } from '@ant-design/react-native'
|
|
4
4
|
import { getCustomEvent } from './getInnerListeners'
|
|
5
5
|
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
|
|
6
6
|
import { WebView } from 'react-native-webview'
|
|
7
7
|
import useNodesRef, { HandlerRef } from './useNodesRef'
|
|
8
|
-
import {
|
|
8
|
+
import { getCurrentPage, extendObject } from './utils'
|
|
9
|
+
import { WebViewNavigationEvent, WebViewErrorEvent, WebViewMessageEvent, WebViewNavigation, WebViewProgressEvent } from 'react-native-webview/lib/WebViewTypes'
|
|
10
|
+
import { RouteContext } from './context'
|
|
11
|
+
import { BackHandler } from 'react-native'
|
|
9
12
|
|
|
10
13
|
type OnMessageCallbackEvent = {
|
|
11
14
|
detail: {
|
|
@@ -28,29 +31,25 @@ interface WebViewProps {
|
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
interface PayloadData {
|
|
31
|
-
|
|
34
|
+
[x: string]: any
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
type MessageData = {
|
|
35
38
|
payload?: PayloadData,
|
|
39
|
+
args?: Array<any>,
|
|
36
40
|
type?: string,
|
|
37
41
|
callbackId?: number
|
|
38
42
|
}
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface FormRef {
|
|
46
|
-
postMessage: (value: any) => void;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element => {
|
|
50
|
-
const { src = '', bindmessage = noop, bindload = noop, binderror = noop } = props
|
|
44
|
+
const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((props, ref): JSX.Element | null => {
|
|
45
|
+
const { src, bindmessage, bindload, binderror } = props
|
|
46
|
+
const mpx = global.__mpx
|
|
51
47
|
if (props.style) {
|
|
52
48
|
warn('The web-view component does not support the style prop.')
|
|
53
49
|
}
|
|
50
|
+
const pageId = useContext(RouteContext)
|
|
51
|
+
const currentPage = useMemo(() => getCurrentPage(pageId), [pageId])
|
|
52
|
+
const webViewRef = useRef<WebView>(null)
|
|
54
53
|
const defaultWebViewStyle = {
|
|
55
54
|
position: 'absolute' as 'absolute' | 'relative' | 'static',
|
|
56
55
|
left: 0 as number,
|
|
@@ -58,29 +57,44 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
58
57
|
top: 0 as number,
|
|
59
58
|
bottom: 0 as number
|
|
60
59
|
}
|
|
60
|
+
const canGoBack = useRef<boolean>(false)
|
|
61
61
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
const onAndroidBackPress = useCallback(() => {
|
|
63
|
+
if (canGoBack.current) {
|
|
64
|
+
webViewRef.current?.goBack()
|
|
65
|
+
return true
|
|
66
|
+
}
|
|
67
|
+
return false
|
|
68
|
+
}, [canGoBack])
|
|
66
69
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const beforeRemoveHandle = useCallback((e: Event) => {
|
|
71
|
+
if (canGoBack.current) {
|
|
72
|
+
webViewRef.current?.goBack()
|
|
73
|
+
e.preventDefault()
|
|
74
|
+
}
|
|
75
|
+
}, [canGoBack])
|
|
76
|
+
|
|
77
|
+
const navigation = getFocusedNavigation()
|
|
78
|
+
|
|
79
|
+
navigation?.addListener('beforeRemove', beforeRemoveHandle)
|
|
77
80
|
|
|
78
81
|
useEffect(() => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
if (__mpx_mode__ === 'android') {
|
|
83
|
+
BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress)
|
|
84
|
+
return () => {
|
|
85
|
+
BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress)
|
|
86
|
+
}
|
|
82
87
|
}
|
|
83
88
|
}, [])
|
|
89
|
+
|
|
90
|
+
useNodesRef<WebView, WebViewProps>(props, ref, webViewRef, {
|
|
91
|
+
style: defaultWebViewStyle
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
if (!src) {
|
|
95
|
+
return null
|
|
96
|
+
}
|
|
97
|
+
|
|
84
98
|
const _load = function (res: WebViewNavigationEvent) {
|
|
85
99
|
const result = {
|
|
86
100
|
type: 'load',
|
|
@@ -101,6 +115,50 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
101
115
|
}
|
|
102
116
|
binderror(result)
|
|
103
117
|
}
|
|
118
|
+
const injectedJavaScript = `
|
|
119
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
120
|
+
var _documentTitle = document.title;
|
|
121
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
122
|
+
type: 'setTitle',
|
|
123
|
+
payload: {
|
|
124
|
+
_documentTitle: _documentTitle
|
|
125
|
+
}
|
|
126
|
+
}))
|
|
127
|
+
Object.defineProperty(document, 'title', {
|
|
128
|
+
set (val) {
|
|
129
|
+
_documentTitle = val
|
|
130
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
131
|
+
type: 'setTitle',
|
|
132
|
+
payload: {
|
|
133
|
+
_documentTitle: _documentTitle
|
|
134
|
+
}
|
|
135
|
+
}))
|
|
136
|
+
},
|
|
137
|
+
get () {
|
|
138
|
+
return _documentTitle
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
true;
|
|
143
|
+
`
|
|
144
|
+
const sendMessage = function(params: string) {
|
|
145
|
+
return `
|
|
146
|
+
window.mpxWebviewMessageCallback(${params})
|
|
147
|
+
true;
|
|
148
|
+
`
|
|
149
|
+
}
|
|
150
|
+
const _changeUrl = function (navState: WebViewNavigation) {
|
|
151
|
+
if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
|
|
152
|
+
canGoBack.current = navState.canGoBack
|
|
153
|
+
currentPage.__webViewUrl = navState.url
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const _onLoadProgress = function (event: WebViewProgressEvent) {
|
|
158
|
+
if (__mpx_mode__ === 'android') {
|
|
159
|
+
canGoBack.current = event.nativeEvent.canGoBack
|
|
160
|
+
}
|
|
161
|
+
}
|
|
104
162
|
const _message = function (res: WebViewMessageEvent) {
|
|
105
163
|
let data: MessageData = {}
|
|
106
164
|
let asyncCallback
|
|
@@ -110,56 +168,104 @@ const _WebView = forwardRef<HandlerRef<WebView, WebViewProps>, WebViewProps>((pr
|
|
|
110
168
|
if (typeof nativeEventData === 'string') {
|
|
111
169
|
data = JSON.parse(nativeEventData)
|
|
112
170
|
}
|
|
113
|
-
} catch (e) {
|
|
114
|
-
|
|
115
|
-
}
|
|
171
|
+
} catch (e) {}
|
|
172
|
+
const args = data.args
|
|
116
173
|
const postData: PayloadData = data.payload || {}
|
|
117
|
-
|
|
174
|
+
const params = Array.isArray(args) ? args : [postData]
|
|
175
|
+
const type = data.type
|
|
176
|
+
switch (type) {
|
|
177
|
+
case 'setTitle':
|
|
178
|
+
{ // case下不允许直接声明,包个块解决该问题
|
|
179
|
+
const title = postData._documentTitle
|
|
180
|
+
if (title) {
|
|
181
|
+
navigation && navigation.setOptions({ title })
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
break
|
|
118
185
|
case 'postMessage':
|
|
119
|
-
|
|
186
|
+
bindmessage && bindmessage(getCustomEvent('messsage', {}, { // RN组件销毁顺序与小程序不一致,所以改成和支付宝消息一致
|
|
187
|
+
detail: {
|
|
188
|
+
data: params[0]?.data
|
|
189
|
+
}
|
|
190
|
+
}))
|
|
120
191
|
asyncCallback = Promise.resolve({
|
|
121
192
|
errMsg: 'invokeWebappApi:ok'
|
|
122
193
|
})
|
|
123
194
|
break
|
|
124
195
|
case 'navigateTo':
|
|
125
|
-
asyncCallback = navObj.navigateTo(
|
|
196
|
+
asyncCallback = navObj.navigateTo(...params)
|
|
126
197
|
break
|
|
127
198
|
case 'navigateBack':
|
|
128
|
-
asyncCallback = navObj.navigateBack(
|
|
199
|
+
asyncCallback = navObj.navigateBack(...params)
|
|
129
200
|
break
|
|
130
201
|
case 'redirectTo':
|
|
131
|
-
asyncCallback = navObj.redirectTo(
|
|
202
|
+
asyncCallback = navObj.redirectTo(...params)
|
|
132
203
|
break
|
|
133
204
|
case 'switchTab':
|
|
134
|
-
asyncCallback = navObj.switchTab(
|
|
205
|
+
asyncCallback = navObj.switchTab(...params)
|
|
135
206
|
break
|
|
136
207
|
case 'reLaunch':
|
|
137
|
-
asyncCallback = navObj.reLaunch(
|
|
208
|
+
asyncCallback = navObj.reLaunch(...params)
|
|
209
|
+
break
|
|
210
|
+
default:
|
|
211
|
+
if (type) {
|
|
212
|
+
const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type]
|
|
213
|
+
if (isFunction(implement)) {
|
|
214
|
+
asyncCallback = Promise.resolve(implement(...params))
|
|
215
|
+
} else {
|
|
216
|
+
/* eslint-disable prefer-promise-reject-errors */
|
|
217
|
+
asyncCallback = Promise.reject({
|
|
218
|
+
errMsg: `未在apiImplementations中配置${type}方法`
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
}
|
|
138
222
|
break
|
|
139
223
|
}
|
|
140
224
|
|
|
141
225
|
asyncCallback && asyncCallback.then((res: any) => {
|
|
142
226
|
if (webViewRef.current?.postMessage) {
|
|
143
|
-
const
|
|
144
|
-
type
|
|
227
|
+
const result = JSON.stringify({
|
|
228
|
+
type,
|
|
145
229
|
callbackId: data.callbackId,
|
|
146
230
|
result: res
|
|
147
231
|
})
|
|
148
|
-
webViewRef.current.
|
|
232
|
+
webViewRef.current.injectJavaScript(sendMessage(result))
|
|
149
233
|
}
|
|
234
|
+
}).catch((error: any) => {
|
|
235
|
+
if (webViewRef.current?.postMessage) {
|
|
236
|
+
const result = JSON.stringify({
|
|
237
|
+
type,
|
|
238
|
+
callbackId: data.callbackId,
|
|
239
|
+
error
|
|
240
|
+
})
|
|
241
|
+
webViewRef.current.injectJavaScript(sendMessage(result))
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
}
|
|
245
|
+
const events = {}
|
|
246
|
+
|
|
247
|
+
if (bindload) {
|
|
248
|
+
extendObject(events, {
|
|
249
|
+
onLoad: _load
|
|
150
250
|
})
|
|
151
251
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
252
|
+
if (binderror) {
|
|
253
|
+
extendObject(events, {
|
|
254
|
+
onError: _error
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return createElement(Portal, null, createElement(WebView, extendObject({
|
|
259
|
+
style: defaultWebViewStyle,
|
|
260
|
+
source: { uri: src },
|
|
261
|
+
ref: webViewRef,
|
|
262
|
+
javaScriptEnabled: true,
|
|
263
|
+
onNavigationStateChange: _changeUrl,
|
|
264
|
+
onMessage: _message,
|
|
265
|
+
injectedJavaScript: injectedJavaScript,
|
|
266
|
+
onLoadProgress: _onLoadProgress,
|
|
267
|
+
allowsBackForwardNavigationGestures: true
|
|
268
|
+
}, events)))
|
|
163
269
|
})
|
|
164
270
|
|
|
165
271
|
_WebView.displayName = 'MpxWebview'
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Borrowed from open-source code: https://github.com/quidone/react-native-wheel-picker
|
|
3
|
+
* Special thanks to the authors for their contribution to the open-source community.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type Faces = {
|
|
7
|
+
index: number
|
|
8
|
+
deg: number
|
|
9
|
+
offsetY: number
|
|
10
|
+
opacity: number
|
|
11
|
+
scale: number
|
|
12
|
+
screenHeight: number
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const degToRad = (deg: number) => (Math.PI * deg) / 180
|
|
16
|
+
|
|
17
|
+
// Calculates the height of the element after rotating it relative to the user's screen.
|
|
18
|
+
const calcHeight = (degree: number, itemHeight: number) =>
|
|
19
|
+
itemHeight * Math.cos(degToRad(degree))
|
|
20
|
+
|
|
21
|
+
export const calcPickerHeight = (faces: Faces[], itemHeight: number) => {
|
|
22
|
+
if (faces.length === 7) {
|
|
23
|
+
return itemHeight * 5
|
|
24
|
+
}
|
|
25
|
+
return faces.reduce((r, v) => r + calcHeight(Math.abs(v.deg), itemHeight), 0)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const createFaces = (
|
|
29
|
+
itemHeight: number,
|
|
30
|
+
visibleCount: number
|
|
31
|
+
): Faces[] => {
|
|
32
|
+
// e.g [30, 60, 90]
|
|
33
|
+
const getDegreesRelativeCenter = () => {
|
|
34
|
+
const maxStep = Math.trunc((visibleCount + 2) / 2) // + 2 because there are 2 more faces at 90 degrees
|
|
35
|
+
const stepDegree = 90 / maxStep
|
|
36
|
+
|
|
37
|
+
const result: number[] = []
|
|
38
|
+
for (let i = 1; i <= maxStep; i++) {
|
|
39
|
+
result.push(i * stepDegree)
|
|
40
|
+
}
|
|
41
|
+
return result
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const getScreenHeightsAndOffsets = <T extends readonly number[]>(
|
|
45
|
+
degrees: T
|
|
46
|
+
): [T, T] => {
|
|
47
|
+
const screenHeights = degrees.map((deg) =>
|
|
48
|
+
calcHeight(deg, itemHeight)
|
|
49
|
+
) as unknown as T
|
|
50
|
+
const freeSpaces = screenHeights.map(
|
|
51
|
+
(screenHeight) => itemHeight - screenHeight
|
|
52
|
+
)
|
|
53
|
+
const offsets = freeSpaces.map((freeSpace, index) => {
|
|
54
|
+
let offset = freeSpace / 2
|
|
55
|
+
for (let i = 0; i < index; i++) {
|
|
56
|
+
offset += freeSpaces[i]
|
|
57
|
+
}
|
|
58
|
+
if (index === 0) {
|
|
59
|
+
offset *= 0.6
|
|
60
|
+
}
|
|
61
|
+
return offset
|
|
62
|
+
}) as unknown as T
|
|
63
|
+
return [screenHeights, offsets]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const getOpacity = (index: number) => {
|
|
67
|
+
const map: Record<number, number> = {
|
|
68
|
+
0: 0,
|
|
69
|
+
1: 0.8,
|
|
70
|
+
2: 0.9 // 0.35
|
|
71
|
+
// 3: 0.45, // 0.45
|
|
72
|
+
// 4: 0.5 // 0.5
|
|
73
|
+
}
|
|
74
|
+
return map[index] ?? Math.min(1, map[2] + index * 0.05)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const degrees = getDegreesRelativeCenter()
|
|
78
|
+
const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees)
|
|
79
|
+
|
|
80
|
+
const scales = [1, 0.925, 0.8]
|
|
81
|
+
|
|
82
|
+
return [
|
|
83
|
+
// top items
|
|
84
|
+
...degrees
|
|
85
|
+
.map<Faces>((degree, index) => {
|
|
86
|
+
return {
|
|
87
|
+
index: -1 * (index + 1),
|
|
88
|
+
deg: degree,
|
|
89
|
+
opacity: getOpacity(degrees.length - 1 - index),
|
|
90
|
+
offsetY: -1 * offsets[index],
|
|
91
|
+
scale: scales[index],
|
|
92
|
+
screenHeight: screenHeight[index]
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
.reverse(),
|
|
96
|
+
|
|
97
|
+
// center item
|
|
98
|
+
{ index: 0, deg: 0, opacity: 1, offsetY: 0, scale: 1, screenHeight: itemHeight },
|
|
99
|
+
|
|
100
|
+
// bottom items
|
|
101
|
+
...degrees.map<Faces>((degree, index) => {
|
|
102
|
+
return {
|
|
103
|
+
index: index + 1,
|
|
104
|
+
deg: -1 * degree,
|
|
105
|
+
opacity: getOpacity(degrees.length - 1 - index),
|
|
106
|
+
offsetY: offsets[index],
|
|
107
|
+
scale: scales[index],
|
|
108
|
+
screenHeight: screenHeight[index]
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
]
|
|
112
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react'
|
|
2
|
+
import { SharedValue } from 'react-native-reanimated'
|
|
3
|
+
|
|
4
|
+
type ContextValue = SharedValue<number>
|
|
5
|
+
|
|
6
|
+
export const PickerViewColumnAnimationContext = createContext<
|
|
7
|
+
ContextValue | undefined
|
|
8
|
+
>(undefined)
|
|
9
|
+
|
|
10
|
+
export const usePickerViewColumnAnimationContext = () => {
|
|
11
|
+
const value = useContext(PickerViewColumnAnimationContext)
|
|
12
|
+
if (value === undefined) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
'usePickerViewColumnAnimationContext must be called from within PickerViewColumnAnimationContext.Provider!'
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
return value
|
|
18
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
|
|
3
|
+
import LinearGradient from 'react-native-linear-gradient'
|
|
4
|
+
|
|
5
|
+
type OverlayProps = {
|
|
6
|
+
itemHeight: number
|
|
7
|
+
maskContainerStyle?: StyleProp<ViewStyle>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const _PickerViewMask = ({
|
|
11
|
+
itemHeight,
|
|
12
|
+
maskContainerStyle
|
|
13
|
+
}: OverlayProps) => {
|
|
14
|
+
return (
|
|
15
|
+
<View style={[styles.overlayContainer, maskContainerStyle]} pointerEvents={'none'}>
|
|
16
|
+
<LinearGradient colors={['rgba(255,255,255,1)', 'rgba(255,255,255,0.5)']} style={{ flex: 1 }} />
|
|
17
|
+
<View style={{ height: itemHeight }} />
|
|
18
|
+
<LinearGradient colors={['rgba(255,255,255,0.5)', 'rgba(255,255,255,1)']} style={{ flex: 1 }} />
|
|
19
|
+
</View>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
const styles = StyleSheet.create({
|
|
23
|
+
overlayContainer: {
|
|
24
|
+
...StyleSheet.absoluteFillObject,
|
|
25
|
+
zIndex: 100
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
_PickerViewMask.displayName = 'MpxPickerViewMask'
|
|
30
|
+
export default _PickerViewMask
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'
|
|
3
|
+
|
|
4
|
+
type OverlayProps = {
|
|
5
|
+
itemHeight: number
|
|
6
|
+
overlayItemStyle?: StyleProp<ViewStyle>
|
|
7
|
+
overlayContainerStyle?: StyleProp<ViewStyle>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const _PickerViewOverlay = ({ itemHeight, overlayItemStyle, overlayContainerStyle }: OverlayProps) => {
|
|
11
|
+
return (
|
|
12
|
+
<View style={[styles.overlayContainer, overlayContainerStyle]} pointerEvents={'none'}>
|
|
13
|
+
<View style={[styles.selection, { height: itemHeight }, overlayItemStyle]} />
|
|
14
|
+
</View>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const styles = StyleSheet.create({
|
|
19
|
+
overlayContainer: {
|
|
20
|
+
...StyleSheet.absoluteFillObject,
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
zIndex: 200
|
|
24
|
+
},
|
|
25
|
+
selection: {
|
|
26
|
+
borderTopWidth: 1,
|
|
27
|
+
borderBottomWidth: 1,
|
|
28
|
+
borderColor: 'rgba(0, 0, 0, 0.05)',
|
|
29
|
+
alignSelf: 'stretch'
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
_PickerViewOverlay.displayName = 'MpxPickerViewOverlay'
|
|
34
|
+
export default _PickerViewOverlay
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
declare
|
|
2
|
-
import type { ImageSourcePropType, StyleProp, ImageStyle } from 'react-native'
|
|
3
|
-
import type { SvgProps as SvgCssUriProps } from 'react-native-svg'
|
|
4
|
-
|
|
5
|
-
export const SvgCssUri: React.ComponentType<SvgCssUriProps & { uri?: string }>
|
|
6
|
-
|
|
7
|
-
export interface WithLocalSvgProps {
|
|
8
|
-
asset: ImageSourcePropType
|
|
9
|
-
style?: StyleProp<ImageStyle>
|
|
10
|
-
width?: string | number
|
|
11
|
-
height?: string | number
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const WithLocalSvg: React.ComponentType<WithLocalSvgProps>
|
|
15
|
-
}
|
|
16
|
-
|
|
1
|
+
declare let __mpx_mode__: 'wx' | 'ali' | 'swan' | 'qq' | 'tt' | 'web' | 'dd' | 'qa' | 'jd' | 'android' | 'ios'
|
|
17
2
|
declare module '@mpxjs/utils' {
|
|
18
3
|
export function isEmptyObject (obj: Object): boolean
|
|
4
|
+
export function isFunction (fn: unknown): boolean
|
|
5
|
+
export function isNumber (num: unknown): boolean
|
|
19
6
|
export function hasOwn (obj: Object, key: string): boolean
|
|
20
7
|
export function noop (...arg: any): void
|
|
21
8
|
export function diffAndCloneA<A, B> (a: A, b?: B): {
|
|
@@ -26,13 +13,16 @@ declare module '@mpxjs/utils' {
|
|
|
26
13
|
export function isObject (value): value is Object
|
|
27
14
|
export function error (msg: string, location?: string, e?: any): void
|
|
28
15
|
export function warn (msg: string, location?: string, e?: any): void
|
|
16
|
+
export function collectDataset (props: Record<string, any>, needParse?: boolean): Record<string, any>
|
|
29
17
|
export function getFocusedNavigation (): {
|
|
30
18
|
insets: {
|
|
31
19
|
top: number
|
|
32
20
|
bottom: number
|
|
33
21
|
left: number
|
|
34
22
|
right: number
|
|
35
|
-
}
|
|
23
|
+
},
|
|
24
|
+
setOptions: (params: Record<string, any>) => void,
|
|
25
|
+
addListener: (eventName: string, callback: (e: Event) => void) => void
|
|
36
26
|
} | undefined
|
|
37
27
|
}
|
|
38
28
|
|
|
@@ -83,12 +83,34 @@ const InitialValue: ExtendedViewStyle = Object.assign({
|
|
|
83
83
|
const TransformOrigin = 'transformOrigin'
|
|
84
84
|
// transform
|
|
85
85
|
const isTransform = (key: string) => Object.keys(TransformInitial).includes(key)
|
|
86
|
+
// 多value解析
|
|
87
|
+
const parseValues = (str: string, char = ' ') => {
|
|
88
|
+
let stack = 0
|
|
89
|
+
let temp = ''
|
|
90
|
+
const result = []
|
|
91
|
+
for (let i = 0; i < str.length; i++) {
|
|
92
|
+
if (str[i] === '(') {
|
|
93
|
+
stack++
|
|
94
|
+
} else if (str[i] === ')') {
|
|
95
|
+
stack--
|
|
96
|
+
}
|
|
97
|
+
// 非括号内 或者 非分隔字符且非空
|
|
98
|
+
if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
|
|
99
|
+
temp += str[i]
|
|
100
|
+
}
|
|
101
|
+
if ((stack === 0 && str[i] === char) || i === str.length - 1) {
|
|
102
|
+
result.push(temp)
|
|
103
|
+
temp = ''
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return result
|
|
107
|
+
}
|
|
86
108
|
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
87
109
|
const parseTransform = (transformStr: string) => {
|
|
88
|
-
const values = transformStr
|
|
110
|
+
const values = parseValues(transformStr)
|
|
89
111
|
const transform: {[propName: string]: string|number|number[]}[] = []
|
|
90
112
|
values.forEach(item => {
|
|
91
|
-
const match = item.match(/([/\w]+)\((
|
|
113
|
+
const match = item.match(/([/\w]+)\((.+)\)/)
|
|
92
114
|
if (match && match.length >= 3) {
|
|
93
115
|
let key = match[1]
|
|
94
116
|
const val = match[2]
|
|
@@ -109,7 +131,7 @@ const parseTransform = (transformStr: string) => {
|
|
|
109
131
|
break
|
|
110
132
|
case 'matrix':
|
|
111
133
|
case 'matrix3d':
|
|
112
|
-
transform.push({ [key]: val
|
|
134
|
+
transform.push({ [key]: parseValues(val, ',').map(val => +val) })
|
|
113
135
|
break
|
|
114
136
|
case 'translate':
|
|
115
137
|
case 'scale':
|
|
@@ -120,8 +142,8 @@ const parseTransform = (transformStr: string) => {
|
|
|
120
142
|
{
|
|
121
143
|
// 2 个以上的值处理
|
|
122
144
|
key = key.replace('3d', '')
|
|
123
|
-
const vals = val
|
|
124
|
-
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
145
|
+
const vals = parseValues(val, ',').splice(0, key === 'rotate' ? 4 : 3)
|
|
146
|
+
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
125
147
|
if (vals.length === 1 && key === 'scale') {
|
|
126
148
|
vals.push(vals[0])
|
|
127
149
|
}
|
|
@@ -218,12 +240,15 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
218
240
|
}
|
|
219
241
|
// 添加每个key的多次step动画
|
|
220
242
|
animatedKeys.forEach(key => {
|
|
221
|
-
let toVal = (rules.get(key) || transform.get(key))
|
|
222
243
|
// key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
244
|
+
const toVal = rules.get(key) !== undefined
|
|
245
|
+
? rules.get(key)
|
|
246
|
+
: transform.get(key) !== undefined
|
|
247
|
+
? transform.get(key)
|
|
248
|
+
: index > 0
|
|
249
|
+
? lastValueMap[key]
|
|
250
|
+
: shareValMap[key].value
|
|
251
|
+
const animation = getAnimation({ key, value: toVal! }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined)
|
|
227
252
|
needSetCallback = false
|
|
228
253
|
if (!sequence[key]) {
|
|
229
254
|
sequence[key] = [animation]
|
|
@@ -231,7 +256,7 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
231
256
|
sequence[key].push(animation)
|
|
232
257
|
}
|
|
233
258
|
// 更新一下 lastValueMap
|
|
234
|
-
lastValueMap[key] = toVal
|
|
259
|
+
lastValueMap[key] = toVal!
|
|
235
260
|
})
|
|
236
261
|
// 赋值驱动动画
|
|
237
262
|
animatedKeys.forEach((key) => {
|
|
@@ -327,6 +352,6 @@ export default function useAnimationHooks<T, P> (props: _ViewProps) {
|
|
|
327
352
|
styles[key] = shareValMap[key].value
|
|
328
353
|
}
|
|
329
354
|
return styles
|
|
330
|
-
},
|
|
355
|
+
}, {} as ExtendedViewStyle)
|
|
331
356
|
})
|
|
332
357
|
}
|