@gravity-ui/date-components 1.0.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 (217) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -0
  3. package/dist/cjs/components/Calendar/Calendar.css +220 -0
  4. package/dist/cjs/components/Calendar/Calendar.d.ts +13 -0
  5. package/dist/cjs/components/Calendar/Calendar.js +15 -0
  6. package/dist/cjs/components/Calendar/CalendarBase.d.ts +18 -0
  7. package/dist/cjs/components/Calendar/CalendarBase.js +89 -0
  8. package/dist/cjs/components/Calendar/RangeCalendar.d.ts +13 -0
  9. package/dist/cjs/components/Calendar/RangeCalendar.js +22 -0
  10. package/dist/cjs/components/Calendar/hooks/types.d.ts +124 -0
  11. package/dist/cjs/components/Calendar/hooks/types.js +2 -0
  12. package/dist/cjs/components/Calendar/hooks/useCalendarCellProps.d.ts +19 -0
  13. package/dist/cjs/components/Calendar/hooks/useCalendarCellProps.js +98 -0
  14. package/dist/cjs/components/Calendar/hooks/useCalendarGridProps.d.ts +5 -0
  15. package/dist/cjs/components/Calendar/hooks/useCalendarGridProps.js +57 -0
  16. package/dist/cjs/components/Calendar/hooks/useCalendarProps.d.ts +10 -0
  17. package/dist/cjs/components/Calendar/hooks/useCalendarProps.js +110 -0
  18. package/dist/cjs/components/Calendar/hooks/useCalendarState.d.ts +7 -0
  19. package/dist/cjs/components/Calendar/hooks/useCalendarState.js +178 -0
  20. package/dist/cjs/components/Calendar/hooks/useRangeCalendarState.d.ts +7 -0
  21. package/dist/cjs/components/Calendar/hooks/useRangeCalendarState.js +82 -0
  22. package/dist/cjs/components/Calendar/i18n/en.json +4 -0
  23. package/dist/cjs/components/Calendar/i18n/index.d.ts +1 -0
  24. package/dist/cjs/components/Calendar/i18n/index.js +11 -0
  25. package/dist/cjs/components/Calendar/i18n/ru.json +4 -0
  26. package/dist/cjs/components/Calendar/index.d.ts +8 -0
  27. package/dist/cjs/components/Calendar/index.js +23 -0
  28. package/dist/cjs/components/Calendar/utils.d.ts +4 -0
  29. package/dist/cjs/components/Calendar/utils.js +40 -0
  30. package/dist/cjs/components/DateField/DateField.css +4 -0
  31. package/dist/cjs/components/DateField/DateField.d.ts +6 -0
  32. package/dist/cjs/components/DateField/DateField.js +38 -0
  33. package/dist/cjs/components/DateField/hooks/useDateFieldProps.d.ts +6 -0
  34. package/dist/cjs/components/DateField/hooks/useDateFieldProps.js +203 -0
  35. package/dist/cjs/components/DateField/hooks/useDateFieldState.d.ts +67 -0
  36. package/dist/cjs/components/DateField/hooks/useDateFieldState.js +628 -0
  37. package/dist/cjs/components/DateField/i18n/en.json +10 -0
  38. package/dist/cjs/components/DateField/i18n/index.d.ts +1 -0
  39. package/dist/cjs/components/DateField/i18n/index.js +11 -0
  40. package/dist/cjs/components/DateField/i18n/ru.json +10 -0
  41. package/dist/cjs/components/DateField/index.d.ts +3 -0
  42. package/dist/cjs/components/DateField/index.js +19 -0
  43. package/dist/cjs/components/DateField/types.d.ts +67 -0
  44. package/dist/cjs/components/DateField/types.js +2 -0
  45. package/dist/cjs/components/DateField/utils.d.ts +14 -0
  46. package/dist/cjs/components/DateField/utils.js +276 -0
  47. package/dist/cjs/components/DatePicker/DatePicker.css +19 -0
  48. package/dist/cjs/components/DatePicker/DatePicker.d.ts +5 -0
  49. package/dist/cjs/components/DatePicker/DatePicker.js +66 -0
  50. package/dist/cjs/components/DatePicker/DesktopCalendar.d.ts +15 -0
  51. package/dist/cjs/components/DatePicker/DesktopCalendar.js +56 -0
  52. package/dist/cjs/components/DatePicker/MobileCalendar.css +49 -0
  53. package/dist/cjs/components/DatePicker/MobileCalendar.d.ts +14 -0
  54. package/dist/cjs/components/DatePicker/MobileCalendar.js +78 -0
  55. package/dist/cjs/components/DatePicker/hooks/useDatePickerState.d.ts +45 -0
  56. package/dist/cjs/components/DatePicker/hooks/useDatePickerState.js +114 -0
  57. package/dist/cjs/components/DatePicker/i18n/en.json +3 -0
  58. package/dist/cjs/components/DatePicker/i18n/index.d.ts +1 -0
  59. package/dist/cjs/components/DatePicker/i18n/index.js +11 -0
  60. package/dist/cjs/components/DatePicker/i18n/ru.json +3 -0
  61. package/dist/cjs/components/DatePicker/index.d.ts +2 -0
  62. package/dist/cjs/components/DatePicker/index.js +18 -0
  63. package/dist/cjs/components/DatePicker/utils.d.ts +1 -0
  64. package/dist/cjs/components/DatePicker/utils.js +5 -0
  65. package/dist/cjs/components/RelativeDateField/RelativeDateField.css +16 -0
  66. package/dist/cjs/components/RelativeDateField/RelativeDateField.d.ts +11 -0
  67. package/dist/cjs/components/RelativeDateField/RelativeDateField.js +37 -0
  68. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.d.ts +12 -0
  69. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +66 -0
  70. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.d.ts +30 -0
  71. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.js +66 -0
  72. package/dist/cjs/components/RelativeDateField/index.d.ts +3 -0
  73. package/dist/cjs/components/RelativeDateField/index.js +19 -0
  74. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.css +16 -0
  75. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.d.ts +6 -0
  76. package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.js +32 -0
  77. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.d.ts +17 -0
  78. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +175 -0
  79. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.d.ts +36 -0
  80. package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +109 -0
  81. package/dist/cjs/components/RelativeDatePicker/i18n/en.json +4 -0
  82. package/dist/cjs/components/RelativeDatePicker/i18n/index.d.ts +1 -0
  83. package/dist/cjs/components/RelativeDatePicker/i18n/index.js +11 -0
  84. package/dist/cjs/components/RelativeDatePicker/i18n/ru.json +4 -0
  85. package/dist/cjs/components/RelativeDatePicker/index.d.ts +3 -0
  86. package/dist/cjs/components/RelativeDatePicker/index.js +19 -0
  87. package/dist/cjs/components/hooks/useControlledState.d.ts +1 -0
  88. package/dist/cjs/components/hooks/useControlledState.js +30 -0
  89. package/dist/cjs/components/index.d.ts +5 -0
  90. package/dist/cjs/components/index.js +21 -0
  91. package/dist/cjs/components/types/datePicker.d.ts +16 -0
  92. package/dist/cjs/components/types/datePicker.js +2 -0
  93. package/dist/cjs/components/types/events.d.ts +17 -0
  94. package/dist/cjs/components/types/events.js +2 -0
  95. package/dist/cjs/components/types/index.d.ts +4 -0
  96. package/dist/cjs/components/types/index.js +2 -0
  97. package/dist/cjs/components/types/inputs.d.ts +79 -0
  98. package/dist/cjs/components/types/inputs.js +2 -0
  99. package/dist/cjs/components/types/style.d.ts +7 -0
  100. package/dist/cjs/components/types/style.js +2 -0
  101. package/dist/cjs/components/utils/getButtonSizeForInput.d.ts +2 -0
  102. package/dist/cjs/components/utils/getButtonSizeForInput.js +20 -0
  103. package/dist/cjs/components/utils/mergeProps.d.ts +13 -0
  104. package/dist/cjs/components/utils/mergeProps.js +47 -0
  105. package/dist/cjs/components/variables.css +0 -0
  106. package/dist/cjs/index.d.ts +1 -0
  107. package/dist/cjs/index.js +17 -0
  108. package/dist/cjs/utils/cn.d.ts +2 -0
  109. package/dist/cjs/utils/cn.js +6 -0
  110. package/dist/esm/components/Calendar/Calendar.css +220 -0
  111. package/dist/esm/components/Calendar/Calendar.d.ts +13 -0
  112. package/dist/esm/components/Calendar/Calendar.js +9 -0
  113. package/dist/esm/components/Calendar/CalendarBase.d.ts +18 -0
  114. package/dist/esm/components/Calendar/CalendarBase.js +83 -0
  115. package/dist/esm/components/Calendar/RangeCalendar.d.ts +13 -0
  116. package/dist/esm/components/Calendar/RangeCalendar.js +16 -0
  117. package/dist/esm/components/Calendar/hooks/types.d.ts +124 -0
  118. package/dist/esm/components/Calendar/hooks/types.js +1 -0
  119. package/dist/esm/components/Calendar/hooks/useCalendarCellProps.d.ts +19 -0
  120. package/dist/esm/components/Calendar/hooks/useCalendarCellProps.js +91 -0
  121. package/dist/esm/components/Calendar/hooks/useCalendarGridProps.d.ts +5 -0
  122. package/dist/esm/components/Calendar/hooks/useCalendarGridProps.js +54 -0
  123. package/dist/esm/components/Calendar/hooks/useCalendarProps.d.ts +10 -0
  124. package/dist/esm/components/Calendar/hooks/useCalendarProps.js +103 -0
  125. package/dist/esm/components/Calendar/hooks/useCalendarState.d.ts +7 -0
  126. package/dist/esm/components/Calendar/hooks/useCalendarState.js +171 -0
  127. package/dist/esm/components/Calendar/hooks/useRangeCalendarState.d.ts +7 -0
  128. package/dist/esm/components/Calendar/hooks/useRangeCalendarState.js +75 -0
  129. package/dist/esm/components/Calendar/i18n/en.json +4 -0
  130. package/dist/esm/components/Calendar/i18n/index.d.ts +1 -0
  131. package/dist/esm/components/Calendar/i18n/index.js +5 -0
  132. package/dist/esm/components/Calendar/i18n/ru.json +4 -0
  133. package/dist/esm/components/Calendar/index.d.ts +8 -0
  134. package/dist/esm/components/Calendar/index.js +7 -0
  135. package/dist/esm/components/Calendar/utils.d.ts +4 -0
  136. package/dist/esm/components/Calendar/utils.js +34 -0
  137. package/dist/esm/components/DateField/DateField.css +4 -0
  138. package/dist/esm/components/DateField/DateField.d.ts +6 -0
  139. package/dist/esm/components/DateField/DateField.js +31 -0
  140. package/dist/esm/components/DateField/hooks/useDateFieldProps.d.ts +6 -0
  141. package/dist/esm/components/DateField/hooks/useDateFieldProps.js +196 -0
  142. package/dist/esm/components/DateField/hooks/useDateFieldState.d.ts +67 -0
  143. package/dist/esm/components/DateField/hooks/useDateFieldState.js +621 -0
  144. package/dist/esm/components/DateField/i18n/en.json +10 -0
  145. package/dist/esm/components/DateField/i18n/index.d.ts +1 -0
  146. package/dist/esm/components/DateField/i18n/index.js +5 -0
  147. package/dist/esm/components/DateField/i18n/ru.json +10 -0
  148. package/dist/esm/components/DateField/index.d.ts +3 -0
  149. package/dist/esm/components/DateField/index.js +3 -0
  150. package/dist/esm/components/DateField/types.d.ts +67 -0
  151. package/dist/esm/components/DateField/types.js +1 -0
  152. package/dist/esm/components/DateField/utils.d.ts +14 -0
  153. package/dist/esm/components/DateField/utils.js +268 -0
  154. package/dist/esm/components/DatePicker/DatePicker.css +19 -0
  155. package/dist/esm/components/DatePicker/DatePicker.d.ts +5 -0
  156. package/dist/esm/components/DatePicker/DatePicker.js +59 -0
  157. package/dist/esm/components/DatePicker/DesktopCalendar.d.ts +15 -0
  158. package/dist/esm/components/DatePicker/DesktopCalendar.js +48 -0
  159. package/dist/esm/components/DatePicker/MobileCalendar.css +49 -0
  160. package/dist/esm/components/DatePicker/MobileCalendar.d.ts +14 -0
  161. package/dist/esm/components/DatePicker/MobileCalendar.js +73 -0
  162. package/dist/esm/components/DatePicker/hooks/useDatePickerState.d.ts +45 -0
  163. package/dist/esm/components/DatePicker/hooks/useDatePickerState.js +107 -0
  164. package/dist/esm/components/DatePicker/i18n/en.json +3 -0
  165. package/dist/esm/components/DatePicker/i18n/index.d.ts +1 -0
  166. package/dist/esm/components/DatePicker/i18n/index.js +5 -0
  167. package/dist/esm/components/DatePicker/i18n/ru.json +3 -0
  168. package/dist/esm/components/DatePicker/index.d.ts +2 -0
  169. package/dist/esm/components/DatePicker/index.js +2 -0
  170. package/dist/esm/components/DatePicker/utils.d.ts +1 -0
  171. package/dist/esm/components/DatePicker/utils.js +2 -0
  172. package/dist/esm/components/RelativeDateField/RelativeDateField.css +16 -0
  173. package/dist/esm/components/RelativeDateField/RelativeDateField.d.ts +11 -0
  174. package/dist/esm/components/RelativeDateField/RelativeDateField.js +30 -0
  175. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldProps.d.ts +12 -0
  176. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +59 -0
  177. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldState.d.ts +30 -0
  178. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldState.js +59 -0
  179. package/dist/esm/components/RelativeDateField/index.d.ts +3 -0
  180. package/dist/esm/components/RelativeDateField/index.js +3 -0
  181. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.css +16 -0
  182. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.d.ts +6 -0
  183. package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.js +25 -0
  184. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.d.ts +17 -0
  185. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +168 -0
  186. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerState.d.ts +36 -0
  187. package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +102 -0
  188. package/dist/esm/components/RelativeDatePicker/i18n/en.json +4 -0
  189. package/dist/esm/components/RelativeDatePicker/i18n/index.d.ts +1 -0
  190. package/dist/esm/components/RelativeDatePicker/i18n/index.js +5 -0
  191. package/dist/esm/components/RelativeDatePicker/i18n/ru.json +4 -0
  192. package/dist/esm/components/RelativeDatePicker/index.d.ts +3 -0
  193. package/dist/esm/components/RelativeDatePicker/index.js +3 -0
  194. package/dist/esm/components/hooks/useControlledState.d.ts +1 -0
  195. package/dist/esm/components/hooks/useControlledState.js +23 -0
  196. package/dist/esm/components/index.d.ts +5 -0
  197. package/dist/esm/components/index.js +5 -0
  198. package/dist/esm/components/types/datePicker.d.ts +16 -0
  199. package/dist/esm/components/types/datePicker.js +1 -0
  200. package/dist/esm/components/types/events.d.ts +17 -0
  201. package/dist/esm/components/types/events.js +1 -0
  202. package/dist/esm/components/types/index.d.ts +4 -0
  203. package/dist/esm/components/types/index.js +1 -0
  204. package/dist/esm/components/types/inputs.d.ts +79 -0
  205. package/dist/esm/components/types/inputs.js +1 -0
  206. package/dist/esm/components/types/style.d.ts +7 -0
  207. package/dist/esm/components/types/style.js +1 -0
  208. package/dist/esm/components/utils/getButtonSizeForInput.d.ts +2 -0
  209. package/dist/esm/components/utils/getButtonSizeForInput.js +16 -0
  210. package/dist/esm/components/utils/mergeProps.d.ts +13 -0
  211. package/dist/esm/components/utils/mergeProps.js +43 -0
  212. package/dist/esm/components/variables.css +0 -0
  213. package/dist/esm/index.d.ts +1 -0
  214. package/dist/esm/index.js +1 -0
  215. package/dist/esm/utils/cn.d.ts +2 -0
  216. package/dist/esm/utils/cn.js +3 -0
  217. package/package.json +119 -0
@@ -0,0 +1,621 @@
1
+ import React from 'react';
2
+ import { dateTime, isValid } from '@gravity-ui/date-utils';
3
+ import { useControlledState } from '../../hooks/useControlledState';
4
+ import { createPlaceholderValue, isInvalid, mergeDateTime, splitFormatIntoSections } from '../utils';
5
+ const EDITABLE_SEGMENTS = {
6
+ year: true,
7
+ month: true,
8
+ day: true,
9
+ hour: true,
10
+ minute: true,
11
+ second: true,
12
+ dayPeriod: true,
13
+ weekday: true,
14
+ };
15
+ const TYPE_MAPPING = {
16
+ weekday: 'day',
17
+ day: 'date',
18
+ dayPeriod: 'hour',
19
+ };
20
+ const PAGE_STEP = {
21
+ year: 5,
22
+ month: 2,
23
+ weekday: 3,
24
+ day: 7,
25
+ hour: 2,
26
+ minute: 15,
27
+ second: 15,
28
+ };
29
+ export function useDateFieldState(props) {
30
+ var _a;
31
+ const [value, setDate] = useControlledState(props.value, props.defaultValue, props.onUpdate);
32
+ const [placeholderDate, setPlaceholderDate] = React.useState(() => {
33
+ return createPlaceholderValue({
34
+ placeholderValue: props.placeholderValue,
35
+ timeZone: props.timeZone,
36
+ });
37
+ });
38
+ const format = props.format || 'L';
39
+ const sections = useFormatSections(format);
40
+ const allSegments = React.useMemo(() => sections
41
+ .filter((seg) => EDITABLE_SEGMENTS[seg.type])
42
+ .reduce((p, seg) => {
43
+ p[seg.type] = true;
44
+ return p;
45
+ }, {}), [sections]);
46
+ const validSegmentsState = React.useState(() => props.value || props.defaultValue ? Object.assign({}, allSegments) : {});
47
+ let validSegments = validSegmentsState[0];
48
+ const setValidSegments = validSegmentsState[1];
49
+ if (value && Object.keys(validSegments).length < Object.keys(allSegments).length) {
50
+ setValidSegments(Object.assign({}, allSegments));
51
+ }
52
+ if (!value &&
53
+ Object.keys(validSegments).length > 0 &&
54
+ Object.keys(validSegments).length === Object.keys(allSegments).length) {
55
+ validSegments = {};
56
+ setValidSegments(validSegments);
57
+ setPlaceholderDate(createPlaceholderValue({ timeZone: props.timeZone }));
58
+ }
59
+ const displayValue = value &&
60
+ isValid(value) &&
61
+ Object.keys(validSegments).length >= Object.keys(allSegments).length
62
+ ? value
63
+ : placeholderDate;
64
+ const sectionsState = useSectionsState(sections, displayValue, validSegments);
65
+ const [selectedSections, setSelectedSections] = React.useState(() => {
66
+ var _a, _b;
67
+ return (_b = (_a = sectionsState.editableSections[0]) === null || _a === void 0 ? void 0 : _a.previousEditableSection) !== null && _b !== void 0 ? _b : -1;
68
+ });
69
+ const selectedSectionIndexes = React.useMemo(() => {
70
+ if (selectedSections === -1) {
71
+ return null;
72
+ }
73
+ if (selectedSections === 'all') {
74
+ return {
75
+ startIndex: 0,
76
+ endIndex: sectionsState.editableSections.length - 1,
77
+ };
78
+ }
79
+ if (typeof selectedSections === 'number') {
80
+ return { startIndex: selectedSections, endIndex: selectedSections };
81
+ }
82
+ if (typeof selectedSections === 'string') {
83
+ const selectedSectionIndex = sectionsState.editableSections.findIndex((section) => section.type === selectedSections);
84
+ return { startIndex: selectedSectionIndex, endIndex: selectedSectionIndex };
85
+ }
86
+ return selectedSections;
87
+ }, [selectedSections, sectionsState.editableSections]);
88
+ function setValue(newValue) {
89
+ if (props.disabled || props.readOnly) {
90
+ return;
91
+ }
92
+ if (Object.keys(validSegments).length >= Object.keys(allSegments).length) {
93
+ setDate(newValue);
94
+ }
95
+ else {
96
+ setPlaceholderDate(newValue);
97
+ }
98
+ }
99
+ function markValid(part) {
100
+ validSegments[part] = true;
101
+ if (validSegments.day && validSegments.month && validSegments.year && allSegments.weekday) {
102
+ validSegments.weekday = true;
103
+ }
104
+ if (validSegments.hour && allSegments.dayPeriod) {
105
+ validSegments.dayPeriod = true;
106
+ }
107
+ setValidSegments(Object.assign({}, validSegments));
108
+ }
109
+ function setSection(section, amount) {
110
+ markValid(section.type);
111
+ setValue(setSegment(section, displayValue, amount));
112
+ }
113
+ function adjustSection(sectionIndex, amount) {
114
+ const section = sectionsState.editableSections[sectionIndex];
115
+ if (validSegments[section.type]) {
116
+ setValue(addSegment(section, displayValue, amount));
117
+ }
118
+ else {
119
+ markValid(section.type);
120
+ if (Object.keys(validSegments).length >= Object.keys(allSegments).length) {
121
+ setValue(displayValue);
122
+ }
123
+ }
124
+ }
125
+ const enteredKeys = React.useRef('');
126
+ const validationState = props.validationState ||
127
+ (isInvalid(value, props.minValue, props.maxValue) ? 'invalid' : undefined) ||
128
+ (value && ((_a = props.isDateUnavailable) === null || _a === void 0 ? void 0 : _a.call(props, value)) ? 'invalid' : undefined);
129
+ return {
130
+ value: value !== null && value !== void 0 ? value : null,
131
+ isEmpty: Object.keys(validSegments).length === 0,
132
+ displayValue,
133
+ setValue,
134
+ text: sectionsState.editableSections.map((s) => s.textValue).join(''),
135
+ readOnly: props.readOnly,
136
+ disabled: props.disabled,
137
+ sections: sectionsState.editableSections,
138
+ selectedSectionIndexes,
139
+ validationState,
140
+ setSelectedSections(position) {
141
+ enteredKeys.current = '';
142
+ setSelectedSections(position);
143
+ },
144
+ focusSectionInPosition(position) {
145
+ const nextSectionIndex = this.sections.findIndex((s) => s.end >= position);
146
+ const index = nextSectionIndex === -1 ? 0 : nextSectionIndex;
147
+ const nextSection = this.sections[index];
148
+ if (nextSection) {
149
+ this.setSelectedSections(EDITABLE_SEGMENTS[nextSection.type] ? index : nextSection.nextEditableSection);
150
+ }
151
+ },
152
+ focusNextSection() {
153
+ var _a, _b;
154
+ const currentIndex = selectedSections === 'all' ? 0 : selectedSections;
155
+ const newIndex = (_b = (_a = this.sections[currentIndex]) === null || _a === void 0 ? void 0 : _a.nextEditableSection) !== null && _b !== void 0 ? _b : -1;
156
+ if (newIndex !== -1) {
157
+ this.setSelectedSections(newIndex);
158
+ }
159
+ },
160
+ focusPreviousSection() {
161
+ var _a, _b;
162
+ const currentIndex = selectedSections === 'all' ? 0 : selectedSections;
163
+ const newIndex = (_b = (_a = this.sections[currentIndex]) === null || _a === void 0 ? void 0 : _a.previousEditableSection) !== null && _b !== void 0 ? _b : -1;
164
+ if (newIndex !== -1) {
165
+ this.setSelectedSections(newIndex);
166
+ }
167
+ },
168
+ focusFirstSection() {
169
+ var _a, _b;
170
+ const newIndex = (_b = (_a = this.sections[0]) === null || _a === void 0 ? void 0 : _a.previousEditableSection) !== null && _b !== void 0 ? _b : -1;
171
+ if (newIndex !== -1) {
172
+ setSelectedSections(newIndex);
173
+ }
174
+ },
175
+ focusLastSection() {
176
+ var _a, _b;
177
+ const newIndex = (_b = (_a = this.sections[this.sections.length - 1]) === null || _a === void 0 ? void 0 : _a.nextEditableSection) !== null && _b !== void 0 ? _b : -1;
178
+ if (newIndex !== -1) {
179
+ this.setSelectedSections(newIndex);
180
+ }
181
+ },
182
+ increment() {
183
+ if (this.readOnly || this.disabled) {
184
+ return;
185
+ }
186
+ enteredKeys.current = '';
187
+ const sectionIndex = getCurrentEditableSectionIndex(this.sections, selectedSections);
188
+ if (sectionIndex !== -1) {
189
+ adjustSection(sectionIndex, 1);
190
+ }
191
+ },
192
+ decrement() {
193
+ if (this.readOnly || this.disabled) {
194
+ return;
195
+ }
196
+ enteredKeys.current = '';
197
+ const sectionIndex = getCurrentEditableSectionIndex(this.sections, selectedSections);
198
+ if (sectionIndex !== -1) {
199
+ adjustSection(sectionIndex, -1);
200
+ }
201
+ },
202
+ incrementPage() {
203
+ if (this.readOnly || this.disabled) {
204
+ return;
205
+ }
206
+ enteredKeys.current = '';
207
+ const sectionIndex = getCurrentEditableSectionIndex(this.sections, selectedSections);
208
+ if (sectionIndex !== -1) {
209
+ adjustSection(sectionIndex, PAGE_STEP[this.sections[sectionIndex].type] || 1);
210
+ }
211
+ },
212
+ decrementPage() {
213
+ if (this.readOnly || this.disabled) {
214
+ return;
215
+ }
216
+ enteredKeys.current = '';
217
+ const sectionIndex = getCurrentEditableSectionIndex(this.sections, selectedSections);
218
+ if (sectionIndex !== -1) {
219
+ adjustSection(sectionIndex, -(PAGE_STEP[this.sections[sectionIndex].type] || 1));
220
+ }
221
+ },
222
+ clearSection() {
223
+ if (this.readOnly || this.disabled) {
224
+ return;
225
+ }
226
+ enteredKeys.current = '';
227
+ if (selectedSections === 'all') {
228
+ this.clearAll();
229
+ return;
230
+ }
231
+ const sectionIndex = getCurrentEditableSectionIndex(this.sections, selectedSections);
232
+ if (sectionIndex === -1) {
233
+ return;
234
+ }
235
+ const section = this.sections[sectionIndex];
236
+ delete validSegments[section.type];
237
+ setValidSegments(Object.assign({}, validSegments));
238
+ const placeholder = createPlaceholderValue({
239
+ placeholderValue: props.placeholderValue,
240
+ timeZone: props.timeZone,
241
+ });
242
+ let currentValue = displayValue;
243
+ // Reset day period to default without changing the hour.
244
+ if (section.type === 'dayPeriod') {
245
+ const isPM = displayValue.hour() >= 12;
246
+ const shouldBePM = placeholder.hour() >= 12;
247
+ if (isPM && !shouldBePM) {
248
+ currentValue = displayValue.set('hour', displayValue.hour() - 12);
249
+ }
250
+ else if (!isPM && shouldBePM) {
251
+ currentValue = displayValue.set('hour', displayValue.hour() + 12);
252
+ }
253
+ }
254
+ else {
255
+ const type = getDurationUnitFromSectionType(section.type);
256
+ currentValue = displayValue.set(type, placeholder[type]());
257
+ }
258
+ if (value) {
259
+ setDate(null);
260
+ }
261
+ setValue(currentValue);
262
+ },
263
+ clearAll() {
264
+ if (this.readOnly || this.disabled) {
265
+ return;
266
+ }
267
+ enteredKeys.current = '';
268
+ validSegments = {};
269
+ setValidSegments({});
270
+ if (value !== null) {
271
+ setDate(null);
272
+ }
273
+ setValue(createPlaceholderValue({
274
+ placeholderValue: props.placeholderValue,
275
+ timeZone: props.timeZone,
276
+ }));
277
+ },
278
+ // eslint-disable-next-line complexity
279
+ onInput(key) {
280
+ if (this.readOnly || this.disabled) {
281
+ return;
282
+ }
283
+ const sectionIndex = getCurrentEditableSectionIndex(this.sections, selectedSections);
284
+ if (sectionIndex === -1) {
285
+ return;
286
+ }
287
+ const section = this.sections[sectionIndex];
288
+ let newValue = enteredKeys.current + key;
289
+ const onInputNumber = (numberValue) => {
290
+ var _a, _b, _c;
291
+ let sectionValue = section.type === 'month' ? numberValue - 1 : numberValue;
292
+ const allowsZero = section.minValue === 0;
293
+ if (section.type === 'hour' &&
294
+ (section.minValue === 12 || section.maxValue === 11)) {
295
+ if (numberValue > 12) {
296
+ sectionValue = Number(key);
297
+ }
298
+ if (section.minValue === 12 && sectionValue > 1) {
299
+ sectionValue += 12;
300
+ }
301
+ }
302
+ else if (sectionValue > ((_a = section.maxValue) !== null && _a !== void 0 ? _a : 0)) {
303
+ sectionValue = Number(key) - (section.type === 'month' ? 1 : 0);
304
+ newValue = key;
305
+ if (sectionValue > ((_b = section.maxValue) !== null && _b !== void 0 ? _b : 0)) {
306
+ enteredKeys.current = '';
307
+ return;
308
+ }
309
+ }
310
+ const shouldSetValue = sectionValue > 0 || (sectionValue === 0 && allowsZero);
311
+ if (shouldSetValue) {
312
+ setSection(section, sectionValue);
313
+ }
314
+ if (Number(numberValue + '0') > ((_c = section.maxValue) !== null && _c !== void 0 ? _c : 0) ||
315
+ newValue.length >= String(section.maxValue).length) {
316
+ enteredKeys.current = '';
317
+ if (shouldSetValue) {
318
+ this.focusNextSection();
319
+ }
320
+ }
321
+ else {
322
+ enteredKeys.current = newValue;
323
+ }
324
+ };
325
+ const onInputString = (stringValue) => {
326
+ var _a;
327
+ const options = (_a = section.options) !== null && _a !== void 0 ? _a : [];
328
+ let sectionValue = stringValue.toLocaleUpperCase();
329
+ let foundOptions = options.filter((v) => v.startsWith(sectionValue));
330
+ if (foundOptions.length === 0) {
331
+ if (stringValue !== key) {
332
+ sectionValue = key.toLocaleUpperCase();
333
+ foundOptions = options.filter((v) => v.startsWith(sectionValue));
334
+ }
335
+ if (foundOptions.length === 0) {
336
+ enteredKeys.current = '';
337
+ return;
338
+ }
339
+ }
340
+ const foundValue = foundOptions[0];
341
+ const index = options.indexOf(foundValue);
342
+ if (section.type === 'dayPeriod') {
343
+ setSection(section, index === 1 ? 12 : 0);
344
+ }
345
+ else {
346
+ setSection(section, index);
347
+ }
348
+ if (foundOptions.length > 1) {
349
+ enteredKeys.current = newValue;
350
+ }
351
+ else {
352
+ enteredKeys.current = '';
353
+ this.focusNextSection();
354
+ }
355
+ };
356
+ switch (section.type) {
357
+ case 'day':
358
+ case 'hour':
359
+ case 'minute':
360
+ case 'second':
361
+ case 'year': {
362
+ if (!Number.isInteger(Number(newValue))) {
363
+ return;
364
+ }
365
+ const numberValue = Number(newValue);
366
+ onInputNumber(numberValue);
367
+ break;
368
+ }
369
+ case 'dayPeriod': {
370
+ onInputString(newValue);
371
+ break;
372
+ }
373
+ case 'weekday':
374
+ case 'month': {
375
+ if (Number.isInteger(Number(newValue))) {
376
+ const numberValue = Number(newValue);
377
+ onInputNumber(numberValue);
378
+ }
379
+ else {
380
+ onInputString(newValue);
381
+ }
382
+ break;
383
+ }
384
+ }
385
+ },
386
+ setValueFromString(str) {
387
+ let date = parseDate({ input: str, format, timeZone: props.timeZone });
388
+ if (isValid(date)) {
389
+ if (props.timeZone && !isDateStringWithTimeZone(str)) {
390
+ const time = parseDate({ input: str, format });
391
+ date = mergeDateTime(date, time);
392
+ }
393
+ setDate(date);
394
+ return true;
395
+ }
396
+ return false;
397
+ },
398
+ };
399
+ }
400
+ function parseDate(options) {
401
+ let date = dateTime(options);
402
+ if (!isValid(date)) {
403
+ date = dateTime(Object.assign(Object.assign({}, options), { format: undefined }));
404
+ }
405
+ return date;
406
+ }
407
+ function isDateStringWithTimeZone(str) {
408
+ return /z$/i.test(str) || /[+-]\d\d:\d\d$/.test(str);
409
+ }
410
+ function addSegment(section, date, amount) {
411
+ var _a;
412
+ let val = (_a = section.value) !== null && _a !== void 0 ? _a : 0;
413
+ if (section.type === 'dayPeriod') {
414
+ val = date.hour() + (date.hour() > 12 ? -12 : 12);
415
+ }
416
+ else {
417
+ val = val + amount;
418
+ const min = section.minValue;
419
+ const max = section.maxValue;
420
+ if (typeof min === 'number' && typeof max === 'number') {
421
+ const length = max - min + 1;
422
+ val = ((val - min + length) % length) + min;
423
+ }
424
+ }
425
+ const type = getDurationUnitFromSectionType(section.type);
426
+ return date.set(type, val);
427
+ }
428
+ function setSegment(section, date, amount) {
429
+ const type = section.type;
430
+ switch (type) {
431
+ case 'day':
432
+ case 'weekday':
433
+ case 'month':
434
+ case 'year': {
435
+ return date.set(getDurationUnitFromSectionType(type), amount);
436
+ }
437
+ case 'dayPeriod': {
438
+ const hours = date.hour();
439
+ const wasPM = hours >= 12;
440
+ const isPM = amount >= 12;
441
+ if (isPM === wasPM) {
442
+ return date;
443
+ }
444
+ return date.set('hour', wasPM ? hours - 12 : hours + 12);
445
+ }
446
+ case 'hour': {
447
+ // In 12 hour time, ensure that AM/PM does not change
448
+ let sectionAmount = amount;
449
+ if (section.minValue === 12 || section.maxValue === 11) {
450
+ const hours = date.hour();
451
+ const wasPM = hours >= 12;
452
+ if (!wasPM && sectionAmount === 12) {
453
+ sectionAmount = 0;
454
+ }
455
+ if (wasPM && sectionAmount < 12) {
456
+ sectionAmount += 12;
457
+ }
458
+ }
459
+ return date.set('hour', sectionAmount);
460
+ }
461
+ case 'minute':
462
+ case 'second': {
463
+ return date.set(type, amount);
464
+ }
465
+ }
466
+ return date;
467
+ }
468
+ function getCurrentEditableSectionIndex(sections, selectedSections) {
469
+ const currentIndex = selectedSections === 'all' || selectedSections === -1 ? 0 : selectedSections;
470
+ const section = sections[currentIndex];
471
+ if (section && !EDITABLE_SEGMENTS[section.type]) {
472
+ return section.nextEditableSection;
473
+ }
474
+ return section ? currentIndex : -1;
475
+ }
476
+ function useFormatSections(format) {
477
+ const usedFormat = format;
478
+ const [sections, setSections] = React.useState(() => splitFormatIntoSections(usedFormat));
479
+ const [previousFormat, setFormat] = React.useState(usedFormat);
480
+ if (usedFormat !== previousFormat) {
481
+ setFormat(usedFormat);
482
+ setSections(splitFormatIntoSections(usedFormat));
483
+ }
484
+ return sections;
485
+ }
486
+ function useSectionsState(sections, value, validSegments) {
487
+ const [state, setState] = React.useState(() => {
488
+ return {
489
+ value,
490
+ sections,
491
+ validSegments,
492
+ editableSections: getEditableSections(sections, value, validSegments),
493
+ };
494
+ });
495
+ if (sections !== state.sections ||
496
+ validSegments !== state.validSegments ||
497
+ !value.isSame(state.value)) {
498
+ setState({
499
+ value,
500
+ sections,
501
+ validSegments,
502
+ editableSections: getEditableSections(sections, value, validSegments),
503
+ });
504
+ }
505
+ return state;
506
+ }
507
+ function getEditableSections(sections, value, validSegments) {
508
+ let position = 0;
509
+ const newSections = [];
510
+ let previousEditableSection = -1;
511
+ for (let i = 0; i < sections.length; i++) {
512
+ const section = sections[i];
513
+ const isEditable = EDITABLE_SEGMENTS[section.type];
514
+ let renderedValue = section.placeholder;
515
+ if ((isEditable && validSegments[section.type]) || section.type === 'timeZoneName') {
516
+ renderedValue = value.format(section.format);
517
+ }
518
+ const sectionLength = renderedValue.length;
519
+ 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) }));
520
+ newSections.push(newSection);
521
+ if (isEditable) {
522
+ for (let j = Math.max(0, previousEditableSection); j <= i; j++) {
523
+ const prevSection = newSections[j];
524
+ if (prevSection) {
525
+ prevSection.nextEditableSection = i;
526
+ if (prevSection.previousEditableSection === -1) {
527
+ prevSection.previousEditableSection = i;
528
+ }
529
+ }
530
+ }
531
+ previousEditableSection = i;
532
+ }
533
+ position += sectionLength;
534
+ }
535
+ return newSections;
536
+ }
537
+ function getValue(date, type) {
538
+ switch (type) {
539
+ case 'year':
540
+ case 'month':
541
+ case 'hour':
542
+ case 'minute':
543
+ case 'second': {
544
+ return date[type]();
545
+ }
546
+ case 'day': {
547
+ return date.date();
548
+ }
549
+ case 'weekday': {
550
+ return date.day();
551
+ }
552
+ case 'dayPeriod': {
553
+ return date.hour() >= 12 ? 12 : 0;
554
+ }
555
+ }
556
+ return undefined;
557
+ }
558
+ function isHour12(section) {
559
+ if (section.type === 'hour') {
560
+ return dateTime().set('hour', 15).format(section.format) !== '15';
561
+ }
562
+ return false;
563
+ }
564
+ function getSectionLimits(date, type, options) {
565
+ switch (type) {
566
+ case 'year': {
567
+ return {
568
+ minValue: 1,
569
+ maxValue: 9999,
570
+ };
571
+ }
572
+ case 'month': {
573
+ return {
574
+ minValue: 0,
575
+ maxValue: 11,
576
+ };
577
+ }
578
+ case 'weekday': {
579
+ return {
580
+ minValue: 0,
581
+ maxValue: 6,
582
+ };
583
+ }
584
+ case 'day': {
585
+ return {
586
+ minValue: 1,
587
+ maxValue: date ? date.daysInMonth() : 31,
588
+ };
589
+ }
590
+ case 'hour': {
591
+ if (options.hour12) {
592
+ const isPM = date.hour() >= 12;
593
+ return {
594
+ minValue: isPM ? 12 : 0,
595
+ maxValue: isPM ? 23 : 11,
596
+ };
597
+ }
598
+ return {
599
+ minValue: 0,
600
+ maxValue: 23,
601
+ };
602
+ }
603
+ case 'minute':
604
+ case 'second': {
605
+ return {
606
+ minValue: 0,
607
+ maxValue: 59,
608
+ };
609
+ }
610
+ }
611
+ return {};
612
+ }
613
+ function getDurationUnitFromSectionType(type) {
614
+ if (type === 'literal' || type === 'timeZoneName' || type === 'unknown') {
615
+ throw new Error(`${type} section does not have duration unit.`);
616
+ }
617
+ if (type in TYPE_MAPPING) {
618
+ return TYPE_MAPPING[type];
619
+ }
620
+ return type;
621
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "year_placeholder": "Y",
3
+ "month_placeholder": "M",
4
+ "weekday_placeholder": "E",
5
+ "day_placeholder": "D",
6
+ "hour_placeholder": "h",
7
+ "minute_placeholder": "m",
8
+ "second_placeholder": "s",
9
+ "dayPeriod_placeholder": "aa"
10
+ }
@@ -0,0 +1 @@
1
+ export declare const i18n: (key: "year_placeholder" | "month_placeholder" | "weekday_placeholder" | "day_placeholder" | "hour_placeholder" | "minute_placeholder" | "second_placeholder" | "dayPeriod_placeholder", params?: import("@gravity-ui/i18n").Params | undefined) => string;
@@ -0,0 +1,5 @@
1
+ import { addComponentKeysets } from '@gravity-ui/uikit/i18n';
2
+ import { NAMESPACE } from '../../../utils/cn';
3
+ import en from './en.json';
4
+ import ru from './ru.json';
5
+ export const i18n = addComponentKeysets({ en, ru }, `${NAMESPACE}date-field`);
@@ -0,0 +1,10 @@
1
+ {
2
+ "year_placeholder": "Г",
3
+ "month_placeholder": "М",
4
+ "weekday_placeholder": "ДН",
5
+ "day_placeholder": "Д",
6
+ "hour_placeholder": "ч",
7
+ "minute_placeholder": "м",
8
+ "second_placeholder": "с",
9
+ "dayPeriod_placeholder": "(д|п)п"
10
+ }
@@ -0,0 +1,3 @@
1
+ export * from './DateField';
2
+ export * from './hooks/useDateFieldState';
3
+ export * from './hooks/useDateFieldProps';
@@ -0,0 +1,3 @@
1
+ export * from './DateField';
2
+ export * from './hooks/useDateFieldState';
3
+ export * from './hooks/useDateFieldProps';