@mpxjs/webpack-plugin 2.9.58 → 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 (109) hide show
  1. package/lib/config.js +1 -3
  2. package/lib/platform/style/wx/index.js +374 -239
  3. package/lib/platform/template/wx/component-config/checkbox-group.js +8 -0
  4. package/lib/platform/template/wx/component-config/checkbox.js +8 -0
  5. package/lib/platform/template/wx/component-config/cover-image.js +15 -0
  6. package/lib/platform/template/wx/component-config/cover-view.js +9 -0
  7. package/lib/platform/template/wx/component-config/form.js +13 -1
  8. package/lib/platform/template/wx/component-config/icon.js +8 -0
  9. package/lib/platform/template/wx/component-config/index.js +5 -1
  10. package/lib/platform/template/wx/component-config/label.js +15 -0
  11. package/lib/platform/template/wx/component-config/movable-area.js +18 -1
  12. package/lib/platform/template/wx/component-config/movable-view.js +18 -1
  13. package/lib/platform/template/wx/component-config/navigator.js +8 -0
  14. package/lib/platform/template/wx/component-config/picker-view-column.js +8 -0
  15. package/lib/platform/template/wx/component-config/picker-view.js +18 -2
  16. package/lib/platform/template/wx/component-config/picker.js +14 -1
  17. package/lib/platform/template/wx/component-config/radio-group.js +8 -0
  18. package/lib/platform/template/wx/component-config/radio.js +8 -0
  19. package/lib/platform/template/wx/component-config/root-portal.js +15 -0
  20. package/lib/platform/template/wx/component-config/switch.js +8 -0
  21. package/lib/platform/template/wx/component-config/unsupported.js +1 -3
  22. package/lib/react/processScript.js +7 -1
  23. package/lib/react/style-helper.js +10 -1
  24. package/lib/runtime/components/react/context.ts +38 -0
  25. package/lib/runtime/components/react/dist/context.js +7 -0
  26. package/lib/runtime/components/react/dist/getInnerListeners.js +24 -13
  27. package/lib/runtime/components/react/dist/mpx-button.jsx +67 -45
  28. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +81 -0
  29. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +152 -0
  30. package/lib/runtime/components/react/dist/mpx-form.jsx +59 -0
  31. package/lib/runtime/components/react/dist/mpx-icon.jsx +51 -0
  32. package/lib/runtime/components/react/dist/mpx-image/index.jsx +17 -22
  33. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +0 -1
  34. package/lib/runtime/components/react/dist/mpx-input.jsx +38 -16
  35. package/lib/runtime/components/react/dist/mpx-label.jsx +63 -0
  36. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +46 -0
  37. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
  38. package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
  39. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
  40. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +139 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +90 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
  45. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
  46. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  47. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +15 -0
  48. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +68 -0
  49. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +79 -0
  50. package/lib/runtime/components/react/dist/mpx-radio.jsx +169 -0
  51. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +11 -0
  52. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +66 -50
  53. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +206 -147
  54. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +9 -7
  55. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +3 -3
  56. package/lib/runtime/components/react/dist/mpx-switch.jsx +76 -0
  57. package/lib/runtime/components/react/dist/mpx-text.jsx +7 -19
  58. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  59. package/lib/runtime/components/react/dist/mpx-view.jsx +326 -96
  60. package/lib/runtime/components/react/dist/mpx-web-view.jsx +9 -15
  61. package/lib/runtime/components/react/dist/types/common.js +1 -0
  62. package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
  63. package/lib/runtime/components/react/dist/utils.js +83 -15
  64. package/lib/runtime/components/react/getInnerListeners.ts +27 -15
  65. package/lib/runtime/components/react/mpx-button.tsx +87 -67
  66. package/lib/runtime/components/react/mpx-checkbox-group.tsx +147 -0
  67. package/lib/runtime/components/react/mpx-checkbox.tsx +245 -0
  68. package/lib/runtime/components/react/mpx-form.tsx +89 -0
  69. package/lib/runtime/components/react/mpx-icon.tsx +103 -0
  70. package/lib/runtime/components/react/mpx-image/index.tsx +20 -32
  71. package/lib/runtime/components/react/mpx-image/svg.tsx +2 -2
  72. package/lib/runtime/components/react/mpx-input.tsx +54 -26
  73. package/lib/runtime/components/react/mpx-label.tsx +115 -0
  74. package/lib/runtime/components/react/mpx-movable-area.tsx +67 -0
  75. package/lib/runtime/components/react/mpx-movable-view.tsx +425 -0
  76. package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
  77. package/lib/runtime/components/react/mpx-picker/date.tsx +83 -0
  78. package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
  79. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +153 -0
  80. package/lib/runtime/components/react/mpx-picker/region.tsx +104 -0
  81. package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
  82. package/lib/runtime/components/react/mpx-picker/selector.tsx +92 -0
  83. package/lib/runtime/components/react/mpx-picker/time.tsx +274 -0
  84. package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
  85. package/lib/runtime/components/react/mpx-picker-view-column.tsx +28 -0
  86. package/lib/runtime/components/react/mpx-picker-view.tsx +104 -0
  87. package/lib/runtime/components/react/mpx-radio-group.tsx +147 -0
  88. package/lib/runtime/components/react/mpx-radio.tsx +246 -0
  89. package/lib/runtime/components/react/mpx-root-portal.tsx +25 -0
  90. package/lib/runtime/components/react/mpx-scroll-view.tsx +82 -58
  91. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +203 -156
  92. package/lib/runtime/components/react/mpx-swiper/index.tsx +12 -13
  93. package/lib/runtime/components/react/mpx-swiper/type.ts +11 -4
  94. package/lib/runtime/components/react/mpx-swiper-item.tsx +5 -3
  95. package/lib/runtime/components/react/mpx-switch.tsx +127 -0
  96. package/lib/runtime/components/react/mpx-text.tsx +52 -68
  97. package/lib/runtime/components/react/mpx-textarea.tsx +2 -2
  98. package/lib/runtime/components/react/mpx-view.tsx +374 -141
  99. package/lib/runtime/components/react/mpx-web-view.tsx +24 -28
  100. package/lib/runtime/components/react/types/common.ts +12 -0
  101. package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
  102. package/lib/runtime/components/react/types/global.d.ts +4 -0
  103. package/lib/runtime/components/react/useNodesRef.ts +3 -8
  104. package/lib/runtime/components/react/utils.ts +94 -16
  105. package/lib/runtime/optionProcessor.js +19 -17
  106. package/lib/template-compiler/compiler.js +73 -44
  107. package/lib/template-compiler/gen-node-react.js +7 -7
  108. package/lib/utils/shallow-stringify.js +1 -1
  109. package/package.json +6 -3
@@ -0,0 +1,425 @@
1
+ /**
2
+ * ✔ direction
3
+ * ✘ inertia
4
+ * ✘ out-of-bounds
5
+ * ✔ x
6
+ * ✔ y
7
+ * ✘ damping
8
+ * ✔ friction
9
+ * ✔ disabled
10
+ * ✔ scale
11
+ * ✔ scale-min
12
+ * ✔ scale-max
13
+ * ✔ scale-value
14
+ * ✘ animation
15
+ * ✔ bindchange
16
+ * ✔ bindscale
17
+ * ✔ htouchmove
18
+ * ✔ vtouchmove
19
+ */
20
+ import { useRef, useEffect, forwardRef, ReactNode, useContext, useState, useMemo } from 'react';
21
+ import { StyleSheet, Animated, NativeSyntheticEvent, PanResponder, View } from 'react-native';
22
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
23
+ import useNodesRef, { HandlerRef } from './useNodesRef'
24
+ import { MovableAreaContext } from './context'
25
+
26
+ interface MovableViewProps {
27
+ children: ReactNode;
28
+ style?: Record<string, any>;
29
+ direction: 'all' | 'vertical' | 'horizontal' | 'none';
30
+ x?: string | number;
31
+ y?: string | number;
32
+ scale?: boolean;
33
+ disabled?: boolean;
34
+ friction?: number;
35
+ 'scale-value'?: number;
36
+ 'scale-min'?: number;
37
+ 'scale-max'?: number;
38
+ bindchange?: (event: unknown) => void;
39
+ bindscale?: (event: unknown) => void;
40
+ bindtouchstart?: (event: NativeSyntheticEvent<TouchEvent>) => void;
41
+ bindtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
42
+ catchtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
43
+ bindtouchend?: (event: NativeSyntheticEvent<TouchEvent>) => void;
44
+ bindhtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
45
+ bindvtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
46
+ catchhtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
47
+ catchvtouchmove?: (event: NativeSyntheticEvent<TouchEvent>) => void;
48
+ }
49
+ const styles = StyleSheet.create({
50
+ container: {
51
+ position: 'absolute',
52
+ left: 0,
53
+ top: 0
54
+ },
55
+ })
56
+
57
+ const _MovableView = forwardRef<HandlerRef<View, MovableViewProps>, MovableViewProps>((props: MovableViewProps, ref): JSX.Element => {
58
+ const {
59
+ children,
60
+ friction = 7,
61
+ scale = false,
62
+ direction = 'none',
63
+ x = 0,
64
+ y = 0,
65
+ style = {},
66
+ 'scale-min': scaleMin = 0.1,
67
+ 'scale-max': scaleMax = 10,
68
+ 'scale-value': originScaleValue = 1,
69
+ bindscale,
70
+ bindchange
71
+ } = props
72
+
73
+ const pan = useRef<any>(new Animated.ValueXY())
74
+ const scaleValue = useRef<any>(new Animated.Value(1))
75
+ const [transformOrigin, setTransformOrigin] = useState('0% 0%')
76
+
77
+ const propsRef = useRef<any>({})
78
+ const layoutRef = useRef<any>({})
79
+
80
+ const MovableAreaLayout = useContext(MovableAreaContext)
81
+
82
+ const movablePosition = useRef({
83
+ x: Number(x),
84
+ y: Number(y)
85
+ })
86
+
87
+ const { nodeRef } = useNodesRef(props, ref, {
88
+ defaultStyle: styles.container
89
+ })
90
+
91
+ let panResponder: any = {}
92
+
93
+ let isFirstTouch = useRef<boolean>(true)
94
+ let touchEvent = useRef<string>('')
95
+ let initialDistance = useRef<number>(0)
96
+
97
+ propsRef.current = props
98
+
99
+ useEffect(() => {
100
+ if (scale && (scaleValue.current._value !== originScaleValue)) {
101
+ const clampedScale = Math.min(scaleMax, Math.max(scaleMin, originScaleValue))
102
+ Animated.spring(scaleValue.current, {
103
+ toValue: clampedScale,
104
+ friction,
105
+ useNativeDriver: false,
106
+ }).start(() => {
107
+ bindscale && bindscale(getCustomEvent('scale', {}, {
108
+ detail: {
109
+ x: pan.current.x._value,
110
+ y: pan.current.y._value,
111
+ scale: clampedScale
112
+ },
113
+ layoutRef
114
+ }, props)
115
+ )
116
+ })
117
+ }
118
+ }, [originScaleValue]);
119
+
120
+ useEffect(() => {
121
+ if (movablePosition.current.x !== Number(x) || movablePosition.current.y !== Number(y)) {
122
+ const { x: newX, y: newY } = checkBoundaryPosition({
123
+ clampedScale: scaleValue.current._value,
124
+ width: layoutRef.current.width,
125
+ height: layoutRef.current.height,
126
+ positionX: Number(x),
127
+ positionY: Number(y)
128
+ })
129
+ movablePosition.current = { x: newX, y: newY }
130
+ Animated.spring(pan.current, {
131
+ toValue: { x: newX, y: newY },
132
+ useNativeDriver: false,
133
+ friction
134
+ }).start(() => {
135
+ bindchange &&
136
+ bindchange(
137
+ getCustomEvent('change', {}, {
138
+ detail: {
139
+ x: newX,
140
+ y: newY,
141
+ source: ''
142
+ },
143
+ layoutRef
144
+ }, props)
145
+ );
146
+ })
147
+ }
148
+ }, [x, y])
149
+
150
+ const handlePanReleaseOrTerminate = () => {
151
+ pan.current.flattenOffset()
152
+ isFirstTouch.current = true
153
+ initialDistance.current = 0
154
+ const { x, y } = checkBoundaryPosition({
155
+ clampedScale: scaleValue.current._value,
156
+ width: layoutRef.current.width,
157
+ height: layoutRef.current.height,
158
+ positionX: pan.current.x._value,
159
+ positionY: pan.current.y._value
160
+ })
161
+ movablePosition.current = {
162
+ x,
163
+ y
164
+ }
165
+ const needChange = x !== pan.current.x._value || y !== pan.current.y._value
166
+
167
+ Animated.spring(pan.current, {
168
+ toValue: { x, y },
169
+ friction: 7,
170
+ useNativeDriver: false
171
+ }).start(() => {
172
+ if (needChange) {
173
+ bindchange && bindchange(
174
+ getCustomEvent('change', {}, {
175
+ detail: {
176
+ x,
177
+ y,
178
+ source: 'out-of-bounds'
179
+ },
180
+ layoutRef
181
+ }, propsRef.current)
182
+ )
183
+ }
184
+ })
185
+ }
186
+
187
+ panResponder = useMemo(() => {
188
+ return PanResponder.create({
189
+ onMoveShouldSetPanResponder: () => !propsRef.current.disabled,
190
+ onMoveShouldSetPanResponderCapture: () => !propsRef.current.disabled,
191
+ onPanResponderGrant: (e, gestureState) => {
192
+ if (gestureState.numberActiveTouches === 1) {
193
+ setTransformOrigin('0% 0%')
194
+ pan.current.setOffset({
195
+ x: direction === 'all' || direction === 'horizontal' ? pan.current.x._value : 0,
196
+ y: direction === 'all' || direction === 'vertical' ? pan.current.y._value : 0
197
+ });
198
+ pan.current.setValue({ x: 0, y: 0 });
199
+ } else {
200
+ initialDistance.current = 0;
201
+ setTransformOrigin('50% 50%')
202
+ }
203
+ },
204
+ onPanResponderMove: (e, gestureState) => {
205
+ if (gestureState.numberActiveTouches === 2 && scale) {
206
+ setTransformOrigin('50% 50%')
207
+ const touch1 = e.nativeEvent.touches[0];
208
+ const touch2 = e.nativeEvent.touches[1];
209
+ const currentTouchDistance = Math.sqrt(
210
+ Math.pow(touch1.pageX - touch2.pageX, 2) + Math.pow(touch1.pageY - touch2.pageY, 2)
211
+ )
212
+
213
+ if (!initialDistance.current) {
214
+ initialDistance.current = currentTouchDistance;
215
+ } else {
216
+ const newScale = currentTouchDistance / initialDistance.current
217
+ const clampedScale = Math.min(scaleMax, Math.max(scaleMin, newScale))
218
+
219
+
220
+ Animated.spring(scaleValue.current, {
221
+ toValue: clampedScale,
222
+ friction: 7,
223
+ useNativeDriver: false
224
+ }).start();
225
+ bindscale && bindscale(getCustomEvent('scale', e, {
226
+ detail: {
227
+ x: pan.current.x._value,
228
+ y: pan.current.y._value,
229
+ scale: clampedScale
230
+ },
231
+ layoutRef
232
+ }, propsRef.current));
233
+ }
234
+ } else if (gestureState.numberActiveTouches === 1) {
235
+ if (initialDistance.current) {
236
+ return; // Skip processing if it's switching from a double touch
237
+ }
238
+ setTransformOrigin('0% 0%')
239
+ if (isFirstTouch.current) {
240
+ touchEvent.current = Math.abs(gestureState.dx) > Math.abs(gestureState.dy) ? 'htouchmove' : 'vtouchmove'
241
+ isFirstTouch.current = false;
242
+ }
243
+ Animated.event(
244
+ [
245
+ null,
246
+ {
247
+ dx: direction === 'all' || direction === 'horizontal' ? pan.current.x : new Animated.Value(0),
248
+ dy: direction === 'all' || direction === 'vertical' ? pan.current.y : new Animated.Value(0),
249
+ }
250
+ ],
251
+ {
252
+ useNativeDriver: false
253
+ }
254
+ )(e, gestureState);
255
+
256
+ movablePosition.current = {
257
+ x: pan.current.x.__getValue(),
258
+ y: pan.current.y.__getValue()
259
+ }
260
+ bindchange && bindchange(
261
+ getCustomEvent('change', e, {
262
+ detail: {
263
+ x: movablePosition.current.x,
264
+ y: movablePosition.current.y,
265
+ source: 'touch'
266
+ },
267
+ layoutRef
268
+ }, propsRef.current)
269
+ )
270
+ }
271
+ },
272
+ onPanResponderRelease: () => {
273
+ handlePanReleaseOrTerminate()
274
+ },
275
+ onPanResponderTerminate: () => {
276
+ handlePanReleaseOrTerminate()
277
+ }
278
+ })
279
+ }, [MovableAreaLayout.width, MovableAreaLayout.height])
280
+
281
+ const onLayout = () => {
282
+ nodeRef.current?.measure((x: number, y: number, width: number, height: number) => {
283
+ layoutRef.current = { x, y, width, height, offsetLeft: 0, offsetTop: 0 }
284
+ const clampedScale = Math.min(scaleMax, Math.max(scaleMin, originScaleValue))
285
+ const { x: newX, y: nexY } = checkBoundaryPosition({
286
+ clampedScale,
287
+ width,
288
+ height,
289
+ positionX: movablePosition.current.x,
290
+ positionY: movablePosition.current.y
291
+ })
292
+
293
+ Animated.spring(pan.current, {
294
+ toValue: { x: newX, y: nexY },
295
+ useNativeDriver: false,
296
+ friction
297
+ }).start(() => {
298
+ movablePosition.current = { x: newX, y: nexY }
299
+ bindchange &&
300
+ bindchange(
301
+ getCustomEvent('change', {}, {
302
+ detail: {
303
+ x: newX,
304
+ y: nexY,
305
+ source: ''
306
+ },
307
+ layoutRef
308
+ }, props)
309
+ )
310
+ })
311
+ })
312
+ }
313
+
314
+ const onTouchMove = (e: NativeSyntheticEvent<TouchEvent>) => {
315
+ const { bindhtouchmove, bindvtouchmove, bindtouchmove } = props
316
+ if (touchEvent.current === 'htouchmove') {
317
+ bindhtouchmove && bindhtouchmove(e)
318
+ } else if (touchEvent.current === 'vtouchmove') {
319
+ bindvtouchmove && bindvtouchmove(e)
320
+ }
321
+ bindtouchmove && bindtouchmove(e)
322
+ }
323
+
324
+ const onCatchTouchMove = (e: NativeSyntheticEvent<TouchEvent>) => {
325
+ const { catchhtouchmove, catchvtouchmove, catchtouchmove } = props
326
+ if (touchEvent.current === 'htouchmove') {
327
+ catchhtouchmove && catchhtouchmove(e)
328
+ } else if (touchEvent.current === 'vtouchmove') {
329
+ catchvtouchmove && catchvtouchmove(e)
330
+ }
331
+ catchtouchmove && catchtouchmove(e)
332
+ }
333
+
334
+ const checkBoundaryPosition = ({ clampedScale, width, height, positionX, positionY }: { clampedScale: number; width: number; height: number; positionX: number; positionY: number }) => {
335
+ // Calculate scaled element size
336
+ const scaledWidth = width * clampedScale
337
+ const scaledHeight = height * clampedScale
338
+
339
+ // Calculate the boundary limits
340
+ let x = positionX
341
+ let y = positionY
342
+
343
+ // Correct y coordinate
344
+ if (scaledHeight > MovableAreaLayout.height) {
345
+ if (y >= 0) {
346
+ y = 0
347
+ } else if (y < MovableAreaLayout.height - scaledHeight) {
348
+ y = MovableAreaLayout.height - scaledHeight
349
+ }
350
+ } else {
351
+ if (y < 0) {
352
+ y = 0
353
+ } else if (y > MovableAreaLayout.height - scaledHeight) {
354
+ y = MovableAreaLayout.height - scaledHeight
355
+ }
356
+ }
357
+ // Correct x coordinate
358
+ if (scaledWidth > MovableAreaLayout.width) {
359
+ if (x >= 0) {
360
+ x = 0
361
+ } else if (x < MovableAreaLayout.width - scaledWidth) {
362
+ x = MovableAreaLayout.width - scaledWidth
363
+ }
364
+ } else {
365
+ if (x < 0) {
366
+ x = 0
367
+ } else if (x > MovableAreaLayout.width - scaledWidth) {
368
+ x = MovableAreaLayout.width - scaledWidth
369
+ }
370
+ }
371
+
372
+ return {
373
+ x,
374
+ y
375
+ }
376
+ }
377
+
378
+ const [translateX, translateY] = [pan.current.x, pan.current.y];
379
+
380
+ const transformStyle = { transform: [{ translateX }, { translateY }, { scale: scaleValue.current }], transformOrigin: transformOrigin }
381
+
382
+ const hasTouchmove = () => !!props.bindhtouchmove || !!props.bindvtouchmove || !!props.bindtouchmove
383
+
384
+ const hasCatchTouchmove = () => !!props.catchhtouchmove || !!props.catchvtouchmove || !!props.catchtouchmove
385
+
386
+ const innerProps = useInnerProps(props, {
387
+ ref: nodeRef,
388
+ ...panResponder.panHandlers,
389
+ onLayout,
390
+ ...(hasTouchmove() ? { 'bindtouchmove': onTouchMove } : {}),
391
+ ...(hasCatchTouchmove() ? { 'catchtouchmove': onCatchTouchMove } : {}),
392
+ }, [
393
+ 'children',
394
+ 'style',
395
+ 'direction',
396
+ 'x',
397
+ 'y',
398
+ 'scale',
399
+ 'disabled',
400
+ 'scale-value',
401
+ 'scale-min',
402
+ 'scale-max',
403
+ 'bindchange',
404
+ 'bindscale',
405
+ 'htouchmove',
406
+ 'vtouchmove'
407
+ ], { layoutRef })
408
+
409
+ return (
410
+ <Animated.View
411
+ {...innerProps}
412
+ style={{
413
+ ...styles.container,
414
+ ...style,
415
+ ...transformStyle
416
+ }}
417
+ >
418
+ {children}
419
+ </Animated.View>
420
+ );
421
+ })
422
+
423
+ _MovableView.displayName = 'mpx-movable-view'
424
+
425
+ export default _MovableView
@@ -0,0 +1,67 @@
1
+ /**
2
+ * ✔ hover-class
3
+ * ✘ hover-stop-propagation
4
+ * ✔ hover-start-time
5
+ * ✔ hover-stay-time
6
+ * ✔ open-type
7
+ * ✔ url
8
+ * ✔ delta
9
+ */
10
+ import { View } from 'react-native'
11
+ import { useCallback, forwardRef, JSX } from 'react';
12
+ import useInnerProps from './getInnerListeners'
13
+ import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
14
+
15
+ import MpxView, { _ViewProps } from './mpx-view'
16
+
17
+ interface _NavigatorProps extends _ViewProps {
18
+ ['open-type']: 'navigate' | 'redirect' | 'switchTab' | 'reLaunch' | 'navigateBack'
19
+ url: string
20
+ delta: number
21
+ }
22
+
23
+ const _Navigator = forwardRef<View, _NavigatorProps>((props, ref): JSX.Element => {
24
+ const {
25
+ children,
26
+ 'open-type': openType,
27
+ url,
28
+ delta
29
+ } = props
30
+
31
+ const handleClick = useCallback(() => {
32
+ switch (openType) {
33
+ case 'navigateBack':
34
+ navigateBack({ delta })
35
+ break
36
+ case 'redirect':
37
+ redirectTo({ url })
38
+ break
39
+ case 'switchTab':
40
+ switchTab({ url })
41
+ break
42
+ case 'reLaunch':
43
+ reLaunch({ url })
44
+ break
45
+ default:
46
+ navigateTo({ url })
47
+ break
48
+ }
49
+ }, [openType, url, delta])
50
+
51
+ const innerProps = useInnerProps(props, {
52
+ ref,
53
+ bindtap: handleClick
54
+ })
55
+
56
+ return (
57
+ <MpxView
58
+ {...innerProps}
59
+ >
60
+ {children}
61
+ </MpxView>
62
+ )
63
+ })
64
+
65
+ _Navigator.displayName = 'mpx-navigator'
66
+
67
+ export default _Navigator
@@ -0,0 +1,83 @@
1
+ import { View, TouchableWithoutFeedback } from 'react-native'
2
+ import { DatePicker } from '@ant-design/react-native'
3
+ import React, { forwardRef, useState, useRef, useEffect } from 'react'
4
+ import useNodesRef, { HandlerRef } from '../useNodesRef' // 引入辅助函数
5
+ import { DateProps, LayoutType } from './type'
6
+
7
+ function formatTimeStr(time = ''): Date {
8
+ let [year, month, day]: any = time.split('-')
9
+ year = ~~year || 2000
10
+ month = ~~month || 1
11
+ day = ~~day || 1
12
+ return new Date(year, month - 1, day)
13
+ }
14
+
15
+ function dateToString (date: Date, fields: 'day' | 'month' | 'year' = 'day'): string {
16
+ const yyyy: string = date.getFullYear() + ''
17
+ const MM: string = ('0' + (date.getMonth() + 1)).slice(-2)
18
+ const dd: string = ('0' + date.getDate()).slice(-2)
19
+ let ret: string = yyyy
20
+ if (fields === 'month' || fields === 'day') {
21
+ ret += `-${MM}`
22
+ if (fields === 'day') {
23
+ ret += `-${dd}`
24
+ }
25
+ }
26
+ return ret
27
+ }
28
+
29
+
30
+ const _DatePicker = forwardRef<HandlerRef<View, DateProps>, DateProps>((props: DateProps, ref): React.JSX.Element => {
31
+ const { children, start = '1970-01-01', end = '2999-01-01', value, bindchange, bindcancel, disabled, fields } = props
32
+ const [datevalue, setDateValue] = useState(value)
33
+ // 存储layout布局信息
34
+ const layoutRef = useRef({})
35
+ const { nodeRef: viewRef } = useNodesRef<View, DateProps>(props, ref, {
36
+ })
37
+
38
+ useEffect(() => {
39
+ value && setDateValue(value)
40
+ }, [value])
41
+
42
+ const onChange = (date: Date): void => {
43
+ const { fields = 'day' } = props
44
+ const ret = dateToString(date, fields)
45
+ setDateValue(ret)
46
+ bindchange && bindchange({ detail: { value: ret } })
47
+ }
48
+
49
+ const onDismiss = (): void => {
50
+ bindcancel && bindcancel()
51
+ }
52
+
53
+ const onElementLayout = (layout: LayoutType) => {
54
+ viewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
55
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
56
+ props.getInnerLayout && props.getInnerLayout(layoutRef)
57
+ })
58
+ }
59
+
60
+ const dateProps = {
61
+ precision: fields,
62
+ value: formatTimeStr(datevalue),
63
+ minDate: formatTimeStr(start),
64
+ maxDate: formatTimeStr(end),
65
+ onChange,
66
+ onDismiss,
67
+ disabled
68
+ }
69
+ const touchProps = {
70
+ onLayout: onElementLayout,
71
+ ref: viewRef
72
+ }
73
+ return (
74
+ <DatePicker {...dateProps}>
75
+ <TouchableWithoutFeedback>
76
+ <View {...touchProps}>{children}</View>
77
+ </TouchableWithoutFeedback>
78
+ </DatePicker>
79
+ )
80
+ })
81
+
82
+ _DatePicker.displayName = 'mpx-picker-date'
83
+ export default _DatePicker