@mpxjs/webpack-plugin 2.10.3-beta.17 → 2.10.3-beta.19
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/context.js +5 -1
- package/lib/runtime/components/react/dist/event.config.js +0 -1
- package/lib/runtime/components/react/dist/getInnerListeners.js +148 -149
- package/lib/runtime/components/react/dist/mpx-async-suspense.jsx +145 -0
- package/lib/runtime/components/react/dist/mpx-button.jsx +11 -7
- package/lib/runtime/components/react/dist/mpx-canvas/Image.js +2 -4
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +23 -21
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +9 -4
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +9 -5
- package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
- 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 +9 -4
- package/lib/runtime/components/react/dist/mpx-image.jsx +92 -41
- package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +14 -13
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +22 -7
- package/lib/runtime/components/react/dist/mpx-label.jsx +9 -5
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +10 -5
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +206 -80
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
- package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +178 -98
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
- package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +16 -15
- package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +95 -26
- package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +16 -16
- package/lib/runtime/components/react/dist/mpx-picker-view-column/pickerViewColumnItemLite.jsx +20 -0
- package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
- package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
- package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
- package/lib/runtime/components/react/dist/mpx-portal/index.jsx +5 -1
- package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +3 -5
- package/lib/runtime/components/react/dist/mpx-progress.jsx +163 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +11 -4
- package/lib/runtime/components/react/dist/mpx-radio.jsx +9 -5
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +12 -4
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +317 -89
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +7 -5
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
- package/lib/runtime/components/react/dist/mpx-slider.jsx +321 -0
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +117 -0
- package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +15 -14
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +245 -121
- package/lib/runtime/components/react/dist/mpx-switch.jsx +10 -7
- package/lib/runtime/components/react/dist/mpx-text.jsx +43 -13
- package/lib/runtime/components/react/dist/mpx-video.jsx +12 -7
- package/lib/runtime/components/react/dist/mpx-view.jsx +34 -18
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +40 -35
- package/lib/runtime/components/react/dist/useAnimationHooks.js +38 -91
- package/lib/runtime/components/react/dist/utils.jsx +215 -109
- package/lib/runtime/components/web/mpx-titlebar.vue +23 -18
- package/package.json +1 -1
- /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
|
@@ -23,6 +23,7 @@ import './CanvasGradient';
|
|
|
23
23
|
import { createImage as canvasCreateImage } from './Image';
|
|
24
24
|
import { createImageData as canvasCreateImageData } from './ImageData';
|
|
25
25
|
import { useConstructorsRegistry } from './constructorsRegistry';
|
|
26
|
+
import Portal from '../mpx-portal';
|
|
26
27
|
const stylesheet = StyleSheet.create({
|
|
27
28
|
container: { overflow: 'hidden', flex: 0 },
|
|
28
29
|
webview: {
|
|
@@ -41,7 +42,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
41
42
|
const { style = {}, originWhitelist = ['*'], 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
|
|
42
43
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
43
44
|
const nodeRef = useRef(null);
|
|
44
|
-
const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(extendObject({}, style, stylesheet.container), {
|
|
45
|
+
const { normalStyle, hasSelfPercent, hasPositionFixed, setWidth, setHeight } = useTransformStyle(extendObject({}, style, stylesheet.container), {
|
|
45
46
|
enableVar,
|
|
46
47
|
externalVarContext,
|
|
47
48
|
parentFontSize,
|
|
@@ -56,11 +57,10 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
56
57
|
});
|
|
57
58
|
const { register } = useConstructorsRegistry();
|
|
58
59
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
59
|
-
const innerProps = useInnerProps(props, {
|
|
60
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
60
61
|
ref: nodeRef,
|
|
61
|
-
style: extendObject({}, normalStyle, layoutStyle, { opacity: isLoaded ? 1 : 0 })
|
|
62
|
-
|
|
63
|
-
}, [], {
|
|
62
|
+
style: extendObject({}, normalStyle, layoutStyle, { opacity: isLoaded ? 1 : 0 })
|
|
63
|
+
}), [], {
|
|
64
64
|
layoutRef
|
|
65
65
|
});
|
|
66
66
|
const context2D = new CanvasRenderingContext2D(canvasRef.current);
|
|
@@ -111,10 +111,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
111
111
|
const postMessage = useCallback(async (message) => {
|
|
112
112
|
if (!canvasRef.current?.bus)
|
|
113
113
|
return;
|
|
114
|
-
const { type, payload } = await canvasRef.current.bus.post({
|
|
115
|
-
id: ID(),
|
|
116
|
-
...message
|
|
117
|
-
});
|
|
114
|
+
const { type, payload } = await canvasRef.current.bus.post(extendObject({ id: ID() }, message));
|
|
118
115
|
switch (type) {
|
|
119
116
|
case 'error': {
|
|
120
117
|
const { binderror } = props;
|
|
@@ -143,7 +140,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
143
140
|
canvasRef.current.listeners.splice(canvasRef.current.listeners.indexOf(listener), 1);
|
|
144
141
|
};
|
|
145
142
|
const onMessage = useCallback((e) => {
|
|
146
|
-
|
|
143
|
+
const data = JSON.parse(e.nativeEvent.data);
|
|
147
144
|
switch (data.type) {
|
|
148
145
|
case 'error': {
|
|
149
146
|
const { binderror } = props;
|
|
@@ -157,27 +154,27 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
157
154
|
break;
|
|
158
155
|
}
|
|
159
156
|
default: {
|
|
157
|
+
const newData = {};
|
|
158
|
+
// createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
|
|
159
|
+
const constructor = constructors[data.meta.constructor];
|
|
160
160
|
if (data.payload) {
|
|
161
|
-
// createLinearGradient 方法调用需要在 constructors 中需要注册 CanvasGradient
|
|
162
|
-
const constructor = constructors[data.meta.constructor];
|
|
163
161
|
if (constructor) {
|
|
164
162
|
const { args, payload } = data;
|
|
165
163
|
// RN 端同步生成一个 CanvasGradient 的实例
|
|
166
164
|
const object = constructor.constructLocally(canvasRef.current, ...args);
|
|
167
|
-
|
|
165
|
+
extendObject(object, payload, {
|
|
168
166
|
[WEBVIEW_TARGET]: data.meta.target
|
|
169
167
|
});
|
|
170
|
-
data
|
|
171
|
-
...data,
|
|
168
|
+
extendObject(newData, data, {
|
|
172
169
|
payload: object
|
|
173
|
-
};
|
|
170
|
+
});
|
|
174
171
|
}
|
|
175
172
|
for (const listener of canvasRef.current.listeners) {
|
|
176
|
-
listener(data.payload);
|
|
173
|
+
listener(constructor ? newData.payload : data.payload);
|
|
177
174
|
}
|
|
178
175
|
}
|
|
179
176
|
if (canvasRef.current.bus) {
|
|
180
|
-
canvasRef.current.bus.handle(data);
|
|
177
|
+
canvasRef.current.bus.handle(constructor && data.payload ? newData : data);
|
|
181
178
|
}
|
|
182
179
|
}
|
|
183
180
|
}
|
|
@@ -193,9 +190,10 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
193
190
|
node: canvasRef.current,
|
|
194
191
|
context: context2D
|
|
195
192
|
});
|
|
196
|
-
|
|
193
|
+
let canvasComponent;
|
|
194
|
+
if (__mpx_mode__ === 'android') {
|
|
197
195
|
const isAndroid9 = Platform.Version >= 28;
|
|
198
|
-
|
|
196
|
+
canvasComponent = createElement(View, innerProps, createElement(WebView, {
|
|
199
197
|
ref: (element) => {
|
|
200
198
|
if (canvasRef.current) {
|
|
201
199
|
canvasRef.current.webview = element;
|
|
@@ -218,7 +216,7 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
218
216
|
allowUniversalAccessFromFileURLs: true
|
|
219
217
|
}));
|
|
220
218
|
}
|
|
221
|
-
|
|
219
|
+
canvasComponent = createElement(View, innerProps, createElement(WebView, {
|
|
222
220
|
ref: (element) => {
|
|
223
221
|
if (canvasRef.current) {
|
|
224
222
|
canvasRef.current.webview = element;
|
|
@@ -231,6 +229,10 @@ const _Canvas = forwardRef((props = {}, ref) => {
|
|
|
231
229
|
onLoad: onLoad,
|
|
232
230
|
scrollEnabled: false
|
|
233
231
|
}));
|
|
232
|
+
if (hasPositionFixed) {
|
|
233
|
+
canvasComponent = createElement(Portal, null, canvasComponent);
|
|
234
|
+
}
|
|
235
|
+
return canvasComponent;
|
|
234
236
|
});
|
|
235
237
|
_Canvas.displayName = 'mpxCanvas';
|
|
236
238
|
export default _Canvas;
|
|
@@ -8,6 +8,7 @@ import { FormContext, CheckboxGroupContext } from './context';
|
|
|
8
8
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
9
9
|
import useNodesRef from './useNodesRef';
|
|
10
10
|
import { useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
|
|
11
|
+
import Portal from './mpx-portal';
|
|
11
12
|
const CheckboxGroup = forwardRef((props, ref) => {
|
|
12
13
|
const propsRef = useRef({});
|
|
13
14
|
propsRef.current = props;
|
|
@@ -23,7 +24,7 @@ const CheckboxGroup = forwardRef((props, ref) => {
|
|
|
23
24
|
flexWrap: 'wrap'
|
|
24
25
|
};
|
|
25
26
|
const styleObj = extendObject({}, defaultStyle, style);
|
|
26
|
-
const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
27
|
+
const { hasPositionFixed, hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
27
28
|
const nodeRef = useRef(null);
|
|
28
29
|
useNodesRef(props, ref, nodeRef, { style: normalStyle });
|
|
29
30
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
@@ -57,10 +58,10 @@ const CheckboxGroup = forwardRef((props, ref) => {
|
|
|
57
58
|
}
|
|
58
59
|
};
|
|
59
60
|
}, []);
|
|
60
|
-
const innerProps = useInnerProps(props,
|
|
61
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
61
62
|
ref: nodeRef,
|
|
62
63
|
style: extendObject({}, normalStyle, layoutStyle)
|
|
63
|
-
}
|
|
64
|
+
}), [
|
|
64
65
|
'name'
|
|
65
66
|
], {
|
|
66
67
|
layoutRef
|
|
@@ -81,10 +82,14 @@ const CheckboxGroup = forwardRef((props, ref) => {
|
|
|
81
82
|
notifyChange
|
|
82
83
|
};
|
|
83
84
|
}, []);
|
|
84
|
-
|
|
85
|
+
const finalComponent = createElement(View, innerProps, createElement(CheckboxGroupContext.Provider, { value: contextValue }, wrapChildren(props, {
|
|
85
86
|
hasVarDec,
|
|
86
87
|
varContext: varContextRef.current
|
|
87
88
|
})));
|
|
89
|
+
if (hasPositionFixed) {
|
|
90
|
+
return createElement(Portal, null, finalComponent);
|
|
91
|
+
}
|
|
92
|
+
return finalComponent;
|
|
88
93
|
});
|
|
89
94
|
CheckboxGroup.displayName = 'MpxCheckboxGroup';
|
|
90
95
|
export default CheckboxGroup;
|
|
@@ -12,6 +12,7 @@ import useNodesRef from './useNodesRef';
|
|
|
12
12
|
import Icon from './mpx-icon';
|
|
13
13
|
import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
|
|
14
14
|
import { CheckboxGroupContext, LabelContext } from './context';
|
|
15
|
+
import Portal from './mpx-portal';
|
|
15
16
|
const styles = StyleSheet.create({
|
|
16
17
|
container: {
|
|
17
18
|
flexDirection: 'row',
|
|
@@ -63,7 +64,7 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
|
|
|
63
64
|
bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props));
|
|
64
65
|
onChange(evt);
|
|
65
66
|
};
|
|
66
|
-
const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
67
|
+
const { hasPositionFixed, hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
67
68
|
const nodeRef = useRef(null);
|
|
68
69
|
useNodesRef(props, ref, nodeRef, {
|
|
69
70
|
style: extendObject({}, defaultStyle, normalStyle),
|
|
@@ -82,10 +83,9 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
|
|
|
82
83
|
if (labelContext) {
|
|
83
84
|
labelContext.current.triggerChange = onChange;
|
|
84
85
|
}
|
|
85
|
-
const innerProps = useInnerProps(props,
|
|
86
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
86
87
|
ref: nodeRef,
|
|
87
|
-
style: extendObject({}, innerStyle, layoutStyle)
|
|
88
|
-
}, layoutProps, {
|
|
88
|
+
style: extendObject({}, innerStyle, layoutStyle),
|
|
89
89
|
bindtap: !disabled && onTap
|
|
90
90
|
}), [
|
|
91
91
|
'value',
|
|
@@ -115,7 +115,7 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
}, [checked]);
|
|
118
|
-
|
|
118
|
+
const finalComponent = createElement(View, innerProps, createElement(View, { style: defaultStyle }, createElement(Icon, {
|
|
119
119
|
type: 'success_no_circle',
|
|
120
120
|
size: 18,
|
|
121
121
|
color: disabled ? '#ADADAD' : color,
|
|
@@ -126,6 +126,10 @@ const Checkbox = forwardRef((checkboxProps, ref) => {
|
|
|
126
126
|
textStyle,
|
|
127
127
|
textProps
|
|
128
128
|
}));
|
|
129
|
+
if (hasPositionFixed) {
|
|
130
|
+
return createElement(Portal, null, finalComponent);
|
|
131
|
+
}
|
|
132
|
+
return finalComponent;
|
|
129
133
|
});
|
|
130
134
|
Checkbox.displayName = 'MpxCheckbox';
|
|
131
135
|
export default Checkbox;
|
|
@@ -22,10 +22,10 @@ const _Form = forwardRef((fromProps, ref) => {
|
|
|
22
22
|
const propsRef = useRef({});
|
|
23
23
|
propsRef.current = props;
|
|
24
24
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: formRef });
|
|
25
|
-
const innerProps = useInnerProps(props,
|
|
25
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
26
26
|
style: extendObject({}, innerStyle, layoutStyle),
|
|
27
27
|
ref: formRef
|
|
28
|
-
}
|
|
28
|
+
}), [
|
|
29
29
|
'bindsubmit',
|
|
30
30
|
'bindreset'
|
|
31
31
|
], { layoutRef });
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -17,6 +17,7 @@ import Cancel from './icons/cancel.png';
|
|
|
17
17
|
import Download from './icons/download.png';
|
|
18
18
|
import Search from './icons/search.png';
|
|
19
19
|
import Clear from './icons/clear.png';
|
|
20
|
+
import Portal from '../mpx-portal';
|
|
20
21
|
const IconTypeMap = new Map([
|
|
21
22
|
['success', Success],
|
|
22
23
|
['success_no_circle', SuccessNoCircle],
|
|
@@ -33,18 +34,22 @@ const Icon = forwardRef((props, ref) => {
|
|
|
33
34
|
const source = IconTypeMap.get(type);
|
|
34
35
|
const defaultStyle = { width: ~~size, height: ~~size };
|
|
35
36
|
const styleObj = extendObject({}, defaultStyle, style);
|
|
36
|
-
const { hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
37
|
+
const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
37
38
|
const nodeRef = useRef(null);
|
|
38
39
|
useNodesRef(props, ref, nodeRef, { style: normalStyle });
|
|
39
40
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
40
|
-
const innerProps = useInnerProps(props,
|
|
41
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
41
42
|
ref: nodeRef,
|
|
42
43
|
source,
|
|
43
44
|
style: extendObject({}, normalStyle, layoutStyle, { tintColor: color })
|
|
44
|
-
}
|
|
45
|
+
}), [], {
|
|
45
46
|
layoutRef
|
|
46
47
|
});
|
|
47
|
-
|
|
48
|
+
const finalComponent = createElement(Image, innerProps);
|
|
49
|
+
if (hasPositionFixed) {
|
|
50
|
+
return createElement(Portal, null, finalComponent);
|
|
51
|
+
}
|
|
52
|
+
return finalComponent;
|
|
48
53
|
});
|
|
49
54
|
Icon.displayName = 'MpxIcon';
|
|
50
55
|
export default Icon;
|
|
@@ -17,6 +17,7 @@ import { SvgCssUri } from 'react-native-svg/css';
|
|
|
17
17
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
18
18
|
import useNodesRef from './useNodesRef';
|
|
19
19
|
import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils';
|
|
20
|
+
import Portal from './mpx-portal';
|
|
20
21
|
const DEFAULT_IMAGE_WIDTH = 320;
|
|
21
22
|
const DEFAULT_IMAGE_HEIGHT = 240;
|
|
22
23
|
const cropMode = [
|
|
@@ -39,7 +40,16 @@ const ModeMap = new Map([
|
|
|
39
40
|
...cropMode.map(mode => [mode, 'stretch'])
|
|
40
41
|
]);
|
|
41
42
|
const isNumber = (value) => typeof value === 'number';
|
|
42
|
-
const relativeCenteredSize = (viewSize, imageSize) =>
|
|
43
|
+
const relativeCenteredSize = (viewSize, imageSize) => {
|
|
44
|
+
return (viewSize - imageSize) / 2;
|
|
45
|
+
};
|
|
46
|
+
// 获取能完全显示图片的缩放比例:长宽方向的缩放比例最小值即为能完全展示的比例
|
|
47
|
+
function getFitScale(width1, height1, width2, height2) {
|
|
48
|
+
return Math.min(width2 / width1, height2 / height1);
|
|
49
|
+
}
|
|
50
|
+
function getFillScale(width1, height1, width2, height2) {
|
|
51
|
+
return Math.max(width2 / width1, height2 / height1);
|
|
52
|
+
}
|
|
43
53
|
function noMeetCalcRule(isSvg, mode, viewWidth, viewHeight, ratio) {
|
|
44
54
|
const isMeetSize = viewWidth && viewHeight && ratio;
|
|
45
55
|
if (isSvg && !isMeetSize)
|
|
@@ -48,6 +58,16 @@ function noMeetCalcRule(isSvg, mode, viewWidth, viewHeight, ratio) {
|
|
|
48
58
|
return true;
|
|
49
59
|
return false;
|
|
50
60
|
}
|
|
61
|
+
const getFixedWidth = (viewWidth, viewHeight, ratio) => {
|
|
62
|
+
if (!ratio)
|
|
63
|
+
return viewWidth;
|
|
64
|
+
const fixed = viewHeight / ratio;
|
|
65
|
+
return !fixed ? viewWidth : fixed;
|
|
66
|
+
};
|
|
67
|
+
const getFixedHeight = (viewWidth, viewHeight, ratio) => {
|
|
68
|
+
const fixed = viewWidth * ratio;
|
|
69
|
+
return !fixed ? viewHeight : fixed;
|
|
70
|
+
};
|
|
51
71
|
const Image = forwardRef((props, ref) => {
|
|
52
72
|
const { src = '', mode = 'scaleToFill', style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'enable-fast-image': enableFastImage, 'parent-width': parentWidth, 'parent-height': parentHeight, bindload, binderror } = props;
|
|
53
73
|
const defaultStyle = {
|
|
@@ -55,7 +75,6 @@ const Image = forwardRef((props, ref) => {
|
|
|
55
75
|
height: DEFAULT_IMAGE_HEIGHT
|
|
56
76
|
};
|
|
57
77
|
const styleObj = extendObject({}, defaultStyle, style, { overflow: 'hidden' });
|
|
58
|
-
const state = useRef({});
|
|
59
78
|
const nodeRef = useRef(null);
|
|
60
79
|
useNodesRef(props, ref, nodeRef, {
|
|
61
80
|
defaultStyle
|
|
@@ -69,17 +88,23 @@ const Image = forwardRef((props, ref) => {
|
|
|
69
88
|
const onLayout = ({ nativeEvent: { layout: { width, height } } }) => {
|
|
70
89
|
state.current.viewWidth = width;
|
|
71
90
|
state.current.viewHeight = height;
|
|
91
|
+
// 实际渲染尺寸可能会指定的值不一致,误差低于 0.5 则认为没有变化
|
|
92
|
+
if (Math.abs(viewHeight - height) < 0.5 && Math.abs(viewWidth - width) < 0.5) {
|
|
93
|
+
if (state.current.imageWidth && state.current.imageHeight && state.current.ratio) {
|
|
94
|
+
if (!loaded)
|
|
95
|
+
setLoaded(true);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
72
99
|
if (state.current.imageWidth && state.current.imageHeight && state.current.ratio) {
|
|
73
|
-
setViewWidth(width);
|
|
74
|
-
setViewHeight(height);
|
|
75
100
|
setRatio(state.current.ratio);
|
|
76
101
|
setImageWidth(state.current.imageWidth);
|
|
77
102
|
setImageHeight(state.current.imageHeight);
|
|
78
|
-
state.current
|
|
103
|
+
setViewSize(state.current.viewWidth, state.current.viewHeight, state.current.ratio);
|
|
79
104
|
setLoaded(true);
|
|
80
105
|
}
|
|
81
106
|
};
|
|
82
|
-
const {
|
|
107
|
+
const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
83
108
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({
|
|
84
109
|
props,
|
|
85
110
|
hasSelfPercent,
|
|
@@ -95,43 +120,56 @@ const Image = forwardRef((props, ref) => {
|
|
|
95
120
|
const [imageHeight, setImageHeight] = useState(0);
|
|
96
121
|
const [ratio, setRatio] = useState(0);
|
|
97
122
|
const [loaded, setLoaded] = useState(!isLayoutMode);
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
123
|
+
const state = useRef({
|
|
124
|
+
viewWidth,
|
|
125
|
+
viewHeight
|
|
126
|
+
});
|
|
127
|
+
function setViewSize(viewWidth, viewHeight, ratio) {
|
|
128
|
+
// 在特定模式下可预测 view 的变化,在onLayout触发时能以此避免重复render
|
|
129
|
+
switch (mode) {
|
|
130
|
+
case 'widthFix': {
|
|
131
|
+
setViewWidth(viewWidth);
|
|
132
|
+
const fixedHeight = getFixedHeight(viewWidth, viewHeight, ratio);
|
|
133
|
+
setViewHeight(fixedHeight);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
case 'heightFix': {
|
|
137
|
+
setViewHeight(viewHeight);
|
|
138
|
+
const fixedWidth = getFixedWidth(viewWidth, viewHeight, ratio);
|
|
139
|
+
setViewWidth(fixedWidth);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
default:
|
|
143
|
+
setViewHeight(viewHeight);
|
|
144
|
+
setViewWidth(viewWidth);
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
108
148
|
const modeStyle = useMemo(() => {
|
|
109
149
|
if (noMeetCalcRule(isSvg, mode, viewWidth, viewHeight, ratio))
|
|
110
150
|
return {};
|
|
111
151
|
switch (mode) {
|
|
112
|
-
case 'scaleToFill':
|
|
152
|
+
case 'scaleToFill': // wx 中 svg 图片的 scaleToFill 模式效果与 aspectFit 一致,不会就行图片缩放,此处保持一致
|
|
113
153
|
case 'aspectFit':
|
|
114
154
|
if (isSvg) {
|
|
115
|
-
const scale =
|
|
116
|
-
? imageWidth >= viewWidth ? viewWidth / imageWidth : imageWidth / viewWidth
|
|
117
|
-
: imageHeight >= viewHeight ? viewHeight / imageHeight : imageHeight / viewHeight;
|
|
155
|
+
const scale = getFitScale(imageWidth, imageHeight, viewWidth, viewHeight);
|
|
118
156
|
return {
|
|
119
157
|
transform: [
|
|
120
|
-
{ scale },
|
|
121
|
-
|
|
158
|
+
{ translateY: relativeCenteredSize(viewHeight, imageHeight * scale) },
|
|
159
|
+
{ translateX: relativeCenteredSize(viewWidth, imageWidth * scale) },
|
|
160
|
+
{ scale }
|
|
122
161
|
]
|
|
123
162
|
};
|
|
124
163
|
}
|
|
125
164
|
return {};
|
|
126
165
|
case 'aspectFill':
|
|
127
166
|
if (isSvg) {
|
|
128
|
-
const scale =
|
|
129
|
-
? imageWidth >= viewWidth ? viewWidth / imageWidth : imageWidth / viewWidth
|
|
130
|
-
: imageHeight >= viewHeight ? viewHeight / imageHeight : imageHeight / viewHeight;
|
|
167
|
+
const scale = getFillScale(imageWidth, imageHeight, viewWidth, viewHeight);
|
|
131
168
|
return {
|
|
132
169
|
transform: [
|
|
133
|
-
{ scale },
|
|
134
|
-
|
|
170
|
+
{ translateY: relativeCenteredSize(viewHeight, imageHeight * scale) },
|
|
171
|
+
{ translateX: relativeCenteredSize(viewWidth, imageWidth * scale) },
|
|
172
|
+
{ scale }
|
|
135
173
|
]
|
|
136
174
|
};
|
|
137
175
|
}
|
|
@@ -139,9 +177,7 @@ const Image = forwardRef((props, ref) => {
|
|
|
139
177
|
case 'widthFix':
|
|
140
178
|
case 'heightFix':
|
|
141
179
|
if (isSvg) {
|
|
142
|
-
const scale =
|
|
143
|
-
? imageWidth >= fixedWidth ? fixedWidth / imageWidth : imageWidth / fixedWidth
|
|
144
|
-
: imageHeight >= fixedHeight ? fixedHeight / imageHeight : imageHeight / fixedHeight;
|
|
180
|
+
const scale = getFitScale(imageWidth, imageHeight, viewWidth, viewHeight);
|
|
145
181
|
return {
|
|
146
182
|
transform: [{ scale }]
|
|
147
183
|
};
|
|
@@ -204,12 +240,23 @@ const Image = forwardRef((props, ref) => {
|
|
|
204
240
|
default:
|
|
205
241
|
return {};
|
|
206
242
|
}
|
|
207
|
-
}, [isSvg, mode, viewWidth, viewHeight, imageWidth, imageHeight, ratio
|
|
243
|
+
}, [isSvg, mode, viewWidth, viewHeight, imageWidth, imageHeight, ratio]);
|
|
208
244
|
const onSvgLoad = (evt) => {
|
|
209
245
|
const { width, height } = evt.nativeEvent.layout;
|
|
210
|
-
|
|
211
|
-
setImageWidth(width);
|
|
246
|
+
state.current.imageHeight = height;
|
|
212
247
|
setImageHeight(height);
|
|
248
|
+
state.current.ratio = !width ? 0 : height / width;
|
|
249
|
+
if (isWidthFixMode
|
|
250
|
+
? state.current.viewWidth
|
|
251
|
+
: isHeightFixMode
|
|
252
|
+
? state.current.viewHeight
|
|
253
|
+
: state.current.viewWidth && state.current.viewHeight) {
|
|
254
|
+
setRatio(state.current.ratio);
|
|
255
|
+
setImageWidth(width);
|
|
256
|
+
setImageHeight(height);
|
|
257
|
+
setViewSize(state.current.viewWidth, state.current.viewHeight, state.current.ratio);
|
|
258
|
+
setLoaded(true);
|
|
259
|
+
}
|
|
213
260
|
bindload && bindload(getCustomEvent('load', evt, {
|
|
214
261
|
detail: { width, height },
|
|
215
262
|
layoutRef
|
|
@@ -247,21 +294,21 @@ const Image = forwardRef((props, ref) => {
|
|
|
247
294
|
: isHeightFixMode
|
|
248
295
|
? state.current.viewHeight
|
|
249
296
|
: state.current.viewWidth && state.current.viewHeight) {
|
|
250
|
-
|
|
251
|
-
state.current.viewHeight && setViewHeight(state.current.viewHeight);
|
|
252
|
-
setRatio(!width ? 0 : height / width);
|
|
297
|
+
setRatio(state.current.ratio);
|
|
253
298
|
setImageWidth(width);
|
|
254
299
|
setImageHeight(height);
|
|
255
|
-
state.current
|
|
300
|
+
setViewSize(state.current.viewWidth, state.current.viewHeight, state.current.ratio);
|
|
256
301
|
setLoaded(true);
|
|
257
302
|
}
|
|
303
|
+
}, () => {
|
|
304
|
+
setLoaded(true);
|
|
258
305
|
});
|
|
259
306
|
}
|
|
260
307
|
}, [src, isSvg, isLayoutMode]);
|
|
261
|
-
const innerProps = useInnerProps(props,
|
|
308
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
262
309
|
ref: nodeRef,
|
|
263
|
-
style: extendObject({}, normalStyle, layoutStyle, isHeightFixMode ? { width:
|
|
264
|
-
}
|
|
310
|
+
style: extendObject({}, normalStyle, layoutStyle, isHeightFixMode ? { width: viewWidth } : {}, isWidthFixMode ? { height: viewHeight } : {})
|
|
311
|
+
}), [
|
|
265
312
|
'src',
|
|
266
313
|
'mode',
|
|
267
314
|
'svg'
|
|
@@ -286,7 +333,11 @@ const Image = forwardRef((props, ref) => {
|
|
|
286
333
|
}, isCropMode ? modeStyle : {})
|
|
287
334
|
}, isLayoutMode ? {} : innerProps), enableFastImage);
|
|
288
335
|
const LayoutImage = createElement(View, innerProps, loaded && BaseImage);
|
|
289
|
-
|
|
336
|
+
const finalComponent = isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage;
|
|
337
|
+
if (hasPositionFixed) {
|
|
338
|
+
return createElement(Portal, null, finalComponent);
|
|
339
|
+
}
|
|
340
|
+
return finalComponent;
|
|
290
341
|
});
|
|
291
342
|
Image.displayName = 'mpx-image';
|
|
292
343
|
export default Image;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Text } from 'react-native';
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
import { extendObject } from './utils';
|
|
4
|
+
const InlineText = (props) => {
|
|
5
|
+
const { allowFontScaling = false } = props;
|
|
6
|
+
return createElement(Text, extendObject({}, props, {
|
|
7
|
+
allowFontScaling
|
|
8
|
+
}));
|
|
9
|
+
};
|
|
10
|
+
InlineText.displayName = 'MpxInlineText';
|
|
11
|
+
export default InlineText;
|
|
@@ -38,20 +38,18 @@
|
|
|
38
38
|
* ✘ bind:onkeyboardheightchange
|
|
39
39
|
*/
|
|
40
40
|
import { forwardRef, useRef, useState, useContext, useEffect, createElement } from 'react';
|
|
41
|
-
import {
|
|
41
|
+
import { TextInput } from 'react-native';
|
|
42
42
|
import { warn } from '@mpxjs/utils';
|
|
43
|
-
import { useUpdateEffect, useTransformStyle, useLayout, extendObject } from './utils';
|
|
43
|
+
import { useUpdateEffect, useTransformStyle, useLayout, extendObject, isIOS } from './utils';
|
|
44
44
|
import useInnerProps, { getCustomEvent } from './getInnerListeners';
|
|
45
45
|
import useNodesRef from './useNodesRef';
|
|
46
46
|
import { FormContext, KeyboardAvoidContext } from './context';
|
|
47
|
+
import Portal from './mpx-portal';
|
|
47
48
|
const keyboardTypeMap = {
|
|
48
49
|
text: 'default',
|
|
49
50
|
number: 'numeric',
|
|
50
51
|
idcard: 'default',
|
|
51
|
-
digit:
|
|
52
|
-
ios: 'decimal-pad',
|
|
53
|
-
android: 'numeric'
|
|
54
|
-
}) || ''
|
|
52
|
+
digit: isIOS ? 'decimal-pad' : 'numeric'
|
|
55
53
|
};
|
|
56
54
|
const Input = forwardRef((props, ref) => {
|
|
57
55
|
const { style = {}, allowFontScaling = false, type = 'text', value, password, 'placeholder-style': placeholderStyle = {}, disabled, maxlength = 140, 'cursor-spacing': cursorSpacing = 0, 'auto-focus': autoFocus, focus, 'confirm-type': confirmType = 'done', 'confirm-hold': confirmHold = false, cursor, 'cursor-color': cursorColor, 'selection-start': selectionStart = -1, 'selection-end': selectionEnd = -1, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight, 'adjust-position': adjustPosition = true, bindinput, bindfocus, bindblur, bindconfirm, bindselectionchange,
|
|
@@ -86,14 +84,14 @@ const Input = forwardRef((props, ref) => {
|
|
|
86
84
|
const styleObj = extendObject({ padding: 0, backgroundColor: '#fff' }, style, multiline && autoHeight
|
|
87
85
|
? { height: 'auto', minHeight: Math.max(style?.minHeight || 35, contentHeight) }
|
|
88
86
|
: {});
|
|
89
|
-
const { hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
87
|
+
const { hasPositionFixed, hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
|
|
90
88
|
const nodeRef = useRef(null);
|
|
91
89
|
useNodesRef(props, ref, nodeRef, {
|
|
92
90
|
style: normalStyle
|
|
93
91
|
});
|
|
94
92
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
|
|
95
93
|
useEffect(() => {
|
|
96
|
-
if (
|
|
94
|
+
if (value !== tmpValue.current) {
|
|
97
95
|
const parsed = parseValue(value);
|
|
98
96
|
tmpValue.current = parsed;
|
|
99
97
|
setInputValue(parsed);
|
|
@@ -250,7 +248,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
250
248
|
? nodeRef.current?.focus()
|
|
251
249
|
: nodeRef.current?.blur();
|
|
252
250
|
}, [focus]);
|
|
253
|
-
const innerProps = useInnerProps(props,
|
|
251
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
254
252
|
ref: nodeRef,
|
|
255
253
|
style: extendObject({}, normalStyle, layoutStyle),
|
|
256
254
|
allowFontScaling,
|
|
@@ -267,8 +265,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
267
265
|
underlineColorAndroid: 'rgba(0,0,0,0)',
|
|
268
266
|
textAlignVertical: textAlignVertical,
|
|
269
267
|
placeholderTextColor: placeholderStyle?.color,
|
|
270
|
-
multiline: !!multiline
|
|
271
|
-
}, !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }, layoutProps, {
|
|
268
|
+
multiline: !!multiline,
|
|
272
269
|
onTouchStart,
|
|
273
270
|
onTouchEnd,
|
|
274
271
|
onFocus,
|
|
@@ -277,7 +274,7 @@ const Input = forwardRef((props, ref) => {
|
|
|
277
274
|
onSelectionChange,
|
|
278
275
|
onContentSizeChange,
|
|
279
276
|
onSubmitEditing: bindconfirm && !multiline && onSubmitEditing
|
|
280
|
-
}), [
|
|
277
|
+
}, !!multiline && confirmType === 'return' ? {} : { enterKeyHint: confirmType }), [
|
|
281
278
|
'type',
|
|
282
279
|
'password',
|
|
283
280
|
'placeholder-style',
|
|
@@ -293,7 +290,11 @@ const Input = forwardRef((props, ref) => {
|
|
|
293
290
|
], {
|
|
294
291
|
layoutRef
|
|
295
292
|
});
|
|
296
|
-
|
|
293
|
+
const finalComponent = createElement(TextInput, innerProps);
|
|
294
|
+
if (hasPositionFixed) {
|
|
295
|
+
return createElement(Portal, null, finalComponent);
|
|
296
|
+
}
|
|
297
|
+
return finalComponent;
|
|
297
298
|
});
|
|
298
299
|
Input.displayName = 'MpxInput';
|
|
299
300
|
export default Input;
|