@snack-uikit/calendar 0.13.13 → 0.13.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +8 -8
- package/dist/cjs/components/Calendar/Calendar.d.ts +27 -7
- package/dist/cjs/constants.d.ts +3 -1
- package/dist/cjs/constants.js +4 -2
- package/dist/cjs/helperComponents/CalendarBase/CalendarBase.js +13 -3
- package/dist/cjs/helperComponents/DecadeView/DecadeView.js +7 -1
- package/dist/cjs/helperComponents/MonthView/MonthView.js +1 -1
- package/dist/cjs/helperComponents/YearView/YearView.js +7 -1
- package/dist/cjs/hooks.js +2 -1
- package/dist/cjs/utils.d.ts +4 -0
- package/dist/cjs/utils.js +9 -1
- package/dist/esm/components/Calendar/Calendar.d.ts +27 -7
- package/dist/esm/constants.d.ts +3 -1
- package/dist/esm/constants.js +3 -1
- package/dist/esm/helperComponents/CalendarBase/CalendarBase.js +14 -4
- package/dist/esm/helperComponents/DecadeView/DecadeView.js +5 -1
- package/dist/esm/helperComponents/MonthView/MonthView.js +1 -1
- package/dist/esm/helperComponents/YearView/YearView.js +5 -1
- package/dist/esm/hooks.js +2 -1
- package/dist/esm/utils.d.ts +4 -0
- package/dist/esm/utils.js +4 -0
- package/package.json +4 -4
- package/src/components/Calendar/Calendar.tsx +35 -7
- package/src/constants.ts +3 -1
- package/src/helperComponents/CalendarBase/CalendarBase.tsx +29 -7
- package/src/helperComponents/DecadeView/DecadeView.tsx +7 -0
- package/src/helperComponents/MonthView/MonthView.tsx +1 -1
- package/src/helperComponents/YearView/YearView.tsx +7 -0
- package/src/hooks.ts +5 -4
- package/src/utils.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## <small>0.13.14 (2026-02-18)</small>
|
|
7
|
+
|
|
8
|
+
* feat(PDS-2680)!: added mode "month-range" and "year-range" for calendar & rename "range" in "date-ra ([6fbf360](https://github.com/cloud-ru-tech/snack-uikit/commit/6fbf360))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## <small>0.13.13 (2026-01-19)</small>
|
|
7
15
|
|
|
8
16
|
* chore(FF-6693): migrate tests from TestCafe to Playwright ([f32aff8](https://github.com/cloud-ru-tech/snack-uikit/commit/f32aff8))
|
package/README.md
CHANGED
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
### Description
|
|
18
18
|
|
|
19
|
-
- `Calendar` — основной компонент для выбора дат и периодов: он может работать в режимах `date`, `range`, `month`, `year` и `date-time` (дата и время).
|
|
19
|
+
- `Calendar` — основной компонент для выбора дат и периодов: он может работать в режимах `date`, `date-range`, `month`, `month-range`, `year-range`, `year` и `date-time` (дата и время).
|
|
20
20
|
- Компонент поддерживает как контролируемый (`value` + `onChangeValue`), так и неконтролируемый (`defaultValue`) режимы и умеет подстраиваться под разные размеры через проп `size` (`s`, `m`, `l`).
|
|
21
21
|
- С помощью колбека `buildCellProps` можно управлять доступностью и подсветкой отдельных ячеек (например, отключить прошлые даты или выделить праздничные дни), а опция `showHolidays` автоматически раскрашивает выходные.
|
|
22
|
-
- Проп `presets` позволяет добавить панель с пресетами для быстрого выбора периода в режиме `range`, в том числе с собственным списком вариантов.
|
|
22
|
+
- Проп `presets` позволяет добавить панель с пресетами для быстрого выбора периода в режиме `date-range`, в том числе с собственным списком вариантов.
|
|
23
23
|
- Локаль (`locale`) задаёт язык подписей и первый день недели, при отсутствии явно переданного значения используется язык браузера пользователя.
|
|
24
24
|
- Figma: [`Calendar`](https://www.figma.com/file/jtGxAPvFJOMir7V0eQFukN/Snack-UI-Kit-1.1.0?node-id=41%3A27244&mode=design).
|
|
25
25
|
|
|
@@ -41,7 +41,7 @@ function CalendarExample() {
|
|
|
41
41
|
|
|
42
42
|
{/* Выбор периода c пресетами */}
|
|
43
43
|
<Calendar
|
|
44
|
-
mode='range'
|
|
44
|
+
mode='date-range'
|
|
45
45
|
presets={{
|
|
46
46
|
enabled: true,
|
|
47
47
|
title: true,
|
|
@@ -102,7 +102,7 @@ function TimePickerExample() {
|
|
|
102
102
|
### Props
|
|
103
103
|
| name | type | default value | description |
|
|
104
104
|
|------|------|---------------|-------------|
|
|
105
|
-
| mode* | "date" \| "date-time" \| "range" \| "month" \| "year" | - | Режим работы календаря: <br> - `date` - режим выбора даты <br> - `range` - режим выбора периода <br> - `month` - режим выбора месяца <br> - `date-time` - режим выбора даты и времени <br> - `year` - режим выбора года |
|
|
105
|
+
| mode* | "date" \| "date-time" \| "date-range" \| "month" \| "month-range" \| "year" \| "year-range" | - | Режим работы календаря: <br> - `date` - режим выбора даты <br> - `date-range` - режим выбора периода <br> - `month-range` - режим выбора периода из месяцев <br> - `year-range` - режим выбора периода из лет <br> - `month` - режим выбора месяца <br> - `date-time` - режим выбора даты и времени <br> - `year` - режим выбора года |
|
|
106
106
|
| size | enum Size: `"s"`, `"m"`, `"l"` | m | Размер |
|
|
107
107
|
| today | `number \| Date` | - | Дата сегодняшнего дня |
|
|
108
108
|
| showHolidays | `boolean` | - | Раскрашивает субботу и воскресенье |
|
|
@@ -114,10 +114,10 @@ function TimePickerExample() {
|
|
|
114
114
|
| locale | `Intl.Locale` | Проставляется в соответствие с языком в настройках браузера | Локаль, в соответствие с которой выставляется язык названий и первый день недели |
|
|
115
115
|
| onFocusLeave | `(direction: FocusDirection) => void` | - | Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. |
|
|
116
116
|
| navigationStartRef | `RefObject<{ focus(): void; }>` | - | Ссылка на управление первым элементом навигации |
|
|
117
|
-
| presets | `PresetsOptions` | - | Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'range' и отсутствии buildCellProps (временно PDS-3139) |
|
|
118
|
-
| value | `Date \| Range` | - | Выбранное значение.<br> - в режиме date тип `Date` <br> - в режиме range тип `Range` (`[Date, Date]`) <br> - в режиме month тип `Date` <br> - в режиме date-time тип `Date` <br> - в режиме year тип `Date` |
|
|
119
|
-
| defaultValue | `Date \| Range` | - | Значение по-умолчанию для uncontrolled.<br> - в режиме date тип `Date` <br> - в режиме range тип `Range` (`[Date, Date]`) <br> - в режиме month тип `Date` <br> - в режиме date-time тип `Date` <br> - в режиме year тип `Date` |
|
|
120
|
-
| onChangeValue | `((value: Date) => void) \| ((value: Range) => void) \| ((value: Date) => void) \| ((value: Date) => void) \| ((value: Date) => void)` | - | Колбек выбора значения.<br> - в режиме date принимает тип `Date` <br> - в режиме range принимает тип `Range` <br> - в режиме month принимает тип `Date` <br> - в режиме date-time принимает тип `Date` <br> - в режиме year принимает тип `Date` |
|
|
117
|
+
| presets | `PresetsOptions` | - | Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) |
|
|
118
|
+
| value | `Date \| Range` | - | Выбранное значение.<br> - в режиме date тип `Date` <br> - в режиме date-range тип `Range` (`[Date, Date]`) <br> - в режиме month-range тип `Range` (`[Date, Date]`) <br> - в режиме year-range тип `Range` (`[Date, Date]`) <br> - в режиме month тип `Date` <br> - в режиме date-time тип `Date` <br> - в режиме year тип `Date` |
|
|
119
|
+
| defaultValue | `Date \| Range` | - | Значение по-умолчанию для uncontrolled.<br> - в режиме date тип `Date` <br> - в режиме date-range тип `Range` (`[Date, Date]`) <br> - в режиме month-range тип `Range` (`[Date, Date]`) <br> - в режиме year-range тип `Range` (`[Date, Date]`) <br> - в режиме month тип `Date` <br> - в режиме date-time тип `Date` <br> - в режиме year тип `Date` |
|
|
120
|
+
| onChangeValue | `((value: Date) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Range) => void) \| ((value: Date) => void) \| ((value: Date) => void) \| ((value: Date) => void)` | - | Колбек выбора значения.<br> - в режиме date принимает тип `Date` <br> - в режиме date-range принимает тип `Range` <br> - в режиме month-range принимает тип `Range` <br> - в режиме year-range принимает тип `Range` <br> - в режиме month принимает тип `Date` <br> - в режиме date-time принимает тип `Date` <br> - в режиме year принимает тип `Date` |
|
|
121
121
|
| showSeconds | `boolean` | - | Показывать ли секунды (только в режиме date-time) |
|
|
122
122
|
## TimePicker
|
|
123
123
|
### Props
|
|
@@ -46,7 +46,7 @@ type CommonCalendarProps = {
|
|
|
46
46
|
navigationStartRef?: RefObject<{
|
|
47
47
|
focus(): void;
|
|
48
48
|
}>;
|
|
49
|
-
/** Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'range' и отсутствии buildCellProps (временно PDS-3139) */
|
|
49
|
+
/** Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) */
|
|
50
50
|
presets?: PresetsOptions;
|
|
51
51
|
};
|
|
52
52
|
type DateCalendarProps = CommonCalendarProps & {
|
|
@@ -92,15 +92,35 @@ type DateTimeCalendarProps = CommonCalendarProps & {
|
|
|
92
92
|
showSeconds?: boolean;
|
|
93
93
|
};
|
|
94
94
|
type RangeCalendarProps = CommonCalendarProps & {
|
|
95
|
-
/** <br> - `range` - режим выбора периода */
|
|
96
|
-
mode: typeof CALENDAR_MODE.
|
|
97
|
-
/** <br> - в режиме range тип `Range` (`[Date, Date]`) */
|
|
95
|
+
/** <br> - `date-range` - режим выбора периода */
|
|
96
|
+
mode: typeof CALENDAR_MODE.DateRange;
|
|
97
|
+
/** <br> - в режиме date-range тип `Range` (`[Date, Date]`) */
|
|
98
98
|
value?: Range;
|
|
99
|
-
/** <br> - в режиме range тип `Range` (`[Date, Date]`) */
|
|
99
|
+
/** <br> - в режиме date-range тип `Range` (`[Date, Date]`) */
|
|
100
100
|
defaultValue?: Range;
|
|
101
|
-
/** <br> - в режиме range принимает тип `Range` */
|
|
101
|
+
/** <br> - в режиме date-range принимает тип `Range` */
|
|
102
102
|
onChangeValue?(value: Range): void;
|
|
103
103
|
};
|
|
104
|
-
|
|
104
|
+
type MonthRangeCalendarProps = CommonCalendarProps & {
|
|
105
|
+
/** <br> - `month-range` - режим выбора периода из месяцев */
|
|
106
|
+
mode: typeof CALENDAR_MODE.MonthRange;
|
|
107
|
+
/** <br> - в режиме month-range тип `Range` (`[Date, Date]`) */
|
|
108
|
+
value?: Range;
|
|
109
|
+
/** <br> - в режиме month-range тип `Range` (`[Date, Date]`) */
|
|
110
|
+
defaultValue?: Range;
|
|
111
|
+
/** <br> - в режиме month-range принимает тип `Range` */
|
|
112
|
+
onChangeValue?(value: Range): void;
|
|
113
|
+
};
|
|
114
|
+
type YearRangeCalendarProps = CommonCalendarProps & {
|
|
115
|
+
/** <br> - `year-range` - режим выбора периода из лет */
|
|
116
|
+
mode: typeof CALENDAR_MODE.YearRange;
|
|
117
|
+
/** <br> - в режиме year-range тип `Range` (`[Date, Date]`) */
|
|
118
|
+
value?: Range;
|
|
119
|
+
/** <br> - в режиме year-range тип `Range` (`[Date, Date]`) */
|
|
120
|
+
defaultValue?: Range;
|
|
121
|
+
/** <br> - в режиме year-range принимает тип `Range` */
|
|
122
|
+
onChangeValue?(value: Range): void;
|
|
123
|
+
};
|
|
124
|
+
export type CalendarProps = WithSupportProps<DateCalendarProps | RangeCalendarProps | MonthRangeCalendarProps | YearRangeCalendarProps | MonthCalendarProps | DateTimeCalendarProps | YearCalendarProps>;
|
|
105
125
|
export declare function Calendar(props: CalendarProps): import("react/jsx-runtime").JSX.Element;
|
|
106
126
|
export {};
|
package/dist/cjs/constants.d.ts
CHANGED
|
@@ -6,9 +6,11 @@ export declare const VIEW_MODE: {
|
|
|
6
6
|
export declare const CALENDAR_MODE: {
|
|
7
7
|
readonly Date: "date";
|
|
8
8
|
readonly DateTime: "date-time";
|
|
9
|
-
readonly
|
|
9
|
+
readonly DateRange: "date-range";
|
|
10
10
|
readonly Month: "month";
|
|
11
|
+
readonly MonthRange: "month-range";
|
|
11
12
|
readonly Year: "year";
|
|
13
|
+
readonly YearRange: "year-range";
|
|
12
14
|
};
|
|
13
15
|
export declare const IN_RANGE_POSITION: {
|
|
14
16
|
readonly Out: "out";
|
package/dist/cjs/constants.js
CHANGED
|
@@ -12,9 +12,11 @@ exports.VIEW_MODE = {
|
|
|
12
12
|
exports.CALENDAR_MODE = {
|
|
13
13
|
Date: 'date',
|
|
14
14
|
DateTime: 'date-time',
|
|
15
|
-
|
|
15
|
+
DateRange: 'date-range',
|
|
16
16
|
Month: 'month',
|
|
17
|
-
|
|
17
|
+
MonthRange: 'month-range',
|
|
18
|
+
Year: 'year',
|
|
19
|
+
YearRange: 'year-range'
|
|
18
20
|
};
|
|
19
21
|
exports.IN_RANGE_POSITION = {
|
|
20
22
|
Out: 'out',
|
|
@@ -50,8 +50,10 @@ const CALENDAR_SIZE_MAP = {
|
|
|
50
50
|
const CALENDAR_DEFAULT_MODE_MAP = {
|
|
51
51
|
[constants_1.CALENDAR_MODE.Date]: constants_1.VIEW_MODE.Month,
|
|
52
52
|
[constants_1.CALENDAR_MODE.DateTime]: constants_1.VIEW_MODE.Month,
|
|
53
|
-
[constants_1.CALENDAR_MODE.
|
|
53
|
+
[constants_1.CALENDAR_MODE.DateRange]: constants_1.VIEW_MODE.Month,
|
|
54
|
+
[constants_1.CALENDAR_MODE.MonthRange]: constants_1.VIEW_MODE.Year,
|
|
54
55
|
[constants_1.CALENDAR_MODE.Month]: constants_1.VIEW_MODE.Year,
|
|
56
|
+
[constants_1.CALENDAR_MODE.YearRange]: constants_1.VIEW_MODE.Decade,
|
|
55
57
|
[constants_1.CALENDAR_MODE.Year]: constants_1.VIEW_MODE.Decade
|
|
56
58
|
};
|
|
57
59
|
function CalendarBase(_a) {
|
|
@@ -111,8 +113,16 @@ function CalendarBase(_a) {
|
|
|
111
113
|
});
|
|
112
114
|
const setValue = (0, react_1.useCallback)(dates => {
|
|
113
115
|
const [first, last] = (0, utils_2.sortDates)(dates);
|
|
116
|
+
if (mode === constants_1.CALENDAR_MODE.MonthRange) {
|
|
117
|
+
setValueState([(0, utils_2.getStartOfTheMonth)(first), (0, utils_2.getEndOfTheMonth)(last)]);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (mode === constants_1.CALENDAR_MODE.YearRange) {
|
|
121
|
+
setValueState([(0, utils_2.getStartOfTheYear)(first), (0, utils_2.getEndOfTheYear)(last)]);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
114
124
|
setValueState([first, (0, utils_2.getEndOfTheDay)(last)]);
|
|
115
|
-
}, [setValueState]);
|
|
125
|
+
}, [mode, setValueState]);
|
|
116
126
|
const {
|
|
117
127
|
preselectedRange,
|
|
118
128
|
continuePreselect,
|
|
@@ -137,7 +147,7 @@ function CalendarBase(_a) {
|
|
|
137
147
|
}
|
|
138
148
|
return (0, utils_3.getDefaultPresets)(t, today);
|
|
139
149
|
}, [presets === null || presets === void 0 ? void 0 : presets.items, t, today]);
|
|
140
|
-
const arePeriodPresetsDisplayed = mode ===
|
|
150
|
+
const arePeriodPresetsDisplayed = mode === constants_1.CALENDAR_MODE.DateRange && (presets === null || presets === void 0 ? void 0 : presets.enabled) && !buildCellProps; // TODO PDS-3139
|
|
141
151
|
const onPresetClick = (0, react_1.useCallback)(selectedPeriod => {
|
|
142
152
|
setValue(selectedPeriod);
|
|
143
153
|
}, [setValue]);
|
|
@@ -21,7 +21,9 @@ function DecadeView() {
|
|
|
21
21
|
continuePreselect,
|
|
22
22
|
restartPreselect,
|
|
23
23
|
mode,
|
|
24
|
-
setValue
|
|
24
|
+
setValue,
|
|
25
|
+
startPreselect,
|
|
26
|
+
completePreselect
|
|
25
27
|
} = (0, react_1.useContext)(CalendarContext_1.CalendarContext);
|
|
26
28
|
const grid = (0, hooks_1.useGrid)({
|
|
27
29
|
buildGrid: utils_2.buildDecadeGrid,
|
|
@@ -29,6 +31,10 @@ function DecadeView() {
|
|
|
29
31
|
isInPeriod: utils_1.isTheSameDecade,
|
|
30
32
|
getItemLabel: utils_1.getYearLabel,
|
|
31
33
|
onSelect(date) {
|
|
34
|
+
if (mode === constants_1.CALENDAR_MODE.YearRange) {
|
|
35
|
+
preselectedRange ? completePreselect(date) : startPreselect(date);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
32
38
|
if (mode === constants_1.CALENDAR_MODE.Year) {
|
|
33
39
|
setValue([date, date]);
|
|
34
40
|
return;
|
|
@@ -23,7 +23,9 @@ function YearView() {
|
|
|
23
23
|
restartPreselect,
|
|
24
24
|
locale,
|
|
25
25
|
setValue,
|
|
26
|
-
mode
|
|
26
|
+
mode,
|
|
27
|
+
startPreselect,
|
|
28
|
+
completePreselect
|
|
27
29
|
} = (0, react_1.useContext)(CalendarContext_1.CalendarContext);
|
|
28
30
|
const grid = (0, hooks_1.useGrid)({
|
|
29
31
|
buildGrid: utils_2.buildYearGrid,
|
|
@@ -35,6 +37,10 @@ function YearView() {
|
|
|
35
37
|
setValue([date, date]);
|
|
36
38
|
return;
|
|
37
39
|
}
|
|
40
|
+
if (mode === constants_1.CALENDAR_MODE.MonthRange) {
|
|
41
|
+
preselectedRange ? completePreselect(date) : startPreselect(date);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
38
44
|
setFocus(constants_1.AUTOFOCUS);
|
|
39
45
|
setViewShift((0, utils_1.getMonthShift)(referenceDate, date));
|
|
40
46
|
setViewMode(constants_1.VIEW_MODE.Month);
|
package/dist/cjs/hooks.js
CHANGED
|
@@ -66,7 +66,8 @@ function useGrid(_ref) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
const dateTimeSelectedValue = isDateFilled() ? new Date((_b = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.year) !== null && _b !== void 0 ? _b : 0, (_c = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.month) !== null && _c !== void 0 ? _c : 0, (_d = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.day) !== null && _d !== void 0 ? _d : 0) : undefined;
|
|
69
|
-
const
|
|
69
|
+
const isRangeMode = mode === constants_1.CALENDAR_MODE.DateRange || mode === constants_1.CALENDAR_MODE.MonthRange || mode === constants_1.CALENDAR_MODE.YearRange;
|
|
70
|
+
const inRangePosition = isRangeMode ? (0, utils_2.getInRangePosition)(date, viewMode, preselectedRange || value) : constants_1.IN_RANGE_POSITION.Out;
|
|
70
71
|
const isSelectedValue = value && !preselectedRange && !dateTimeSelectedValue ? isTheSameItem(value[0], date) || isTheSameItem(value[1], date) : false;
|
|
71
72
|
const isPreselected = preselectedRange ? isTheSameItem(preselectedRange[0], date) : false;
|
|
72
73
|
const isDateTimeValueSelected = dateTimeSelectedValue ? isTheSameItem(dateTimeSelectedValue, date) : false;
|
package/dist/cjs/utils.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare const isTheSameItem: (viewMode: ViewMode, date1: Date, date2: Dat
|
|
|
15
15
|
export declare const sortDates: (dates: Date[]) => Date[];
|
|
16
16
|
export declare const getInRangePosition: (date: Date, viewMode: ViewMode, range?: Range) => InRangePosition;
|
|
17
17
|
export declare const getEndOfTheDay: (date: Date) => Date;
|
|
18
|
+
export declare const getStartOfTheMonth: (date: Date) => Date;
|
|
19
|
+
export declare const getEndOfTheMonth: (date: Date) => Date;
|
|
20
|
+
export declare const getStartOfTheYear: (date: Date) => Date;
|
|
21
|
+
export declare const getEndOfTheYear: (date: Date) => Date;
|
|
18
22
|
export declare const getTestIdBuilder: (testId?: string) => (prefix: string) => string | undefined;
|
|
19
23
|
export declare const getLocale: ({ localeProp, ctxLang }?: {
|
|
20
24
|
localeProp?: Intl.Locale;
|
package/dist/cjs/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isWeekend = exports.getStartOfWeek = exports.getLocale = exports.getTestIdBuilder = exports.getEndOfTheDay = exports.getInRangePosition = exports.sortDates = exports.isTheSameItem = exports.getDecadeShift = exports.getYearShift = exports.getMonthShift = exports.getYearLabel = exports.getDateLabel = exports.getMonthName = exports.capitalize = exports.isTheSameMonth = exports.isTheSameYear = exports.isTheSameDecade = void 0;
|
|
6
|
+
exports.isWeekend = exports.getStartOfWeek = exports.getLocale = exports.getTestIdBuilder = exports.getEndOfTheYear = exports.getStartOfTheYear = exports.getEndOfTheMonth = exports.getStartOfTheMonth = exports.getEndOfTheDay = exports.getInRangePosition = exports.sortDates = exports.isTheSameItem = exports.getDecadeShift = exports.getYearShift = exports.getMonthShift = exports.getYearLabel = exports.getDateLabel = exports.getMonthName = exports.capitalize = exports.isTheSameMonth = exports.isTheSameYear = exports.isTheSameDecade = void 0;
|
|
7
7
|
exports.isTheSameDate = isTheSameDate;
|
|
8
8
|
const weekstart_1 = require("weekstart");
|
|
9
9
|
const utils_1 = require("@snack-uikit/utils");
|
|
@@ -77,6 +77,14 @@ const getInRangePosition = (date, viewMode, range) => {
|
|
|
77
77
|
exports.getInRangePosition = getInRangePosition;
|
|
78
78
|
const getEndOfTheDay = date => new Date(new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).valueOf() - 1);
|
|
79
79
|
exports.getEndOfTheDay = getEndOfTheDay;
|
|
80
|
+
const getStartOfTheMonth = date => new Date(new Date(date.getFullYear(), date.getMonth(), 1).valueOf());
|
|
81
|
+
exports.getStartOfTheMonth = getStartOfTheMonth;
|
|
82
|
+
const getEndOfTheMonth = date => new Date(new Date(date.getFullYear(), date.getMonth() + 1, 1).valueOf() - 1);
|
|
83
|
+
exports.getEndOfTheMonth = getEndOfTheMonth;
|
|
84
|
+
const getStartOfTheYear = date => new Date(new Date(date.getFullYear(), 0, 1).valueOf());
|
|
85
|
+
exports.getStartOfTheYear = getStartOfTheYear;
|
|
86
|
+
const getEndOfTheYear = date => new Date(new Date(date.getFullYear() + 1, 0, 1).valueOf() - 1);
|
|
87
|
+
exports.getEndOfTheYear = getEndOfTheYear;
|
|
80
88
|
const getTestIdBuilder = testId => prefix => testId ? `${prefix}-${testId}` : undefined;
|
|
81
89
|
exports.getTestIdBuilder = getTestIdBuilder;
|
|
82
90
|
const getNavigatorLocale = () => {
|
|
@@ -46,7 +46,7 @@ type CommonCalendarProps = {
|
|
|
46
46
|
navigationStartRef?: RefObject<{
|
|
47
47
|
focus(): void;
|
|
48
48
|
}>;
|
|
49
|
-
/** Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'range' и отсутствии buildCellProps (временно PDS-3139) */
|
|
49
|
+
/** Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) */
|
|
50
50
|
presets?: PresetsOptions;
|
|
51
51
|
};
|
|
52
52
|
type DateCalendarProps = CommonCalendarProps & {
|
|
@@ -92,15 +92,35 @@ type DateTimeCalendarProps = CommonCalendarProps & {
|
|
|
92
92
|
showSeconds?: boolean;
|
|
93
93
|
};
|
|
94
94
|
type RangeCalendarProps = CommonCalendarProps & {
|
|
95
|
-
/** <br> - `range` - режим выбора периода */
|
|
96
|
-
mode: typeof CALENDAR_MODE.
|
|
97
|
-
/** <br> - в режиме range тип `Range` (`[Date, Date]`) */
|
|
95
|
+
/** <br> - `date-range` - режим выбора периода */
|
|
96
|
+
mode: typeof CALENDAR_MODE.DateRange;
|
|
97
|
+
/** <br> - в режиме date-range тип `Range` (`[Date, Date]`) */
|
|
98
98
|
value?: Range;
|
|
99
|
-
/** <br> - в режиме range тип `Range` (`[Date, Date]`) */
|
|
99
|
+
/** <br> - в режиме date-range тип `Range` (`[Date, Date]`) */
|
|
100
100
|
defaultValue?: Range;
|
|
101
|
-
/** <br> - в режиме range принимает тип `Range` */
|
|
101
|
+
/** <br> - в режиме date-range принимает тип `Range` */
|
|
102
102
|
onChangeValue?(value: Range): void;
|
|
103
103
|
};
|
|
104
|
-
|
|
104
|
+
type MonthRangeCalendarProps = CommonCalendarProps & {
|
|
105
|
+
/** <br> - `month-range` - режим выбора периода из месяцев */
|
|
106
|
+
mode: typeof CALENDAR_MODE.MonthRange;
|
|
107
|
+
/** <br> - в режиме month-range тип `Range` (`[Date, Date]`) */
|
|
108
|
+
value?: Range;
|
|
109
|
+
/** <br> - в режиме month-range тип `Range` (`[Date, Date]`) */
|
|
110
|
+
defaultValue?: Range;
|
|
111
|
+
/** <br> - в режиме month-range принимает тип `Range` */
|
|
112
|
+
onChangeValue?(value: Range): void;
|
|
113
|
+
};
|
|
114
|
+
type YearRangeCalendarProps = CommonCalendarProps & {
|
|
115
|
+
/** <br> - `year-range` - режим выбора периода из лет */
|
|
116
|
+
mode: typeof CALENDAR_MODE.YearRange;
|
|
117
|
+
/** <br> - в режиме year-range тип `Range` (`[Date, Date]`) */
|
|
118
|
+
value?: Range;
|
|
119
|
+
/** <br> - в режиме year-range тип `Range` (`[Date, Date]`) */
|
|
120
|
+
defaultValue?: Range;
|
|
121
|
+
/** <br> - в режиме year-range принимает тип `Range` */
|
|
122
|
+
onChangeValue?(value: Range): void;
|
|
123
|
+
};
|
|
124
|
+
export type CalendarProps = WithSupportProps<DateCalendarProps | RangeCalendarProps | MonthRangeCalendarProps | YearRangeCalendarProps | MonthCalendarProps | DateTimeCalendarProps | YearCalendarProps>;
|
|
105
125
|
export declare function Calendar(props: CalendarProps): import("react/jsx-runtime").JSX.Element;
|
|
106
126
|
export {};
|
package/dist/esm/constants.d.ts
CHANGED
|
@@ -6,9 +6,11 @@ export declare const VIEW_MODE: {
|
|
|
6
6
|
export declare const CALENDAR_MODE: {
|
|
7
7
|
readonly Date: "date";
|
|
8
8
|
readonly DateTime: "date-time";
|
|
9
|
-
readonly
|
|
9
|
+
readonly DateRange: "date-range";
|
|
10
10
|
readonly Month: "month";
|
|
11
|
+
readonly MonthRange: "month-range";
|
|
11
12
|
readonly Year: "year";
|
|
13
|
+
readonly YearRange: "year-range";
|
|
12
14
|
};
|
|
13
15
|
export declare const IN_RANGE_POSITION: {
|
|
14
16
|
readonly Out: "out";
|
package/dist/esm/constants.js
CHANGED
|
@@ -6,9 +6,11 @@ export const VIEW_MODE = {
|
|
|
6
6
|
export const CALENDAR_MODE = {
|
|
7
7
|
Date: 'date',
|
|
8
8
|
DateTime: 'date-time',
|
|
9
|
-
|
|
9
|
+
DateRange: 'date-range',
|
|
10
10
|
Month: 'month',
|
|
11
|
+
MonthRange: 'month-range',
|
|
11
12
|
Year: 'year',
|
|
13
|
+
YearRange: 'year-range',
|
|
12
14
|
};
|
|
13
15
|
export const IN_RANGE_POSITION = {
|
|
14
16
|
Out: 'out',
|
|
@@ -18,7 +18,7 @@ import { useLocale } from '@snack-uikit/locale';
|
|
|
18
18
|
import { extractSupportProps } from '@snack-uikit/utils';
|
|
19
19
|
import { AUTOFOCUS, CALENDAR_MODE, SIZE, VIEW_MODE } from '../../constants';
|
|
20
20
|
import { useDateAndTime } from '../../hooks';
|
|
21
|
-
import { getEndOfTheDay, getLocale, getTestIdBuilder, sortDates } from '../../utils';
|
|
21
|
+
import { getEndOfTheDay, getEndOfTheMonth, getEndOfTheYear, getLocale, getStartOfTheMonth, getStartOfTheYear, getTestIdBuilder, sortDates, } from '../../utils';
|
|
22
22
|
import { CalendarBody } from '../CalendarBody';
|
|
23
23
|
import { CalendarContext } from '../CalendarContext';
|
|
24
24
|
import { CalendarNavigation } from '../CalendarNavigation';
|
|
@@ -42,8 +42,10 @@ const CALENDAR_SIZE_MAP = {
|
|
|
42
42
|
const CALENDAR_DEFAULT_MODE_MAP = {
|
|
43
43
|
[CALENDAR_MODE.Date]: VIEW_MODE.Month,
|
|
44
44
|
[CALENDAR_MODE.DateTime]: VIEW_MODE.Month,
|
|
45
|
-
[CALENDAR_MODE.
|
|
45
|
+
[CALENDAR_MODE.DateRange]: VIEW_MODE.Month,
|
|
46
|
+
[CALENDAR_MODE.MonthRange]: VIEW_MODE.Year,
|
|
46
47
|
[CALENDAR_MODE.Month]: VIEW_MODE.Year,
|
|
48
|
+
[CALENDAR_MODE.YearRange]: VIEW_MODE.Decade,
|
|
47
49
|
[CALENDAR_MODE.Year]: VIEW_MODE.Decade,
|
|
48
50
|
};
|
|
49
51
|
export function CalendarBase(_a) {
|
|
@@ -64,8 +66,16 @@ export function CalendarBase(_a) {
|
|
|
64
66
|
const secondsKeyboardNavigationRef = useRef({ focusItem: () => { } });
|
|
65
67
|
const setValue = useCallback((dates) => {
|
|
66
68
|
const [first, last] = sortDates(dates);
|
|
69
|
+
if (mode === CALENDAR_MODE.MonthRange) {
|
|
70
|
+
setValueState([getStartOfTheMonth(first), getEndOfTheMonth(last)]);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (mode === CALENDAR_MODE.YearRange) {
|
|
74
|
+
setValueState([getStartOfTheYear(first), getEndOfTheYear(last)]);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
67
77
|
setValueState([first, getEndOfTheDay(last)]);
|
|
68
|
-
}, [setValueState]);
|
|
78
|
+
}, [mode, setValueState]);
|
|
69
79
|
const { preselectedRange, continuePreselect, completePreselect, restartPreselect, startPreselect } = useRange({
|
|
70
80
|
setValue,
|
|
71
81
|
});
|
|
@@ -79,7 +89,7 @@ export function CalendarBase(_a) {
|
|
|
79
89
|
}
|
|
80
90
|
return getDefaultPresets(t, today);
|
|
81
91
|
}, [presets === null || presets === void 0 ? void 0 : presets.items, t, today]);
|
|
82
|
-
const arePeriodPresetsDisplayed = mode ===
|
|
92
|
+
const arePeriodPresetsDisplayed = mode === CALENDAR_MODE.DateRange && (presets === null || presets === void 0 ? void 0 : presets.enabled) && !buildCellProps; // TODO PDS-3139
|
|
83
93
|
const onPresetClick = useCallback((selectedPeriod) => {
|
|
84
94
|
setValue(selectedPeriod);
|
|
85
95
|
}, [setValue]);
|
|
@@ -7,13 +7,17 @@ import { CalendarContext } from '../CalendarContext';
|
|
|
7
7
|
import { Grid } from '../Grid';
|
|
8
8
|
import { buildDecadeGrid } from './utils';
|
|
9
9
|
export function DecadeView() {
|
|
10
|
-
const { referenceDate, setViewMode, setViewShift, preselectedRange, continuePreselect, restartPreselect, mode, setValue, } = useContext(CalendarContext);
|
|
10
|
+
const { referenceDate, setViewMode, setViewShift, preselectedRange, continuePreselect, restartPreselect, mode, setValue, startPreselect, completePreselect, } = useContext(CalendarContext);
|
|
11
11
|
const grid = useGrid({
|
|
12
12
|
buildGrid: buildDecadeGrid,
|
|
13
13
|
isTheSameItem: isTheSameYear,
|
|
14
14
|
isInPeriod: isTheSameDecade,
|
|
15
15
|
getItemLabel: getYearLabel,
|
|
16
16
|
onSelect(date) {
|
|
17
|
+
if (mode === CALENDAR_MODE.YearRange) {
|
|
18
|
+
preselectedRange ? completePreselect(date) : startPreselect(date);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
17
21
|
if (mode === CALENDAR_MODE.Year) {
|
|
18
22
|
setValue([date, date]);
|
|
19
23
|
return;
|
|
@@ -7,7 +7,7 @@ import { CalendarContext } from '../CalendarContext';
|
|
|
7
7
|
import { Grid } from '../Grid';
|
|
8
8
|
import { buildYearGrid } from './utils';
|
|
9
9
|
export function YearView() {
|
|
10
|
-
const { referenceDate, setViewMode, setViewShift, setFocus, preselectedRange, continuePreselect, restartPreselect, locale, setValue, mode, } = useContext(CalendarContext);
|
|
10
|
+
const { referenceDate, setViewMode, setViewShift, setFocus, preselectedRange, continuePreselect, restartPreselect, locale, setValue, mode, startPreselect, completePreselect, } = useContext(CalendarContext);
|
|
11
11
|
const grid = useGrid({
|
|
12
12
|
buildGrid: buildYearGrid,
|
|
13
13
|
isTheSameItem: isTheSameMonth,
|
|
@@ -18,6 +18,10 @@ export function YearView() {
|
|
|
18
18
|
setValue([date, date]);
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
+
if (mode === CALENDAR_MODE.MonthRange) {
|
|
22
|
+
preselectedRange ? completePreselect(date) : startPreselect(date);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
21
25
|
setFocus(AUTOFOCUS);
|
|
22
26
|
setViewShift(getMonthShift(referenceDate, date));
|
|
23
27
|
setViewMode(VIEW_MODE.Month);
|
package/dist/esm/hooks.js
CHANGED
|
@@ -31,7 +31,8 @@ export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameIt
|
|
|
31
31
|
const dateTimeSelectedValue = isDateFilled()
|
|
32
32
|
? new Date((_b = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.year) !== null && _b !== void 0 ? _b : 0, (_c = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.month) !== null && _c !== void 0 ? _c : 0, (_d = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.day) !== null && _d !== void 0 ? _d : 0)
|
|
33
33
|
: undefined;
|
|
34
|
-
const
|
|
34
|
+
const isRangeMode = mode === CALENDAR_MODE.DateRange || mode === CALENDAR_MODE.MonthRange || mode === CALENDAR_MODE.YearRange;
|
|
35
|
+
const inRangePosition = isRangeMode
|
|
35
36
|
? getInRangePosition(date, viewMode, preselectedRange || value)
|
|
36
37
|
: IN_RANGE_POSITION.Out;
|
|
37
38
|
const isSelectedValue = value && !preselectedRange && !dateTimeSelectedValue
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export declare const isTheSameItem: (viewMode: ViewMode, date1: Date, date2: Dat
|
|
|
15
15
|
export declare const sortDates: (dates: Date[]) => Date[];
|
|
16
16
|
export declare const getInRangePosition: (date: Date, viewMode: ViewMode, range?: Range) => InRangePosition;
|
|
17
17
|
export declare const getEndOfTheDay: (date: Date) => Date;
|
|
18
|
+
export declare const getStartOfTheMonth: (date: Date) => Date;
|
|
19
|
+
export declare const getEndOfTheMonth: (date: Date) => Date;
|
|
20
|
+
export declare const getStartOfTheYear: (date: Date) => Date;
|
|
21
|
+
export declare const getEndOfTheYear: (date: Date) => Date;
|
|
18
22
|
export declare const getTestIdBuilder: (testId?: string) => (prefix: string) => string | undefined;
|
|
19
23
|
export declare const getLocale: ({ localeProp, ctxLang }?: {
|
|
20
24
|
localeProp?: Intl.Locale;
|
package/dist/esm/utils.js
CHANGED
|
@@ -54,6 +54,10 @@ export const getInRangePosition = (date, viewMode, range) => {
|
|
|
54
54
|
return date.valueOf() >= start && date.valueOf() <= end ? IN_RANGE_POSITION.In : IN_RANGE_POSITION.Out;
|
|
55
55
|
};
|
|
56
56
|
export const getEndOfTheDay = (date) => new Date(new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).valueOf() - 1);
|
|
57
|
+
export const getStartOfTheMonth = (date) => new Date(new Date(date.getFullYear(), date.getMonth(), 1).valueOf());
|
|
58
|
+
export const getEndOfTheMonth = (date) => new Date(new Date(date.getFullYear(), date.getMonth() + 1, 1).valueOf() - 1);
|
|
59
|
+
export const getStartOfTheYear = (date) => new Date(new Date(date.getFullYear(), 0, 1).valueOf());
|
|
60
|
+
export const getEndOfTheYear = (date) => new Date(new Date(date.getFullYear() + 1, 0, 1).valueOf() - 1);
|
|
57
61
|
export const getTestIdBuilder = (testId) => (prefix) => (testId ? `${prefix}-${testId}` : undefined);
|
|
58
62
|
const getNavigatorLocale = () => { var _a; return (isBrowser() ? ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.language) !== null && _a !== void 0 ? _a : 'ru-RU') : 'ru-RU'); };
|
|
59
63
|
export const getLocale = ({ localeProp, ctxLang } = {}) => localeProp || new Intl.Locale(ctxLang ? ctxLang.replace('_', '-') : getNavigatorLocale());
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Calendar",
|
|
7
|
-
"version": "0.13.
|
|
7
|
+
"version": "0.13.14",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@snack-uikit/button": "0.19.17",
|
|
40
40
|
"@snack-uikit/divider": "3.2.11",
|
|
41
|
-
"@snack-uikit/icons": "0.27.
|
|
42
|
-
"@snack-uikit/list": "0.32.
|
|
41
|
+
"@snack-uikit/icons": "0.27.6",
|
|
42
|
+
"@snack-uikit/list": "0.32.13",
|
|
43
43
|
"@snack-uikit/utils": "4.0.1",
|
|
44
44
|
"classnames": "2.5.1",
|
|
45
45
|
"uncontrollable": "8.0.4",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@snack-uikit/locale": "*"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "17b72086167d3d6503e4e74142358765230478c8"
|
|
52
52
|
}
|
|
@@ -49,7 +49,7 @@ type CommonCalendarProps = {
|
|
|
49
49
|
onFocusLeave?(direction: FocusDirection): void;
|
|
50
50
|
/** Ссылка на управление первым элементом навигации */
|
|
51
51
|
navigationStartRef?: RefObject<{ focus(): void }>;
|
|
52
|
-
/** Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'range' и отсутствии buildCellProps (временно PDS-3139) */
|
|
52
|
+
/** Настройки секции с пресетами быстрого выбора периода. Доступны только при mode === 'date-range' и отсутствии buildCellProps (временно PDS-3139) */
|
|
53
53
|
presets?: PresetsOptions;
|
|
54
54
|
};
|
|
55
55
|
|
|
@@ -100,18 +100,46 @@ type DateTimeCalendarProps = CommonCalendarProps & {
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
type RangeCalendarProps = CommonCalendarProps & {
|
|
103
|
-
/** <br> - `range` - режим выбора периода */
|
|
104
|
-
mode: typeof CALENDAR_MODE.
|
|
105
|
-
/** <br> - в режиме range тип `Range` (`[Date, Date]`) */
|
|
103
|
+
/** <br> - `date-range` - режим выбора периода */
|
|
104
|
+
mode: typeof CALENDAR_MODE.DateRange;
|
|
105
|
+
/** <br> - в режиме date-range тип `Range` (`[Date, Date]`) */
|
|
106
106
|
value?: Range;
|
|
107
|
-
/** <br> - в режиме range тип `Range` (`[Date, Date]`) */
|
|
107
|
+
/** <br> - в режиме date-range тип `Range` (`[Date, Date]`) */
|
|
108
108
|
defaultValue?: Range;
|
|
109
|
-
/** <br> - в режиме range принимает тип `Range` */
|
|
109
|
+
/** <br> - в режиме date-range принимает тип `Range` */
|
|
110
|
+
onChangeValue?(value: Range): void;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
type MonthRangeCalendarProps = CommonCalendarProps & {
|
|
114
|
+
/** <br> - `month-range` - режим выбора периода из месяцев */
|
|
115
|
+
mode: typeof CALENDAR_MODE.MonthRange;
|
|
116
|
+
/** <br> - в режиме month-range тип `Range` (`[Date, Date]`) */
|
|
117
|
+
value?: Range;
|
|
118
|
+
/** <br> - в режиме month-range тип `Range` (`[Date, Date]`) */
|
|
119
|
+
defaultValue?: Range;
|
|
120
|
+
/** <br> - в режиме month-range принимает тип `Range` */
|
|
121
|
+
onChangeValue?(value: Range): void;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
type YearRangeCalendarProps = CommonCalendarProps & {
|
|
125
|
+
/** <br> - `year-range` - режим выбора периода из лет */
|
|
126
|
+
mode: typeof CALENDAR_MODE.YearRange;
|
|
127
|
+
/** <br> - в режиме year-range тип `Range` (`[Date, Date]`) */
|
|
128
|
+
value?: Range;
|
|
129
|
+
/** <br> - в режиме year-range тип `Range` (`[Date, Date]`) */
|
|
130
|
+
defaultValue?: Range;
|
|
131
|
+
/** <br> - в режиме year-range принимает тип `Range` */
|
|
110
132
|
onChangeValue?(value: Range): void;
|
|
111
133
|
};
|
|
112
134
|
|
|
113
135
|
export type CalendarProps = WithSupportProps<
|
|
114
|
-
|
|
136
|
+
| DateCalendarProps
|
|
137
|
+
| RangeCalendarProps
|
|
138
|
+
| MonthRangeCalendarProps
|
|
139
|
+
| YearRangeCalendarProps
|
|
140
|
+
| MonthCalendarProps
|
|
141
|
+
| DateTimeCalendarProps
|
|
142
|
+
| YearCalendarProps
|
|
115
143
|
>;
|
|
116
144
|
|
|
117
145
|
export function Calendar(props: CalendarProps) {
|
package/src/constants.ts
CHANGED
|
@@ -7,9 +7,11 @@ export const VIEW_MODE = {
|
|
|
7
7
|
export const CALENDAR_MODE = {
|
|
8
8
|
Date: 'date',
|
|
9
9
|
DateTime: 'date-time',
|
|
10
|
-
|
|
10
|
+
DateRange: 'date-range',
|
|
11
11
|
Month: 'month',
|
|
12
|
+
MonthRange: 'month-range',
|
|
12
13
|
Year: 'year',
|
|
14
|
+
YearRange: 'year-range',
|
|
13
15
|
} as const;
|
|
14
16
|
|
|
15
17
|
export const IN_RANGE_POSITION = {
|
|
@@ -18,7 +18,16 @@ import {
|
|
|
18
18
|
Size,
|
|
19
19
|
ViewMode,
|
|
20
20
|
} from '../../types';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
getEndOfTheDay,
|
|
23
|
+
getEndOfTheMonth,
|
|
24
|
+
getEndOfTheYear,
|
|
25
|
+
getLocale,
|
|
26
|
+
getStartOfTheMonth,
|
|
27
|
+
getStartOfTheYear,
|
|
28
|
+
getTestIdBuilder,
|
|
29
|
+
sortDates,
|
|
30
|
+
} from '../../utils';
|
|
22
31
|
import { CalendarBody } from '../CalendarBody';
|
|
23
32
|
import { CalendarContext } from '../CalendarContext';
|
|
24
33
|
import { CalendarNavigation } from '../CalendarNavigation';
|
|
@@ -65,8 +74,10 @@ const CALENDAR_SIZE_MAP: Record<Size, string> = {
|
|
|
65
74
|
const CALENDAR_DEFAULT_MODE_MAP: Record<CalendarMode, ViewMode> = {
|
|
66
75
|
[CALENDAR_MODE.Date]: VIEW_MODE.Month,
|
|
67
76
|
[CALENDAR_MODE.DateTime]: VIEW_MODE.Month,
|
|
68
|
-
[CALENDAR_MODE.
|
|
77
|
+
[CALENDAR_MODE.DateRange]: VIEW_MODE.Month,
|
|
78
|
+
[CALENDAR_MODE.MonthRange]: VIEW_MODE.Year,
|
|
69
79
|
[CALENDAR_MODE.Month]: VIEW_MODE.Year,
|
|
80
|
+
[CALENDAR_MODE.YearRange]: VIEW_MODE.Decade,
|
|
70
81
|
[CALENDAR_MODE.Year]: VIEW_MODE.Decade,
|
|
71
82
|
};
|
|
72
83
|
|
|
@@ -113,16 +124,27 @@ export function CalendarBase({
|
|
|
113
124
|
|
|
114
125
|
const applyButtonRef = useRef<HTMLButtonElement>(null);
|
|
115
126
|
const currentButtonRef = useRef<HTMLButtonElement>(null);
|
|
116
|
-
const hoursKeyboardNavigationRef: ListProps['keyboardNavigationRef'] = useRef({ focusItem: () => {} });
|
|
117
|
-
const minutesKeyboardNavigationRef: ListProps['keyboardNavigationRef'] = useRef({ focusItem: () => {} });
|
|
118
|
-
const secondsKeyboardNavigationRef: ListProps['keyboardNavigationRef'] = useRef({ focusItem: () => {} });
|
|
127
|
+
const hoursKeyboardNavigationRef: ListProps['keyboardNavigationRef'] = useRef({ focusItem: () => { } });
|
|
128
|
+
const minutesKeyboardNavigationRef: ListProps['keyboardNavigationRef'] = useRef({ focusItem: () => { } });
|
|
129
|
+
const secondsKeyboardNavigationRef: ListProps['keyboardNavigationRef'] = useRef({ focusItem: () => { } });
|
|
119
130
|
|
|
120
131
|
const setValue = useCallback(
|
|
121
132
|
(dates: Range) => {
|
|
122
133
|
const [first, last] = sortDates(dates);
|
|
134
|
+
|
|
135
|
+
if (mode === CALENDAR_MODE.MonthRange) {
|
|
136
|
+
setValueState([getStartOfTheMonth(first), getEndOfTheMonth(last)]);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (mode === CALENDAR_MODE.YearRange) {
|
|
141
|
+
setValueState([getStartOfTheYear(first), getEndOfTheYear(last)]);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
123
145
|
setValueState([first, getEndOfTheDay(last)]);
|
|
124
146
|
},
|
|
125
|
-
[setValueState],
|
|
147
|
+
[mode, setValueState],
|
|
126
148
|
);
|
|
127
149
|
|
|
128
150
|
const { preselectedRange, continuePreselect, completePreselect, restartPreselect, startPreselect } = useRange({
|
|
@@ -145,7 +167,7 @@ export function CalendarBase({
|
|
|
145
167
|
return getDefaultPresets(t, today);
|
|
146
168
|
}, [presets?.items, t, today]);
|
|
147
169
|
|
|
148
|
-
const arePeriodPresetsDisplayed = mode ===
|
|
170
|
+
const arePeriodPresetsDisplayed = mode === CALENDAR_MODE.DateRange && presets?.enabled && !buildCellProps; // TODO PDS-3139
|
|
149
171
|
|
|
150
172
|
const onPresetClick = useCallback(
|
|
151
173
|
(selectedPeriod: Range) => {
|
|
@@ -17,6 +17,8 @@ export function DecadeView() {
|
|
|
17
17
|
restartPreselect,
|
|
18
18
|
mode,
|
|
19
19
|
setValue,
|
|
20
|
+
startPreselect,
|
|
21
|
+
completePreselect,
|
|
20
22
|
} = useContext(CalendarContext);
|
|
21
23
|
|
|
22
24
|
const grid = useGrid({
|
|
@@ -26,6 +28,11 @@ export function DecadeView() {
|
|
|
26
28
|
getItemLabel: getYearLabel,
|
|
27
29
|
|
|
28
30
|
onSelect(date: Date) {
|
|
31
|
+
if (mode === CALENDAR_MODE.YearRange) {
|
|
32
|
+
preselectedRange ? completePreselect(date) : startPreselect(date);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
29
36
|
if (mode === CALENDAR_MODE.Year) {
|
|
30
37
|
setValue([date, date]);
|
|
31
38
|
return;
|
|
@@ -19,6 +19,8 @@ export function YearView() {
|
|
|
19
19
|
locale,
|
|
20
20
|
setValue,
|
|
21
21
|
mode,
|
|
22
|
+
startPreselect,
|
|
23
|
+
completePreselect,
|
|
22
24
|
} = useContext(CalendarContext);
|
|
23
25
|
|
|
24
26
|
const grid = useGrid({
|
|
@@ -33,6 +35,11 @@ export function YearView() {
|
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
if (mode === CALENDAR_MODE.MonthRange) {
|
|
39
|
+
preselectedRange ? completePreselect(date) : startPreselect(date);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
setFocus(AUTOFOCUS);
|
|
37
44
|
setViewShift(getMonthShift(referenceDate, date));
|
|
38
45
|
setViewMode(VIEW_MODE.Month);
|
package/src/hooks.ts
CHANGED
|
@@ -72,10 +72,11 @@ export function useGrid({
|
|
|
72
72
|
? new Date(dateAndTime?.year ?? 0, dateAndTime?.month ?? 0, dateAndTime?.day ?? 0)
|
|
73
73
|
: undefined;
|
|
74
74
|
|
|
75
|
-
const
|
|
76
|
-
mode === CALENDAR_MODE.
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
const isRangeMode =
|
|
76
|
+
mode === CALENDAR_MODE.DateRange || mode === CALENDAR_MODE.MonthRange || mode === CALENDAR_MODE.YearRange;
|
|
77
|
+
const inRangePosition = isRangeMode
|
|
78
|
+
? getInRangePosition(date, viewMode, preselectedRange || value)
|
|
79
|
+
: IN_RANGE_POSITION.Out;
|
|
79
80
|
|
|
80
81
|
const isSelectedValue =
|
|
81
82
|
value && !preselectedRange && !dateTimeSelectedValue
|
package/src/utils.ts
CHANGED
|
@@ -85,6 +85,15 @@ export const getInRangePosition = (date: Date, viewMode: ViewMode, range?: Range
|
|
|
85
85
|
export const getEndOfTheDay = (date: Date) =>
|
|
86
86
|
new Date(new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).valueOf() - 1);
|
|
87
87
|
|
|
88
|
+
export const getStartOfTheMonth = (date: Date) => new Date(new Date(date.getFullYear(), date.getMonth(), 1).valueOf());
|
|
89
|
+
|
|
90
|
+
export const getEndOfTheMonth = (date: Date) =>
|
|
91
|
+
new Date(new Date(date.getFullYear(), date.getMonth() + 1, 1).valueOf() - 1);
|
|
92
|
+
|
|
93
|
+
export const getStartOfTheYear = (date: Date) => new Date(new Date(date.getFullYear(), 0, 1).valueOf());
|
|
94
|
+
|
|
95
|
+
export const getEndOfTheYear = (date: Date) => new Date(new Date(date.getFullYear() + 1, 0, 1).valueOf() - 1);
|
|
96
|
+
|
|
88
97
|
export const getTestIdBuilder = (testId?: string) => (prefix: string) => (testId ? `${prefix}-${testId}` : undefined);
|
|
89
98
|
|
|
90
99
|
const getNavigatorLocale = () => (isBrowser() ? (navigator?.language ?? 'ru-RU') : 'ru-RU');
|