@mpxjs/webpack-plugin 2.9.59 → 2.9.62

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 (106) hide show
  1. package/lib/platform/style/wx/index.js +314 -254
  2. package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
  3. package/lib/platform/template/wx/component-config/checkbox.js +8 -0
  4. package/lib/platform/template/wx/component-config/cover-image.js +15 -0
  5. package/lib/platform/template/wx/component-config/cover-view.js +9 -0
  6. package/lib/platform/template/wx/component-config/form.js +13 -1
  7. package/lib/platform/template/wx/component-config/icon.js +8 -0
  8. package/lib/platform/template/wx/component-config/index.js +5 -1
  9. package/lib/platform/template/wx/component-config/label.js +15 -0
  10. package/lib/platform/template/wx/component-config/movable-area.js +18 -1
  11. package/lib/platform/template/wx/component-config/movable-view.js +18 -1
  12. package/lib/platform/template/wx/component-config/navigator.js +8 -0
  13. package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
  14. package/lib/platform/template/wx/component-config/picker-view.js +18 -2
  15. package/lib/platform/template/wx/component-config/picker.js +14 -1
  16. package/lib/platform/template/wx/component-config/radio-group.js +8 -0
  17. package/lib/platform/template/wx/component-config/radio.js +8 -0
  18. package/lib/platform/template/wx/component-config/root-portal.js +15 -0
  19. package/lib/platform/template/wx/component-config/switch.js +8 -0
  20. package/lib/platform/template/wx/component-config/unsupported.js +1 -3
  21. package/lib/react/processScript.js +2 -0
  22. package/lib/runtime/components/react/context.ts +38 -0
  23. package/lib/runtime/components/react/dist/context.js +7 -0
  24. package/lib/runtime/components/react/dist/getInnerListeners.js +22 -11
  25. package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
  26. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
  27. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
  28. package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
  29. package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
  30. package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
  31. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
  32. package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
  33. package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
  34. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
  35. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
  36. package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
  37. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
  38. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  45. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
  46. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
  47. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
  48. package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
  49. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
  50. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
  51. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
  52. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
  53. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
  54. package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
  55. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
  56. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  57. package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
  58. package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
  59. package/lib/runtime/components/react/dist/types/common.js +1 -0
  60. package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
  61. package/lib/runtime/components/react/dist/utils.js +82 -14
  62. package/lib/runtime/components/react/getInnerListeners.ts +25 -13
  63. package/lib/runtime/components/react/mpx-button.tsx +87 -67
  64. package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
  65. package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
  66. package/lib/runtime/components/react/mpx-form.tsx +89 -0
  67. package/lib/runtime/components/react/mpx-icon.tsx +103 -0
  68. package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
  69. package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
  70. package/lib/runtime/components/react/mpx-input.tsx +54 -26
  71. package/lib/runtime/components/react/mpx-label.tsx +115 -0
  72. package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
  73. package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
  74. package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
  75. package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
  76. package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
  77. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
  78. package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
  79. package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
  80. package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
  81. package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
  82. package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
  83. package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
  84. package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
  85. package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
  86. package/lib/runtime/components/react/mpx-radio.tsx +246 -0
  87. package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
  88. package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
  89. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
  90. package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
  91. package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
  92. package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
  93. package/lib/runtime/components/react/mpx-switch.tsx +127 -0
  94. package/lib/runtime/components/react/mpx-text.tsx +52 -68
  95. package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
  96. package/lib/runtime/components/react/mpx-view.tsx +373 -140
  97. package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
  98. package/lib/runtime/components/react/types/common.ts +12 -0
  99. package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
  100. package/lib/runtime/components/react/types/global.d.ts +4 -0
  101. package/lib/runtime/components/react/useNodesRef.ts +3 -8
  102. package/lib/runtime/components/react/utils.ts +93 -15
  103. package/lib/runtime/optionProcessor.js +19 -17
  104. package/lib/template-compiler/compiler.js +56 -41
  105. package/lib/template-compiler/gen-node-react.js +7 -7
  106. package/package.json +6 -3
@@ -4,7 +4,7 @@
4
4
  * ✔ plain
5
5
  * ✔ disabled
6
6
  * ✔ loading
7
- * form-type
7
+ * form-type
8
8
  * - open-type: Partially. Only support `share`、`getUserInfo`
9
9
  * ✔ hover-class: Convert hoverClass to hoverStyle.
10
10
  * ✔ hover-style
@@ -34,11 +34,13 @@
34
34
  * ✘ bindagreeprivacyauthorization
35
35
  * ✔ bindtap
36
36
  */
37
- import React, { useEffect, useRef, useState, forwardRef, } from 'react';
37
+ import { useEffect, useRef, useState, forwardRef, useContext } from 'react';
38
38
  import { View, Text, StyleSheet, Animated, Easing, } from 'react-native';
39
- import { extractTextStyle, isText, every } from './utils';
39
+ import { splitStyle, isText, every, splitProps, throwReactWarning, transformTextStyle } from './utils';
40
40
  import useInnerProps, { getCustomEvent } from './getInnerListeners';
41
41
  import useNodesRef from './useNodesRef';
42
+ import { FormContext } from './context';
43
+ import { isEmptyObject } from '@mpxjs/utils';
42
44
  const LOADING_IMAGE_URI = 'data:image/png;base64,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';
43
45
  const TypeColorMap = {
44
46
  default: ['#F8F8F8', '#DEDEDE', '35,35,35', '#F7F7F7'],
@@ -78,18 +80,18 @@ const styles = StyleSheet.create({
78
80
  const getOpenTypeEvent = (openType) => {
79
81
  // @ts-ignore
80
82
  if (!global?.__mpx?.config?.rnConfig) {
81
- console.warn('Environment not supported');
83
+ throwReactWarning('[Mpx runtime warn]: Environment not supported');
82
84
  return;
83
85
  }
84
86
  const eventName = OpenTypeEventsMap.get(openType);
85
87
  if (!eventName) {
86
- console.warn(`open-type not support ${openType}`);
88
+ throwReactWarning(`[Mpx runtime warn]: open-type not support ${openType}`);
87
89
  return;
88
90
  }
89
91
  // @ts-ignore
90
92
  const event = global.__mpx.config.rnConfig?.openTypeHandler?.[eventName];
91
93
  if (!event) {
92
- console.warn(`Unregistered ${eventName} event`);
94
+ throwReactWarning(`[Mpx runtime warn]: Unregistered ${eventName} event`);
93
95
  return;
94
96
  }
95
97
  return event;
@@ -122,7 +124,14 @@ const Loading = ({ alone = false }) => {
122
124
  return <Animated.Image testID="loading" style={loadingStyle} source={{ uri: LOADING_IMAGE_URI }}/>;
123
125
  };
124
126
  const Button = forwardRef((props, ref) => {
125
- const { size = 'default', type = 'default', plain = false, disabled = false, loading = false, 'hover-class': hoverClass, 'hover-style': hoverStyle = [], 'hover-start-time': hoverStartTime = 20, 'hover-stay-time': hoverStayTime = 70, 'open-type': openType, 'enable-offset': enableOffset, style = [], children, bindgetuserinfo, bindtap, catchtap, bindtouchstart, bindtouchend, } = props;
127
+ const { size = 'default', type = 'default', plain = false, disabled = false, loading = false, 'hover-class': hoverClass, 'hover-style': hoverStyle = {}, 'hover-start-time': hoverStartTime = 20, 'hover-stay-time': hoverStayTime = 70, 'open-type': openType, 'enable-offset': enableOffset, 'form-type': formType, style = {}, children, bindgetuserinfo, bindtap, bindtouchstart, bindtouchend, } = props;
128
+ const formContext = useContext(FormContext);
129
+ let submitFn;
130
+ let resetFn;
131
+ if (formContext) {
132
+ submitFn = formContext.submit;
133
+ resetFn = formContext.reset;
134
+ }
126
135
  const refs = useRef({
127
136
  hoverStartTimer: undefined,
128
137
  hoverStayTimer: undefined,
@@ -131,8 +140,11 @@ const Button = forwardRef((props, ref) => {
131
140
  const [isHover, setIsHover] = useState(false);
132
141
  const isMiniSize = size === 'mini';
133
142
  const applyHoverEffect = isHover && hoverClass !== 'none';
134
- const inheritTextStyle = extractTextStyle(style);
135
- const textHoverStyle = extractTextStyle(hoverStyle);
143
+ const { textStyle, imageStyle, innerStyle } = splitStyle(style);
144
+ const { textStyle: hoverTextStyle, imageStyle: hoverImageStyle, innerStyle: hoverInnerStyle } = splitStyle(hoverStyle);
145
+ if (imageStyle || hoverImageStyle) {
146
+ throwReactWarning('[Mpx runtime warn]: Button does not support background image-related styles!');
147
+ }
136
148
  const [color, hoverColor, plainColor, disabledColor] = TypeColorMap[type];
137
149
  const normalBackgroundColor = disabled ? disabledColor : applyHoverEffect || loading ? hoverColor : color;
138
150
  const plainBorderColor = disabled
@@ -155,18 +167,16 @@ const Button = forwardRef((props, ref) => {
155
167
  borderColor: plain ? plainBorderColor : normalBorderColor,
156
168
  backgroundColor: plain ? 'transparent' : normalBackgroundColor,
157
169
  };
158
- const textStyle = {
170
+ const defaultViewStyle = {
171
+ ...styles.button,
172
+ ...(isMiniSize && styles.buttonMini),
173
+ ...viewStyle,
174
+ };
175
+ const defaultTextStyle = {
176
+ ...styles.text,
177
+ ...(isMiniSize && styles.textMini),
159
178
  color: plain ? plainTextColor : normalTextColor,
160
- ...inheritTextStyle
161
179
  };
162
- const defaultViewStyle = [
163
- styles.button,
164
- isMiniSize && styles.buttonMini || {},
165
- viewStyle,
166
- ];
167
- const defaultTextStyle = [
168
- styles.text, isMiniSize && styles.textMini, textStyle
169
- ];
170
180
  const handleOpenTypeEvent = (evt) => {
171
181
  if (!openType)
172
182
  return;
@@ -177,11 +187,13 @@ const Button = forwardRef((props, ref) => {
177
187
  target: getCustomEvent('tap', evt, { layoutRef }, props).target,
178
188
  });
179
189
  }
180
- if (openType === 'getUserInfo') {
181
- const userInfo = handleEvent && handleEvent();
182
- if (typeof userInfo === 'object') {
183
- bindgetuserinfo && bindgetuserinfo(userInfo);
184
- }
190
+ if (openType === 'getUserInfo' && handleEvent && bindgetuserinfo) {
191
+ Promise.resolve(handleEvent)
192
+ .then((userInfo) => {
193
+ if (typeof userInfo === 'object') {
194
+ bindgetuserinfo(userInfo);
195
+ }
196
+ });
185
197
  }
186
198
  };
187
199
  const setStayTimer = () => {
@@ -210,32 +222,42 @@ const Button = forwardRef((props, ref) => {
210
222
  return;
211
223
  setStayTimer();
212
224
  };
225
+ const handleFormTypeFn = () => {
226
+ if (formType === 'submit') {
227
+ submitFn && submitFn();
228
+ }
229
+ else if (formType === 'reset') {
230
+ resetFn && resetFn();
231
+ }
232
+ };
213
233
  const onTap = (evt) => {
214
234
  if (disabled)
215
235
  return;
216
236
  bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props));
217
237
  handleOpenTypeEvent(evt);
238
+ handleFormTypeFn();
218
239
  };
219
- const catchTap = (evt) => {
220
- if (disabled)
221
- return;
222
- catchtap && catchtap(getCustomEvent('tap', evt, { layoutRef }, props));
223
- };
224
- function wrapChildren(children, textStyle) {
240
+ function wrapChildren(children, defaultTextStyle, textStyle) {
241
+ if (!children)
242
+ return children;
243
+ const hasTextStyle = !isEmptyObject(textStyle);
244
+ const { textProps } = splitProps(props);
225
245
  if (every(children, (child) => isText(child))) {
226
- children = [<Text key='buttonTextWrap' style={textStyle}>{children}</Text>];
246
+ transformTextStyle(textStyle);
247
+ children = <Text key='buttonTextWrap' style={{ ...defaultTextStyle, ...textStyle }} {...(textProps || {})}>{children}</Text>;
227
248
  }
228
249
  else {
229
- if (textStyle)
230
- console.warn('Text style will be ignored unless every child of the Button is Text node!');
250
+ if (hasTextStyle)
251
+ throwReactWarning('[Mpx runtime warn]: Text style will be ignored unless every child of the Button is Text node!');
231
252
  }
232
253
  return children;
233
254
  }
234
255
  const { nodeRef } = useNodesRef(props, ref, {
235
- defaultStyle: StyleSheet.flatten([
256
+ defaultStyle: {
236
257
  ...defaultViewStyle,
237
258
  ...defaultTextStyle,
238
- ])
259
+ ...textStyle
260
+ }
239
261
  });
240
262
  const onLayout = () => {
241
263
  nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
@@ -247,23 +269,23 @@ const Button = forwardRef((props, ref) => {
247
269
  bindtouchstart: onTouchStart,
248
270
  bindtouchend: onTouchEnd,
249
271
  bindtap: onTap,
250
- catchtap: catchTap,
251
272
  ...(enableOffset ? { onLayout } : {}),
252
273
  }, [
253
274
  'enable-offset'
254
275
  ], {
255
- layoutRef
276
+ layoutRef,
277
+ disableTap: disabled
256
278
  });
257
- return (<View {...innerProps} style={[
279
+ return (<View {...innerProps} style={{
258
280
  ...defaultViewStyle,
259
- style,
260
- applyHoverEffect && hoverStyle,
261
- ]}>
281
+ ...innerStyle,
282
+ ...(applyHoverEffect && hoverInnerStyle),
283
+ }}>
262
284
  {loading && <Loading alone={!children}/>}
263
- {wrapChildren(children, [
264
- ...defaultTextStyle,
265
- applyHoverEffect && textHoverStyle,
266
- ])}
285
+ {wrapChildren(children, defaultTextStyle, {
286
+ ...textStyle,
287
+ ...(applyHoverEffect && hoverTextStyle),
288
+ })}
267
289
  </View>);
268
290
  });
269
291
  Button.displayName = 'mpx-button';
@@ -0,0 +1,81 @@
1
+ /**
2
+ * ✔ bindchange
3
+ */
4
+ import { useRef, forwardRef, useContext } from 'react';
5
+ import { View } from 'react-native';
6
+ import { FormContext, CheckboxGroupContext } from './context';
7
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
8
+ import useNodesRef from './useNodesRef';
9
+ import { throwReactWarning } from './utils';
10
+ const CheckboxGroup = forwardRef((props, ref) => {
11
+ const { style = {}, 'enable-offset': enableOffset, children, bindchange } = props;
12
+ const layoutRef = useRef({});
13
+ const formContext = useContext(FormContext);
14
+ let formValuesMap;
15
+ if (formContext) {
16
+ formValuesMap = formContext.formValuesMap;
17
+ }
18
+ const groupValue = useRef({}).current;
19
+ const defaultStyle = {
20
+ flexDirection: 'row',
21
+ flexWrap: 'wrap',
22
+ ...style
23
+ };
24
+ const { nodeRef } = useNodesRef(props, ref, {
25
+ defaultStyle
26
+ });
27
+ const onLayout = () => {
28
+ nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
29
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
30
+ });
31
+ };
32
+ const getSelectionValue = () => {
33
+ const arr = [];
34
+ for (let key in groupValue) {
35
+ if (groupValue[key].checked) {
36
+ arr.push(key);
37
+ }
38
+ }
39
+ return arr;
40
+ };
41
+ const getValue = () => {
42
+ return getSelectionValue();
43
+ };
44
+ const resetValue = () => {
45
+ Object.keys(groupValue).forEach((key) => {
46
+ groupValue[key].checked = false;
47
+ groupValue[key].setValue(false);
48
+ });
49
+ };
50
+ if (formValuesMap) {
51
+ if (!props.name) {
52
+ throwReactWarning('[Mpx runtime warn]: If a form component is used, the name attribute is required.');
53
+ }
54
+ else {
55
+ formValuesMap.set(props.name, { getValue, resetValue });
56
+ }
57
+ }
58
+ const notifyChange = (evt) => {
59
+ bindchange &&
60
+ bindchange(getCustomEvent('tap', evt, {
61
+ layoutRef,
62
+ detail: {
63
+ value: getSelectionValue()
64
+ }
65
+ }, props));
66
+ };
67
+ const innerProps = useInnerProps(props, {
68
+ ref: nodeRef,
69
+ style: defaultStyle,
70
+ ...(enableOffset ? { onLayout } : {})
71
+ }, ['enable-offset'], {
72
+ layoutRef
73
+ });
74
+ return (<View {...innerProps}>
75
+ <CheckboxGroupContext.Provider value={{ groupValue, notifyChange }}>
76
+ {children}
77
+ </CheckboxGroupContext.Provider>
78
+ </View>);
79
+ });
80
+ CheckboxGroup.displayName = 'mpx-checkbox-group';
81
+ export default CheckboxGroup;
@@ -0,0 +1,152 @@
1
+ /**
2
+ * ✔ value
3
+ * ✔ disabled
4
+ * ✔ checked
5
+ * ✔ color
6
+ */
7
+ import { useRef, useState, forwardRef, useEffect, useContext } from 'react';
8
+ import { View, Text, StyleSheet } from 'react-native';
9
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
10
+ import useNodesRef from './useNodesRef';
11
+ import Icon from './mpx-icon';
12
+ import { every, splitStyle, isText, splitProps, throwReactWarning } from './utils';
13
+ import { CheckboxGroupContext, LabelContext } from './context';
14
+ const styles = StyleSheet.create({
15
+ container: {
16
+ flexDirection: 'row',
17
+ alignItems: 'center'
18
+ },
19
+ wrapper: {
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ width: 24,
23
+ height: 24,
24
+ borderColor: '#D1D1D1',
25
+ borderWidth: 1,
26
+ borderRadius: 3,
27
+ backgroundColor: '#ffffff',
28
+ marginRight: 5
29
+ },
30
+ wrapperDisabled: {
31
+ backgroundColor: '#E1E1E1'
32
+ },
33
+ icon: {
34
+ opacity: 0
35
+ },
36
+ iconChecked: {
37
+ opacity: 1
38
+ }
39
+ });
40
+ const Checkbox = forwardRef((props, ref) => {
41
+ const { value = '', disabled = false, checked = false, color = '#09BB07', style = {}, 'enable-offset': enableOffset, children, bindtap, catchtap, } = props;
42
+ const layoutRef = useRef({});
43
+ const [isChecked, setIsChecked] = useState(!!checked);
44
+ const { textStyle, imageStyle, innerStyle } = splitStyle(style);
45
+ if (imageStyle) {
46
+ throwReactWarning('[Mpx runtime warn]: Checkbox does not support background image-related styles!');
47
+ }
48
+ const groupContext = useContext(CheckboxGroupContext);
49
+ let groupValue;
50
+ let notifyChange;
51
+ const defaultStyle = {
52
+ ...styles.wrapper,
53
+ ...(disabled && styles.wrapperDisabled),
54
+ };
55
+ const viewStyle = {
56
+ ...defaultStyle,
57
+ ...innerStyle
58
+ };
59
+ const onChange = (evt) => {
60
+ if (disabled)
61
+ return;
62
+ const checked = !isChecked;
63
+ setIsChecked(checked);
64
+ if (groupValue) {
65
+ groupValue[value].checked = checked;
66
+ }
67
+ notifyChange && notifyChange(evt);
68
+ };
69
+ const onTap = (evt) => {
70
+ if (disabled)
71
+ return;
72
+ bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, props));
73
+ onChange(evt);
74
+ };
75
+ const catchTap = (evt) => {
76
+ if (disabled)
77
+ return;
78
+ catchtap && catchtap(getCustomEvent('tap', evt, { layoutRef }, props));
79
+ onChange(evt);
80
+ };
81
+ const { nodeRef } = useNodesRef(props, ref, {
82
+ defaultStyle,
83
+ change: onChange
84
+ });
85
+ const onLayout = () => {
86
+ nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
87
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
88
+ });
89
+ };
90
+ const wrapChildren = (children, textStyle) => {
91
+ if (!children)
92
+ return children;
93
+ const { textProps } = splitProps(props);
94
+ if (every(children, (child) => isText(child))) {
95
+ if (textStyle || textProps) {
96
+ children = <Text key='checkboxTextWrap' style={textStyle || {}} {...(textProps || {})}>{children}</Text>;
97
+ }
98
+ }
99
+ else {
100
+ if (textStyle) {
101
+ throwReactWarning('[Mpx runtime warn]: Text style will be ignored unless every child of the Checkbox is Text node!');
102
+ }
103
+ }
104
+ return children;
105
+ };
106
+ const labelContext = useContext(LabelContext);
107
+ if (groupContext) {
108
+ groupValue = groupContext.groupValue;
109
+ notifyChange = groupContext.notifyChange;
110
+ }
111
+ if (labelContext) {
112
+ labelContext.current.triggerChange = onChange;
113
+ }
114
+ const innerProps = useInnerProps(props, {
115
+ ref: nodeRef,
116
+ style: styles.container,
117
+ bindtap: onTap,
118
+ catchtap: catchTap,
119
+ ...(enableOffset ? { onLayout } : {})
120
+ }, ['enable-offset'], {
121
+ layoutRef
122
+ });
123
+ useEffect(() => {
124
+ if (groupValue) {
125
+ groupValue[value] = {
126
+ checked: checked,
127
+ setValue: setIsChecked
128
+ };
129
+ }
130
+ return () => {
131
+ if (groupValue) {
132
+ delete groupValue[value];
133
+ }
134
+ };
135
+ }, []);
136
+ useEffect(() => {
137
+ if (checked !== isChecked) {
138
+ setIsChecked(checked);
139
+ if (groupValue) {
140
+ groupValue[value].checked = checked;
141
+ }
142
+ }
143
+ }, [checked]);
144
+ return (<View {...innerProps}>
145
+ <View style={viewStyle}>
146
+ <Icon type='success_no_circle' size={18} color={disabled ? '#ADADAD' : color} style={isChecked ? styles.iconChecked : styles.icon}/>
147
+ </View>
148
+ {wrapChildren(children, textStyle)}
149
+ </View>);
150
+ });
151
+ Checkbox.displayName = 'mpx-checkbox';
152
+ export default Checkbox;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * ✘ report-submit
3
+ * ✘ report-submit-timeout
4
+ * ✔ bindsubmit
5
+ * ✔ bindreset
6
+ */
7
+ import { View } from 'react-native';
8
+ import { useRef, forwardRef } from 'react';
9
+ import useNodesRef from './useNodesRef';
10
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
11
+ import { FormContext } from './context';
12
+ const _Form = forwardRef((props, ref) => {
13
+ const { children, style } = props;
14
+ const layoutRef = useRef({});
15
+ const formValuesMap = useRef(new Map()).current;
16
+ const { nodeRef: formRef } = useNodesRef(props, ref);
17
+ const onLayout = (e) => {
18
+ formRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
19
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
20
+ });
21
+ };
22
+ const submit = () => {
23
+ const { bindsubmit } = props;
24
+ const formValue = {};
25
+ for (let name of formValuesMap.keys()) {
26
+ if (formValuesMap.get(name).getValue) {
27
+ formValue[name] = formValuesMap.get(name).getValue();
28
+ }
29
+ }
30
+ bindsubmit && bindsubmit(getCustomEvent('submit', {}, {
31
+ detail: {
32
+ value: formValue
33
+ },
34
+ layoutRef
35
+ }, props));
36
+ };
37
+ const reset = () => {
38
+ const { bindreset } = props;
39
+ bindreset && bindreset();
40
+ formValuesMap.forEach(item => item.resetValue());
41
+ };
42
+ const innerProps = useInnerProps(props, {
43
+ ref: formRef,
44
+ style,
45
+ onLayout
46
+ }, [
47
+ 'children',
48
+ 'style',
49
+ 'bindsubmit',
50
+ 'bindreset'
51
+ ], { layoutRef });
52
+ return (<View {...innerProps}>
53
+ <FormContext.Provider value={{ formValuesMap, submit, reset }}>
54
+ {children}
55
+ </FormContext.Provider>
56
+ </View>);
57
+ });
58
+ _Form.displayName = 'mpx-form';
59
+ export default _Form;