@gravity-ui/date-components 1.1.0 → 1.2.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.
- package/dist/cjs/components/Calendar/Calendar.css +37 -37
- package/dist/cjs/components/Calendar/Calendar.js +2 -4
- package/dist/cjs/components/Calendar/CalendarBase.js +2 -4
- package/dist/cjs/components/Calendar/RangeCalendar.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useCalendarCellProps.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useCalendarGridProps.js +11 -0
- package/dist/cjs/components/Calendar/hooks/useCalendarProps.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useCalendarState.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useRangeCalendarState.js +13 -21
- package/dist/cjs/components/Calendar/i18n/index.js +3 -5
- package/dist/cjs/components/Calendar/index.js +8 -21
- package/dist/cjs/components/DateField/DateField.js +3 -16
- package/dist/cjs/components/DateField/hooks/useDateFieldProps.js +25 -20
- package/dist/cjs/components/DateField/hooks/useDateFieldState.js +23 -167
- package/dist/cjs/components/DateField/i18n/index.js +3 -5
- package/dist/cjs/components/DateField/index.js +4 -17
- package/dist/cjs/components/DateField/utils.d.ts +14 -3
- package/dist/cjs/components/DateField/utils.js +172 -3
- package/dist/cjs/components/DatePicker/DatePicker.css +6 -0
- package/dist/cjs/components/DatePicker/DatePicker.d.ts +2 -2
- package/dist/cjs/components/DatePicker/DatePicker.js +8 -48
- package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.d.ts +20 -0
- package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.js +121 -0
- package/dist/cjs/components/DatePicker/hooks/useDatePickerState.d.ts +4 -5
- package/dist/cjs/components/DatePicker/hooks/useDatePickerState.js +17 -4
- package/dist/cjs/components/DatePicker/i18n/index.js +3 -5
- package/dist/cjs/components/DatePicker/index.d.ts +1 -0
- package/dist/cjs/components/DatePicker/index.js +4 -16
- package/dist/cjs/components/RelativeDateField/RelativeDateField.js +2 -4
- package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +2 -4
- package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.js +2 -4
- package/dist/cjs/components/RelativeDateField/index.js +4 -17
- package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.css +1 -0
- package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.js +2 -4
- package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +32 -43
- package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +2 -4
- package/dist/cjs/components/RelativeDatePicker/i18n/index.js +3 -5
- package/dist/cjs/components/RelativeDatePicker/index.js +4 -17
- package/dist/cjs/components/hooks/useControlledState.js +2 -4
- package/dist/cjs/components/index.js +6 -19
- package/dist/cjs/index.js +2 -15
- package/dist/esm/components/Calendar/Calendar.css +37 -37
- package/dist/esm/components/Calendar/hooks/useCalendarGridProps.js +11 -0
- package/dist/esm/components/Calendar/hooks/useRangeCalendarState.js +11 -16
- package/dist/esm/components/DateField/DateField.js +1 -11
- package/dist/esm/components/DateField/hooks/useDateFieldProps.js +24 -17
- package/dist/esm/components/DateField/hooks/useDateFieldState.js +19 -161
- package/dist/esm/components/DateField/utils.d.ts +14 -3
- package/dist/esm/components/DateField/utils.js +165 -2
- package/dist/esm/components/DatePicker/DatePicker.css +6 -0
- package/dist/esm/components/DatePicker/DatePicker.d.ts +2 -2
- package/dist/esm/components/DatePicker/DatePicker.js +9 -46
- package/dist/esm/components/DatePicker/hooks/useDatePickerProps.d.ts +20 -0
- package/dist/esm/components/DatePicker/hooks/useDatePickerProps.js +117 -0
- package/dist/esm/components/DatePicker/hooks/useDatePickerState.d.ts +4 -5
- package/dist/esm/components/DatePicker/hooks/useDatePickerState.js +15 -0
- package/dist/esm/components/DatePicker/index.d.ts +1 -0
- package/dist/esm/components/DatePicker/index.js +1 -0
- package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.css +1 -0
- package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +30 -38
- package/package.json +37 -33
- package/dist/cjs/components/DatePicker/DesktopCalendar.d.ts +0 -17
- package/dist/cjs/components/DatePicker/DesktopCalendar.js +0 -65
- package/dist/esm/components/DatePicker/DesktopCalendar.d.ts +0 -17
- package/dist/esm/components/DatePicker/DesktopCalendar.js +0 -57
|
@@ -50,43 +50,6 @@
|
|
|
50
50
|
height: 100%;
|
|
51
51
|
padding: 0 var(--_--calendar-padding) var(--_--calendar-padding);
|
|
52
52
|
}
|
|
53
|
-
.g-date-calendar__content_animation_forward {
|
|
54
|
-
transform: translateX(-100%);
|
|
55
|
-
animation: calendar-forward 0.25s ease forwards;
|
|
56
|
-
}
|
|
57
|
-
.g-date-calendar__content_animation_forward.g-date-calendar__current-state {
|
|
58
|
-
left: -100%;
|
|
59
|
-
}
|
|
60
|
-
.g-date-calendar__content_animation_backward {
|
|
61
|
-
transform: translateX(0);
|
|
62
|
-
animation: calendar-backward 0.25s ease forwards;
|
|
63
|
-
}
|
|
64
|
-
.g-date-calendar__content_animation_backward.g-date-calendar__current-state {
|
|
65
|
-
left: 100%;
|
|
66
|
-
}
|
|
67
|
-
.g-date-calendar__content_animation_zoom-in {
|
|
68
|
-
transform: scale();
|
|
69
|
-
}
|
|
70
|
-
.g-date-calendar__content_animation_zoom-in.g-date-calendar__previous-state {
|
|
71
|
-
animation: calendar-zoom-in-hiding 0.25s ease forwards;
|
|
72
|
-
}
|
|
73
|
-
.g-date-calendar__content_animation_zoom-in.g-date-calendar__current-state {
|
|
74
|
-
animation: calendar-zoom-in-showing 0.25s ease forwards;
|
|
75
|
-
}
|
|
76
|
-
.g-date-calendar__content_animation_zoom-out {
|
|
77
|
-
transform: scale();
|
|
78
|
-
}
|
|
79
|
-
.g-date-calendar__content_animation_zoom-out.g-date-calendar__current-state {
|
|
80
|
-
animation: calendar-zoom-out-showing 0.25s ease forwards;
|
|
81
|
-
}
|
|
82
|
-
.g-date-calendar__content_animation_zoom-out.g-date-calendar__previous-state {
|
|
83
|
-
animation: calendar-zoom-out-hiding 0.25s ease forwards;
|
|
84
|
-
}
|
|
85
|
-
@media screen and (prefers-reduced-motion: reduce), (update: slow) {
|
|
86
|
-
.g-date-calendar__content[class] {
|
|
87
|
-
animation-duration: 0.001ms;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
53
|
@keyframes calendar-forward {
|
|
91
54
|
from {
|
|
92
55
|
transform: translateX(0);
|
|
@@ -143,6 +106,43 @@
|
|
|
143
106
|
transform: scale(2);
|
|
144
107
|
}
|
|
145
108
|
}
|
|
109
|
+
.g-date-calendar__content_animation_forward {
|
|
110
|
+
transform: translateX(-100%);
|
|
111
|
+
animation: calendar-forward 0.25s ease forwards;
|
|
112
|
+
}
|
|
113
|
+
.g-date-calendar__content_animation_forward.g-date-calendar__current-state {
|
|
114
|
+
left: -100%;
|
|
115
|
+
}
|
|
116
|
+
.g-date-calendar__content_animation_backward {
|
|
117
|
+
transform: translateX(0);
|
|
118
|
+
animation: calendar-backward 0.25s ease forwards;
|
|
119
|
+
}
|
|
120
|
+
.g-date-calendar__content_animation_backward.g-date-calendar__current-state {
|
|
121
|
+
left: 100%;
|
|
122
|
+
}
|
|
123
|
+
.g-date-calendar__content_animation_zoom-in {
|
|
124
|
+
transform: scale();
|
|
125
|
+
}
|
|
126
|
+
.g-date-calendar__content_animation_zoom-in.g-date-calendar__previous-state {
|
|
127
|
+
animation: calendar-zoom-in-hiding 0.25s ease forwards;
|
|
128
|
+
}
|
|
129
|
+
.g-date-calendar__content_animation_zoom-in.g-date-calendar__current-state {
|
|
130
|
+
animation: calendar-zoom-in-showing 0.25s ease forwards;
|
|
131
|
+
}
|
|
132
|
+
.g-date-calendar__content_animation_zoom-out {
|
|
133
|
+
transform: scale();
|
|
134
|
+
}
|
|
135
|
+
.g-date-calendar__content_animation_zoom-out.g-date-calendar__current-state {
|
|
136
|
+
animation: calendar-zoom-out-showing 0.25s ease forwards;
|
|
137
|
+
}
|
|
138
|
+
.g-date-calendar__content_animation_zoom-out.g-date-calendar__previous-state {
|
|
139
|
+
animation: calendar-zoom-out-hiding 0.25s ease forwards;
|
|
140
|
+
}
|
|
141
|
+
@media screen and (prefers-reduced-motion: reduce), (update: slow) {
|
|
142
|
+
.g-date-calendar__content[class] {
|
|
143
|
+
animation-duration: 0.001ms;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
146
|
.g-date-calendar__grid-rowgroup {
|
|
147
147
|
display: grid;
|
|
148
148
|
gap: var(--_--calendar-days-gap);
|
|
@@ -10,36 +10,47 @@ export function useCalendarGridProps(state) {
|
|
|
10
10
|
? `${state.startDate.year()} — ${state.endDate.year()}`
|
|
11
11
|
: state.focusedDate.format(state.mode === 'days' ? 'MMMM YYYY' : 'YYYY'), 'aria-disabled': state.disabled ? 'true' : undefined, 'aria-readonly': state.readOnly ? 'true' : undefined }, focusWithinProps), { onKeyDown: (e) => {
|
|
12
12
|
if (e.key === 'ArrowRight') {
|
|
13
|
+
e.preventDefault();
|
|
13
14
|
state.focusNextCell();
|
|
14
15
|
}
|
|
15
16
|
else if (e.key === 'ArrowLeft') {
|
|
17
|
+
e.preventDefault();
|
|
16
18
|
state.focusPreviousCell();
|
|
17
19
|
}
|
|
18
20
|
else if (e.key === 'ArrowDown') {
|
|
21
|
+
e.preventDefault();
|
|
19
22
|
state.focusNextRow();
|
|
20
23
|
}
|
|
21
24
|
else if (e.key === 'ArrowUp') {
|
|
25
|
+
e.preventDefault();
|
|
22
26
|
state.focusPreviousRow();
|
|
23
27
|
}
|
|
24
28
|
else if (e.key === 'PageDown') {
|
|
29
|
+
e.preventDefault();
|
|
25
30
|
state.focusNextPage(e.shiftKey);
|
|
26
31
|
}
|
|
27
32
|
else if (e.key === 'PageUp') {
|
|
33
|
+
e.preventDefault();
|
|
28
34
|
state.focusPreviousPage(e.shiftKey);
|
|
29
35
|
}
|
|
30
36
|
else if (e.key === 'End') {
|
|
37
|
+
e.preventDefault();
|
|
31
38
|
state.focusSectionEnd();
|
|
32
39
|
}
|
|
33
40
|
else if (e.key === 'Home') {
|
|
41
|
+
e.preventDefault();
|
|
34
42
|
state.focusSectionStart();
|
|
35
43
|
}
|
|
36
44
|
else if (e.code === 'Minus') {
|
|
45
|
+
e.preventDefault();
|
|
37
46
|
state.zoomOut();
|
|
38
47
|
}
|
|
39
48
|
else if (e.code === 'Equal') {
|
|
49
|
+
e.preventDefault();
|
|
40
50
|
state.zoomIn();
|
|
41
51
|
}
|
|
42
52
|
else if (e.key === 'Enter' || e.key === ' ') {
|
|
53
|
+
e.preventDefault();
|
|
43
54
|
state.selectDate(state.focusedDate);
|
|
44
55
|
}
|
|
45
56
|
} });
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
1
|
+
import { __rest } from "tslib";
|
|
12
2
|
import React from 'react';
|
|
13
3
|
import { useControlledState } from '../../hooks/useControlledState';
|
|
14
4
|
import { constrainValue } from '../utils';
|
|
@@ -22,8 +12,16 @@ export function useRangeCalendarState(props) {
|
|
|
22
12
|
const highlightedRange = anchorDate
|
|
23
13
|
? makeRange(anchorDate, calendar.focusedDate, calendar.mode)
|
|
24
14
|
: (_b = (value && makeRange(value.start, value.end, calendar.mode))) !== null && _b !== void 0 ? _b : undefined;
|
|
25
|
-
const
|
|
26
|
-
|
|
15
|
+
const minMode = calendar.availableModes[0];
|
|
16
|
+
const selectDate = (date, force = false) => {
|
|
17
|
+
if (props.disabled) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!force && calendar.mode !== minMode) {
|
|
21
|
+
calendar.zoomIn();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (props.readOnly) {
|
|
27
25
|
return;
|
|
28
26
|
}
|
|
29
27
|
date = constrainValue(date, props.minValue, props.maxValue);
|
|
@@ -43,9 +41,6 @@ export function useRangeCalendarState(props) {
|
|
|
43
41
|
setValue,
|
|
44
42
|
selectDate,
|
|
45
43
|
anchorDate, setAnchorDate: setAnchorDateState, highlightedRange,
|
|
46
|
-
selectFocusedDate() {
|
|
47
|
-
selectDate(calendar.focusedDate);
|
|
48
|
-
},
|
|
49
44
|
isSelected(date) {
|
|
50
45
|
if (!highlightedRange) {
|
|
51
46
|
return false;
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
1
|
+
import { __rest } from "tslib";
|
|
12
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
3
|
import React from 'react';
|
|
14
4
|
import { TextInput, useFocusWithin } from '@gravity-ui/uikit';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { cleanString } from '../utils';
|
|
3
3
|
export function useDateFieldProps(state, props) {
|
|
4
4
|
const inputRef = React.useRef(null);
|
|
5
5
|
const [, setInnerState] = React.useState({});
|
|
@@ -80,12 +80,16 @@ export function useDateFieldProps(state, props) {
|
|
|
80
80
|
if (state.selectedSectionIndexes !== null) {
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
|
-
const input =
|
|
83
|
+
const input = e.target;
|
|
84
|
+
const isAutofocus = !inputRef.current;
|
|
84
85
|
setTimeout(() => {
|
|
85
86
|
if (!input || input !== inputRef.current) {
|
|
86
87
|
return;
|
|
87
88
|
}
|
|
88
|
-
if (
|
|
89
|
+
if (isAutofocus) {
|
|
90
|
+
state.focusSectionInPosition(0);
|
|
91
|
+
}
|
|
92
|
+
else if (
|
|
89
93
|
// avoid selecting all sections when focusing empty field without value
|
|
90
94
|
input.value.length &&
|
|
91
95
|
Number(input.selectionEnd) - Number(input.selectionStart) ===
|
|
@@ -141,7 +145,7 @@ export function useDateFieldProps(state, props) {
|
|
|
141
145
|
e.preventDefault();
|
|
142
146
|
state.clearSection();
|
|
143
147
|
}
|
|
144
|
-
else if (e.key === 'a' && e[
|
|
148
|
+
else if (e.key === 'a' && (e['ctrlKey'] || e['metaKey'])) {
|
|
145
149
|
e.preventDefault();
|
|
146
150
|
setSelectedSections('all');
|
|
147
151
|
}
|
|
@@ -163,32 +167,35 @@ export function useDateFieldProps(state, props) {
|
|
|
163
167
|
onBeforeInput(e) {
|
|
164
168
|
e.preventDefault();
|
|
165
169
|
// @ts-expect-error
|
|
166
|
-
const key = e.
|
|
167
|
-
|
|
168
|
-
if (key != null) {
|
|
170
|
+
const key = e.data;
|
|
171
|
+
if (key !== undefined && key !== null) {
|
|
169
172
|
state.onInput(key);
|
|
170
173
|
}
|
|
171
174
|
},
|
|
172
175
|
onPaste(e) {
|
|
176
|
+
e.preventDefault();
|
|
173
177
|
if (state.readOnly) {
|
|
174
|
-
e.preventDefault();
|
|
175
178
|
return;
|
|
176
179
|
}
|
|
177
|
-
const pastedValue = e.clipboardData.getData('text');
|
|
178
|
-
if (state.
|
|
179
|
-
e.preventDefault();
|
|
180
|
-
}
|
|
181
|
-
else if (state.selectedSectionIndexes &&
|
|
180
|
+
const pastedValue = cleanString(e.clipboardData.getData('text'));
|
|
181
|
+
if (state.selectedSectionIndexes &&
|
|
182
182
|
state.selectedSectionIndexes.startIndex ===
|
|
183
183
|
state.selectedSectionIndexes.endIndex) {
|
|
184
184
|
const activeSection = state.sections[state.selectedSectionIndexes.startIndex];
|
|
185
|
+
const digitsOnly = /^\d+$/.test(pastedValue);
|
|
186
|
+
const lettersOnly = /^[a-zA-Z]+$/.test(pastedValue);
|
|
185
187
|
const isValidValue = Boolean(activeSection) &&
|
|
186
|
-
((activeSection.contentType === 'digit' &&
|
|
187
|
-
activeSection.contentType === 'letter');
|
|
188
|
-
if (
|
|
189
|
-
|
|
188
|
+
((activeSection.contentType === 'digit' && digitsOnly) ||
|
|
189
|
+
(activeSection.contentType === 'letter' && lettersOnly));
|
|
190
|
+
if (isValidValue) {
|
|
191
|
+
state.onInput(pastedValue);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (digitsOnly || lettersOnly) {
|
|
195
|
+
return;
|
|
190
196
|
}
|
|
191
197
|
}
|
|
198
|
+
state.setValueFromString(pastedValue);
|
|
192
199
|
},
|
|
193
200
|
},
|
|
194
201
|
},
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { dateTime, isValid } from '@gravity-ui/date-utils';
|
|
3
3
|
import { useControlledState } from '../../hooks/useControlledState';
|
|
4
4
|
import { createPlaceholderValue, isInvalid, mergeDateTime } from '../../utils/dates';
|
|
5
|
-
import { splitFormatIntoSections } from '../utils';
|
|
5
|
+
import { addSegment, getDurationUnitFromSectionType, getSectionLimits, getSectionValue, setSegment, splitFormatIntoSections, } from '../utils';
|
|
6
6
|
const EDITABLE_SEGMENTS = {
|
|
7
7
|
year: true,
|
|
8
8
|
month: true,
|
|
@@ -13,11 +13,6 @@ const EDITABLE_SEGMENTS = {
|
|
|
13
13
|
dayPeriod: true,
|
|
14
14
|
weekday: true,
|
|
15
15
|
};
|
|
16
|
-
const TYPE_MAPPING = {
|
|
17
|
-
weekday: 'day',
|
|
18
|
-
day: 'date',
|
|
19
|
-
dayPeriod: 'hour',
|
|
20
|
-
};
|
|
21
16
|
const PAGE_STEP = {
|
|
22
17
|
year: 5,
|
|
23
18
|
month: 2,
|
|
@@ -63,10 +58,7 @@ export function useDateFieldState(props) {
|
|
|
63
58
|
? value
|
|
64
59
|
: placeholderDate;
|
|
65
60
|
const sectionsState = useSectionsState(sections, displayValue, validSegments);
|
|
66
|
-
const [selectedSections, setSelectedSections] = React.useState(
|
|
67
|
-
var _a, _b;
|
|
68
|
-
return (_b = (_a = sectionsState.editableSections[0]) === null || _a === void 0 ? void 0 : _a.previousEditableSection) !== null && _b !== void 0 ? _b : -1;
|
|
69
|
-
});
|
|
61
|
+
const [selectedSections, setSelectedSections] = React.useState(-1);
|
|
70
62
|
const selectedSectionIndexes = React.useMemo(() => {
|
|
71
63
|
if (selectedSections === -1) {
|
|
72
64
|
return null;
|
|
@@ -91,9 +83,14 @@ export function useDateFieldState(props) {
|
|
|
91
83
|
return;
|
|
92
84
|
}
|
|
93
85
|
if (Object.keys(validSegments).length >= Object.keys(allSegments).length) {
|
|
94
|
-
|
|
86
|
+
if (!value || !newValue.isSame(value)) {
|
|
87
|
+
setDate(newValue);
|
|
88
|
+
}
|
|
95
89
|
}
|
|
96
90
|
else {
|
|
91
|
+
if (value) {
|
|
92
|
+
setDate(null);
|
|
93
|
+
}
|
|
97
94
|
setPlaceholderDate(newValue);
|
|
98
95
|
}
|
|
99
96
|
}
|
|
@@ -132,7 +129,8 @@ export function useDateFieldState(props) {
|
|
|
132
129
|
isEmpty: Object.keys(validSegments).length === 0,
|
|
133
130
|
displayValue,
|
|
134
131
|
setValue,
|
|
135
|
-
|
|
132
|
+
// use ltr direction context to get predictable navigation inside input
|
|
133
|
+
text: '\u2066' + sectionsState.editableSections.map((s) => s.textValue).join('') + '\u2069',
|
|
136
134
|
readOnly: props.readOnly,
|
|
137
135
|
disabled: props.disabled,
|
|
138
136
|
sections: sectionsState.editableSections,
|
|
@@ -282,9 +280,6 @@ export function useDateFieldState(props) {
|
|
|
282
280
|
const type = getDurationUnitFromSectionType(section.type);
|
|
283
281
|
currentValue = displayValue.set(type, placeholder[type]());
|
|
284
282
|
}
|
|
285
|
-
if (value) {
|
|
286
|
-
setDate(null);
|
|
287
|
-
}
|
|
288
283
|
setValue(currentValue);
|
|
289
284
|
},
|
|
290
285
|
clearAll() {
|
|
@@ -302,7 +297,6 @@ export function useDateFieldState(props) {
|
|
|
302
297
|
timeZone: props.timeZone,
|
|
303
298
|
}));
|
|
304
299
|
},
|
|
305
|
-
// eslint-disable-next-line complexity
|
|
306
300
|
onInput(key) {
|
|
307
301
|
if (this.readOnly || this.disabled) {
|
|
308
302
|
return;
|
|
@@ -411,6 +405,7 @@ export function useDateFieldState(props) {
|
|
|
411
405
|
}
|
|
412
406
|
},
|
|
413
407
|
setValueFromString(str) {
|
|
408
|
+
enteredKeys.current = '';
|
|
414
409
|
let date = parseDate({ input: str, format, timeZone: props.timeZone });
|
|
415
410
|
if (isValid(date)) {
|
|
416
411
|
if (props.timeZone && !isDateStringWithTimeZone(str)) {
|
|
@@ -434,64 +429,6 @@ function parseDate(options) {
|
|
|
434
429
|
function isDateStringWithTimeZone(str) {
|
|
435
430
|
return /z$/i.test(str) || /[+-]\d\d:\d\d$/.test(str);
|
|
436
431
|
}
|
|
437
|
-
function addSegment(section, date, amount) {
|
|
438
|
-
var _a;
|
|
439
|
-
let val = (_a = section.value) !== null && _a !== void 0 ? _a : 0;
|
|
440
|
-
if (section.type === 'dayPeriod') {
|
|
441
|
-
val = date.hour() + (date.hour() > 12 ? -12 : 12);
|
|
442
|
-
}
|
|
443
|
-
else {
|
|
444
|
-
val = val + amount;
|
|
445
|
-
const min = section.minValue;
|
|
446
|
-
const max = section.maxValue;
|
|
447
|
-
if (typeof min === 'number' && typeof max === 'number') {
|
|
448
|
-
const length = max - min + 1;
|
|
449
|
-
val = ((val - min + length) % length) + min;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
const type = getDurationUnitFromSectionType(section.type);
|
|
453
|
-
return date.set(type, val);
|
|
454
|
-
}
|
|
455
|
-
function setSegment(section, date, amount) {
|
|
456
|
-
const type = section.type;
|
|
457
|
-
switch (type) {
|
|
458
|
-
case 'day':
|
|
459
|
-
case 'weekday':
|
|
460
|
-
case 'month':
|
|
461
|
-
case 'year': {
|
|
462
|
-
return date.set(getDurationUnitFromSectionType(type), amount);
|
|
463
|
-
}
|
|
464
|
-
case 'dayPeriod': {
|
|
465
|
-
const hours = date.hour();
|
|
466
|
-
const wasPM = hours >= 12;
|
|
467
|
-
const isPM = amount >= 12;
|
|
468
|
-
if (isPM === wasPM) {
|
|
469
|
-
return date;
|
|
470
|
-
}
|
|
471
|
-
return date.set('hour', wasPM ? hours - 12 : hours + 12);
|
|
472
|
-
}
|
|
473
|
-
case 'hour': {
|
|
474
|
-
// In 12 hour time, ensure that AM/PM does not change
|
|
475
|
-
let sectionAmount = amount;
|
|
476
|
-
if (section.minValue === 12 || section.maxValue === 11) {
|
|
477
|
-
const hours = date.hour();
|
|
478
|
-
const wasPM = hours >= 12;
|
|
479
|
-
if (!wasPM && sectionAmount === 12) {
|
|
480
|
-
sectionAmount = 0;
|
|
481
|
-
}
|
|
482
|
-
if (wasPM && sectionAmount < 12) {
|
|
483
|
-
sectionAmount += 12;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
return date.set('hour', sectionAmount);
|
|
487
|
-
}
|
|
488
|
-
case 'minute':
|
|
489
|
-
case 'second': {
|
|
490
|
-
return date.set(type, amount);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return date;
|
|
494
|
-
}
|
|
495
432
|
function getCurrentEditableSectionIndex(sections, selectedSections) {
|
|
496
433
|
const currentIndex = selectedSections === 'all' || selectedSections === -1 ? 0 : selectedSections;
|
|
497
434
|
const section = sections[currentIndex];
|
|
@@ -532,7 +469,7 @@ function useSectionsState(sections, value, validSegments) {
|
|
|
532
469
|
return state;
|
|
533
470
|
}
|
|
534
471
|
function getEditableSections(sections, value, validSegments) {
|
|
535
|
-
let position =
|
|
472
|
+
let position = 1;
|
|
536
473
|
const newSections = [];
|
|
537
474
|
let previousEditableSection = -1;
|
|
538
475
|
for (let i = 0; i < sections.length; i++) {
|
|
@@ -541,9 +478,15 @@ function getEditableSections(sections, value, validSegments) {
|
|
|
541
478
|
let renderedValue = section.placeholder;
|
|
542
479
|
if ((isEditable && validSegments[section.type]) || section.type === 'timeZoneName') {
|
|
543
480
|
renderedValue = value.format(section.format);
|
|
481
|
+
if (section.contentType === 'digit' &&
|
|
482
|
+
renderedValue.length < section.placeholder.length) {
|
|
483
|
+
renderedValue = renderedValue.padStart(section.placeholder.length, '0');
|
|
484
|
+
}
|
|
544
485
|
}
|
|
486
|
+
// use bidirectional context to allow the browser autodetect text direction
|
|
487
|
+
renderedValue = '\u2068' + renderedValue + '\u2069';
|
|
545
488
|
const sectionLength = renderedValue.length;
|
|
546
|
-
const newSection = Object.assign(Object.assign(Object.assign({}, section), { value:
|
|
489
|
+
const newSection = Object.assign(Object.assign(Object.assign({}, section), { value: getSectionValue(section, value), textValue: renderedValue, start: position, end: position + sectionLength, modified: false, previousEditableSection, nextEditableSection: previousEditableSection }), getSectionLimits(section, value));
|
|
547
490
|
newSections.push(newSection);
|
|
548
491
|
if (isEditable) {
|
|
549
492
|
for (let j = Math.max(0, previousEditableSection); j <= i; j++) {
|
|
@@ -561,88 +504,3 @@ function getEditableSections(sections, value, validSegments) {
|
|
|
561
504
|
}
|
|
562
505
|
return newSections;
|
|
563
506
|
}
|
|
564
|
-
function getValue(date, type) {
|
|
565
|
-
switch (type) {
|
|
566
|
-
case 'year':
|
|
567
|
-
case 'month':
|
|
568
|
-
case 'hour':
|
|
569
|
-
case 'minute':
|
|
570
|
-
case 'second': {
|
|
571
|
-
return date[type]();
|
|
572
|
-
}
|
|
573
|
-
case 'day': {
|
|
574
|
-
return date.date();
|
|
575
|
-
}
|
|
576
|
-
case 'weekday': {
|
|
577
|
-
return date.day();
|
|
578
|
-
}
|
|
579
|
-
case 'dayPeriod': {
|
|
580
|
-
return date.hour() >= 12 ? 12 : 0;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
return undefined;
|
|
584
|
-
}
|
|
585
|
-
function isHour12(section) {
|
|
586
|
-
if (section.type === 'hour') {
|
|
587
|
-
return dateTime().set('hour', 15).format(section.format) !== '15';
|
|
588
|
-
}
|
|
589
|
-
return false;
|
|
590
|
-
}
|
|
591
|
-
function getSectionLimits(date, type, options) {
|
|
592
|
-
switch (type) {
|
|
593
|
-
case 'year': {
|
|
594
|
-
return {
|
|
595
|
-
minValue: 1,
|
|
596
|
-
maxValue: 9999,
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
case 'month': {
|
|
600
|
-
return {
|
|
601
|
-
minValue: 0,
|
|
602
|
-
maxValue: 11,
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
case 'weekday': {
|
|
606
|
-
return {
|
|
607
|
-
minValue: 0,
|
|
608
|
-
maxValue: 6,
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
case 'day': {
|
|
612
|
-
return {
|
|
613
|
-
minValue: 1,
|
|
614
|
-
maxValue: date ? date.daysInMonth() : 31,
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
case 'hour': {
|
|
618
|
-
if (options.hour12) {
|
|
619
|
-
const isPM = date.hour() >= 12;
|
|
620
|
-
return {
|
|
621
|
-
minValue: isPM ? 12 : 0,
|
|
622
|
-
maxValue: isPM ? 23 : 11,
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
return {
|
|
626
|
-
minValue: 0,
|
|
627
|
-
maxValue: 23,
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
case 'minute':
|
|
631
|
-
case 'second': {
|
|
632
|
-
return {
|
|
633
|
-
minValue: 0,
|
|
634
|
-
maxValue: 59,
|
|
635
|
-
};
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
return {};
|
|
639
|
-
}
|
|
640
|
-
function getDurationUnitFromSectionType(type) {
|
|
641
|
-
if (type === 'literal' || type === 'timeZoneName' || type === 'unknown') {
|
|
642
|
-
throw new Error(`${type} section does not have duration unit.`);
|
|
643
|
-
}
|
|
644
|
-
if (type in TYPE_MAPPING) {
|
|
645
|
-
return TYPE_MAPPING[type];
|
|
646
|
-
}
|
|
647
|
-
return type;
|
|
648
|
-
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const CtrlCmd: string;
|
|
1
|
+
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
|
+
import type { DateFieldSection, DateFieldSectionType, DateFieldSectionWithoutPosition } from './types';
|
|
4
3
|
export declare function expandFormat(format: string): string;
|
|
4
|
+
export declare function getSectionLimits(section: DateFieldSectionWithoutPosition, date: DateTime): {
|
|
5
|
+
minValue: number;
|
|
6
|
+
maxValue: number;
|
|
7
|
+
} | {
|
|
8
|
+
minValue?: undefined;
|
|
9
|
+
maxValue?: undefined;
|
|
10
|
+
};
|
|
11
|
+
export declare function getSectionValue(sections: DateFieldSectionWithoutPosition, date: DateTime): number | undefined;
|
|
12
|
+
export declare function getDurationUnitFromSectionType(type: DateFieldSectionType): "year" | "month" | "day" | "date" | "hour" | "minute" | "second";
|
|
13
|
+
export declare function addSegment(section: DateFieldSection, date: DateTime, amount: number): DateTime;
|
|
14
|
+
export declare function setSegment(section: DateFieldSection, date: DateTime, amount: number): DateTime;
|
|
5
15
|
export declare function splitFormatIntoSections(format: string): DateFieldSectionWithoutPosition[];
|
|
16
|
+
export declare function cleanString(dirtyString: string): string;
|