@mpxjs/webpack-plugin 2.10.3-beta.17 → 2.10.3-beta.18

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.
Files changed (68) hide show
  1. package/lib/runtime/components/react/dist/context.js +5 -1
  2. package/lib/runtime/components/react/dist/event.config.js +0 -1
  3. package/lib/runtime/components/react/dist/getInnerListeners.js +148 -149
  4. package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +145 -0
  5. package/lib/runtime/components/react/dist/mpx-button.jsx +11 -7
  6. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
  7. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +23 -21
  8. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +9 -4
  9. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +9 -5
  10. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
  11. package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
  12. package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
  13. package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
  14. package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
  15. package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
  16. package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
  17. package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
  18. package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
  19. package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
  20. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +9 -4
  21. package/lib/runtime/components/react/dist/mpx-image.jsx +92 -41
  22. package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
  23. package/lib/runtime/components/react/dist/mpx-input.jsx +14 -13
  24. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +22 -7
  25. package/lib/runtime/components/react/dist/mpx-label.jsx +9 -5
  26. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -5
  27. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +206 -80
  28. package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
  29. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
  30. package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
  31. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +178 -98
  32. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
  33. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
  34. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
  35. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
  36. package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +16 -15
  37. package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +95 -26
  38. package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +16 -16
  39. package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +20 -0
  40. package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
  41. package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
  42. package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
  43. package/lib/runtime/components/react/dist/mpx-portal/index.jsx +5 -1
  44. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +3 -5
  45. package/lib/runtime/components/react/dist/mpx-progress.jsx +163 -0
  46. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -4
  47. package/lib/runtime/components/react/dist/mpx-radio.jsx +9 -5
  48. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +12 -4
  49. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +317 -89
  50. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +7 -5
  51. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
  52. package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
  53. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +117 -0
  54. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +15 -14
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +245 -121
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +10 -7
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +43 -13
  59. package/lib/runtime/components/react/dist/mpx-video.jsx +12 -7
  60. package/lib/runtime/components/react/dist/mpx-view.jsx +34 -18
  61. package/lib/runtime/components/react/dist/mpx-web-view.jsx +40 -35
  62. package/lib/runtime/components/react/dist/useAnimationHooks.js +35 -90
  63. package/lib/runtime/components/react/dist/utils.jsx +215 -109
  64. package/lib/runtime/components/web/mpx-titlebar.vue +21 -18
  65. package/package.json +1 -1
  66. /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
  67. /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
  68. /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
@@ -1,11 +1,10 @@
1
- import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement } from 'react';
1
+ import { useEffect, useCallback, useMemo, useRef, isValidElement, useContext, useState, Children, cloneElement, createElement } from 'react';
2
2
  import { Image } from 'react-native';
3
3
  import { isObject, isFunction, isNumber, hasOwn, diffAndCloneA, error, warn } from '@mpxjs/utils';
4
4
  import { VarContext, ScrollViewContext, RouteContext } from './context';
5
5
  import { ExpressionParser, parseFunc, ReplaceSource } from './parser';
6
6
  import { initialWindowMetrics } from 'react-native-safe-area-context';
7
7
  import FastImage from '@d11/react-native-fast-image';
8
- import { runOnJS } from 'react-native-reanimated';
9
8
  import { Gesture } from 'react-native-gesture-handler';
10
9
  export const TEXT_STYLE_REGEX = /color|font.*|text.*|letterSpacing|lineHeight|includeFontPadding|writingDirection/;
11
10
  export const PERCENT_REGEX = /^\s*-?\d+(\.\d+)?%\s*$/;
@@ -26,6 +25,7 @@ const unoVarDecRegExp = /^--un-/;
26
25
  const unoVarUseRegExp = /var\(--un-/;
27
26
  const calcUseRegExp = /calc\(/;
28
27
  const envUseRegExp = /env\(/;
28
+ const filterRegExp = /(calc|env|%)/;
29
29
  const safeAreaInsetMap = {
30
30
  'safe-area-inset-top': 'top',
31
31
  'safe-area-inset-right': 'right',
@@ -81,7 +81,7 @@ export function isText(ele) {
81
81
  if (isValidElement(ele)) {
82
82
  const displayName = ele.type?.displayName;
83
83
  const isCustomText = ele.type?.isCustomText;
84
- return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'Text' || !!isCustomText;
84
+ return displayName === 'MpxText' || displayName === 'MpxSimpleText' || displayName === 'MpxInlineText' || displayName === 'Text' || !!isCustomText;
85
85
  }
86
86
  return false;
87
87
  }
@@ -121,6 +121,8 @@ const selfPercentRule = {
121
121
  };
122
122
  const parentHeightPercentRule = {
123
123
  height: true,
124
+ minHeight: true,
125
+ maxHeight: true,
124
126
  top: true,
125
127
  bottom: true
126
128
  };
@@ -167,24 +169,35 @@ function transformPercent(styleObj, percentKeyPaths, percentConfig) {
167
169
  function resolveVar(input, varContext) {
168
170
  const parsed = parseFunc(input, 'var');
169
171
  const replaced = new ReplaceSource(input);
170
- parsed.forEach(({ start, end, args }) => {
172
+ for (const { start, end, args } of parsed) {
171
173
  const varName = args[0];
172
- const fallback = args[1] || '';
174
+ const fallback = args[1];
173
175
  let varValue = hasOwn(varContext, varName) ? varContext[varName] : fallback;
176
+ if (varValue === undefined)
177
+ return;
174
178
  if (varUseRegExp.test(varValue)) {
175
- varValue = '' + resolveVar(varValue, varContext);
179
+ varValue = resolveVar(varValue, varContext);
180
+ if (varValue === undefined)
181
+ return;
176
182
  }
177
183
  else {
178
- varValue = '' + global.__formatValue(varValue);
184
+ varValue = global.__formatValue(varValue);
179
185
  }
180
186
  replaced.replace(start, end - 1, varValue);
181
- });
187
+ }
182
188
  return global.__formatValue(replaced.source());
183
189
  }
184
- function transformVar(styleObj, varKeyPaths, varContext) {
190
+ function transformVar(styleObj, varKeyPaths, varContext, visitOther) {
185
191
  varKeyPaths.forEach((varKeyPath) => {
186
192
  setStyle(styleObj, varKeyPath, ({ target, key, value }) => {
187
- target[key] = resolveVar(value, varContext);
193
+ const resolved = resolveVar(value, varContext);
194
+ if (resolved === undefined) {
195
+ delete target[key];
196
+ error(`Can not resolve css var at ${varKeyPath.join('.')}:${value}.`);
197
+ return;
198
+ }
199
+ target[key] = resolved;
200
+ visitOther({ target, key, value: target[key], keyPath: varKeyPath });
188
201
  });
189
202
  });
190
203
  }
@@ -224,28 +237,122 @@ function transformCalc(styleObj, calcKeyPaths, formatter) {
224
237
  });
225
238
  });
226
239
  }
227
- const stringifyProps = ['fontWeight'];
228
240
  function transformStringify(styleObj) {
229
- stringifyProps.forEach((prop) => {
230
- if (isNumber(styleObj[prop])) {
231
- styleObj[prop] = '' + styleObj[prop];
241
+ if (isNumber(styleObj.fontWeight)) {
242
+ styleObj.fontWeight = '' + styleObj.fontWeight;
243
+ }
244
+ }
245
+ function transformPosition(styleObj, meta) {
246
+ if (styleObj.position === 'fixed') {
247
+ styleObj.position = 'absolute';
248
+ meta.hasPositionFixed = true;
249
+ }
250
+ }
251
+ // 多value解析
252
+ function parseValues(str, char = ' ') {
253
+ let stack = 0;
254
+ let temp = '';
255
+ const result = [];
256
+ for (let i = 0; i < str.length; i++) {
257
+ if (str[i] === '(') {
258
+ stack++;
259
+ }
260
+ else if (str[i] === ')') {
261
+ stack--;
262
+ }
263
+ // 非括号内 或者 非分隔字符且非空
264
+ if (stack !== 0 || (str[i] !== char && str[i] !== ' ')) {
265
+ temp += str[i];
266
+ }
267
+ if ((stack === 0 && str[i] === char) || i === str.length - 1) {
268
+ result.push(temp);
269
+ temp = '';
270
+ }
271
+ }
272
+ return result;
273
+ }
274
+ // parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
275
+ function parseTransform(transformStr) {
276
+ const values = parseValues(transformStr);
277
+ const transform = [];
278
+ values.forEach(item => {
279
+ const match = item.match(/([/\w]+)\((.+)\)/);
280
+ if (match && match.length >= 3) {
281
+ let key = match[1];
282
+ const val = match[2];
283
+ switch (key) {
284
+ case 'translateX':
285
+ case 'translateY':
286
+ case 'scaleX':
287
+ case 'scaleY':
288
+ case 'rotateX':
289
+ case 'rotateY':
290
+ case 'rotateZ':
291
+ case 'rotate':
292
+ case 'skewX':
293
+ case 'skewY':
294
+ case 'perspective':
295
+ // rotate 处理成 rotateZ
296
+ key = key === 'rotate' ? 'rotateZ' : key;
297
+ // 单个值处理
298
+ transform.push({ [key]: global.__formatValue(val) });
299
+ break;
300
+ case 'matrix':
301
+ transform.push({ [key]: parseValues(val, ',').map(val => +val) });
302
+ break;
303
+ case 'translate':
304
+ case 'scale':
305
+ case 'skew':
306
+ case 'translate3d': // x y 支持 z不支持
307
+ case 'scale3d': // x y 支持 z不支持
308
+ {
309
+ // 2 个以上的值处理
310
+ key = key.replace('3d', '');
311
+ const vals = parseValues(val, ',').splice(0, 3);
312
+ // scale(.5) === scaleX(.5) scaleY(.5)
313
+ if (vals.length === 1 && key === 'scale') {
314
+ vals.push(vals[0]);
315
+ }
316
+ const xyz = ['X', 'Y', 'Z'];
317
+ transform.push(...vals.map((v, index) => {
318
+ return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
319
+ }));
320
+ break;
321
+ }
322
+ }
232
323
  }
233
324
  });
325
+ return transform;
326
+ }
327
+ // format style transform
328
+ function transformTransform(style) {
329
+ if (!style.transform || Array.isArray(style.transform))
330
+ return;
331
+ style.transform = parseTransform(style.transform);
332
+ }
333
+ function transformBoxShadow(styleObj) {
334
+ if (!styleObj.boxShadow)
335
+ return;
336
+ styleObj.boxShadow = parseValues(styleObj.boxShadow).reduce((res, i, idx) => {
337
+ return `${res}${idx === 0 ? '' : ' '}${global.__formatValue(i)}`;
338
+ }, '');
234
339
  }
235
340
  export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight }) {
236
341
  const varStyle = {};
237
342
  const unoVarStyle = {};
238
343
  const normalStyle = {};
239
- const normalStyleRef = useRef({});
240
- const normalStyleChangedRef = useRef(false);
241
344
  let hasVarDec = false;
242
345
  let hasVarUse = false;
346
+ let hasSelfPercent = false;
243
347
  const varKeyPaths = [];
244
348
  const unoVarKeyPaths = [];
349
+ const percentKeyPaths = [];
350
+ const calcKeyPaths = [];
351
+ const envKeyPaths = [];
245
352
  const [width, setWidth] = useState(0);
246
353
  const [height, setHeight] = useState(0);
247
354
  const navigation = useNavigation();
248
- function varVisitor({ key, value, keyPath }) {
355
+ function varVisitor({ target, key, value, keyPath }) {
249
356
  if (keyPath.length === 1) {
250
357
  if (unoVarDecRegExp.test(key)) {
251
358
  unoVarStyle[key] = value;
@@ -269,6 +376,33 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
269
376
  hasVarUse = true;
270
377
  varKeyPaths.push(keyPath.slice());
271
378
  }
379
+ else {
380
+ visitOther({ target, key, value, keyPath });
381
+ }
382
+ }
383
+ }
384
+ function envVisitor({ value, keyPath }) {
385
+ if (envUseRegExp.test(value)) {
386
+ envKeyPaths.push(keyPath.slice());
387
+ }
388
+ }
389
+ function calcVisitor({ value, keyPath }) {
390
+ if (calcUseRegExp.test(value)) {
391
+ calcKeyPaths.push(keyPath.slice());
392
+ }
393
+ }
394
+ function percentVisitor({ key, value, keyPath }) {
395
+ if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) {
396
+ hasSelfPercent = true;
397
+ percentKeyPaths.push(keyPath.slice());
398
+ }
399
+ else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
400
+ percentKeyPaths.push(keyPath.slice());
401
+ }
402
+ }
403
+ function visitOther({ target, key, value, keyPath }) {
404
+ if (filterRegExp.test(value)) {
405
+ [envVisitor, percentVisitor, calcVisitor].forEach(visitor => visitor({ target, key, value, keyPath }));
272
406
  }
273
407
  }
274
408
  // traverse var & generate normalStyle
@@ -289,96 +423,61 @@ export function useTransformStyle(styleObj = {}, { enableVar, externalVarContext
289
423
  if (diffAndCloneA(varContextRef.current, newVarContext).diff) {
290
424
  varContextRef.current = newVarContext;
291
425
  }
292
- transformVar(normalStyle, varKeyPaths, varContextRef.current);
426
+ transformVar(normalStyle, varKeyPaths, varContextRef.current, visitOther);
293
427
  }
294
428
  // apply unocss var
295
429
  if (unoVarKeyPaths.length) {
296
- transformVar(normalStyle, unoVarKeyPaths, unoVarStyle);
430
+ transformVar(normalStyle, unoVarKeyPaths, unoVarStyle, visitOther);
297
431
  }
298
- const { clone, diff } = diffAndCloneA(normalStyle, normalStyleRef.current);
299
- if (diff) {
300
- normalStyleRef.current = clone;
301
- normalStyleChangedRef.current = !normalStyleChangedRef.current;
302
- }
303
- const memoResult = useMemo(() => {
304
- let hasSelfPercent = false;
305
- let hasPositionFixed = false;
306
- const percentKeyPaths = [];
307
- const calcKeyPaths = [];
308
- const envKeyPaths = [];
309
- // transform can be memoized
310
- function envVisitor({ value, keyPath }) {
311
- if (envUseRegExp.test(value)) {
312
- envKeyPaths.push(keyPath.slice());
313
- }
314
- }
315
- function calcVisitor({ value, keyPath }) {
316
- if (calcUseRegExp.test(value)) {
317
- calcKeyPaths.push(keyPath.slice());
318
- }
319
- }
320
- function percentVisitor({ key, value, keyPath }) {
321
- if (hasOwn(selfPercentRule, key) && PERCENT_REGEX.test(value)) {
322
- hasSelfPercent = true;
323
- percentKeyPaths.push(keyPath.slice());
324
- }
325
- else if ((key === 'fontSize' || key === 'lineHeight') && PERCENT_REGEX.test(value)) {
326
- percentKeyPaths.push(keyPath.slice());
327
- }
328
- }
329
- function transformPosition(styleObj) {
330
- if (styleObj.position === 'fixed') {
331
- hasPositionFixed = true;
332
- styleObj.position = 'absolute';
333
- }
432
+ const percentConfig = {
433
+ width,
434
+ height,
435
+ fontSize: normalStyle.fontSize,
436
+ parentWidth,
437
+ parentHeight,
438
+ parentFontSize
439
+ };
440
+ const positionMeta = {
441
+ hasPositionFixed: false
442
+ };
443
+ // apply env
444
+ transformEnv(normalStyle, envKeyPaths, navigation);
445
+ // apply percent
446
+ transformPercent(normalStyle, percentKeyPaths, percentConfig);
447
+ // apply calc
448
+ transformCalc(normalStyle, calcKeyPaths, (value, key) => {
449
+ if (PERCENT_REGEX.test(value)) {
450
+ const resolved = resolvePercent(value, key, percentConfig);
451
+ return typeof resolved === 'number' ? resolved : 0;
334
452
  }
335
- // traverse env & calc & percent
336
- traverseStyle(normalStyle, [envVisitor, percentVisitor, calcVisitor]);
337
- const percentConfig = {
338
- width,
339
- height,
340
- fontSize: normalStyle.fontSize,
341
- parentWidth,
342
- parentHeight,
343
- parentFontSize
344
- };
345
- // apply env
346
- transformEnv(normalStyle, envKeyPaths, navigation);
347
- // apply percent
348
- transformPercent(normalStyle, percentKeyPaths, percentConfig);
349
- // apply calc
350
- transformCalc(normalStyle, calcKeyPaths, (value, key) => {
351
- if (PERCENT_REGEX.test(value)) {
352
- const resolved = resolvePercent(value, key, percentConfig);
353
- return typeof resolved === 'number' ? resolved : 0;
453
+ else {
454
+ const formatted = global.__formatValue(value);
455
+ if (typeof formatted === 'number') {
456
+ return formatted;
354
457
  }
355
458
  else {
356
- const formatted = global.__formatValue(value);
357
- if (typeof formatted === 'number') {
358
- return formatted;
359
- }
360
- else {
361
- warn('calc() only support number, px, rpx, % temporarily.');
362
- return 0;
363
- }
459
+ warn('calc() only support number, px, rpx, % temporarily.');
460
+ return 0;
364
461
  }
365
- });
366
- // apply position
367
- transformPosition(normalStyle);
368
- // transform number enum stringify
369
- transformStringify(normalStyle);
370
- return {
371
- normalStyle,
372
- hasSelfPercent,
373
- hasPositionFixed
374
- };
375
- }, [normalStyleChangedRef.current, width, height, parentWidth, parentHeight, parentFontSize]);
376
- return extendObject({
462
+ }
463
+ });
464
+ // apply position
465
+ transformPosition(normalStyle, positionMeta);
466
+ // transform number enum stringify
467
+ transformStringify(normalStyle);
468
+ // transform rpx to px
469
+ transformBoxShadow(normalStyle);
470
+ // transform 字符串格式转化数组格式
471
+ transformTransform(normalStyle);
472
+ return {
377
473
  hasVarDec,
378
474
  varContextRef,
379
475
  setWidth,
380
- setHeight
381
- }, memoResult);
476
+ setHeight,
477
+ normalStyle,
478
+ hasSelfPercent,
479
+ hasPositionFixed: positionMeta.hasPositionFixed
480
+ };
382
481
  }
383
482
  export function traverseStyle(styleObj, visitors) {
384
483
  const keyPath = [];
@@ -387,12 +486,7 @@ export function traverseStyle(styleObj, visitors) {
387
486
  target.forEach((value, index) => {
388
487
  const key = String(index);
389
488
  keyPath.push(key);
390
- visitors.forEach(visitor => visitor({
391
- target,
392
- key,
393
- value,
394
- keyPath
395
- }));
489
+ visitors.forEach(visitor => visitor({ target, key, value, keyPath }));
396
490
  traverse(value);
397
491
  keyPath.pop();
398
492
  });
@@ -450,7 +544,7 @@ export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout
450
544
  }
451
545
  if (enableOffset) {
452
546
  nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
453
- const { y: navigationY = 0 } = navigation?.layout || {};
547
+ const { top: navigationY = 0 } = navigation?.layout || {};
454
548
  layoutRef.current = { x, y: y - navigationY, width, height, offsetLeft, offsetTop: offsetTop - navigationY };
455
549
  });
456
550
  }
@@ -527,7 +621,7 @@ export function getCurrentPage(pageId) {
527
621
  }
528
622
  export function renderImage(imageProps, enableFastImage = false) {
529
623
  const Component = enableFastImage ? FastImage : Image;
530
- return <Component {...imageProps}/>;
624
+ return createElement(Component, imageProps);
531
625
  }
532
626
  export function pickStyle(styleObj = {}, pickedKeys, callback) {
533
627
  return pickedKeys.reduce((acc, key) => {
@@ -578,13 +672,11 @@ export function useHover({ enableHover, hoverStartTime, hoverStayTime, disabled
578
672
  const gesture = useMemo(() => {
579
673
  return Gesture.Pan()
580
674
  .onTouchesDown(() => {
581
- 'worklet';
582
- runOnJS(setStartTimer)();
675
+ setStartTimer();
583
676
  })
584
677
  .onTouchesUp(() => {
585
- 'worklet';
586
- runOnJS(setStayTimer)();
587
- });
678
+ setStayTimer();
679
+ }).runOnJS(true);
588
680
  }, []);
589
681
  if (gestureRef) {
590
682
  gesture.simultaneousWithExternalGesture(gestureRef);
@@ -594,3 +686,17 @@ export function useHover({ enableHover, hoverStartTime, hoverStayTime, disabled
594
686
  gesture
595
687
  };
596
688
  }
689
+ export function useRunOnJSCallback(callbackMapRef) {
690
+ const invokeCallback = useCallback((key, ...args) => {
691
+ const callback = callbackMapRef.current[key];
692
+ // eslint-disable-next-line node/no-callback-literal
693
+ if (isFunction(callback))
694
+ return callback(...args);
695
+ }, []);
696
+ useEffect(() => {
697
+ return () => {
698
+ callbackMapRef.current = {};
699
+ };
700
+ }, []);
701
+ return invokeCallback;
702
+ }
@@ -1,5 +1,13 @@
1
1
  <script>
2
2
  import mpx from '@mpxjs/core'
3
+
4
+ const isIOS = /iP(hone|od|ad)/.test(navigator.userAgent)
5
+ const innerHeight = (isIOS ? 44 : 48) + 'px'
6
+
7
+ const safeStyle = { paddingTop: 'var(--safe-area-inset-top)' }
8
+
9
+ console.log('isIOS', isIOS)
10
+
3
11
  export default {
4
12
  name: 'mpx-titlebar',
5
13
  props: {
@@ -49,24 +57,20 @@ export default {
49
57
  return false
50
58
  }
51
59
  },
52
- // safe area 顶部 padding,使用 env(safe-area-inset-top)
53
- safeStyle() {
54
- // 多数浏览器支持 env(), 为兼容也使用 constant() 备选(旧 iOS Safari)
55
- return {
56
- paddingTop: 'env(safe-area-inset-top, 0px)'
60
+ // 安卓安全高度
61
+ safeAreaInsetTop() {
62
+ if (typeof mpx.config.webConfig.safeAreaInsetTop === 'number' && mpx.config.webConfig.safeAreaInsetTop >= 0) {
63
+ return mpx.config.webConfig.safeAreaInsetTop
57
64
  }
65
+ return 24
58
66
  },
59
67
  warpStyle() {
60
68
  return {
61
- paddingTop: 'calc(env(safe-area-inset-top, 0px) + 44px)',
62
- height: '100%'
69
+ '--titlebar-height': innerHeight,
70
+ '--safe-area-inset-top': `${isIOS ? 'env(safe-area-inset-top, constant(safe-area-inset-top), 0px)' : this.safeAreaInsetTop + 'px'}`,
71
+ paddingTop: 'calc(var(--safe-area-inset-top) + var(--titlebar-height))',
63
72
  }
64
73
  },
65
- // 内部标题栏高度(遵循小程序常见平台差异)
66
- innerHeight() {
67
- const isIOS = /iP(hone|od|ad)/.test(navigator.userAgent)
68
- return (isIOS ? 44 : 48) + 'px'
69
- },
70
74
  rootStyle() {
71
75
  return {
72
76
  background: this.backgroundColor,
@@ -75,7 +79,7 @@ export default {
75
79
  },
76
80
  innerStyle() {
77
81
  return {
78
- height: this.innerHeight
82
+ height: innerHeight
79
83
  }
80
84
  }
81
85
  },
@@ -134,7 +138,7 @@ export default {
134
138
  class: ['mpx-titlebar'],
135
139
  style: this.rootStyle
136
140
  }, [
137
- h('div', { class: 'mpx-titlebar__safe', style: this.safeStyle }, [
141
+ h('div', { class: 'mpx-titlebar__safe', style: safeStyle }, [
138
142
  h('div', { class: 'mpx-titlebar__inner', style: this.innerStyle }, [
139
143
  h('div', { class: 'mpx-titlebar__left', on: { click: this.onLeftClick } }, leftChildren),
140
144
  h('div', { class: 'mpx-titlebar__center' }, centerChildren),
@@ -151,6 +155,7 @@ export default {
151
155
  <style scoped>
152
156
  .mpx-page-warp {
153
157
  width: 100%;
158
+ height: 100%;
154
159
  box-sizing: border-box;
155
160
  }
156
161
 
@@ -160,9 +165,7 @@ export default {
160
165
  }
161
166
 
162
167
  .mpx-titlebar__safe {
163
- /* safe area handled by padding-top; include both env and constant for broader iOS support */
164
- padding-top: env(safe-area-inset-top, 0px);
165
- padding-top: constant(safe-area-inset-top, 0px);
168
+ padding-top: var(--safe-area-inset-top);
166
169
  }
167
170
 
168
171
  .mpx-titlebar__inner {
@@ -209,7 +212,7 @@ export default {
209
212
 
210
213
  .mpx-titlebar {
211
214
  /* flex-shrink: 0; */
212
- height: calc(env(safe-area-inset-top, 0px) + 44px);
215
+ height: calc(var(--safe-area-inset-top) + var(--titlebar-height));
213
216
  width: 100%;
214
217
  box-sizing: border-box;
215
218
  -webkit-font-smoothing: antialiased;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.10.3-beta.17",
3
+ "version": "2.10.3-beta.18",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"