@mpxjs/webpack-plugin 2.9.69 → 2.9.70-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/config.js +14 -0
- package/lib/dependencies/AddEntryDependency.js +24 -0
- package/lib/dependencies/ResolveDependency.js +5 -0
- package/lib/index.js +38 -7
- package/lib/json-compiler/helper.js +3 -3
- package/lib/loader.js +52 -0
- package/lib/platform/template/wx/component-config/button.js +14 -2
- package/lib/platform/template/wx/component-config/image.js +4 -0
- package/lib/platform/template/wx/component-config/input.js +5 -1
- package/lib/platform/template/wx/component-config/rich-text.js +4 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
- package/lib/platform/template/wx/component-config/swiper.js +1 -1
- package/lib/platform/template/wx/component-config/switch.js +4 -0
- package/lib/platform/template/wx/component-config/text.js +4 -0
- package/lib/platform/template/wx/component-config/textarea.js +6 -1
- package/lib/platform/template/wx/component-config/view.js +4 -0
- package/lib/platform/template/wx/index.js +127 -1
- package/lib/react/processTemplate.js +3 -0
- package/lib/resolve-loader.js +4 -1
- package/lib/runtime/components/react/context.ts +4 -0
- package/lib/runtime/components/react/dist/context.js +5 -0
- package/lib/runtime/components/react/dist/event.config.js +24 -24
- package/lib/runtime/components/react/dist/getInnerListeners.js +183 -166
- package/lib/runtime/components/react/dist/locale-provider.jsx +15 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +39 -74
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +30 -12
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +13 -19
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +29 -38
- package/lib/runtime/components/react/dist/mpx-form.jsx +16 -19
- package/lib/runtime/components/react/dist/mpx-icon.jsx +8 -16
- package/lib/runtime/components/react/dist/mpx-image.jsx +295 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +54 -27
- package/lib/runtime/components/react/dist/mpx-label.jsx +15 -22
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +13 -16
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +14 -14
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +2 -4
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +5 -3
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +6 -2
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +10 -14
- package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +39 -0
- package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +126 -112
- package/lib/runtime/components/react/dist/mpx-picker-view.jsx +32 -29
- package/lib/runtime/components/react/dist/mpx-portal/portal-consumer.jsx +23 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +124 -0
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +40 -0
- package/lib/runtime/components/react/dist/mpx-portal.jsx +12 -0
- package/lib/runtime/components/react/dist/mpx-provider.jsx +31 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -19
- package/lib/runtime/components/react/dist/mpx-radio.jsx +27 -42
- package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +62 -0
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +7 -5
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +62 -47
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +28 -9
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +613 -0
- package/lib/runtime/components/react/dist/mpx-switch.jsx +20 -10
- package/lib/runtime/components/react/dist/mpx-text.jsx +11 -10
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +8 -3
- package/lib/runtime/components/react/dist/mpx-view.jsx +37 -89
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +205 -46
- package/lib/runtime/components/react/dist/pickerFaces.js +12 -6
- package/lib/runtime/components/react/dist/pickerVIewContext.js +9 -0
- package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
- package/lib/runtime/components/react/dist/{pickerOverlay.jsx → pickerViewOverlay.jsx} +5 -3
- package/lib/runtime/components/react/dist/useAnimationHooks.js +50 -12
- package/lib/runtime/components/react/dist/utils.jsx +83 -28
- package/lib/runtime/components/react/getInnerListeners.ts +35 -28
- package/lib/runtime/components/react/mpx-button.tsx +55 -36
- package/lib/runtime/components/react/mpx-canvas/index.tsx +2 -2
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +13 -12
- package/lib/runtime/components/react/mpx-checkbox.tsx +28 -28
- package/lib/runtime/components/react/mpx-form.tsx +10 -8
- package/lib/runtime/components/react/mpx-icon.tsx +10 -15
- package/lib/runtime/components/react/mpx-image.tsx +396 -0
- package/lib/runtime/components/react/mpx-input.tsx +61 -33
- package/lib/runtime/components/react/mpx-label.tsx +14 -13
- package/lib/runtime/components/react/mpx-movable-area.tsx +8 -7
- package/lib/runtime/components/react/mpx-movable-view.tsx +1 -1
- package/lib/runtime/components/react/mpx-picker/date.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/index.tsx +3 -2
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/region.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/selector.tsx +5 -2
- package/lib/runtime/components/react/mpx-picker/time.tsx +10 -15
- package/lib/runtime/components/react/mpx-picker/type.ts +48 -43
- package/lib/runtime/components/react/mpx-picker-view-column.tsx +4 -1
- package/lib/runtime/components/react/mpx-picker-view.tsx +7 -1
- package/lib/runtime/components/react/mpx-radio-group.tsx +11 -12
- package/lib/runtime/components/react/mpx-radio.tsx +26 -29
- package/lib/runtime/components/react/mpx-scroll-view.tsx +32 -30
- package/lib/runtime/components/react/mpx-simple-text.tsx +18 -0
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +4 -2
- package/lib/runtime/components/react/mpx-swiper-item.tsx +3 -2
- package/lib/runtime/components/react/mpx-switch.tsx +10 -8
- package/lib/runtime/components/react/mpx-text.tsx +6 -2
- package/lib/runtime/components/react/mpx-view.tsx +37 -45
- package/lib/runtime/components/react/mpx-web-view.tsx +25 -15
- package/lib/runtime/components/react/types/global.d.ts +1 -16
- package/lib/runtime/components/react/utils.tsx +24 -24
- package/lib/runtime/components/tenon/getInnerListeners.js +334 -0
- package/lib/runtime/components/tenon/tenon-button.vue +309 -0
- package/lib/runtime/components/tenon/tenon-image.vue +66 -0
- package/lib/runtime/components/tenon/tenon-input.vue +171 -0
- package/lib/runtime/components/tenon/tenon-rich-text.vue +26 -0
- package/lib/runtime/components/tenon/tenon-scroll-view.vue +127 -0
- package/lib/runtime/components/tenon/tenon-switch.vue +96 -0
- package/lib/runtime/components/tenon/tenon-text.vue +70 -0
- package/lib/runtime/components/tenon/tenon-textarea.vue +86 -0
- package/lib/runtime/components/tenon/tenon-view.vue +93 -0
- package/lib/runtime/components/web/getInnerListeners.js +6 -6
- package/lib/runtime/components/web/mpx-movable-view.vue +334 -344
- package/lib/runtime/components/web/mpx-picker-view-column.vue +75 -75
- package/lib/runtime/components/web/mpx-picker.vue +382 -385
- package/lib/runtime/components/web/mpx-web-view.vue +162 -162
- package/lib/runtime/optionProcessor.js +7 -16
- package/lib/runtime/optionProcessor.tenon.js +84 -0
- package/lib/runtime/utils.js +2 -0
- package/lib/style-compiler/index.js +1 -1
- package/lib/style-compiler/plugins/hm.js +20 -0
- package/lib/template-compiler/bind-this.js +7 -2
- package/lib/template-compiler/compiler.js +67 -40
- package/lib/template-compiler/gen-node-react.js +2 -2
- package/lib/tenon/index.js +112 -0
- package/lib/tenon/processJSON.js +352 -0
- package/lib/tenon/processScript.js +198 -0
- package/lib/tenon/processStyles.js +21 -0
- package/lib/tenon/processTemplate.js +125 -0
- package/lib/tenon/script-helper.js +223 -0
- package/lib/utils/env.js +6 -1
- package/lib/utils/get-relative-path.js +25 -0
- package/package.json +7 -3
- package/LICENSE +0 -433
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +0 -226
- package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -7
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +0 -478
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +0 -68
- package/lib/runtime/components/react/dist/mpx-swiper/type.js +0 -1
- package/lib/runtime/components/react/mpx-image/index.tsx +0 -345
- package/lib/runtime/components/react/mpx-image/svg.tsx +0 -22
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
* ✘ decode
|
|
5
5
|
*/
|
|
6
6
|
import { Text } from 'react-native';
|
|
7
|
-
import { useRef, forwardRef } from 'react';
|
|
7
|
+
import { useRef, forwardRef, createElement } from 'react';
|
|
8
8
|
import useInnerProps from './getInnerListeners';
|
|
9
9
|
import useNodesRef from './useNodesRef'; // 引入辅助函数
|
|
10
10
|
import { useTransformStyle, wrapChildren } from './utils';
|
|
11
11
|
const _Text = forwardRef((props, ref) => {
|
|
12
|
-
const { style = {}, selectable, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'user-select': userSelect, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
12
|
+
const { style = {}, allowFontScaling = false, selectable, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'user-select': userSelect, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
13
13
|
const layoutRef = useRef({});
|
|
14
14
|
const { normalStyle, hasVarDec, varContextRef } = useTransformStyle(style, {
|
|
15
15
|
enableVar,
|
|
@@ -19,22 +19,23 @@ const _Text = forwardRef((props, ref) => {
|
|
|
19
19
|
parentHeight
|
|
20
20
|
});
|
|
21
21
|
const nodeRef = useRef(null);
|
|
22
|
-
useNodesRef(props, ref, nodeRef
|
|
22
|
+
useNodesRef(props, ref, nodeRef, {
|
|
23
|
+
style: normalStyle
|
|
24
|
+
});
|
|
23
25
|
const innerProps = useInnerProps(props, {
|
|
24
26
|
ref: nodeRef,
|
|
25
27
|
style: normalStyle,
|
|
26
|
-
selectable: !!selectable || !!userSelect
|
|
28
|
+
selectable: !!selectable || !!userSelect,
|
|
29
|
+
allowFontScaling
|
|
27
30
|
}, [
|
|
28
31
|
'user-select'
|
|
29
32
|
], {
|
|
30
33
|
layoutRef
|
|
31
34
|
});
|
|
32
|
-
return (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
})}
|
|
37
|
-
</Text>);
|
|
35
|
+
return createElement(Text, innerProps, wrapChildren(props, {
|
|
36
|
+
hasVarDec,
|
|
37
|
+
varContext: varContextRef.current
|
|
38
|
+
}));
|
|
38
39
|
});
|
|
39
40
|
_Text.displayName = 'MpxText';
|
|
40
41
|
export default _Text;
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* ✘ show-confirm-bar
|
|
10
10
|
* ✔ bindlinechange: No `heightRpx` info.
|
|
11
11
|
*/
|
|
12
|
-
import { forwardRef } from 'react';
|
|
12
|
+
import { forwardRef, createElement } from 'react';
|
|
13
13
|
import { Keyboard } from 'react-native';
|
|
14
14
|
import Input from './mpx-input';
|
|
15
|
-
import { omit } from './utils';
|
|
15
|
+
import { omit, extendObject } from './utils';
|
|
16
16
|
const Textarea = forwardRef((props, ref) => {
|
|
17
17
|
const restProps = omit(props, [
|
|
18
18
|
'ref',
|
|
@@ -21,7 +21,12 @@ const Textarea = forwardRef((props, ref) => {
|
|
|
21
21
|
'multiline',
|
|
22
22
|
'confirm-hold'
|
|
23
23
|
]);
|
|
24
|
-
return (
|
|
24
|
+
return createElement(Input, extendObject({
|
|
25
|
+
ref: ref,
|
|
26
|
+
multiline: true,
|
|
27
|
+
confirmType: 'next',
|
|
28
|
+
bindblur: () => Keyboard.dismiss()
|
|
29
|
+
}, restProps));
|
|
25
30
|
});
|
|
26
31
|
Textarea.displayName = 'MpxTextarea';
|
|
27
32
|
export default Textarea;
|
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
* ✔ hover-stay-time
|
|
6
6
|
*/
|
|
7
7
|
import { View, StyleSheet, Image } from 'react-native';
|
|
8
|
-
import { useRef, useState, useEffect, forwardRef } from 'react';
|
|
8
|
+
import { useRef, useState, useEffect, forwardRef, createElement } from 'react';
|
|
9
9
|
import useInnerProps from './getInnerListeners';
|
|
10
10
|
import Animated from 'react-native-reanimated';
|
|
11
11
|
import useAnimationHooks from './useAnimationHooks';
|
|
12
12
|
import useNodesRef from './useNodesRef';
|
|
13
|
-
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle } from './utils';
|
|
13
|
+
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout, renderImage, pickStyle, extendObject, useHoverStyle } from './utils';
|
|
14
|
+
import { error } from '@mpxjs/utils';
|
|
14
15
|
import LinearGradient from 'react-native-linear-gradient';
|
|
16
|
+
import { GestureDetector } from 'react-native-gesture-handler';
|
|
15
17
|
const linearMap = new Map([
|
|
16
18
|
['top', 0],
|
|
17
19
|
['bottom', 180],
|
|
@@ -148,10 +150,7 @@ function backgroundPosition(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
148
150
|
style[key] = val;
|
|
149
151
|
}
|
|
150
152
|
}
|
|
151
|
-
imageProps.style
|
|
152
|
-
...imageProps.style,
|
|
153
|
-
...style
|
|
154
|
-
};
|
|
153
|
+
extendObject(imageProps.style, style);
|
|
155
154
|
}
|
|
156
155
|
// background-size 转换
|
|
157
156
|
function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
@@ -209,10 +208,7 @@ function backgroundSize(imageProps, preImageInfo, imageSize, layoutInfo) {
|
|
|
209
208
|
}
|
|
210
209
|
}
|
|
211
210
|
// 样式合并
|
|
212
|
-
imageProps.style
|
|
213
|
-
...imageProps.style,
|
|
214
|
-
...dimensions
|
|
215
|
-
};
|
|
211
|
+
extendObject(imageProps.style, dimensions);
|
|
216
212
|
}
|
|
217
213
|
// background-image转换为source
|
|
218
214
|
function backgroundImage(imageProps, preImageInfo) {
|
|
@@ -385,10 +381,9 @@ function parseLinearGradient(text) {
|
|
|
385
381
|
!isNaN(numberVal) && locations.push(numberVal);
|
|
386
382
|
return prev;
|
|
387
383
|
}, { colors: [], locations: [] });
|
|
388
|
-
return {
|
|
389
|
-
...linearInfo,
|
|
384
|
+
return extendObject({}, linearInfo, {
|
|
390
385
|
direction: direction.trim()
|
|
391
|
-
};
|
|
386
|
+
});
|
|
392
387
|
}
|
|
393
388
|
function parseBgImage(text) {
|
|
394
389
|
if (!text)
|
|
@@ -533,6 +528,11 @@ function wrapImage(imageStyle, innerStyle, enableFastImage) {
|
|
|
533
528
|
</View>;
|
|
534
529
|
}
|
|
535
530
|
function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backgroundStyle, varContext, textProps, innerStyle, enableFastImage }) {
|
|
531
|
+
enableBackground = enableBackground || !!backgroundStyle;
|
|
532
|
+
const enableBackgroundRef = useRef(enableBackground);
|
|
533
|
+
if (enableBackgroundRef.current !== enableBackground) {
|
|
534
|
+
error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.');
|
|
535
|
+
}
|
|
536
536
|
const children = wrapChildren(props, {
|
|
537
537
|
hasVarDec,
|
|
538
538
|
varContext,
|
|
@@ -546,23 +546,18 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
|
|
|
546
546
|
}
|
|
547
547
|
const _View = forwardRef((viewProps, ref) => {
|
|
548
548
|
const { textProps, innerProps: props = {} } = splitProps(viewProps);
|
|
549
|
-
|
|
550
|
-
const [isHover, setIsHover] = useState(false);
|
|
549
|
+
const { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'enable-fast-image': enableFastImage, 'enable-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
|
|
551
550
|
// 默认样式
|
|
552
|
-
const defaultStyle =
|
|
553
|
-
|
|
554
|
-
...style.display === 'flex' && {
|
|
551
|
+
const defaultStyle = style.display === 'flex'
|
|
552
|
+
? {
|
|
555
553
|
flexDirection: 'row',
|
|
556
554
|
flexBasis: 'auto',
|
|
557
555
|
flexShrink: 1,
|
|
558
556
|
flexWrap: 'nowrap'
|
|
559
557
|
}
|
|
560
|
-
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
...style,
|
|
564
|
-
...(isHover ? hoverStyle : null)
|
|
565
|
-
};
|
|
558
|
+
: {};
|
|
559
|
+
const { isHover, enableHoverStyle, gesture } = useHoverStyle({ hoverStyle, hoverStartTime, hoverStayTime });
|
|
560
|
+
const styleObj = extendObject({}, defaultStyle, style, isHover ? hoverStyle : {});
|
|
566
561
|
const { normalStyle, hasSelfPercent, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, {
|
|
567
562
|
enableVar,
|
|
568
563
|
externalVarContext,
|
|
@@ -570,68 +565,22 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
570
565
|
parentWidth,
|
|
571
566
|
parentHeight
|
|
572
567
|
});
|
|
573
|
-
const { textStyle, backgroundStyle, innerStyle } = splitStyle(normalStyle);
|
|
574
|
-
enableBackground = enableBackground || !!backgroundStyle;
|
|
575
|
-
const enableBackgroundRef = useRef(enableBackground);
|
|
576
|
-
if (enableBackgroundRef.current !== enableBackground) {
|
|
577
|
-
throw new Error('[Mpx runtime error]: background use should be stable in the component lifecycle, or you can set [enable-background] with true.');
|
|
578
|
-
}
|
|
568
|
+
const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle);
|
|
579
569
|
const nodeRef = useRef(null);
|
|
580
570
|
useNodesRef(props, ref, nodeRef, {
|
|
581
|
-
|
|
571
|
+
style: normalStyle
|
|
582
572
|
});
|
|
583
|
-
const dataRef = useRef({});
|
|
584
|
-
useEffect(() => {
|
|
585
|
-
return () => {
|
|
586
|
-
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
587
|
-
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
|
|
588
|
-
};
|
|
589
|
-
}, []);
|
|
590
|
-
const setStartTimer = () => {
|
|
591
|
-
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
592
|
-
dataRef.current.startTimer = setTimeout(() => {
|
|
593
|
-
setIsHover(true);
|
|
594
|
-
}, +hoverStartTime);
|
|
595
|
-
};
|
|
596
|
-
const setStayTimer = () => {
|
|
597
|
-
dataRef.current.stayTimer && clearTimeout(dataRef.current.stayTimer);
|
|
598
|
-
dataRef.current.startTimer && clearTimeout(dataRef.current.startTimer);
|
|
599
|
-
dataRef.current.stayTimer = setTimeout(() => {
|
|
600
|
-
setIsHover(false);
|
|
601
|
-
}, +hoverStayTime);
|
|
602
|
-
};
|
|
603
|
-
function onTouchStart(e) {
|
|
604
|
-
const { bindtouchstart } = props;
|
|
605
|
-
bindtouchstart && bindtouchstart(e);
|
|
606
|
-
setStartTimer();
|
|
607
|
-
}
|
|
608
|
-
function onTouchEnd(e) {
|
|
609
|
-
const { bindtouchend } = props;
|
|
610
|
-
bindtouchend && bindtouchend(e);
|
|
611
|
-
setStayTimer();
|
|
612
|
-
}
|
|
613
573
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
614
|
-
const viewStyle =
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
}
|
|
620
|
-
const
|
|
621
|
-
? useAnimationHooks({
|
|
622
|
-
animation,
|
|
623
|
-
style: viewStyle
|
|
624
|
-
})
|
|
625
|
-
: viewStyle;
|
|
626
|
-
const innerProps = useInnerProps(props, {
|
|
574
|
+
const viewStyle = extendObject({}, innerStyle, layoutStyle);
|
|
575
|
+
const { enableStyleAnimation, animationStyle } = useAnimationHooks({
|
|
576
|
+
enableAnimation,
|
|
577
|
+
animation,
|
|
578
|
+
style: viewStyle
|
|
579
|
+
});
|
|
580
|
+
const innerProps = useInnerProps(props, extendObject({
|
|
627
581
|
ref: nodeRef,
|
|
628
|
-
style:
|
|
629
|
-
|
|
630
|
-
...(hoverStyle && {
|
|
631
|
-
bindtouchstart: onTouchStart,
|
|
632
|
-
bindtouchend: onTouchEnd
|
|
633
|
-
})
|
|
634
|
-
}, [
|
|
582
|
+
style: enableStyleAnimation ? [viewStyle, animationStyle] : viewStyle
|
|
583
|
+
}, layoutProps), [
|
|
635
584
|
'hover-start-time',
|
|
636
585
|
'hover-stay-time',
|
|
637
586
|
'hover-style',
|
|
@@ -641,7 +590,7 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
641
590
|
});
|
|
642
591
|
const childNode = wrapWithChildren(props, {
|
|
643
592
|
hasVarDec,
|
|
644
|
-
enableBackground
|
|
593
|
+
enableBackground,
|
|
645
594
|
textStyle,
|
|
646
595
|
backgroundStyle,
|
|
647
596
|
varContext: varContextRef.current,
|
|
@@ -649,13 +598,12 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
649
598
|
innerStyle,
|
|
650
599
|
enableFastImage
|
|
651
600
|
});
|
|
652
|
-
|
|
653
|
-
? (
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
</View>);
|
|
601
|
+
const BaseComponent = enableStyleAnimation
|
|
602
|
+
? createElement(Animated.View, innerProps, childNode)
|
|
603
|
+
: createElement(View, innerProps, childNode);
|
|
604
|
+
return enableHoverStyle
|
|
605
|
+
? createElement(GestureDetector, { gesture }, BaseComponent)
|
|
606
|
+
: BaseComponent;
|
|
659
607
|
});
|
|
660
608
|
_View.displayName = 'MpxView';
|
|
661
609
|
export default _View;
|
|
@@ -1,19 +1,58 @@
|
|
|
1
|
-
import { forwardRef,
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
import { forwardRef, useRef, useContext, useMemo, useState, useCallback, useEffect } from 'react';
|
|
2
|
+
import { warn, getFocusedNavigation, isFunction } from '@mpxjs/utils';
|
|
3
|
+
import Portal from './mpx-portal';
|
|
4
4
|
import { getCustomEvent } from './getInnerListeners';
|
|
5
5
|
import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
|
|
6
6
|
import { WebView } from 'react-native-webview';
|
|
7
7
|
import useNodesRef from './useNodesRef';
|
|
8
|
-
import { getCurrentPage } from './utils';
|
|
8
|
+
import { getCurrentPage, extendObject } from './utils';
|
|
9
9
|
import { RouteContext } from './context';
|
|
10
|
+
import { BackHandler, StyleSheet, View, Text, Platform } from 'react-native';
|
|
11
|
+
const styles = StyleSheet.create({
|
|
12
|
+
loadErrorContext: {
|
|
13
|
+
display: 'flex',
|
|
14
|
+
alignItems: 'center'
|
|
15
|
+
},
|
|
16
|
+
loadErrorText: {
|
|
17
|
+
fontSize: 12,
|
|
18
|
+
color: '#666666',
|
|
19
|
+
paddingTop: '40%',
|
|
20
|
+
paddingBottom: 20,
|
|
21
|
+
paddingLeft: '10%',
|
|
22
|
+
paddingRight: '10%',
|
|
23
|
+
textAlign: 'center'
|
|
24
|
+
},
|
|
25
|
+
loadErrorButton: {
|
|
26
|
+
color: '#666666',
|
|
27
|
+
textAlign: 'center',
|
|
28
|
+
padding: 10,
|
|
29
|
+
borderColor: '#666666',
|
|
30
|
+
borderStyle: 'solid',
|
|
31
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
32
|
+
borderRadius: 10
|
|
33
|
+
}
|
|
34
|
+
});
|
|
10
35
|
const _WebView = forwardRef((props, ref) => {
|
|
11
|
-
const { src
|
|
36
|
+
const { src, bindmessage, bindload, binderror } = props;
|
|
37
|
+
const mpx = global.__mpx;
|
|
38
|
+
const errorText = {
|
|
39
|
+
'zh-CN': {
|
|
40
|
+
text: '网络不可用,请检查网络设置',
|
|
41
|
+
button: '重新加载'
|
|
42
|
+
},
|
|
43
|
+
'en-US': {
|
|
44
|
+
text: 'The network is not available. Please check the network settings',
|
|
45
|
+
button: 'Reload'
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const currentErrorText = errorText[mpx.i18n.locale || 'zh-CN'];
|
|
12
49
|
if (props.style) {
|
|
13
50
|
warn('The web-view component does not support the style prop.');
|
|
14
51
|
}
|
|
15
52
|
const pageId = useContext(RouteContext);
|
|
53
|
+
const [pageLoadErr, setPageLoadErr] = useState(false);
|
|
16
54
|
const currentPage = useMemo(() => getCurrentPage(pageId), [pageId]);
|
|
55
|
+
const webViewRef = useRef(null);
|
|
17
56
|
const defaultWebViewStyle = {
|
|
18
57
|
position: 'absolute',
|
|
19
58
|
left: 0,
|
|
@@ -21,31 +60,58 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
21
60
|
top: 0,
|
|
22
61
|
bottom: 0
|
|
23
62
|
};
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
63
|
+
const canGoBack = useRef(false);
|
|
64
|
+
const onAndroidBackPress = useCallback(() => {
|
|
65
|
+
if (canGoBack.current) {
|
|
66
|
+
webViewRef.current?.goBack();
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}, [canGoBack]);
|
|
71
|
+
const beforeRemoveHandle = useCallback((e) => {
|
|
72
|
+
if (canGoBack.current) {
|
|
73
|
+
webViewRef.current?.goBack();
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
}
|
|
76
|
+
}, [canGoBack]);
|
|
77
|
+
const navigation = getFocusedNavigation();
|
|
78
|
+
// ios 16以下版本 的hash会被转义,因此对于iOS环境下在页面load之后再注入hash部分的逻辑
|
|
79
|
+
let [baseUrl, hashParams = ''] = src.split('#');
|
|
80
|
+
if (hashParams)
|
|
81
|
+
hashParams = '#' + hashParams;
|
|
82
|
+
const source = useMemo(() => {
|
|
83
|
+
if (Platform.OS === 'ios') {
|
|
84
|
+
return { uri: baseUrl };
|
|
85
|
+
}
|
|
86
|
+
return { uri: baseUrl + hashParams };
|
|
87
|
+
}, [baseUrl, hashParams]);
|
|
88
|
+
const hashInjectedJavascript = useMemo(() => {
|
|
89
|
+
if (Platform.OS === 'ios' && hashParams) {
|
|
90
|
+
return `(function() {
|
|
91
|
+
try {
|
|
92
|
+
location.hash = '${hashParams}';
|
|
93
|
+
} catch(e) {
|
|
41
94
|
}
|
|
42
|
-
|
|
95
|
+
})()`;
|
|
96
|
+
}
|
|
97
|
+
return '';
|
|
98
|
+
}, [hashParams]);
|
|
99
|
+
navigation?.addListener('beforeRemove', beforeRemoveHandle);
|
|
43
100
|
useEffect(() => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
101
|
+
if (__mpx_mode__ === 'android') {
|
|
102
|
+
BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress);
|
|
103
|
+
return () => {
|
|
104
|
+
BackHandler.removeEventListener('hardwareBackPress', onAndroidBackPress);
|
|
105
|
+
navigation?.removeListener('beforeRemove', beforeRemoveHandle);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
48
108
|
}, []);
|
|
109
|
+
useNodesRef(props, ref, webViewRef, {
|
|
110
|
+
style: defaultWebViewStyle
|
|
111
|
+
});
|
|
112
|
+
if (!src) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
49
115
|
const _load = function (res) {
|
|
50
116
|
const result = {
|
|
51
117
|
type: 'load',
|
|
@@ -54,9 +120,10 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
54
120
|
src: res.nativeEvent?.url
|
|
55
121
|
}
|
|
56
122
|
};
|
|
57
|
-
bindload(result);
|
|
123
|
+
bindload?.(result);
|
|
58
124
|
};
|
|
59
125
|
const _error = function (res) {
|
|
126
|
+
setPageLoadErr(true);
|
|
60
127
|
const result = {
|
|
61
128
|
type: 'error',
|
|
62
129
|
timeStamp: res.timeStamp,
|
|
@@ -64,13 +131,55 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
64
131
|
src: ''
|
|
65
132
|
}
|
|
66
133
|
};
|
|
67
|
-
binderror(result);
|
|
134
|
+
binderror && binderror(result);
|
|
135
|
+
};
|
|
136
|
+
const _reload = function () {
|
|
137
|
+
setPageLoadErr(false);
|
|
138
|
+
};
|
|
139
|
+
const injectedJavaScript = `
|
|
140
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
141
|
+
var _documentTitle = document.title;
|
|
142
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
143
|
+
type: 'setTitle',
|
|
144
|
+
payload: {
|
|
145
|
+
_documentTitle: _documentTitle
|
|
146
|
+
}
|
|
147
|
+
}))
|
|
148
|
+
Object.defineProperty(document, 'title', {
|
|
149
|
+
set (val) {
|
|
150
|
+
_documentTitle = val
|
|
151
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
152
|
+
type: 'setTitle',
|
|
153
|
+
payload: {
|
|
154
|
+
_documentTitle: _documentTitle
|
|
155
|
+
}
|
|
156
|
+
}))
|
|
157
|
+
},
|
|
158
|
+
get () {
|
|
159
|
+
return _documentTitle
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
${hashInjectedJavascript}
|
|
163
|
+
}
|
|
164
|
+
true;
|
|
165
|
+
`;
|
|
166
|
+
const sendMessage = function (params) {
|
|
167
|
+
return `
|
|
168
|
+
window.mpxWebviewMessageCallback(${params})
|
|
169
|
+
true;
|
|
170
|
+
`;
|
|
68
171
|
};
|
|
69
172
|
const _changeUrl = function (navState) {
|
|
70
|
-
if (
|
|
173
|
+
if (navState.navigationType) { // navigationType这个事件在页面开始加载时和页面加载完成时都会被触发所以判断这个避免其他无效触发执行该逻辑
|
|
174
|
+
canGoBack.current = navState.canGoBack;
|
|
71
175
|
currentPage.__webViewUrl = navState.url;
|
|
72
176
|
}
|
|
73
177
|
};
|
|
178
|
+
const _onLoadProgress = function (event) {
|
|
179
|
+
if (__mpx_mode__ === 'android') {
|
|
180
|
+
canGoBack.current = event.nativeEvent.canGoBack;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
74
183
|
const _message = function (res) {
|
|
75
184
|
let data = {};
|
|
76
185
|
let asyncCallback;
|
|
@@ -81,47 +190,97 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
81
190
|
data = JSON.parse(nativeEventData);
|
|
82
191
|
}
|
|
83
192
|
}
|
|
84
|
-
catch (e) {
|
|
85
|
-
|
|
86
|
-
}
|
|
193
|
+
catch (e) { }
|
|
194
|
+
const args = data.args;
|
|
87
195
|
const postData = data.payload || {};
|
|
88
|
-
|
|
196
|
+
const params = Array.isArray(args) ? args : [postData];
|
|
197
|
+
const type = data.type;
|
|
198
|
+
switch (type) {
|
|
199
|
+
case 'setTitle':
|
|
200
|
+
{ // case下不允许直接声明,包个块解决该问题
|
|
201
|
+
const title = postData._documentTitle;
|
|
202
|
+
if (title) {
|
|
203
|
+
navigation && navigation.setOptions({ title });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
break;
|
|
89
207
|
case 'postMessage':
|
|
90
|
-
|
|
208
|
+
bindmessage && bindmessage(getCustomEvent('messsage', {}, {
|
|
209
|
+
detail: {
|
|
210
|
+
data: params[0]?.data
|
|
211
|
+
}
|
|
212
|
+
}));
|
|
91
213
|
asyncCallback = Promise.resolve({
|
|
92
214
|
errMsg: 'invokeWebappApi:ok'
|
|
93
215
|
});
|
|
94
216
|
break;
|
|
95
217
|
case 'navigateTo':
|
|
96
|
-
asyncCallback = navObj.navigateTo(
|
|
218
|
+
asyncCallback = navObj.navigateTo(...params);
|
|
97
219
|
break;
|
|
98
220
|
case 'navigateBack':
|
|
99
|
-
asyncCallback = navObj.navigateBack(
|
|
221
|
+
asyncCallback = navObj.navigateBack(...params);
|
|
100
222
|
break;
|
|
101
223
|
case 'redirectTo':
|
|
102
|
-
asyncCallback = navObj.redirectTo(
|
|
224
|
+
asyncCallback = navObj.redirectTo(...params);
|
|
103
225
|
break;
|
|
104
226
|
case 'switchTab':
|
|
105
|
-
asyncCallback = navObj.switchTab(
|
|
227
|
+
asyncCallback = navObj.switchTab(...params);
|
|
106
228
|
break;
|
|
107
229
|
case 'reLaunch':
|
|
108
|
-
asyncCallback = navObj.reLaunch(
|
|
230
|
+
asyncCallback = navObj.reLaunch(...params);
|
|
231
|
+
break;
|
|
232
|
+
default:
|
|
233
|
+
if (type) {
|
|
234
|
+
const implement = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations[type];
|
|
235
|
+
if (isFunction(implement)) {
|
|
236
|
+
asyncCallback = Promise.resolve(implement(...params));
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
/* eslint-disable prefer-promise-reject-errors */
|
|
240
|
+
asyncCallback = Promise.reject({
|
|
241
|
+
errMsg: `未在apiImplementations中配置${type}方法`
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
109
245
|
break;
|
|
110
246
|
}
|
|
111
247
|
asyncCallback && asyncCallback.then((res) => {
|
|
112
248
|
if (webViewRef.current?.postMessage) {
|
|
113
|
-
const
|
|
114
|
-
type
|
|
249
|
+
const result = JSON.stringify({
|
|
250
|
+
type,
|
|
115
251
|
callbackId: data.callbackId,
|
|
116
252
|
result: res
|
|
117
253
|
});
|
|
118
|
-
webViewRef.current.
|
|
254
|
+
webViewRef.current.injectJavaScript(sendMessage(result));
|
|
255
|
+
}
|
|
256
|
+
}).catch((error) => {
|
|
257
|
+
if (webViewRef.current?.postMessage) {
|
|
258
|
+
const result = JSON.stringify({
|
|
259
|
+
type,
|
|
260
|
+
callbackId: data.callbackId,
|
|
261
|
+
error
|
|
262
|
+
});
|
|
263
|
+
webViewRef.current.injectJavaScript(sendMessage(result));
|
|
119
264
|
}
|
|
120
265
|
});
|
|
121
266
|
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
267
|
+
const events = {};
|
|
268
|
+
if (bindload) {
|
|
269
|
+
extendObject(events, {
|
|
270
|
+
onLoad: _load
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
extendObject(events, {
|
|
274
|
+
onError: _error
|
|
275
|
+
});
|
|
276
|
+
return (<Portal key={pageLoadErr ? 'error' : 'webview'}>
|
|
277
|
+
{pageLoadErr
|
|
278
|
+
? (<View style={[styles.loadErrorContext, defaultWebViewStyle]}>
|
|
279
|
+
<View style={styles.loadErrorText}><Text style={{ fontSize: 14, color: '#999999' }}>{currentErrorText.text}</Text></View>
|
|
280
|
+
<View style={styles.loadErrorButton} onTouchEnd={_reload}><Text style={{ fontSize: 12, color: '#666666' }}>{currentErrorText.button}</Text></View>
|
|
281
|
+
</View>)
|
|
282
|
+
: (<WebView style={defaultWebViewStyle} source={source} ref={webViewRef} javaScriptEnabled={true} onNavigationStateChange={_changeUrl} onMessage={_message} injectedJavaScript={injectedJavaScript} onLoadProgress={_onLoadProgress} allowsBackForwardNavigationGestures={true} {...events}></WebView>)}
|
|
283
|
+
</Portal>);
|
|
125
284
|
});
|
|
126
285
|
_WebView.displayName = 'MpxWebview';
|
|
127
286
|
export default _WebView;
|
|
@@ -30,6 +30,9 @@ export const createFaces = (itemHeight, visibleCount) => {
|
|
|
30
30
|
for (let i = 0; i < index; i++) {
|
|
31
31
|
offset += freeSpaces[i];
|
|
32
32
|
}
|
|
33
|
+
if (index === 0) {
|
|
34
|
+
offset *= 0.6;
|
|
35
|
+
}
|
|
33
36
|
return offset;
|
|
34
37
|
});
|
|
35
38
|
return [screenHeights, offsets];
|
|
@@ -37,15 +40,16 @@ export const createFaces = (itemHeight, visibleCount) => {
|
|
|
37
40
|
const getOpacity = (index) => {
|
|
38
41
|
const map = {
|
|
39
42
|
0: 0,
|
|
40
|
-
1: 0.
|
|
41
|
-
2: 0.35
|
|
42
|
-
3: 0.45,
|
|
43
|
-
4: 0.5
|
|
43
|
+
1: 0.8,
|
|
44
|
+
2: 0.9 // 0.35
|
|
45
|
+
// 3: 0.45, // 0.45
|
|
46
|
+
// 4: 0.5 // 0.5
|
|
44
47
|
};
|
|
45
|
-
return map[index] ?? Math.min(1, map[
|
|
48
|
+
return map[index] ?? Math.min(1, map[2] + index * 0.05);
|
|
46
49
|
};
|
|
47
50
|
const degrees = getDegreesRelativeCenter();
|
|
48
51
|
const [screenHeight, offsets] = getScreenHeightsAndOffsets(degrees);
|
|
52
|
+
const scales = [0.973, 0.9, 0.8];
|
|
49
53
|
return [
|
|
50
54
|
// top items
|
|
51
55
|
...degrees
|
|
@@ -55,12 +59,13 @@ export const createFaces = (itemHeight, visibleCount) => {
|
|
|
55
59
|
deg: degree,
|
|
56
60
|
opacity: getOpacity(degrees.length - 1 - index),
|
|
57
61
|
offsetY: -1 * offsets[index],
|
|
62
|
+
scale: scales[index],
|
|
58
63
|
screenHeight: screenHeight[index]
|
|
59
64
|
};
|
|
60
65
|
})
|
|
61
66
|
.reverse(),
|
|
62
67
|
// center item
|
|
63
|
-
{ index: 0, deg: 0, opacity: 1, offsetY: 0, screenHeight: itemHeight },
|
|
68
|
+
{ index: 0, deg: 0, opacity: 1, offsetY: 0, scale: 1, screenHeight: itemHeight },
|
|
64
69
|
// bottom items
|
|
65
70
|
...degrees.map((degree, index) => {
|
|
66
71
|
return {
|
|
@@ -68,6 +73,7 @@ export const createFaces = (itemHeight, visibleCount) => {
|
|
|
68
73
|
deg: -1 * degree,
|
|
69
74
|
opacity: getOpacity(degrees.length - 1 - index),
|
|
70
75
|
offsetY: offsets[index],
|
|
76
|
+
scale: scales[index],
|
|
71
77
|
screenHeight: screenHeight[index]
|
|
72
78
|
};
|
|
73
79
|
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const PickerViewColumnAnimationContext = createContext(undefined);
|
|
3
|
+
export const usePickerViewColumnAnimationContext = () => {
|
|
4
|
+
const value = useContext(PickerViewColumnAnimationContext);
|
|
5
|
+
if (value === undefined) {
|
|
6
|
+
throw new Error('usePickerViewColumnAnimationContext must be called from within PickerViewColumnAnimationContext.Provider!');
|
|
7
|
+
}
|
|
8
|
+
return value;
|
|
9
|
+
};
|