@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.
Files changed (65) hide show
  1. package/dist/cjs/components/Calendar/Calendar.css +37 -37
  2. package/dist/cjs/components/Calendar/Calendar.js +2 -4
  3. package/dist/cjs/components/Calendar/CalendarBase.js +2 -4
  4. package/dist/cjs/components/Calendar/RangeCalendar.js +2 -4
  5. package/dist/cjs/components/Calendar/hooks/useCalendarCellProps.js +2 -4
  6. package/dist/cjs/components/Calendar/hooks/useCalendarGridProps.js +11 -0
  7. package/dist/cjs/components/Calendar/hooks/useCalendarProps.js +2 -4
  8. package/dist/cjs/components/Calendar/hooks/useCalendarState.js +2 -4
  9. package/dist/cjs/components/Calendar/hooks/useRangeCalendarState.js +13 -21
  10. package/dist/cjs/components/Calendar/i18n/index.js +3 -5
  11. package/dist/cjs/components/Calendar/index.js +8 -21
  12. package/dist/cjs/components/DateField/DateField.js +3 -16
  13. package/dist/cjs/components/DateField/hooks/useDateFieldProps.js +25 -20
  14. package/dist/cjs/components/DateField/hooks/useDateFieldState.js +23 -167
  15. package/dist/cjs/components/DateField/i18n/index.js +3 -5
  16. package/dist/cjs/components/DateField/index.js +4 -17
  17. package/dist/cjs/components/DateField/utils.d.ts +14 -3
  18. package/dist/cjs/components/DateField/utils.js +172 -3
  19. package/dist/cjs/components/DatePicker/DatePicker.css +6 -0
  20. package/dist/cjs/components/DatePicker/DatePicker.d.ts +2 -2
  21. package/dist/cjs/components/DatePicker/DatePicker.js +8 -48
  22. package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.d.ts +20 -0
  23. package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.js +121 -0
  24. package/dist/cjs/components/DatePicker/hooks/useDatePickerState.d.ts +4 -5
  25. package/dist/cjs/components/DatePicker/hooks/useDatePickerState.js +17 -4
  26. package/dist/cjs/components/DatePicker/i18n/index.js +3 -5
  27. package/dist/cjs/components/DatePicker/index.d.ts +1 -0
  28. package/dist/cjs/components/DatePicker/index.js +4 -16
  29. package/dist/cjs/components/RelativeDateField/RelativeDateField.js +2 -4
  30. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +2 -4
  31. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.js +2 -4
  32. package/dist/cjs/components/RelativeDateField/index.js +4 -17
  33. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.css +1 -0
  34. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.js +2 -4
  35. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +32 -43
  36. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +2 -4
  37. package/dist/cjs/components/RelativeDatePicker/i18n/index.js +3 -5
  38. package/dist/cjs/components/RelativeDatePicker/index.js +4 -17
  39. package/dist/cjs/components/hooks/useControlledState.js +2 -4
  40. package/dist/cjs/components/index.js +6 -19
  41. package/dist/cjs/index.js +2 -15
  42. package/dist/esm/components/Calendar/Calendar.css +37 -37
  43. package/dist/esm/components/Calendar/hooks/useCalendarGridProps.js +11 -0
  44. package/dist/esm/components/Calendar/hooks/useRangeCalendarState.js +11 -16
  45. package/dist/esm/components/DateField/DateField.js +1 -11
  46. package/dist/esm/components/DateField/hooks/useDateFieldProps.js +24 -17
  47. package/dist/esm/components/DateField/hooks/useDateFieldState.js +19 -161
  48. package/dist/esm/components/DateField/utils.d.ts +14 -3
  49. package/dist/esm/components/DateField/utils.js +165 -2
  50. package/dist/esm/components/DatePicker/DatePicker.css +6 -0
  51. package/dist/esm/components/DatePicker/DatePicker.d.ts +2 -2
  52. package/dist/esm/components/DatePicker/DatePicker.js +9 -46
  53. package/dist/esm/components/DatePicker/hooks/useDatePickerProps.d.ts +20 -0
  54. package/dist/esm/components/DatePicker/hooks/useDatePickerProps.js +117 -0
  55. package/dist/esm/components/DatePicker/hooks/useDatePickerState.d.ts +4 -5
  56. package/dist/esm/components/DatePicker/hooks/useDatePickerState.js +15 -0
  57. package/dist/esm/components/DatePicker/index.d.ts +1 -0
  58. package/dist/esm/components/DatePicker/index.js +1 -0
  59. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.css +1 -0
  60. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +30 -38
  61. package/package.json +37 -33
  62. package/dist/cjs/components/DatePicker/DesktopCalendar.d.ts +0 -17
  63. package/dist/cjs/components/DatePicker/DesktopCalendar.js +0 -65
  64. package/dist/esm/components/DatePicker/DesktopCalendar.d.ts +0 -17
  65. 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
- var __rest = (this && this.__rest) || function (s, e) {
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 selectDate = (date) => {
26
- if (props.disabled || props.readOnly) {
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
- var __rest = (this && this.__rest) || function (s, e) {
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 { CtrlCmd } from '../utils';
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 = inputRef.current;
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[CtrlCmd]) {
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.nativeEvent.data;
167
- // eslint-disable-next-line no-eq-null, eqeqeq
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.setValueFromString(pastedValue)) {
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' && /^\d+$/.test(pastedValue)) ||
187
- activeSection.contentType === 'letter');
188
- if (!isValidValue) {
189
- e.preventDefault();
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
- setDate(newValue);
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
- text: sectionsState.editableSections.map((s) => s.textValue).join(''),
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 = 0;
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: getValue(value, section.type), textValue: renderedValue, start: position, end: position + sectionLength, modified: false, previousEditableSection, nextEditableSection: previousEditableSection }), getSectionLimits(value, section.type, { hour12: isHour12(section) }));
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 { DateFieldSectionWithoutPosition } from './types';
2
- export declare const isMac: boolean;
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;