@mpxjs/webpack-plugin 2.9.59 → 2.9.62
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/platform/style/wx/index.js +314 -254
- package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
- package/lib/platform/template/wx/component-config/checkbox.js +8 -0
- package/lib/platform/template/wx/component-config/cover-image.js +15 -0
- package/lib/platform/template/wx/component-config/cover-view.js +9 -0
- package/lib/platform/template/wx/component-config/form.js +13 -1
- package/lib/platform/template/wx/component-config/icon.js +8 -0
- package/lib/platform/template/wx/component-config/index.js +5 -1
- package/lib/platform/template/wx/component-config/label.js +15 -0
- package/lib/platform/template/wx/component-config/movable-area.js +18 -1
- package/lib/platform/template/wx/component-config/movable-view.js +18 -1
- package/lib/platform/template/wx/component-config/navigator.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
- package/lib/platform/template/wx/component-config/picker-view.js +18 -2
- package/lib/platform/template/wx/component-config/picker.js +14 -1
- package/lib/platform/template/wx/component-config/radio-group.js +8 -0
- package/lib/platform/template/wx/component-config/radio.js +8 -0
- package/lib/platform/template/wx/component-config/root-portal.js +15 -0
- package/lib/platform/template/wx/component-config/switch.js +8 -0
- package/lib/platform/template/wx/component-config/unsupported.js +1 -3
- package/lib/react/processScript.js +2 -0
- package/lib/runtime/components/react/context.ts +38 -0
- package/lib/runtime/components/react/dist/context.js +7 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +22 -11
- package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
- package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
- package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
- package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
- package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
- package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
- package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
- package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
- package/lib/runtime/components/react/dist/types/common.js +1 -0
- package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
- package/lib/runtime/components/react/dist/utils.js +82 -14
- package/lib/runtime/components/react/getInnerListeners.ts +25 -13
- package/lib/runtime/components/react/mpx-button.tsx +87 -67
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
- package/lib/runtime/components/react/mpx-form.tsx +89 -0
- package/lib/runtime/components/react/mpx-icon.tsx +103 -0
- package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
- package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
- package/lib/runtime/components/react/mpx-input.tsx +54 -26
- package/lib/runtime/components/react/mpx-label.tsx +115 -0
- package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
- package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
- package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
- package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
- package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
- package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
- package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
- package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
- package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
- package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
- package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
- package/lib/runtime/components/react/mpx-radio.tsx +246 -0
- package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
- package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
- package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
- package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
- package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
- package/lib/runtime/components/react/mpx-switch.tsx +127 -0
- package/lib/runtime/components/react/mpx-text.tsx +52 -68
- package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
- package/lib/runtime/components/react/mpx-view.tsx +373 -140
- package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
- package/lib/runtime/components/react/types/common.ts +12 -0
- package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
- package/lib/runtime/components/react/types/global.d.ts +4 -0
- package/lib/runtime/components/react/useNodesRef.ts +3 -8
- package/lib/runtime/components/react/utils.ts +93 -15
- package/lib/runtime/optionProcessor.js +19 -17
- package/lib/template-compiler/compiler.js +56 -41
- package/lib/template-compiler/gen-node-react.js +7 -7
- package/package.json +6 -3
|
@@ -3,30 +3,18 @@
|
|
|
3
3
|
* ✘ space
|
|
4
4
|
* ✘ decode
|
|
5
5
|
*/
|
|
6
|
-
import { Text
|
|
6
|
+
import { Text } from 'react-native';
|
|
7
7
|
import { useRef, useEffect, forwardRef } from 'react';
|
|
8
8
|
import useInnerProps from './getInnerListeners';
|
|
9
|
-
// @ts-ignore
|
|
10
9
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
11
|
-
import {
|
|
12
|
-
const DEFAULT_STYLE = {
|
|
13
|
-
fontSize: 16
|
|
14
|
-
};
|
|
15
|
-
const transformStyle = (styleObj) => {
|
|
16
|
-
let { lineHeight } = styleObj;
|
|
17
|
-
if (typeof lineHeight === 'string' && PERCENT_REGEX.test(lineHeight)) {
|
|
18
|
-
lineHeight = (parseFloat(lineHeight) / 100) * (styleObj.fontSize || DEFAULT_STYLE.fontSize);
|
|
19
|
-
styleObj.lineHeight = lineHeight;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
10
|
+
import { transformTextStyle, DEFAULT_STYLE } from './utils';
|
|
22
11
|
const _Text = forwardRef((props, ref) => {
|
|
23
|
-
const { style =
|
|
12
|
+
const { style = {}, children, selectable, 'enable-offset': enableOffset, 'user-select': userSelect, 'disable-default-style': disableDefaultStyle = false, } = props;
|
|
24
13
|
const layoutRef = useRef({});
|
|
25
|
-
const styleObj = StyleSheet.flatten(style);
|
|
26
14
|
let defaultStyle = {};
|
|
27
15
|
if (!disableDefaultStyle) {
|
|
28
16
|
defaultStyle = DEFAULT_STYLE;
|
|
29
|
-
|
|
17
|
+
transformTextStyle(style);
|
|
30
18
|
}
|
|
31
19
|
const { nodeRef } = useNodesRef(props, ref, {
|
|
32
20
|
defaultStyle
|
|
@@ -59,9 +47,9 @@ const _Text = forwardRef((props, ref) => {
|
|
|
59
47
|
};
|
|
60
48
|
}
|
|
61
49
|
}, []);
|
|
62
|
-
return (<Text style={{ ...defaultStyle, ...
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
return (<Text style={{ ...defaultStyle, ...style }} selectable={!!selectable || !!userSelect} {...innerProps}>
|
|
51
|
+
{children}
|
|
52
|
+
</Text>);
|
|
65
53
|
});
|
|
66
54
|
_Text.displayName = 'mpx-text';
|
|
67
55
|
export default _Text;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* ✘ show-confirm-bar
|
|
10
10
|
* ✔ bindlinechange: No `heightRpx` info.
|
|
11
11
|
*/
|
|
12
|
-
import
|
|
12
|
+
import { forwardRef } from 'react';
|
|
13
13
|
import { Keyboard } from 'react-native';
|
|
14
14
|
import Input from './mpx-input';
|
|
15
15
|
import { omit } from './utils';
|
|
@@ -6,26 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { View, Text, StyleSheet, Image } from 'react-native';
|
|
8
8
|
import { useRef, useState, useEffect, forwardRef } from 'react';
|
|
9
|
-
// @ts-ignore
|
|
10
9
|
import useInnerProps from './getInnerListeners';
|
|
11
|
-
|
|
12
|
-
import
|
|
13
|
-
import { parseUrl, TEXT_STYLE_REGEX, PERCENT_REGEX, isText } from './utils';
|
|
14
|
-
const IMAGE_STYLE_REGEX = /^background(Image|Size|Repeat|Position)$/;
|
|
15
|
-
function groupBy(style, callback, group = {}) {
|
|
16
|
-
let groupKey = '';
|
|
17
|
-
for (let key in style) {
|
|
18
|
-
if (style.hasOwnProperty(key)) { // 确保处理对象自身的属性
|
|
19
|
-
let val = style[key];
|
|
20
|
-
groupKey = callback(key, val);
|
|
21
|
-
if (!group[groupKey]) {
|
|
22
|
-
group[groupKey] = {};
|
|
23
|
-
}
|
|
24
|
-
group[groupKey][key] = val;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return group;
|
|
28
|
-
}
|
|
10
|
+
import useNodesRef from './useNodesRef';
|
|
11
|
+
import { parseUrl, PERCENT_REGEX, isText, every, normalizeStyle, splitStyle, splitProps, throwReactWarning, transformTextStyle } from './utils';
|
|
29
12
|
const applyHandlers = (handlers, args) => {
|
|
30
13
|
for (let handler of handlers) {
|
|
31
14
|
handler(...args);
|
|
@@ -33,19 +16,30 @@ const applyHandlers = (handlers, args) => {
|
|
|
33
16
|
};
|
|
34
17
|
const checkNeedLayout = (style) => {
|
|
35
18
|
const [width, height] = style.sizeList;
|
|
36
|
-
|
|
19
|
+
const bp = style.backgroundPosition;
|
|
20
|
+
// 含有百分号,center 需计算布局
|
|
21
|
+
const containPercentSymbol = typeof bp[1] === 'string' && PERCENT_REGEX.test(bp[1]) || typeof bp[3] === 'string' && PERCENT_REGEX.test(bp[3]);
|
|
22
|
+
return {
|
|
23
|
+
// 是否开启layout的计算
|
|
24
|
+
needLayout: typeof width === 'string' && /^cover|contain$/.test(width) || (typeof height === 'string' && PERCENT_REGEX.test(height) && width === 'auto') || (typeof width === 'string' && PERCENT_REGEX.test(width) && height === 'auto') || containPercentSymbol,
|
|
25
|
+
// 是否开启原始宽度的计算
|
|
26
|
+
needImageSize: typeof width === 'string' && /^cover|contain$/.test(width) || style.sizeList.includes('auto')
|
|
27
|
+
};
|
|
37
28
|
};
|
|
38
29
|
/**
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
function calculateSize(h, lh,
|
|
44
|
-
let height, width;
|
|
45
|
-
if (
|
|
30
|
+
* h - 用户设置的高度
|
|
31
|
+
* lh - 容器的高度
|
|
32
|
+
* ratio - 原始图片的宽高比
|
|
33
|
+
* **/
|
|
34
|
+
function calculateSize(h, ratio, lh, reverse = false) {
|
|
35
|
+
let height = 0, width = 0;
|
|
36
|
+
if (typeof lh === 'boolean') {
|
|
37
|
+
reverse = lh;
|
|
38
|
+
}
|
|
39
|
+
if (typeof h === 'string' && PERCENT_REGEX.test(h)) { // auto px/rpx
|
|
46
40
|
if (!lh)
|
|
47
41
|
return null;
|
|
48
|
-
height = (parseFloat(
|
|
42
|
+
height = (parseFloat(h) / 100) * lh;
|
|
49
43
|
width = height * ratio;
|
|
50
44
|
}
|
|
51
45
|
else { // 2. auto px/rpx - 根据比例计算
|
|
@@ -53,8 +47,50 @@ function calculateSize(h, lh, ratio) {
|
|
|
53
47
|
width = height * ratio;
|
|
54
48
|
}
|
|
55
49
|
return {
|
|
56
|
-
width,
|
|
57
|
-
height
|
|
50
|
+
width: reverse ? height : width,
|
|
51
|
+
height: reverse ? width : height
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 用户设置百分比后,转换为偏移量
|
|
56
|
+
* h - 用户设置图片的高度
|
|
57
|
+
* ch - 容器的高度
|
|
58
|
+
* val - 用户设置的百分比
|
|
59
|
+
* **/
|
|
60
|
+
function calculateSizePosition(h, ch, val) {
|
|
61
|
+
if (!h || !ch)
|
|
62
|
+
return 0;
|
|
63
|
+
// 百分比需要单独的计算
|
|
64
|
+
if (typeof h === 'string' && PERCENT_REGEX.test(h)) {
|
|
65
|
+
h = ch * parseFloat(h) / 100;
|
|
66
|
+
}
|
|
67
|
+
// (container width - image width) * (position x%) = (x offset value)
|
|
68
|
+
return (ch - h) * parseFloat(val) / 100;
|
|
69
|
+
}
|
|
70
|
+
function backgroundPosition(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
71
|
+
const bps = preImageInfo.backgroundPosition;
|
|
72
|
+
if (bps.length === 0)
|
|
73
|
+
return;
|
|
74
|
+
let style = {};
|
|
75
|
+
let imageStyle = imageProps.style || {};
|
|
76
|
+
for (let i = 0; i < bps.length; i += 2) {
|
|
77
|
+
let key = bps[i], val = bps[i + 1];
|
|
78
|
+
// 需要获取 图片宽度 和 容器的宽度 进行计算
|
|
79
|
+
if (typeof val === 'string' && PERCENT_REGEX.test(val)) {
|
|
80
|
+
if (i === 0) {
|
|
81
|
+
style[key] = calculateSizePosition(imageStyle.width, layoutInfo?.width, val);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
style[key] = calculateSizePosition(imageStyle.height, layoutInfo?.height, val);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
style[key] = val;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
imageProps.style = {
|
|
92
|
+
...imageProps.style,
|
|
93
|
+
...style
|
|
58
94
|
};
|
|
59
95
|
}
|
|
60
96
|
// background-size 转换
|
|
@@ -62,51 +98,61 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
62
98
|
let sizeList = preImageInfo.sizeList;
|
|
63
99
|
if (!sizeList)
|
|
64
100
|
return;
|
|
101
|
+
const { width: layoutWidth, height: layoutHeight } = layoutInfo || {};
|
|
102
|
+
const { width: imageSizeWidth, height: imageSizeHeight } = imageSize || {};
|
|
103
|
+
const [width, height] = sizeList;
|
|
104
|
+
let dimensions = { width: 0, height: 0 };
|
|
65
105
|
// 枚举值
|
|
66
|
-
if (['cover', 'contain'].includes(
|
|
67
|
-
|
|
106
|
+
if (typeof width === 'string' && ['cover', 'contain'].includes(width)) {
|
|
107
|
+
if (layoutInfo && imageSize) {
|
|
108
|
+
let layoutRatio = layoutWidth / imageSizeWidth;
|
|
109
|
+
let eleRatio = imageSizeWidth / imageSizeHeight;
|
|
110
|
+
// 容器宽高比 大于 图片的宽高比,依据宽度作为基准,否则以高度为基准
|
|
111
|
+
if (layoutRatio <= eleRatio && width === 'contain' || layoutRatio >= eleRatio && width === 'cover') {
|
|
112
|
+
dimensions = calculateSize(layoutWidth, imageSizeHeight / imageSizeWidth, true);
|
|
113
|
+
}
|
|
114
|
+
else if (layoutRatio > eleRatio && width === 'contain' || layoutRatio < eleRatio && width === 'cover') {
|
|
115
|
+
dimensions = calculateSize(layoutHeight, imageSizeWidth / imageSizeHeight);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
68
118
|
}
|
|
69
119
|
else {
|
|
70
|
-
const [width, height] = sizeList;
|
|
71
|
-
let newWidth = 0, newHeight = 0;
|
|
72
|
-
const { width: imageSizeWidth, height: imageSizeHeight } = imageSize || {};
|
|
73
120
|
if (width === 'auto' && height === 'auto') { // 均为auto
|
|
74
121
|
if (!imageSize)
|
|
75
122
|
return;
|
|
76
|
-
|
|
77
|
-
|
|
123
|
+
dimensions = {
|
|
124
|
+
width: imageSizeWidth,
|
|
125
|
+
height: imageSizeHeight
|
|
126
|
+
};
|
|
78
127
|
}
|
|
79
128
|
else if (width === 'auto') { // auto px/rpx/%
|
|
80
129
|
if (!imageSize)
|
|
81
130
|
return;
|
|
82
|
-
|
|
131
|
+
dimensions = calculateSize(height, imageSizeWidth / imageSizeHeight, layoutInfo?.height);
|
|
83
132
|
if (!dimensions)
|
|
84
133
|
return;
|
|
85
|
-
newWidth = dimensions.width;
|
|
86
|
-
newHeight = dimensions.height;
|
|
87
134
|
}
|
|
88
135
|
else if (height === 'auto') { // auto px/rpx/%
|
|
89
136
|
if (!imageSize)
|
|
90
137
|
return;
|
|
91
|
-
|
|
138
|
+
dimensions = calculateSize(width, imageSizeHeight / imageSizeWidth, layoutInfo?.width, true);
|
|
92
139
|
if (!dimensions)
|
|
93
140
|
return;
|
|
94
|
-
newHeight = dimensions.width;
|
|
95
|
-
newWidth = dimensions.height;
|
|
96
141
|
}
|
|
97
142
|
else { // 数值类型 ImageStyle
|
|
98
143
|
// 数值类型设置为 stretch
|
|
99
144
|
imageProps.style.resizeMode = 'stretch';
|
|
100
|
-
|
|
101
|
-
|
|
145
|
+
dimensions = {
|
|
146
|
+
width: typeof width === 'string' && PERCENT_REGEX.test(width) ? width : +width,
|
|
147
|
+
height: typeof height === 'string' && PERCENT_REGEX.test(height) ? height : +height
|
|
148
|
+
};
|
|
102
149
|
}
|
|
103
|
-
// 样式合并
|
|
104
|
-
imageProps.style = {
|
|
105
|
-
...imageProps.style,
|
|
106
|
-
width: newWidth,
|
|
107
|
-
height: newHeight
|
|
108
|
-
};
|
|
109
150
|
}
|
|
151
|
+
// 样式合并
|
|
152
|
+
imageProps.style = {
|
|
153
|
+
...imageProps.style,
|
|
154
|
+
...dimensions
|
|
155
|
+
};
|
|
110
156
|
}
|
|
111
157
|
// background-image转换为source
|
|
112
158
|
function backgroundImage(imageProps, preImageInfo) {
|
|
@@ -117,22 +163,98 @@ const imageStyleToProps = (preImageInfo, imageSize, layoutInfo) => {
|
|
|
117
163
|
const imageProps = {
|
|
118
164
|
style: {
|
|
119
165
|
resizeMode: 'cover',
|
|
120
|
-
|
|
166
|
+
position: 'absolute'
|
|
167
|
+
// ...StyleSheet.absoluteFillObject
|
|
121
168
|
}
|
|
122
169
|
};
|
|
123
|
-
applyHandlers([backgroundSize, backgroundImage], [imageProps, preImageInfo, imageSize, layoutInfo]);
|
|
170
|
+
applyHandlers([backgroundSize, backgroundImage, backgroundPosition], [imageProps, preImageInfo, imageSize, layoutInfo]);
|
|
124
171
|
if (!imageProps?.src)
|
|
125
172
|
return null;
|
|
126
173
|
return imageProps;
|
|
127
174
|
};
|
|
175
|
+
function isHorizontal(val) {
|
|
176
|
+
return typeof val === 'string' && /^(left|right)$/.test(val);
|
|
177
|
+
}
|
|
178
|
+
function isVertical(val) {
|
|
179
|
+
return typeof val === 'string' && /^(top|bottom)$/.test(val);
|
|
180
|
+
}
|
|
181
|
+
function normalizeBackgroundPosition(parts) {
|
|
182
|
+
if (parts.length === 0)
|
|
183
|
+
return [];
|
|
184
|
+
// 定义默认值
|
|
185
|
+
let hStart = 'left';
|
|
186
|
+
let hOffset = 0;
|
|
187
|
+
let vStart = 'top';
|
|
188
|
+
let vOffset = 0;
|
|
189
|
+
if (parts.length === 4)
|
|
190
|
+
return parts;
|
|
191
|
+
// 归一化
|
|
192
|
+
if (parts.length === 1) {
|
|
193
|
+
// 1. center
|
|
194
|
+
// 2. 2px - hOffset, vOffset(center) - center为50%
|
|
195
|
+
// 3. 10% - hOffset, vOffset(center) - center为50%
|
|
196
|
+
// 4. left - hStart, vOffset(center) - center为50%
|
|
197
|
+
// 5. top - hOffset(center), vStart - center为50%
|
|
198
|
+
if (isHorizontal(parts[0])) {
|
|
199
|
+
hStart = parts[0];
|
|
200
|
+
vOffset = '50%';
|
|
201
|
+
}
|
|
202
|
+
else if (isVertical(parts[0])) {
|
|
203
|
+
vStart = parts[0];
|
|
204
|
+
hOffset = '50%';
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
hOffset = parts[0];
|
|
208
|
+
vOffset = '50%';
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (parts.length === 2) {
|
|
212
|
+
// 1. center center - hOffset, vOffset
|
|
213
|
+
// 2. 10px center - hOffset, vStart
|
|
214
|
+
// 3. left center - hStart, vOffset
|
|
215
|
+
// 4. right center - hStart, vOffset
|
|
216
|
+
// 5. 第一位是 left right 覆盖的是 hStart
|
|
217
|
+
// center, 100% 正常的px 覆盖的是 hOffset
|
|
218
|
+
// 第二位是 top bottom 覆盖的是 vStart
|
|
219
|
+
// center, 100% 覆盖的是 vOffset
|
|
220
|
+
//
|
|
221
|
+
// 水平方向
|
|
222
|
+
if (isHorizontal(parts[0])) {
|
|
223
|
+
hStart = parts[0];
|
|
224
|
+
}
|
|
225
|
+
else { // center, 100% 正常的px 覆盖的是 hOffset
|
|
226
|
+
hOffset = parts[0];
|
|
227
|
+
}
|
|
228
|
+
// 垂直方向
|
|
229
|
+
if (isVertical(parts[1])) {
|
|
230
|
+
vStart = parts[1];
|
|
231
|
+
}
|
|
232
|
+
else { // center, 100% 正常的px 覆盖的是 hOffset
|
|
233
|
+
vOffset = parts[1];
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else if (parts.length === 3) {
|
|
237
|
+
// 1. center top 10px / top 10px center 等价 - center为50%
|
|
238
|
+
// 2. right 10px center / center right 10px 等价 - center为50%
|
|
239
|
+
// 2. bottom 50px right
|
|
240
|
+
if (typeof parts[0] === 'string' && typeof parts[1] === 'string' && /^left|bottom|right|top$/.test(parts[0]) && /^left|bottom|right|top$/.test(parts[1])) {
|
|
241
|
+
[hStart, vStart, vOffset] = parts;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
[hStart, hOffset, vStart] = parts;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return [hStart, hOffset, vStart, vOffset];
|
|
248
|
+
}
|
|
128
249
|
function preParseImage(imageStyle) {
|
|
129
|
-
const { backgroundImage, backgroundSize = [
|
|
250
|
+
const { backgroundImage, backgroundSize = ['auto'], backgroundPosition = [0, 0] } = imageStyle || {};
|
|
130
251
|
const src = parseUrl(backgroundImage);
|
|
131
252
|
let sizeList = backgroundSize.slice();
|
|
132
|
-
sizeList.length === 1 && sizeList.push(
|
|
253
|
+
sizeList.length === 1 && sizeList.push('auto');
|
|
133
254
|
return {
|
|
134
255
|
src,
|
|
135
|
-
sizeList
|
|
256
|
+
sizeList,
|
|
257
|
+
backgroundPosition: normalizeBackgroundPosition(backgroundPosition)
|
|
136
258
|
};
|
|
137
259
|
}
|
|
138
260
|
function wrapImage(imageStyle) {
|
|
@@ -146,8 +268,8 @@ function wrapImage(imageStyle) {
|
|
|
146
268
|
// 预解析
|
|
147
269
|
const preImageInfo = preParseImage(imageStyle);
|
|
148
270
|
// 判断是否可挂载onLayout
|
|
149
|
-
const needLayout = checkNeedLayout(preImageInfo);
|
|
150
|
-
const { src
|
|
271
|
+
const { needLayout, needImageSize } = checkNeedLayout(preImageInfo);
|
|
272
|
+
const { src } = preImageInfo;
|
|
151
273
|
useEffect(() => {
|
|
152
274
|
if (!src) {
|
|
153
275
|
setShow(false);
|
|
@@ -155,7 +277,7 @@ function wrapImage(imageStyle) {
|
|
|
155
277
|
layoutInfo.current = null;
|
|
156
278
|
return;
|
|
157
279
|
}
|
|
158
|
-
if (!
|
|
280
|
+
if (!needImageSize) {
|
|
159
281
|
setShow(true);
|
|
160
282
|
return;
|
|
161
283
|
}
|
|
@@ -184,11 +306,15 @@ function wrapImage(imageStyle) {
|
|
|
184
306
|
width,
|
|
185
307
|
height
|
|
186
308
|
};
|
|
187
|
-
if (
|
|
188
|
-
|
|
189
|
-
|
|
309
|
+
if (!needImageSize) {
|
|
310
|
+
setLayoutInfoWidth(width);
|
|
311
|
+
setLayoutInfoHeight(height);
|
|
312
|
+
}
|
|
313
|
+
else if (sizeInfo.current) {
|
|
190
314
|
setLayoutInfoWidth(width);
|
|
191
315
|
setLayoutInfoHeight(height);
|
|
316
|
+
setImageSizeWidth(sizeInfo.current.width);
|
|
317
|
+
setImageSizeHeight(sizeInfo.current.height);
|
|
192
318
|
setShow(true);
|
|
193
319
|
}
|
|
194
320
|
};
|
|
@@ -196,38 +322,60 @@ function wrapImage(imageStyle) {
|
|
|
196
322
|
{show && <Image {...imageStyleToProps(preImageInfo, sizeInfo.current, layoutInfo.current)}/>}
|
|
197
323
|
</View>;
|
|
198
324
|
}
|
|
199
|
-
function
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return 'textStyle';
|
|
203
|
-
else if (IMAGE_STYLE_REGEX.test(key))
|
|
204
|
-
return 'imageStyle';
|
|
205
|
-
return 'innerStyle';
|
|
206
|
-
}, {});
|
|
207
|
-
}
|
|
208
|
-
function every(children, callback) {
|
|
209
|
-
return children.every((child) => callback(child));
|
|
210
|
-
}
|
|
211
|
-
function wrapChildren(children, textStyle, imageStyle) {
|
|
212
|
-
children = Array.isArray(children) ? children : [children];
|
|
325
|
+
function wrapChildren(children, props, textStyle, imageStyle) {
|
|
326
|
+
const { textProps } = splitProps(props);
|
|
327
|
+
const { 'enable-background-image': enableBackgroundImage } = props;
|
|
213
328
|
if (every(children, (child) => isText(child))) {
|
|
214
|
-
|
|
329
|
+
if (textStyle || textProps) {
|
|
330
|
+
transformTextStyle(textStyle);
|
|
331
|
+
children = <Text key='viewTextWrap' style={textStyle} {...(textProps || {})}>{children}</Text>;
|
|
332
|
+
}
|
|
215
333
|
}
|
|
216
334
|
else {
|
|
217
335
|
if (textStyle)
|
|
218
|
-
|
|
336
|
+
throwReactWarning('[Mpx runtime warn]: Text style will be ignored unless every child of the view is Text node!');
|
|
219
337
|
}
|
|
220
338
|
return [
|
|
221
|
-
wrapImage(imageStyle),
|
|
222
|
-
|
|
339
|
+
enableBackgroundImage ? wrapImage(imageStyle) : null,
|
|
340
|
+
children
|
|
223
341
|
];
|
|
224
342
|
}
|
|
225
343
|
const _View = forwardRef((props, ref) => {
|
|
226
|
-
const
|
|
344
|
+
const combinationStyleProps = [{
|
|
345
|
+
key: 'transform',
|
|
346
|
+
rules: {
|
|
347
|
+
width: 'translateX',
|
|
348
|
+
height: 'translateY'
|
|
349
|
+
}
|
|
350
|
+
}, {
|
|
351
|
+
key: 'borderTopLeftRadius',
|
|
352
|
+
rules: {
|
|
353
|
+
width: 'borderTopLeftRadius'
|
|
354
|
+
}
|
|
355
|
+
}, {
|
|
356
|
+
key: 'borderBottomLeftRadius',
|
|
357
|
+
rules: {
|
|
358
|
+
width: 'borderBottomLeftRadius'
|
|
359
|
+
}
|
|
360
|
+
}, {
|
|
361
|
+
key: 'borderBottomRightRadius',
|
|
362
|
+
rules: {
|
|
363
|
+
height: 'borderBottomRightRadius'
|
|
364
|
+
}
|
|
365
|
+
}, {
|
|
366
|
+
key: 'borderTopRightRadius',
|
|
367
|
+
rules: {
|
|
368
|
+
height: 'borderTopRightRadius'
|
|
369
|
+
}
|
|
370
|
+
}];
|
|
371
|
+
const { style = {}, children, hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-offset': enableOffset, } = props;
|
|
227
372
|
const [isHover, setIsHover] = useState(false);
|
|
373
|
+
let transformStyle = {};
|
|
374
|
+
const [containerWidth, setContainerWidth] = useState(0);
|
|
375
|
+
const [containerHeight, setContainerHeight] = useState(0);
|
|
228
376
|
const layoutRef = useRef({});
|
|
229
377
|
// 打平 style 数组
|
|
230
|
-
const styleObj =
|
|
378
|
+
const styleObj = normalizeStyle(style);
|
|
231
379
|
// 默认样式
|
|
232
380
|
const defaultStyle = {
|
|
233
381
|
// flex 布局相关的默认样式
|
|
@@ -238,6 +386,23 @@ const _View = forwardRef((props, ref) => {
|
|
|
238
386
|
flexWrap: 'nowrap'
|
|
239
387
|
}
|
|
240
388
|
};
|
|
389
|
+
const hasPercentStyle = combinationStyleProps.some(({ key, rules }) => {
|
|
390
|
+
return Object.entries(rules).some(([dimension, transformKey]) => {
|
|
391
|
+
const transformItemValue = styleObj[key];
|
|
392
|
+
if (transformItemValue) {
|
|
393
|
+
if (Array.isArray(transformItemValue)) {
|
|
394
|
+
const transformValue = transformItemValue.find((item) => item.hasOwnProperty(transformKey));
|
|
395
|
+
return transformValue && PERCENT_REGEX.test(transformValue[transformKey]);
|
|
396
|
+
}
|
|
397
|
+
else if (typeof transformItemValue === 'string') {
|
|
398
|
+
return PERCENT_REGEX.test(transformItemValue);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
if (hasPercentStyle) {
|
|
404
|
+
transformStyle = percentTransform(combinationStyleProps, { width: containerWidth, height: containerHeight });
|
|
405
|
+
}
|
|
241
406
|
const { nodeRef } = useNodesRef(props, ref, {
|
|
242
407
|
defaultStyle
|
|
243
408
|
});
|
|
@@ -251,14 +416,14 @@ const _View = forwardRef((props, ref) => {
|
|
|
251
416
|
const setStartTimer = () => {
|
|
252
417
|
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
253
418
|
dataRef.current.startTimer = setTimeout(() => {
|
|
254
|
-
setIsHover(
|
|
419
|
+
setIsHover(true);
|
|
255
420
|
}, +hoverStartTime);
|
|
256
421
|
};
|
|
257
422
|
const setStayTimer = () => {
|
|
258
423
|
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
|
|
259
424
|
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
260
425
|
dataRef.current.stayTimer = setTimeout(() => {
|
|
261
|
-
setIsHover(
|
|
426
|
+
setIsHover(false);
|
|
262
427
|
}, +hoverStayTime);
|
|
263
428
|
};
|
|
264
429
|
function onTouchStart(e) {
|
|
@@ -271,19 +436,83 @@ const _View = forwardRef((props, ref) => {
|
|
|
271
436
|
bindtouchend && bindtouchend(e);
|
|
272
437
|
setStayTimer();
|
|
273
438
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
439
|
+
function percentTransform(style, { width, height }) {
|
|
440
|
+
const styleMap = {};
|
|
441
|
+
style.forEach((styleItem) => {
|
|
442
|
+
const transformItemValue = styleObj[styleItem.key];
|
|
443
|
+
if (Array.isArray(transformItemValue)) {
|
|
444
|
+
const transformStyle = [];
|
|
445
|
+
styleObj[styleItem.key].forEach((transformItem) => {
|
|
446
|
+
const rules = styleItem.rules;
|
|
447
|
+
for (const type in rules) {
|
|
448
|
+
const value = transformItem[rules[type]];
|
|
449
|
+
if (value !== undefined) {
|
|
450
|
+
if (PERCENT_REGEX.test(value)) {
|
|
451
|
+
const percentage = parseFloat(value) / 100;
|
|
452
|
+
if (type === 'height' && height) {
|
|
453
|
+
transformStyle.push({ [rules[type]]: percentage * height });
|
|
454
|
+
}
|
|
455
|
+
else if (type === 'width' && width) {
|
|
456
|
+
transformStyle.push({ [rules[type]]: percentage * width });
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
transformStyle.push({ [rules[type]]: 0 });
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
transformStyle.push(transformItem);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
styleMap[styleItem.key] = transformStyle;
|
|
469
|
+
}
|
|
470
|
+
else if (typeof transformItemValue === 'string') {
|
|
471
|
+
const rules = styleItem.rules;
|
|
472
|
+
for (const type in rules) {
|
|
473
|
+
if (transformItemValue) {
|
|
474
|
+
if (PERCENT_REGEX.test(transformItemValue)) {
|
|
475
|
+
const percentage = parseFloat(transformItemValue) / 100;
|
|
476
|
+
if (type === 'height' && height) {
|
|
477
|
+
styleMap[styleItem.key] = percentage * height;
|
|
478
|
+
}
|
|
479
|
+
else if (type === 'width' && width) {
|
|
480
|
+
styleMap[styleItem.key] = percentage * width;
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
styleMap[styleItem.key] = 0;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
styleMap[styleItem.key] = transformItemValue;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
277
492
|
});
|
|
493
|
+
return styleMap;
|
|
494
|
+
}
|
|
495
|
+
const onLayout = (res) => {
|
|
496
|
+
if (hasPercentStyle) {
|
|
497
|
+
const { width, height } = res?.nativeEvent?.layout || {};
|
|
498
|
+
setContainerWidth(width || 0);
|
|
499
|
+
setContainerHeight(height || 0);
|
|
500
|
+
}
|
|
501
|
+
if (enableOffset) {
|
|
502
|
+
nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
|
|
503
|
+
layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
|
|
504
|
+
});
|
|
505
|
+
}
|
|
278
506
|
};
|
|
279
|
-
const { textStyle, imageStyle, innerStyle } = splitStyle(
|
|
280
|
-
defaultStyle,
|
|
281
|
-
styleObj,
|
|
282
|
-
...(isHover ? hoverStyle :
|
|
283
|
-
|
|
507
|
+
const { textStyle, imageStyle, innerStyle } = splitStyle({
|
|
508
|
+
...defaultStyle,
|
|
509
|
+
...styleObj,
|
|
510
|
+
...(isHover ? hoverStyle : null)
|
|
511
|
+
});
|
|
512
|
+
const needLayout = enableOffset || hasPercentStyle;
|
|
284
513
|
const innerProps = useInnerProps(props, {
|
|
285
514
|
ref: nodeRef,
|
|
286
|
-
...
|
|
515
|
+
...needLayout ? { onLayout } : {},
|
|
287
516
|
...(hoverStyle && {
|
|
288
517
|
bindtouchstart: onTouchStart,
|
|
289
518
|
bindtouchend: onTouchEnd
|
|
@@ -295,12 +524,13 @@ const _View = forwardRef((props, ref) => {
|
|
|
295
524
|
'hover-stay-time',
|
|
296
525
|
'hoverStyle',
|
|
297
526
|
'hover-class',
|
|
298
|
-
'enable-offset'
|
|
527
|
+
'enable-offset',
|
|
528
|
+
'enable-background-image'
|
|
299
529
|
], {
|
|
300
530
|
layoutRef
|
|
301
531
|
});
|
|
302
|
-
return (<View {...innerProps} style={innerStyle}>
|
|
303
|
-
{wrapChildren(children, textStyle, imageStyle)}
|
|
532
|
+
return (<View {...innerProps} style={{ ...innerStyle, ...transformStyle }}>
|
|
533
|
+
{wrapChildren(children, props, textStyle, imageStyle)}
|
|
304
534
|
</View>);
|
|
305
535
|
});
|
|
306
536
|
_View.displayName = 'mpx-view';
|
|
@@ -7,22 +7,17 @@ import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab }
|
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
import { WebView } from 'react-native-webview';
|
|
9
9
|
import useNodesRef from './useNodesRef';
|
|
10
|
-
import { StyleSheet } from 'react-native';
|
|
11
10
|
const _WebView = forwardRef((props, ref) => {
|
|
12
11
|
const { src, bindmessage = noop, bindload = noop, binderror = noop } = props;
|
|
13
|
-
const defaultWebViewStyle =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
];
|
|
12
|
+
const defaultWebViewStyle = {
|
|
13
|
+
position: 'absolute',
|
|
14
|
+
left: 0,
|
|
15
|
+
right: 0,
|
|
16
|
+
top: 0,
|
|
17
|
+
bottom: 0
|
|
18
|
+
};
|
|
22
19
|
const { nodeRef: webViewRef } = useNodesRef(props, ref, {
|
|
23
|
-
defaultStyle:
|
|
24
|
-
...defaultWebViewStyle
|
|
25
|
-
])
|
|
20
|
+
defaultStyle: defaultWebViewStyle
|
|
26
21
|
});
|
|
27
22
|
const _messageList = [];
|
|
28
23
|
const handleUnload = () => {
|
|
@@ -106,9 +101,8 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
106
101
|
}
|
|
107
102
|
});
|
|
108
103
|
};
|
|
109
|
-
// @ts-ignore
|
|
110
104
|
return (<Portal>
|
|
111
|
-
<WebView style={
|
|
105
|
+
<WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} onLoad={_load} onError={_error} onMessage={_message} javaScriptEnabled={true}></WebView>
|
|
112
106
|
</Portal>);
|
|
113
107
|
});
|
|
114
108
|
_WebView.displayName = 'mpx-web-view';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|