@snack-uikit/calendar 0.9.0 → 0.11.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.
- package/CHANGELOG.md +27 -0
- package/README.md +20 -5
- package/dist/cjs/components/Calendar/Calendar.d.ts +22 -8
- package/dist/cjs/components/Calendar/Calendar.js +3 -3
- package/dist/cjs/components/Calendar/utils.d.ts +1 -2
- package/dist/cjs/components/Calendar/utils.js +15 -20
- package/dist/cjs/components/TimePicker/TimePicker.d.ts +34 -0
- package/dist/cjs/components/TimePicker/TimePicker.js +149 -0
- package/dist/cjs/components/TimePicker/index.d.ts +1 -0
- package/dist/cjs/components/TimePicker/index.js +25 -0
- package/dist/cjs/components/TimePicker/styles.module.css +12 -0
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/index.js +2 -1
- package/dist/cjs/constants.d.ts +5 -0
- package/dist/cjs/constants.js +7 -2
- package/dist/cjs/helperComponents/Button/Button.js +7 -6
- package/dist/cjs/helperComponents/Button/styles.module.css +13 -13
- package/dist/cjs/helperComponents/CalendarBase/CalendarBase.d.ts +6 -3
- package/dist/cjs/helperComponents/CalendarBase/CalendarBase.js +86 -38
- package/dist/cjs/helperComponents/CalendarBase/hooks.d.ts +10 -1
- package/dist/cjs/helperComponents/CalendarBase/hooks.js +30 -0
- package/dist/cjs/helperComponents/CalendarBase/styles.module.css +36 -12
- package/dist/cjs/helperComponents/CalendarContext/CalendarContext.d.ts +23 -6
- package/dist/cjs/helperComponents/CalendarContext/CalendarContext.js +18 -2
- package/dist/cjs/helperComponents/ColumnLabels/styles.module.css +3 -3
- package/dist/cjs/helperComponents/Footer/Footer.d.ts +1 -0
- package/dist/cjs/helperComponents/Footer/Footer.js +126 -0
- package/dist/cjs/helperComponents/Footer/index.d.ts +1 -0
- package/dist/cjs/helperComponents/Footer/index.js +25 -0
- package/dist/cjs/helperComponents/Footer/styles.module.css +49 -0
- package/dist/cjs/helperComponents/Item/Item.js +3 -2
- package/dist/cjs/helperComponents/Item/hooks.d.ts +2 -2
- package/dist/cjs/helperComponents/Item/hooks.js +6 -4
- package/dist/cjs/helperComponents/MonthView/MonthView.js +38 -3
- package/dist/cjs/helperComponents/TimeList/TimeList.d.ts +15 -0
- package/dist/cjs/helperComponents/TimeList/TimeList.js +65 -0
- package/dist/cjs/helperComponents/TimeList/index.d.ts +1 -0
- package/dist/cjs/helperComponents/TimeList/index.js +25 -0
- package/dist/cjs/helperComponents/TimePickerBase/TimePickerBase.d.ts +3 -0
- package/dist/cjs/helperComponents/TimePickerBase/TimePickerBase.js +190 -0
- package/dist/cjs/helperComponents/TimePickerBase/index.d.ts +1 -0
- package/dist/cjs/helperComponents/TimePickerBase/index.js +25 -0
- package/dist/cjs/helperComponents/TimePickerBase/styles.module.css +103 -0
- package/dist/cjs/hooks.d.ts +17 -2
- package/dist/cjs/hooks.js +119 -9
- package/dist/cjs/types.d.ts +12 -0
- package/dist/cjs/utils.d.ts +1 -1
- package/dist/cjs/utils.js +6 -4
- package/dist/esm/components/Calendar/Calendar.d.ts +22 -8
- package/dist/esm/components/Calendar/Calendar.js +3 -3
- package/dist/esm/components/Calendar/utils.d.ts +1 -2
- package/dist/esm/components/Calendar/utils.js +11 -11
- package/dist/esm/components/TimePicker/TimePicker.d.ts +34 -0
- package/dist/esm/components/TimePicker/TimePicker.js +86 -0
- package/dist/esm/components/TimePicker/index.d.ts +1 -0
- package/dist/esm/components/TimePicker/index.js +1 -0
- package/dist/esm/components/TimePicker/styles.module.css +12 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/constants.d.ts +5 -0
- package/dist/esm/constants.js +5 -0
- package/dist/esm/helperComponents/Button/Button.js +8 -7
- package/dist/esm/helperComponents/Button/styles.module.css +13 -13
- package/dist/esm/helperComponents/CalendarBase/CalendarBase.d.ts +6 -3
- package/dist/esm/helperComponents/CalendarBase/CalendarBase.js +37 -22
- package/dist/esm/helperComponents/CalendarBase/hooks.d.ts +10 -1
- package/dist/esm/helperComponents/CalendarBase/hooks.js +20 -0
- package/dist/esm/helperComponents/CalendarBase/styles.module.css +36 -12
- package/dist/esm/helperComponents/CalendarContext/CalendarContext.d.ts +23 -6
- package/dist/esm/helperComponents/CalendarContext/CalendarContext.js +15 -1
- package/dist/esm/helperComponents/ColumnLabels/styles.module.css +3 -3
- package/dist/esm/helperComponents/Footer/Footer.d.ts +1 -0
- package/dist/esm/helperComponents/Footer/Footer.js +63 -0
- package/dist/esm/helperComponents/Footer/index.d.ts +1 -0
- package/dist/esm/helperComponents/Footer/index.js +1 -0
- package/dist/esm/helperComponents/Footer/styles.module.css +49 -0
- package/dist/esm/helperComponents/Item/Item.js +2 -2
- package/dist/esm/helperComponents/Item/hooks.d.ts +2 -2
- package/dist/esm/helperComponents/Item/hooks.js +6 -5
- package/dist/esm/helperComponents/MonthView/MonthView.js +31 -3
- package/dist/esm/helperComponents/TimeList/TimeList.d.ts +15 -0
- package/dist/esm/helperComponents/TimeList/TimeList.js +37 -0
- package/dist/esm/helperComponents/TimeList/index.d.ts +1 -0
- package/dist/esm/helperComponents/TimeList/index.js +1 -0
- package/dist/esm/helperComponents/TimePickerBase/TimePickerBase.d.ts +3 -0
- package/dist/esm/helperComponents/TimePickerBase/TimePickerBase.js +113 -0
- package/dist/esm/helperComponents/TimePickerBase/index.d.ts +1 -0
- package/dist/esm/helperComponents/TimePickerBase/index.js +1 -0
- package/dist/esm/helperComponents/TimePickerBase/styles.module.css +103 -0
- package/dist/esm/hooks.d.ts +17 -2
- package/dist/esm/hooks.js +109 -8
- package/dist/esm/types.d.ts +12 -0
- package/dist/esm/utils.d.ts +1 -1
- package/dist/esm/utils.js +4 -2
- package/package.json +6 -3
- package/src/components/Calendar/Calendar.tsx +27 -12
- package/src/components/Calendar/utils.ts +17 -10
- package/src/components/TimePicker/TimePicker.tsx +166 -0
- package/src/components/TimePicker/index.ts +1 -0
- package/src/components/TimePicker/styles.module.scss +13 -0
- package/src/components/index.ts +1 -0
- package/src/constants.ts +7 -0
- package/src/helperComponents/Button/Button.tsx +8 -7
- package/src/helperComponents/Button/styles.module.scss +12 -12
- package/src/helperComponents/CalendarBase/CalendarBase.tsx +78 -43
- package/src/helperComponents/CalendarBase/hooks.ts +31 -1
- package/src/helperComponents/CalendarBase/styles.module.scss +37 -14
- package/src/helperComponents/CalendarContext/CalendarContext.tsx +47 -7
- package/src/helperComponents/ColumnLabel/styles.module.scss +6 -6
- package/src/helperComponents/ColumnLabels/styles.module.scss +2 -2
- package/src/helperComponents/Footer/Footer.tsx +129 -0
- package/src/helperComponents/Footer/index.ts +1 -0
- package/src/helperComponents/Footer/styles.module.scss +31 -0
- package/src/helperComponents/Item/Item.tsx +2 -1
- package/src/helperComponents/Item/hooks.ts +8 -6
- package/src/helperComponents/Item/styles.module.scss +29 -29
- package/src/helperComponents/MonthView/MonthView.tsx +43 -2
- package/src/helperComponents/TimeList/TimeList.tsx +69 -0
- package/src/helperComponents/TimeList/index.ts +1 -0
- package/src/helperComponents/TimePickerBase/TimePickerBase.tsx +202 -0
- package/src/helperComponents/TimePickerBase/index.ts +1 -0
- package/src/helperComponents/TimePickerBase/styles.module.scss +76 -0
- package/src/hooks.ts +139 -6
- package/src/types.ts +15 -0
- package/src/utils.ts +4 -3
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useContext, useMemo } from 'react';
|
|
3
|
+
import { Divider } from '@snack-uikit/divider';
|
|
4
|
+
import { getDefaultItemId } from '@snack-uikit/list';
|
|
5
|
+
import { useLocale } from '@snack-uikit/locale';
|
|
6
|
+
import { AUTOFOCUS, HOURS, MINUTES, SECONDS } from '../../constants';
|
|
7
|
+
import { CalendarContext } from '../CalendarContext';
|
|
8
|
+
import { TimeList } from '../TimeList';
|
|
9
|
+
import styles from './styles.module.css';
|
|
10
|
+
export function TimePickerBase({ showDivider = true }) {
|
|
11
|
+
const { t } = useLocale('Calendar');
|
|
12
|
+
const { size, mode, fitToContainer, showSeconds, dateAndTime, onTimeChange, applyButtonRef, currentButtonRef, hoursKeyboardNavigationRef, minutesKeyboardNavigationRef, secondsKeyboardNavigationRef, setFocus, getTestId, navigationStartRef, onFocusLeave, } = useContext(CalendarContext);
|
|
13
|
+
const hours = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.hours;
|
|
14
|
+
const minutes = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.minutes;
|
|
15
|
+
const seconds = dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.seconds;
|
|
16
|
+
const getTimeChangeHandler = useCallback((propName) => (value) => {
|
|
17
|
+
var _a;
|
|
18
|
+
const timeValues = Object.assign({ hours: 0, minutes: 0, seconds: 0 }, dateAndTime);
|
|
19
|
+
onTimeChange(Object.assign(Object.assign({}, timeValues), { [propName]: (_a = value !== null && value !== void 0 ? value : dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime[propName]) !== null && _a !== void 0 ? _a : 0 }));
|
|
20
|
+
}, [dateAndTime, onTimeChange]);
|
|
21
|
+
const onHoursChange = useMemo(() => getTimeChangeHandler('hours'), [getTimeChangeHandler]);
|
|
22
|
+
const onMinutesChange = useMemo(() => getTimeChangeHandler('minutes'), [getTimeChangeHandler]);
|
|
23
|
+
const onSecondsChange = useMemo(() => getTimeChangeHandler('seconds'), [getTimeChangeHandler]);
|
|
24
|
+
const onHourKeyDownGetter = useCallback(id => event => {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
switch (event.key) {
|
|
27
|
+
case 'Tab':
|
|
28
|
+
if (mode === 'time' && event.shiftKey) {
|
|
29
|
+
onFocusLeave === null || onFocusLeave === void 0 ? void 0 : onFocusLeave('prev');
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
event.stopPropagation();
|
|
33
|
+
event.preventDefault();
|
|
34
|
+
if (event.shiftKey) {
|
|
35
|
+
setFocus(AUTOFOCUS);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
(_a = minutesKeyboardNavigationRef.current) === null || _a === void 0 ? void 0 : _a.focusItem(getDefaultItemId(minutes !== null && minutes !== void 0 ? minutes : 0));
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
case 'Enter':
|
|
42
|
+
(_b = minutesKeyboardNavigationRef.current) === null || _b === void 0 ? void 0 : _b.focusItem(getDefaultItemId(minutes !== null && minutes !== void 0 ? minutes : 0));
|
|
43
|
+
break;
|
|
44
|
+
case 'ArrowUp':
|
|
45
|
+
if (mode === 'time' && id === 0) {
|
|
46
|
+
onFocusLeave === null || onFocusLeave === void 0 ? void 0 : onFocusLeave('prev');
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
default:
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}, [minutes, minutesKeyboardNavigationRef, mode, onFocusLeave, setFocus]);
|
|
54
|
+
const onMinuteKeyDownGetter = useCallback(() => event => {
|
|
55
|
+
var _a, _b, _c, _d, _e;
|
|
56
|
+
switch (event.key) {
|
|
57
|
+
case 'Tab':
|
|
58
|
+
event.stopPropagation();
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
if (event.shiftKey) {
|
|
61
|
+
(_a = hoursKeyboardNavigationRef.current) === null || _a === void 0 ? void 0 : _a.focusItem(getDefaultItemId(hours !== null && hours !== void 0 ? hours : 0));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (showSeconds) {
|
|
65
|
+
(_b = secondsKeyboardNavigationRef.current) === null || _b === void 0 ? void 0 : _b.focusItem(getDefaultItemId(seconds !== null && seconds !== void 0 ? seconds : 0));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
(_c = currentButtonRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
case 'Enter':
|
|
73
|
+
if (showSeconds) {
|
|
74
|
+
(_d = secondsKeyboardNavigationRef.current) === null || _d === void 0 ? void 0 : _d.focusItem(getDefaultItemId(seconds !== null && seconds !== void 0 ? seconds : 0));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
(_e = applyButtonRef.current) === null || _e === void 0 ? void 0 : _e.focus();
|
|
78
|
+
}
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}, [
|
|
84
|
+
applyButtonRef,
|
|
85
|
+
currentButtonRef,
|
|
86
|
+
hours,
|
|
87
|
+
hoursKeyboardNavigationRef,
|
|
88
|
+
seconds,
|
|
89
|
+
secondsKeyboardNavigationRef,
|
|
90
|
+
showSeconds,
|
|
91
|
+
]);
|
|
92
|
+
const onSecondKeyDownGetter = useCallback(() => event => {
|
|
93
|
+
var _a, _b, _c;
|
|
94
|
+
switch (event.key) {
|
|
95
|
+
case 'Tab':
|
|
96
|
+
event.stopPropagation();
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
if (event.shiftKey) {
|
|
99
|
+
(_a = minutesKeyboardNavigationRef.current) === null || _a === void 0 ? void 0 : _a.focusItem(getDefaultItemId(minutes !== null && minutes !== void 0 ? minutes : 0));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
(_b = currentButtonRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
case 'Enter':
|
|
106
|
+
(_c = applyButtonRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}, [applyButtonRef, currentButtonRef, minutes, minutesKeyboardNavigationRef]);
|
|
112
|
+
return (_jsxs(_Fragment, { children: [showDivider && _jsx(Divider, { orientation: 'vertical', className: styles.divider }), _jsxs("div", { className: styles.timePicker, "data-size": size, "data-fit-to-container": fitToContainer || undefined, children: [_jsx("div", { className: styles.header, "data-size": size, children: _jsx("span", { className: styles.title, children: t('time') }) }), _jsxs("div", { className: styles.timeListsWrapper, "data-size": size, "data-show-seconds": showSeconds || undefined, children: [_jsx(TimeList, { value: hours, onChange: onHoursChange, "data-test-id": getTestId('hours'), numberOfItems: HOURS, onKeyDownGetter: onHourKeyDownGetter, keyboardNavigationRef: hoursKeyboardNavigationRef, navigationStartRef: mode === 'time' ? navigationStartRef : undefined }), _jsx(Divider, { className: styles.divider, orientation: 'vertical' }), _jsx(TimeList, { value: minutes, onChange: onMinutesChange, "data-test-id": getTestId('minutes'), numberOfItems: MINUTES, onKeyDownGetter: onMinuteKeyDownGetter, keyboardNavigationRef: minutesKeyboardNavigationRef }), showSeconds && (_jsxs(_Fragment, { children: [_jsx(Divider, { className: styles.divider, orientation: 'vertical' }), _jsx(TimeList, { value: seconds, onChange: onSecondsChange, "data-test-id": getTestId('seconds'), numberOfItems: SECONDS, onKeyDownGetter: onSecondKeyDownGetter, keyboardNavigationRef: secondsKeyboardNavigationRef })] }))] })] })] }));
|
|
113
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimePickerBase';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TimePickerBase';
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
.divider{
|
|
2
|
+
flex-shrink:0;
|
|
3
|
+
height:auto;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.timePicker{
|
|
7
|
+
overflow:hidden;
|
|
8
|
+
display:flex;
|
|
9
|
+
flex-direction:column;
|
|
10
|
+
box-sizing:border-box;
|
|
11
|
+
max-width:100%;
|
|
12
|
+
}
|
|
13
|
+
.timePicker[data-size=s]{
|
|
14
|
+
min-width:var(--size-calendar-time-min-width-s, 120px);
|
|
15
|
+
max-height:var(--size-calendar-container-min-height-s, 256px);
|
|
16
|
+
}
|
|
17
|
+
.timePicker[data-size=s][data-fit-to-container]{
|
|
18
|
+
max-height:100%;
|
|
19
|
+
}
|
|
20
|
+
.timePicker[data-size=m]{
|
|
21
|
+
min-width:var(--size-calendar-time-min-width-m, 144px);
|
|
22
|
+
max-height:var(--size-calendar-container-min-height-m, 320px);
|
|
23
|
+
}
|
|
24
|
+
.timePicker[data-size=m][data-fit-to-container]{
|
|
25
|
+
max-height:100%;
|
|
26
|
+
}
|
|
27
|
+
.timePicker[data-size=l]{
|
|
28
|
+
min-width:var(--size-calendar-time-min-width-l, 168px);
|
|
29
|
+
max-height:var(--size-calendar-container-min-height-l, 384px);
|
|
30
|
+
}
|
|
31
|
+
.timePicker[data-size=l][data-fit-to-container]{
|
|
32
|
+
max-height:100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.timeListsWrapper{
|
|
36
|
+
display:grid;
|
|
37
|
+
grid-template-columns:1fr 1px 1fr;
|
|
38
|
+
min-height:0;
|
|
39
|
+
}
|
|
40
|
+
.timeListsWrapper[data-show-seconds]{
|
|
41
|
+
grid-template-columns:1fr 1px 1fr 1px 1fr;
|
|
42
|
+
}
|
|
43
|
+
.timeListsWrapper[data-size=s]{
|
|
44
|
+
max-height:calc(100% - var(--size-calendar-container-header-lines-height-s, 32px));
|
|
45
|
+
}
|
|
46
|
+
.timeListsWrapper[data-size=m]{
|
|
47
|
+
max-height:calc(100% - var(--size-calendar-container-header-lines-height-m, 40px));
|
|
48
|
+
}
|
|
49
|
+
.timeListsWrapper[data-size=l]{
|
|
50
|
+
max-height:calc(100% - var(--size-calendar-container-header-lines-height-l, 48px));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.title{
|
|
54
|
+
display:flex;
|
|
55
|
+
align-items:center;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.header{
|
|
59
|
+
display:flex;
|
|
60
|
+
flex-grow:0;
|
|
61
|
+
flex-shrink:0;
|
|
62
|
+
align-items:center;
|
|
63
|
+
color:var(--sys-neutral-text-main, #41424e);
|
|
64
|
+
}
|
|
65
|
+
.header[data-size=s]{
|
|
66
|
+
padding-left:var(--space-calendar-container-s, 8px);
|
|
67
|
+
padding-right:var(--space-calendar-container-s, 8px);
|
|
68
|
+
font-family:var(--sans-label-m-font-family, SB Sans Interface);
|
|
69
|
+
font-weight:var(--sans-label-m-font-weight, Semibold);
|
|
70
|
+
line-height:var(--sans-label-m-line-height, 16px);
|
|
71
|
+
font-size:var(--sans-label-m-font-size, 12px);
|
|
72
|
+
letter-spacing:var(--sans-label-m-letter-spacing, 0px);
|
|
73
|
+
paragraph-spacing:var(--sans-label-m-paragraph-spacing, 6.6px);
|
|
74
|
+
}
|
|
75
|
+
.header[data-size=s] .title{
|
|
76
|
+
height:var(--size-calendar-container-header-lines-height-s, 32px);
|
|
77
|
+
}
|
|
78
|
+
.header[data-size=m]{
|
|
79
|
+
padding-left:var(--space-calendar-container-m, 8px);
|
|
80
|
+
padding-right:var(--space-calendar-container-m, 8px);
|
|
81
|
+
font-family:var(--sans-label-l-font-family, SB Sans Interface);
|
|
82
|
+
font-weight:var(--sans-label-l-font-weight, Semibold);
|
|
83
|
+
line-height:var(--sans-label-l-line-height, 20px);
|
|
84
|
+
font-size:var(--sans-label-l-font-size, 14px);
|
|
85
|
+
letter-spacing:var(--sans-label-l-letter-spacing, 0px);
|
|
86
|
+
paragraph-spacing:var(--sans-label-l-paragraph-spacing, 7.7px);
|
|
87
|
+
}
|
|
88
|
+
.header[data-size=m] .title{
|
|
89
|
+
height:var(--size-calendar-container-header-lines-height-m, 40px);
|
|
90
|
+
}
|
|
91
|
+
.header[data-size=l]{
|
|
92
|
+
padding-left:var(--space-calendar-container-l, 8px);
|
|
93
|
+
padding-right:var(--space-calendar-container-l, 8px);
|
|
94
|
+
font-family:var(--sans-label-l-font-family, SB Sans Interface);
|
|
95
|
+
font-weight:var(--sans-label-l-font-weight, Semibold);
|
|
96
|
+
line-height:var(--sans-label-l-line-height, 20px);
|
|
97
|
+
font-size:var(--sans-label-l-font-size, 14px);
|
|
98
|
+
letter-spacing:var(--sans-label-l-letter-spacing, 0px);
|
|
99
|
+
paragraph-spacing:var(--sans-label-l-paragraph-spacing, 7.7px);
|
|
100
|
+
}
|
|
101
|
+
.header[data-size=l] .title{
|
|
102
|
+
height:var(--size-calendar-container-header-lines-height-l, 48px);
|
|
103
|
+
}
|
package/dist/esm/hooks.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KeyboardEventHandler } from 'react';
|
|
2
|
+
import { BaseGrid, Cell, DateAndTime, Range, TimeValue } from './types';
|
|
2
3
|
export type UseGridParams = {
|
|
3
4
|
buildGrid(viewDate: Date): BaseGrid;
|
|
4
5
|
isTheSameItem(date1: Date, date2: Date): boolean;
|
|
@@ -7,5 +8,19 @@ export type UseGridParams = {
|
|
|
7
8
|
onSelect?(date: Date): void;
|
|
8
9
|
onPreselect?(date: Date): void;
|
|
9
10
|
onLeave?(): void;
|
|
11
|
+
onKeyDown?: KeyboardEventHandler;
|
|
12
|
+
};
|
|
13
|
+
export declare function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameItem, getItemLabel, isInPeriod, onKeyDown, }: UseGridParams): Cell[][];
|
|
14
|
+
export declare function useDateAndTime({ showSeconds, value, }: {
|
|
15
|
+
showSeconds?: boolean;
|
|
16
|
+
value: Range | TimeValue | undefined;
|
|
17
|
+
}): {
|
|
18
|
+
dateAndTime: DateAndTime;
|
|
19
|
+
setDateAndTime: import("react").Dispatch<import("react").SetStateAction<DateAndTime>>;
|
|
20
|
+
isDateAndTimeFilled: () => boolean;
|
|
21
|
+
isTimeFilled: () => boolean;
|
|
22
|
+
isDateFilled: () => boolean;
|
|
23
|
+
onDateChange: (value: Pick<DateAndTime, "year" | "month" | "day"> | Date) => void;
|
|
24
|
+
onTimeChange: (value: TimeValue | Date) => void;
|
|
25
|
+
onDateAndTimeChange: (value: DateAndTime | Date) => void;
|
|
10
26
|
};
|
|
11
|
-
export declare function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameItem, getItemLabel, isInPeriod, }: UseGridParams): Cell[][];
|
package/dist/esm/hooks.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { useContext, useMemo } from 'react';
|
|
1
|
+
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
2
|
+
import { CALENDAR_MODE, IN_RANGE_POSITION } from './constants';
|
|
2
3
|
import { CalendarContext } from './helperComponents/CalendarContext';
|
|
3
4
|
import { stringifyAddress } from './helperComponents/Item/utils';
|
|
4
5
|
import { getInRangePosition, isWeekend } from './utils';
|
|
5
|
-
export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameItem, getItemLabel, isInPeriod, }) {
|
|
6
|
-
const { today, showHolidays, preselectedRange, value, viewDate, viewMode, focus, buildCellProps, firstNotDisableCell, } = useContext(CalendarContext);
|
|
6
|
+
export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameItem, getItemLabel, isInPeriod, onKeyDown, }) {
|
|
7
|
+
const { today, showHolidays, preselectedRange, value, dateAndTime, mode, viewDate, viewMode, focus, buildCellProps, firstNotDisableCell, isDateFilled, } = useContext(CalendarContext);
|
|
7
8
|
return useMemo(() => {
|
|
8
9
|
let hasFocusInGrid = false;
|
|
9
10
|
let currentItem;
|
|
10
11
|
let hasFoundFirstNotDisableCell = false;
|
|
11
12
|
const result = buildGrid(viewDate).map(row => row.map(({ date, address }) => {
|
|
12
|
-
var _a;
|
|
13
|
+
var _a, _b, _c, _d;
|
|
13
14
|
let isDisabled = false;
|
|
14
15
|
let isHoliday = undefined;
|
|
15
16
|
let cellProps = { isDisabled, isHoliday };
|
|
@@ -27,12 +28,20 @@ export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameIt
|
|
|
27
28
|
hasFoundFirstNotDisableCell = true;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
|
-
const
|
|
31
|
-
|
|
31
|
+
const dateTimeSelectedValue = isDateFilled()
|
|
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
|
+
: undefined;
|
|
34
|
+
const inRangePosition = mode === CALENDAR_MODE.Range
|
|
35
|
+
? getInRangePosition(date, viewMode, preselectedRange || value)
|
|
36
|
+
: IN_RANGE_POSITION.Out;
|
|
37
|
+
const isSelectedValue = value && !preselectedRange && !dateTimeSelectedValue
|
|
38
|
+
? isTheSameItem(value[0], date) || isTheSameItem(value[1], date)
|
|
39
|
+
: false;
|
|
32
40
|
const isPreselected = preselectedRange ? isTheSameItem(preselectedRange[0], date) : false;
|
|
41
|
+
const isDateTimeValueSelected = dateTimeSelectedValue ? isTheSameItem(dateTimeSelectedValue, date) : false;
|
|
33
42
|
const tabIndex = focus && stringifyAddress(address) === focus ? 0 : -1;
|
|
34
43
|
hasFocusInGrid = tabIndex === 0 || hasFocusInGrid;
|
|
35
|
-
const isCurrent = isTheSameItem(today, date);
|
|
44
|
+
const isCurrent = isTheSameItem(today || new Date(), date);
|
|
36
45
|
const cell = {
|
|
37
46
|
date,
|
|
38
47
|
onLeave,
|
|
@@ -45,8 +54,9 @@ export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameIt
|
|
|
45
54
|
onPreselect,
|
|
46
55
|
inRangePosition,
|
|
47
56
|
label: getItemLabel(date),
|
|
48
|
-
isSelected: isSelectedValue || isPreselected,
|
|
57
|
+
isSelected: isSelectedValue || isPreselected || isDateTimeValueSelected,
|
|
49
58
|
isInCurrentLevelPeriod: isInPeriod(viewDate, date),
|
|
59
|
+
onKeyDown,
|
|
50
60
|
};
|
|
51
61
|
if (isCurrent) {
|
|
52
62
|
currentItem = cell;
|
|
@@ -60,11 +70,17 @@ export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameIt
|
|
|
60
70
|
}, [
|
|
61
71
|
buildCellProps,
|
|
62
72
|
buildGrid,
|
|
73
|
+
dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.day,
|
|
74
|
+
dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.month,
|
|
75
|
+
dateAndTime === null || dateAndTime === void 0 ? void 0 : dateAndTime.year,
|
|
63
76
|
firstNotDisableCell,
|
|
64
77
|
focus,
|
|
65
78
|
getItemLabel,
|
|
79
|
+
isDateFilled,
|
|
66
80
|
isInPeriod,
|
|
67
81
|
isTheSameItem,
|
|
82
|
+
mode,
|
|
83
|
+
onKeyDown,
|
|
68
84
|
onLeave,
|
|
69
85
|
onPreselect,
|
|
70
86
|
onSelect,
|
|
@@ -76,3 +92,88 @@ export function useGrid({ onSelect, onPreselect, onLeave, buildGrid, isTheSameIt
|
|
|
76
92
|
viewMode,
|
|
77
93
|
]);
|
|
78
94
|
}
|
|
95
|
+
export function useDateAndTime({ showSeconds, value, }) {
|
|
96
|
+
const [dateAndTime, setDateAndTime] = useState(() => {
|
|
97
|
+
if (Array.isArray(value)) {
|
|
98
|
+
const initialValue = value[0];
|
|
99
|
+
return {
|
|
100
|
+
year: initialValue.getFullYear(),
|
|
101
|
+
month: initialValue.getMonth(),
|
|
102
|
+
day: initialValue.getDate(),
|
|
103
|
+
hours: initialValue.getHours(),
|
|
104
|
+
minutes: initialValue.getMinutes(),
|
|
105
|
+
seconds: initialValue.getSeconds(),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
year: undefined,
|
|
110
|
+
month: undefined,
|
|
111
|
+
day: undefined,
|
|
112
|
+
hours: value === null || value === void 0 ? void 0 : value.hours,
|
|
113
|
+
minutes: value === null || value === void 0 ? void 0 : value.minutes,
|
|
114
|
+
seconds: value === null || value === void 0 ? void 0 : value.seconds,
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
const isDateFilled = useCallback(() => {
|
|
118
|
+
const { year, month, day } = dateAndTime;
|
|
119
|
+
return [year, month, day].every(value => value !== undefined);
|
|
120
|
+
}, [dateAndTime]);
|
|
121
|
+
const isTimeFilled = useCallback(() => {
|
|
122
|
+
const { hours, minutes, seconds } = dateAndTime;
|
|
123
|
+
return [hours, minutes, ...(showSeconds ? [seconds] : [])].every(value => value !== undefined);
|
|
124
|
+
}, [dateAndTime, showSeconds]);
|
|
125
|
+
const isDateAndTimeFilled = useCallback(() => isTimeFilled() && isDateFilled(), [isDateFilled, isTimeFilled]);
|
|
126
|
+
const onDateChange = useCallback((value) => {
|
|
127
|
+
if (value instanceof Date) {
|
|
128
|
+
setDateAndTime(prevDate => (Object.assign(Object.assign({}, prevDate), { year: value.getFullYear(), month: value.getMonth(), day: value.getDate() })));
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
setDateAndTime(prevDate => (Object.assign(Object.assign({}, prevDate), value)));
|
|
132
|
+
}
|
|
133
|
+
}, []);
|
|
134
|
+
const onTimeChange = useCallback((value) => {
|
|
135
|
+
if (value instanceof Date) {
|
|
136
|
+
setDateAndTime(prevDate => (Object.assign(Object.assign({}, prevDate), { hours: value.getHours(), minutes: value.getMinutes(), seconds: value.getSeconds() })));
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
setDateAndTime(prevDate => (Object.assign(Object.assign({}, prevDate), value)));
|
|
140
|
+
}
|
|
141
|
+
}, []);
|
|
142
|
+
const onDateAndTimeChange = useCallback((value) => {
|
|
143
|
+
if (value instanceof Date) {
|
|
144
|
+
setDateAndTime({
|
|
145
|
+
year: value.getFullYear(),
|
|
146
|
+
month: value.getMonth(),
|
|
147
|
+
day: value.getDate(),
|
|
148
|
+
hours: value.getHours(),
|
|
149
|
+
minutes: value.getMinutes(),
|
|
150
|
+
seconds: value.getSeconds(),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
setDateAndTime(value);
|
|
155
|
+
}
|
|
156
|
+
}, []);
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
if (!value) {
|
|
159
|
+
setDateAndTime({});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (Array.isArray(value)) {
|
|
163
|
+
onDateAndTimeChange(value[0]);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
onTimeChange(value);
|
|
167
|
+
}
|
|
168
|
+
}, [onDateAndTimeChange, onTimeChange, value]);
|
|
169
|
+
return {
|
|
170
|
+
dateAndTime,
|
|
171
|
+
setDateAndTime,
|
|
172
|
+
isDateAndTimeFilled,
|
|
173
|
+
isTimeFilled,
|
|
174
|
+
isDateFilled,
|
|
175
|
+
onDateChange,
|
|
176
|
+
onTimeChange,
|
|
177
|
+
onDateAndTimeChange,
|
|
178
|
+
};
|
|
179
|
+
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { KeyboardEventHandler } from 'react';
|
|
1
2
|
import { ValueOf } from '@snack-uikit/utils';
|
|
2
3
|
import { CALENDAR_MODE, IN_RANGE_POSITION, SIZE, VIEW_MODE } from './constants';
|
|
3
4
|
export type InRangePosition = ValueOf<typeof IN_RANGE_POSITION>;
|
|
@@ -24,6 +25,7 @@ export type Cell = {
|
|
|
24
25
|
onSelect?(date: Date): void;
|
|
25
26
|
onPreselect?(date: Date): void;
|
|
26
27
|
onLeave?(): void;
|
|
28
|
+
onKeyDown?: KeyboardEventHandler;
|
|
27
29
|
};
|
|
28
30
|
export type FocusDirection = 'prev' | 'next';
|
|
29
31
|
export type BuildCellProps = {
|
|
@@ -31,3 +33,13 @@ export type BuildCellProps = {
|
|
|
31
33
|
isHoliday?: boolean;
|
|
32
34
|
};
|
|
33
35
|
export type BuildCellPropsFunction = (date: Date, viewMode: ViewMode) => BuildCellProps;
|
|
36
|
+
export type TimeValue = {
|
|
37
|
+
hours?: number;
|
|
38
|
+
minutes?: number;
|
|
39
|
+
seconds?: number;
|
|
40
|
+
};
|
|
41
|
+
export type DateAndTime = TimeValue & {
|
|
42
|
+
year?: number;
|
|
43
|
+
month?: number;
|
|
44
|
+
day?: number;
|
|
45
|
+
};
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { InRangePosition, Range, ViewMode } from './types';
|
|
|
3
3
|
export declare const isTheSameDecade: (date1: Date, date2: Date) => boolean;
|
|
4
4
|
export declare const isTheSameYear: (date1: Date, date2: Date) => boolean;
|
|
5
5
|
export declare const isTheSameMonth: (date1: Date, date2: Date) => boolean;
|
|
6
|
-
export declare
|
|
6
|
+
export declare function isTheSameDate(date1: Date, date2: Date): boolean;
|
|
7
7
|
export declare const capitalize: (str: string) => string;
|
|
8
8
|
export declare const getMonthName: (date: Date, locale?: Intl.Locale) => string;
|
|
9
9
|
export declare const getDateLabel: (date: Date) => string;
|
package/dist/esm/utils.js
CHANGED
|
@@ -3,7 +3,9 @@ import { IN_RANGE_POSITION, VIEW_MODE } from './constants';
|
|
|
3
3
|
export const isTheSameDecade = (date1, date2) => Math.floor(date1.getFullYear() / 10) === Math.floor(date2.getFullYear() / 10);
|
|
4
4
|
export const isTheSameYear = (date1, date2) => date1.getFullYear() === date2.getFullYear();
|
|
5
5
|
export const isTheSameMonth = (date1, date2) => isTheSameYear(date1, date2) && date1.getMonth() === date2.getMonth();
|
|
6
|
-
export
|
|
6
|
+
export function isTheSameDate(date1, date2) {
|
|
7
|
+
return isTheSameMonth(date1, date2) && date1.getDate() === date2.getDate();
|
|
8
|
+
}
|
|
7
9
|
export const capitalize = (str) => str.substring(0, 1).toUpperCase() + str.substring(1);
|
|
8
10
|
export const getMonthName = (date, locale) => {
|
|
9
11
|
const monthName = date.toLocaleString(locale, { month: 'long' });
|
|
@@ -52,7 +54,7 @@ export const getInRangePosition = (date, viewMode, range) => {
|
|
|
52
54
|
};
|
|
53
55
|
export const getEndOfTheDay = (date) => new Date(new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).valueOf() - 1);
|
|
54
56
|
export const getTestIdBuilder = (testId) => (prefix) => (testId ? `${prefix}-${testId}` : undefined);
|
|
55
|
-
export const getLocale = ({ localeProp, ctxLang } = {}) => { var _a; return localeProp || new Intl.Locale(ctxLang ? ctxLang.replace('_', '-') : (_a = navigator === null || navigator === void 0 ? void 0 : navigator.language) !== null && _a !== void 0 ? _a : 'ru-RU'); };
|
|
57
|
+
export const getLocale = ({ localeProp, ctxLang } = {}) => { var _a; return localeProp || new Intl.Locale(ctxLang ? ctxLang.replace('_', '-') : ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.language) !== null && _a !== void 0 ? _a : 'ru-RU')); };
|
|
56
58
|
export const getStartOfWeek = (locale) => getWeekStartByLocale(locale.language);
|
|
57
59
|
export const isWeekend = (date, viewMode) => {
|
|
58
60
|
if (viewMode === 'month') {
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Calendar",
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.11.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -36,7 +36,10 @@
|
|
|
36
36
|
"license": "Apache-2.0",
|
|
37
37
|
"scripts": {},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@snack-uikit/
|
|
39
|
+
"@snack-uikit/button": "0.19.1",
|
|
40
|
+
"@snack-uikit/divider": "3.2.0",
|
|
41
|
+
"@snack-uikit/icons": "0.24.0",
|
|
42
|
+
"@snack-uikit/list": "0.21.0",
|
|
40
43
|
"@snack-uikit/utils": "3.5.0",
|
|
41
44
|
"classnames": "2.3.2",
|
|
42
45
|
"uncontrollable": "8.0.2",
|
|
@@ -45,5 +48,5 @@
|
|
|
45
48
|
"peerDependencies": {
|
|
46
49
|
"@snack-uikit/locale": "*"
|
|
47
50
|
},
|
|
48
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "b7163c6f939105eb34cabec64c9e983ac7958c26"
|
|
49
52
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { CSSProperties,
|
|
1
|
+
import { CSSProperties, RefObject, useCallback } from 'react';
|
|
2
2
|
|
|
3
3
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
4
4
|
|
|
5
5
|
import { CALENDAR_MODE } from '../../constants';
|
|
6
6
|
import { CalendarBase } from '../../helperComponents/CalendarBase';
|
|
7
7
|
import { BuildCellPropsFunction, FocusDirection, Range, Size } from '../../types';
|
|
8
|
-
import {
|
|
8
|
+
import { getNormalizedValue } from './utils';
|
|
9
9
|
|
|
10
10
|
type CommonCalendarProps = {
|
|
11
11
|
/**
|
|
@@ -47,8 +47,8 @@ type CommonCalendarProps = {
|
|
|
47
47
|
locale?: Intl.Locale;
|
|
48
48
|
/** Колбек потери фокуса. Вызывается со значением `next`, когда фокус покидает компонент, передвигаясь вперед, по клавише `tab`. Со значением `prev` - по клавише стрелки вверх или `shift + tab`. */
|
|
49
49
|
onFocusLeave?(direction: FocusDirection): void;
|
|
50
|
-
/**
|
|
51
|
-
navigationStartRef?:
|
|
50
|
+
/** Ссылка на управление первым элементом навигации */
|
|
51
|
+
navigationStartRef?: RefObject<{ focus(): void }>;
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
type DateCalendarProps = CommonCalendarProps & {
|
|
@@ -63,16 +63,29 @@ type DateCalendarProps = CommonCalendarProps & {
|
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
type MonthCalendarProps = CommonCalendarProps & {
|
|
66
|
-
/**
|
|
66
|
+
/** <br> - `month` - режим выбора месяца */
|
|
67
67
|
mode: typeof CALENDAR_MODE.Month;
|
|
68
|
-
/**
|
|
68
|
+
/** <br> - в режиме month тип `Date` */
|
|
69
69
|
value?: Date;
|
|
70
|
-
/**
|
|
70
|
+
/** <br> - в режиме month тип `Date` */
|
|
71
71
|
defaultValue?: Date;
|
|
72
|
-
/**
|
|
72
|
+
/** <br> - в режиме month принимает тип `Date` */
|
|
73
73
|
onChangeValue?(value: Date): void;
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
+
type DateTimeCalendarProps = CommonCalendarProps & {
|
|
77
|
+
/** <br> - `date-time` - режим выбора даты и времени */
|
|
78
|
+
mode: typeof CALENDAR_MODE.DateTime;
|
|
79
|
+
/** <br> - в режиме date-time тип `Date` */
|
|
80
|
+
value?: Date;
|
|
81
|
+
/** <br> - в режиме date-time тип `Date` */
|
|
82
|
+
defaultValue?: Date;
|
|
83
|
+
/** <br> - в режиме date-time принимает тип `Date` */
|
|
84
|
+
onChangeValue?(value: Date): void;
|
|
85
|
+
/** Показывать ли секунды (только в режиме date-time) */
|
|
86
|
+
showSeconds?: boolean;
|
|
87
|
+
};
|
|
88
|
+
|
|
76
89
|
type RangeCalendarProps = CommonCalendarProps & {
|
|
77
90
|
/** <br> - `range` - режим выбора периода */
|
|
78
91
|
mode: typeof CALENDAR_MODE.Range;
|
|
@@ -84,14 +97,16 @@ type RangeCalendarProps = CommonCalendarProps & {
|
|
|
84
97
|
onChangeValue?(value: Range): void;
|
|
85
98
|
};
|
|
86
99
|
|
|
87
|
-
export type CalendarProps = WithSupportProps<
|
|
100
|
+
export type CalendarProps = WithSupportProps<
|
|
101
|
+
DateCalendarProps | RangeCalendarProps | MonthCalendarProps | DateTimeCalendarProps
|
|
102
|
+
>;
|
|
88
103
|
|
|
89
104
|
export function Calendar(props: CalendarProps) {
|
|
90
105
|
const { className, onChangeValue, buildCellProps, mode, ...rest } = props;
|
|
91
106
|
|
|
92
107
|
const changeValueHandler = useCallback(
|
|
93
108
|
(value: Range) => {
|
|
94
|
-
if (mode === CALENDAR_MODE.Date || mode === CALENDAR_MODE.Month) {
|
|
109
|
+
if (mode === CALENDAR_MODE.Date || mode === CALENDAR_MODE.Month || mode === CALENDAR_MODE.DateTime) {
|
|
95
110
|
const [date] = value;
|
|
96
111
|
onChangeValue?.(date);
|
|
97
112
|
return;
|
|
@@ -106,8 +121,8 @@ export function Calendar(props: CalendarProps) {
|
|
|
106
121
|
{...rest}
|
|
107
122
|
mode={mode}
|
|
108
123
|
className={className}
|
|
109
|
-
value={getNormalizedValue(props)}
|
|
110
|
-
defaultValue={
|
|
124
|
+
value={getNormalizedValue(props.value)}
|
|
125
|
+
defaultValue={getNormalizedValue(props.defaultValue)}
|
|
111
126
|
onChangeValue={changeValueHandler}
|
|
112
127
|
buildCellProps={buildCellProps}
|
|
113
128
|
/>
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import { CALENDAR_MODE } from '../../constants';
|
|
2
1
|
import { Range } from '../../types';
|
|
3
2
|
import { CalendarProps } from './Calendar';
|
|
4
3
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
function isRangeValue(value: CalendarProps['value']): value is Range {
|
|
5
|
+
return Array.isArray(value) && value.length === 2 && value[0] instanceof Date && value[1] instanceof Date;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function isDateValue(value: CalendarProps['value']): value is Date {
|
|
9
|
+
return value instanceof Date;
|
|
10
|
+
}
|
|
10
11
|
|
|
11
|
-
export const
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
export const getNormalizedValue = (value: CalendarProps['value']): Range | undefined => {
|
|
13
|
+
if (isRangeValue(value)) {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (isDateValue(value)) {
|
|
18
|
+
return [value, value];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return value;
|
|
15
22
|
};
|