@mpxjs/webpack-plugin 2.8.25-alpha.21 → 2.8.25-alpha.22

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 (72) hide show
  1. package/lib/runtime/components/react/dist/KeyboardAvoidingView.jsx +89 -0
  2. package/lib/runtime/components/react/dist/context.js +14 -0
  3. package/lib/runtime/components/react/dist/event.config.js +27 -0
  4. package/lib/runtime/components/react/dist/getInnerListeners.js +262 -0
  5. package/lib/runtime/components/react/dist/mpx-button.jsx +271 -0
  6. package/lib/runtime/components/react/dist/mpx-canvas/Bus.js +60 -0
  7. package/lib/runtime/components/react/dist/mpx-canvas/CanvasGradient.js +15 -0
  8. package/lib/runtime/components/react/dist/mpx-canvas/CanvasRenderingContext2D.js +84 -0
  9. package/lib/runtime/components/react/dist/mpx-canvas/Image.js +87 -0
  10. package/lib/runtime/components/react/dist/mpx-canvas/ImageData.js +15 -0
  11. package/lib/runtime/components/react/dist/mpx-canvas/constructorsRegistry.js +28 -0
  12. package/lib/runtime/components/react/dist/mpx-canvas/html.js +341 -0
  13. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +236 -0
  14. package/lib/runtime/components/react/dist/mpx-canvas/utils.jsx +89 -0
  15. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +90 -0
  16. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +131 -0
  17. package/lib/runtime/components/react/dist/mpx-form.jsx +68 -0
  18. package/lib/runtime/components/react/dist/mpx-icon/icons/cancel.png +0 -0
  19. package/lib/runtime/components/react/dist/mpx-icon/icons/clear.png +0 -0
  20. package/lib/runtime/components/react/dist/mpx-icon/icons/download.png +0 -0
  21. package/lib/runtime/components/react/dist/mpx-icon/icons/info.png +0 -0
  22. package/lib/runtime/components/react/dist/mpx-icon/icons/search.png +0 -0
  23. package/lib/runtime/components/react/dist/mpx-icon/icons/success.png +0 -0
  24. package/lib/runtime/components/react/dist/mpx-icon/icons/success_no_circle.png +0 -0
  25. package/lib/runtime/components/react/dist/mpx-icon/icons/waiting.png +0 -0
  26. package/lib/runtime/components/react/dist/mpx-icon/icons/warn.png +0 -0
  27. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +50 -0
  28. package/lib/runtime/components/react/dist/mpx-image.jsx +292 -0
  29. package/lib/runtime/components/react/dist/mpx-input.jsx +292 -0
  30. package/lib/runtime/components/react/dist/mpx-label.jsx +52 -0
  31. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +32 -0
  32. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +468 -0
  33. package/lib/runtime/components/react/dist/mpx-navigator.jsx +33 -0
  34. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +74 -0
  35. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +141 -0
  36. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +147 -0
  37. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +99 -0
  38. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +81 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +242 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  42. package/lib/runtime/components/react/dist/mpx-picker-view-column-item.jsx +35 -0
  43. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +193 -0
  44. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +125 -0
  45. package/lib/runtime/components/react/dist/mpx-portal/index.jsx +30 -0
  46. package/lib/runtime/components/react/dist/mpx-portal/portal-host.jsx +112 -0
  47. package/lib/runtime/components/react/dist/mpx-portal/portal-manager.jsx +41 -0
  48. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +86 -0
  49. package/lib/runtime/components/react/dist/mpx-radio.jsx +140 -0
  50. package/lib/runtime/components/react/dist/mpx-rich-text/html.js +39 -0
  51. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +62 -0
  52. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +17 -0
  53. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +372 -0
  54. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +11 -0
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +59 -0
  56. package/lib/runtime/components/react/dist/mpx-swiper.jsx +671 -0
  57. package/lib/runtime/components/react/dist/mpx-switch.jsx +97 -0
  58. package/lib/runtime/components/react/dist/mpx-text.jsx +41 -0
  59. package/lib/runtime/components/react/dist/mpx-textarea.jsx +40 -0
  60. package/lib/runtime/components/react/dist/mpx-video.jsx +248 -0
  61. package/lib/runtime/components/react/dist/mpx-view.jsx +611 -0
  62. package/lib/runtime/components/react/dist/mpx-web-view.jsx +289 -0
  63. package/lib/runtime/components/react/dist/parser.js +218 -0
  64. package/lib/runtime/components/react/dist/pickerFaces.js +76 -0
  65. package/lib/runtime/components/react/dist/pickerVIewContext.js +14 -0
  66. package/lib/runtime/components/react/dist/pickerViewIndicator.jsx +23 -0
  67. package/lib/runtime/components/react/dist/pickerViewMask.jsx +18 -0
  68. package/lib/runtime/components/react/dist/useAnimationHooks.js +346 -0
  69. package/lib/runtime/components/react/dist/useNodesRef.js +16 -0
  70. package/lib/runtime/components/react/dist/utils.jsx +599 -0
  71. package/package.json +6 -3
  72. package/LICENSE +0 -433
@@ -0,0 +1,292 @@
1
+ /**
2
+ * ✔ src
3
+ * ✔ mode
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 { useEffect, useMemo, useState, useRef, forwardRef, createElement } from 'react';
14
+ import { Image as RNImage, View } from 'react-native';
15
+ import { noop } from '@mpxjs/utils';
16
+ import { SvgCssUri } from 'react-native-svg/css';
17
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
18
+ import useNodesRef from './useNodesRef';
19
+ import { SVG_REGEXP, useLayout, useTransformStyle, renderImage, extendObject } from './utils';
20
+ const DEFAULT_IMAGE_WIDTH = 320;
21
+ const DEFAULT_IMAGE_HEIGHT = 240;
22
+ const cropMode = [
23
+ 'top',
24
+ 'bottom',
25
+ 'center',
26
+ 'right',
27
+ 'left',
28
+ 'top left',
29
+ 'top right',
30
+ 'bottom left',
31
+ 'bottom right'
32
+ ];
33
+ const ModeMap = new Map([
34
+ ['scaleToFill', 'stretch'],
35
+ ['aspectFit', 'contain'],
36
+ ['aspectFill', 'cover'],
37
+ ['widthFix', 'stretch'],
38
+ ['heightFix', 'stretch'],
39
+ ...cropMode.map(mode => [mode, 'stretch'])
40
+ ]);
41
+ const isNumber = (value) => typeof value === 'number';
42
+ const relativeCenteredSize = (viewSize, imageSize) => (viewSize - imageSize) / 2;
43
+ function noMeetCalcRule(isSvg, mode, viewWidth, viewHeight, ratio) {
44
+ const isMeetSize = viewWidth && viewHeight && ratio;
45
+ if (isSvg && !isMeetSize)
46
+ return true;
47
+ if (!isSvg && !['scaleToFill', 'aspectFit', 'aspectFill'].includes(mode) && !isMeetSize)
48
+ return true;
49
+ return false;
50
+ }
51
+ const Image = forwardRef((props, ref) => {
52
+ 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
+ const defaultStyle = {
54
+ width: DEFAULT_IMAGE_WIDTH,
55
+ height: DEFAULT_IMAGE_HEIGHT
56
+ };
57
+ const styleObj = extendObject({}, defaultStyle, style, { overflow: 'hidden' });
58
+ const state = useRef({});
59
+ const nodeRef = useRef(null);
60
+ useNodesRef(props, ref, nodeRef, {
61
+ defaultStyle
62
+ });
63
+ const isSvg = SVG_REGEXP.test(src);
64
+ const isWidthFixMode = mode === 'widthFix';
65
+ const isHeightFixMode = mode === 'heightFix';
66
+ const isCropMode = cropMode.includes(mode);
67
+ const isLayoutMode = isWidthFixMode || isHeightFixMode || isCropMode;
68
+ const resizeMode = ModeMap.get(mode) || 'stretch';
69
+ const onLayout = ({ nativeEvent: { layout: { width, height } } }) => {
70
+ state.current.viewWidth = width;
71
+ state.current.viewHeight = height;
72
+ if (state.current.imageWidth && state.current.imageHeight && state.current.ratio) {
73
+ setViewWidth(width);
74
+ setViewHeight(height);
75
+ setRatio(state.current.ratio);
76
+ setImageWidth(state.current.imageWidth);
77
+ setImageHeight(state.current.imageHeight);
78
+ state.current = {};
79
+ setLoaded(true);
80
+ }
81
+ };
82
+ const { normalStyle, hasSelfPercent, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
83
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({
84
+ props,
85
+ hasSelfPercent,
86
+ setWidth,
87
+ setHeight,
88
+ nodeRef,
89
+ onLayout: isLayoutMode ? onLayout : noop
90
+ });
91
+ const { width, height } = normalStyle;
92
+ const [viewWidth, setViewWidth] = useState(isNumber(width) ? width : 0);
93
+ const [viewHeight, setViewHeight] = useState(isNumber(height) ? height : 0);
94
+ const [imageWidth, setImageWidth] = useState(0);
95
+ const [imageHeight, setImageHeight] = useState(0);
96
+ const [ratio, setRatio] = useState(0);
97
+ const [loaded, setLoaded] = useState(!isLayoutMode);
98
+ const fixedHeight = useMemo(() => {
99
+ const fixed = viewWidth * ratio;
100
+ return !fixed ? viewHeight : fixed;
101
+ }, [ratio, viewWidth, viewHeight]);
102
+ const fixedWidth = useMemo(() => {
103
+ if (!ratio)
104
+ return viewWidth;
105
+ const fixed = viewHeight / ratio;
106
+ return !fixed ? viewWidth : fixed;
107
+ }, [ratio, viewWidth, viewHeight]);
108
+ const modeStyle = useMemo(() => {
109
+ if (noMeetCalcRule(isSvg, mode, viewWidth, viewHeight, ratio))
110
+ return {};
111
+ switch (mode) {
112
+ case 'scaleToFill':
113
+ case 'aspectFit':
114
+ if (isSvg) {
115
+ const scale = ratio <= 1
116
+ ? imageWidth >= viewWidth ? viewWidth / imageWidth : imageWidth / viewWidth
117
+ : imageHeight >= viewHeight ? viewHeight / imageHeight : imageHeight / viewHeight;
118
+ return {
119
+ transform: [
120
+ { scale },
121
+ ratio <= 1 ? { translateY: -(imageHeight * scale - viewHeight) / 2 / scale } : { translateX: -(imageWidth * scale - viewWidth) / 2 / scale }
122
+ ]
123
+ };
124
+ }
125
+ return {};
126
+ case 'aspectFill':
127
+ if (isSvg) {
128
+ const scale = ratio >= 1
129
+ ? imageWidth >= viewWidth ? viewWidth / imageWidth : imageWidth / viewWidth
130
+ : imageHeight >= viewHeight ? viewHeight / imageHeight : imageHeight / viewHeight;
131
+ return {
132
+ transform: [
133
+ { scale },
134
+ ratio >= 1 ? { translateY: -(imageHeight * scale - viewHeight) / 2 / scale } : { translateX: -(imageWidth * scale - viewWidth) / 2 / scale }
135
+ ]
136
+ };
137
+ }
138
+ return {};
139
+ case 'widthFix':
140
+ case 'heightFix':
141
+ if (isSvg) {
142
+ const scale = ratio >= 1
143
+ ? imageWidth >= fixedWidth ? fixedWidth / imageWidth : imageWidth / fixedWidth
144
+ : imageHeight >= fixedHeight ? fixedHeight / imageHeight : imageHeight / fixedHeight;
145
+ return {
146
+ transform: [{ scale }]
147
+ };
148
+ }
149
+ return {};
150
+ case 'top':
151
+ return {
152
+ transform: [
153
+ { translateX: relativeCenteredSize(viewWidth, imageWidth) }
154
+ ]
155
+ };
156
+ case 'bottom':
157
+ return {
158
+ transform: [
159
+ { translateY: viewHeight - imageHeight },
160
+ { translateX: relativeCenteredSize(viewWidth, imageWidth) }
161
+ ]
162
+ };
163
+ case 'center':
164
+ return {
165
+ transform: [
166
+ { translateY: relativeCenteredSize(viewHeight, imageHeight) },
167
+ { translateX: relativeCenteredSize(viewWidth, imageWidth) }
168
+ ]
169
+ };
170
+ case 'left':
171
+ return {
172
+ transform: [
173
+ { translateY: relativeCenteredSize(viewHeight, imageHeight) }
174
+ ]
175
+ };
176
+ case 'right':
177
+ return {
178
+ transform: [
179
+ { translateY: relativeCenteredSize(viewHeight, imageHeight) },
180
+ { translateX: viewWidth - imageWidth }
181
+ ]
182
+ };
183
+ case 'top left':
184
+ return {};
185
+ case 'top right':
186
+ return {
187
+ transform: [
188
+ { translateX: viewWidth - imageWidth }
189
+ ]
190
+ };
191
+ case 'bottom left':
192
+ return {
193
+ transform: [
194
+ { translateY: viewHeight - imageHeight }
195
+ ]
196
+ };
197
+ case 'bottom right':
198
+ return {
199
+ transform: [
200
+ { translateY: viewHeight - imageHeight },
201
+ { translateX: viewWidth - imageWidth }
202
+ ]
203
+ };
204
+ default:
205
+ return {};
206
+ }
207
+ }, [isSvg, mode, viewWidth, viewHeight, imageWidth, imageHeight, ratio, fixedWidth, fixedHeight]);
208
+ const onSvgLoad = (evt) => {
209
+ const { width, height } = evt.nativeEvent.layout;
210
+ setRatio(!width ? 0 : height / width);
211
+ setImageWidth(width);
212
+ setImageHeight(height);
213
+ bindload && bindload(getCustomEvent('load', evt, {
214
+ detail: { width, height },
215
+ layoutRef
216
+ }, props));
217
+ };
218
+ const onSvgError = (evt) => {
219
+ binderror(getCustomEvent('error', evt, {
220
+ detail: { errMsg: evt?.message },
221
+ layoutRef
222
+ }, props));
223
+ };
224
+ const onImageLoad = (evt) => {
225
+ evt.persist();
226
+ RNImage.getSize(src, (width, height) => {
227
+ bindload(getCustomEvent('load', evt, {
228
+ detail: { width, height },
229
+ layoutRef
230
+ }, props));
231
+ });
232
+ };
233
+ const onImageError = (evt) => {
234
+ binderror(getCustomEvent('error', evt, {
235
+ detail: { errMsg: evt.nativeEvent.error },
236
+ layoutRef
237
+ }, props));
238
+ };
239
+ useEffect(() => {
240
+ if (!isSvg && isLayoutMode) {
241
+ RNImage.getSize(src, (width, height) => {
242
+ state.current.imageWidth = width;
243
+ state.current.imageHeight = height;
244
+ state.current.ratio = !width ? 0 : height / width;
245
+ if (isWidthFixMode
246
+ ? state.current.viewWidth
247
+ : isHeightFixMode
248
+ ? state.current.viewHeight
249
+ : state.current.viewWidth && state.current.viewHeight) {
250
+ state.current.viewWidth && setViewWidth(state.current.viewWidth);
251
+ state.current.viewHeight && setViewHeight(state.current.viewHeight);
252
+ setRatio(!width ? 0 : height / width);
253
+ setImageWidth(width);
254
+ setImageHeight(height);
255
+ state.current = {};
256
+ setLoaded(true);
257
+ }
258
+ });
259
+ }
260
+ }, [src, isSvg, isLayoutMode]);
261
+ const innerProps = useInnerProps(props, extendObject({
262
+ ref: nodeRef,
263
+ style: extendObject({}, normalStyle, layoutStyle, isHeightFixMode ? { width: fixedWidth } : {}, isWidthFixMode ? { height: fixedHeight } : {})
264
+ }, layoutProps), [
265
+ 'src',
266
+ 'mode',
267
+ 'svg'
268
+ ], {
269
+ layoutRef
270
+ });
271
+ const SvgImage = createElement(View, innerProps, createElement(SvgCssUri, {
272
+ uri: src,
273
+ onLayout: onSvgLoad,
274
+ onError: binderror && onSvgError,
275
+ style: extendObject({ transformOrigin: 'top left' }, modeStyle)
276
+ }));
277
+ const BaseImage = renderImage(extendObject({
278
+ source: { uri: src },
279
+ resizeMode: resizeMode,
280
+ onLoad: bindload && onImageLoad,
281
+ onError: binderror && onImageError,
282
+ style: extendObject({
283
+ transformOrigin: 'top left',
284
+ width: isCropMode ? imageWidth : '100%',
285
+ height: isCropMode ? imageHeight : '100%'
286
+ }, isCropMode ? modeStyle : {})
287
+ }, isLayoutMode ? {} : innerProps), enableFastImage);
288
+ const LayoutImage = createElement(View, innerProps, loaded && BaseImage);
289
+ return isSvg ? SvgImage : isLayoutMode ? LayoutImage : BaseImage;
290
+ });
291
+ Image.displayName = 'mpx-image';
292
+ export default Image;
@@ -0,0 +1,292 @@
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 { forwardRef, useRef, useState, useContext, useEffect, createElement } from 'react';
41
+ import { Platform, TextInput } from 'react-native';
42
+ import { warn } from '@mpxjs/utils';
43
+ import { parseInlineStyle, useUpdateEffect, useTransformStyle, useLayout, extendObject } from './utils';
44
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
45
+ import useNodesRef from './useNodesRef';
46
+ import { FormContext, KeyboardAvoidContext } from './context';
47
+ const keyboardTypeMap = {
48
+ text: 'default',
49
+ number: 'numeric',
50
+ idcard: 'default',
51
+ digit: Platform.select({
52
+ ios: 'decimal-pad',
53
+ android: 'numeric'
54
+ }) || ''
55
+ };
56
+ const Input = forwardRef((props, ref) => {
57
+ 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,
58
+ // private
59
+ multiline, 'auto-height': autoHeight, bindlinechange } = props;
60
+ const formContext = useContext(FormContext);
61
+ const keyboardAvoid = useContext(KeyboardAvoidContext);
62
+ let formValuesMap;
63
+ if (formContext) {
64
+ formValuesMap = formContext.formValuesMap;
65
+ }
66
+ const parseValue = (value) => {
67
+ if (typeof value === 'string') {
68
+ if (value.length > maxlength && maxlength >= 0) {
69
+ return value.slice(0, maxlength);
70
+ }
71
+ return value;
72
+ }
73
+ if (typeof value === 'number')
74
+ return value + '';
75
+ return '';
76
+ };
77
+ const keyboardType = keyboardTypeMap[type];
78
+ const defaultValue = parseValue(value);
79
+ const placeholderTextColor = parseInlineStyle(placeholderStyle)?.color;
80
+ const textAlignVertical = multiline ? 'top' : 'auto';
81
+ const tmpValue = useRef(defaultValue);
82
+ const cursorIndex = useRef(0);
83
+ const lineCount = useRef(0);
84
+ const [inputValue, setInputValue] = useState(defaultValue);
85
+ const [contentHeight, setContentHeight] = useState(0);
86
+ const [selection, setSelection] = useState({ start: -1, end: -1 });
87
+ const styleObj = extendObject({ padding: 0, backgroundColor: '#fff' }, style, multiline && autoHeight
88
+ ? { minHeight: Math.max(style?.minHeight || 35, contentHeight) }
89
+ : {});
90
+ const { hasSelfPercent, normalStyle, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
91
+ const nodeRef = useRef(null);
92
+ useNodesRef(props, ref, nodeRef, {
93
+ style: normalStyle
94
+ });
95
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
96
+ useEffect(() => {
97
+ if (inputValue !== value) {
98
+ setInputValue(parseValue(value));
99
+ }
100
+ }, [value]);
101
+ useEffect(() => {
102
+ if (typeof cursor === 'number') {
103
+ setSelection({ start: cursor, end: cursor });
104
+ }
105
+ else if (selectionStart >= 0 && selectionEnd >= 0 && selectionStart !== selectionEnd) {
106
+ setSelection({ start: selectionStart, end: selectionEnd });
107
+ }
108
+ }, [cursor, selectionStart, selectionEnd]);
109
+ const onTextInput = ({ nativeEvent }) => {
110
+ if (!bindinput && !bindblur)
111
+ return;
112
+ const { range: { start, end }, text } = nativeEvent;
113
+ cursorIndex.current = start < end ? start : start + text.length;
114
+ };
115
+ const onChange = (evt) => {
116
+ tmpValue.current = evt.nativeEvent.text;
117
+ if (!bindinput)
118
+ return;
119
+ const result = bindinput(getCustomEvent('input', evt, {
120
+ detail: {
121
+ value: evt.nativeEvent.text,
122
+ cursor: cursorIndex.current
123
+ },
124
+ layoutRef
125
+ }, props));
126
+ if (typeof result === 'string') {
127
+ tmpValue.current = result;
128
+ setInputValue(result);
129
+ }
130
+ else {
131
+ setInputValue(tmpValue.current);
132
+ }
133
+ };
134
+ const setKeyboardAvoidContext = () => {
135
+ if (adjustPosition && keyboardAvoid?.current) {
136
+ extendObject(keyboardAvoid.current, {
137
+ cursorSpacing,
138
+ ref: nodeRef
139
+ });
140
+ }
141
+ };
142
+ const onInputTouchStart = () => {
143
+ // sometimes the focus event occurs later than the keyboardWillShow event
144
+ setKeyboardAvoidContext();
145
+ };
146
+ const onInputFocus = (evt) => {
147
+ setKeyboardAvoidContext();
148
+ bindfocus && bindfocus(getCustomEvent('focus', evt, {
149
+ detail: {
150
+ value: tmpValue.current || ''
151
+ },
152
+ layoutRef
153
+ }, props));
154
+ };
155
+ const onInputBlur = (evt) => {
156
+ bindblur && bindblur(getCustomEvent('blur', evt, {
157
+ detail: {
158
+ value: tmpValue.current || '',
159
+ cursor: cursorIndex.current
160
+ },
161
+ layoutRef
162
+ }, props));
163
+ };
164
+ const onKeyPress = (evt) => {
165
+ evt.nativeEvent.key === 'Enter' &&
166
+ bindconfirm(getCustomEvent('confirm', evt, {
167
+ detail: {
168
+ value: tmpValue.current || ''
169
+ },
170
+ layoutRef
171
+ }, props));
172
+ };
173
+ const onSubmitEditing = (evt) => {
174
+ bindconfirm(getCustomEvent('confirm', evt, {
175
+ detail: {
176
+ value: tmpValue.current || ''
177
+ },
178
+ layoutRef
179
+ }, props));
180
+ };
181
+ const onSelectionChange = (evt) => {
182
+ setSelection(evt.nativeEvent.selection);
183
+ bindselectionchange && bindselectionchange(getCustomEvent('selectionchange', evt, {
184
+ detail: {
185
+ selectionStart: evt.nativeEvent.selection.start,
186
+ selectionEnd: evt.nativeEvent.selection.end
187
+ },
188
+ layoutRef
189
+ }, props));
190
+ };
191
+ const onContentSizeChange = (evt) => {
192
+ const { width, height } = evt.nativeEvent.contentSize;
193
+ if (width && height) {
194
+ if (!multiline || !autoHeight || height === contentHeight)
195
+ return;
196
+ lineCount.current += height > contentHeight ? 1 : -1;
197
+ const lineHeight = lineCount.current === 0 ? 0 : height / lineCount.current;
198
+ bindlinechange &&
199
+ bindlinechange(getCustomEvent('linechange', evt, {
200
+ detail: {
201
+ height,
202
+ lineHeight,
203
+ lineCount: lineCount.current
204
+ },
205
+ layoutRef
206
+ }, props));
207
+ setContentHeight(height);
208
+ }
209
+ };
210
+ const resetValue = () => {
211
+ setInputValue('');
212
+ };
213
+ const getValue = () => {
214
+ return inputValue;
215
+ };
216
+ if (formValuesMap) {
217
+ if (!props.name) {
218
+ warn('If a form component is used, the name attribute is required.');
219
+ }
220
+ else {
221
+ formValuesMap.set(props.name, { getValue, resetValue });
222
+ }
223
+ }
224
+ useEffect(() => {
225
+ return () => {
226
+ if (formValuesMap && props.name) {
227
+ formValuesMap.delete(props.name);
228
+ }
229
+ };
230
+ }, []);
231
+ useEffect(() => {
232
+ if (focus) {
233
+ setKeyboardAvoidContext();
234
+ }
235
+ }, [focus]);
236
+ useUpdateEffect(() => {
237
+ if (!nodeRef?.current) {
238
+ return;
239
+ }
240
+ focus
241
+ ? nodeRef.current?.focus()
242
+ : nodeRef.current?.blur();
243
+ }, [focus]);
244
+ const innerProps = useInnerProps(props, extendObject({
245
+ ref: nodeRef,
246
+ style: extendObject({}, normalStyle, layoutStyle),
247
+ allowFontScaling,
248
+ keyboardType: keyboardType,
249
+ secureTextEntry: !!password,
250
+ defaultValue: defaultValue,
251
+ value: inputValue,
252
+ maxLength: maxlength === -1 ? undefined : maxlength,
253
+ editable: !disabled,
254
+ autoFocus: !!autoFocus || !!focus,
255
+ returnKeyType: confirmType,
256
+ selection: selection,
257
+ selectionColor: cursorColor,
258
+ blurOnSubmit: !multiline && !confirmHold,
259
+ underlineColorAndroid: 'rgba(0,0,0,0)',
260
+ textAlignVertical: textAlignVertical,
261
+ placeholderTextColor: placeholderTextColor,
262
+ multiline: !!multiline
263
+ }, layoutProps, {
264
+ onTouchStart: onInputTouchStart,
265
+ onFocus: onInputFocus,
266
+ onBlur: onInputBlur,
267
+ onKeyPress: bindconfirm && onKeyPress,
268
+ onSubmitEditing: bindconfirm && multiline && onSubmitEditing,
269
+ onSelectionChange: onSelectionChange,
270
+ onTextInput: onTextInput,
271
+ onChange: onChange,
272
+ onContentSizeChange: onContentSizeChange
273
+ }), [
274
+ 'type',
275
+ 'password',
276
+ 'placeholder-style',
277
+ 'disabled',
278
+ 'auto-focus',
279
+ 'focus',
280
+ 'confirm-type',
281
+ 'confirm-hold',
282
+ 'cursor',
283
+ 'cursor-color',
284
+ 'selection-start',
285
+ 'selection-end'
286
+ ], {
287
+ layoutRef
288
+ });
289
+ return createElement(TextInput, innerProps);
290
+ });
291
+ Input.displayName = 'MpxInput';
292
+ export default Input;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * ✘ for
3
+ */
4
+ import { useRef, forwardRef, useCallback, createElement } from 'react';
5
+ import { View } from 'react-native';
6
+ import { noop, warn } from '@mpxjs/utils';
7
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
8
+ import useNodesRef from './useNodesRef';
9
+ import { splitProps, splitStyle, useLayout, useTransformStyle, wrapChildren, extendObject } from './utils';
10
+ import { LabelContext } from './context';
11
+ const Label = forwardRef((labelProps, ref) => {
12
+ const { textProps, innerProps: props = {} } = splitProps(labelProps);
13
+ const propsRef = useRef({});
14
+ const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
15
+ propsRef.current = props;
16
+ const defaultStyle = {
17
+ flexDirection: 'row'
18
+ };
19
+ const styleObj = extendObject({}, defaultStyle, style);
20
+ const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(styleObj, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
21
+ const nodeRef = useRef(null);
22
+ useNodesRef(props, ref, nodeRef, { style: normalStyle });
23
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef });
24
+ const { textStyle, backgroundStyle, innerStyle = {} } = splitStyle(normalStyle);
25
+ if (backgroundStyle) {
26
+ warn('Label does not support background image-related styles!');
27
+ }
28
+ const contextRef = useRef({
29
+ triggerChange: noop
30
+ });
31
+ const onTap = useCallback((evt) => {
32
+ const { bindtap } = propsRef.current;
33
+ bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, { props: propsRef.current }));
34
+ contextRef.current.triggerChange(evt);
35
+ }, []);
36
+ const innerProps = useInnerProps(props, extendObject({
37
+ ref: nodeRef,
38
+ style: extendObject({}, innerStyle, layoutStyle)
39
+ }, layoutProps, {
40
+ bindtap: onTap
41
+ }), [], {
42
+ layoutRef
43
+ });
44
+ return createElement(View, innerProps, createElement(LabelContext.Provider, { value: contextRef }, wrapChildren(props, {
45
+ hasVarDec,
46
+ varContext: varContextRef.current,
47
+ textStyle,
48
+ textProps
49
+ })));
50
+ });
51
+ Label.displayName = 'MpxLabel';
52
+ export default Label;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * ✘ scale-area
3
+ */
4
+ import { View } from 'react-native';
5
+ import { forwardRef, useRef, useMemo, createElement } from 'react';
6
+ import useNodesRef from './useNodesRef';
7
+ import useInnerProps from './getInnerListeners';
8
+ import { MovableAreaContext } from './context';
9
+ import { useTransformStyle, wrapChildren, useLayout, extendObject } from './utils';
10
+ const _MovableArea = forwardRef((props, ref) => {
11
+ const { style = {}, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props;
12
+ const { hasSelfPercent, normalStyle, hasVarDec, varContextRef, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight });
13
+ const movableViewRef = useRef(null);
14
+ useNodesRef(props, ref, movableViewRef, {
15
+ style: normalStyle
16
+ });
17
+ const contextValue = useMemo(() => ({
18
+ height: normalStyle.height || 10,
19
+ width: normalStyle.width || 10
20
+ }), [normalStyle.width, normalStyle.height]);
21
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef });
22
+ const innerProps = useInnerProps(props, extendObject({
23
+ style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
24
+ ref: movableViewRef
25
+ }, layoutProps), [], { layoutRef });
26
+ return createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(View, innerProps, wrapChildren(props, {
27
+ hasVarDec,
28
+ varContext: varContextRef.current
29
+ })));
30
+ });
31
+ _MovableArea.displayName = 'MpxMovableArea';
32
+ export default _MovableArea;