@gravity-ui/date-components 2.8.3 → 2.9.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 (35) hide show
  1. package/dist/cjs/components/CalendarView/Calendar.css +1 -1
  2. package/dist/cjs/components/CalendarView/CalendarView.js +3 -2
  3. package/dist/cjs/components/CalendarView/hooks/types.d.ts +2 -0
  4. package/dist/cjs/components/CalendarView/hooks/useCalendarCellProps.js +22 -19
  5. package/dist/cjs/components/CalendarView/hooks/useCalendarGridProps.js +2 -1
  6. package/dist/cjs/components/CalendarView/hooks/useCalendarProps.js +2 -1
  7. package/dist/cjs/components/CalendarView/hooks/useCalendarState.js +14 -8
  8. package/dist/cjs/components/CalendarView/hooks/useRangeCalendarState.js +1 -2
  9. package/dist/cjs/components/CalendarView/utils.d.ts +0 -1
  10. package/dist/cjs/components/CalendarView/utils.js +0 -10
  11. package/dist/cjs/components/DateField/hooks/useDateFieldProps.js +1 -4
  12. package/dist/cjs/components/RangeDatePicker/RangeDatePicker.js +1 -1
  13. package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +1 -0
  14. package/dist/cjs/components/RelativeRangeDatePicker/RelativeRangeDatePicker.js +1 -0
  15. package/dist/cjs/components/RelativeRangeDatePicker/components/Zones/Zones.js +2 -2
  16. package/dist/cjs/components/utils/dates.d.ts +3 -0
  17. package/dist/cjs/components/utils/dates.js +18 -0
  18. package/dist/esm/components/CalendarView/Calendar.css +1 -1
  19. package/dist/esm/components/CalendarView/CalendarView.js +3 -2
  20. package/dist/esm/components/CalendarView/hooks/types.d.ts +2 -0
  21. package/dist/esm/components/CalendarView/hooks/useCalendarCellProps.js +22 -19
  22. package/dist/esm/components/CalendarView/hooks/useCalendarGridProps.js +2 -1
  23. package/dist/esm/components/CalendarView/hooks/useCalendarProps.js +2 -1
  24. package/dist/esm/components/CalendarView/hooks/useCalendarState.js +9 -3
  25. package/dist/esm/components/CalendarView/hooks/useRangeCalendarState.js +1 -2
  26. package/dist/esm/components/CalendarView/utils.d.ts +0 -1
  27. package/dist/esm/components/CalendarView/utils.js +0 -9
  28. package/dist/esm/components/DateField/hooks/useDateFieldProps.js +1 -4
  29. package/dist/esm/components/RangeDatePicker/RangeDatePicker.js +1 -1
  30. package/dist/esm/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +1 -0
  31. package/dist/esm/components/RelativeRangeDatePicker/RelativeRangeDatePicker.js +1 -0
  32. package/dist/esm/components/RelativeRangeDatePicker/components/Zones/Zones.js +2 -2
  33. package/dist/esm/components/utils/dates.d.ts +3 -0
  34. package/dist/esm/components/utils/dates.js +15 -0
  35. package/package.json +1 -1
@@ -215,7 +215,7 @@
215
215
  height: 4px;
216
216
  content: "";
217
217
  border-radius: 50%;
218
- background-color: var(--g-color-text-primary);
218
+ background-color: currentColor;
219
219
  transform: translateY(8px);
220
220
  }
221
221
  .g-date-calendar__button_disabled {
@@ -10,6 +10,7 @@ const react_1 = __importDefault(require("react"));
10
10
  const icons_1 = require("@gravity-ui/icons");
11
11
  const uikit_1 = require("@gravity-ui/uikit");
12
12
  const cn_1 = require("../../utils/cn");
13
+ const dates_1 = require("../utils/dates");
13
14
  const useCalendarCellProps_1 = require("./hooks/useCalendarCellProps");
14
15
  const useCalendarGridProps_1 = require("./hooks/useCalendarGridProps");
15
16
  const useCalendarProps_1 = require("./hooks/useCalendarProps");
@@ -62,14 +63,14 @@ function Content({ className, state, animation, onAnimationEnd }) {
62
63
  function Weekdays({ state }) {
63
64
  const weekdays = (0, utils_1.getWeekDays)();
64
65
  return ((0, jsx_runtime_1.jsx)("div", { className: b('grid-row'), role: "row", children: weekdays.map((date) => {
65
- return ((0, jsx_runtime_1.jsx)("div", { className: b('weekday', { weekend: state.isWeekend(date) }), role: "columnheader", "aria-label": date.format('dddd'), children: date.format('dd') }, date.day()));
66
+ return ((0, jsx_runtime_1.jsx)("div", { className: b('weekday', { weekend: state.isWeekend(date) }), role: "columnheader", "aria-label": (0, dates_1.formatDateTime)(date, 'dddd', state.timeZone), children: (0, dates_1.formatDateTime)(date, 'dd', state.timeZone) }, date.day()));
66
67
  }) }));
67
68
  }
68
69
  function CalendarGridCells({ state }) {
69
70
  const rowsInPeriod = state.mode === 'days' ? 6 : 4;
70
71
  const columnsInRow = state.mode === 'days' ? 7 : 3 + (state.mode === 'quarters' ? 1 : 0);
71
72
  const days = (0, utils_1.getDaysInPeriod)(state.startDate, state.endDate, state.mode);
72
- return ((0, jsx_runtime_1.jsx)("div", { className: b('grid-rowgroup', { mode: state.mode }), role: "rowgroup", children: [...new Array(rowsInPeriod).keys()].map((rowIndex) => ((0, jsx_runtime_1.jsxs)("div", { className: b('grid-row'), role: "row", children: [state.mode === 'quarters' ? ((0, jsx_runtime_1.jsx)("span", { role: "rowheader", className: b('grid-rowgroup-header'), children: days[rowIndex * columnsInRow].format('YYYY') })) : null, days
73
+ return ((0, jsx_runtime_1.jsx)("div", { className: b('grid-rowgroup', { mode: state.mode }), role: "rowgroup", children: [...new Array(rowsInPeriod).keys()].map((rowIndex) => ((0, jsx_runtime_1.jsxs)("div", { className: b('grid-row'), role: "row", children: [state.mode === 'quarters' ? ((0, jsx_runtime_1.jsx)("span", { role: "rowheader", className: b('grid-rowgroup-header'), children: (0, dates_1.formatDateTime)(days[rowIndex * columnsInRow], 'YYYY', state.timeZone) })) : null, days
73
74
  .slice(rowIndex * columnsInRow, (rowIndex + 1) * columnsInRow)
74
75
  .map((date) => {
75
76
  return (0, jsx_runtime_1.jsx)(CalendarCell, { date: date, state: state }, date.unix());
@@ -8,6 +8,8 @@ export interface CalendarStateOptionsBase extends InputBase {
8
8
  maxValue?: DateTime;
9
9
  /** Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. */
10
10
  isDateUnavailable?: (date: DateTime) => boolean;
11
+ /** Callback that is called for each date of the calendar. If it returns true, then the date is weekend. */
12
+ isWeekend?: (date: DateTime) => boolean;
11
13
  /**
12
14
  * Which timezone use to show values. Example: 'default', 'system', 'Europe/Amsterdam'.
13
15
  * @default The timezone of the `value` or `defaultValue` or `focusedValue` or `defaultFocusedValue`, 'default' otherwise.
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.useCalendarCellProps = useCalendarCellProps;
7
7
  const react_1 = __importDefault(require("react"));
8
+ const dates_1 = require("../../utils/dates");
8
9
  function useCalendarCellProps(date, state) {
9
10
  const ref = react_1.default.useRef(null);
10
11
  const isFocused = state.isCellFocused(date);
@@ -26,7 +27,7 @@ function useCalendarCellProps(date, state) {
26
27
  const isSelectable = !isDisabled && !isUnavailable;
27
28
  const isCurrent = state.isCurrent(date);
28
29
  const isWeekend = state.isWeekend(date);
29
- const label = getDateLabel(date, state.mode);
30
+ const label = getDateLabel(date, state);
30
31
  const cellProps = {
31
32
  role: 'gridcell',
32
33
  'aria-selected': isSelected ? 'true' : undefined,
@@ -58,15 +59,15 @@ function useCalendarCellProps(date, state) {
58
59
  }
59
60
  },
60
61
  };
61
- let formattedDate = date.format('D');
62
+ let formattedDate = (0, dates_1.formatDateTime)(date, 'D', state.timeZone);
62
63
  if (state.mode === 'months') {
63
- formattedDate = date.format('MMM');
64
+ formattedDate = (0, dates_1.formatDateTime)(date, 'MMM', state.timeZone);
64
65
  }
65
66
  else if (state.mode === 'quarters') {
66
- formattedDate = date.format('[Q]Q');
67
+ formattedDate = (0, dates_1.formatDateTime)(date, '[Q]Q', state.timeZone);
67
68
  }
68
69
  else if (state.mode === 'years') {
69
- formattedDate = date.format('YYYY');
70
+ formattedDate = (0, dates_1.formatDateTime)(date, 'YYYY', state.timeZone);
70
71
  }
71
72
  return {
72
73
  cellProps,
@@ -83,19 +84,21 @@ function useCalendarCellProps(date, state) {
83
84
  isWeekend,
84
85
  };
85
86
  }
86
- function getDateLabel(date, mode) {
87
- let label = '';
88
- if (mode === 'days') {
89
- label = `${date.format('dddd')}, ${date.format('LL')}`;
90
- }
91
- else if (mode === 'months') {
92
- label = `${date.format('MMMM YYYY')}`;
93
- }
94
- else if (mode === 'quarters') {
95
- label = `${date.format('[Q]Q YYYY')}`;
96
- }
97
- else if (mode === 'years') {
98
- label = `${date.format('YYYY')}`;
87
+ function getDateLabel(date, state) {
88
+ switch (state.mode) {
89
+ case 'days': {
90
+ return `${(0, dates_1.formatDateTime)(date, 'dddd', state.timeZone)}, ${(0, dates_1.formatDateTime)(date, 'LL', state.timeZone)}`;
91
+ }
92
+ case 'months': {
93
+ return `${(0, dates_1.formatDateTime)(date, 'MMMM YYYY', state.timeZone)}`;
94
+ }
95
+ case 'quarters': {
96
+ return `${(0, dates_1.formatDateTime)(date, '[Q]Q YYYY', state.timeZone)}`;
97
+ }
98
+ case 'years': {
99
+ return `${(0, dates_1.formatDateTime)(date, 'YYYY', state.timeZone)}`;
100
+ }
101
+ default:
102
+ return '';
99
103
  }
100
- return label;
101
104
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useCalendarGridProps = useCalendarGridProps;
4
4
  const uikit_1 = require("@gravity-ui/uikit");
5
+ const dates_1 = require("../../utils/dates");
5
6
  function useCalendarGridProps(state) {
6
7
  const { focusWithinProps } = (0, uikit_1.useFocusWithin)({
7
8
  onFocusWithinChange: (isFocused) => {
@@ -10,7 +11,7 @@ function useCalendarGridProps(state) {
10
11
  });
11
12
  const gridProps = Object.assign(Object.assign({ role: 'grid', 'aria-label': state.mode === 'years' || state.mode === 'quarters'
12
13
  ? `${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
+ : (0, dates_1.formatDateTime)(state.focusedDate, state.mode === 'days' ? 'MMMM YYYY' : 'YYYY', state.timeZone), 'aria-disabled': state.disabled ? 'true' : undefined, 'aria-readonly': state.readOnly ? 'true' : undefined }, focusWithinProps), { onKeyDown: (e) => {
14
15
  if (e.key === 'ArrowRight') {
15
16
  e.preventDefault();
16
17
  state.focusNextCell();
@@ -6,13 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.useCalendarProps = useCalendarProps;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const uikit_1 = require("@gravity-ui/uikit");
9
+ const dates_1 = require("../../utils/dates");
9
10
  const i18n_1 = require("../i18n");
10
11
  const buttonDisabledClassName = 'yc-button_disabled g-button_disabled';
11
12
  // eslint-disable-next-line complexity
12
13
  function useCalendarProps(props, state) {
13
14
  const title = state.mode === 'years' || state.mode === 'quarters'
14
15
  ? `${state.startDate.year()} — ${state.endDate.year()}`
15
- : state.focusedDate.format(state.mode === 'days' ? 'MMMM YYYY' : 'YYYY');
16
+ : (0, dates_1.formatDateTime)(state.focusedDate, state.mode === 'days' ? 'MMMM YYYY' : 'YYYY', state.timeZone);
16
17
  const { focusWithinProps } = (0, uikit_1.useFocusWithin)({
17
18
  onFocusWithin: props.onFocus,
18
19
  onBlurWithin: props.onBlur,
@@ -32,25 +32,25 @@ function useCalendarState(props) {
32
32
  if (!props.focusedValue) {
33
33
  return props.focusedValue;
34
34
  }
35
- return (0, utils_1.constrainValue)(props.focusedValue.timeZone(timeZone), minValue, maxValue);
35
+ return (0, dates_1.constrainValue)(props.focusedValue.timeZone(timeZone), minValue, maxValue);
36
36
  }, [props.focusedValue, minValue, maxValue, timeZone]);
37
37
  const defaultFocusedValue = react_1.default.useMemo(() => {
38
38
  var _a;
39
39
  const defaultValue = ((_a = (props.defaultFocusedValue ? props.defaultFocusedValue : value)) === null || _a === void 0 ? void 0 : _a.timeZone(timeZone)) ||
40
40
  (0, dates_1.createPlaceholderValue)({ timeZone }).startOf(minMode);
41
- return (0, utils_1.constrainValue)(defaultValue, minValue, maxValue);
41
+ return (0, dates_1.constrainValue)(defaultValue, minValue, maxValue);
42
42
  }, [maxValue, minValue, props.defaultFocusedValue, timeZone, value, minMode]);
43
43
  const [focusedDateInner, setFocusedDate] = (0, uikit_1.useControlledState)(focusedValue, defaultFocusedValue, (date) => {
44
44
  var _a;
45
45
  (_a = props.onFocusUpdate) === null || _a === void 0 ? void 0 : _a.call(props, date.timeZone(inputTimeZone));
46
46
  });
47
- const focusedDate = (_c = focusedDateInner === null || focusedDateInner === void 0 ? void 0 : focusedDateInner.timeZone(timeZone)) !== null && _c !== void 0 ? _c : (0, utils_1.constrainValue)((0, dates_1.createPlaceholderValue)({ timeZone }), minValue, maxValue);
47
+ const focusedDate = (_c = focusedDateInner === null || focusedDateInner === void 0 ? void 0 : focusedDateInner.timeZone(timeZone)) !== null && _c !== void 0 ? _c : (0, dates_1.constrainValue)((0, dates_1.createPlaceholderValue)({ timeZone }), minValue, maxValue);
48
48
  if (isInvalid(focusedDate, minValue, maxValue)) {
49
49
  // If the focused date was moved to an invalid value, it can't be focused, so constrain it.
50
- setFocusedDate((0, utils_1.constrainValue)(focusedDate, minValue, maxValue));
50
+ setFocusedDate((0, dates_1.constrainValue)(focusedDate, minValue, maxValue));
51
51
  }
52
52
  function focusCell(date) {
53
- setFocusedDate((0, utils_1.constrainValue)(date.startOf(currentMode), minValue, maxValue));
53
+ setFocusedDate((0, dates_1.constrainValue)(date.startOf(currentMode), minValue, maxValue));
54
54
  }
55
55
  const [isFocused, setFocused] = react_1.default.useState(props.autoFocus || false);
56
56
  const startDate = getStartDate(focusedDate, currentMode);
@@ -61,7 +61,7 @@ function useCalendarState(props) {
61
61
  value,
62
62
  setValue(date) {
63
63
  if (!disabled && !readOnly) {
64
- let newValue = (0, utils_1.constrainValue)(date, minValue, maxValue);
64
+ let newValue = (0, dates_1.constrainValue)(date, minValue, maxValue);
65
65
  if (this.isCellUnavailable(newValue)) {
66
66
  return;
67
67
  }
@@ -199,7 +199,13 @@ function useCalendarState(props) {
199
199
  return this.disabled || this.isInvalid(date);
200
200
  },
201
201
  isWeekend(date) {
202
- return this.mode === 'days' && [0, 6].includes(date.day());
202
+ if (this.mode !== 'days') {
203
+ return false;
204
+ }
205
+ if (typeof props.isWeekend === 'function') {
206
+ return props.isWeekend(date);
207
+ }
208
+ return (0, dates_1.isWeekend)(date);
203
209
  },
204
210
  isCurrent(date) {
205
211
  return (0, date_utils_1.dateTime)({ timeZone }).isSame(date, this.mode);
@@ -237,6 +243,6 @@ function getEndDate(date, mode) {
237
243
  return startDate.add({ [mode]: 11 });
238
244
  }
239
245
  function isInvalid(date, minValue, maxValue, mode = 'days') {
240
- const constrainedDate = (0, utils_1.constrainValue)(date, minValue, maxValue);
246
+ const constrainedDate = (0, dates_1.constrainValue)(date, minValue, maxValue);
241
247
  return !constrainedDate.isSame(date, mode);
242
248
  }
@@ -6,7 +6,6 @@ const react_1 = tslib_1.__importDefault(require("react"));
6
6
  const uikit_1 = require("@gravity-ui/uikit");
7
7
  const dates_1 = require("../../utils/dates");
8
8
  const useDefaultTimeZone_1 = require("../../utils/useDefaultTimeZone");
9
- const utils_1 = require("../utils");
10
9
  const useCalendarState_1 = require("./useCalendarState");
11
10
  function useRangeCalendarState(props) {
12
11
  var _a;
@@ -40,7 +39,7 @@ function useRangeCalendarState(props) {
40
39
  if (props.readOnly) {
41
40
  return;
42
41
  }
43
- const newDate = (0, utils_1.constrainValue)(date, calendar.minValue, calendar.maxValue);
42
+ const newDate = (0, dates_1.constrainValue)(date, calendar.minValue, calendar.maxValue);
44
43
  if (calendar.isCellUnavailable(newDate)) {
45
44
  return;
46
45
  }
@@ -1,6 +1,5 @@
1
1
  import type { DateTime } from '@gravity-ui/date-utils';
2
2
  import type { CalendarLayout } from './hooks/types';
3
- export declare function constrainValue(value: DateTime, minValue: DateTime | undefined, maxValue: DateTime | undefined): DateTime;
4
3
  export declare function getDaysInPeriod(startDate: DateTime, _endDate: DateTime, mode: CalendarLayout): DateTime[];
5
4
  export declare function getWeekDays(): DateTime[];
6
5
  export declare const calendarLayouts: CalendarLayout[];
@@ -1,19 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.calendarLayouts = void 0;
4
- exports.constrainValue = constrainValue;
5
4
  exports.getDaysInPeriod = getDaysInPeriod;
6
5
  exports.getWeekDays = getWeekDays;
7
6
  const date_utils_1 = require("@gravity-ui/date-utils");
8
- function constrainValue(value, minValue, maxValue) {
9
- if (minValue && value.isBefore(minValue)) {
10
- return minValue;
11
- }
12
- if (maxValue && maxValue.isBefore(value)) {
13
- return maxValue;
14
- }
15
- return value;
16
- }
17
7
  function getDaysInPeriod(startDate, _endDate, mode) {
18
8
  const days = [];
19
9
  if (mode === 'days') {
@@ -40,10 +40,6 @@ function useDateFieldProps(state, props) {
40
40
  });
41
41
  function syncSelectionFromDOM() {
42
42
  var _a, _b;
43
- if (state.readOnly) {
44
- setSelectedSections(-1);
45
- return;
46
- }
47
43
  state.focusSectionInPosition((_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart) !== null && _b !== void 0 ? _b : 0);
48
44
  setInnerState({});
49
45
  }
@@ -165,6 +161,7 @@ function useDateFieldProps(state, props) {
165
161
  'aria-describedby': props['aria-describedby'] || undefined,
166
162
  'aria-details': props['aria-details'] || undefined,
167
163
  'aria-disabled': state.disabled || undefined,
164
+ readOnly: state.readOnly,
168
165
  inputMode,
169
166
  onClick() {
170
167
  syncSelectionFromDOM();
@@ -22,7 +22,7 @@ function RangeDatePicker(_a) {
22
22
  const state = (0, useRangeDatePickerState_1.useRangeDatePickerState)(props);
23
23
  const { groupProps, fieldProps, calendarButtonProps, popupProps, calendarProps, timeInputProps } = (0, DatePicker_1.useDatePickerProps)(state, props);
24
24
  const isOnlyTime = state.hasTime && !state.hasDate;
25
- return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: b(null, className) }, groupProps, { children: [!isOnlyTime && ((0, jsx_runtime_1.jsx)("div", { ref: anchorRef, className: b('popup-anchor'), children: (0, jsx_runtime_1.jsx)(uikit_1.Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: (0, jsx_runtime_1.jsxs)("div", { className: b('popup-content'), children: [typeof props.children === 'function' ? (props.children(Object.assign(Object.assign({}, calendarProps), { value: state.value }))) : ((0, jsx_runtime_1.jsx)(Calendar_1.RangeCalendar, Object.assign({}, calendarProps, { value: state.value }))), state.hasTime && ((0, jsx_runtime_1.jsx)("div", { className: b('time-field-wrapper'), children: (0, jsx_runtime_1.jsx)(RangeDateField_1.RangeDateField, Object.assign({}, timeInputProps)) }))] }) })) })), (0, jsx_runtime_1.jsx)(uikit_1.TextInput, Object.assign({}, fieldProps, { className: b('field'), hasClear: fieldProps.hasClear, endContent: (0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [!isOnlyTime && ((0, jsx_runtime_1.jsx)(uikit_1.Button, Object.assign({}, calendarButtonProps, { children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Calendar }) }))), isOnlyTime && ((0, jsx_runtime_1.jsx)(StubButton_1.StubButton, { size: calendarButtonProps.size, icon: icons_1.Clock }))] }) })), (0, jsx_runtime_1.jsx)(HiddenInput_1.HiddenInput, { name: props.name, form: props.form, onReset: (v) => {
25
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: b(null, className) }, groupProps, { children: [!isOnlyTime && ((0, jsx_runtime_1.jsx)("div", { ref: anchorRef, className: b('popup-anchor'), children: (0, jsx_runtime_1.jsx)(uikit_1.Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: (0, jsx_runtime_1.jsxs)("div", { className: b('popup-content'), children: [typeof props.children === 'function' ? (props.children(Object.assign(Object.assign({}, calendarProps), { value: state.value }))) : ((0, jsx_runtime_1.jsx)(Calendar_1.RangeCalendar, Object.assign({}, calendarProps, { value: state.value }))), state.hasTime && ((0, jsx_runtime_1.jsx)("div", { className: b('time-field-wrapper'), children: (0, jsx_runtime_1.jsx)(RangeDateField_1.RangeDateField, Object.assign({}, timeInputProps)) }))] }) })) })), (0, jsx_runtime_1.jsx)(uikit_1.TextInput, Object.assign({}, fieldProps, { className: b('field'), endContent: (0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [!isOnlyTime && ((0, jsx_runtime_1.jsx)(uikit_1.Button, Object.assign({}, calendarButtonProps, { children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Calendar }) }))), isOnlyTime && ((0, jsx_runtime_1.jsx)(StubButton_1.StubButton, { size: calendarButtonProps.size, icon: icons_1.Clock }))] }) })), (0, jsx_runtime_1.jsx)(HiddenInput_1.HiddenInput, { name: props.name, form: props.form, onReset: (v) => {
26
26
  state.dateFieldState.setDate(v);
27
27
  }, value: state.value, toStringValue: (v) => (v ? v.start.toISOString() : ''), disabled: state.disabled }), (0, jsx_runtime_1.jsx)(HiddenInput_1.HiddenInput, { name: props.name, form: props.form, value: state.value, toStringValue: (v) => (v ? v.end.toISOString() : ''), disabled: state.disabled })] })));
28
28
  }
@@ -40,6 +40,7 @@ function useRelativeDateFieldProps(state, props) {
40
40
  'aria-describedby': props['aria-describedby'] || undefined,
41
41
  'aria-details': props['aria-details'] || undefined,
42
42
  'aria-disabled': state.disabled || undefined,
43
+ readOnly: state.readOnly,
43
44
  },
44
45
  },
45
46
  calendarProps: {
@@ -63,6 +63,7 @@ function RelativeRangeDatePicker(props) {
63
63
  role: 'combobox',
64
64
  'aria-expanded': open,
65
65
  disabled: isMobile,
66
+ readOnly: props.readOnly,
66
67
  className: b('input', { mobile: isMobile }),
67
68
  onClick: () => {
68
69
  if (props.disabled) {
@@ -43,14 +43,14 @@ const b = (0, cn_1.block)('relative-range-date-picker-zones');
43
43
  function Zones(props) {
44
44
  const timeZone = (0, utils_1.normalizeTimeZone)(props.value);
45
45
  const size = props.isMobile ? 'xl' : props.size;
46
- return ((0, jsx_runtime_1.jsx)(uikit_1.Select, { value: [timeZone], options: zones, size: size, onUpdate: (v) => {
46
+ return ((0, jsx_runtime_1.jsx)(uikit_1.Select, { disabled: props.disabled, value: [timeZone], options: zones, size: size, onUpdate: (v) => {
47
47
  const tz = v[0];
48
48
  if (tz) {
49
49
  props.onUpdate(tz);
50
50
  }
51
51
  }, width: "max", renderControl: (controlProps) => {
52
52
  const value = timeZone === 'system' || timeZone === 'default' ? (0, i18n_1.i18n)(timeZone) : timeZone;
53
- return ((0, jsx_runtime_1.jsxs)(uikit_1.Button, { onClick: controlProps.onClick, ref: controlProps.ref, view: "flat-secondary", width: "max", pin: "clear-clear", size: size, extraProps: {
53
+ return ((0, jsx_runtime_1.jsxs)(uikit_1.Button, { onClick: controlProps.onClick, ref: controlProps.ref, view: "flat-secondary", width: "max", pin: "clear-clear", size: size, disabled: props.disabled, extraProps: {
54
54
  'aria-haspopup': 'listbox',
55
55
  'aria-expanded': controlProps.open,
56
56
  onKeyDown: controlProps.onKeyDown,
@@ -1,8 +1,11 @@
1
1
  import type { DateTime } from '@gravity-ui/date-utils';
2
+ export declare function isWeekend(date: DateTime): boolean;
2
3
  export interface PlaceholderValueOptions {
3
4
  placeholderValue?: DateTime;
4
5
  timeZone?: string;
5
6
  }
6
7
  export declare function createPlaceholderValue({ placeholderValue, timeZone }: PlaceholderValueOptions): DateTime;
7
8
  export declare function isInvalid(value: DateTime | null | undefined, minValue: DateTime | undefined, maxValue: DateTime | undefined): boolean;
9
+ export declare function constrainValue(value: DateTime, minValue: DateTime | undefined, maxValue: DateTime | undefined): DateTime;
8
10
  export declare function mergeDateTime(date: DateTime, time: DateTime): DateTime;
11
+ export declare function formatDateTime(date: DateTime, format: string, timezone: string): string;
@@ -1,9 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isWeekend = isWeekend;
3
4
  exports.createPlaceholderValue = createPlaceholderValue;
4
5
  exports.isInvalid = isInvalid;
6
+ exports.constrainValue = constrainValue;
5
7
  exports.mergeDateTime = mergeDateTime;
8
+ exports.formatDateTime = formatDateTime;
6
9
  const date_utils_1 = require("@gravity-ui/date-utils");
10
+ function isWeekend(date) {
11
+ return [0, 6].includes(date.day());
12
+ }
7
13
  function createPlaceholderValue({ placeholderValue, timeZone }) {
8
14
  return (placeholderValue !== null && placeholderValue !== void 0 ? placeholderValue : (0, date_utils_1.dateTime)({ timeZone }).set('hour', 0).set('minute', 0).set('second', 0));
9
15
  }
@@ -19,9 +25,21 @@ function isInvalid(value, minValue, maxValue) {
19
25
  }
20
26
  return false;
21
27
  }
28
+ function constrainValue(value, minValue, maxValue) {
29
+ if (minValue && value.isBefore(minValue)) {
30
+ return minValue;
31
+ }
32
+ if (maxValue && maxValue.isBefore(value)) {
33
+ return maxValue;
34
+ }
35
+ return value;
36
+ }
22
37
  function mergeDateTime(date, time) {
23
38
  return date
24
39
  .set('hours', time.hour())
25
40
  .set('minutes', time.minute())
26
41
  .set('seconds', time.second());
27
42
  }
43
+ function formatDateTime(date, format, timezone) {
44
+ return (0, date_utils_1.dateTime)({ input: date, timeZone: timezone }).format(format);
45
+ }
@@ -215,7 +215,7 @@
215
215
  height: 4px;
216
216
  content: "";
217
217
  border-radius: 50%;
218
- background-color: var(--g-color-text-primary);
218
+ background-color: currentColor;
219
219
  transform: translateY(8px);
220
220
  }
221
221
  .g-date-calendar__button_disabled {
@@ -4,6 +4,7 @@ import React from 'react';
4
4
  import { ChevronLeft, ChevronRight } from '@gravity-ui/icons';
5
5
  import { ArrowToggle, Button } from '@gravity-ui/uikit';
6
6
  import { block } from '../../utils/cn';
7
+ import { formatDateTime } from '../utils/dates';
7
8
  import { useCalendarCellProps } from './hooks/useCalendarCellProps';
8
9
  import { useCalendarGridProps } from './hooks/useCalendarGridProps';
9
10
  import { useCalendarProps } from './hooks/useCalendarProps';
@@ -56,14 +57,14 @@ function Content({ className, state, animation, onAnimationEnd }) {
56
57
  function Weekdays({ state }) {
57
58
  const weekdays = getWeekDays();
58
59
  return (_jsx("div", { className: b('grid-row'), role: "row", children: weekdays.map((date) => {
59
- return (_jsx("div", { className: b('weekday', { weekend: state.isWeekend(date) }), role: "columnheader", "aria-label": date.format('dddd'), children: date.format('dd') }, date.day()));
60
+ return (_jsx("div", { className: b('weekday', { weekend: state.isWeekend(date) }), role: "columnheader", "aria-label": formatDateTime(date, 'dddd', state.timeZone), children: formatDateTime(date, 'dd', state.timeZone) }, date.day()));
60
61
  }) }));
61
62
  }
62
63
  function CalendarGridCells({ state }) {
63
64
  const rowsInPeriod = state.mode === 'days' ? 6 : 4;
64
65
  const columnsInRow = state.mode === 'days' ? 7 : 3 + (state.mode === 'quarters' ? 1 : 0);
65
66
  const days = getDaysInPeriod(state.startDate, state.endDate, state.mode);
66
- return (_jsx("div", { className: b('grid-rowgroup', { mode: state.mode }), role: "rowgroup", children: [...new Array(rowsInPeriod).keys()].map((rowIndex) => (_jsxs("div", { className: b('grid-row'), role: "row", children: [state.mode === 'quarters' ? (_jsx("span", { role: "rowheader", className: b('grid-rowgroup-header'), children: days[rowIndex * columnsInRow].format('YYYY') })) : null, days
67
+ return (_jsx("div", { className: b('grid-rowgroup', { mode: state.mode }), role: "rowgroup", children: [...new Array(rowsInPeriod).keys()].map((rowIndex) => (_jsxs("div", { className: b('grid-row'), role: "row", children: [state.mode === 'quarters' ? (_jsx("span", { role: "rowheader", className: b('grid-rowgroup-header'), children: formatDateTime(days[rowIndex * columnsInRow], 'YYYY', state.timeZone) })) : null, days
67
68
  .slice(rowIndex * columnsInRow, (rowIndex + 1) * columnsInRow)
68
69
  .map((date) => {
69
70
  return _jsx(CalendarCell, { date: date, state: state }, date.unix());
@@ -8,6 +8,8 @@ export interface CalendarStateOptionsBase extends InputBase {
8
8
  maxValue?: DateTime;
9
9
  /** Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. */
10
10
  isDateUnavailable?: (date: DateTime) => boolean;
11
+ /** Callback that is called for each date of the calendar. If it returns true, then the date is weekend. */
12
+ isWeekend?: (date: DateTime) => boolean;
11
13
  /**
12
14
  * Which timezone use to show values. Example: 'default', 'system', 'Europe/Amsterdam'.
13
15
  * @default The timezone of the `value` or `defaultValue` or `focusedValue` or `defaultFocusedValue`, 'default' otherwise.
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import { formatDateTime } from '../../utils/dates';
2
3
  export function useCalendarCellProps(date, state) {
3
4
  const ref = React.useRef(null);
4
5
  const isFocused = state.isCellFocused(date);
@@ -20,7 +21,7 @@ export function useCalendarCellProps(date, state) {
20
21
  const isSelectable = !isDisabled && !isUnavailable;
21
22
  const isCurrent = state.isCurrent(date);
22
23
  const isWeekend = state.isWeekend(date);
23
- const label = getDateLabel(date, state.mode);
24
+ const label = getDateLabel(date, state);
24
25
  const cellProps = {
25
26
  role: 'gridcell',
26
27
  'aria-selected': isSelected ? 'true' : undefined,
@@ -52,15 +53,15 @@ export function useCalendarCellProps(date, state) {
52
53
  }
53
54
  },
54
55
  };
55
- let formattedDate = date.format('D');
56
+ let formattedDate = formatDateTime(date, 'D', state.timeZone);
56
57
  if (state.mode === 'months') {
57
- formattedDate = date.format('MMM');
58
+ formattedDate = formatDateTime(date, 'MMM', state.timeZone);
58
59
  }
59
60
  else if (state.mode === 'quarters') {
60
- formattedDate = date.format('[Q]Q');
61
+ formattedDate = formatDateTime(date, '[Q]Q', state.timeZone);
61
62
  }
62
63
  else if (state.mode === 'years') {
63
- formattedDate = date.format('YYYY');
64
+ formattedDate = formatDateTime(date, 'YYYY', state.timeZone);
64
65
  }
65
66
  return {
66
67
  cellProps,
@@ -77,19 +78,21 @@ export function useCalendarCellProps(date, state) {
77
78
  isWeekend,
78
79
  };
79
80
  }
80
- function getDateLabel(date, mode) {
81
- let label = '';
82
- if (mode === 'days') {
83
- label = `${date.format('dddd')}, ${date.format('LL')}`;
84
- }
85
- else if (mode === 'months') {
86
- label = `${date.format('MMMM YYYY')}`;
87
- }
88
- else if (mode === 'quarters') {
89
- label = `${date.format('[Q]Q YYYY')}`;
90
- }
91
- else if (mode === 'years') {
92
- label = `${date.format('YYYY')}`;
81
+ function getDateLabel(date, state) {
82
+ switch (state.mode) {
83
+ case 'days': {
84
+ return `${formatDateTime(date, 'dddd', state.timeZone)}, ${formatDateTime(date, 'LL', state.timeZone)}`;
85
+ }
86
+ case 'months': {
87
+ return `${formatDateTime(date, 'MMMM YYYY', state.timeZone)}`;
88
+ }
89
+ case 'quarters': {
90
+ return `${formatDateTime(date, '[Q]Q YYYY', state.timeZone)}`;
91
+ }
92
+ case 'years': {
93
+ return `${formatDateTime(date, 'YYYY', state.timeZone)}`;
94
+ }
95
+ default:
96
+ return '';
93
97
  }
94
- return label;
95
98
  }
@@ -1,4 +1,5 @@
1
1
  import { useFocusWithin } from '@gravity-ui/uikit';
2
+ import { formatDateTime } from '../../utils/dates';
2
3
  export function useCalendarGridProps(state) {
3
4
  const { focusWithinProps } = useFocusWithin({
4
5
  onFocusWithinChange: (isFocused) => {
@@ -7,7 +8,7 @@ export function useCalendarGridProps(state) {
7
8
  });
8
9
  const gridProps = Object.assign(Object.assign({ role: 'grid', 'aria-label': state.mode === 'years' || state.mode === 'quarters'
9
10
  ? `${state.startDate.year()} — ${state.endDate.year()}`
10
- : state.focusedDate.format(state.mode === 'days' ? 'MMMM YYYY' : 'YYYY'), 'aria-disabled': state.disabled ? 'true' : undefined, 'aria-readonly': state.readOnly ? 'true' : undefined }, focusWithinProps), { onKeyDown: (e) => {
11
+ : formatDateTime(state.focusedDate, state.mode === 'days' ? 'MMMM YYYY' : 'YYYY', state.timeZone), 'aria-disabled': state.disabled ? 'true' : undefined, 'aria-readonly': state.readOnly ? 'true' : undefined }, focusWithinProps), { onKeyDown: (e) => {
11
12
  if (e.key === 'ArrowRight') {
12
13
  e.preventDefault();
13
14
  state.focusNextCell();
@@ -1,12 +1,13 @@
1
1
  import React from 'react';
2
2
  import { useFocusWithin } from '@gravity-ui/uikit';
3
+ import { formatDateTime } from '../../utils/dates';
3
4
  import { i18n } from '../i18n';
4
5
  const buttonDisabledClassName = 'yc-button_disabled g-button_disabled';
5
6
  // eslint-disable-next-line complexity
6
7
  export function useCalendarProps(props, state) {
7
8
  const title = state.mode === 'years' || state.mode === 'quarters'
8
9
  ? `${state.startDate.year()} — ${state.endDate.year()}`
9
- : state.focusedDate.format(state.mode === 'days' ? 'MMMM YYYY' : 'YYYY');
10
+ : formatDateTime(state.focusedDate, state.mode === 'days' ? 'MMMM YYYY' : 'YYYY', state.timeZone);
10
11
  const { focusWithinProps } = useFocusWithin({
11
12
  onFocusWithin: props.onFocus,
12
13
  onBlurWithin: props.onBlur,
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
  import { dateTime } from '@gravity-ui/date-utils';
3
3
  import { useControlledState } from '@gravity-ui/uikit';
4
- import { createPlaceholderValue, mergeDateTime } from '../../utils/dates';
4
+ import { constrainValue, createPlaceholderValue, isWeekend, mergeDateTime } from '../../utils/dates';
5
5
  import { useDefaultTimeZone } from '../../utils/useDefaultTimeZone';
6
- import { calendarLayouts, constrainValue } from '../utils';
6
+ import { calendarLayouts } from '../utils';
7
7
  const defaultModes = {
8
8
  days: true,
9
9
  months: true,
@@ -193,7 +193,13 @@ export function useCalendarState(props) {
193
193
  return this.disabled || this.isInvalid(date);
194
194
  },
195
195
  isWeekend(date) {
196
- return this.mode === 'days' && [0, 6].includes(date.day());
196
+ if (this.mode !== 'days') {
197
+ return false;
198
+ }
199
+ if (typeof props.isWeekend === 'function') {
200
+ return props.isWeekend(date);
201
+ }
202
+ return isWeekend(date);
197
203
  },
198
204
  isCurrent(date) {
199
205
  return dateTime({ timeZone }).isSame(date, this.mode);
@@ -1,9 +1,8 @@
1
1
  import { __rest } from "tslib";
2
2
  import React from 'react';
3
3
  import { useControlledState } from '@gravity-ui/uikit';
4
- import { mergeDateTime } from '../../utils/dates';
4
+ import { constrainValue, mergeDateTime } from '../../utils/dates';
5
5
  import { useDefaultTimeZone } from '../../utils/useDefaultTimeZone';
6
- import { constrainValue } from '../utils';
7
6
  import { useCalendarState } from './useCalendarState';
8
7
  export function useRangeCalendarState(props) {
9
8
  var _a;
@@ -1,6 +1,5 @@
1
1
  import type { DateTime } from '@gravity-ui/date-utils';
2
2
  import type { CalendarLayout } from './hooks/types';
3
- export declare function constrainValue(value: DateTime, minValue: DateTime | undefined, maxValue: DateTime | undefined): DateTime;
4
3
  export declare function getDaysInPeriod(startDate: DateTime, _endDate: DateTime, mode: CalendarLayout): DateTime[];
5
4
  export declare function getWeekDays(): DateTime[];
6
5
  export declare const calendarLayouts: CalendarLayout[];
@@ -1,13 +1,4 @@
1
1
  import { dateTime } from '@gravity-ui/date-utils';
2
- export function constrainValue(value, minValue, maxValue) {
3
- if (minValue && value.isBefore(minValue)) {
4
- return minValue;
5
- }
6
- if (maxValue && maxValue.isBefore(value)) {
7
- return maxValue;
8
- }
9
- return value;
10
- }
11
2
  export function getDaysInPeriod(startDate, _endDate, mode) {
12
3
  const days = [];
13
4
  if (mode === 'days') {
@@ -34,10 +34,6 @@ export function useDateFieldProps(state, props) {
34
34
  });
35
35
  function syncSelectionFromDOM() {
36
36
  var _a, _b;
37
- if (state.readOnly) {
38
- setSelectedSections(-1);
39
- return;
40
- }
41
37
  state.focusSectionInPosition((_b = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.selectionStart) !== null && _b !== void 0 ? _b : 0);
42
38
  setInnerState({});
43
39
  }
@@ -159,6 +155,7 @@ export function useDateFieldProps(state, props) {
159
155
  'aria-describedby': props['aria-describedby'] || undefined,
160
156
  'aria-details': props['aria-details'] || undefined,
161
157
  'aria-disabled': state.disabled || undefined,
158
+ readOnly: state.readOnly,
162
159
  inputMode,
163
160
  onClick() {
164
161
  syncSelectionFromDOM();
@@ -19,7 +19,7 @@ export function RangeDatePicker(_a) {
19
19
  const state = useRangeDatePickerState(props);
20
20
  const { groupProps, fieldProps, calendarButtonProps, popupProps, calendarProps, timeInputProps } = useDatePickerProps(state, props);
21
21
  const isOnlyTime = state.hasTime && !state.hasDate;
22
- return (_jsxs("div", Object.assign({ className: b(null, className) }, groupProps, { children: [!isOnlyTime && (_jsx("div", { ref: anchorRef, className: b('popup-anchor'), children: _jsx(Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: _jsxs("div", { className: b('popup-content'), children: [typeof props.children === 'function' ? (props.children(Object.assign(Object.assign({}, calendarProps), { value: state.value }))) : (_jsx(RangeCalendar, Object.assign({}, calendarProps, { value: state.value }))), state.hasTime && (_jsx("div", { className: b('time-field-wrapper'), children: _jsx(RangeDateField, Object.assign({}, timeInputProps)) }))] }) })) })), _jsx(TextInput, Object.assign({}, fieldProps, { className: b('field'), hasClear: fieldProps.hasClear, endContent: _jsxs(React.Fragment, { children: [!isOnlyTime && (_jsx(Button, Object.assign({}, calendarButtonProps, { children: _jsx(Icon, { data: CalendarIcon }) }))), isOnlyTime && (_jsx(StubButton, { size: calendarButtonProps.size, icon: ClockIcon }))] }) })), _jsx(HiddenInput, { name: props.name, form: props.form, onReset: (v) => {
22
+ return (_jsxs("div", Object.assign({ className: b(null, className) }, groupProps, { children: [!isOnlyTime && (_jsx("div", { ref: anchorRef, className: b('popup-anchor'), children: _jsx(Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: _jsxs("div", { className: b('popup-content'), children: [typeof props.children === 'function' ? (props.children(Object.assign(Object.assign({}, calendarProps), { value: state.value }))) : (_jsx(RangeCalendar, Object.assign({}, calendarProps, { value: state.value }))), state.hasTime && (_jsx("div", { className: b('time-field-wrapper'), children: _jsx(RangeDateField, Object.assign({}, timeInputProps)) }))] }) })) })), _jsx(TextInput, Object.assign({}, fieldProps, { className: b('field'), endContent: _jsxs(React.Fragment, { children: [!isOnlyTime && (_jsx(Button, Object.assign({}, calendarButtonProps, { children: _jsx(Icon, { data: CalendarIcon }) }))), isOnlyTime && (_jsx(StubButton, { size: calendarButtonProps.size, icon: ClockIcon }))] }) })), _jsx(HiddenInput, { name: props.name, form: props.form, onReset: (v) => {
23
23
  state.dateFieldState.setDate(v);
24
24
  }, value: state.value, toStringValue: (v) => (v ? v.start.toISOString() : ''), disabled: state.disabled }), _jsx(HiddenInput, { name: props.name, form: props.form, value: state.value, toStringValue: (v) => (v ? v.end.toISOString() : ''), disabled: state.disabled })] })));
25
25
  }
@@ -34,6 +34,7 @@ export function useRelativeDateFieldProps(state, props) {
34
34
  'aria-describedby': props['aria-describedby'] || undefined,
35
35
  'aria-details': props['aria-details'] || undefined,
36
36
  'aria-disabled': state.disabled || undefined,
37
+ readOnly: state.readOnly,
37
38
  },
38
39
  },
39
40
  calendarProps: {
@@ -57,6 +57,7 @@ export function RelativeRangeDatePicker(props) {
57
57
  role: 'combobox',
58
58
  'aria-expanded': open,
59
59
  disabled: isMobile,
60
+ readOnly: props.readOnly,
60
61
  className: b('input', { mobile: isMobile }),
61
62
  onClick: () => {
62
63
  if (props.disabled) {
@@ -40,14 +40,14 @@ const b = block('relative-range-date-picker-zones');
40
40
  export function Zones(props) {
41
41
  const timeZone = normalizeTimeZone(props.value);
42
42
  const size = props.isMobile ? 'xl' : props.size;
43
- return (_jsx(Select, { value: [timeZone], options: zones, size: size, onUpdate: (v) => {
43
+ return (_jsx(Select, { disabled: props.disabled, value: [timeZone], options: zones, size: size, onUpdate: (v) => {
44
44
  const tz = v[0];
45
45
  if (tz) {
46
46
  props.onUpdate(tz);
47
47
  }
48
48
  }, width: "max", renderControl: (controlProps) => {
49
49
  const value = timeZone === 'system' || timeZone === 'default' ? i18n(timeZone) : timeZone;
50
- return (_jsxs(Button, { onClick: controlProps.onClick, ref: controlProps.ref, view: "flat-secondary", width: "max", pin: "clear-clear", size: size, extraProps: {
50
+ return (_jsxs(Button, { onClick: controlProps.onClick, ref: controlProps.ref, view: "flat-secondary", width: "max", pin: "clear-clear", size: size, disabled: props.disabled, extraProps: {
51
51
  'aria-haspopup': 'listbox',
52
52
  'aria-expanded': controlProps.open,
53
53
  onKeyDown: controlProps.onKeyDown,
@@ -1,8 +1,11 @@
1
1
  import type { DateTime } from '@gravity-ui/date-utils';
2
+ export declare function isWeekend(date: DateTime): boolean;
2
3
  export interface PlaceholderValueOptions {
3
4
  placeholderValue?: DateTime;
4
5
  timeZone?: string;
5
6
  }
6
7
  export declare function createPlaceholderValue({ placeholderValue, timeZone }: PlaceholderValueOptions): DateTime;
7
8
  export declare function isInvalid(value: DateTime | null | undefined, minValue: DateTime | undefined, maxValue: DateTime | undefined): boolean;
9
+ export declare function constrainValue(value: DateTime, minValue: DateTime | undefined, maxValue: DateTime | undefined): DateTime;
8
10
  export declare function mergeDateTime(date: DateTime, time: DateTime): DateTime;
11
+ export declare function formatDateTime(date: DateTime, format: string, timezone: string): string;
@@ -1,4 +1,7 @@
1
1
  import { dateTime } from '@gravity-ui/date-utils';
2
+ export function isWeekend(date) {
3
+ return [0, 6].includes(date.day());
4
+ }
2
5
  export function createPlaceholderValue({ placeholderValue, timeZone }) {
3
6
  return (placeholderValue !== null && placeholderValue !== void 0 ? placeholderValue : dateTime({ timeZone }).set('hour', 0).set('minute', 0).set('second', 0));
4
7
  }
@@ -14,9 +17,21 @@ export function isInvalid(value, minValue, maxValue) {
14
17
  }
15
18
  return false;
16
19
  }
20
+ export function constrainValue(value, minValue, maxValue) {
21
+ if (minValue && value.isBefore(minValue)) {
22
+ return minValue;
23
+ }
24
+ if (maxValue && maxValue.isBefore(value)) {
25
+ return maxValue;
26
+ }
27
+ return value;
28
+ }
17
29
  export function mergeDateTime(date, time) {
18
30
  return date
19
31
  .set('hours', time.hour())
20
32
  .set('minutes', time.minute())
21
33
  .set('seconds', time.second());
22
34
  }
35
+ export function formatDateTime(date, format, timezone) {
36
+ return dateTime({ input: date, timeZone: timezone }).format(format);
37
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/date-components",
3
- "version": "2.8.3",
3
+ "version": "2.9.0",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",