@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.
Files changed (155) hide show
  1. package/lib/config.js +2 -1
  2. package/lib/index.js +1 -1
  3. package/lib/platform/json/wx/index.js +6 -4
  4. package/lib/platform/style/wx/index.js +42 -30
  5. package/lib/platform/template/wx/component-config/button.js +20 -3
  6. package/lib/platform/template/wx/component-config/canvas.js +4 -0
  7. package/lib/platform/template/wx/component-config/checkbox-group.js +4 -0
  8. package/lib/platform/template/wx/component-config/checkbox.js +4 -0
  9. package/lib/platform/template/wx/component-config/cover-image.js +7 -1
  10. package/lib/platform/template/wx/component-config/cover-view.js +4 -0
  11. package/lib/platform/template/wx/component-config/fix-component-name.js +3 -2
  12. package/lib/platform/template/wx/component-config/form.js +7 -1
  13. package/lib/platform/template/wx/component-config/icon.js +4 -0
  14. package/lib/platform/template/wx/component-config/image.js +7 -1
  15. package/lib/platform/template/wx/component-config/index.js +5 -1
  16. package/lib/platform/template/wx/component-config/input.js +19 -4
  17. package/lib/platform/template/wx/component-config/label.js +4 -0
  18. package/lib/platform/template/wx/component-config/movable-area.js +7 -1
  19. package/lib/platform/template/wx/component-config/movable-view.js +12 -3
  20. package/lib/platform/template/wx/component-config/navigator.js +4 -0
  21. package/lib/platform/template/wx/component-config/picker-view-column.js +4 -0
  22. package/lib/platform/template/wx/component-config/picker-view.js +7 -1
  23. package/lib/platform/template/wx/component-config/picker.js +7 -1
  24. package/lib/platform/template/wx/component-config/radio-group.js +4 -0
  25. package/lib/platform/template/wx/component-config/radio.js +4 -0
  26. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  27. package/lib/platform/template/wx/component-config/root-portal.js +4 -0
  28. package/lib/platform/template/wx/component-config/scroll-view.js +10 -2
  29. package/lib/platform/template/wx/component-config/sticky-header.js +23 -0
  30. package/lib/platform/template/wx/component-config/sticky-section.js +23 -0
  31. package/lib/platform/template/wx/component-config/swiper-item.js +7 -1
  32. package/lib/platform/template/wx/component-config/swiper.js +12 -3
  33. package/lib/platform/template/wx/component-config/switch.js +4 -0
  34. package/lib/platform/template/wx/component-config/text.js +24 -3
  35. package/lib/platform/template/wx/component-config/textarea.js +17 -2
  36. package/lib/platform/template/wx/component-config/unsupported.js +7 -0
  37. package/lib/platform/template/wx/component-config/video.js +10 -2
  38. package/lib/platform/template/wx/component-config/view.js +11 -1
  39. package/lib/platform/template/wx/component-config/web-view.js +4 -0
  40. package/lib/platform/template/wx/index.js +42 -75
  41. package/lib/react/processJSON.js +7 -6
  42. package/lib/react/processScript.js +1 -18
  43. package/lib/runtime/components/react/context.ts +12 -3
  44. package/lib/runtime/components/react/dist/context.js +4 -1
  45. package/lib/runtime/components/react/dist/event.config.js +0 -1
  46. package/lib/runtime/components/react/dist/getInnerListeners.js +127 -142
  47. package/lib/runtime/components/react/dist/mpx-button.jsx +4 -5
  48. package/lib/runtime/components/react/dist/mpx-canvas/index.jsx +4 -5
  49. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +2 -2
  50. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +2 -3
  51. package/lib/runtime/components/react/dist/mpx-form.jsx +2 -2
  52. package/lib/runtime/components/react/dist/mpx-icon/index.jsx +2 -2
  53. package/lib/runtime/components/react/dist/mpx-image.jsx +2 -2
  54. package/lib/runtime/components/react/dist/mpx-inline-text.jsx +11 -0
  55. package/lib/runtime/components/react/dist/mpx-input.jsx +20 -17
  56. package/lib/runtime/components/react/dist/mpx-keyboard-avoiding-view.jsx +24 -31
  57. package/lib/runtime/components/react/dist/mpx-label.jsx +2 -3
  58. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +2 -2
  59. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +1 -1
  60. package/lib/runtime/components/react/dist/mpx-navigator.jsx +11 -3
  61. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +194 -68
  62. package/lib/runtime/components/react/dist/mpx-picker/dateData.js +17 -0
  63. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +180 -98
  64. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +79 -139
  65. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +190 -90
  66. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +60 -75
  67. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +100 -228
  68. package/lib/runtime/components/react/dist/{mpx-picker-view.jsx → mpx-picker-view/index.jsx} +5 -6
  69. package/lib/runtime/components/react/dist/{mpx-picker-view-column.jsx → mpx-picker-view-column/index.jsx} +66 -18
  70. package/lib/runtime/components/react/dist/{mpx-picker-view-column-item.jsx → mpx-picker-view-column/pickerViewColumnItem.jsx} +8 -5
  71. package/lib/runtime/components/react/dist/{pickerFaces.js → mpx-picker-view-column/pickerViewFaces.js} +6 -0
  72. package/lib/runtime/components/react/dist/mpx-popup/index.jsx +61 -0
  73. package/lib/runtime/components/react/dist/mpx-popup/popupBase.jsx +92 -0
  74. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +2 -2
  75. package/lib/runtime/components/react/dist/mpx-radio.jsx +2 -3
  76. package/lib/runtime/components/react/dist/mpx-rich-text/index.jsx +2 -2
  77. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +207 -29
  78. package/lib/runtime/components/react/dist/mpx-simple-text.jsx +7 -5
  79. package/lib/runtime/components/react/dist/mpx-simple-view.jsx +11 -15
  80. package/lib/runtime/components/react/dist/mpx-sticky-header.jsx +115 -0
  81. package/lib/runtime/components/react/dist/mpx-sticky-section.jsx +45 -0
  82. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +4 -5
  83. package/lib/runtime/components/react/dist/mpx-swiper.jsx +9 -9
  84. package/lib/runtime/components/react/dist/mpx-switch.jsx +3 -5
  85. package/lib/runtime/components/react/dist/mpx-text.jsx +4 -7
  86. package/lib/runtime/components/react/dist/mpx-video.jsx +5 -5
  87. package/lib/runtime/components/react/dist/mpx-view.jsx +23 -9
  88. package/lib/runtime/components/react/dist/mpx-web-view.jsx +16 -13
  89. package/lib/runtime/components/react/dist/useAnimationHooks.js +26 -4
  90. package/lib/runtime/components/react/dist/utils.jsx +14 -2
  91. package/lib/runtime/components/react/event.config.ts +1 -6
  92. package/lib/runtime/components/react/getInnerListeners.ts +148 -191
  93. package/lib/runtime/components/react/mpx-button.tsx +7 -7
  94. package/lib/runtime/components/react/mpx-canvas/index.tsx +25 -17
  95. package/lib/runtime/components/react/mpx-checkbox-group.tsx +4 -3
  96. package/lib/runtime/components/react/mpx-checkbox.tsx +8 -9
  97. package/lib/runtime/components/react/mpx-form.tsx +25 -19
  98. package/lib/runtime/components/react/mpx-icon/index.tsx +4 -3
  99. package/lib/runtime/components/react/mpx-image.tsx +4 -3
  100. package/lib/runtime/components/react/mpx-inline-text.tsx +18 -0
  101. package/lib/runtime/components/react/mpx-input.tsx +24 -21
  102. package/lib/runtime/components/react/mpx-keyboard-avoiding-view.tsx +31 -42
  103. package/lib/runtime/components/react/mpx-label.tsx +4 -5
  104. package/lib/runtime/components/react/mpx-movable-area.tsx +22 -13
  105. package/lib/runtime/components/react/mpx-movable-view.tsx +47 -40
  106. package/lib/runtime/components/react/mpx-navigator.tsx +4 -6
  107. package/lib/runtime/components/react/mpx-picker/date.tsx +226 -69
  108. package/lib/runtime/components/react/mpx-picker/dateData.ts +22 -0
  109. package/lib/runtime/components/react/mpx-picker/index.tsx +242 -118
  110. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +96 -139
  111. package/lib/runtime/components/react/mpx-picker/region.tsx +217 -89
  112. package/lib/runtime/components/react/mpx-picker/selector.tsx +75 -80
  113. package/lib/runtime/components/react/mpx-picker/time.tsx +119 -236
  114. package/lib/runtime/components/react/mpx-picker/type.ts +85 -71
  115. package/lib/runtime/components/react/{mpx-picker-view.tsx → mpx-picker-view/index.tsx} +24 -21
  116. package/lib/runtime/components/react/{mpx-picker-view-column.tsx → mpx-picker-view-column/index.tsx} +72 -21
  117. package/lib/runtime/components/react/{mpx-picker-view-column-item.tsx → mpx-picker-view-column/pickerViewColumnItem.tsx} +8 -5
  118. package/lib/runtime/components/react/{pickerFaces.ts → mpx-picker-view-column/pickerViewFaces.ts} +7 -0
  119. package/lib/runtime/components/react/mpx-popup/index.tsx +86 -0
  120. package/lib/runtime/components/react/mpx-popup/popupBase.tsx +130 -0
  121. package/lib/runtime/components/react/mpx-radio-group.tsx +4 -3
  122. package/lib/runtime/components/react/mpx-radio.tsx +8 -9
  123. package/lib/runtime/components/react/mpx-rich-text/index.tsx +15 -6
  124. package/lib/runtime/components/react/mpx-scroll-view.tsx +326 -96
  125. package/lib/runtime/components/react/mpx-simple-text.tsx +17 -8
  126. package/lib/runtime/components/react/mpx-simple-view.tsx +17 -16
  127. package/lib/runtime/components/react/mpx-sticky-header.tsx +179 -0
  128. package/lib/runtime/components/react/mpx-sticky-section.tsx +96 -0
  129. package/lib/runtime/components/react/mpx-swiper-item.tsx +31 -24
  130. package/lib/runtime/components/react/mpx-swiper.tsx +67 -61
  131. package/lib/runtime/components/react/mpx-switch.tsx +19 -14
  132. package/lib/runtime/components/react/mpx-text.tsx +16 -13
  133. package/lib/runtime/components/react/mpx-video.tsx +36 -35
  134. package/lib/runtime/components/react/mpx-view.tsx +41 -17
  135. package/lib/runtime/components/react/mpx-web-view.tsx +15 -12
  136. package/lib/runtime/components/react/types/getInnerListeners.d.ts +69 -35
  137. package/lib/runtime/components/react/types/global.d.ts +1 -1
  138. package/lib/runtime/components/react/useAnimationHooks.ts +29 -9
  139. package/lib/runtime/components/react/utils.tsx +15 -3
  140. package/lib/runtime/components/web/mini-video-controls.min.js +1 -1
  141. package/lib/runtime/components/web/mpx-input.vue +1 -1
  142. package/lib/runtime/components/web/mpx-scroll-view.vue +21 -4
  143. package/lib/runtime/components/web/mpx-sticky-header.vue +91 -0
  144. package/lib/runtime/components/web/mpx-sticky-section.vue +15 -0
  145. package/lib/runtime/stringify.wxs +2 -2
  146. package/lib/template-compiler/compiler.js +8 -8
  147. package/lib/utils/env.js +1 -1
  148. package/package.json +4 -5
  149. package/LICENSE +0 -433
  150. /package/lib/runtime/components/react/dist/{pickerVIewContext.js → mpx-picker-view/pickerVIewContext.js} +0 -0
  151. /package/lib/runtime/components/react/dist/{pickerViewIndicator.jsx → mpx-picker-view-column/pickerViewIndicator.jsx} +0 -0
  152. /package/lib/runtime/components/react/dist/{pickerViewMask.jsx → mpx-picker-view-column/pickerViewMask.jsx} +0 -0
  153. /package/lib/runtime/components/react/{pickerVIewContext.ts → mpx-picker-view/pickerVIewContext.ts} +0 -0
  154. /package/lib/runtime/components/react/{pickerViewIndicator.tsx → mpx-picker-view-column/pickerViewIndicator.tsx} +0 -0
  155. /package/lib/runtime/components/react/{pickerViewMask.tsx → mpx-picker-view-column/pickerViewMask.tsx} +0 -0
@@ -1,29 +1,18 @@
1
- import React, { useContext, useEffect, useMemo } from 'react';
2
- import { Keyboard, Platform, View } from 'react-native';
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 dismiss = () => {
14
- Keyboard.isVisible() && Keyboard.dismiss();
15
- };
16
- const gesture = useMemo(() => {
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 (<GestureDetector gesture={gesture}>
89
- <View style={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
- {children}
95
- </Animated.View>
96
- </View>
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, extendObject({
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, extendObject({
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
- }, layoutProps), [], { layoutRef });
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, extendObject({
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 = useInnerProps(props, {
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 { 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 from '../useNodesRef'; // 引入辅助函数
5
- function formatTimeStr(time = '') {
6
- let [year, month, day] = time.split('-');
7
- year = ~~year || 2000;
8
- month = ~~month || 1;
9
- day = ~~day || 1;
10
- return new Date(year, month - 1, day);
11
- }
12
- function dateToString(date, fields = 'day') {
13
- const yyyy = date.getFullYear() + '';
14
- const MM = ('0' + (date.getMonth() + 1)).slice(-2);
15
- const dd = ('0' + date.getDate()).slice(-2);
16
- let ret = yyyy;
17
- if (fields === 'month' || fields === 'day') {
18
- ret += `-${MM}`;
19
- if (fields === 'day') {
20
- ret += `-${dd}`;
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 ret;
24
- }
25
- const _DatePicker = forwardRef((props, ref) => {
26
- const { children, start = '1970-01-01', end = '2999-01-01', value, bindchange, bindcancel, disabled, fields, style } = props;
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
- useNodesRef(props, ref, nodeRef, {
33
- style
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
- value && setDateValue(value);
37
- }, [value]);
38
- const onChange = (date) => {
39
- const { fields = 'day' } = props;
40
- const ret = dateToString(date, fields);
41
- setDateValue(ret);
42
- bindchange && bindchange({ detail: { value: ret } });
43
- };
44
- const onDismiss = () => {
45
- bindcancel && bindcancel();
46
- };
47
- const onElementLayout = (layout) => {
48
- viewRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
49
- layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
50
- props.getInnerLayout && props.getInnerLayout(layoutRef);
51
- });
52
- };
53
- const dateProps = {
54
- ref: nodeRef,
55
- precision: fields,
56
- value: formatTimeStr(datevalue),
57
- minDate: formatTimeStr(start),
58
- maxDate: formatTimeStr(end),
59
- onChange,
60
- onDismiss,
61
- disabled
62
- };
63
- const touchProps = {
64
- onLayout: onElementLayout,
65
- ref: viewRef
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 (<DatePicker {...dateProps}>
68
- <TouchableWithoutFeedback>
69
- <View {...touchProps}>{children}</View>
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
- _DatePicker.displayName = 'mpx-picker-date';
74
- export default _DatePicker;
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
+ };