@mpxjs/webpack-plugin 2.8.25-alpha.21 → 2.8.25-alpha.22
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/runtime/components/react/dist/KeyboardAvoidingView.jsx +89 -0
- package/lib/runtime/components/react/dist/context.js +14 -0
- package/lib/runtime/components/react/dist/event.config.js +27 -0
- package/lib/runtime/components/react/dist/getInnerListeners.js +262 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +271 -0
- 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 +341 -0
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +236 -0
- package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +90 -0
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +131 -0
- package/lib/runtime/components/react/dist/mpx-form.jsx +68 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
- package/lib/runtime/components/react/dist/mpx-icon/index.jsx +50 -0
- package/lib/runtime/components/react/dist/mpx-image.jsx +292 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +292 -0
- package/lib/runtime/components/react/dist/mpx-label.jsx +52 -0
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +32 -0
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +468 -0
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +33 -0
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +74 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +141 -0
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +147 -0
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +99 -0
- package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +81 -0
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +242 -0
- package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +35 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +193 -0
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +125 -0
- package/lib/runtime/components/react/dist/mpx-portal/index.jsx +30 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +112 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +41 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +86 -0
- package/lib/runtime/components/react/dist/mpx-radio.jsx +140 -0
- 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 +17 -0
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +372 -0
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +59 -0
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +671 -0
- package/lib/runtime/components/react/dist/mpx-switch.jsx +97 -0
- package/lib/runtime/components/react/dist/mpx-text.jsx +41 -0
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +40 -0
- package/lib/runtime/components/react/dist/mpx-video.jsx +248 -0
- package/lib/runtime/components/react/dist/mpx-view.jsx +611 -0
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +289 -0
- package/lib/runtime/components/react/dist/parser.js +218 -0
- package/lib/runtime/components/react/dist/pickerFaces.js +76 -0
- package/lib/runtime/components/react/dist/pickerVIewContext.js +14 -0
- package/lib/runtime/components/react/dist/pickerViewIndicator.jsx +23 -0
- package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
- package/lib/runtime/components/react/dist/useAnimationHooks.js +346 -0
- package/lib/runtime/components/react/dist/useNodesRef.js +16 -0
- package/lib/runtime/components/react/dist/utils.jsx +599 -0
- package/package.json +6 -3
- package/LICENSE +0 -433
|
@@ -0,0 +1,599 @@
|
|
|
1
|
+
import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement } from 'react';
|
|
2
|
+
import { Image } from 'react-native';
|
|
3
|
+
import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils';
|
|
4
|
+
import { VarContext, ScrollViewContext, RouteContext } from './context';
|
|
5
|
+
import { ExpressionParser, parseFunc, ReplaceSource } from './parser';
|
|
6
|
+
import { initialWindowMetrics } from 'react-native-safe-area-context';
|
|
7
|
+
import FastImage from '@d11/react-native-fast-image';
|
|
8
|
+
import { runOnJS } from 'react-native-reanimated';
|
|
9
|
+
import { Gesture } from 'react-native-gesture-handler';
|
|
10
|
+
export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/;
|
|
11
|
+
export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/;
|
|
12
|
+
export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/;
|
|
13
|
+
export const SVG_REGEXP = /https?:\/\/.*\.(?:svg)/i;
|
|
14
|
+
export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/;
|
|
15
|
+
export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines|allowFontScaling/;
|
|
16
|
+
export const DEFAULT_FONT_SIZE = 16;
|
|
17
|
+
export const HIDDEN_STYLE = {
|
|
18
|
+
opacity: 0
|
|
19
|
+
};
|
|
20
|
+
export const isIOS = __mpx_mode__ === 'ios';
|
|
21
|
+
export const isAndroid = __mpx_mode__ === 'android';
|
|
22
|
+
const varDecRegExp = /^--/;
|
|
23
|
+
const varUseRegExp = /var\(/;
|
|
24
|
+
const unoVarDecRegExp = /^--un-/;
|
|
25
|
+
const unoVarUseRegExp = /var\(--un-/;
|
|
26
|
+
const calcUseRegExp = /calc\(/;
|
|
27
|
+
const envUseRegExp = /env\(/;
|
|
28
|
+
const safeAreaInsetMap = {
|
|
29
|
+
'safe-area-inset-top': 'top',
|
|
30
|
+
'safe-area-inset-right': 'right',
|
|
31
|
+
'safe-area-inset-bottom': 'bottom',
|
|
32
|
+
'safe-area-inset-left': 'left'
|
|
33
|
+
};
|
|
34
|
+
function getSafeAreaInset(name, navigation) {
|
|
35
|
+
const insets = extendObject({}, initialWindowMetrics?.insets, navigation?.insets);
|
|
36
|
+
return insets[safeAreaInsetMap[name]];
|
|
37
|
+
}
|
|
38
|
+
export function useNavigation() {
|
|
39
|
+
const { navigation } = useContext(RouteContext) || {};
|
|
40
|
+
return navigation;
|
|
41
|
+
}
|
|
42
|
+
export function omit(obj, fields) {
|
|
43
|
+
const shallowCopy = extendObject({}, obj);
|
|
44
|
+
for (let i = 0; i < fields.length; i += 1) {
|
|
45
|
+
const key = fields[i];
|
|
46
|
+
delete shallowCopy[key];
|
|
47
|
+
}
|
|
48
|
+
return shallowCopy;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 用法等同于 useEffect,但是会忽略首次执行,只在依赖更新时执行
|
|
52
|
+
*/
|
|
53
|
+
export const useUpdateEffect = (effect, deps) => {
|
|
54
|
+
const isMounted = useRef(false);
|
|
55
|
+
// for react-refresh
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
return () => {
|
|
58
|
+
isMounted.current = false;
|
|
59
|
+
};
|
|
60
|
+
}, []);
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!isMounted.current) {
|
|
63
|
+
isMounted.current = true;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
return effect();
|
|
67
|
+
}
|
|
68
|
+
}, deps);
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* 解析行内样式
|
|
72
|
+
* @param inlineStyle
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
export const parseInlineStyle = (inlineStyle = '') => {
|
|
76
|
+
return inlineStyle.split(';').reduce((styleObj, style) => {
|
|
77
|
+
const [k, v, ...rest] = style.split(':');
|
|
78
|
+
if (rest.length || !v || !k)
|
|
79
|
+
return styleObj;
|
|
80
|
+
const key = k.trim().replace(/-./g, c => c.substring(1).toUpperCase());
|
|
81
|
+
return extendObject(styleObj, { [key]: global.__formatValue(v.trim()) });
|
|
82
|
+
}, {});
|
|
83
|
+
};
|
|
84
|
+
export const parseUrl = (cssUrl = '') => {
|
|
85
|
+
if (!cssUrl)
|
|
86
|
+
return;
|
|
87
|
+
const match = cssUrl.match(URL_REGEX);
|
|
88
|
+
return match?.[1];
|
|
89
|
+
};
|
|
90
|
+
export const getRestProps = (transferProps = {}, originProps = {}, deletePropsKey = []) => {
|
|
91
|
+
return extendObject({}, transferProps, omit(originProps, deletePropsKey));
|
|
92
|
+
};
|
|
93
|
+
export function isText(ele) {
|
|
94
|
+
if (isValidElement(ele)) {
|
|
95
|
+
const displayName = ele.type?.displayName;
|
|
96
|
+
const isCustomText = ele.type?.isCustomText;
|
|
97
|
+
return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'Text' || !!isCustomText;
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
export function every(children, callback) {
|
|
102
|
+
const childrenArray = Array.isArray(children) ? children : [children];
|
|
103
|
+
return childrenArray.every((child) => callback(child));
|
|
104
|
+
}
|
|
105
|
+
export function groupBy(obj, callback, group = {}) {
|
|
106
|
+
Object.entries(obj).forEach(([key, val]) => {
|
|
107
|
+
const groupKey = callback(key, val);
|
|
108
|
+
group[groupKey] = group[groupKey] || {};
|
|
109
|
+
group[groupKey][key] = val;
|
|
110
|
+
});
|
|
111
|
+
return group;
|
|
112
|
+
}
|
|
113
|
+
export function splitStyle(styleObj) {
|
|
114
|
+
return groupBy(styleObj, (key) => {
|
|
115
|
+
if (TEXT_STYLE_REGEX.test(key)) {
|
|
116
|
+
return 'textStyle';
|
|
117
|
+
}
|
|
118
|
+
else if (BACKGROUND_REGEX.test(key)) {
|
|
119
|
+
return 'backgroundStyle';
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
return 'innerStyle';
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const selfPercentRule = {
|
|
127
|
+
translateX: 'width',
|
|
128
|
+
translateY: 'height',
|
|
129
|
+
borderTopLeftRadius: 'width',
|
|
130
|
+
borderBottomLeftRadius: 'width',
|
|
131
|
+
borderBottomRightRadius: 'width',
|
|
132
|
+
borderTopRightRadius: 'width',
|
|
133
|
+
borderRadius: 'width'
|
|
134
|
+
};
|
|
135
|
+
const parentHeightPercentRule = {
|
|
136
|
+
height: true,
|
|
137
|
+
top: true,
|
|
138
|
+
bottom: true
|
|
139
|
+
};
|
|
140
|
+
function resolvePercent(value, key, percentConfig) {
|
|
141
|
+
if (!(typeof value === 'string' && PERCENT_REGEX.test(value)))
|
|
142
|
+
return value;
|
|
143
|
+
let base;
|
|
144
|
+
let reason;
|
|
145
|
+
if (key === 'fontSize') {
|
|
146
|
+
base = percentConfig.parentFontSize;
|
|
147
|
+
reason = 'parent-font-size';
|
|
148
|
+
}
|
|
149
|
+
else if (key === 'lineHeight') {
|
|
150
|
+
base = resolvePercent(percentConfig.fontSize, 'fontSize', percentConfig);
|
|
151
|
+
reason = 'font-size';
|
|
152
|
+
}
|
|
153
|
+
else if (selfPercentRule[key]) {
|
|
154
|
+
base = percentConfig[selfPercentRule[key]];
|
|
155
|
+
reason = selfPercentRule[key];
|
|
156
|
+
}
|
|
157
|
+
else if (parentHeightPercentRule[key]) {
|
|
158
|
+
base = percentConfig.parentHeight;
|
|
159
|
+
reason = 'parent-height';
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
base = percentConfig.parentWidth;
|
|
163
|
+
reason = 'parent-width';
|
|
164
|
+
}
|
|
165
|
+
if (typeof base !== 'number') {
|
|
166
|
+
error(`[${key}] can not contain % unit unless you set [${reason}] with a number for the percent calculation.`);
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return parseFloat(value) / 100 * base;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function transformPercent(styleObj, percentKeyPaths, percentConfig) {
|
|
174
|
+
percentKeyPaths.forEach((percentKeyPath) => {
|
|
175
|
+
setStyle(styleObj, percentKeyPath, ({ target, key, value }) => {
|
|
176
|
+
target[key] = resolvePercent(value, key, percentConfig);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function resolveVar(input, varContext) {
|
|
181
|
+
const parsed = parseFunc(input, 'var');
|
|
182
|
+
const replaced = new ReplaceSource(input);
|
|
183
|
+
parsed.forEach(({ start, end, args }) => {
|
|
184
|
+
const varName = args[0];
|
|
185
|
+
const fallback = args[1] || '';
|
|
186
|
+
let varValue = hasOwn(varContext, varName) ? varContext[varName] : fallback;
|
|
187
|
+
if (varUseRegExp.test(varValue)) {
|
|
188
|
+
varValue = '' + resolveVar(varValue, varContext);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
varValue = '' + global.__formatValue(varValue);
|
|
192
|
+
}
|
|
193
|
+
replaced.replace(start, end - 1, varValue);
|
|
194
|
+
});
|
|
195
|
+
return global.__formatValue(replaced.source());
|
|
196
|
+
}
|
|
197
|
+
function transformVar(styleObj, varKeyPaths, varContext) {
|
|
198
|
+
varKeyPaths.forEach((varKeyPath) => {
|
|
199
|
+
setStyle(styleObj, varKeyPath, ({ target, key, value }) => {
|
|
200
|
+
target[key] = resolveVar(value, varContext);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function transformEnv(styleObj, envKeyPaths, navigation) {
|
|
205
|
+
envKeyPaths.forEach((envKeyPath) => {
|
|
206
|
+
setStyle(styleObj, envKeyPath, ({ target, key, value }) => {
|
|
207
|
+
const parsed = parseFunc(value, 'env');
|
|
208
|
+
const replaced = new ReplaceSource(value);
|
|
209
|
+
parsed.forEach(({ start, end, args }) => {
|
|
210
|
+
const name = args[0];
|
|
211
|
+
const fallback = args[1] || '';
|
|
212
|
+
const value = '' + (getSafeAreaInset(name, navigation) ?? global.__formatValue(fallback));
|
|
213
|
+
replaced.replace(start, end - 1, value);
|
|
214
|
+
});
|
|
215
|
+
target[key] = global.__formatValue(replaced.source());
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
function transformCalc(styleObj, calcKeyPaths, formatter) {
|
|
220
|
+
calcKeyPaths.forEach((calcKeyPath) => {
|
|
221
|
+
setStyle(styleObj, calcKeyPath, ({ target, key, value }) => {
|
|
222
|
+
const parsed = parseFunc(value, 'calc');
|
|
223
|
+
const replaced = new ReplaceSource(value);
|
|
224
|
+
parsed.forEach(({ start, end, args }) => {
|
|
225
|
+
const exp = args[0];
|
|
226
|
+
try {
|
|
227
|
+
const result = new ExpressionParser(exp, (value) => {
|
|
228
|
+
return formatter(value, key);
|
|
229
|
+
}).parse();
|
|
230
|
+
replaced.replace(start, end - 1, '' + result.value);
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
error(`calc(${exp}) parse error.`, undefined, e);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
target[key] = global.__formatValue(replaced.source());
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
const stringifyProps = ['fontWeight'];
|
|
241
|
+
function transformStringify(styleObj) {
|
|
242
|
+
stringifyProps.forEach((prop) => {
|
|
243
|
+
if (isNumber(styleObj[prop])) {
|
|
244
|
+
styleObj[prop] = '' + styleObj[prop];
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
|
|
249
|
+
const varStyle = {};
|
|
250
|
+
const unoVarStyle = {};
|
|
251
|
+
const normalStyle = {};
|
|
252
|
+
const normalStyleRef = useRef({});
|
|
253
|
+
const normalStyleChangedRef = useRef(false);
|
|
254
|
+
let hasVarDec = false;
|
|
255
|
+
let hasVarUse = false;
|
|
256
|
+
let hasSelfPercent = false;
|
|
257
|
+
const varKeyPaths = [];
|
|
258
|
+
const unoVarKeyPaths = [];
|
|
259
|
+
const percentKeyPaths = [];
|
|
260
|
+
const calcKeyPaths = [];
|
|
261
|
+
const envKeyPaths = [];
|
|
262
|
+
const [width, setWidth] = useState(0);
|
|
263
|
+
const [height, setHeight] = useState(0);
|
|
264
|
+
const navigation = useNavigation();
|
|
265
|
+
function varVisitor({ key, value, keyPath }) {
|
|
266
|
+
if (keyPath.length === 1) {
|
|
267
|
+
if (unoVarDecRegExp.test(key)) {
|
|
268
|
+
unoVarStyle[key] = value;
|
|
269
|
+
}
|
|
270
|
+
else if (varDecRegExp.test(key)) {
|
|
271
|
+
hasVarDec = true;
|
|
272
|
+
varStyle[key] = value;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// clone对象避免set值时改写到props
|
|
276
|
+
normalStyle[key] = isObject(value) ? diffAndCloneA(value).clone : value;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// 对于var定义中使用的var无需替换值,可以通过resolveVar递归解析出值
|
|
280
|
+
if (!varDecRegExp.test(key)) {
|
|
281
|
+
// 一般情况下一个样式属性中不会混用unocss var和普通css var,可分开进行互斥处理
|
|
282
|
+
if (unoVarUseRegExp.test(value)) {
|
|
283
|
+
unoVarKeyPaths.push(keyPath.slice());
|
|
284
|
+
}
|
|
285
|
+
else if (varUseRegExp.test(value)) {
|
|
286
|
+
hasVarUse = true;
|
|
287
|
+
varKeyPaths.push(keyPath.slice());
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// traverse var & generate normalStyle
|
|
292
|
+
traverseStyle(styleObj, [varVisitor]);
|
|
293
|
+
hasVarDec = hasVarDec || !!externalVarContext;
|
|
294
|
+
enableVar = enableVar || hasVarDec || hasVarUse;
|
|
295
|
+
const enableVarRef = useRef(enableVar);
|
|
296
|
+
if (enableVarRef.current !== enableVar) {
|
|
297
|
+
error('css variable use/declare should be stable in the component lifecycle, or you can set [enable-var] with true.');
|
|
298
|
+
}
|
|
299
|
+
// apply css var
|
|
300
|
+
const varContextRef = useRef({});
|
|
301
|
+
if (enableVarRef.current) {
|
|
302
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
303
|
+
const varContext = useContext(VarContext);
|
|
304
|
+
const newVarContext = extendObject({}, varContext, externalVarContext, varStyle);
|
|
305
|
+
// 缓存比较newVarContext是否发生变化
|
|
306
|
+
if (diffAndCloneA(varContextRef.current, newVarContext).diff) {
|
|
307
|
+
varContextRef.current = newVarContext;
|
|
308
|
+
}
|
|
309
|
+
transformVar(normalStyle, varKeyPaths, varContextRef.current);
|
|
310
|
+
}
|
|
311
|
+
// apply unocss var
|
|
312
|
+
if (unoVarKeyPaths.length) {
|
|
313
|
+
transformVar(normalStyle, unoVarKeyPaths, unoVarStyle);
|
|
314
|
+
}
|
|
315
|
+
const { clone, diff } = diffAndCloneA(normalStyle, normalStyleRef.current);
|
|
316
|
+
if (diff) {
|
|
317
|
+
normalStyleRef.current = clone;
|
|
318
|
+
normalStyleChangedRef.current = !normalStyleChangedRef.current;
|
|
319
|
+
}
|
|
320
|
+
const memoResult = useMemo(() => {
|
|
321
|
+
// transform can be memoized
|
|
322
|
+
function envVisitor({ value, keyPath }) {
|
|
323
|
+
if (envUseRegExp.test(value)) {
|
|
324
|
+
envKeyPaths.push(keyPath.slice());
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function calcVisitor({ value, keyPath }) {
|
|
328
|
+
if (calcUseRegExp.test(value)) {
|
|
329
|
+
calcKeyPaths.push(keyPath.slice());
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function percentVisitor({ key, value, keyPath }) {
|
|
333
|
+
if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) {
|
|
334
|
+
hasSelfPercent = true;
|
|
335
|
+
percentKeyPaths.push(keyPath.slice());
|
|
336
|
+
}
|
|
337
|
+
else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
|
|
338
|
+
percentKeyPaths.push(keyPath.slice());
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// traverse env & calc & percent
|
|
342
|
+
traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor]);
|
|
343
|
+
const percentConfig = {
|
|
344
|
+
width,
|
|
345
|
+
height,
|
|
346
|
+
fontSize: normalStyle.fontSize,
|
|
347
|
+
parentWidth,
|
|
348
|
+
parentHeight,
|
|
349
|
+
parentFontSize
|
|
350
|
+
};
|
|
351
|
+
// apply env
|
|
352
|
+
transformEnv(normalStyle, envKeyPaths, navigation);
|
|
353
|
+
// apply percent
|
|
354
|
+
transformPercent(normalStyle, percentKeyPaths, percentConfig);
|
|
355
|
+
// apply calc
|
|
356
|
+
transformCalc(normalStyle, calcKeyPaths, (value, key) => {
|
|
357
|
+
if (PERCENT_REGEX.test(value)) {
|
|
358
|
+
const resolved = resolvePercent(value, key, percentConfig);
|
|
359
|
+
return typeof resolved === 'number' ? resolved : 0;
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
const formatted = global.__formatValue(value);
|
|
363
|
+
if (typeof formatted === 'number') {
|
|
364
|
+
return formatted;
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
warn('calc() only support number, px, rpx, % temporarily.');
|
|
368
|
+
return 0;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
// transform number enum stringify
|
|
373
|
+
transformStringify(normalStyle);
|
|
374
|
+
return {
|
|
375
|
+
normalStyle,
|
|
376
|
+
hasSelfPercent
|
|
377
|
+
};
|
|
378
|
+
}, [normalStyleChangedRef.current, width, height, parentWidth, parentHeight, parentFontSize]);
|
|
379
|
+
return extendObject({
|
|
380
|
+
hasVarDec,
|
|
381
|
+
varContextRef,
|
|
382
|
+
setWidth,
|
|
383
|
+
setHeight
|
|
384
|
+
}, memoResult);
|
|
385
|
+
}
|
|
386
|
+
export function traverseStyle(styleObj, visitors) {
|
|
387
|
+
const keyPath = [];
|
|
388
|
+
function traverse(target) {
|
|
389
|
+
if (Array.isArray(target)) {
|
|
390
|
+
target.forEach((value, index) => {
|
|
391
|
+
const key = String(index);
|
|
392
|
+
keyPath.push(key);
|
|
393
|
+
visitors.forEach(visitor => visitor({
|
|
394
|
+
target,
|
|
395
|
+
key,
|
|
396
|
+
value,
|
|
397
|
+
keyPath
|
|
398
|
+
}));
|
|
399
|
+
traverse(value);
|
|
400
|
+
keyPath.pop();
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
else if (isObject(target)) {
|
|
404
|
+
Object.entries(target).forEach(([key, value]) => {
|
|
405
|
+
keyPath.push(key);
|
|
406
|
+
visitors.forEach(visitor => visitor({ target, key, value, keyPath }));
|
|
407
|
+
traverse(value);
|
|
408
|
+
keyPath.pop();
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
traverse(styleObj);
|
|
413
|
+
}
|
|
414
|
+
export function setStyle(styleObj, keyPath, setter) {
|
|
415
|
+
let target = styleObj;
|
|
416
|
+
const lastKey = keyPath[keyPath.length - 1];
|
|
417
|
+
for (let i = 0; i < keyPath.length - 1; i++) {
|
|
418
|
+
target = target[keyPath[i]];
|
|
419
|
+
if (!target)
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
setter({
|
|
423
|
+
target,
|
|
424
|
+
key: lastKey,
|
|
425
|
+
value: target[lastKey],
|
|
426
|
+
keyPath
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
export function splitProps(props) {
|
|
430
|
+
return groupBy(props, (key) => {
|
|
431
|
+
if (TEXT_PROPS_REGEX.test(key)) {
|
|
432
|
+
return 'textProps';
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
return 'innerProps';
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }) => {
|
|
440
|
+
const layoutRef = useRef({});
|
|
441
|
+
const hasLayoutRef = useRef(false);
|
|
442
|
+
const layoutStyle = useMemo(() => { return !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {}; }, [hasLayoutRef.current]);
|
|
443
|
+
const layoutProps = {};
|
|
444
|
+
const navigation = useNavigation();
|
|
445
|
+
const enableOffset = props['enable-offset'];
|
|
446
|
+
if (hasSelfPercent || onLayout || enableOffset) {
|
|
447
|
+
layoutProps.onLayout = (e) => {
|
|
448
|
+
hasLayoutRef.current = true;
|
|
449
|
+
if (hasSelfPercent) {
|
|
450
|
+
const { width, height } = e?.nativeEvent?.layout || {};
|
|
451
|
+
setWidth(width || 0);
|
|
452
|
+
setHeight(height || 0);
|
|
453
|
+
}
|
|
454
|
+
if (enableOffset) {
|
|
455
|
+
nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
|
|
456
|
+
const { y: navigationY = 0 } = navigation?.layout || {};
|
|
457
|
+
layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft, offsetTop: offsetTop - navigationY };
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
onLayout && onLayout(e);
|
|
461
|
+
props.onLayout && props.onLayout(e);
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
layoutRef,
|
|
466
|
+
layoutStyle,
|
|
467
|
+
layoutProps
|
|
468
|
+
};
|
|
469
|
+
};
|
|
470
|
+
export function wrapChildren(props = {}, { hasVarDec, varContext, textStyle, textProps }) {
|
|
471
|
+
let { children } = props;
|
|
472
|
+
if (textStyle || textProps) {
|
|
473
|
+
children = Children.map(children, (child) => {
|
|
474
|
+
if (isText(child)) {
|
|
475
|
+
const style = extendObject({}, textStyle, child.props.style);
|
|
476
|
+
return cloneElement(child, extendObject({}, textProps, { style }));
|
|
477
|
+
}
|
|
478
|
+
return child;
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
if (hasVarDec && varContext) {
|
|
482
|
+
children = <VarContext.Provider value={varContext} key='varContextWrap'>{children}</VarContext.Provider>;
|
|
483
|
+
}
|
|
484
|
+
return children;
|
|
485
|
+
}
|
|
486
|
+
export const debounce = (func, delay) => {
|
|
487
|
+
let timer;
|
|
488
|
+
const wrapper = (...args) => {
|
|
489
|
+
timer && clearTimeout(timer);
|
|
490
|
+
timer = setTimeout(() => {
|
|
491
|
+
func(...args);
|
|
492
|
+
}, delay);
|
|
493
|
+
};
|
|
494
|
+
wrapper.clear = () => {
|
|
495
|
+
timer && clearTimeout(timer);
|
|
496
|
+
timer = null;
|
|
497
|
+
};
|
|
498
|
+
return wrapper;
|
|
499
|
+
};
|
|
500
|
+
export const useDebounceCallback = (func, delay) => {
|
|
501
|
+
const debounced = useMemo(() => debounce(func, delay), [func]);
|
|
502
|
+
return debounced;
|
|
503
|
+
};
|
|
504
|
+
export const useStableCallback = (callback) => {
|
|
505
|
+
const ref = useRef(callback);
|
|
506
|
+
ref.current = callback;
|
|
507
|
+
return useCallback((...args) => ref.current?.(...args), []);
|
|
508
|
+
};
|
|
509
|
+
export function usePrevious(value) {
|
|
510
|
+
const ref = useRef();
|
|
511
|
+
const prev = ref.current;
|
|
512
|
+
ref.current = value;
|
|
513
|
+
return prev;
|
|
514
|
+
}
|
|
515
|
+
export function flatGesture(gestures = []) {
|
|
516
|
+
return (gestures && gestures.flatMap((gesture) => {
|
|
517
|
+
if (gesture && gesture.nodeRefs) {
|
|
518
|
+
return gesture.nodeRefs
|
|
519
|
+
.map((item) => item.getNodeInstance()?.instance?.gestureRef || {});
|
|
520
|
+
}
|
|
521
|
+
return gesture?.current ? [gesture] : [];
|
|
522
|
+
})) || [];
|
|
523
|
+
}
|
|
524
|
+
export const extendObject = Object.assign;
|
|
525
|
+
export function getCurrentPage(pageId) {
|
|
526
|
+
if (!global.getCurrentPages)
|
|
527
|
+
return;
|
|
528
|
+
const pages = global.getCurrentPages();
|
|
529
|
+
return pages.find((page) => isFunction(page.getPageId) && page.getPageId() === pageId);
|
|
530
|
+
}
|
|
531
|
+
export function renderImage(imageProps, enableFastImage = false) {
|
|
532
|
+
const Component = enableFastImage ? FastImage : Image;
|
|
533
|
+
return <Component {...imageProps}/>;
|
|
534
|
+
}
|
|
535
|
+
export function pickStyle(styleObj = {}, pickedKeys, callback) {
|
|
536
|
+
return pickedKeys.reduce((acc, key) => {
|
|
537
|
+
if (key in styleObj) {
|
|
538
|
+
acc[key] = callback ? callback(key, styleObj[key]) : styleObj[key];
|
|
539
|
+
}
|
|
540
|
+
return acc;
|
|
541
|
+
}, {});
|
|
542
|
+
}
|
|
543
|
+
export function useHover({ enableHover, hoverStartTime, hoverStayTime, disabled }) {
|
|
544
|
+
const enableHoverRef = useRef(enableHover);
|
|
545
|
+
if (enableHoverRef.current !== enableHover) {
|
|
546
|
+
error('[Mpx runtime error]: hover-class use should be stable in the component lifecycle.');
|
|
547
|
+
}
|
|
548
|
+
if (!enableHoverRef.current)
|
|
549
|
+
return { isHover: false };
|
|
550
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
551
|
+
const gestureRef = useContext(ScrollViewContext).gestureRef;
|
|
552
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
553
|
+
const [isHover, setIsHover] = useState(false);
|
|
554
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
555
|
+
const dataRef = useRef({});
|
|
556
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
557
|
+
useEffect(() => {
|
|
558
|
+
return () => {
|
|
559
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
560
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
|
|
561
|
+
};
|
|
562
|
+
}, []);
|
|
563
|
+
const setStartTimer = () => {
|
|
564
|
+
if (disabled)
|
|
565
|
+
return;
|
|
566
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
567
|
+
dataRef.current.startTimer = setTimeout(() => {
|
|
568
|
+
setIsHover(true);
|
|
569
|
+
}, +hoverStartTime);
|
|
570
|
+
};
|
|
571
|
+
const setStayTimer = () => {
|
|
572
|
+
if (disabled)
|
|
573
|
+
return;
|
|
574
|
+
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
|
|
575
|
+
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
576
|
+
dataRef.current.stayTimer = setTimeout(() => {
|
|
577
|
+
setIsHover(false);
|
|
578
|
+
}, +hoverStayTime);
|
|
579
|
+
};
|
|
580
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
581
|
+
const gesture = useMemo(() => {
|
|
582
|
+
return Gesture.Pan()
|
|
583
|
+
.onTouchesDown(() => {
|
|
584
|
+
'worklet';
|
|
585
|
+
runOnJS(setStartTimer)();
|
|
586
|
+
})
|
|
587
|
+
.onTouchesUp(() => {
|
|
588
|
+
'worklet';
|
|
589
|
+
runOnJS(setStayTimer)();
|
|
590
|
+
});
|
|
591
|
+
}, []);
|
|
592
|
+
if (gestureRef) {
|
|
593
|
+
gesture.simultaneousWithExternalGesture(gestureRef);
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
isHover,
|
|
597
|
+
gesture
|
|
598
|
+
};
|
|
599
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mpxjs/webpack-plugin",
|
|
3
|
-
"version": "2.8.25-alpha.
|
|
3
|
+
"version": "2.8.25-alpha.22",
|
|
4
4
|
"description": "mpx compile core",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mpx"
|
|
@@ -61,7 +61,10 @@
|
|
|
61
61
|
"source-list-map": "^2.0.0"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"webpack": "^5.48.0"
|
|
64
|
+
"webpack": "^5.48.0",
|
|
65
|
+
"@hummer/tenon-dev-server-webpack-plugin": "0.0.2",
|
|
66
|
+
"@hummer/tenon-loader": "^1.2.0",
|
|
67
|
+
"@hummer/tenon-style-loader": "^0.2.0"
|
|
65
68
|
},
|
|
66
69
|
"publishConfig": {
|
|
67
70
|
"registry": "https://registry.npmjs.org",
|
|
@@ -85,5 +88,5 @@
|
|
|
85
88
|
"engines": {
|
|
86
89
|
"node": ">=14.14.0"
|
|
87
90
|
},
|
|
88
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "2d37697869b9bdda3efab92dda8c910b68fd05c0"
|
|
89
92
|
}
|