@mpxjs/webpack-plugin 2.10.1 → 2.10.3
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/dependencies/RecordPageConfigsMapDependency.js +45 -0
- package/lib/index.js +23 -1
- package/lib/platform/style/wx/index.js +6 -4
- package/lib/platform/template/wx/component-config/input.js +1 -1
- package/lib/platform/template/wx/component-config/textarea.js +1 -1
- package/lib/platform/template/wx/component-config/view.js +12 -2
- package/lib/react/index.js +0 -1
- package/lib/react/processJSON.js +13 -2
- package/lib/react/processScript.js +7 -4
- package/lib/react/processTemplate.js +18 -3
- package/lib/react/script-helper.js +18 -4
- package/lib/runtime/components/react/context.ts +3 -4
- package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-input.jsx +54 -54
- package/lib/runtime/components/react/dist/{KeyboardAvoidingView.jsx → mpx-keyboard-avoiding-view.jsx} +23 -12
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +1 -2
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +16 -8
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +22 -0
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +6 -6
- package/lib/runtime/components/react/dist/mpx-view.jsx +10 -5
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +6 -5
- package/lib/runtime/components/react/dist/useAnimationHooks.js +46 -48
- package/lib/runtime/components/react/dist/utils.jsx +17 -21
- package/lib/runtime/components/react/mpx-image.tsx +2 -2
- package/lib/runtime/components/react/mpx-input.tsx +66 -72
- package/lib/runtime/components/react/{KeyboardAvoidingView.tsx → mpx-keyboard-avoiding-view.tsx} +32 -18
- package/lib/runtime/components/react/mpx-portal/portal-manager.tsx +1 -2
- package/lib/runtime/components/react/mpx-scroll-view.tsx +21 -8
- package/lib/runtime/components/react/mpx-simple-view.tsx +32 -0
- package/lib/runtime/components/react/mpx-textarea.tsx +10 -6
- package/lib/runtime/components/react/mpx-view.tsx +17 -10
- package/lib/runtime/components/react/mpx-web-view.tsx +12 -10
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +1 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +46 -48
- package/lib/runtime/components/react/utils.tsx +21 -24
- package/lib/runtime/optionProcessor.js +3 -2
- package/lib/style-compiler/index.js +8 -6
- package/lib/template-compiler/compiler.js +22 -14
- package/lib/utils/match-condition.js +14 -8
- package/lib/web/processJSON.js +1 -3
- package/package.json +4 -4
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const NullDependency = require('webpack/lib/dependencies/NullDependency')
|
|
2
|
+
const makeSerializable = require('webpack/lib/util/makeSerializable')
|
|
3
|
+
const isEmptyObject = require('../utils/is-empty-object')
|
|
4
|
+
|
|
5
|
+
class RecordPageConfigMapDependency extends NullDependency {
|
|
6
|
+
constructor (resourcePath, jsonObj) {
|
|
7
|
+
super()
|
|
8
|
+
this.resourcePath = resourcePath || ''
|
|
9
|
+
this.jsonObj = jsonObj || {}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get type () {
|
|
13
|
+
return 'mpx record pageConfigsMap'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
mpxAction (module, compilation, callback) {
|
|
17
|
+
const mpx = compilation.__mpx__
|
|
18
|
+
const pagePath = mpx.pagesMap[this.resourcePath]
|
|
19
|
+
if (pagePath && !isEmptyObject(this.jsonObj)) mpx.pageConfigsMap[pagePath] = this.jsonObj
|
|
20
|
+
return callback()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
serialize (context) {
|
|
24
|
+
const { write } = context
|
|
25
|
+
write(this.resourcePath)
|
|
26
|
+
write(this.jsonObj)
|
|
27
|
+
super.serialize(context)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
deserialize (context) {
|
|
31
|
+
const { read } = context
|
|
32
|
+
this.pagePath = read()
|
|
33
|
+
this.jsonObj = read()
|
|
34
|
+
super.deserialize(context)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
RecordPageConfigMapDependency.Template = class RecordPageConfigMapDependencyTemplate {
|
|
39
|
+
apply () {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
makeSerializable(RecordPageConfigMapDependency, '@mpxjs/webpack-plugin/lib/dependencies/RecordPageConfigMapDependency')
|
|
44
|
+
|
|
45
|
+
module.exports = RecordPageConfigMapDependency
|
package/lib/index.js
CHANGED
|
@@ -34,6 +34,7 @@ const FixDescriptionInfoPlugin = require('./resolver/FixDescriptionInfoPlugin')
|
|
|
34
34
|
// const RequireHeaderDependency = require('webpack/lib/dependencies/RequireHeaderDependency')
|
|
35
35
|
// const RemovedModuleDependency = require('./dependencies/RemovedModuleDependency')
|
|
36
36
|
const AppEntryDependency = require('./dependencies/AppEntryDependency')
|
|
37
|
+
const RecordPageConfigMapDependency = require('./dependencies/RecordPageConfigsMapDependency')
|
|
37
38
|
const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
|
|
38
39
|
const RecordGlobalComponentsDependency = require('./dependencies/RecordGlobalComponentsDependency')
|
|
39
40
|
const RecordIndependentDependency = require('./dependencies/RecordIndependentDependency')
|
|
@@ -617,6 +618,9 @@ class MpxWebpackPlugin {
|
|
|
617
618
|
compilation.dependencyFactories.set(RemoveEntryDependency, new NullFactory())
|
|
618
619
|
compilation.dependencyTemplates.set(RemoveEntryDependency, new RemoveEntryDependency.Template())
|
|
619
620
|
|
|
621
|
+
compilation.dependencyFactories.set(RecordPageConfigMapDependency, new NullFactory())
|
|
622
|
+
compilation.dependencyTemplates.set(RecordPageConfigMapDependency, new RecordPageConfigMapDependency.Template())
|
|
623
|
+
|
|
620
624
|
compilation.dependencyFactories.set(RecordResourceMapDependency, new NullFactory())
|
|
621
625
|
compilation.dependencyTemplates.set(RecordResourceMapDependency, new RecordResourceMapDependency.Template())
|
|
622
626
|
|
|
@@ -656,6 +660,8 @@ class MpxWebpackPlugin {
|
|
|
656
660
|
__vfs,
|
|
657
661
|
// app信息,便于获取appName
|
|
658
662
|
appInfo: {},
|
|
663
|
+
// pageConfig信息
|
|
664
|
+
pageConfigsMap: {},
|
|
659
665
|
// pages全局记录,无需区分主包分包
|
|
660
666
|
pagesMap: {},
|
|
661
667
|
// 组件资源记录,依照所属包进行记录
|
|
@@ -1598,7 +1604,7 @@ class MpxWebpackPlugin {
|
|
|
1598
1604
|
name: 'MpxWebpackPlugin',
|
|
1599
1605
|
stage: compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
|
1600
1606
|
}, () => {
|
|
1601
|
-
if (isWeb(mpx.mode)
|
|
1607
|
+
if (isWeb(mpx.mode)) return
|
|
1602
1608
|
|
|
1603
1609
|
if (this.options.generateBuildMap) {
|
|
1604
1610
|
const pagesMap = compilation.__mpx__.pagesMap
|
|
@@ -1637,6 +1643,22 @@ class MpxWebpackPlugin {
|
|
|
1637
1643
|
|
|
1638
1644
|
const originalSource = compilation.assets[chunkFile]
|
|
1639
1645
|
const source = new ConcatSource()
|
|
1646
|
+
|
|
1647
|
+
if (isReact(mpx.mode)) {
|
|
1648
|
+
// 添加 @refresh reset 注释用于在 React HMR 时刷新组件
|
|
1649
|
+
source.add('/* @refresh reset */\n')
|
|
1650
|
+
// 注入页面的配置,供screen前置设置导航情况
|
|
1651
|
+
if (isRuntime) {
|
|
1652
|
+
source.add('// inject pageconfigmap for screen\n' +
|
|
1653
|
+
'var context = (function() { return this })() || Function("return this")();\n')
|
|
1654
|
+
source.add(`context.__mpxPageConfigsMap = ${JSON.stringify(mpx.pageConfigsMap)};\n`)
|
|
1655
|
+
}
|
|
1656
|
+
source.add(originalSource)
|
|
1657
|
+
compilation.assets[chunkFile] = source
|
|
1658
|
+
processedChunk.add(chunk)
|
|
1659
|
+
return
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1640
1662
|
source.add(`\nvar ${globalObject} = {};\n`)
|
|
1641
1663
|
|
|
1642
1664
|
relativeChunks.forEach((relativeChunk, index) => {
|
|
@@ -47,7 +47,7 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
47
47
|
'flex-wrap': ['wrap', 'nowrap', 'wrap-reverse'],
|
|
48
48
|
'pointer-events': ['auto', 'box-none', 'box-only', 'none'],
|
|
49
49
|
'vertical-align': ['auto', 'top', 'bottom', 'center'],
|
|
50
|
-
position: ['relative', 'absolute'],
|
|
50
|
+
position: ['relative', 'absolute', 'fixed'],
|
|
51
51
|
'font-variant': ['small-caps', 'oldstyle-nums', 'lining-nums', 'tabular-nums', 'proportional-nums'],
|
|
52
52
|
'text-align': ['left', 'right', 'center', 'justify'],
|
|
53
53
|
'font-style': ['normal', 'italic'],
|
|
@@ -395,22 +395,22 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
395
395
|
case 'skewY':
|
|
396
396
|
case 'perspective':
|
|
397
397
|
// 单个值处理
|
|
398
|
+
// rotate 处理成 rotateZ
|
|
399
|
+
key = key === 'rotate' ? 'rotateZ' : key
|
|
398
400
|
transform.push({ [key]: val })
|
|
399
401
|
break
|
|
400
402
|
case 'matrix':
|
|
401
|
-
case 'matrix3d':
|
|
402
403
|
transform.push({ [key]: parseValues(val, ',').map(val => +val) })
|
|
403
404
|
break
|
|
404
405
|
case 'translate':
|
|
405
406
|
case 'scale':
|
|
406
407
|
case 'skew':
|
|
407
|
-
case 'rotate3d': // x y z angle
|
|
408
408
|
case 'translate3d': // x y 支持 z不支持
|
|
409
409
|
case 'scale3d': // x y 支持 z不支持
|
|
410
410
|
{
|
|
411
411
|
// 2 个以上的值处理
|
|
412
412
|
key = key.replace('3d', '')
|
|
413
|
-
const vals = parseValues(val, ',').splice(0,
|
|
413
|
+
const vals = parseValues(val, ',').splice(0, 3)
|
|
414
414
|
// scale(.5) === scaleX(.5) scaleY(.5)
|
|
415
415
|
if (vals.length === 1 && key === 'scale') {
|
|
416
416
|
vals.push(vals[0])
|
|
@@ -426,6 +426,8 @@ module.exports = function getSpec ({ warn, error }) {
|
|
|
426
426
|
}
|
|
427
427
|
case 'translateZ':
|
|
428
428
|
case 'scaleZ':
|
|
429
|
+
case 'rotate3d': // x y z angle
|
|
430
|
+
case 'matrix3d':
|
|
429
431
|
default:
|
|
430
432
|
// 不支持的属性处理
|
|
431
433
|
unsupportedPropError({ prop, value, selector }, { mode })
|
|
@@ -92,7 +92,7 @@ module.exports = function ({ print }) {
|
|
|
92
92
|
qa: qaPropLog
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
|
-
test: /^(
|
|
95
|
+
test: /^(always-embed|hold-keyboard|safe-password-.+)$/,
|
|
96
96
|
ios: iosPropLog,
|
|
97
97
|
android: androidPropLog
|
|
98
98
|
}
|
|
@@ -78,7 +78,7 @@ module.exports = function ({ print }) {
|
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
{
|
|
81
|
-
test: /^(
|
|
81
|
+
test: /^(always-embed|hold-keyboard|disable-default-padding|adjust-keyboard-to|fixed|show-confirm-bar)$/,
|
|
82
82
|
ios: iosPropLog,
|
|
83
83
|
android: androidPropLog
|
|
84
84
|
}
|
|
@@ -25,11 +25,11 @@ module.exports = function ({ print }) {
|
|
|
25
25
|
},
|
|
26
26
|
ios (tag, { el }) {
|
|
27
27
|
el.isBuiltIn = true
|
|
28
|
-
return 'mpx-view'
|
|
28
|
+
return el.isSimple ? 'mpx-simple-view' : 'mpx-view'
|
|
29
29
|
},
|
|
30
30
|
android (tag, { el }) {
|
|
31
31
|
el.isBuiltIn = true
|
|
32
|
-
return 'mpx-view'
|
|
32
|
+
return el.isSimple ? 'mpx-simple-view' : 'mpx-view'
|
|
33
33
|
},
|
|
34
34
|
qa (tag) {
|
|
35
35
|
return 'div'
|
|
@@ -47,6 +47,16 @@ module.exports = function ({ print }) {
|
|
|
47
47
|
test: /^(hover-stop-propagation)$/,
|
|
48
48
|
android: androidPropLog,
|
|
49
49
|
ios: iosPropLog
|
|
50
|
+
}, {
|
|
51
|
+
test: /^(is-simple)$/,
|
|
52
|
+
android (prop, { el }) {
|
|
53
|
+
el.isSimple = true
|
|
54
|
+
return false
|
|
55
|
+
},
|
|
56
|
+
ios (prop, { el }) {
|
|
57
|
+
el.isSimple = true
|
|
58
|
+
return false
|
|
59
|
+
}
|
|
50
60
|
}
|
|
51
61
|
],
|
|
52
62
|
// 组件事件中的差异部分
|
package/lib/react/index.js
CHANGED
package/lib/react/processJSON.js
CHANGED
|
@@ -12,6 +12,7 @@ const createJSONHelper = require('../json-compiler/helper')
|
|
|
12
12
|
const getRulesRunner = require('../platform/index')
|
|
13
13
|
const { RESOLVE_IGNORED_ERR } = require('../utils/const')
|
|
14
14
|
const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDependency')
|
|
15
|
+
const RecordPageConfigsMapDependency = require('../dependencies/RecordPageConfigsMapDependency')
|
|
15
16
|
|
|
16
17
|
module.exports = function (jsonContent, {
|
|
17
18
|
loaderContext,
|
|
@@ -79,7 +80,6 @@ module.exports = function (jsonContent, {
|
|
|
79
80
|
})
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
const isApp = ctorType === 'app'
|
|
83
83
|
if (!jsonContent) {
|
|
84
84
|
return callback()
|
|
85
85
|
}
|
|
@@ -99,7 +99,7 @@ module.exports = function (jsonContent, {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
if (
|
|
102
|
+
if (ctorType !== 'app') {
|
|
103
103
|
rulesRunnerOptions.mainKey = ctorType
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -112,6 +112,17 @@ module.exports = function (jsonContent, {
|
|
|
112
112
|
return callback(e)
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
if (ctorType === 'page') {
|
|
116
|
+
const keysToExtract = ['navigationStyle']
|
|
117
|
+
const configObj = {}
|
|
118
|
+
keysToExtract.forEach(key => {
|
|
119
|
+
if (jsonObj[key]) {
|
|
120
|
+
configObj[key] = jsonObj[key]
|
|
121
|
+
}
|
|
122
|
+
})
|
|
123
|
+
loaderContext._module.addPresentationalDependency(new RecordPageConfigsMapDependency(parseRequest(loaderContext.resource).resourcePath, configObj))
|
|
124
|
+
}
|
|
125
|
+
|
|
115
126
|
const fs = loaderContext._compiler.inputFileSystem
|
|
116
127
|
|
|
117
128
|
const defaultTabbar = {
|
|
@@ -12,9 +12,12 @@ module.exports = function (script, {
|
|
|
12
12
|
outputPath,
|
|
13
13
|
builtInComponentsMap,
|
|
14
14
|
localComponentsMap,
|
|
15
|
-
localPagesMap
|
|
15
|
+
localPagesMap,
|
|
16
|
+
componentGenerics,
|
|
17
|
+
genericsInfo
|
|
16
18
|
}, callback) {
|
|
17
19
|
let scriptSrcMode = srcMode
|
|
20
|
+
const mode = loaderContext.getMpx().mode
|
|
18
21
|
if (script) {
|
|
19
22
|
scriptSrcMode = script.mode || scriptSrcMode
|
|
20
23
|
} else {
|
|
@@ -26,7 +29,7 @@ module.exports = function (script, {
|
|
|
26
29
|
output += `
|
|
27
30
|
import { getComponent } from ${stringifyRequest(loaderContext, optionProcessorPath)}
|
|
28
31
|
import { NavigationContainer, StackActions } from '@react-navigation/native'
|
|
29
|
-
import { createNativeStackNavigator } from '@react-navigation/native-stack'
|
|
32
|
+
${mode === 'ios' ? "import { createNativeStackNavigator as createStackNavigator } from '@react-navigation/native-stack'" : "import { createStackNavigator } from '@react-navigation/stack'"}
|
|
30
33
|
import PortalHost from '@mpxjs/webpack-plugin/lib/runtime/components/react/dist/mpx-portal/portal-host'
|
|
31
34
|
import { useHeaderHeight } from '@react-navigation/elements';
|
|
32
35
|
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context'
|
|
@@ -34,7 +37,7 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler'
|
|
|
34
37
|
|
|
35
38
|
global.__navigationHelper = {
|
|
36
39
|
NavigationContainer: NavigationContainer,
|
|
37
|
-
createStackNavigator:
|
|
40
|
+
createStackNavigator: createStackNavigator,
|
|
38
41
|
useHeaderHeight: useHeaderHeight,
|
|
39
42
|
StackActions: StackActions,
|
|
40
43
|
GestureHandlerRootView: GestureHandlerRootView,
|
|
@@ -67,7 +70,7 @@ global.__navigationHelper = {
|
|
|
67
70
|
jsonConfig
|
|
68
71
|
})
|
|
69
72
|
|
|
70
|
-
output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, outputPath })
|
|
73
|
+
output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, outputPath, genericsInfo, componentGenerics })
|
|
71
74
|
output += getRequireScript({ ctorType, script, loaderContext })
|
|
72
75
|
output += `export default global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
|
|
73
76
|
}
|
|
@@ -5,6 +5,8 @@ const loaderUtils = require('loader-utils')
|
|
|
5
5
|
const templateCompiler = require('../template-compiler/compiler')
|
|
6
6
|
const genNode = require('../template-compiler/gen-node-react')
|
|
7
7
|
const bindThis = require('../template-compiler/bind-this')
|
|
8
|
+
const isEmptyObject = require('../utils/is-empty-object')
|
|
9
|
+
const dash2hump = require('../utils/hump-dash').dash2hump
|
|
8
10
|
|
|
9
11
|
module.exports = function (template, {
|
|
10
12
|
loaderContext,
|
|
@@ -75,16 +77,15 @@ module.exports = function (template, {
|
|
|
75
77
|
defs,
|
|
76
78
|
decodeHTMLText,
|
|
77
79
|
externalClasses,
|
|
78
|
-
// todo 后续输出web也采用mpx的scoped处理
|
|
79
80
|
hasScoped: false,
|
|
80
81
|
moduleId,
|
|
81
82
|
filePath: rawResourcePath,
|
|
82
83
|
// react中模版i18n不需要特殊处理
|
|
83
84
|
i18n: null,
|
|
84
85
|
checkUsingComponents,
|
|
85
|
-
//
|
|
86
|
+
// rn模式下全局组件不会被合入usingComponents中,故globalComponents可以传空
|
|
86
87
|
globalComponents: [],
|
|
87
|
-
//
|
|
88
|
+
// rn模式下实现抽象组件
|
|
88
89
|
componentGenerics,
|
|
89
90
|
hasVirtualHost: matchCondition(resourcePath, autoVirtualHostRules),
|
|
90
91
|
forceProxyEvent: matchCondition(resourcePath, forceProxyEventRules),
|
|
@@ -148,6 +149,20 @@ ${e.stack}`)
|
|
|
148
149
|
if (meta.options) {
|
|
149
150
|
output += `global.currentInject.injectOptions = ${JSON.stringify(meta.options)};\n`
|
|
150
151
|
}
|
|
152
|
+
if (!isEmptyObject(componentGenerics)) {
|
|
153
|
+
output += 'global.currentInject.injectProperties = {\n'
|
|
154
|
+
output += ' generichash: String,\n'
|
|
155
|
+
|
|
156
|
+
Object.keys(componentGenerics).forEach(genericName => {
|
|
157
|
+
const defaultValue = componentGenerics[genericName].default
|
|
158
|
+
if (defaultValue) {
|
|
159
|
+
output += ` generic${dash2hump(genericName)}: { type: String, value: '${genericName}default' },\n`
|
|
160
|
+
} else {
|
|
161
|
+
output += ` generic${dash2hump(genericName)}: String,\n`
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
output += '}\n'
|
|
165
|
+
}
|
|
151
166
|
}
|
|
152
167
|
}
|
|
153
168
|
|
|
@@ -89,7 +89,8 @@ function buildGlobalParams ({
|
|
|
89
89
|
componentsMap,
|
|
90
90
|
pagesMap,
|
|
91
91
|
firstPage,
|
|
92
|
-
outputPath
|
|
92
|
+
outputPath,
|
|
93
|
+
genericsInfo
|
|
93
94
|
}) {
|
|
94
95
|
let content = ''
|
|
95
96
|
if (ctorType === 'app') {
|
|
@@ -115,9 +116,22 @@ global.currentInject.firstPage = ${JSON.stringify(firstPage)}\n`
|
|
|
115
116
|
delete pageConfig.usingComponents
|
|
116
117
|
content += `global.currentInject.pageConfig = ${JSON.stringify(pageConfig)}\n`
|
|
117
118
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
|
|
120
|
+
content += `
|
|
121
|
+
|
|
122
|
+
function getComponents() {
|
|
123
|
+
return ${shallowStringify(componentsMap)}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
global.currentInject.getComponents = getComponents\n`
|
|
127
|
+
if (genericsInfo) {
|
|
128
|
+
content += `
|
|
129
|
+
const genericHash = ${JSON.stringify(genericsInfo.hash)}\n
|
|
130
|
+
global.__mpxGenericsMap[genericHash] = function (name) {
|
|
131
|
+
return getComponents()[name]
|
|
132
|
+
}
|
|
133
|
+
\n`
|
|
134
|
+
}
|
|
121
135
|
if (ctorType === 'component') {
|
|
122
136
|
content += `global.currentInject.componentPath = '/' + ${JSON.stringify(outputPath)}\n`
|
|
123
137
|
}
|
|
@@ -5,10 +5,9 @@ export type LabelContextValue = MutableRefObject<{
|
|
|
5
5
|
triggerChange: (evt: NativeSyntheticEvent<TouchEvent>) => void
|
|
6
6
|
}>
|
|
7
7
|
|
|
8
|
-
export type KeyboardAvoidContextValue = MutableRefObject<
|
|
9
|
-
cursorSpacing: number
|
|
10
|
-
|
|
11
|
-
}>
|
|
8
|
+
export type KeyboardAvoidContextValue = MutableRefObject<
|
|
9
|
+
{ cursorSpacing: number, ref: MutableRefObject<any> } | null
|
|
10
|
+
>
|
|
12
11
|
|
|
13
12
|
export interface GroupValue {
|
|
14
13
|
[key: string]: { checked: boolean; setValue: Dispatch<SetStateAction<boolean>> }
|
|
@@ -272,7 +272,7 @@ const Image = forwardRef((props, ref) => {
|
|
|
272
272
|
uri: src,
|
|
273
273
|
onLayout: onSvgLoad,
|
|
274
274
|
onError: binderror && onSvgError,
|
|
275
|
-
style: extendObject({ transformOrigin: 'top
|
|
275
|
+
style: extendObject({ transformOrigin: 'left top' }, modeStyle)
|
|
276
276
|
}));
|
|
277
277
|
const BaseImage = renderImage(extendObject({
|
|
278
278
|
source: { uri: src },
|
|
@@ -280,7 +280,7 @@ const Image = forwardRef((props, ref) => {
|
|
|
280
280
|
onLoad: bindload && onImageLoad,
|
|
281
281
|
onError: binderror && onImageError,
|
|
282
282
|
style: extendObject({
|
|
283
|
-
transformOrigin: 'top
|
|
283
|
+
transformOrigin: 'left top',
|
|
284
284
|
width: isCropMode ? imageWidth : '100%',
|
|
285
285
|
height: isCropMode ? imageHeight : '100%'
|
|
286
286
|
}, isCropMode ? modeStyle : {})
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* ✔ password
|
|
5
5
|
* ✔ placeholder
|
|
6
6
|
* - placeholder-style: Only support color.
|
|
7
|
-
*
|
|
7
|
+
* - placeholder-class: Only support color.
|
|
8
8
|
* ✔ disabled
|
|
9
9
|
* ✔ maxlength
|
|
10
10
|
* ✔ cursor-spacing
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
import { forwardRef, useRef, useState, useContext, useEffect, createElement } from 'react';
|
|
41
41
|
import { Platform, TextInput } from 'react-native';
|
|
42
42
|
import { warn } from '@mpxjs/utils';
|
|
43
|
-
import {
|
|
43
|
+
import { useUpdateEffect, useTransformStyle, useLayout, extendObject } from './utils';
|
|
44
44
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
45
45
|
import useNodesRef from './useNodesRef';
|
|
46
46
|
import { FormContext, KeyboardAvoidContext } from './context';
|
|
@@ -54,7 +54,7 @@ const keyboardTypeMap = {
|
|
|
54
54
|
}) || ''
|
|
55
55
|
};
|
|
56
56
|
const Input = forwardRef((props, ref) => {
|
|
57
|
-
const { style = {}, allowFontScaling = false, type = 'text', value, password, 'placeholder-style': placeholderStyle, disabled, maxlength = 140, 'cursor-spacing': cursorSpacing = 0, 'auto-focus': autoFocus, focus, 'confirm-type': confirmType = 'done', 'confirm-hold': confirmHold = false, cursor, 'cursor-color': cursorColor, 'selection-start': selectionStart = -1, 'selection-end': selectionEnd = -1, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'adjust-position': adjustPosition = true, bindinput, bindfocus, bindblur, bindconfirm, bindselectionchange,
|
|
57
|
+
const { style = {}, allowFontScaling = false, type = 'text', value, password, 'placeholder-style': placeholderStyle = {}, disabled, maxlength = 140, 'cursor-spacing': cursorSpacing = 0, 'auto-focus': autoFocus, focus, 'confirm-type': confirmType = 'done', 'confirm-hold': confirmHold = false, cursor, 'cursor-color': cursorColor, 'selection-start': selectionStart = -1, 'selection-end': selectionEnd = -1, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'adjust-position': adjustPosition = true, bindinput, bindfocus, bindblur, bindconfirm, bindselectionchange,
|
|
58
58
|
// private
|
|
59
59
|
multiline, 'auto-height': autoHeight, bindlinechange } = props;
|
|
60
60
|
const formContext = useContext(FormContext);
|
|
@@ -76,7 +76,6 @@ const Input = forwardRef((props, ref) => {
|
|
|
76
76
|
};
|
|
77
77
|
const keyboardType = keyboardTypeMap[type];
|
|
78
78
|
const defaultValue = parseValue(value);
|
|
79
|
-
const placeholderTextColor = parseInlineStyle(placeholderStyle)?.color;
|
|
80
79
|
const textAlignVertical = multiline ? 'top' : 'auto';
|
|
81
80
|
const tmpValue = useRef(defaultValue);
|
|
82
81
|
const cursorIndex = useRef(0);
|
|
@@ -85,7 +84,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
85
84
|
const [contentHeight, setContentHeight] = useState(0);
|
|
86
85
|
const [selection, setSelection] = useState({ start: -1, end: -1 });
|
|
87
86
|
const styleObj = extendObject({ padding: 0, backgroundColor: '#fff' }, style, multiline && autoHeight
|
|
88
|
-
? { minHeight: Math.max(style?.minHeight || 35, contentHeight) }
|
|
87
|
+
? { height: 'auto', minHeight: Math.max(style?.minHeight || 35, contentHeight) }
|
|
89
88
|
: {});
|
|
90
89
|
const { hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
91
90
|
const nodeRef = useRef(null);
|
|
@@ -106,44 +105,54 @@ const Input = forwardRef((props, ref) => {
|
|
|
106
105
|
setSelection({ start: selectionStart, end: selectionEnd });
|
|
107
106
|
}
|
|
108
107
|
}, [cursor, selectionStart, selectionEnd]);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
// have not selection on the Android platformg
|
|
109
|
+
const getCursorIndex = (changedSelection, prevValue, curValue) => {
|
|
110
|
+
if (changedSelection)
|
|
111
|
+
return changedSelection.end;
|
|
112
|
+
if (!prevValue || !curValue || prevValue.length === curValue.length)
|
|
113
|
+
return curValue.length;
|
|
114
|
+
const prevStr = prevValue.substring(cursorIndex.current);
|
|
115
|
+
const curStr = curValue.substring(cursorIndex.current);
|
|
116
|
+
return cursorIndex.current + curStr.length - prevStr.length;
|
|
114
117
|
};
|
|
115
118
|
const onChange = (evt) => {
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
const { text, selection } = evt.nativeEvent;
|
|
120
|
+
// will trigger twice on the Android platformg, prevent the second trigger
|
|
121
|
+
if (tmpValue.current === text)
|
|
118
122
|
return;
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
123
|
+
const index = getCursorIndex(selection, tmpValue.current, text);
|
|
124
|
+
tmpValue.current = text;
|
|
125
|
+
cursorIndex.current = index;
|
|
126
|
+
if (bindinput) {
|
|
127
|
+
const result = bindinput(getCustomEvent('input', evt, {
|
|
128
|
+
detail: {
|
|
129
|
+
value: tmpValue.current,
|
|
130
|
+
cursor: cursorIndex.current
|
|
131
|
+
},
|
|
132
|
+
layoutRef
|
|
133
|
+
}, props));
|
|
134
|
+
if (typeof result === 'string') {
|
|
135
|
+
tmpValue.current = result;
|
|
136
|
+
setInputValue(result);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
setInputValue(tmpValue.current);
|
|
140
|
+
}
|
|
129
141
|
}
|
|
130
142
|
else {
|
|
131
143
|
setInputValue(tmpValue.current);
|
|
132
144
|
}
|
|
133
145
|
};
|
|
134
146
|
const setKeyboardAvoidContext = () => {
|
|
135
|
-
if (adjustPosition && keyboardAvoid
|
|
136
|
-
|
|
137
|
-
cursorSpacing,
|
|
138
|
-
ref: nodeRef
|
|
139
|
-
});
|
|
147
|
+
if (adjustPosition && keyboardAvoid) {
|
|
148
|
+
keyboardAvoid.current = { cursorSpacing, ref: nodeRef };
|
|
140
149
|
}
|
|
141
150
|
};
|
|
142
|
-
const
|
|
151
|
+
const onTouchStart = () => {
|
|
143
152
|
// sometimes the focus event occurs later than the keyboardWillShow event
|
|
144
153
|
setKeyboardAvoidContext();
|
|
145
154
|
};
|
|
146
|
-
const
|
|
155
|
+
const onFocus = (evt) => {
|
|
147
156
|
setKeyboardAvoidContext();
|
|
148
157
|
bindfocus && bindfocus(getCustomEvent('focus', evt, {
|
|
149
158
|
detail: {
|
|
@@ -152,7 +161,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
152
161
|
layoutRef
|
|
153
162
|
}, props));
|
|
154
163
|
};
|
|
155
|
-
const
|
|
164
|
+
const onBlur = (evt) => {
|
|
156
165
|
bindblur && bindblur(getCustomEvent('blur', evt, {
|
|
157
166
|
detail: {
|
|
158
167
|
value: tmpValue.current || '',
|
|
@@ -161,15 +170,6 @@ const Input = forwardRef((props, ref) => {
|
|
|
161
170
|
layoutRef
|
|
162
171
|
}, props));
|
|
163
172
|
};
|
|
164
|
-
const onKeyPress = (evt) => {
|
|
165
|
-
evt.nativeEvent.key === 'Enter' &&
|
|
166
|
-
bindconfirm(getCustomEvent('confirm', evt, {
|
|
167
|
-
detail: {
|
|
168
|
-
value: tmpValue.current || ''
|
|
169
|
-
},
|
|
170
|
-
layoutRef
|
|
171
|
-
}, props));
|
|
172
|
-
};
|
|
173
173
|
const onSubmitEditing = (evt) => {
|
|
174
174
|
bindconfirm(getCustomEvent('confirm', evt, {
|
|
175
175
|
detail: {
|
|
@@ -179,11 +179,14 @@ const Input = forwardRef((props, ref) => {
|
|
|
179
179
|
}, props));
|
|
180
180
|
};
|
|
181
181
|
const onSelectionChange = (evt) => {
|
|
182
|
-
|
|
182
|
+
const { selection } = evt.nativeEvent;
|
|
183
|
+
const { start, end } = selection;
|
|
184
|
+
cursorIndex.current = start;
|
|
185
|
+
setSelection(selection);
|
|
183
186
|
bindselectionchange && bindselectionchange(getCustomEvent('selectionchange', evt, {
|
|
184
187
|
detail: {
|
|
185
|
-
selectionStart:
|
|
186
|
-
selectionEnd:
|
|
188
|
+
selectionStart: start,
|
|
189
|
+
selectionEnd: end
|
|
187
190
|
},
|
|
188
191
|
layoutRef
|
|
189
192
|
}, props));
|
|
@@ -252,24 +255,21 @@ const Input = forwardRef((props, ref) => {
|
|
|
252
255
|
maxLength: maxlength === -1 ? undefined : maxlength,
|
|
253
256
|
editable: !disabled,
|
|
254
257
|
autoFocus: !!autoFocus || !!focus,
|
|
255
|
-
returnKeyType: confirmType,
|
|
256
258
|
selection: selection,
|
|
257
259
|
selectionColor: cursorColor,
|
|
258
260
|
blurOnSubmit: !multiline && !confirmHold,
|
|
259
261
|
underlineColorAndroid: 'rgba(0,0,0,0)',
|
|
260
262
|
textAlignVertical: textAlignVertical,
|
|
261
|
-
placeholderTextColor:
|
|
263
|
+
placeholderTextColor: placeholderStyle?.color,
|
|
262
264
|
multiline: !!multiline
|
|
263
|
-
}, layoutProps, {
|
|
264
|
-
onTouchStart
|
|
265
|
-
onFocus
|
|
266
|
-
onBlur
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
onChange: onChange,
|
|
272
|
-
onContentSizeChange: onContentSizeChange
|
|
265
|
+
}, !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }, layoutProps, {
|
|
266
|
+
onTouchStart,
|
|
267
|
+
onFocus,
|
|
268
|
+
onBlur,
|
|
269
|
+
onChange,
|
|
270
|
+
onSelectionChange,
|
|
271
|
+
onContentSizeChange,
|
|
272
|
+
onSubmitEditing: bindconfirm && !multiline && onSubmitEditing
|
|
273
273
|
}), [
|
|
274
274
|
'type',
|
|
275
275
|
'password',
|