rsuite 5.48.0 → 5.49.0

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 (146) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/Cascader/styles/index.less +1 -0
  3. package/DatePicker/styles/index.less +18 -11
  4. package/DateRangeInput/package.json +7 -0
  5. package/DateRangePicker/styles/index.less +10 -0
  6. package/InputGroup/styles/index.less +1 -0
  7. package/Picker/styles/index.less +20 -0
  8. package/README.md +34 -24
  9. package/Sidenav/styles/index.less +2 -0
  10. package/cjs/Calendar/CalendarContainer.d.ts +2 -0
  11. package/cjs/Calendar/CalendarContainer.js +11 -4
  12. package/cjs/Calendar/CalendarHeader.js +2 -0
  13. package/cjs/Calendar/MonthDropdown.js +7 -2
  14. package/cjs/Calendar/MonthDropdownItem.js +2 -2
  15. package/cjs/Calendar/Table.js +6 -1
  16. package/cjs/Calendar/TimeDropdown.js +17 -10
  17. package/cjs/Calendar/types.d.ts +1 -0
  18. package/cjs/CustomProvider/CustomProvider.d.ts +13 -0
  19. package/cjs/CustomProvider/CustomProvider.js +2 -2
  20. package/cjs/DateInput/DateField.d.ts +9 -31
  21. package/cjs/DateInput/DateField.js +61 -12
  22. package/cjs/DateInput/DateInput.d.ts +7 -2
  23. package/cjs/DateInput/DateInput.js +74 -92
  24. package/cjs/DateInput/index.d.ts +4 -0
  25. package/cjs/DateInput/index.js +19 -1
  26. package/cjs/DateInput/useDateInputState.d.ts +7 -31
  27. package/cjs/DateInput/useDateInputState.js +39 -15
  28. package/cjs/DateInput/useIsFocused.d.ts +7 -0
  29. package/cjs/DateInput/useIsFocused.js +28 -0
  30. package/cjs/DateInput/useKeyboardInputEvent.d.ts +10 -0
  31. package/cjs/DateInput/useKeyboardInputEvent.js +44 -0
  32. package/cjs/DateInput/utils.d.ts +23 -1
  33. package/cjs/DateInput/utils.js +155 -51
  34. package/cjs/DatePicker/DatePicker.d.ts +20 -7
  35. package/cjs/DatePicker/DatePicker.js +215 -245
  36. package/cjs/DatePicker/PickerIndicator.d.ts +10 -0
  37. package/cjs/DatePicker/PickerIndicator.js +48 -0
  38. package/cjs/DatePicker/PickerLabel.d.ts +9 -0
  39. package/cjs/DatePicker/PickerLabel.js +23 -0
  40. package/cjs/DatePicker/Toolbar.js +3 -21
  41. package/cjs/DatePicker/utils.d.ts +5 -1
  42. package/cjs/DatePicker/utils.js +17 -1
  43. package/cjs/DateRangeInput/DateRangeInput.d.ts +29 -0
  44. package/cjs/DateRangeInput/DateRangeInput.js +244 -0
  45. package/cjs/DateRangeInput/index.d.ts +3 -0
  46. package/cjs/DateRangeInput/index.js +9 -0
  47. package/cjs/DateRangeInput/utils.d.ts +61 -0
  48. package/cjs/DateRangeInput/utils.js +146 -0
  49. package/cjs/DateRangePicker/DateRangePicker.js +12 -2
  50. package/cjs/FormControl/FormControl.js +2 -1
  51. package/cjs/Input/Input.d.ts +11 -0
  52. package/cjs/Input/Input.js +11 -8
  53. package/cjs/MultiCascader/MultiCascader.js +3 -1
  54. package/cjs/Overlay/OverlayTrigger.d.ts +3 -0
  55. package/cjs/Overlay/OverlayTrigger.js +5 -0
  56. package/cjs/Picker/PickerToggle.js +2 -1
  57. package/cjs/Picker/usePickerRef.d.ts +17 -0
  58. package/cjs/Picker/usePickerRef.js +82 -0
  59. package/cjs/index.d.ts +2 -0
  60. package/cjs/index.js +3 -1
  61. package/cjs/locales/index.d.ts +2 -2
  62. package/cjs/useMediaQuery/useMediaQuery.js +2 -2
  63. package/cjs/utils/index.d.ts +2 -0
  64. package/cjs/utils/index.js +8 -2
  65. package/cjs/utils/useCustom.js +1 -1
  66. package/cjs/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  67. package/cjs/utils/useIsomorphicLayoutEffect.js +9 -0
  68. package/dist/rsuite-no-reset-rtl.css +51 -141
  69. package/dist/rsuite-no-reset-rtl.min.css +1 -1
  70. package/dist/rsuite-no-reset-rtl.min.css.map +1 -1
  71. package/dist/rsuite-no-reset.css +51 -141
  72. package/dist/rsuite-no-reset.min.css +1 -1
  73. package/dist/rsuite-no-reset.min.css.map +1 -1
  74. package/dist/rsuite-rtl.css +51 -9
  75. package/dist/rsuite-rtl.min.css +1 -1
  76. package/dist/rsuite-rtl.min.css.map +1 -1
  77. package/dist/rsuite.css +51 -9
  78. package/dist/rsuite.js +4804 -250
  79. package/dist/rsuite.js.map +1 -1
  80. package/dist/rsuite.min.css +1 -1
  81. package/dist/rsuite.min.css.map +1 -1
  82. package/dist/rsuite.min.js +1 -1
  83. package/dist/rsuite.min.js.map +1 -1
  84. package/esm/Calendar/CalendarContainer.d.ts +2 -0
  85. package/esm/Calendar/CalendarContainer.js +12 -5
  86. package/esm/Calendar/CalendarHeader.js +2 -0
  87. package/esm/Calendar/MonthDropdown.js +7 -2
  88. package/esm/Calendar/MonthDropdownItem.js +2 -2
  89. package/esm/Calendar/Table.js +6 -1
  90. package/esm/Calendar/TimeDropdown.js +17 -10
  91. package/esm/Calendar/types.d.ts +1 -0
  92. package/esm/CustomProvider/CustomProvider.d.ts +13 -0
  93. package/esm/CustomProvider/CustomProvider.js +3 -3
  94. package/esm/DateInput/DateField.d.ts +9 -31
  95. package/esm/DateInput/DateField.js +61 -12
  96. package/esm/DateInput/DateInput.d.ts +7 -2
  97. package/esm/DateInput/DateInput.js +77 -95
  98. package/esm/DateInput/index.d.ts +4 -0
  99. package/esm/DateInput/index.js +4 -0
  100. package/esm/DateInput/useDateInputState.d.ts +7 -31
  101. package/esm/DateInput/useDateInputState.js +41 -18
  102. package/esm/DateInput/useIsFocused.d.ts +7 -0
  103. package/esm/DateInput/useIsFocused.js +22 -0
  104. package/esm/DateInput/useKeyboardInputEvent.d.ts +10 -0
  105. package/esm/DateInput/useKeyboardInputEvent.js +38 -0
  106. package/esm/DateInput/utils.d.ts +23 -1
  107. package/esm/DateInput/utils.js +150 -51
  108. package/esm/DatePicker/DatePicker.d.ts +20 -7
  109. package/esm/DatePicker/DatePicker.js +218 -248
  110. package/esm/DatePicker/PickerIndicator.d.ts +10 -0
  111. package/esm/DatePicker/PickerIndicator.js +42 -0
  112. package/esm/DatePicker/PickerLabel.d.ts +9 -0
  113. package/esm/DatePicker/PickerLabel.js +17 -0
  114. package/esm/DatePicker/Toolbar.js +3 -21
  115. package/esm/DatePicker/utils.d.ts +5 -1
  116. package/esm/DatePicker/utils.js +16 -1
  117. package/esm/DateRangeInput/DateRangeInput.d.ts +29 -0
  118. package/esm/DateRangeInput/DateRangeInput.js +237 -0
  119. package/esm/DateRangeInput/index.d.ts +3 -0
  120. package/esm/DateRangeInput/index.js +3 -0
  121. package/esm/DateRangeInput/utils.d.ts +61 -0
  122. package/esm/DateRangeInput/utils.js +137 -0
  123. package/esm/DateRangePicker/DateRangePicker.js +12 -2
  124. package/esm/FormControl/FormControl.js +2 -1
  125. package/esm/Input/Input.d.ts +11 -0
  126. package/esm/Input/Input.js +12 -9
  127. package/esm/MultiCascader/MultiCascader.js +4 -2
  128. package/esm/Overlay/OverlayTrigger.d.ts +3 -0
  129. package/esm/Overlay/OverlayTrigger.js +5 -0
  130. package/esm/Picker/PickerToggle.js +2 -1
  131. package/esm/Picker/usePickerRef.d.ts +17 -0
  132. package/esm/Picker/usePickerRef.js +77 -0
  133. package/esm/index.d.ts +2 -0
  134. package/esm/index.js +1 -0
  135. package/esm/locales/index.d.ts +2 -2
  136. package/esm/useMediaQuery/useMediaQuery.js +2 -2
  137. package/esm/utils/index.d.ts +2 -0
  138. package/esm/utils/index.js +3 -1
  139. package/esm/utils/useCustom.js +2 -2
  140. package/esm/utils/useIsomorphicLayoutEffect.d.ts +3 -0
  141. package/esm/utils/useIsomorphicLayoutEffect.js +4 -0
  142. package/package.json +1 -1
  143. package/styles/color-modes/dark.less +1 -0
  144. package/styles/color-modes/high-contrast.less +1 -0
  145. package/styles/color-modes/light.less +1 -0
  146. package/styles/normalize.less +230 -231
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ interface PickerIndicatorProps {
3
+ loading?: boolean;
4
+ caretAs?: React.ElementType | null;
5
+ onClose?: () => void;
6
+ showCleanButton?: boolean;
7
+ as?: React.ElementType;
8
+ }
9
+ declare const PickerIndicator: ({ loading, caretAs, onClose, showCleanButton, as: Component }: PickerIndicatorProps) => JSX.Element;
10
+ export default PickerIndicator;
@@ -0,0 +1,42 @@
1
+ 'use client';
2
+ import React from 'react';
3
+ import { Icon } from '@rsuite/icons';
4
+ import { useCustom, useClassNames } from '../utils';
5
+ import InputGroup from '../InputGroup';
6
+ import CloseButton from '../CloseButton';
7
+ import Loader from '../Loader';
8
+ var PickerIndicator = function PickerIndicator(_ref) {
9
+ var loading = _ref.loading,
10
+ caretAs = _ref.caretAs,
11
+ onClose = _ref.onClose,
12
+ showCleanButton = _ref.showCleanButton,
13
+ _ref$as = _ref.as,
14
+ Component = _ref$as === void 0 ? InputGroup.Addon : _ref$as;
15
+ var _useCustom = useCustom(),
16
+ locale = _useCustom.locale;
17
+ var _useClassNames = useClassNames('picker'),
18
+ prefix = _useClassNames.prefix;
19
+ var addon = function addon() {
20
+ if (loading) {
21
+ return /*#__PURE__*/React.createElement(Loader, {
22
+ className: prefix('loader'),
23
+ "data-testid": "spinner"
24
+ });
25
+ }
26
+ if (showCleanButton) {
27
+ return /*#__PURE__*/React.createElement(CloseButton, {
28
+ className: prefix('clean'),
29
+ tabIndex: -1,
30
+ locale: {
31
+ closeLabel: locale === null || locale === void 0 ? void 0 : locale.clear
32
+ },
33
+ onClick: onClose
34
+ });
35
+ }
36
+ return caretAs && /*#__PURE__*/React.createElement(Icon, {
37
+ as: caretAs
38
+ });
39
+ };
40
+ return /*#__PURE__*/React.createElement(Component, null, addon());
41
+ };
42
+ export default PickerIndicator;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface PickerLabelProps {
3
+ id: string;
4
+ className?: string;
5
+ children?: React.ReactNode;
6
+ as?: React.ElementType;
7
+ }
8
+ declare const PickerLabel: ({ children, className, as: Component, ...rest }: PickerLabelProps) => JSX.Element | null;
9
+ export default PickerLabel;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import _extends from "@babel/runtime/helpers/esm/extends";
3
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
4
+ import React from 'react';
5
+ import InputGroup from '../InputGroup';
6
+ var PickerLabel = function PickerLabel(_ref) {
7
+ var children = _ref.children,
8
+ className = _ref.className,
9
+ _ref$as = _ref.as,
10
+ Component = _ref$as === void 0 ? InputGroup.Addon : _ref$as,
11
+ rest = _objectWithoutPropertiesLoose(_ref, ["children", "className", "as"]);
12
+ return children ? /*#__PURE__*/React.createElement(Component, _extends({
13
+ "data-testid": "picker-label",
14
+ className: className
15
+ }, rest), children) : null;
16
+ };
17
+ export default PickerLabel;
@@ -2,20 +2,15 @@
2
2
  import _extends from "@babel/runtime/helpers/esm/extends";
3
3
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
4
4
  import React from 'react';
5
- import PropTypes from 'prop-types';
6
5
  import Button from '../Button';
7
6
  import { useClassNames } from '../utils';
8
7
  import PredefinedRanges from './PredefinedRanges';
9
8
  import Stack from '../Stack';
10
9
  var SubmitButton = function SubmitButton(_ref) {
11
- var hide = _ref.hide,
12
- disabledOkBtn = _ref.disabledOkBtn,
10
+ var disabledOkBtn = _ref.disabledOkBtn,
13
11
  calendarDate = _ref.calendarDate,
14
12
  onOk = _ref.onOk,
15
13
  children = _ref.children;
16
- if (hide) {
17
- return null;
18
- }
19
14
  var disabled = disabledOkBtn === null || disabledOkBtn === void 0 ? void 0 : disabledOkBtn(calendarDate);
20
15
  return /*#__PURE__*/React.createElement(Button, {
21
16
  appearance: "primary",
@@ -28,7 +23,7 @@ var SubmitButton = function SubmitButton(_ref) {
28
23
  /**
29
24
  * Toolbar for DatePicker and DateRangePicker
30
25
  */
31
- var Toolbar = /*#__PURE__*/React.forwardRef(function (props, ref) {
26
+ var Toolbar = /*#__PURE__*/React.forwardRef(function Toolbar(props, ref) {
32
27
  var className = props.className,
33
28
  _props$classPrefix = props.classPrefix,
34
29
  classPrefix = _props$classPrefix === void 0 ? 'picker-toolbar' : _props$classPrefix,
@@ -64,23 +59,10 @@ var Toolbar = /*#__PURE__*/React.forwardRef(function (props, ref) {
64
59
  onShortcutClick: onShortcutClick
65
60
  }), /*#__PURE__*/React.createElement("div", {
66
61
  className: prefix('right')
67
- }, /*#__PURE__*/React.createElement(SubmitButton, {
62
+ }, !hideOkBtn && /*#__PURE__*/React.createElement(SubmitButton, {
68
63
  disabledOkBtn: disabledOkBtn,
69
- hide: hideOkBtn,
70
64
  calendarDate: calendarDate,
71
65
  onOk: onOk
72
66
  }, locale === null || locale === void 0 ? void 0 : locale.ok)));
73
67
  });
74
- Toolbar.displayName = 'Toolbar';
75
- Toolbar.propTypes = {
76
- ranges: PropTypes.array,
77
- className: PropTypes.string,
78
- classPrefix: PropTypes.string,
79
- calendarDate: PropTypes.oneOfType([PropTypes.instanceOf(Date), PropTypes.arrayOf(PropTypes.instanceOf(Date))]).isRequired,
80
- onShortcutClick: PropTypes.func,
81
- onOk: PropTypes.func,
82
- disabledShortcut: PropTypes.func,
83
- disabledOkBtn: PropTypes.func,
84
- hideOkBtn: PropTypes.bool
85
- };
86
68
  export default Toolbar;
@@ -1,5 +1,5 @@
1
1
  import { ToolbarProps } from './Toolbar';
2
- import { InnerRange } from './types';
2
+ import { InnerRange, RangeType } from './types';
3
3
  import { DateRange } from '../DateRangePicker/types';
4
4
  export declare function getDefaultRanges<T extends Date | DateRange>(value: T): InnerRange<T>[];
5
5
  /**
@@ -8,3 +8,7 @@ export declare function getDefaultRanges<T extends Date | DateRange>(value: T):
8
8
  * @param calendarDate
9
9
  */
10
10
  export declare const getRanges: <T extends Date | DateRange>({ ranges, calendarDate }: Pick<ToolbarProps<T, T>, "calendarDate" | "ranges">) => InnerRange<T>[];
11
+ export declare function splitRanges(ranges?: RangeType<Date>[]): {
12
+ sideRanges: RangeType<Date>[];
13
+ bottomRanges: RangeType<Date>[];
14
+ };
@@ -51,4 +51,19 @@ export var getRanges = function getRanges(_ref3) {
51
51
  return typeof ranges === 'undefined' ? getDefaultRanges(calendarDate) : ranges.map(generateRangesIterator({
52
52
  calendarDate: calendarDate
53
53
  }));
54
- };
54
+ };
55
+ export function splitRanges(ranges) {
56
+ // The shortcut option on the left side of the calendar panel
57
+ var sideRanges = (ranges === null || ranges === void 0 ? void 0 : ranges.filter(function (range) {
58
+ return (range === null || range === void 0 ? void 0 : range.placement) === 'left';
59
+ })) || [];
60
+
61
+ // The shortcut option on the bottom of the calendar panel
62
+ var bottomRanges = (ranges === null || ranges === void 0 ? void 0 : ranges.filter(function (range) {
63
+ return (range === null || range === void 0 ? void 0 : range.placement) === 'bottom' || (range === null || range === void 0 ? void 0 : range.placement) === undefined;
64
+ })) || [];
65
+ return {
66
+ sideRanges: sideRanges,
67
+ bottomRanges: bottomRanges
68
+ };
69
+ }
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { InputProps } from '../Input';
3
+ import { FormControlBaseProps } from '../@types/common';
4
+ declare type ValueType = [Date | null, Date | null] | null;
5
+ export interface DateRangeInputProps extends Omit<InputProps, 'value' | 'onChange' | 'defaultValue'>, FormControlBaseProps<ValueType> {
6
+ /**
7
+ * The character between the start and end dates.
8
+ * @default ' ~ '
9
+ **/
10
+ character?: string;
11
+ /**
12
+ * Format of the date when rendered in the input. Format of the string is based on Unicode Technical Standard.
13
+ *
14
+ * @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
15
+ * @default 'yyyy-MM-dd'
16
+ **/
17
+ format?: string;
18
+ /**
19
+ * The `placeholder` prop defines the text displayed in a form control when the control has no value.
20
+ */
21
+ placeholder?: string;
22
+ }
23
+ /**
24
+ * The DateRangeInput component lets users select a date with the keyboard.
25
+ * @version 5.59.0
26
+ * @see https://rsuitejs.com/components/date-range-input/
27
+ */
28
+ declare const DateRangeInput: React.ForwardRefExoticComponent<DateRangeInputProps & React.RefAttributes<unknown>>;
29
+ export default DateRangeInput;
@@ -0,0 +1,237 @@
1
+ 'use client';
2
+ import _extends from "@babel/runtime/helpers/esm/extends";
3
+ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
4
+ import React, { useState, useRef, useMemo } from 'react';
5
+ import PropTypes from 'prop-types';
6
+ import Input from '../Input';
7
+ import { mergeRefs, useClassNames, useCustom, useControlled, useEventCallback } from '../utils';
8
+ import { validateDateTime, isFieldFullValue, useDateInputState, useInputSelection, useKeyboardInputEvent, useIsFocused } from '../DateInput';
9
+ import { getInputSelectedState, DateType, getDateType, isSwitchDateType } from './utils';
10
+ /**
11
+ * The DateRangeInput component lets users select a date with the keyboard.
12
+ * @version 5.59.0
13
+ * @see https://rsuitejs.com/components/date-range-input/
14
+ */
15
+ var DateRangeInput = /*#__PURE__*/React.forwardRef(function (props, ref) {
16
+ var className = props.className,
17
+ _props$classPrefix = props.classPrefix,
18
+ classPrefix = _props$classPrefix === void 0 ? 'date-range-input' : _props$classPrefix,
19
+ _props$character = props.character,
20
+ character = _props$character === void 0 ? ' ~ ' : _props$character,
21
+ _props$format = props.format,
22
+ formatStr = _props$format === void 0 ? 'yyyy-MM-dd' : _props$format,
23
+ valueProp = props.value,
24
+ _props$defaultValue = props.defaultValue,
25
+ defaultValue = _props$defaultValue === void 0 ? [] : _props$defaultValue,
26
+ placeholder = props.placeholder,
27
+ onChange = props.onChange,
28
+ onKeyDown = props.onKeyDown,
29
+ onBlur = props.onBlur,
30
+ onFocus = props.onFocus,
31
+ rest = _objectWithoutPropertiesLoose(props, ["className", "classPrefix", "character", "format", "value", "defaultValue", "placeholder", "onChange", "onKeyDown", "onBlur", "onFocus"]);
32
+ var _useClassNames = useClassNames(classPrefix),
33
+ withClassPrefix = _useClassNames.withClassPrefix,
34
+ merge = _useClassNames.merge;
35
+ var classes = merge(className, withClassPrefix());
36
+ var inputRef = useRef();
37
+ var _useState = useState({
38
+ selectedPattern: 'y',
39
+ selectionStart: 0,
40
+ selectionEnd: 0
41
+ }),
42
+ selectedState = _useState[0],
43
+ setSelectedState = _useState[1];
44
+ var _useCustom = useCustom('Calendar'),
45
+ locale = _useCustom.locale;
46
+ var rangeFormatStr = "" + formatStr + character + formatStr;
47
+ var dateLocale = locale.dateLocale;
48
+ var _useControlled = useControlled(valueProp, defaultValue),
49
+ value = _useControlled[0],
50
+ setValue = _useControlled[1],
51
+ isControlled = _useControlled[2];
52
+ var _useState2 = useState(DateType.Start),
53
+ dateType = _useState2[0],
54
+ setDateType = _useState2[1];
55
+ var dateInputOptions = {
56
+ formatStr: formatStr,
57
+ locale: dateLocale,
58
+ isControlledDate: isControlled
59
+ };
60
+ var startDateState = useDateInputState(_extends({}, dateInputOptions, {
61
+ date: value === null || value === void 0 ? void 0 : value[0]
62
+ }));
63
+ var endDateState = useDateInputState(_extends({}, dateInputOptions, {
64
+ date: value === null || value === void 0 ? void 0 : value[1]
65
+ }));
66
+ var getActiveState = function getActiveState(type) {
67
+ if (type === void 0) {
68
+ type = dateType;
69
+ }
70
+ return type === DateType.Start ? startDateState : endDateState;
71
+ };
72
+ var _useIsFocused = useIsFocused({
73
+ onBlur: onBlur,
74
+ onFocus: onFocus
75
+ }),
76
+ focused = _useIsFocused[0],
77
+ focusEventProps = _useIsFocused[1];
78
+ var renderedValue = useMemo(function () {
79
+ var dateString = startDateState.toDateString() + character + endDateState.toDateString();
80
+ if (!startDateState.isEmptyValue() || !endDateState.isEmptyValue()) {
81
+ return dateString;
82
+ }
83
+ return !focused ? '' : dateString;
84
+ }, [character, endDateState, focused, startDateState]);
85
+ var keyPressOptions = {
86
+ formatStr: formatStr,
87
+ rangeFormatStr: rangeFormatStr,
88
+ localize: dateLocale.localize,
89
+ selectedMonth: getActiveState().dateField.month,
90
+ dateString: renderedValue,
91
+ dateType: dateType,
92
+ character: character
93
+ };
94
+ var setSelectionRange = useInputSelection(inputRef);
95
+ var handleChange = useEventCallback(function (date, event) {
96
+ var nextValue = dateType === DateType.Start ? [date, value === null || value === void 0 ? void 0 : value[1]] : [value === null || value === void 0 ? void 0 : value[0], date];
97
+ onChange === null || onChange === void 0 ? void 0 : onChange(nextValue, event);
98
+ setValue(nextValue);
99
+ });
100
+ var onSegmentChange = useEventCallback(function (event, nextDirection) {
101
+ var input = event.target;
102
+ var key = event.key;
103
+ var direction = nextDirection || (key === 'ArrowRight' ? 'right' : 'left');
104
+ if (input.selectionEnd === null || input.selectionStart === null) {
105
+ return;
106
+ }
107
+ var cursorIndex = direction === 'right' ? input.selectionEnd : input.selectionStart;
108
+ var nextDateType = dateType;
109
+ if (isSwitchDateType(renderedValue, character, cursorIndex, direction)) {
110
+ nextDateType = dateType === DateType.Start ? DateType.End : DateType.Start;
111
+ setDateType(nextDateType);
112
+ }
113
+ var state = getInputSelectedState(_extends({}, keyPressOptions, {
114
+ dateType: nextDateType,
115
+ selectedMonth: getActiveState(nextDateType).dateField.month,
116
+ input: input,
117
+ direction: direction
118
+ }));
119
+ setSelectionRange(state.selectionStart, state.selectionEnd);
120
+ setSelectedState(state);
121
+ });
122
+ var onSegmentValueChange = useEventCallback(function (event) {
123
+ var input = event.target;
124
+ var key = event.key;
125
+ var offset = key === 'ArrowUp' ? 1 : -1;
126
+ var state = getInputSelectedState(_extends({}, keyPressOptions, {
127
+ input: input,
128
+ valueOffset: offset
129
+ }));
130
+ setSelectedState(state);
131
+ getActiveState().setDateOffset(state.selectedPattern, offset, function (date) {
132
+ return handleChange(date, event);
133
+ });
134
+ setSelectionRange(state.selectionStart, state.selectionEnd);
135
+ });
136
+ var onSegmentValueChangeWithNumericKeys = useEventCallback(function (event) {
137
+ var input = event.target;
138
+ var key = event.key;
139
+ var pattern = selectedState.selectedPattern;
140
+ if (!pattern) {
141
+ return;
142
+ }
143
+ var field = getActiveState().getDateField(pattern);
144
+ var value = parseInt(key, 10);
145
+ var padValue = parseInt("" + (field.value || '') + key, 10);
146
+ var newValue = value;
147
+
148
+ // Check if the value entered by the user is a valid date
149
+ if (validateDateTime(field.name, padValue)) {
150
+ newValue = padValue;
151
+ }
152
+ if (pattern === 'M') {
153
+ // Month cannot be less than 1.
154
+ newValue = Math.max(1, newValue);
155
+ }
156
+ getActiveState().setDateField(pattern, newValue, function (date) {
157
+ return handleChange(date, event);
158
+ });
159
+
160
+ // The currently selected month will be retained as a parameter of getInputSelectedState,
161
+ // but if the user enters a month, the month value will be replaced with the value entered by the user.
162
+ var selectedMonth = pattern === 'M' ? newValue : getActiveState().dateField.month;
163
+ var nextState = getInputSelectedState(_extends({}, keyPressOptions, {
164
+ input: input,
165
+ selectedMonth: selectedMonth
166
+ }));
167
+ setSelectedState(nextState);
168
+ setSelectionRange(nextState.selectionStart, nextState.selectionEnd);
169
+
170
+ // If the field is full value, move the cursor to the next field
171
+ if (isFieldFullValue(formatStr, newValue, pattern) && input.selectionEnd !== input.value.length) {
172
+ onSegmentChange(event, 'right');
173
+ }
174
+ });
175
+ var onSegmentValueRemove = useEventCallback(function (event) {
176
+ var input = event.target;
177
+ if (selectedState.selectedPattern) {
178
+ var nextState = getInputSelectedState(_extends({}, keyPressOptions, {
179
+ input: input,
180
+ valueOffset: null
181
+ }));
182
+ setSelectedState(nextState);
183
+ setSelectionRange(nextState.selectionStart, nextState.selectionEnd);
184
+ getActiveState().setDateField(selectedState.selectedPattern, null, function (date) {
185
+ return handleChange(date, event);
186
+ });
187
+ }
188
+ });
189
+ var handleClick = useEventCallback(function (event) {
190
+ var input = event.target;
191
+ if (input.selectionStart === null) {
192
+ return;
193
+ }
194
+ var cursorIndex = input.selectionStart === renderedValue.length ? 0 : input.selectionStart;
195
+ var dateType = getDateType(renderedValue, character, cursorIndex);
196
+ var state = getInputSelectedState(_extends({}, keyPressOptions, {
197
+ dateType: dateType,
198
+ selectedMonth: getActiveState(dateType).dateField.month,
199
+ input: input
200
+ }));
201
+ setDateType(dateType);
202
+ setSelectedState(state);
203
+ setSelectionRange(state.selectionStart, state.selectionEnd);
204
+ });
205
+ var onKeyboardInput = useKeyboardInputEvent({
206
+ onSegmentChange: onSegmentChange,
207
+ onSegmentValueChange: onSegmentValueChange,
208
+ onSegmentValueChangeWithNumericKeys: onSegmentValueChangeWithNumericKeys,
209
+ onSegmentValueRemove: onSegmentValueRemove,
210
+ onKeyDown: onKeyDown
211
+ });
212
+ return /*#__PURE__*/React.createElement(Input, _extends({
213
+ inputMode: focused ? 'numeric' : 'text',
214
+ autoComplete: "off",
215
+ autoCorrect: "off",
216
+ spellCheck: false,
217
+ className: classes,
218
+ ref: mergeRefs(inputRef, ref),
219
+ onKeyDown: onKeyboardInput,
220
+ onClick: handleClick,
221
+ value: renderedValue,
222
+ placeholder: placeholder || rangeFormatStr
223
+ }, focusEventProps, rest));
224
+ });
225
+ DateRangeInput.displayName = 'DateRangeInput';
226
+ DateRangeInput.propTypes = {
227
+ character: PropTypes.string,
228
+ className: PropTypes.string,
229
+ classPrefix: PropTypes.string,
230
+ format: PropTypes.string,
231
+ placeholder: PropTypes.string,
232
+ onChange: PropTypes.func,
233
+ onKeyDown: PropTypes.func,
234
+ onFocus: PropTypes.func,
235
+ onBlur: PropTypes.func
236
+ };
237
+ export default DateRangeInput;
@@ -0,0 +1,3 @@
1
+ import DateRangeInput from './DateRangeInput';
2
+ export type { DateRangeInputProps } from './DateRangeInput';
3
+ export default DateRangeInput;
@@ -0,0 +1,3 @@
1
+ 'use client';
2
+ import DateRangeInput from './DateRangeInput';
3
+ export default DateRangeInput;
@@ -0,0 +1,61 @@
1
+ import { type Locale } from 'date-fns';
2
+ export declare enum DateType {
3
+ Start = "Start",
4
+ End = "End"
5
+ }
6
+ interface SelectedStateOptions {
7
+ /**
8
+ * The input element
9
+ */
10
+ input: HTMLInputElement;
11
+ /**
12
+ * The direction of the arrow key, left or right
13
+ */
14
+ direction?: 'left' | 'right';
15
+ /**
16
+ * Format of the string is based on Unicode Technical Standard.
17
+ * @see https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
18
+ */
19
+ formatStr: string;
20
+ /**
21
+ * The format string of the range, which is used to calculate the selection range.
22
+ */
23
+ rangeFormatStr: string;
24
+ /**
25
+ * The locale object, date-fns locale object
26
+ */
27
+ localize: Locale['localize'];
28
+ /**
29
+ * The selected month, used to calculate the offset of the character selection range
30
+ */
31
+ selectedMonth: number | null;
32
+ /**
33
+ * The offset of the value, which is used to calculate the month.
34
+ * This value will be changed when pressing the up and down arrow keys.
35
+ */
36
+ valueOffset?: number | null;
37
+ /**
38
+ * The date is rendered in string format according to format
39
+ */
40
+ dateString: string;
41
+ /**
42
+ * The character that separates two dates
43
+ *
44
+ * Only for `DateRangeInput`
45
+ **/
46
+ character: string;
47
+ /**
48
+ * The date type, start or end
49
+ *
50
+ * Only for `DateRangeInput`
51
+ */
52
+ dateType: DateType;
53
+ }
54
+ export declare function getInputSelectedState(options: SelectedStateOptions): {
55
+ selectionStart: number;
56
+ selectionEnd: number;
57
+ selectedPattern: string;
58
+ };
59
+ export declare function getDateType(dateString: string, character: string, cursorIndex: number): DateType;
60
+ export declare function isSwitchDateType(dateString: string, character: string, cursorIndex: number, direction: 'right' | 'left'): boolean;
61
+ export {};
@@ -0,0 +1,137 @@
1
+ 'use client';
2
+ import _extends from "@babel/runtime/helpers/esm/extends";
3
+ import { getSelectIndexGap, isCursorAfterMonth, getDatePattern } from '../DateInput';
4
+ export var DateType;
5
+ (function (DateType) {
6
+ DateType["Start"] = "Start";
7
+ DateType["End"] = "End";
8
+ })(DateType || (DateType = {}));
9
+ export function getInputSelectedState(options) {
10
+ var input = options.input,
11
+ direction = options.direction,
12
+ formatStr = options.formatStr,
13
+ rangeFormatStr = options.rangeFormatStr,
14
+ localize = options.localize,
15
+ selectedMonth = options.selectedMonth,
16
+ _options$valueOffset = options.valueOffset,
17
+ valueOffset = _options$valueOffset === void 0 ? 0 : _options$valueOffset,
18
+ character = options.character,
19
+ dateType = options.dateType,
20
+ dateString = options.dateString;
21
+ var getPatternSelectedIndexes = function getPatternSelectedIndexes(pattern) {
22
+ var selectionStart = 0;
23
+ var selectionEnd = 0;
24
+ if (dateType === DateType.Start) {
25
+ selectionStart = rangeFormatStr.indexOf(pattern);
26
+ selectionEnd = rangeFormatStr.split(character)[0].lastIndexOf(pattern) + 1;
27
+ } else if (dateType === DateType.End) {
28
+ var position = rangeFormatStr.indexOf(character) + character.length;
29
+ selectionStart = rangeFormatStr.indexOf(pattern, position);
30
+ selectionEnd = rangeFormatStr.lastIndexOf(pattern) + 1;
31
+ }
32
+ var endDateGap = dateString.indexOf(character) - rangeFormatStr.indexOf(character);
33
+
34
+ // If the date type is end, and the end date is not selected, the selection range needs to be adjusted.
35
+ if (dateType === DateType.End && endDateGap > 0) {
36
+ selectionStart += endDateGap;
37
+ selectionEnd += endDateGap;
38
+ }
39
+ var gap = getSelectIndexGap({
40
+ pattern: pattern,
41
+ formatStr: formatStr,
42
+ valueOffset: valueOffset,
43
+ selectedMonth: selectedMonth,
44
+ localize: localize
45
+ });
46
+ var isSelectedMonth = pattern === 'M';
47
+ var isNullMonth = selectedMonth === null && !(isSelectedMonth && valueOffset !== 0);
48
+
49
+ // If the month is null and the valueOffset is 0, the month will not be updated, and the gap is 0 at this time.
50
+ if (isNullMonth) {
51
+ return {
52
+ selectionStart: selectionStart,
53
+ selectionEnd: selectionEnd
54
+ };
55
+ }
56
+ if (isSelectedMonth) {
57
+ return {
58
+ selectionStart: selectionStart,
59
+ selectionEnd: selectionEnd + gap
60
+ };
61
+ }
62
+ if (isCursorAfterMonth(selectionStart, formatStr)) {
63
+ return {
64
+ selectionStart: selectionStart + gap,
65
+ selectionEnd: selectionEnd + gap
66
+ };
67
+ }
68
+ return {
69
+ selectionStart: selectionStart,
70
+ selectionEnd: selectionEnd
71
+ };
72
+ };
73
+ if (typeof input.selectionEnd === 'number' && typeof input.selectionStart === 'number') {
74
+ var index = input.selectionStart;
75
+ var positionOffset = -1;
76
+ if (direction === 'left') {
77
+ index = input.selectionStart - 1;
78
+ } else if (direction === 'right') {
79
+ index = input.selectionEnd + 1;
80
+ positionOffset = 1;
81
+ }
82
+
83
+ // The start position of the index of the end date
84
+ var endDateIndex = dateString.indexOf(character) + character.length;
85
+ var datePattern = getDatePattern({
86
+ selectionIndex: dateType === DateType.End ? index - endDateIndex : index,
87
+ positionOffset: positionOffset,
88
+ formatStr: formatStr,
89
+ dateString: dateString,
90
+ valueOffset: valueOffset,
91
+ selectedMonth: selectedMonth,
92
+ localize: localize
93
+ });
94
+ var indexes = getPatternSelectedIndexes(datePattern);
95
+ return _extends({
96
+ selectedPattern: datePattern
97
+ }, indexes);
98
+ }
99
+ return {
100
+ selectedPattern: 'y',
101
+ selectionStart: 0,
102
+ selectionEnd: 0
103
+ };
104
+ }
105
+ export function getDateType(dateString, character, cursorIndex) {
106
+ var splitIndex = dateString.indexOf(character);
107
+ if (cursorIndex > splitIndex) {
108
+ return DateType.End;
109
+ }
110
+ return DateType.Start;
111
+ }
112
+ export function isSwitchDateType(dateString, character, cursorIndex, direction) {
113
+ var characterIndex = dateString.indexOf(character);
114
+ var startIndex = cursorIndex;
115
+ var endIndex = startIndex + character.length;
116
+ if (direction === 'left') {
117
+ endIndex = cursorIndex;
118
+ startIndex = endIndex - character.length;
119
+ }
120
+
121
+ // Check whether the cursor is a separator before and after
122
+ if (dateString.substring(startIndex, endIndex) === character) {
123
+ return true;
124
+ }
125
+
126
+ // Check whether the cursor is a number or letter before and after. If not, switch the date type.
127
+ // eg: `2020年12月01日`, the cursor is behind 01, press the right key, and switch to the end date.
128
+ if (direction === 'right') {
129
+ if (!dateString.substring(cursorIndex, characterIndex).match(/[0-9a-zA-Z]/)) {
130
+ return true;
131
+ }
132
+ }
133
+ if (!dateString.substring(characterIndex, cursorIndex).match(/[0-9a-zA-Z]/)) {
134
+ return true;
135
+ }
136
+ return false;
137
+ }