@mpxjs/webpack-plugin 2.9.56 → 2.9.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/lib/runtime/base.styl +27 -0
  2. package/lib/runtime/components/react/dist/event.config.js +27 -0
  3. package/lib/runtime/components/react/dist/getInnerListeners.js +230 -0
  4. package/lib/runtime/components/react/dist/mpx-button.jsx +270 -0
  5. package/lib/runtime/components/react/dist/mpx-image/index.jsx +229 -0
  6. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +6 -0
  7. package/lib/runtime/components/react/dist/mpx-input.jsx +203 -0
  8. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +294 -0
  9. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +353 -0
  10. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +57 -0
  11. package/lib/runtime/components/react/dist/mpx-swiper/type.js +1 -0
  12. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +25 -0
  13. package/lib/runtime/components/react/dist/mpx-text.jsx +67 -0
  14. package/lib/runtime/components/react/dist/mpx-textarea.jsx +27 -0
  15. package/lib/runtime/components/react/dist/mpx-view.jsx +307 -0
  16. package/lib/runtime/components/react/dist/types/getInnerListeners.js +1 -0
  17. package/lib/runtime/components/react/dist/useNodesRef.js +25 -0
  18. package/lib/runtime/components/react/dist/utils.js +80 -0
  19. package/lib/runtime/components/react/getInnerListeners.ts +1 -1
  20. package/lib/runtime/components/react/mpx-button.tsx +1 -2
  21. package/lib/runtime/components/react/mpx-image/svg.tsx +0 -1
  22. package/lib/runtime/components/react/{getInnerListeners.type.ts → types/getInnerListeners.ts} +2 -2
  23. package/lib/runtime/components/react/types/global.d.ts +15 -0
  24. package/lib/runtime/optionProcessor.js +27 -1
  25. package/lib/template-compiler/compiler.js +68 -25
  26. package/lib/web/processTemplate.js +1 -1
  27. package/package.json +7 -4
@@ -0,0 +1,229 @@
1
+ /**
2
+ * ✔ src
3
+ * - mode: Partially, Only SVG format do not support
4
+ * ✘ show-menu-by-longpress
5
+ * ✔ binderror
6
+ * ✔ bindload
7
+ * ✘ fade-in
8
+ * ✔ webp
9
+ * ✘ lazy-load
10
+ * ✔ bindtap
11
+ * ✔ DEFAULT_SIZE
12
+ */
13
+ import React, { useEffect, useMemo, useState, forwardRef, useRef, } from 'react';
14
+ import { Image as RNImage, View, StyleSheet, } from 'react-native';
15
+ import useInnerProps, { getCustomEvent } from '../getInnerListeners';
16
+ import useNodesRef from '../useNodesRef';
17
+ const DEFAULT_IMAGE_WIDTH = 320;
18
+ const DEFAULT_IMAGE_HEIGHT = 240;
19
+ // const REMOTE_SVG_REGEXP = /https?:\/\/.*\.(?:svg)/i
20
+ // const styls = StyleSheet.create({
21
+ // suspense: {
22
+ // display: 'flex',
23
+ // justifyContent: 'center',
24
+ // alignItems: 'center',
25
+ // width: '100%',
26
+ // height: '100%',
27
+ // },
28
+ // })
29
+ const cropMode = [
30
+ 'top',
31
+ 'bottom',
32
+ 'center',
33
+ 'right',
34
+ 'left',
35
+ 'top left',
36
+ 'top right',
37
+ 'bottom left',
38
+ 'bottom right',
39
+ ];
40
+ const ModeMap = new Map([
41
+ ['scaleToFill', 'stretch'],
42
+ ['aspectFit', 'contain'],
43
+ ['aspectFill', 'cover'],
44
+ ['widthFix', 'stretch'],
45
+ ['heightFix', 'stretch'],
46
+ ...cropMode.map(mode => [mode, 'stretch']),
47
+ ]);
48
+ const isNumber = (value) => typeof value === 'number';
49
+ const relativeCenteredSize = (viewSize, imageSize) => (viewSize - imageSize) / 2;
50
+ // const Svg = lazy(() => import('./svg'))
51
+ // const Fallback = (
52
+ // <View style={styls.suspense}>
53
+ // <Text>loading ...</Text>
54
+ // </View>
55
+ // )
56
+ const Image = forwardRef((props, ref) => {
57
+ const { src = '', mode = 'scaleToFill',
58
+ // svg = false,
59
+ style = [], 'enable-offset': enableOffset, bindload, binderror } = props;
60
+ const { width = DEFAULT_IMAGE_WIDTH, height = DEFAULT_IMAGE_HEIGHT } = StyleSheet.flatten(style);
61
+ const { nodeRef } = useNodesRef(props, ref, {
62
+ defaultStyle: {
63
+ width: DEFAULT_IMAGE_WIDTH,
64
+ height: DEFAULT_IMAGE_HEIGHT
65
+ }
66
+ });
67
+ const layoutRef = useRef({});
68
+ const preSrc = useRef();
69
+ const resizeMode = ModeMap.get(mode) || 'stretch';
70
+ const isWidthFixMode = mode === 'widthFix';
71
+ const isHeightFixMode = mode === 'heightFix';
72
+ const isCropMode = cropMode.includes(mode);
73
+ const source = typeof src === 'string' ? { uri: src } : src;
74
+ const [viewWidth, setViewWidth] = useState(isNumber(width) ? width : 0);
75
+ const [viewHeight, setViewHeight] = useState(isNumber(height) ? height : 0);
76
+ const [imageWidth, setImageWidth] = useState(0);
77
+ const [imageHeight, setImageHeight] = useState(0);
78
+ const [ratio, setRatio] = useState(0);
79
+ const [loaded, setLoaded] = useState(false);
80
+ const fixedHeight = useMemo(() => {
81
+ const fixed = viewWidth * ratio;
82
+ return !fixed ? viewHeight : fixed;
83
+ }, [ratio, viewWidth, viewHeight]);
84
+ const fixedWidth = useMemo(() => {
85
+ if (!ratio)
86
+ return viewWidth;
87
+ const fixed = viewHeight / ratio;
88
+ return !fixed ? viewWidth : fixed;
89
+ }, [ratio, viewWidth, viewHeight]);
90
+ const cropModeStyle = useMemo(() => {
91
+ switch (mode) {
92
+ case 'top':
93
+ return { top: 0, left: relativeCenteredSize(viewWidth, imageWidth) };
94
+ case 'bottom':
95
+ return { top: 'auto', bottom: 0, left: relativeCenteredSize(viewWidth, imageWidth) };
96
+ case 'center':
97
+ return { top: relativeCenteredSize(viewHeight, imageHeight), left: relativeCenteredSize(viewWidth, imageWidth) };
98
+ case 'left':
99
+ return { top: relativeCenteredSize(viewHeight, imageHeight), left: 0 };
100
+ case 'right':
101
+ return { top: relativeCenteredSize(viewHeight, imageHeight), left: 'auto', right: 0 };
102
+ case 'top left':
103
+ return { top: 0, left: 0 };
104
+ case 'top right':
105
+ return { top: 0, left: 'auto', right: 0 };
106
+ case 'bottom left':
107
+ return { top: 'auto', bottom: 0, left: 0 };
108
+ case 'bottom right':
109
+ return { top: 'auto', bottom: 0, left: 'auto', right: 0 };
110
+ default:
111
+ return {};
112
+ }
113
+ }, [mode, viewWidth, viewHeight, imageWidth, imageHeight]);
114
+ const onImageLoad = (evt) => {
115
+ if (!bindload)
116
+ return;
117
+ if (typeof src === 'string') {
118
+ RNImage.getSize(src, (width, height) => {
119
+ bindload(getCustomEvent('load', evt, {
120
+ detail: { width, height },
121
+ layoutRef
122
+ }, props));
123
+ });
124
+ }
125
+ else {
126
+ const { width = 0, height = 0 } = RNImage.resolveAssetSource(src) || {};
127
+ bindload(getCustomEvent('load', evt, {
128
+ detail: { width, height },
129
+ layoutRef
130
+ }, props));
131
+ }
132
+ };
133
+ const onImageError = (evt) => {
134
+ binderror &&
135
+ binderror(getCustomEvent('error', evt, {
136
+ detail: { errMsg: evt.nativeEvent.error },
137
+ layoutRef
138
+ }, props));
139
+ };
140
+ const onViewLayout = ({ nativeEvent: { layout: { width, height }, }, }) => {
141
+ setViewWidth(width);
142
+ setViewHeight(height);
143
+ };
144
+ const onImageLayout = () => {
145
+ nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
146
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
147
+ });
148
+ };
149
+ useEffect(() => {
150
+ if (!isWidthFixMode && !isHeightFixMode && !isCropMode) {
151
+ setLoaded(true);
152
+ return;
153
+ }
154
+ const changed = preSrc.current !== src;
155
+ preSrc.current = src;
156
+ changed && setLoaded(false);
157
+ if (typeof src === 'string') {
158
+ RNImage.getSize(src, (width, height) => {
159
+ if (isWidthFixMode || isHeightFixMode) {
160
+ setRatio(width === 0 ? 0 : height / width);
161
+ }
162
+ if (isCropMode) {
163
+ setImageWidth(width);
164
+ setImageHeight(height);
165
+ }
166
+ changed && setLoaded(true);
167
+ });
168
+ }
169
+ else {
170
+ const { width = 0, height = 0 } = RNImage.resolveAssetSource(src) || {};
171
+ if (isWidthFixMode || isHeightFixMode) {
172
+ setRatio(width === 0 ? 0 : height / width);
173
+ }
174
+ if (isCropMode) {
175
+ setImageWidth(width);
176
+ setImageHeight(height);
177
+ }
178
+ changed && setLoaded(true);
179
+ }
180
+ }, [isWidthFixMode, isHeightFixMode, isCropMode, src]);
181
+ const innerProps = useInnerProps(props, {
182
+ ref: nodeRef,
183
+ ...(enableOffset ? { onLayout: onImageLayout } : {})
184
+ }, [
185
+ 'enable-offset'
186
+ ], {
187
+ layoutRef
188
+ });
189
+ // if (typeof src === 'string' && REMOTE_SVG_REGEXP.test(src)) {
190
+ // return (
191
+ // <Suspense fallback={Fallback} {...innerProps}>
192
+ // <View {...innerProps}>
193
+ // <Svg src={src} style={style} width={width as SvgNumberProp} height={height as SvgNumberProp} />
194
+ // </View>
195
+ // </Suspense>
196
+ // )
197
+ // }
198
+ // if (svg) {
199
+ // return (
200
+ // <Suspense fallback={Fallback}>
201
+ // <View {...innerProps}>
202
+ // <Svg local src={src} style={style} width={width as SvgNumberProp} height={height as SvgNumberProp} />
203
+ // </View>
204
+ // </Suspense>
205
+ // )
206
+ // }
207
+ return (<View style={[
208
+ { width, height },
209
+ style,
210
+ {
211
+ ...(isHeightFixMode && { width: fixedWidth }),
212
+ ...(isWidthFixMode && { height: fixedHeight }),
213
+ },
214
+ { overflow: 'hidden' },
215
+ ]} onLayout={onViewLayout}>
216
+ {loaded && <RNImage {...innerProps} source={source} resizeMode={resizeMode} onLoad={onImageLoad} onError={onImageError} style={[
217
+ StyleSheet.absoluteFill,
218
+ {
219
+ width: !isCropMode ? '100%' : imageWidth,
220
+ height: !isCropMode ? '100%' : imageHeight,
221
+ },
222
+ {
223
+ ...(isCropMode && cropModeStyle),
224
+ },
225
+ ]}/>}
226
+ </View>);
227
+ });
228
+ Image.displayName = 'mpx-image';
229
+ export default Image;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import { SvgCssUri, WithLocalSvg } from 'react-native-svg/css';
3
+ const Svg = ({ local = false, src, style, width, height }) => {
4
+ return local ? (<WithLocalSvg style={style} asset={src} width={width} height={height}/>) : (<SvgCssUri style={style} uri={src} width={width} height={height}/>);
5
+ };
6
+ export default Svg;
@@ -0,0 +1,203 @@
1
+ /**
2
+ * ✔ value
3
+ * - type: Partially. Not support `safe-password`、`nickname`
4
+ * ✔ password
5
+ * ✔ placeholder
6
+ * - placeholder-style: Only support color.
7
+ * ✘ placeholder-class
8
+ * ✔ disabled
9
+ * ✔ maxlength
10
+ * ✘ cursor-spacing
11
+ * ✔ auto-focus
12
+ * ✔ focus
13
+ * ✔ confirm-type
14
+ * ✘ always-embed
15
+ * ✔ confirm-hold
16
+ * ✔ cursor
17
+ * ✔ cursor-color
18
+ * ✔ selection-start
19
+ * ✔ selection-end
20
+ * ✘ adjust-position
21
+ * ✘ hold-keyboard
22
+ * ✘ safe-password-cert-path
23
+ * ✘ safe-password-length
24
+ * ✘ safe-password-time-stamp
25
+ * ✘ safe-password-nonce
26
+ * ✘ safe-password-salt
27
+ * ✘ safe-password-custom-hash
28
+ * - bindinput: No `keyCode` info.
29
+ * - bindfocus: No `height` info.
30
+ * - bindblur: No `encryptedValue`、`encryptError` info.
31
+ * ✔ bindconfirm
32
+ * ✘ bindkeyboardheightchange
33
+ * ✘ bindnicknamereview
34
+ * ✔ bind:selectionchange
35
+ * ✘ bind:keyboardcompositionstart
36
+ * ✘ bind:keyboardcompositionupdate
37
+ * ✘ bind:keyboardcompositionend
38
+ * ✘ bind:onkeyboardheightchange
39
+ */
40
+ import React, { forwardRef, useMemo, useRef, useState } from 'react';
41
+ import { Platform, TextInput } from 'react-native';
42
+ import { parseInlineStyle, useUpdateEffect } from './utils';
43
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
44
+ import useNodesRef from './useNodesRef';
45
+ const keyboardTypeMap = {
46
+ text: 'default',
47
+ number: 'numeric',
48
+ idcard: 'default',
49
+ digit: Platform.select({
50
+ ios: 'decimal-pad',
51
+ android: 'numeric',
52
+ }) || '',
53
+ };
54
+ const Input = forwardRef((props, ref) => {
55
+ const { style = [], type = 'text', value, password, 'placeholder-style': placeholderStyle, disabled, maxlength = 140, '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-offset': enableOffset, bindinput, bindfocus, bindblur, bindconfirm, bindselectionchange,
56
+ // private
57
+ multiline, 'auto-height': autoHeight, bindlinechange, } = props;
58
+ const { nodeRef } = useNodesRef(props, ref);
59
+ const keyboardType = keyboardTypeMap[type];
60
+ const defaultValue = type === 'number' && value ? value + '' : value;
61
+ const placeholderTextColor = parseInlineStyle(placeholderStyle)?.color;
62
+ const textAlignVertical = multiline ? 'top' : 'auto';
63
+ const layoutRef = useRef({});
64
+ const tmpValue = useRef();
65
+ const cursorIndex = useRef(0);
66
+ const lineCount = useRef(0);
67
+ const [inputValue, setInputValue] = useState();
68
+ const [contentHeight, setContentHeight] = useState(0);
69
+ const selection = useMemo(() => {
70
+ if (selectionStart >= 0 && selectionEnd >= 0) {
71
+ return { start: selectionStart, end: selectionEnd };
72
+ }
73
+ else if (typeof cursor === 'number') {
74
+ return { start: cursor, end: cursor };
75
+ }
76
+ }, [cursor, selectionStart, selectionEnd]);
77
+ const onTextInput = ({ nativeEvent }) => {
78
+ if (!bindinput && !bindblur)
79
+ return;
80
+ const { range: { start, end }, text, } = nativeEvent;
81
+ cursorIndex.current = start < end ? start : start + text.length;
82
+ };
83
+ const onChange = (evt) => {
84
+ tmpValue.current = evt.nativeEvent.text;
85
+ if (!bindinput)
86
+ return;
87
+ const result = bindinput(getCustomEvent('input', evt, {
88
+ detail: {
89
+ value: evt.nativeEvent.text,
90
+ cursor: cursorIndex.current,
91
+ },
92
+ layoutRef
93
+ }, props));
94
+ if (typeof result === 'string') {
95
+ tmpValue.current = result;
96
+ setInputValue(result);
97
+ }
98
+ else if (inputValue) {
99
+ setInputValue(undefined);
100
+ }
101
+ };
102
+ const onInputFocus = (evt) => {
103
+ bindfocus &&
104
+ bindfocus(getCustomEvent('focus', evt, {
105
+ detail: {
106
+ value: tmpValue.current || '',
107
+ },
108
+ layoutRef
109
+ }, props));
110
+ };
111
+ const onInputBlur = (evt) => {
112
+ bindblur &&
113
+ bindblur(getCustomEvent('blur', evt, {
114
+ detail: {
115
+ value: tmpValue.current || '',
116
+ cursor: cursorIndex.current,
117
+ },
118
+ layoutRef
119
+ }, props));
120
+ };
121
+ const onKeyPress = (evt) => {
122
+ bindconfirm &&
123
+ evt.nativeEvent.key === 'Enter' &&
124
+ bindconfirm(getCustomEvent('confirm', evt, {
125
+ detail: {
126
+ value: tmpValue.current || '',
127
+ },
128
+ layoutRef
129
+ }, props));
130
+ };
131
+ const onSubmitEditing = (evt) => {
132
+ bindconfirm &&
133
+ multiline &&
134
+ bindconfirm(getCustomEvent('confirm', evt, {
135
+ detail: {
136
+ value: tmpValue.current || '',
137
+ },
138
+ layoutRef
139
+ }, props));
140
+ };
141
+ const onContentSizeChange = (evt) => {
142
+ const { width, height } = evt.nativeEvent.contentSize;
143
+ if (width && height) {
144
+ if (!multiline || !autoHeight || height === contentHeight)
145
+ return;
146
+ lineCount.current += height > contentHeight ? 1 : -1;
147
+ const lineHeight = lineCount.current === 0 ? 0 : height / lineCount.current;
148
+ bindlinechange &&
149
+ bindlinechange(getCustomEvent('linechange', evt, {
150
+ detail: {
151
+ height,
152
+ lineHeight,
153
+ lineCount: lineCount.current,
154
+ },
155
+ layoutRef
156
+ }, props));
157
+ setContentHeight(height);
158
+ }
159
+ };
160
+ const onSelectionChange = (evt) => {
161
+ bindselectionchange &&
162
+ bindselectionchange(getCustomEvent('selectionchange', evt, {
163
+ detail: {
164
+ selectionStart: evt.nativeEvent.selection.start,
165
+ selectionEnd: evt.nativeEvent.selection.end,
166
+ },
167
+ layoutRef
168
+ }, props));
169
+ };
170
+ const onLayout = () => {
171
+ nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
172
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
173
+ });
174
+ };
175
+ useUpdateEffect(() => {
176
+ if (!nodeRef?.current) {
177
+ return;
178
+ }
179
+ focus
180
+ ? nodeRef.current?.focus()
181
+ : nodeRef.current?.blur();
182
+ }, [focus]);
183
+ const innerProps = useInnerProps(props, {
184
+ ref: nodeRef,
185
+ ...(enableOffset ? { onLayout } : {}),
186
+ }, [
187
+ 'enable-offset'
188
+ ], {
189
+ layoutRef
190
+ });
191
+ return (<TextInput {...innerProps} keyboardType={keyboardType} secureTextEntry={!!password} defaultValue={defaultValue} value={inputValue} maxLength={maxlength === -1 ? undefined : maxlength} editable={!disabled} autoFocus={!!autoFocus || !!focus} returnKeyType={confirmType} selection={selection} selectionColor={cursorColor} blurOnSubmit={!multiline && !confirmHold} underlineColorAndroid="rgba(0,0,0,0)" textAlignVertical={textAlignVertical} placeholderTextColor={placeholderTextColor} multiline={!!multiline} onTextInput={onTextInput} onChange={onChange} onFocus={onInputFocus} onBlur={onInputBlur} onKeyPress={onKeyPress} onSubmitEditing={onSubmitEditing} onContentSizeChange={onContentSizeChange} onSelectionChange={onSelectionChange} style={[
192
+ {
193
+ padding: 0,
194
+ },
195
+ style,
196
+ multiline &&
197
+ autoHeight && {
198
+ height: Math.max(style?.minHeight || 35, contentHeight),
199
+ },
200
+ ]}/>);
201
+ });
202
+ Input.displayName = 'mpx-input';
203
+ export default Input;