@mpxjs/webpack-plugin 2.10.3 → 2.10.4-beta.11
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.
- package/lib/config.js +2 -1
- package/lib/index.js +1 -1
- package/lib/platform/json/wx/index.js +6 -4
- package/lib/platform/style/wx/index.js +42 -30
- package/lib/platform/template/wx/component-config/button.js +20 -3
- package/lib/platform/template/wx/component-config/canvas.js +4 -0
- package/lib/platform/template/wx/component-config/checkbox-group.js +4 -0
- package/lib/platform/template/wx/component-config/checkbox.js +4 -0
- package/lib/platform/template/wx/component-config/cover-image.js +7 -1
- package/lib/platform/template/wx/component-config/cover-view.js +4 -0
- package/lib/platform/template/wx/component-config/fix-component-name.js +3 -2
- package/lib/platform/template/wx/component-config/form.js +7 -1
- package/lib/platform/template/wx/component-config/icon.js +4 -0
- package/lib/platform/template/wx/component-config/image.js +7 -1
- package/lib/platform/template/wx/component-config/index.js +5 -1
- package/lib/platform/template/wx/component-config/input.js +19 -4
- package/lib/platform/template/wx/component-config/label.js +4 -0
- package/lib/platform/template/wx/component-config/movable-area.js +7 -1
- package/lib/platform/template/wx/component-config/movable-view.js +12 -3
- package/lib/platform/template/wx/component-config/navigator.js +4 -0
- package/lib/platform/template/wx/component-config/picker-view-column.js +4 -0
- package/lib/platform/template/wx/component-config/picker-view.js +7 -1
- package/lib/platform/template/wx/component-config/picker.js +7 -1
- package/lib/platform/template/wx/component-config/radio-group.js +4 -0
- package/lib/platform/template/wx/component-config/radio.js +4 -0
- package/lib/platform/template/wx/component-config/rich-text.js +4 -0
- package/lib/platform/template/wx/component-config/root-portal.js +4 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +10 -2
- package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
- package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
- package/lib/platform/template/wx/component-config/swiper-item.js +7 -1
- package/lib/platform/template/wx/component-config/swiper.js +12 -3
- package/lib/platform/template/wx/component-config/switch.js +4 -0
- package/lib/platform/template/wx/component-config/text.js +24 -3
- package/lib/platform/template/wx/component-config/textarea.js +17 -2
- package/lib/platform/template/wx/component-config/unsupported.js +7 -0
- package/lib/platform/template/wx/component-config/video.js +10 -2
- package/lib/platform/template/wx/component-config/view.js +11 -1
- package/lib/platform/template/wx/component-config/web-view.js +4 -0
- package/lib/platform/template/wx/index.js +42 -75
- package/lib/react/processJSON.js +7 -6
- package/lib/react/processScript.js +1 -18
- package/lib/runtime/components/react/context.ts +12 -3
- package/lib/runtime/components/react/dist/context.js +4 -1
- package/lib/runtime/components/react/dist/event.config.js +0 -1
- package/lib/runtime/components/react/dist/getInnerListeners.js +127 -142
- package/lib/runtime/components/react/dist/mpx-button.jsx +4 -5
- package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +4 -5
- package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -3
- package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
- package/lib/runtime/components/react/dist/mpx-input.jsx +20 -17
- package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +24 -31
- package/lib/runtime/components/react/dist/mpx-label.jsx +2 -3
- package/lib/runtime/components/react/dist/mpx-movable-area.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
- package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
- package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
- package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
- package/lib/runtime/components/react/dist/mpx-picker/index.jsx +180 -98
- package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
- package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
- package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
- package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
- package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +5 -6
- package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +66 -18
- package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +8 -5
- package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
- package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
- package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
- package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -3
- package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +2 -2
- package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +207 -29
- package/lib/runtime/components/react/dist/mpx-simple-text.jsx +7 -5
- package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
- package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +115 -0
- package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
- package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -5
- package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -9
- package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -5
- package/lib/runtime/components/react/dist/mpx-text.jsx +4 -7
- package/lib/runtime/components/react/dist/mpx-video.jsx +5 -5
- package/lib/runtime/components/react/dist/mpx-view.jsx +23 -9
- package/lib/runtime/components/react/dist/mpx-web-view.jsx +16 -13
- package/lib/runtime/components/react/dist/useAnimationHooks.js +26 -4
- package/lib/runtime/components/react/dist/utils.jsx +14 -2
- package/lib/runtime/components/react/event.config.ts +1 -6
- package/lib/runtime/components/react/getInnerListeners.ts +148 -191
- package/lib/runtime/components/react/mpx-button.tsx +7 -7
- package/lib/runtime/components/react/mpx-canvas/index.tsx +25 -17
- package/lib/runtime/components/react/mpx-checkbox-group.tsx +4 -3
- package/lib/runtime/components/react/mpx-checkbox.tsx +8 -9
- package/lib/runtime/components/react/mpx-form.tsx +25 -19
- package/lib/runtime/components/react/mpx-icon/index.tsx +4 -3
- package/lib/runtime/components/react/mpx-image.tsx +4 -3
- package/lib/runtime/components/react/mpx-inline-text.tsx +18 -0
- package/lib/runtime/components/react/mpx-input.tsx +24 -21
- package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +31 -42
- package/lib/runtime/components/react/mpx-label.tsx +4 -5
- package/lib/runtime/components/react/mpx-movable-area.tsx +22 -13
- package/lib/runtime/components/react/mpx-movable-view.tsx +47 -40
- package/lib/runtime/components/react/mpx-navigator.tsx +4 -6
- package/lib/runtime/components/react/mpx-picker/date.tsx +226 -69
- package/lib/runtime/components/react/mpx-picker/dateData.ts +22 -0
- package/lib/runtime/components/react/mpx-picker/index.tsx +242 -118
- package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +96 -139
- package/lib/runtime/components/react/mpx-picker/region.tsx +217 -89
- package/lib/runtime/components/react/mpx-picker/selector.tsx +75 -80
- package/lib/runtime/components/react/mpx-picker/time.tsx +119 -236
- package/lib/runtime/components/react/mpx-picker/type.ts +85 -71
- package/lib/runtime/components/react/{mpx-picker-view.tsx → mpx-picker-view/index.tsx} +24 -21
- package/lib/runtime/components/react/{mpx-picker-view-column.tsx → mpx-picker-view-column/index.tsx} +72 -21
- package/lib/runtime/components/react/{mpx-picker-view-column-item.tsx → mpx-picker-view-column/pickerViewColumnItem.tsx} +8 -5
- package/lib/runtime/components/react/{pickerFaces.ts → mpx-picker-view-column/pickerViewFaces.ts} +7 -0
- package/lib/runtime/components/react/mpx-popup/index.tsx +86 -0
- package/lib/runtime/components/react/mpx-popup/popupBase.tsx +130 -0
- package/lib/runtime/components/react/mpx-radio-group.tsx +4 -3
- package/lib/runtime/components/react/mpx-radio.tsx +8 -9
- package/lib/runtime/components/react/mpx-rich-text/index.tsx +15 -6
- package/lib/runtime/components/react/mpx-scroll-view.tsx +326 -96
- package/lib/runtime/components/react/mpx-simple-text.tsx +17 -8
- package/lib/runtime/components/react/mpx-simple-view.tsx +17 -16
- package/lib/runtime/components/react/mpx-sticky-header.tsx +179 -0
- package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
- package/lib/runtime/components/react/mpx-swiper-item.tsx +31 -24
- package/lib/runtime/components/react/mpx-swiper.tsx +67 -61
- package/lib/runtime/components/react/mpx-switch.tsx +19 -14
- package/lib/runtime/components/react/mpx-text.tsx +16 -13
- package/lib/runtime/components/react/mpx-video.tsx +36 -35
- package/lib/runtime/components/react/mpx-view.tsx +41 -17
- package/lib/runtime/components/react/mpx-web-view.tsx +15 -12
- package/lib/runtime/components/react/types/getInnerListeners.d.ts +69 -35
- package/lib/runtime/components/react/types/global.d.ts +1 -1
- package/lib/runtime/components/react/useAnimationHooks.ts +29 -9
- package/lib/runtime/components/react/utils.tsx +15 -3
- package/lib/runtime/components/web/mini-video-controls.min.js +1 -1
- package/lib/runtime/components/web/mpx-input.vue +1 -1
- package/lib/runtime/components/web/mpx-scroll-view.vue +21 -4
- package/lib/runtime/components/web/mpx-sticky-header.vue +91 -0
- package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
- package/lib/runtime/stringify.wxs +2 -2
- package/lib/template-compiler/compiler.js +8 -8
- package/lib/utils/env.js +1 -1
- package/package.json +4 -5
- package/LICENSE +0 -433
- /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
- /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
- /package/lib/runtime/components/react/{pickerVIewContext.ts → mpx-picker-view/pickerVIewContext.ts} +0 -0
- /package/lib/runtime/components/react/{pickerViewIndicator.tsx → mpx-picker-view-column/pickerViewIndicator.tsx} +0 -0
- /package/lib/runtime/components/react/{pickerViewMask.tsx → mpx-picker-view-column/pickerViewMask.tsx} +0 -0
|
@@ -1,29 +1,18 @@
|
|
|
1
|
-
import React, { useContext, useEffect
|
|
2
|
-
import { Keyboard,
|
|
1
|
+
import React, { useContext, useEffect } from 'react';
|
|
2
|
+
import { Keyboard, View } from 'react-native';
|
|
3
3
|
import Animated, { useSharedValue, useAnimatedStyle, withTiming, Easing } from 'react-native-reanimated';
|
|
4
|
-
import { GestureDetector, Gesture } from 'react-native-gesture-handler';
|
|
5
4
|
import { KeyboardAvoidContext } from './context';
|
|
5
|
+
import { isIOS } from './utils';
|
|
6
6
|
const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
|
|
7
|
-
const isIOS = Platform.OS === 'ios';
|
|
8
7
|
const duration = isIOS ? 250 : 300;
|
|
9
8
|
const easing = isIOS ? Easing.inOut(Easing.ease) : Easing.out(Easing.quad);
|
|
10
9
|
const offset = useSharedValue(0);
|
|
11
10
|
const basic = useSharedValue('auto');
|
|
12
11
|
const keyboardAvoid = useContext(KeyboardAvoidContext);
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return Gesture.Tap()
|
|
18
|
-
.onEnd(() => {
|
|
19
|
-
dismiss();
|
|
20
|
-
}).runOnJS(true);
|
|
21
|
-
}, []);
|
|
22
|
-
const animatedStyle = useAnimatedStyle(() => {
|
|
23
|
-
return Object.assign({
|
|
24
|
-
transform: [{ translateY: -offset.value }]
|
|
25
|
-
}, isIOS ? {} : { flexBasis: basic.value });
|
|
26
|
-
});
|
|
12
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
13
|
+
transform: [{ translateY: -offset.value }],
|
|
14
|
+
flexBasis: basic.value
|
|
15
|
+
}));
|
|
27
16
|
const resetKeyboard = () => {
|
|
28
17
|
if (keyboardAvoid?.current) {
|
|
29
18
|
keyboardAvoid.current = null;
|
|
@@ -31,6 +20,11 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
|
|
|
31
20
|
offset.value = withTiming(0, { duration, easing });
|
|
32
21
|
basic.value = 'auto';
|
|
33
22
|
};
|
|
23
|
+
const onTouchEnd = ({ nativeEvent }) => {
|
|
24
|
+
if (nativeEvent.origin !== 'input') {
|
|
25
|
+
Keyboard.isVisible() && Keyboard.dismiss();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
34
28
|
useEffect(() => {
|
|
35
29
|
let subscriptions = [];
|
|
36
30
|
if (isIOS) {
|
|
@@ -46,7 +40,12 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
|
|
|
46
40
|
const aboveValue = -aboveOffset >= cursorSpacing ? 0 : aboveOffset + cursorSpacing;
|
|
47
41
|
const belowValue = Math.min(endCoordinates.height, aboveOffset + cursorSpacing);
|
|
48
42
|
const value = aboveOffset > 0 ? belowValue : aboveValue;
|
|
49
|
-
offset.value = withTiming(value, { duration, easing })
|
|
43
|
+
offset.value = withTiming(value, { duration, easing }, (finished) => {
|
|
44
|
+
if (finished) {
|
|
45
|
+
// Set flexBasic after animation to trigger re-layout and reset layout information
|
|
46
|
+
basic.value = '99.99%';
|
|
47
|
+
}
|
|
48
|
+
});
|
|
50
49
|
});
|
|
51
50
|
});
|
|
52
51
|
}),
|
|
@@ -68,11 +67,7 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
|
|
|
68
67
|
const value = aboveOffset > 0 ? belowValue : aboveValue;
|
|
69
68
|
offset.value = withTiming(value, { duration, easing }, (finished) => {
|
|
70
69
|
if (finished) {
|
|
71
|
-
|
|
72
|
-
* In the Android environment, the layout information is not synchronized after the animation,
|
|
73
|
-
* which results in the inability to correctly trigger element events.
|
|
74
|
-
* Here, we utilize flexBasic to proactively trigger a re-layout
|
|
75
|
-
*/
|
|
70
|
+
// Set flexBasic after animation to trigger re-layout and reset layout information
|
|
76
71
|
basic.value = '99.99%';
|
|
77
72
|
}
|
|
78
73
|
});
|
|
@@ -85,16 +80,14 @@ const KeyboardAvoidingView = ({ children, style, contentContainerStyle }) => {
|
|
|
85
80
|
subscriptions.forEach(subscription => subscription.remove());
|
|
86
81
|
};
|
|
87
82
|
}, [keyboardAvoid]);
|
|
88
|
-
return (<
|
|
89
|
-
<View style={
|
|
90
|
-
<Animated.View style={[
|
|
83
|
+
return (<View style={style} onTouchEnd={onTouchEnd}>
|
|
84
|
+
<Animated.View style={[
|
|
91
85
|
contentContainerStyle,
|
|
92
86
|
animatedStyle
|
|
93
87
|
]}>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</GestureDetector>);
|
|
88
|
+
{children}
|
|
89
|
+
</Animated.View>
|
|
90
|
+
</View>);
|
|
98
91
|
};
|
|
99
92
|
KeyboardAvoidingView.displayName = 'MpxKeyboardAvoidingView';
|
|
100
93
|
export default KeyboardAvoidingView;
|
|
@@ -33,10 +33,9 @@ const Label = forwardRef((labelProps, ref) => {
|
|
|
33
33
|
bindtap && bindtap(getCustomEvent('tap', evt, { layoutRef }, { props: propsRef.current }));
|
|
34
34
|
contextRef.current.triggerChange(evt);
|
|
35
35
|
}, []);
|
|
36
|
-
const innerProps = useInnerProps(props,
|
|
36
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
37
37
|
ref: nodeRef,
|
|
38
|
-
style: extendObject({}, innerStyle, layoutStyle)
|
|
39
|
-
}, layoutProps, {
|
|
38
|
+
style: extendObject({}, innerStyle, layoutStyle),
|
|
40
39
|
bindtap: onTap
|
|
41
40
|
}), [], {
|
|
42
41
|
layoutRef
|
|
@@ -19,10 +19,10 @@ const _MovableArea = forwardRef((props, ref) => {
|
|
|
19
19
|
width: normalStyle.width || 10
|
|
20
20
|
}), [normalStyle.width, normalStyle.height]);
|
|
21
21
|
const { layoutRef, layoutStyle, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: movableViewRef });
|
|
22
|
-
const innerProps = useInnerProps(props,
|
|
22
|
+
const innerProps = useInnerProps(extendObject({}, props, layoutProps, {
|
|
23
23
|
style: extendObject({ height: contextValue.height, width: contextValue.width, overflow: 'hidden' }, normalStyle, layoutStyle),
|
|
24
24
|
ref: movableViewRef
|
|
25
|
-
}
|
|
25
|
+
}), [], { layoutRef });
|
|
26
26
|
return createElement(MovableAreaContext.Provider, { value: contextValue }, createElement(View, innerProps, wrapChildren(props, {
|
|
27
27
|
hasVarDec,
|
|
28
28
|
varContext: varContextRef.current
|
|
@@ -452,7 +452,7 @@ const _MovableView = forwardRef((movableViewProps, ref) => {
|
|
|
452
452
|
'catchhtouchmove',
|
|
453
453
|
'catchtouchend'
|
|
454
454
|
]);
|
|
455
|
-
const innerProps = useInnerProps(filterProps,
|
|
455
|
+
const innerProps = useInnerProps(extendObject({}, filterProps, {
|
|
456
456
|
ref: nodeRef,
|
|
457
457
|
onLayout: onLayout,
|
|
458
458
|
style: [innerStyle, animatedStyles, layoutStyle]
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ✔ hover-class
|
|
3
|
+
* ✘ hover-stop-propagation
|
|
4
|
+
* ✔ hover-start-time
|
|
5
|
+
* ✔ hover-stay-time
|
|
6
|
+
* ✔ open-type
|
|
7
|
+
* ✔ url
|
|
8
|
+
* ✔ delta
|
|
9
|
+
*/
|
|
1
10
|
import { useCallback, forwardRef, createElement } from 'react';
|
|
2
|
-
import useInnerProps from './getInnerListeners';
|
|
3
11
|
import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy';
|
|
4
12
|
import MpxView from './mpx-view';
|
|
5
13
|
const _Navigator = forwardRef((props, ref) => {
|
|
@@ -23,10 +31,10 @@ const _Navigator = forwardRef((props, ref) => {
|
|
|
23
31
|
break;
|
|
24
32
|
}
|
|
25
33
|
}, [openType, url, delta]);
|
|
26
|
-
const innerProps =
|
|
34
|
+
const innerProps = {
|
|
27
35
|
ref,
|
|
28
36
|
bindtap: handleClick
|
|
29
|
-
}
|
|
37
|
+
};
|
|
30
38
|
return createElement(MpxView, innerProps, children);
|
|
31
39
|
});
|
|
32
40
|
_Navigator.displayName = 'MpxNavigator';
|
|
@@ -1,74 +1,200 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import React, { forwardRef, useCallback, useMemo, useRef, useState, useEffect, useImperativeHandle } from 'react';
|
|
2
|
+
import { StyleSheet, Text } from 'react-native';
|
|
3
|
+
import MpxPickerView from '../mpx-picker-view';
|
|
4
|
+
import MpxPickerViewColumn from '../mpx-picker-view-column';
|
|
5
|
+
import { useUpdateEffect } from '../utils';
|
|
6
|
+
import { years, months, daysInMonth, wrapDate, daysInMonthLength, START_YEAR, END_YEAR } from './dateData';
|
|
7
|
+
const START_DATE = `${START_YEAR}-01-01`;
|
|
8
|
+
const END_DATE = `${END_YEAR}-12-31`;
|
|
9
|
+
const START_DATE_ARR = [START_YEAR, 1, 1];
|
|
10
|
+
const END_DATE_ARR = [END_YEAR, 12, 31];
|
|
11
|
+
const styles = StyleSheet.create({
|
|
12
|
+
pickerContainer: {
|
|
13
|
+
height: 240,
|
|
14
|
+
paddingHorizontal: 10,
|
|
15
|
+
borderTopLeftRadius: 10,
|
|
16
|
+
borderTopRightRadius: 10
|
|
17
|
+
},
|
|
18
|
+
pickerIndicator: {
|
|
19
|
+
height: 45
|
|
20
|
+
},
|
|
21
|
+
pickerItem: {
|
|
22
|
+
fontSize: 16,
|
|
23
|
+
lineHeight: 45,
|
|
24
|
+
textAlign: 'center'
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const getColumnLength = (fields = 'day') => {
|
|
28
|
+
return fields === 'year' ? 1 : fields === 'month' ? 2 : 3;
|
|
29
|
+
};
|
|
30
|
+
const compareDateStr = (date1, date2) => {
|
|
31
|
+
const [y1 = START_YEAR, m1 = 0, d1 = 0] = typeof date1 === 'string' ? date1.split('-').map(Number) : date1;
|
|
32
|
+
const [y2 = START_YEAR, m2 = 0, d2 = 0] = typeof date2 === 'string' ? date2.split('-').map(Number) : date2;
|
|
33
|
+
const num1 = y1 * 10000 + m1 * 100 + d1;
|
|
34
|
+
const num2 = y2 * 10000 + m2 * 100 + d2;
|
|
35
|
+
if (num1 === num2) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
return num1 > num2 ? 1 : -1;
|
|
39
|
+
};
|
|
40
|
+
const getDateArr = (date) => {
|
|
41
|
+
const [y, m, d] = typeof date === 'string' ? date.split('-').map(Number) : date;
|
|
42
|
+
return [y || 0, m || 0, d || 0];
|
|
43
|
+
};
|
|
44
|
+
const calibrateDate = (date, start, end) => {
|
|
45
|
+
let startArr = getDateArr(start);
|
|
46
|
+
let endArr = getDateArr(end);
|
|
47
|
+
let dateArr = getDateArr(date);
|
|
48
|
+
if (compareDateStr(startArr, endArr) > 0) {
|
|
49
|
+
startArr = START_DATE_ARR;
|
|
50
|
+
}
|
|
51
|
+
if (compareDateStr(endArr, startArr) < 0) {
|
|
52
|
+
endArr = END_DATE_ARR;
|
|
53
|
+
}
|
|
54
|
+
if (compareDateStr(start, end) > 0) {
|
|
55
|
+
startArr = START_DATE_ARR;
|
|
56
|
+
endArr = END_DATE_ARR;
|
|
57
|
+
}
|
|
58
|
+
if (compareDateStr(dateArr, endArr) > 0) {
|
|
59
|
+
dateArr = endArr;
|
|
60
|
+
}
|
|
61
|
+
if (compareDateStr(dateArr, startArr) < 0) {
|
|
62
|
+
dateArr = startArr;
|
|
63
|
+
}
|
|
64
|
+
return dateArr;
|
|
65
|
+
};
|
|
66
|
+
const initDateStr2Arr = (dateStr, start, end) => {
|
|
67
|
+
if (!dateStr) {
|
|
68
|
+
const today = new Date();
|
|
69
|
+
const todayYear = today.getFullYear();
|
|
70
|
+
const todayMonth = today.getMonth() + 1;
|
|
71
|
+
const todayDay = today.getDate();
|
|
72
|
+
dateStr = [todayYear, todayMonth, todayDay];
|
|
73
|
+
}
|
|
74
|
+
const [y, m, d] = getDateArr(dateStr);
|
|
75
|
+
const year = Math.min(Math.max(START_YEAR, y), END_YEAR);
|
|
76
|
+
const month = Math.min(Math.max(1, m), 12);
|
|
77
|
+
const day = Math.min(Math.max(1, d), daysInMonthLength(year, month));
|
|
78
|
+
const res = [year, month, day];
|
|
79
|
+
return calibrateDate(res, start, end);
|
|
80
|
+
};
|
|
81
|
+
const valueStr2Obj = (_value = '', // eg: 2025-2-12
|
|
82
|
+
limit, start, end) => {
|
|
83
|
+
const [y, m, d] = initDateStr2Arr(_value, start, end);
|
|
84
|
+
const ans = {
|
|
85
|
+
indexArr: [y - START_YEAR],
|
|
86
|
+
rangeArr: [years]
|
|
87
|
+
};
|
|
88
|
+
if (limit === 2) {
|
|
89
|
+
ans.indexArr.push(m - 1);
|
|
90
|
+
ans.rangeArr.push(months);
|
|
91
|
+
}
|
|
92
|
+
else if (limit === 3) {
|
|
93
|
+
const days = daysInMonth(y, m);
|
|
94
|
+
ans.indexArr.push(m - 1, d - 1);
|
|
95
|
+
ans.rangeArr.push(months, days);
|
|
96
|
+
}
|
|
97
|
+
return ans;
|
|
98
|
+
};
|
|
99
|
+
const valueChanged2Obj = (currentObj, value, limit = 3) => {
|
|
100
|
+
const currentValue = currentObj.indexArr;
|
|
101
|
+
const rangeArr = currentObj.rangeArr;
|
|
102
|
+
if (limit === 3 && (currentValue[0] !== value[0] || currentValue[1] !== value[1])) {
|
|
103
|
+
const days = daysInMonth(value[0], value[1] + 1);
|
|
104
|
+
rangeArr[2] = days;
|
|
105
|
+
const maxIndex = days.length - 1;
|
|
106
|
+
if (value[2] > maxIndex) {
|
|
107
|
+
value[2] = maxIndex;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
indexArr: value,
|
|
112
|
+
rangeArr
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const valueChanged2Obj2 = (value, limit = 3, start, end) => {
|
|
116
|
+
const y = value[0] + START_YEAR;
|
|
117
|
+
const m = value[1] + 1;
|
|
118
|
+
const d = value[2] + 1;
|
|
119
|
+
return valueStr2Obj([y, m, d], limit, start, end);
|
|
120
|
+
};
|
|
121
|
+
const valueNum2String = (value) => {
|
|
122
|
+
return value.map((item, index) => {
|
|
123
|
+
if (index === 0) {
|
|
124
|
+
return item + START_YEAR;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
return wrapDate()(item + 1);
|
|
128
|
+
}
|
|
129
|
+
}).join('-');
|
|
130
|
+
};
|
|
131
|
+
const hasDiff = (currentValue, value, limit = 3) => {
|
|
132
|
+
for (let i = 0; i < limit; i++) {
|
|
133
|
+
if (currentValue[i] !== value[i]) {
|
|
134
|
+
return true;
|
|
21
135
|
}
|
|
22
136
|
}
|
|
23
|
-
return
|
|
24
|
-
}
|
|
25
|
-
const
|
|
26
|
-
const {
|
|
27
|
-
const [datevalue, setDateValue] = useState(value);
|
|
28
|
-
// 存储layout布局信息
|
|
29
|
-
const layoutRef = useRef({});
|
|
30
|
-
const viewRef = useRef(null);
|
|
137
|
+
return false;
|
|
138
|
+
};
|
|
139
|
+
const PickerDate = forwardRef((props, ref) => {
|
|
140
|
+
const { value = '', start = START_DATE, end = END_DATE, fields, bindchange } = props;
|
|
31
141
|
const nodeRef = useRef(null);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
142
|
+
const columnLength = useMemo(() => getColumnLength(fields), [fields]);
|
|
143
|
+
const [formatObj, setFormatObj] = useState(valueStr2Obj(value, columnLength, start, end));
|
|
144
|
+
const timerRef = useRef(null);
|
|
35
145
|
useEffect(() => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
146
|
+
return () => {
|
|
147
|
+
timerRef.current && clearTimeout(timerRef.current);
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
150
|
+
useUpdateEffect(() => {
|
|
151
|
+
const calibratedValue = valueStr2Obj(value, columnLength, start, end);
|
|
152
|
+
setFormatObj(calibratedValue);
|
|
153
|
+
}, [value, columnLength, start, end]);
|
|
154
|
+
const updateValue = useCallback((value = '') => {
|
|
155
|
+
const calibratedValue = valueStr2Obj(value, columnLength, start, end);
|
|
156
|
+
setFormatObj(calibratedValue);
|
|
157
|
+
}, [columnLength, start, end]);
|
|
158
|
+
const _props = useRef(props);
|
|
159
|
+
_props.current = props;
|
|
160
|
+
useImperativeHandle(ref, () => ({
|
|
161
|
+
updateValue,
|
|
162
|
+
getNodeInstance: () => ({
|
|
163
|
+
props: _props,
|
|
164
|
+
nodeRef,
|
|
165
|
+
instance: {
|
|
166
|
+
style: {}
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
}));
|
|
170
|
+
const onChange = useCallback((e) => {
|
|
171
|
+
const { value } = e.detail;
|
|
172
|
+
const currentValue = formatObj.indexArr;
|
|
173
|
+
const newObj = valueChanged2Obj(formatObj, value, columnLength);
|
|
174
|
+
if (hasDiff(currentValue, value, columnLength)) {
|
|
175
|
+
setFormatObj(newObj);
|
|
176
|
+
const newObj2 = valueChanged2Obj2(value, columnLength, start, end);
|
|
177
|
+
if (hasDiff(newObj.indexArr, newObj2.indexArr, columnLength)) {
|
|
178
|
+
timerRef.current && clearTimeout(timerRef.current);
|
|
179
|
+
timerRef.current = setTimeout(() => setFormatObj(newObj2));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
bindchange?.({ detail: { value: valueNum2String(newObj.indexArr) } });
|
|
183
|
+
}, [formatObj, columnLength, bindchange, start, end]);
|
|
184
|
+
const renderColumn = () => {
|
|
185
|
+
return formatObj.rangeArr?.map((item, index) => (
|
|
186
|
+
// @ts-expect-error ignore
|
|
187
|
+
<MpxPickerViewColumn key={index}>
|
|
188
|
+
{item.map((item, index) => {
|
|
189
|
+
return <Text key={index} style={styles.pickerItem}>
|
|
190
|
+
{item}
|
|
191
|
+
</Text>;
|
|
192
|
+
})}
|
|
193
|
+
</MpxPickerViewColumn>));
|
|
66
194
|
};
|
|
67
|
-
return (<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</TouchableWithoutFeedback>
|
|
71
|
-
</DatePicker>);
|
|
195
|
+
return (<MpxPickerView style={styles.pickerContainer} indicator-style={styles.pickerIndicator} value={formatObj.indexArr} bindchange={onChange}>
|
|
196
|
+
{renderColumn()}
|
|
197
|
+
</MpxPickerView>);
|
|
72
198
|
});
|
|
73
|
-
|
|
74
|
-
export default
|
|
199
|
+
PickerDate.displayName = 'MpxPickerDate';
|
|
200
|
+
export default PickerDate;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const wrapDate = (union = '') => (num) => String(num).padStart(2, '0') + union;
|
|
2
|
+
export const START_YEAR = 1900;
|
|
3
|
+
export const END_YEAR = 2099;
|
|
4
|
+
export const years = Array.from({ length: 200 }, (_, index) => index + START_YEAR + '年');
|
|
5
|
+
export const months = Array.from({ length: 12 }, (_, index) => index + 1).map(wrapDate('月'));
|
|
6
|
+
export const daysInMonthLength = (year, month) => {
|
|
7
|
+
return month === 2
|
|
8
|
+
? year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
|
|
9
|
+
? 29
|
|
10
|
+
: 28
|
|
11
|
+
: [4, 6, 9, 11].includes(month)
|
|
12
|
+
? 30
|
|
13
|
+
: 31;
|
|
14
|
+
};
|
|
15
|
+
export const daysInMonth = (year, month) => {
|
|
16
|
+
return Array.from({ length: daysInMonthLength(year, month) }, (_, index) => index + 1).map(wrapDate('日'));
|
|
17
|
+
};
|