@mpxjs/webpack-plugin 2.9.65 → 2.9.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/dependencies/RecordGlobalComponentsDependency.js +11 -12
- package/lib/dependencies/RecordRuntimeInfoDependency.js +1 -1
- package/lib/index.js +28 -8
- package/lib/json-compiler/index.js +2 -11
- package/lib/loader.js +24 -45
- package/lib/native-loader.js +49 -64
- package/lib/platform/json/wx/index.js +3 -10
- package/lib/platform/style/wx/index.js +32 -56
- package/lib/react/index.js +4 -3
- package/lib/react/processJSON.js +5 -13
- package/lib/react/processMainScript.js +7 -3
- package/lib/react/processScript.js +3 -4
- package/lib/react/processTemplate.js +6 -4
- package/lib/resolver/AddModePlugin.js +17 -4
- package/lib/runtime/components/react/context.ts +8 -0
- package/lib/runtime/components/react/dist/context.js +1 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +30 -17
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-form.jsx +33 -24
- package/lib/runtime/components/react/dist/mpx-icon.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-image/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-input.jsx +44 -38
- package/lib/runtime/components/react/dist/mpx-label.jsx +10 -7
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -17
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +378 -294
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +30 -17
- package/lib/runtime/components/react/dist/mpx-radio.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-root-portal.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +58 -30
- package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +77 -77
- package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-switch.jsx +8 -1
- package/lib/runtime/components/react/dist/mpx-text.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-view.jsx +31 -12
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +2 -2
- package/lib/runtime/components/react/dist/useAnimationHooks.js +303 -0
- package/lib/runtime/components/react/dist/utils.jsx +13 -3
- package/lib/runtime/components/react/getInnerListeners.ts +1 -0
- package/lib/runtime/components/react/mpx-button.tsx +1 -1
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +52 -29
- package/lib/runtime/components/react/mpx-checkbox.tsx +1 -1
- package/lib/runtime/components/react/mpx-form.tsx +42 -34
- package/lib/runtime/components/react/mpx-icon.tsx +1 -1
- package/lib/runtime/components/react/mpx-image/index.tsx +2 -3
- package/lib/runtime/components/react/mpx-input.tsx +68 -66
- package/lib/runtime/components/react/mpx-label.tsx +11 -8
- package/lib/runtime/components/react/mpx-movable-area.tsx +11 -19
- package/lib/runtime/components/react/mpx-movable-view.tsx +456 -334
- package/lib/runtime/components/react/mpx-navigator.tsx +1 -1
- package/lib/runtime/components/react/mpx-radio-group.tsx +55 -29
- package/lib/runtime/components/react/mpx-radio.tsx +1 -1
- package/lib/runtime/components/react/mpx-root-portal.tsx +1 -1
- package/lib/runtime/components/react/mpx-scroll-view.tsx +92 -37
- package/lib/runtime/components/react/mpx-swiper/carouse.tsx +77 -76
- package/lib/runtime/components/react/mpx-swiper/index.tsx +2 -1
- package/lib/runtime/components/react/mpx-swiper-item.tsx +1 -1
- package/lib/runtime/components/react/mpx-switch.tsx +10 -2
- package/lib/runtime/components/react/mpx-text.tsx +1 -1
- package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
- package/lib/runtime/components/react/mpx-view.tsx +40 -20
- package/lib/runtime/components/react/mpx-web-view.tsx +2 -2
- package/lib/runtime/components/react/types/common.ts +8 -2
- package/lib/runtime/components/react/useAnimationHooks.ts +332 -0
- package/lib/runtime/components/react/useNodesRef.ts +1 -0
- package/lib/runtime/components/react/utils.tsx +23 -6
- package/lib/runtime/optionProcessorReact.js +0 -15
- package/lib/runtime/swanHelper.wxs +1 -1
- package/lib/style-compiler/index.js +1 -1
- package/lib/style-compiler/plugins/scope-id.js +1 -0
- package/lib/template-compiler/compiler.js +68 -33
- package/lib/template-compiler/index.js +4 -4
- package/lib/utils/pre-process-json.js +113 -0
- package/lib/web/index.js +5 -4
- package/lib/web/processJSON.js +5 -13
- package/lib/web/processTemplate.js +2 -2
- package/package.json +5 -4
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import { View, StyleSheet, Image } from 'react-native';
|
|
8
8
|
import { useRef, useState, useEffect, forwardRef } from 'react';
|
|
9
9
|
import useInnerProps from './getInnerListeners';
|
|
10
|
+
import Animated from 'react-native-reanimated';
|
|
11
|
+
import useAnimationHooks from './useAnimationHooks';
|
|
10
12
|
import useNodesRef from './useNodesRef';
|
|
11
13
|
import { parseUrl, PERCENT_REGEX, splitStyle, splitProps, useTransformStyle, wrapChildren, useLayout } from './utils';
|
|
12
14
|
import LinearGradient from 'react-native-linear-gradient';
|
|
@@ -527,7 +529,7 @@ function wrapWithChildren(props, { hasVarDec, enableBackground, textStyle, backg
|
|
|
527
529
|
}
|
|
528
530
|
const _View = forwardRef((viewProps, ref) => {
|
|
529
531
|
const { textProps, innerProps: props = {} } = splitProps(viewProps);
|
|
530
|
-
let { style = {}, 'hover-style': hoverStyle, 'hover-start-time': hoverStartTime = 50, 'hover-stay-time': hoverStayTime = 400, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'enable-background': enableBackground, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
532
|
+
let { 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-animation': enableAnimation, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, animation } = props;
|
|
531
533
|
const [isHover, setIsHover] = useState(false);
|
|
532
534
|
// 默认样式
|
|
533
535
|
const defaultStyle = {
|
|
@@ -592,9 +594,10 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
592
594
|
setStayTimer();
|
|
593
595
|
}
|
|
594
596
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
597
|
+
const viewStyle = Object.assign({}, innerStyle, layoutStyle);
|
|
595
598
|
const innerProps = useInnerProps(props, {
|
|
596
599
|
ref: nodeRef,
|
|
597
|
-
style:
|
|
600
|
+
style: viewStyle,
|
|
598
601
|
...layoutProps,
|
|
599
602
|
...(hoverStyle && {
|
|
600
603
|
bindtouchstart: onTouchStart,
|
|
@@ -608,16 +611,32 @@ const _View = forwardRef((viewProps, ref) => {
|
|
|
608
611
|
], {
|
|
609
612
|
layoutRef
|
|
610
613
|
});
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
614
|
+
enableAnimation = enableAnimation || !!animation;
|
|
615
|
+
const enableAnimationRef = useRef(enableAnimation);
|
|
616
|
+
if (enableAnimationRef.current !== enableAnimation) {
|
|
617
|
+
throw new Error('[Mpx runtime error]: animation use should be stable in the component lifecycle, or you can set [enable-animation] with true.');
|
|
618
|
+
}
|
|
619
|
+
const finalStyle = enableAnimation
|
|
620
|
+
? useAnimationHooks({
|
|
621
|
+
animation,
|
|
622
|
+
style: viewStyle
|
|
623
|
+
})
|
|
624
|
+
: viewStyle;
|
|
625
|
+
const childNode = wrapWithChildren(props, {
|
|
626
|
+
hasVarDec,
|
|
627
|
+
enableBackground: enableBackgroundRef.current,
|
|
628
|
+
textStyle,
|
|
629
|
+
backgroundStyle,
|
|
630
|
+
varContext: varContextRef.current,
|
|
631
|
+
textProps
|
|
632
|
+
});
|
|
633
|
+
return animation?.actions?.length
|
|
634
|
+
? (<Animated.View {...innerProps} style={finalStyle}>
|
|
635
|
+
{childNode}
|
|
636
|
+
</Animated.View>)
|
|
637
|
+
: (<View {...innerProps}>
|
|
638
|
+
{childNode}
|
|
620
639
|
</View>);
|
|
621
640
|
});
|
|
622
|
-
_View.displayName = '
|
|
641
|
+
_View.displayName = 'MpxView';
|
|
623
642
|
export default _View;
|
|
@@ -6,7 +6,7 @@ import { promisify, redirectTo, navigateTo, navigateBack, reLaunch, switchTab }
|
|
|
6
6
|
import { WebView } from 'react-native-webview';
|
|
7
7
|
import useNodesRef from './useNodesRef';
|
|
8
8
|
const _WebView = forwardRef((props, ref) => {
|
|
9
|
-
const { src, bindmessage = noop, bindload = noop, binderror = noop } = props;
|
|
9
|
+
const { src = '', bindmessage = noop, bindload = noop, binderror = noop } = props;
|
|
10
10
|
if (props.style) {
|
|
11
11
|
warn('The web-view component does not support the style prop.');
|
|
12
12
|
}
|
|
@@ -109,5 +109,5 @@ const _WebView = forwardRef((props, ref) => {
|
|
|
109
109
|
<WebView style={defaultWebViewStyle} source={{ uri: src }} ref={webViewRef} onLoad={_load} onError={_error} onMessage={_message} javaScriptEnabled={true}></WebView>
|
|
110
110
|
</Portal>);
|
|
111
111
|
});
|
|
112
|
-
_WebView.displayName = '
|
|
112
|
+
_WebView.displayName = 'MpxWebview';
|
|
113
113
|
export default _WebView;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
2
|
+
import { Easing, useSharedValue, withTiming, useAnimatedStyle, withSequence, withDelay, makeMutable, cancelAnimation } from 'react-native-reanimated';
|
|
3
|
+
// 微信 timingFunction 和 RN Easing 对应关系
|
|
4
|
+
const EasingKey = {
|
|
5
|
+
linear: Easing.linear,
|
|
6
|
+
ease: Easing.ease,
|
|
7
|
+
'ease-in': Easing.in(Easing.ease),
|
|
8
|
+
'ease-in-out': Easing.inOut(Easing.ease),
|
|
9
|
+
'ease-out': Easing.out(Easing.ease)
|
|
10
|
+
// 'step-start': '',
|
|
11
|
+
// 'step-end': ''
|
|
12
|
+
};
|
|
13
|
+
const TransformInitial = {
|
|
14
|
+
// matrix: 0,
|
|
15
|
+
// matrix3d: 0,
|
|
16
|
+
rotate: '0deg',
|
|
17
|
+
rotateX: '0deg',
|
|
18
|
+
rotateY: '0deg',
|
|
19
|
+
rotateZ: '0deg',
|
|
20
|
+
// rotate3d:[0,0,0]
|
|
21
|
+
scale: 1,
|
|
22
|
+
// scale3d: [1, 1, 1],
|
|
23
|
+
scaleX: 1,
|
|
24
|
+
scaleY: 1,
|
|
25
|
+
// scaleZ: 1,
|
|
26
|
+
skew: 0,
|
|
27
|
+
skewX: '0deg',
|
|
28
|
+
skewY: '0deg',
|
|
29
|
+
translate: 0,
|
|
30
|
+
// translate3d: 0,
|
|
31
|
+
translateX: 0,
|
|
32
|
+
translateY: 0
|
|
33
|
+
// translateZ: 0,
|
|
34
|
+
};
|
|
35
|
+
// 动画默认初始值
|
|
36
|
+
const InitialValue = Object.assign({
|
|
37
|
+
opacity: 1,
|
|
38
|
+
backgroundColor: 'transparent',
|
|
39
|
+
width: 0,
|
|
40
|
+
height: 0,
|
|
41
|
+
top: 0,
|
|
42
|
+
right: 0,
|
|
43
|
+
bottom: 0,
|
|
44
|
+
left: 0,
|
|
45
|
+
transformOrigin: ['50%', '50%', 0]
|
|
46
|
+
}, TransformInitial);
|
|
47
|
+
const TransformOrigin = 'transformOrigin';
|
|
48
|
+
// transform
|
|
49
|
+
const isTransform = (key) => Object.keys(TransformInitial).includes(key);
|
|
50
|
+
// parse string transform, eg: transform: 'rotateX(45deg) rotateZ(0.785398rad)'
|
|
51
|
+
const parseTransform = (transformStr) => {
|
|
52
|
+
const values = transformStr.trim().split(/\s+/);
|
|
53
|
+
const transform = [];
|
|
54
|
+
values.forEach(item => {
|
|
55
|
+
const match = item.match(/([/\w]+)\(([^)]+)\)/);
|
|
56
|
+
if (match && match.length >= 3) {
|
|
57
|
+
let key = match[1];
|
|
58
|
+
const val = match[2];
|
|
59
|
+
switch (key) {
|
|
60
|
+
case 'translateX':
|
|
61
|
+
case 'translateY':
|
|
62
|
+
case 'scaleX':
|
|
63
|
+
case 'scaleY':
|
|
64
|
+
case 'rotateX':
|
|
65
|
+
case 'rotateY':
|
|
66
|
+
case 'rotateZ':
|
|
67
|
+
case 'rotate':
|
|
68
|
+
case 'skewX':
|
|
69
|
+
case 'skewY':
|
|
70
|
+
case 'perspective':
|
|
71
|
+
// 单个值处理
|
|
72
|
+
transform.push({ [key]: global.__formatValue(val) });
|
|
73
|
+
break;
|
|
74
|
+
case 'matrix':
|
|
75
|
+
case 'matrix3d':
|
|
76
|
+
transform.push({ [key]: val.split(',').map(val => +val) });
|
|
77
|
+
break;
|
|
78
|
+
case 'translate':
|
|
79
|
+
case 'scale':
|
|
80
|
+
case 'skew':
|
|
81
|
+
case 'rotate3d': // x y z angle
|
|
82
|
+
case 'translate3d': // x y 支持 z不支持
|
|
83
|
+
case 'scale3d': // x y 支持 z不支持
|
|
84
|
+
{
|
|
85
|
+
// 2 个以上的值处理
|
|
86
|
+
key = key.replace('3d', '');
|
|
87
|
+
const vals = val.split(',', key === 'rotate' ? 4 : 3);
|
|
88
|
+
// scale(.5) === scaleX(.5) scaleY(.5) 这里处理一下
|
|
89
|
+
if (vals.length === 1 && key === 'scale') {
|
|
90
|
+
vals.push(vals[0]);
|
|
91
|
+
}
|
|
92
|
+
const xyz = ['X', 'Y', 'Z'];
|
|
93
|
+
transform.push(...vals.map((v, index) => {
|
|
94
|
+
return { [`${key}${xyz[index] || ''}`]: global.__formatValue(v.trim()) };
|
|
95
|
+
}));
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
return transform;
|
|
102
|
+
};
|
|
103
|
+
// format style
|
|
104
|
+
const formatStyle = (style) => {
|
|
105
|
+
if (!style.transform || Array.isArray(style.transform))
|
|
106
|
+
return style;
|
|
107
|
+
return Object.assign({}, style, {
|
|
108
|
+
transform: parseTransform(style.transform)
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
export default function useAnimationHooks(props) {
|
|
112
|
+
const { style = {}, animation } = props;
|
|
113
|
+
const originalStyle = formatStyle(style);
|
|
114
|
+
// id 标识
|
|
115
|
+
const id = animation?.id || -1;
|
|
116
|
+
// 有动画样式的 style key
|
|
117
|
+
const animatedStyleKeys = useSharedValue([]);
|
|
118
|
+
// 记录动画key的style样式值 没有的话设置为false
|
|
119
|
+
const animatedKeys = useRef({});
|
|
120
|
+
// const animatedKeys = useRef({} as {[propName: keyof ExtendedViewStyle]: boolean|number|string})
|
|
121
|
+
// ** 全量 style prop sharedValue
|
|
122
|
+
// 不能做增量的原因:
|
|
123
|
+
// 1 尝试用 useRef,但 useAnimatedStyle 访问后的 ref 不能在增加新的值,被冻结
|
|
124
|
+
// 2 尝试用 useSharedValue,因为实际触发的 style prop 需要是 sharedValue 才能驱动动画,若外层 shareValMap 也是 sharedValue,动画无法驱动。
|
|
125
|
+
const shareValMap = useMemo(() => {
|
|
126
|
+
return Object.keys(InitialValue).reduce((valMap, key) => {
|
|
127
|
+
const defaultVal = getInitialVal(key, isTransform(key));
|
|
128
|
+
valMap[key] = makeMutable(defaultVal);
|
|
129
|
+
return valMap;
|
|
130
|
+
}, {});
|
|
131
|
+
}, []);
|
|
132
|
+
// ** 获取动画样式prop & 驱动动画
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
if (id === -1)
|
|
135
|
+
return;
|
|
136
|
+
// 更新动画样式 key map
|
|
137
|
+
animatedKeys.current = getAnimatedStyleKeys();
|
|
138
|
+
const keys = Object.keys(animatedKeys.current);
|
|
139
|
+
animatedStyleKeys.value = formatAnimatedKeys([TransformOrigin, ...keys]);
|
|
140
|
+
// 驱动动画
|
|
141
|
+
createAnimation(keys);
|
|
142
|
+
}, [id]);
|
|
143
|
+
// 同步style更新
|
|
144
|
+
// useEffect(() => {
|
|
145
|
+
// Object.keys(animatedKeys.current).forEach(key => {
|
|
146
|
+
// const originVal = getOriginalStyleVal(key, isTransform(key))
|
|
147
|
+
// if (originVal && animatedKeys.current[key] !== originVal) {
|
|
148
|
+
// animatedKeys.current[key] = originVal
|
|
149
|
+
// shareValMap[key].value = originVal
|
|
150
|
+
// }
|
|
151
|
+
// })
|
|
152
|
+
// }, [style])
|
|
153
|
+
// ** 清空动画
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
return () => {
|
|
156
|
+
Object.values(shareValMap).forEach((value) => {
|
|
157
|
+
cancelAnimation(value);
|
|
158
|
+
});
|
|
159
|
+
};
|
|
160
|
+
}, []);
|
|
161
|
+
// 根据 animation action 创建&驱动动画 key => wi
|
|
162
|
+
function createAnimation(animatedKeys = []) {
|
|
163
|
+
const actions = animation?.actions || [];
|
|
164
|
+
const sequence = {};
|
|
165
|
+
const lastValueMap = {};
|
|
166
|
+
actions.forEach(({ animatedOption, rules, transform }, index) => {
|
|
167
|
+
const { delay, duration, timingFunction, transformOrigin } = animatedOption;
|
|
168
|
+
const easing = EasingKey[timingFunction] || Easing.inOut(Easing.quad);
|
|
169
|
+
let needSetCallback = true;
|
|
170
|
+
const setTransformOrigin = (finished) => {
|
|
171
|
+
'worklet';
|
|
172
|
+
// 动画结束后设置下一次transformOrigin
|
|
173
|
+
if (finished) {
|
|
174
|
+
if (index < actions.length - 1) {
|
|
175
|
+
const transformOrigin = actions[index + 1].animatedOption?.transformOrigin;
|
|
176
|
+
transformOrigin && (shareValMap[TransformOrigin].value = transformOrigin);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
if (index === 0) {
|
|
181
|
+
// 设置当次中心
|
|
182
|
+
shareValMap[TransformOrigin].value = transformOrigin;
|
|
183
|
+
}
|
|
184
|
+
// 添加每个key的多次step动画
|
|
185
|
+
animatedKeys.forEach(key => {
|
|
186
|
+
let toVal = (rules.get(key) || transform.get(key));
|
|
187
|
+
// key不存在,第一轮取shareValMap[key]value,非第一轮取上一轮的
|
|
188
|
+
if (toVal === undefined) {
|
|
189
|
+
toVal = index > 0 ? lastValueMap[key] : shareValMap[key].value;
|
|
190
|
+
}
|
|
191
|
+
const animation = getAnimation({ key, value: toVal }, { delay, duration, easing }, needSetCallback ? setTransformOrigin : undefined);
|
|
192
|
+
needSetCallback = false;
|
|
193
|
+
if (!sequence[key]) {
|
|
194
|
+
sequence[key] = [animation];
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
sequence[key].push(animation);
|
|
198
|
+
}
|
|
199
|
+
// 更新一下 lastValueMap
|
|
200
|
+
lastValueMap[key] = toVal;
|
|
201
|
+
});
|
|
202
|
+
// 赋值驱动动画
|
|
203
|
+
animatedKeys.forEach((key) => {
|
|
204
|
+
const animations = sequence[key];
|
|
205
|
+
shareValMap[key].value = withSequence(...animations);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
// 创建单个animation
|
|
210
|
+
function getAnimation({ key, value }, { delay, duration, easing }, callback) {
|
|
211
|
+
const animation = typeof callback === 'function'
|
|
212
|
+
? withTiming(value, { duration, easing }, callback)
|
|
213
|
+
: withTiming(value, { duration, easing });
|
|
214
|
+
return delay ? withDelay(delay, animation) : animation;
|
|
215
|
+
}
|
|
216
|
+
function getInitialVal(key, isTransform = false) {
|
|
217
|
+
if (isTransform && Array.isArray(originalStyle.transform)) {
|
|
218
|
+
let initialVal = InitialValue[key];
|
|
219
|
+
// 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
|
|
220
|
+
originalStyle.transform.forEach(item => {
|
|
221
|
+
if (item[key] !== undefined)
|
|
222
|
+
initialVal = item[key];
|
|
223
|
+
});
|
|
224
|
+
return initialVal;
|
|
225
|
+
}
|
|
226
|
+
return originalStyle[key] === undefined ? InitialValue[key] : originalStyle[key];
|
|
227
|
+
}
|
|
228
|
+
// 从 prop style 中获取样式初始值 没有为undefined
|
|
229
|
+
// function getOriginalStyleVal (key: keyof ExtendedViewStyle, isTransform = false) {
|
|
230
|
+
// if (isTransform && Array.isArray(originalStyle.transform)) {
|
|
231
|
+
// let initialVal = undefined // InitialValue[key]
|
|
232
|
+
// // 仅支持 { transform: [{rotateX: '45deg'}, {rotateZ: '0.785398rad'}] } 格式的初始样式
|
|
233
|
+
// originalStyle.transform.forEach(item => {
|
|
234
|
+
// if (item[key] !== undefined) initialVal = item[key]
|
|
235
|
+
// })
|
|
236
|
+
// return initialVal
|
|
237
|
+
// }
|
|
238
|
+
// return originalStyle[key] // === undefined ? InitialValue[key] : originalStyle[key]
|
|
239
|
+
// }
|
|
240
|
+
// 获取动画shareVal初始值(prop style or 默认值)
|
|
241
|
+
// function getInitialVal (key: keyof ExtendedViewStyle, isTransform = false) {
|
|
242
|
+
// const originalVal = getOriginalStyleVal(key, isTransform)
|
|
243
|
+
// return originalVal === undefined ? InitialValue[key] : originalStyle[key]
|
|
244
|
+
// }
|
|
245
|
+
// 循环 animation actions 获取所有有动画的 style prop name
|
|
246
|
+
function getAnimatedStyleKeys() {
|
|
247
|
+
return (animation?.actions || []).reduce((keyMap, action) => {
|
|
248
|
+
const { rules, transform } = action;
|
|
249
|
+
const ruleArr = [...rules.keys(), ...transform.keys()];
|
|
250
|
+
ruleArr.forEach(key => {
|
|
251
|
+
// const originalVal = getOriginalStyleVal(key, isTransform(key))
|
|
252
|
+
// if (!keyMap[key]) keyMap[key] = originalVal === undefined ? false : originalVal
|
|
253
|
+
if (!keyMap[key])
|
|
254
|
+
keyMap[key] = true;
|
|
255
|
+
});
|
|
256
|
+
return keyMap;
|
|
257
|
+
}, animatedKeys.current);
|
|
258
|
+
}
|
|
259
|
+
// animated key transform 格式化
|
|
260
|
+
function formatAnimatedKeys(keys = []) {
|
|
261
|
+
const animatedKeys = [];
|
|
262
|
+
const transforms = [];
|
|
263
|
+
keys.forEach(key => {
|
|
264
|
+
if (isTransform(key)) {
|
|
265
|
+
transforms.push(key);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
animatedKeys.push(key);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
if (transforms.length)
|
|
272
|
+
animatedKeys.push(transforms);
|
|
273
|
+
return animatedKeys;
|
|
274
|
+
}
|
|
275
|
+
// transform 数组转对象
|
|
276
|
+
function getTransformObj() {
|
|
277
|
+
'worklet';
|
|
278
|
+
const transforms = originalStyle.transform || [];
|
|
279
|
+
return transforms.reduce((transformObj, item) => {
|
|
280
|
+
return Object.assign(transformObj, item);
|
|
281
|
+
}, {});
|
|
282
|
+
}
|
|
283
|
+
// ** 生成动画样式
|
|
284
|
+
return useAnimatedStyle(() => {
|
|
285
|
+
// console.info(`useAnimatedStyle styles=`, originalStyle)
|
|
286
|
+
return animatedStyleKeys.value.reduce((styles, key) => {
|
|
287
|
+
// console.info('getAnimationStyles', key, shareValMap[key].value)
|
|
288
|
+
if (Array.isArray(key)) {
|
|
289
|
+
const transformStyle = getTransformObj();
|
|
290
|
+
key.forEach((transformKey) => {
|
|
291
|
+
transformStyle[transformKey] = shareValMap[transformKey].value;
|
|
292
|
+
});
|
|
293
|
+
styles.transform = Object.entries(transformStyle).map(([key, value]) => {
|
|
294
|
+
return { [key]: value };
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
styles[key] = shareValMap[key].value;
|
|
299
|
+
}
|
|
300
|
+
return styles;
|
|
301
|
+
}, Object.assign({}, originalStyle));
|
|
302
|
+
});
|
|
303
|
+
}
|
|
@@ -9,7 +9,7 @@ export const URL_REGEX = /^\s*url\(["']?(.*?)["']?\)\s*$/;
|
|
|
9
9
|
export const BACKGROUND_REGEX = /^background(Image|Size|Repeat|Position)$/;
|
|
10
10
|
export const TEXT_PROPS_REGEX = /ellipsizeMode|numberOfLines/;
|
|
11
11
|
export const DEFAULT_FONT_SIZE = 16;
|
|
12
|
-
export const
|
|
12
|
+
export const HIDDEN_STYLE = {
|
|
13
13
|
opacity: 0
|
|
14
14
|
};
|
|
15
15
|
const varDecRegExp = /^--.*/;
|
|
@@ -87,7 +87,8 @@ export const getRestProps = (transferProps = {}, originProps = {}, deletePropsKe
|
|
|
87
87
|
export function isText(ele) {
|
|
88
88
|
if (isValidElement(ele)) {
|
|
89
89
|
const displayName = ele.type?.displayName;
|
|
90
|
-
|
|
90
|
+
const isCustomText = ele.type?.isCustomText;
|
|
91
|
+
return displayName === 'MpxText' || displayName === 'Text' || !!isCustomText;
|
|
91
92
|
}
|
|
92
93
|
return false;
|
|
93
94
|
}
|
|
@@ -401,7 +402,7 @@ export function splitProps(props) {
|
|
|
401
402
|
export const useLayout = ({ props, hasSelfPercent, setWidth, setHeight, onLayout, nodeRef }) => {
|
|
402
403
|
const layoutRef = useRef({});
|
|
403
404
|
const hasLayoutRef = useRef(false);
|
|
404
|
-
const layoutStyle = !hasLayoutRef.current && hasSelfPercent ?
|
|
405
|
+
const layoutStyle = !hasLayoutRef.current && hasSelfPercent ? HIDDEN_STYLE : {};
|
|
405
406
|
const layoutProps = {};
|
|
406
407
|
const enableOffset = props['enable-offset'];
|
|
407
408
|
if (hasSelfPercent || onLayout || enableOffset) {
|
|
@@ -443,3 +444,12 @@ export function wrapChildren(props = {}, { hasVarDec, varContext, textStyle, tex
|
|
|
443
444
|
}
|
|
444
445
|
return children;
|
|
445
446
|
}
|
|
447
|
+
export function flatGesture(gestures = []) {
|
|
448
|
+
return (gestures && gestures.flatMap((gesture) => {
|
|
449
|
+
if (gesture && gesture.nodeRefs) {
|
|
450
|
+
return gesture.nodeRefs
|
|
451
|
+
.map((item) => item.getNodeInstance()?.instance?.gestureRef || {});
|
|
452
|
+
}
|
|
453
|
+
return gesture?.current ? [gesture] : [];
|
|
454
|
+
})) || [];
|
|
455
|
+
}
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ✔ bindchange
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
JSX,
|
|
6
|
+
useRef,
|
|
7
|
+
forwardRef,
|
|
8
|
+
ReactNode,
|
|
9
|
+
useContext,
|
|
10
|
+
useMemo,
|
|
11
|
+
useEffect
|
|
12
|
+
} from 'react'
|
|
13
|
+
import {
|
|
14
|
+
View,
|
|
15
|
+
NativeSyntheticEvent,
|
|
16
|
+
ViewStyle
|
|
17
|
+
} from 'react-native'
|
|
6
18
|
import { warn } from '@mpxjs/utils'
|
|
7
19
|
import { FormContext, FormFieldValue, CheckboxGroupContext, GroupValue } from './context'
|
|
8
20
|
import useInnerProps, { getCustomEvent } from './getInnerListeners'
|
|
@@ -26,14 +38,15 @@ const CheckboxGroup = forwardRef<
|
|
|
26
38
|
HandlerRef<View, CheckboxGroupProps>,
|
|
27
39
|
CheckboxGroupProps
|
|
28
40
|
>((props, ref): JSX.Element => {
|
|
41
|
+
const propsRef = useRef({} as CheckboxGroupProps)
|
|
42
|
+
propsRef.current = props
|
|
29
43
|
const {
|
|
30
44
|
style = {},
|
|
31
45
|
'enable-var': enableVar,
|
|
32
46
|
'external-var-context': externalVarContext,
|
|
33
47
|
'parent-font-size': parentFontSize,
|
|
34
48
|
'parent-width': parentWidth,
|
|
35
|
-
'parent-height': parentHeight
|
|
36
|
-
bindchange
|
|
49
|
+
'parent-height': parentHeight
|
|
37
50
|
} = props
|
|
38
51
|
|
|
39
52
|
const formContext = useContext(FormContext)
|
|
@@ -71,7 +84,7 @@ const CheckboxGroup = forwardRef<
|
|
|
71
84
|
|
|
72
85
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef })
|
|
73
86
|
|
|
74
|
-
const
|
|
87
|
+
const getValue = (): string[] => {
|
|
75
88
|
const arr: string[] = []
|
|
76
89
|
for (const key in groupValue) {
|
|
77
90
|
if (groupValue[key].checked) {
|
|
@@ -81,10 +94,6 @@ const CheckboxGroup = forwardRef<
|
|
|
81
94
|
return arr
|
|
82
95
|
}
|
|
83
96
|
|
|
84
|
-
const getValue = () => {
|
|
85
|
-
return getSelectionValue()
|
|
86
|
-
}
|
|
87
|
-
|
|
88
97
|
const resetValue = () => {
|
|
89
98
|
Object.keys(groupValue).forEach((key) => {
|
|
90
99
|
groupValue[key].checked = false
|
|
@@ -100,24 +109,13 @@ const CheckboxGroup = forwardRef<
|
|
|
100
109
|
}
|
|
101
110
|
}
|
|
102
111
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
evt,
|
|
111
|
-
{
|
|
112
|
-
layoutRef,
|
|
113
|
-
detail: {
|
|
114
|
-
value: getSelectionValue()
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
props
|
|
118
|
-
)
|
|
119
|
-
)
|
|
120
|
-
}
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
return () => {
|
|
114
|
+
if (formValuesMap && props.name) {
|
|
115
|
+
formValuesMap.delete(props.name)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, [])
|
|
121
119
|
|
|
122
120
|
const innerProps = useInnerProps(
|
|
123
121
|
props,
|
|
@@ -132,9 +130,34 @@ const CheckboxGroup = forwardRef<
|
|
|
132
130
|
}
|
|
133
131
|
)
|
|
134
132
|
|
|
133
|
+
const contextValue = useMemo(() => {
|
|
134
|
+
const notifyChange = (
|
|
135
|
+
evt: NativeSyntheticEvent<TouchEvent>
|
|
136
|
+
) => {
|
|
137
|
+
const { bindchange } = propsRef.current
|
|
138
|
+
bindchange &&
|
|
139
|
+
bindchange(
|
|
140
|
+
getCustomEvent(
|
|
141
|
+
'tap',
|
|
142
|
+
evt,
|
|
143
|
+
{
|
|
144
|
+
layoutRef,
|
|
145
|
+
detail: {
|
|
146
|
+
value: getValue()
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
propsRef.current
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
groupValue,
|
|
155
|
+
notifyChange
|
|
156
|
+
}
|
|
157
|
+
}, [])
|
|
135
158
|
return (
|
|
136
159
|
<View {...innerProps}>
|
|
137
|
-
<CheckboxGroupContext.Provider value={
|
|
160
|
+
<CheckboxGroupContext.Provider value={contextValue}>
|
|
138
161
|
{
|
|
139
162
|
wrapChildren(
|
|
140
163
|
props,
|
|
@@ -149,6 +172,6 @@ const CheckboxGroup = forwardRef<
|
|
|
149
172
|
)
|
|
150
173
|
})
|
|
151
174
|
|
|
152
|
-
CheckboxGroup.displayName = '
|
|
175
|
+
CheckboxGroup.displayName = 'MpxCheckboxGroup'
|
|
153
176
|
|
|
154
177
|
export default CheckboxGroup
|