@mpxjs/webpack-plugin 2.9.59 → 2.9.64

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 (115) hide show
  1. package/lib/index.js +1 -3
  2. package/lib/platform/style/wx/index.js +344 -270
  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 +2 -0
  23. package/lib/react/processStyles.js +1 -0
  24. package/lib/react/processTemplate.js +2 -3
  25. package/lib/react/style-helper.js +12 -7
  26. package/lib/runtime/components/react/context.ts +40 -0
  27. package/lib/runtime/components/react/dist/context.js +8 -0
  28. package/lib/runtime/components/react/dist/getInnerListeners.js +34 -12
  29. package/lib/runtime/components/react/dist/mpx-button.jsx +88 -88
  30. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +82 -0
  31. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +139 -0
  32. package/lib/runtime/components/react/dist/mpx-form.jsx +61 -0
  33. package/lib/runtime/components/react/dist/mpx-icon.jsx +48 -0
  34. package/lib/runtime/components/react/dist/mpx-image/index.jsx +39 -43
  35. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +3 -2
  36. package/lib/runtime/components/react/dist/mpx-input.jsx +63 -37
  37. package/lib/runtime/components/react/dist/mpx-label.jsx +55 -0
  38. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +41 -0
  39. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +346 -0
  40. package/lib/runtime/components/react/dist/mpx-navigator.jsx +35 -0
  41. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +69 -0
  42. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +138 -0
  43. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +142 -0
  44. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +94 -0
  45. package/lib/runtime/components/react/dist/mpx-picker/regionData.js +6099 -0
  46. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +76 -0
  47. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +244 -0
  48. package/lib/runtime/components/react/dist/mpx-picker/type.js +1 -0
  49. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +107 -0
  50. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +162 -0
  51. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +80 -0
  52. package/lib/runtime/components/react/dist/mpx-radio.jsx +154 -0
  53. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +15 -0
  54. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +93 -70
  55. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +281 -157
  56. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +21 -11
  57. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +19 -11
  58. package/lib/runtime/components/react/dist/mpx-switch.jsx +79 -0
  59. package/lib/runtime/components/react/dist/mpx-text.jsx +21 -49
  60. package/lib/runtime/components/react/dist/mpx-textarea.jsx +2 -2
  61. package/lib/runtime/components/react/dist/mpx-view.jsx +451 -146
  62. package/lib/runtime/components/react/dist/mpx-web-view.jsx +17 -20
  63. package/lib/runtime/components/react/dist/parser.js +218 -0
  64. package/lib/runtime/components/react/dist/types/common.js +1 -0
  65. package/lib/runtime/components/react/dist/useNodesRef.js +3 -8
  66. package/lib/runtime/components/react/dist/utils.jsx +433 -0
  67. package/lib/runtime/components/react/getInnerListeners.ts +43 -21
  68. package/lib/runtime/components/react/mpx-button.tsx +129 -119
  69. package/lib/runtime/components/react/mpx-checkbox-group.tsx +152 -0
  70. package/lib/runtime/components/react/mpx-checkbox.tsx +234 -0
  71. package/lib/runtime/components/react/mpx-form.tsx +117 -0
  72. package/lib/runtime/components/react/mpx-icon.tsx +106 -0
  73. package/lib/runtime/components/react/mpx-image/index.tsx +62 -68
  74. package/lib/runtime/components/react/mpx-image/svg.tsx +7 -5
  75. package/lib/runtime/components/react/mpx-input.tsx +90 -42
  76. package/lib/runtime/components/react/mpx-label.tsx +110 -0
  77. package/lib/runtime/components/react/mpx-movable-area.tsx +81 -0
  78. package/lib/runtime/components/react/mpx-movable-view.tsx +424 -0
  79. package/lib/runtime/components/react/mpx-navigator.tsx +67 -0
  80. package/lib/runtime/components/react/mpx-picker/date.tsx +82 -0
  81. package/lib/runtime/components/react/mpx-picker/index.tsx +155 -0
  82. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +156 -0
  83. package/lib/runtime/components/react/mpx-picker/region.tsx +107 -0
  84. package/lib/runtime/components/react/mpx-picker/regionData.ts +6101 -0
  85. package/lib/runtime/components/react/mpx-picker/selector.tsx +91 -0
  86. package/lib/runtime/components/react/mpx-picker/time.tsx +270 -0
  87. package/lib/runtime/components/react/mpx-picker/type.ts +107 -0
  88. package/lib/runtime/components/react/mpx-picker-view-column.tsx +156 -0
  89. package/lib/runtime/components/react/mpx-picker-view.tsx +220 -0
  90. package/lib/runtime/components/react/mpx-radio-group.tsx +150 -0
  91. package/lib/runtime/components/react/mpx-radio.tsx +230 -0
  92. package/lib/runtime/components/react/mpx-root-portal.tsx +27 -0
  93. package/lib/runtime/components/react/mpx-scroll-view.tsx +184 -130
  94. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +308 -183
  95. package/lib/runtime/components/react/mpx-swiper/index.tsx +27 -19
  96. package/lib/runtime/components/react/mpx-swiper/type.ts +23 -5
  97. package/lib/runtime/components/react/mpx-swiper-item.tsx +49 -14
  98. package/lib/runtime/components/react/mpx-switch.tsx +148 -0
  99. package/lib/runtime/components/react/mpx-text.tsx +53 -77
  100. package/lib/runtime/components/react/mpx-textarea.tsx +3 -3
  101. package/lib/runtime/components/react/mpx-view.tsx +576 -195
  102. package/lib/runtime/components/react/mpx-web-view.tsx +34 -39
  103. package/lib/runtime/components/react/parser.ts +245 -0
  104. package/lib/runtime/components/react/types/common.ts +12 -0
  105. package/lib/runtime/components/react/types/getInnerListeners.ts +2 -1
  106. package/lib/runtime/components/react/types/global.d.ts +17 -1
  107. package/lib/runtime/components/react/useNodesRef.ts +4 -10
  108. package/lib/runtime/components/react/utils.tsx +505 -0
  109. package/lib/runtime/optionProcessor.js +19 -17
  110. package/lib/template-compiler/compiler.js +84 -61
  111. package/lib/template-compiler/gen-node-react.js +7 -9
  112. package/lib/web/processStyles.js +2 -5
  113. package/package.json +8 -3
  114. package/lib/runtime/components/react/dist/utils.js +0 -80
  115. package/lib/runtime/components/react/utils.ts +0 -92
@@ -0,0 +1,81 @@
1
+ /**
2
+ * ✘ scale-area
3
+ */
4
+
5
+ import { View, LayoutChangeEvent } from 'react-native'
6
+ import { JSX, useState, useEffect, forwardRef, ReactNode } from 'react'
7
+ import useNodesRef, { HandlerRef } from './useNodesRef'
8
+ import useInnerProps from './getInnerListeners'
9
+ import { MovableAreaContext } from './context'
10
+ import { useTransformStyle, wrapChildren, useLayout } from './utils'
11
+
12
+ interface MovableAreaProps {
13
+ style?: Record<string, any>;
14
+ children: ReactNode;
15
+ width?: number;
16
+ height?: number;
17
+ 'enable-offset'?: boolean;
18
+ 'enable-var'?: boolean
19
+ 'external-var-context'?: Record<string, any>;
20
+ 'parent-font-size'?: number;
21
+ 'parent-width'?: number;
22
+ 'parent-height'?: number;
23
+ }
24
+
25
+ const _MovableArea = forwardRef<HandlerRef<View, MovableAreaProps>, MovableAreaProps>((props: MovableAreaProps, ref): JSX.Element => {
26
+ const { style = {}, width = 10, height = 10, 'enable-var': enableVar, 'external-var-context': externalVarContext, 'parent-font-size': parentFontSize, 'parent-width': parentWidth, 'parent-height': parentHeight } = props
27
+ const [areaWidth, setAreaWidth] = useState(0)
28
+ const [areaHeight, setAreaHeight] = useState(0)
29
+
30
+ useEffect(() => {
31
+ setAreaWidth(width)
32
+ setAreaHeight(height)
33
+ }, [width, height])
34
+
35
+ const {
36
+ hasSelfPercent,
37
+ normalStyle,
38
+ hasVarDec,
39
+ varContextRef,
40
+ setWidth,
41
+ setHeight
42
+ } = useTransformStyle(style, { enableVar, externalVarContext, parentFontSize, parentWidth, parentHeight })
43
+
44
+ const { nodeRef: movableViewRef } = useNodesRef(props, ref)
45
+
46
+ const onLayout = (e: LayoutChangeEvent) => {
47
+ const { width = 10, height = 10 } = e.nativeEvent.layout
48
+ setAreaWidth(width)
49
+ setAreaHeight(height)
50
+ }
51
+
52
+ const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef, onLayout })
53
+
54
+ const innerProps = useInnerProps(props, {
55
+ style: { height: areaHeight, width: areaWidth, overflow: 'hidden', ...normalStyle, ...layoutStyle },
56
+ ref: movableViewRef,
57
+ ...layoutProps
58
+ }, [], { layoutRef })
59
+
60
+ return (
61
+ <MovableAreaContext.Provider value={{ height: areaHeight, width: areaWidth }}>
62
+ <View
63
+ {...innerProps}
64
+ >
65
+ {
66
+ wrapChildren(
67
+ props,
68
+ {
69
+ hasVarDec,
70
+ varContext: varContextRef.current
71
+ }
72
+ )
73
+ }
74
+ </View>
75
+ </MovableAreaContext.Provider>
76
+ )
77
+ })
78
+
79
+ _MovableArea.displayName = 'mpx-movable-area'
80
+
81
+ export default _MovableArea
@@ -0,0 +1,424 @@
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
+ const isFirstTouch = useRef<boolean>(true)
94
+ const touchEvent = useRef<string>('')
95
+ const 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
+ Animated.spring(scaleValue.current, {
220
+ toValue: clampedScale,
221
+ friction: 7,
222
+ useNativeDriver: false
223
+ }).start()
224
+ bindscale && bindscale(getCustomEvent('scale', e, {
225
+ detail: {
226
+ x: pan.current.x._value,
227
+ y: pan.current.y._value,
228
+ scale: clampedScale
229
+ },
230
+ layoutRef
231
+ }, propsRef.current))
232
+ }
233
+ } else if (gestureState.numberActiveTouches === 1) {
234
+ if (initialDistance.current) {
235
+ return // Skip processing if it's switching from a double touch
236
+ }
237
+ setTransformOrigin('0% 0%')
238
+ if (isFirstTouch.current) {
239
+ touchEvent.current = Math.abs(gestureState.dx) > Math.abs(gestureState.dy) ? 'htouchmove' : 'vtouchmove'
240
+ isFirstTouch.current = false
241
+ }
242
+ Animated.event(
243
+ [
244
+ null,
245
+ {
246
+ dx: direction === 'all' || direction === 'horizontal' ? pan.current.x : new Animated.Value(0),
247
+ dy: direction === 'all' || direction === 'vertical' ? pan.current.y : new Animated.Value(0)
248
+ }
249
+ ],
250
+ {
251
+ useNativeDriver: false
252
+ }
253
+ )(e, gestureState)
254
+
255
+ movablePosition.current = {
256
+ x: pan.current.x.__getValue(),
257
+ y: pan.current.y.__getValue()
258
+ }
259
+ bindchange && bindchange(
260
+ getCustomEvent('change', e, {
261
+ detail: {
262
+ x: movablePosition.current.x,
263
+ y: movablePosition.current.y,
264
+ source: 'touch'
265
+ },
266
+ layoutRef
267
+ }, propsRef.current)
268
+ )
269
+ }
270
+ },
271
+ onPanResponderRelease: () => {
272
+ handlePanReleaseOrTerminate()
273
+ },
274
+ onPanResponderTerminate: () => {
275
+ handlePanReleaseOrTerminate()
276
+ }
277
+ })
278
+ }, [MovableAreaLayout.width, MovableAreaLayout.height])
279
+
280
+ const onLayout = () => {
281
+ nodeRef.current?.measure((x: number, y: number, width: number, height: number) => {
282
+ layoutRef.current = { x, y, width, height, offsetLeft: 0, offsetTop: 0 }
283
+ const clampedScale = Math.min(scaleMax, Math.max(scaleMin, originScaleValue))
284
+ const { x: newX, y: nexY } = checkBoundaryPosition({
285
+ clampedScale,
286
+ width,
287
+ height,
288
+ positionX: movablePosition.current.x,
289
+ positionY: movablePosition.current.y
290
+ })
291
+
292
+ Animated.spring(pan.current, {
293
+ toValue: { x: newX, y: nexY },
294
+ useNativeDriver: false,
295
+ friction
296
+ }).start(() => {
297
+ movablePosition.current = { x: newX, y: nexY }
298
+ bindchange &&
299
+ bindchange(
300
+ getCustomEvent('change', {}, {
301
+ detail: {
302
+ x: newX,
303
+ y: nexY,
304
+ source: ''
305
+ },
306
+ layoutRef
307
+ }, props)
308
+ )
309
+ })
310
+ })
311
+ }
312
+
313
+ const onTouchMove = (e: NativeSyntheticEvent<TouchEvent>) => {
314
+ const { bindhtouchmove, bindvtouchmove, bindtouchmove } = props
315
+ if (touchEvent.current === 'htouchmove') {
316
+ bindhtouchmove && bindhtouchmove(e)
317
+ } else if (touchEvent.current === 'vtouchmove') {
318
+ bindvtouchmove && bindvtouchmove(e)
319
+ }
320
+ bindtouchmove && bindtouchmove(e)
321
+ }
322
+
323
+ const onCatchTouchMove = (e: NativeSyntheticEvent<TouchEvent>) => {
324
+ const { catchhtouchmove, catchvtouchmove, catchtouchmove } = props
325
+ if (touchEvent.current === 'htouchmove') {
326
+ catchhtouchmove && catchhtouchmove(e)
327
+ } else if (touchEvent.current === 'vtouchmove') {
328
+ catchvtouchmove && catchvtouchmove(e)
329
+ }
330
+ catchtouchmove && catchtouchmove(e)
331
+ }
332
+
333
+ const checkBoundaryPosition = ({ clampedScale, width, height, positionX, positionY }: { clampedScale: number; width: number; height: number; positionX: number; positionY: number }) => {
334
+ // Calculate scaled element size
335
+ const scaledWidth = width * clampedScale
336
+ const scaledHeight = height * clampedScale
337
+
338
+ // Calculate the boundary limits
339
+ let x = positionX
340
+ let y = positionY
341
+
342
+ // Correct y coordinate
343
+ if (scaledHeight > MovableAreaLayout.height) {
344
+ if (y >= 0) {
345
+ y = 0
346
+ } else if (y < MovableAreaLayout.height - scaledHeight) {
347
+ y = MovableAreaLayout.height - scaledHeight
348
+ }
349
+ } else {
350
+ if (y < 0) {
351
+ y = 0
352
+ } else if (y > MovableAreaLayout.height - scaledHeight) {
353
+ y = MovableAreaLayout.height - scaledHeight
354
+ }
355
+ }
356
+ // Correct x coordinate
357
+ if (scaledWidth > MovableAreaLayout.width) {
358
+ if (x >= 0) {
359
+ x = 0
360
+ } else if (x < MovableAreaLayout.width - scaledWidth) {
361
+ x = MovableAreaLayout.width - scaledWidth
362
+ }
363
+ } else {
364
+ if (x < 0) {
365
+ x = 0
366
+ } else if (x > MovableAreaLayout.width - scaledWidth) {
367
+ x = MovableAreaLayout.width - scaledWidth
368
+ }
369
+ }
370
+
371
+ return {
372
+ x,
373
+ y
374
+ }
375
+ }
376
+
377
+ const [translateX, translateY] = [pan.current.x, pan.current.y]
378
+
379
+ const transformStyle = { transform: [{ translateX }, { translateY }, { scale: scaleValue.current }], transformOrigin: transformOrigin }
380
+
381
+ const hasTouchmove = () => !!props.bindhtouchmove || !!props.bindvtouchmove || !!props.bindtouchmove
382
+
383
+ const hasCatchTouchmove = () => !!props.catchhtouchmove || !!props.catchvtouchmove || !!props.catchtouchmove
384
+
385
+ const innerProps = useInnerProps(props, {
386
+ ref: nodeRef,
387
+ ...panResponder.panHandlers,
388
+ onLayout,
389
+ ...(hasTouchmove() ? { bindtouchmove: onTouchMove } : {}),
390
+ ...(hasCatchTouchmove() ? { catchtouchmove: onCatchTouchMove } : {})
391
+ }, [
392
+ 'children',
393
+ 'style',
394
+ 'direction',
395
+ 'x',
396
+ 'y',
397
+ 'scale',
398
+ 'disabled',
399
+ 'scale-value',
400
+ 'scale-min',
401
+ 'scale-max',
402
+ 'bindchange',
403
+ 'bindscale',
404
+ 'htouchmove',
405
+ 'vtouchmove'
406
+ ], { layoutRef })
407
+
408
+ return (
409
+ <Animated.View
410
+ {...innerProps}
411
+ style={{
412
+ ...styles.container,
413
+ ...style,
414
+ ...transformStyle
415
+ }}
416
+ >
417
+ {children}
418
+ </Animated.View>
419
+ )
420
+ })
421
+
422
+ _MovableView.displayName = 'mpx-movable-view'
423
+
424
+ 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,82 @@
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
+ const _DatePicker = forwardRef<HandlerRef<View, DateProps>, DateProps>((props: DateProps, ref): React.JSX.Element => {
30
+ const { children, start = '1970-01-01', end = '2999-01-01', value, bindchange, bindcancel, disabled, fields } = props
31
+ const [datevalue, setDateValue] = useState(value)
32
+ // 存储layout布局信息
33
+ const layoutRef = useRef({})
34
+ const { nodeRef: viewRef } = useNodesRef<View, DateProps>(props, ref, {
35
+ })
36
+
37
+ useEffect(() => {
38
+ value && setDateValue(value)
39
+ }, [value])
40
+
41
+ const onChange = (date: Date): void => {
42
+ const { fields = 'day' } = props
43
+ const ret = dateToString(date, fields)
44
+ setDateValue(ret)
45
+ bindchange && bindchange({ detail: { value: ret } })
46
+ }
47
+
48
+ const onDismiss = (): void => {
49
+ bindcancel && bindcancel()
50
+ }
51
+
52
+ const onElementLayout = (layout: LayoutType) => {
53
+ viewRef.current?.measure((x: number, y: number, width: number, height: number, offsetLeft: number, offsetTop: number) => {
54
+ layoutRef.current = { x, y, width, height, offsetLeft, offsetTop }
55
+ props.getInnerLayout && props.getInnerLayout(layoutRef)
56
+ })
57
+ }
58
+
59
+ const dateProps = {
60
+ precision: fields,
61
+ value: formatTimeStr(datevalue),
62
+ minDate: formatTimeStr(start),
63
+ maxDate: formatTimeStr(end),
64
+ onChange,
65
+ onDismiss,
66
+ disabled
67
+ }
68
+ const touchProps = {
69
+ onLayout: onElementLayout,
70
+ ref: viewRef
71
+ }
72
+ return (
73
+ <DatePicker {...dateProps}>
74
+ <TouchableWithoutFeedback>
75
+ <View {...touchProps}>{children}</View>
76
+ </TouchableWithoutFeedback>
77
+ </DatePicker>
78
+ )
79
+ })
80
+
81
+ _DatePicker.displayName = 'mpx-picker-date'
82
+ export default _DatePicker