@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,98 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useCalendarCellProps = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const date_utils_1 = require("@gravity-ui/date-utils");
9
+ function useCalendarCellProps(date, state) {
10
+ const ref = react_1.default.useRef(null);
11
+ const isFocused = state.isCellFocused(date);
12
+ react_1.default.useEffect(() => {
13
+ var _a;
14
+ if (isFocused) {
15
+ (_a = ref.current) === null || _a === void 0 ? void 0 : _a.focus({ preventScroll: true });
16
+ }
17
+ }, [isFocused]);
18
+ const tabIndex = state.focusedDate.isSame(date, state.mode) ? 0 : -1;
19
+ const isDisabled = state.isCellDisabled(date);
20
+ const isSelected = state.isSelected(date);
21
+ const highlightedRange = 'highlightedRange' in state && state.highlightedRange;
22
+ const isRangeSelection = Boolean(highlightedRange && isSelected);
23
+ const isSelectionStart = isSelected && highlightedRange && date.isSame(highlightedRange.start, state.mode);
24
+ const isSelectionEnd = isSelected && highlightedRange && date.isSame(highlightedRange.end, state.mode);
25
+ const isOutsideCurrentRange = state.mode === 'days' ? !state.focusedDate.isSame(date, 'month') : false;
26
+ const isUnavailable = state.isCellUnavailable(date);
27
+ const isSelectable = !isDisabled && !isUnavailable;
28
+ const isCurrent = (0, date_utils_1.dateTime)().isSame(date, state.mode);
29
+ const isWeekend = state.isWeekend(date);
30
+ let label = '';
31
+ if (state.mode === 'days') {
32
+ label = `${date.format('dddd')}, ${date.format('LL')}`;
33
+ }
34
+ else if (state.mode === 'months') {
35
+ label = `${date.format('MMMM YYYY')}`;
36
+ }
37
+ else if (state.mode === 'years') {
38
+ label = `${date.format('YYYY')}`;
39
+ }
40
+ const cellProps = {
41
+ role: 'gridcell',
42
+ 'aria-selected': isSelected ? 'true' : undefined,
43
+ 'aria-disabled': isDisabled ? 'true' : undefined,
44
+ };
45
+ const buttonProps = {
46
+ ref,
47
+ role: 'button',
48
+ tabIndex: isDisabled ? undefined : tabIndex,
49
+ 'aria-disabled': isSelectable ? undefined : 'true',
50
+ 'aria-label': label,
51
+ onClick: isSelectable
52
+ ? () => {
53
+ state.setFocusedDate(date);
54
+ if (state.mode === 'days') {
55
+ state.selectDate(date);
56
+ }
57
+ else {
58
+ state.zoomIn();
59
+ }
60
+ }
61
+ : undefined,
62
+ onPointerEnter() {
63
+ if ('highlightDate' in state && isSelectable) {
64
+ if (isOutsideCurrentRange) {
65
+ const newDate = date.isBefore(state.focusedDate)
66
+ ? state.focusedDate.startOf('month')
67
+ : state.focusedDate.endOf('month').startOf('date');
68
+ state.highlightDate(newDate);
69
+ }
70
+ else {
71
+ state.highlightDate(date);
72
+ }
73
+ }
74
+ },
75
+ };
76
+ let formattedDate = date.format('D');
77
+ if (state.mode === 'months') {
78
+ formattedDate = date.format('MMM');
79
+ }
80
+ else if (state.mode === 'years') {
81
+ formattedDate = date.format('YYYY');
82
+ }
83
+ return {
84
+ cellProps,
85
+ buttonProps,
86
+ formattedDate,
87
+ isDisabled,
88
+ isSelected,
89
+ isRangeSelection,
90
+ isSelectionStart,
91
+ isSelectionEnd,
92
+ isOutsideCurrentRange,
93
+ isUnavailable,
94
+ isCurrent,
95
+ isWeekend,
96
+ };
97
+ }
98
+ exports.useCalendarCellProps = useCalendarCellProps;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { CalendarState, RangeCalendarState } from './types';
3
+ export declare function useCalendarGridProps(state: CalendarState | RangeCalendarState): {
4
+ gridProps: React.HTMLAttributes<HTMLElement>;
5
+ };
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCalendarGridProps = void 0;
4
+ const uikit_1 = require("@gravity-ui/uikit");
5
+ function useCalendarGridProps(state) {
6
+ const { focusWithinProps } = (0, uikit_1.useFocusWithin)({
7
+ onFocusWithinChange: (isFocused) => {
8
+ state.setFocused(isFocused);
9
+ },
10
+ });
11
+ const gridProps = Object.assign(Object.assign({ role: 'grid', 'aria-label': state.mode === 'years'
12
+ ? `${state.startDate.year()} — ${state.endDate.year()}`
13
+ : state.focusedDate.format(state.mode === 'days' ? 'MMMM YYYY' : 'YYYY'), 'aria-disabled': state.disabled ? 'true' : undefined, 'aria-readonly': state.readOnly ? 'true' : undefined }, focusWithinProps), { onKeyDown: (e) => {
14
+ if (e.key === 'ArrowRight') {
15
+ state.focusNextCell();
16
+ }
17
+ else if (e.key === 'ArrowLeft') {
18
+ state.focusPreviousCell();
19
+ }
20
+ else if (e.key === 'ArrowDown') {
21
+ state.focusNextRow();
22
+ }
23
+ else if (e.key === 'ArrowUp') {
24
+ state.focusPreviousRow();
25
+ }
26
+ else if (e.key === 'PageDown') {
27
+ state.focusNextPage(e.shiftKey);
28
+ }
29
+ else if (e.key === 'PageUp') {
30
+ state.focusPreviousPage(e.shiftKey);
31
+ }
32
+ else if (e.key === 'End') {
33
+ state.focusSectionEnd();
34
+ }
35
+ else if (e.key === 'Home') {
36
+ state.focusSectionStart();
37
+ }
38
+ else if (e.code === 'Minus') {
39
+ state.zoomOut();
40
+ }
41
+ else if (e.code === 'Equal') {
42
+ state.zoomIn();
43
+ }
44
+ else if (e.key === 'Enter' || e.key === ' ') {
45
+ if (state.mode === 'days') {
46
+ state.selectFocusedDate();
47
+ }
48
+ else {
49
+ state.setMode(state.mode === 'months' ? 'days' : 'months');
50
+ }
51
+ }
52
+ } });
53
+ return {
54
+ gridProps,
55
+ };
56
+ }
57
+ exports.useCalendarGridProps = useCalendarGridProps;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { ButtonProps } from '@gravity-ui/uikit';
3
+ import type { CalendarProps } from '../Calendar';
4
+ import type { CalendarState, RangeCalendarState } from './types';
5
+ export declare function useCalendarProps(props: CalendarProps, state: CalendarState | RangeCalendarState): {
6
+ calendarProps: React.HTMLAttributes<HTMLElement>;
7
+ modeButtonProps: ButtonProps;
8
+ nextButtonProps: ButtonProps;
9
+ previousButtonProps: ButtonProps;
10
+ };
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useCalendarProps = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const uikit_1 = require("@gravity-ui/uikit");
9
+ const i18n_1 = require("../i18n");
10
+ const buttonDisabledClassName = 'yc-button_disabled g-button_disabled';
11
+ // eslint-disable-next-line complexity
12
+ function useCalendarProps(props, state) {
13
+ const title = state.mode === 'years'
14
+ ? `${state.startDate.year()} — ${state.endDate.year()}`
15
+ : state.focusedDate.format(state.mode === 'days' ? 'MMMM YYYY' : 'YYYY');
16
+ const { focusWithinProps } = (0, uikit_1.useFocusWithin)({
17
+ onFocusWithin: props.onFocus,
18
+ onBlurWithin: props.onBlur,
19
+ });
20
+ const calendarProps = Object.assign({ role: 'group', id: props.id, 'aria-label': [props['aria-label'], title].filter(Boolean).join(', '), 'aria-labelledby': props['aria-labelledby'] || undefined, 'aria-describedby': props['aria-describedby'] || undefined, 'aria-details': props['aria-details'] || undefined, 'aria-disabled': state.disabled || undefined }, focusWithinProps);
21
+ const modeDisabled = state.disabled || state.mode === 'years';
22
+ const modeButtonProps = {
23
+ disabled: state.disabled,
24
+ // FIXME: do not use button class name
25
+ className: modeDisabled ? buttonDisabledClassName : undefined,
26
+ onClick: modeDisabled
27
+ ? undefined
28
+ : () => {
29
+ state.zoomOut();
30
+ if (state.mode === 'months') {
31
+ state.setFocused(true);
32
+ }
33
+ },
34
+ extraProps: {
35
+ 'aria-disabled': modeDisabled ? 'true' : undefined,
36
+ },
37
+ children: title,
38
+ };
39
+ const previousFocused = react_1.default.useRef(false);
40
+ const previousDisabled = state.disabled || state.isPreviousPageInvalid();
41
+ react_1.default.useLayoutEffect(() => {
42
+ if (previousDisabled && previousFocused.current) {
43
+ previousFocused.current = false;
44
+ state.setFocused(true);
45
+ }
46
+ });
47
+ const previousButtonProps = {
48
+ disabled: state.disabled,
49
+ // FIXME: do not use button class name
50
+ className: previousDisabled ? buttonDisabledClassName : undefined,
51
+ onClick: previousDisabled
52
+ ? undefined
53
+ : () => {
54
+ state.focusPreviousPage();
55
+ },
56
+ onFocus: previousDisabled
57
+ ? undefined
58
+ : () => {
59
+ previousFocused.current = true;
60
+ },
61
+ onBlur: previousDisabled
62
+ ? undefined
63
+ : () => {
64
+ previousFocused.current = false;
65
+ },
66
+ extraProps: {
67
+ 'aria-label': (0, i18n_1.i18n)('Previous'),
68
+ 'aria-disabled': previousDisabled ? 'true' : undefined,
69
+ },
70
+ };
71
+ const nextFocused = react_1.default.useRef(false);
72
+ const nextDisabled = state.disabled || state.isNextPageInvalid();
73
+ react_1.default.useLayoutEffect(() => {
74
+ if (nextDisabled && nextFocused.current) {
75
+ nextFocused.current = false;
76
+ state.setFocused(true);
77
+ }
78
+ });
79
+ const nextButtonProps = {
80
+ disabled: state.disabled,
81
+ // FIXME: do not use button class name
82
+ className: nextDisabled ? buttonDisabledClassName : undefined,
83
+ onClick: nextDisabled
84
+ ? undefined
85
+ : () => {
86
+ state.focusNextPage();
87
+ },
88
+ onFocus: nextDisabled
89
+ ? undefined
90
+ : () => {
91
+ nextFocused.current = true;
92
+ },
93
+ onBlur: nextDisabled
94
+ ? undefined
95
+ : () => {
96
+ nextFocused.current = false;
97
+ },
98
+ extraProps: {
99
+ 'aria-label': (0, i18n_1.i18n)('Next'),
100
+ 'aria-disabled': previousDisabled ? 'true' : undefined,
101
+ },
102
+ };
103
+ return {
104
+ calendarProps,
105
+ modeButtonProps,
106
+ nextButtonProps,
107
+ previousButtonProps,
108
+ };
109
+ }
110
+ exports.useCalendarProps = useCalendarProps;
@@ -0,0 +1,7 @@
1
+ import type { DateTime } from '@gravity-ui/date-utils';
2
+ import type { ValueBase } from '../../types';
3
+ import type { CalendarState, CalendarStateOptionsBase } from './types';
4
+ export interface CalendarStateOptions extends ValueBase<DateTime>, CalendarStateOptionsBase {
5
+ }
6
+ export type { CalendarState } from './types';
7
+ export declare function useCalendarState(props: CalendarStateOptions): CalendarState;
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useCalendarState = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const date_utils_1 = require("@gravity-ui/date-utils");
9
+ const useControlledState_1 = require("../../hooks/useControlledState");
10
+ const utils_1 = require("../utils");
11
+ function useCalendarState(props) {
12
+ const { disabled, readOnly, minValue, maxValue, timeZone } = props;
13
+ const [value, setValue] = (0, useControlledState_1.useControlledState)(props.value, props.defaultValue, props.onUpdate);
14
+ const [mode, setMode] = (0, useControlledState_1.useControlledState)(props.mode, props.defaultMode, props.onUpdateMode);
15
+ const currentMode = mode || 'days';
16
+ const focusedValue = react_1.default.useMemo(() => {
17
+ if (!props.focusedValue) {
18
+ return props.focusedValue;
19
+ }
20
+ return (0, utils_1.constrainValue)(props.focusedValue, minValue, maxValue);
21
+ }, [props.focusedValue, minValue, maxValue]);
22
+ const defaultFocusedValue = react_1.default.useMemo(() => {
23
+ const defaultValue = (props.defaultFocusedValue ? props.defaultFocusedValue : value) || (0, date_utils_1.dateTime)({ timeZone });
24
+ return (0, utils_1.constrainValue)(defaultValue, minValue, maxValue);
25
+ }, [maxValue, minValue, props.defaultFocusedValue, timeZone, value]);
26
+ const [focusedDateInner, setFocusedDate] = (0, useControlledState_1.useControlledState)(focusedValue, defaultFocusedValue, props.onFocusUpdate);
27
+ const focusedDate = focusedDateInner !== null && focusedDateInner !== void 0 ? focusedDateInner : (0, utils_1.constrainValue)((0, date_utils_1.dateTime)({ timeZone }), minValue, maxValue);
28
+ if (isInvalid(focusedDate, minValue, maxValue)) {
29
+ // If the focused date was moved to an invalid value, it can't be focused, so constrain it.
30
+ setFocusedDate((0, utils_1.constrainValue)(focusedDate, minValue, maxValue));
31
+ }
32
+ function focusCell(date) {
33
+ setFocusedDate((0, utils_1.constrainValue)(date, minValue, maxValue));
34
+ }
35
+ const [isFocused, setFocused] = react_1.default.useState(props.autoFocus || false);
36
+ const startDate = getStartDate(focusedDate, currentMode);
37
+ const endDate = getEndDate(focusedDate, currentMode);
38
+ return {
39
+ disabled,
40
+ readOnly,
41
+ value,
42
+ setValue,
43
+ timeZone,
44
+ selectDate(date) {
45
+ if (!disabled && !readOnly) {
46
+ const newValue = (0, utils_1.constrainValue)(date, minValue, maxValue);
47
+ if (this.isCellUnavailable(newValue)) {
48
+ return;
49
+ }
50
+ setValue((0, utils_1.constrainValue)(newValue, minValue, maxValue));
51
+ }
52
+ },
53
+ minValue,
54
+ maxValue,
55
+ focusedDate,
56
+ startDate,
57
+ endDate,
58
+ setFocusedDate(date) {
59
+ focusCell(date);
60
+ setFocused(true);
61
+ },
62
+ focusNextCell() {
63
+ focusCell(focusedDate.add({ [this.mode]: 1 }));
64
+ },
65
+ focusPreviousCell() {
66
+ focusCell(focusedDate.subtract({ [this.mode]: 1 }));
67
+ },
68
+ focusNextRow() {
69
+ if (this.mode === 'days') {
70
+ focusCell(focusedDate.add(1, 'week'));
71
+ }
72
+ else {
73
+ focusCell(focusedDate.add({ [this.mode]: 3 }));
74
+ }
75
+ },
76
+ focusPreviousRow() {
77
+ if (this.mode === 'days') {
78
+ focusCell(focusedDate.subtract(1, 'week'));
79
+ }
80
+ else {
81
+ focusCell(focusedDate.subtract({ [this.mode]: 3 }));
82
+ }
83
+ },
84
+ focusNextPage(larger) {
85
+ if (this.mode === 'days') {
86
+ focusCell(focusedDate.add({ months: larger ? 12 : 1 }));
87
+ }
88
+ else {
89
+ focusCell(focusedDate.add({ [this.mode]: 12 }));
90
+ }
91
+ },
92
+ focusPreviousPage(larger) {
93
+ if (this.mode === 'days') {
94
+ focusCell(focusedDate.subtract({ months: larger ? 12 : 1 }));
95
+ }
96
+ else {
97
+ focusCell(focusedDate.subtract({ [this.mode]: 12 }));
98
+ }
99
+ },
100
+ focusSectionStart() {
101
+ focusCell(getStartDate(focusedDate, this.mode));
102
+ },
103
+ focusSectionEnd() {
104
+ focusCell(getEndDate(focusedDate, this.mode));
105
+ },
106
+ zoomIn() {
107
+ this.setMode(this.mode === 'years' ? 'months' : 'days');
108
+ },
109
+ zoomOut() {
110
+ this.setMode(this.mode === 'days' ? 'months' : 'years');
111
+ },
112
+ selectFocusedDate() {
113
+ this.selectDate(focusedDate);
114
+ },
115
+ isFocused,
116
+ setFocused,
117
+ isInvalid(date) {
118
+ return isInvalid(date, this.minValue, this.maxValue, this.mode);
119
+ },
120
+ isPreviousPageInvalid() {
121
+ const prev = this.startDate.add({ days: -1 });
122
+ return this.isInvalid(prev);
123
+ },
124
+ isNextPageInvalid() {
125
+ const next = this.endDate.add({ days: 1 });
126
+ return this.isInvalid(next);
127
+ },
128
+ isSelected(date) {
129
+ return (Boolean(value) &&
130
+ date.isSame(value !== null && value !== void 0 ? value : undefined, currentMode) &&
131
+ !this.isCellDisabled(date));
132
+ },
133
+ isCellUnavailable(date) {
134
+ if (this.mode === 'days') {
135
+ return Boolean(props.isDateUnavailable && props.isDateUnavailable(date));
136
+ }
137
+ else {
138
+ return false;
139
+ }
140
+ },
141
+ isCellFocused(date) {
142
+ return this.isFocused && focusedDate && date.isSame(focusedDate, currentMode);
143
+ },
144
+ isCellDisabled(date) {
145
+ return this.disabled || this.isInvalid(date);
146
+ },
147
+ isWeekend(date) {
148
+ return this.mode === 'days' && [0, 6].includes(date.day());
149
+ },
150
+ mode: currentMode,
151
+ setMode,
152
+ };
153
+ }
154
+ exports.useCalendarState = useCalendarState;
155
+ function getStartDate(date, mode) {
156
+ if (mode === 'days') {
157
+ return date.startOf('month');
158
+ }
159
+ if (mode === 'months') {
160
+ return date.startOf('year');
161
+ }
162
+ const year = Math.floor(date.year() / 12) * 12;
163
+ return date.startOf('year').set('year', year);
164
+ }
165
+ function getEndDate(date, mode) {
166
+ if (mode === 'days') {
167
+ return date.endOf('month').startOf('day');
168
+ }
169
+ if (mode === 'months') {
170
+ return date.endOf('month').startOf('day');
171
+ }
172
+ const startDate = getStartDate(date, mode);
173
+ return startDate.add({ [mode]: 11 });
174
+ }
175
+ function isInvalid(date, minValue, maxValue, mode = 'days') {
176
+ const constrainedDate = (0, utils_1.constrainValue)(date, minValue, maxValue);
177
+ return !constrainedDate.isSame(date, mode);
178
+ }
@@ -0,0 +1,7 @@
1
+ import type { DateTime } from '@gravity-ui/date-utils';
2
+ import type { RangeValue, ValueBase } from '../../types';
3
+ import type { CalendarStateOptionsBase, RangeCalendarState } from './types';
4
+ export interface RangeCalendarStateOptions extends ValueBase<RangeValue<DateTime>>, CalendarStateOptionsBase {
5
+ }
6
+ export type { RangeCalendarState } from './types';
7
+ export declare function useRangeCalendarState(props: RangeCalendarStateOptions): RangeCalendarState;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.useRangeCalendarState = void 0;
18
+ const react_1 = __importDefault(require("react"));
19
+ const useControlledState_1 = require("../../hooks/useControlledState");
20
+ const utils_1 = require("../utils");
21
+ const useCalendarState_1 = require("./useCalendarState");
22
+ function useRangeCalendarState(props) {
23
+ var _a, _b;
24
+ const { value: valueProp, defaultValue, onUpdate } = props, calendarProps = __rest(props, ["value", "defaultValue", "onUpdate"]);
25
+ const [value, setValue] = (0, useControlledState_1.useControlledState)(valueProp, defaultValue, onUpdate);
26
+ const [anchorDate, setAnchorDateState] = react_1.default.useState();
27
+ const calendar = (0, useCalendarState_1.useCalendarState)(Object.assign(Object.assign({}, calendarProps), { value: (_a = value === null || value === void 0 ? void 0 : value.start) !== null && _a !== void 0 ? _a : null }));
28
+ const highlightedRange = anchorDate
29
+ ? makeRange(anchorDate, calendar.focusedDate)
30
+ : (_b = (value && makeRange(value.start, value.end))) !== null && _b !== void 0 ? _b : undefined;
31
+ const selectDate = (date) => {
32
+ if (props.disabled || props.readOnly) {
33
+ return;
34
+ }
35
+ date = (0, utils_1.constrainValue)(date, props.minValue, props.maxValue);
36
+ if (calendar.isCellUnavailable(date)) {
37
+ return;
38
+ }
39
+ if (anchorDate) {
40
+ const range = makeRange(anchorDate, date);
41
+ setValue(range);
42
+ setAnchorDateState(undefined);
43
+ }
44
+ else {
45
+ setAnchorDateState(date);
46
+ }
47
+ };
48
+ return Object.assign(Object.assign({}, calendar), { value,
49
+ setValue,
50
+ selectDate,
51
+ anchorDate, setAnchorDate: setAnchorDateState, highlightedRange,
52
+ selectFocusedDate() {
53
+ selectDate(calendar.focusedDate);
54
+ },
55
+ isSelected(date) {
56
+ if (!highlightedRange) {
57
+ return false;
58
+ }
59
+ return ((date.isSame(highlightedRange.start, this.mode) ||
60
+ date.isAfter(highlightedRange.start)) &&
61
+ (date.isSame(highlightedRange.end, this.mode) ||
62
+ date.isBefore(highlightedRange.end)));
63
+ },
64
+ highlightDate(date) {
65
+ if (anchorDate) {
66
+ this.setFocusedDate(date);
67
+ }
68
+ } });
69
+ }
70
+ exports.useRangeCalendarState = useRangeCalendarState;
71
+ function makeRange(start, end) {
72
+ if (start.isBefore(end)) {
73
+ return {
74
+ start,
75
+ end,
76
+ };
77
+ }
78
+ return {
79
+ start: end,
80
+ end: start,
81
+ };
82
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "Previous": "Previous",
3
+ "Next": "Next"
4
+ }
@@ -0,0 +1 @@
1
+ export declare const i18n: (key: "Previous" | "Next", params?: import("@gravity-ui/i18n").Params | undefined) => string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.i18n = void 0;
7
+ const i18n_1 = require("@gravity-ui/uikit/i18n");
8
+ const cn_1 = require("../../../utils/cn");
9
+ const en_json_1 = __importDefault(require("./en.json"));
10
+ const ru_json_1 = __importDefault(require("./ru.json"));
11
+ exports.i18n = (0, i18n_1.addComponentKeysets)({ en: en_json_1.default, ru: ru_json_1.default }, `${cn_1.NAMESPACE}calendar`);
@@ -0,0 +1,4 @@
1
+ {
2
+ "Previous": "Назад",
3
+ "Next": "Вперёд"
4
+ }
@@ -0,0 +1,8 @@
1
+ export * from './Calendar';
2
+ export * from './RangeCalendar';
3
+ export type { CalendarInstance } from './CalendarBase';
4
+ export * from './hooks/useCalendarState';
5
+ export * from './hooks/useRangeCalendarState';
6
+ export * from './hooks/useCalendarProps';
7
+ export * from './hooks/useCalendarGridProps';
8
+ export * from './hooks/useCalendarCellProps';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./Calendar"), exports);
18
+ __exportStar(require("./RangeCalendar"), exports);
19
+ __exportStar(require("./hooks/useCalendarState"), exports);
20
+ __exportStar(require("./hooks/useRangeCalendarState"), exports);
21
+ __exportStar(require("./hooks/useCalendarProps"), exports);
22
+ __exportStar(require("./hooks/useCalendarGridProps"), exports);
23
+ __exportStar(require("./hooks/useCalendarCellProps"), exports);
@@ -0,0 +1,4 @@
1
+ import type { DateTime } from '@gravity-ui/date-utils';
2
+ export declare function constrainValue(value: DateTime, minValue: DateTime | undefined, maxValue: DateTime | undefined): DateTime;
3
+ export declare function getDaysInPeriod(startDate: DateTime, _endDate: DateTime, mode: 'days' | 'months' | 'years'): DateTime[];
4
+ export declare function getWeekDays(): DateTime[];
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWeekDays = exports.getDaysInPeriod = exports.constrainValue = void 0;
4
+ const date_utils_1 = require("@gravity-ui/date-utils");
5
+ function constrainValue(value, minValue, maxValue) {
6
+ if (minValue && value.isBefore(minValue)) {
7
+ return minValue;
8
+ }
9
+ if (maxValue && maxValue.isBefore(value)) {
10
+ return maxValue;
11
+ }
12
+ return value;
13
+ }
14
+ exports.constrainValue = constrainValue;
15
+ function getDaysInPeriod(startDate, _endDate, mode) {
16
+ const days = [];
17
+ if (mode === 'days') {
18
+ const currentDate = startDate.startOf('week');
19
+ for (let i = 0; i < 42; i++) {
20
+ days.push(currentDate.add({ days: i }));
21
+ }
22
+ }
23
+ else {
24
+ for (let i = 0; i < 12; i++) {
25
+ days.push(startDate.add({ [mode]: i }));
26
+ }
27
+ }
28
+ return days;
29
+ }
30
+ exports.getDaysInPeriod = getDaysInPeriod;
31
+ function getWeekDays() {
32
+ const weekDays = [];
33
+ const weekStart = (0, date_utils_1.dateTime)().startOf('week');
34
+ for (let i = 0; i < 7; i++) {
35
+ const date = weekStart.add({ days: i });
36
+ weekDays.push(date);
37
+ }
38
+ return weekDays;
39
+ }
40
+ exports.getWeekDays = getWeekDays;