@alfalab/core-components-calendar-input 10.2.26 → 10.3.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/components/calendar-input/Component.js +1 -1
- package/components/calendar-input/index.css +11 -11
- package/esm/components/calendar-input/Component.js +1 -1
- package/esm/components/calendar-input/index.css +11 -11
- package/modern/components/calendar-input/Component.js +1 -1
- package/modern/components/calendar-input/index.css +11 -11
- package/moderncssm/Component.responsive.d.ts +23 -0
- package/moderncssm/Component.responsive.js +18 -0
- package/moderncssm/components/calendar-input/Component.d.ts +246 -0
- package/moderncssm/components/calendar-input/Component.js +149 -0
- package/moderncssm/components/calendar-input/index.d.ts +1 -0
- package/moderncssm/components/calendar-input/index.js +1 -0
- package/moderncssm/components/calendar-input/index.module.css +76 -0
- package/moderncssm/desktop/Component.desktop.d.ts +10 -0
- package/moderncssm/desktop/Component.desktop.js +11 -0
- package/moderncssm/desktop/index.d.ts +2 -0
- package/moderncssm/desktop/index.js +1 -0
- package/moderncssm/index.d.ts +3 -0
- package/moderncssm/index.js +1 -0
- package/moderncssm/mobile/Component.mobile.d.ts +10 -0
- package/moderncssm/mobile/Component.mobile.js +11 -0
- package/moderncssm/mobile/index.d.ts +2 -0
- package/moderncssm/mobile/index.js +1 -0
- package/moderncssm/shared/index.d.ts +1 -0
- package/moderncssm/shared/index.js +1 -0
- package/moderncssm/utils.d.ts +13 -0
- package/moderncssm/utils.js +34 -0
- package/package.json +6 -6
- package/src/components/calendar-input/index.module.css +1 -1
|
@@ -18,7 +18,7 @@ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
|
|
|
18
18
|
var mergeRefs__default = /*#__PURE__*/_interopDefaultCompat(mergeRefs);
|
|
19
19
|
var cn__default = /*#__PURE__*/_interopDefaultCompat(cn);
|
|
20
20
|
|
|
21
|
-
var styles = {"component":"calendar-
|
|
21
|
+
var styles = {"component":"calendar-input__component_psfsj","block":"calendar-input__block_psfsj","calendarContainer":"calendar-input__calendarContainer_psfsj","calendarResponsive":"calendar-input__calendarResponsive_psfsj","calendarIcon":"calendar-input__calendarIcon_psfsj","nativeInput":"calendar-input__nativeInput_psfsj"};
|
|
22
22
|
require('./index.css')
|
|
23
23
|
|
|
24
24
|
var CalendarInput = React.forwardRef(function (_a, ref) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: 1vpiz */
|
|
2
2
|
:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
|
|
3
3
|
} /* deprecated */ :root {
|
|
4
4
|
--color-light-neutral-300: #e7e8eb;
|
|
@@ -48,31 +48,31 @@
|
|
|
48
48
|
} :root {
|
|
49
49
|
--calendar-input-icon-color: var(--color-light-neutral-translucent-700);
|
|
50
50
|
--calendar-input-popover-border-radius: var(--border-radius-m);
|
|
51
|
-
} .calendar-
|
|
51
|
+
} .calendar-input__component_psfsj {
|
|
52
52
|
display: inline-block;
|
|
53
53
|
outline: none;
|
|
54
54
|
position: relative;
|
|
55
|
-
} .calendar-
|
|
55
|
+
} .calendar-input__block_psfsj {
|
|
56
56
|
width: 100%;
|
|
57
|
-
} .calendar-
|
|
57
|
+
} .calendar-input__calendarContainer_psfsj {
|
|
58
58
|
display: inline-block;
|
|
59
59
|
box-sizing: border-box;
|
|
60
60
|
border-radius: var(--calendar-input-popover-border-radius);
|
|
61
61
|
border: 1px solid var(--color-light-neutral-300)
|
|
62
|
-
} @media (max-width: 374px) { .calendar-
|
|
62
|
+
} @media (max-width: 374px) { .calendar-input__calendarContainer_psfsj {
|
|
63
63
|
width: 100%;
|
|
64
64
|
min-width: 288px
|
|
65
65
|
}
|
|
66
|
-
} .calendar-
|
|
66
|
+
} .calendar-input__calendarResponsive_psfsj {
|
|
67
67
|
width: var(--calendar-width);
|
|
68
|
-
} .calendar-
|
|
68
|
+
} .calendar-input__calendarIcon_psfsj {
|
|
69
69
|
width: 24px;
|
|
70
70
|
height: 24px;
|
|
71
71
|
display: block;
|
|
72
72
|
color: var(--calendar-input-icon-color)
|
|
73
|
-
} .calendar-
|
|
73
|
+
} .calendar-input__calendarIcon_psfsj:not(:only-child) {
|
|
74
74
|
margin-right: var(--gap-4);
|
|
75
|
-
} .calendar-
|
|
75
|
+
} .calendar-input__nativeInput_psfsj {
|
|
76
76
|
opacity: 0;
|
|
77
77
|
position: absolute;
|
|
78
78
|
top: 0;
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
height: 100%;
|
|
82
82
|
appearance: none;
|
|
83
83
|
z-index: 1
|
|
84
|
-
} .calendar-
|
|
84
|
+
} .calendar-input__nativeInput_psfsj::-webkit-calendar-picker-indicator {
|
|
85
85
|
display: none;
|
|
86
|
-
} .calendar-
|
|
86
|
+
} .calendar-input__nativeInput_psfsj::-webkit-inner-spin-button {
|
|
87
87
|
display: none;
|
|
88
88
|
}
|
|
@@ -8,7 +8,7 @@ import { Popover } from '@alfalab/core-components-popover/esm';
|
|
|
8
8
|
import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
|
|
9
9
|
import { SUPPORTS_INPUT_TYPE_DATE } from '../../utils.js';
|
|
10
10
|
|
|
11
|
-
var styles = {"component":"calendar-
|
|
11
|
+
var styles = {"component":"calendar-input__component_psfsj","block":"calendar-input__block_psfsj","calendarContainer":"calendar-input__calendarContainer_psfsj","calendarResponsive":"calendar-input__calendarResponsive_psfsj","calendarIcon":"calendar-input__calendarIcon_psfsj","nativeInput":"calendar-input__nativeInput_psfsj"};
|
|
12
12
|
require('./index.css')
|
|
13
13
|
|
|
14
14
|
var CalendarInput = forwardRef(function (_a, ref) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: 1vpiz */
|
|
2
2
|
:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
|
|
3
3
|
} /* deprecated */ :root {
|
|
4
4
|
--color-light-neutral-300: #e7e8eb;
|
|
@@ -48,31 +48,31 @@
|
|
|
48
48
|
} :root {
|
|
49
49
|
--calendar-input-icon-color: var(--color-light-neutral-translucent-700);
|
|
50
50
|
--calendar-input-popover-border-radius: var(--border-radius-m);
|
|
51
|
-
} .calendar-
|
|
51
|
+
} .calendar-input__component_psfsj {
|
|
52
52
|
display: inline-block;
|
|
53
53
|
outline: none;
|
|
54
54
|
position: relative;
|
|
55
|
-
} .calendar-
|
|
55
|
+
} .calendar-input__block_psfsj {
|
|
56
56
|
width: 100%;
|
|
57
|
-
} .calendar-
|
|
57
|
+
} .calendar-input__calendarContainer_psfsj {
|
|
58
58
|
display: inline-block;
|
|
59
59
|
box-sizing: border-box;
|
|
60
60
|
border-radius: var(--calendar-input-popover-border-radius);
|
|
61
61
|
border: 1px solid var(--color-light-neutral-300)
|
|
62
|
-
} @media (max-width: 374px) { .calendar-
|
|
62
|
+
} @media (max-width: 374px) { .calendar-input__calendarContainer_psfsj {
|
|
63
63
|
width: 100%;
|
|
64
64
|
min-width: 288px
|
|
65
65
|
}
|
|
66
|
-
} .calendar-
|
|
66
|
+
} .calendar-input__calendarResponsive_psfsj {
|
|
67
67
|
width: var(--calendar-width);
|
|
68
|
-
} .calendar-
|
|
68
|
+
} .calendar-input__calendarIcon_psfsj {
|
|
69
69
|
width: 24px;
|
|
70
70
|
height: 24px;
|
|
71
71
|
display: block;
|
|
72
72
|
color: var(--calendar-input-icon-color)
|
|
73
|
-
} .calendar-
|
|
73
|
+
} .calendar-input__calendarIcon_psfsj:not(:only-child) {
|
|
74
74
|
margin-right: var(--gap-4);
|
|
75
|
-
} .calendar-
|
|
75
|
+
} .calendar-input__nativeInput_psfsj {
|
|
76
76
|
opacity: 0;
|
|
77
77
|
position: absolute;
|
|
78
78
|
top: 0;
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
height: 100%;
|
|
82
82
|
appearance: none;
|
|
83
83
|
z-index: 1
|
|
84
|
-
} .calendar-
|
|
84
|
+
} .calendar-input__nativeInput_psfsj::-webkit-calendar-picker-indicator {
|
|
85
85
|
display: none;
|
|
86
|
-
} .calendar-
|
|
86
|
+
} .calendar-input__nativeInput_psfsj::-webkit-inner-spin-button {
|
|
87
87
|
display: none;
|
|
88
88
|
}
|
|
@@ -7,7 +7,7 @@ import { Popover } from '@alfalab/core-components-popover/modern';
|
|
|
7
7
|
import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
|
|
8
8
|
import { SUPPORTS_INPUT_TYPE_DATE } from '../../utils.js';
|
|
9
9
|
|
|
10
|
-
const styles = {"component":"calendar-
|
|
10
|
+
const styles = {"component":"calendar-input__component_psfsj","block":"calendar-input__block_psfsj","calendarContainer":"calendar-input__calendarContainer_psfsj","calendarResponsive":"calendar-input__calendarResponsive_psfsj","calendarIcon":"calendar-input__calendarIcon_psfsj","nativeInput":"calendar-input__nativeInput_psfsj"};
|
|
11
11
|
require('./index.css')
|
|
12
12
|
|
|
13
13
|
const CalendarInput = forwardRef(({ block = false, className, inputClassName, popoverClassName, defaultOpen = false, defaultMonth, defaultValue = '', calendarPosition = 'popover', value, dataTestId, calendarProps = {}, minDate = calendarProps.minDate, maxDate = calendarProps.maxDate, offDays = calendarProps.offDays || [], events = calendarProps.events || [], preventFlip, mobileMode = 'popover', wrapperRef = null, disabled, onChange = () => null, onInputChange, onCalendarChange, onCalendarOpen, onCalendarClose, onKeyDown, readOnly, disableUserInput = false, Calendar, popoverPosition = 'bottom-start', zIndexPopover, useAnchorWidth, rightAddons, error, view = 'desktop', ...restProps }, ref) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hash:
|
|
1
|
+
/* hash: 1vpiz */
|
|
2
2
|
:root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
|
|
3
3
|
} /* deprecated */ :root {
|
|
4
4
|
--color-light-neutral-300: #e7e8eb;
|
|
@@ -48,31 +48,31 @@
|
|
|
48
48
|
} :root {
|
|
49
49
|
--calendar-input-icon-color: var(--color-light-neutral-translucent-700);
|
|
50
50
|
--calendar-input-popover-border-radius: var(--border-radius-m);
|
|
51
|
-
} .calendar-
|
|
51
|
+
} .calendar-input__component_psfsj {
|
|
52
52
|
display: inline-block;
|
|
53
53
|
outline: none;
|
|
54
54
|
position: relative;
|
|
55
|
-
} .calendar-
|
|
55
|
+
} .calendar-input__block_psfsj {
|
|
56
56
|
width: 100%;
|
|
57
|
-
} .calendar-
|
|
57
|
+
} .calendar-input__calendarContainer_psfsj {
|
|
58
58
|
display: inline-block;
|
|
59
59
|
box-sizing: border-box;
|
|
60
60
|
border-radius: var(--calendar-input-popover-border-radius);
|
|
61
61
|
border: 1px solid var(--color-light-neutral-300)
|
|
62
|
-
} @media (max-width: 374px) { .calendar-
|
|
62
|
+
} @media (max-width: 374px) { .calendar-input__calendarContainer_psfsj {
|
|
63
63
|
width: 100%;
|
|
64
64
|
min-width: 288px
|
|
65
65
|
}
|
|
66
|
-
} .calendar-
|
|
66
|
+
} .calendar-input__calendarResponsive_psfsj {
|
|
67
67
|
width: var(--calendar-width);
|
|
68
|
-
} .calendar-
|
|
68
|
+
} .calendar-input__calendarIcon_psfsj {
|
|
69
69
|
width: 24px;
|
|
70
70
|
height: 24px;
|
|
71
71
|
display: block;
|
|
72
72
|
color: var(--calendar-input-icon-color)
|
|
73
|
-
} .calendar-
|
|
73
|
+
} .calendar-input__calendarIcon_psfsj:not(:only-child) {
|
|
74
74
|
margin-right: var(--gap-4);
|
|
75
|
-
} .calendar-
|
|
75
|
+
} .calendar-input__nativeInput_psfsj {
|
|
76
76
|
opacity: 0;
|
|
77
77
|
position: absolute;
|
|
78
78
|
top: 0;
|
|
@@ -81,8 +81,8 @@
|
|
|
81
81
|
height: 100%;
|
|
82
82
|
appearance: none;
|
|
83
83
|
z-index: 1
|
|
84
|
-
} .calendar-
|
|
84
|
+
} .calendar-input__nativeInput_psfsj::-webkit-calendar-picker-indicator {
|
|
85
85
|
display: none;
|
|
86
|
-
} .calendar-
|
|
86
|
+
} .calendar-input__nativeInput_psfsj::-webkit-inner-spin-button {
|
|
87
87
|
display: none;
|
|
88
88
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { CalendarInputProps } from "./components/calendar-input/Component";
|
|
4
|
+
type CalendarInputResponsiveProps = Omit<CalendarInputProps, 'view'> & {
|
|
5
|
+
/**
|
|
6
|
+
* Контрольная точка, с нее начинается desktop версия
|
|
7
|
+
* @default 1024
|
|
8
|
+
*/
|
|
9
|
+
breakpoint?: number;
|
|
10
|
+
};
|
|
11
|
+
type CalendarInputMedia = 'desktop' | 'mobile';
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated
|
|
14
|
+
* use UniversalDateInput instead
|
|
15
|
+
*/
|
|
16
|
+
declare const CalendarInputResponsive: React.ForwardRefExoticComponent<Omit<CalendarInputProps, "view"> & {
|
|
17
|
+
/**
|
|
18
|
+
* Контрольная точка, с нее начинается desktop версия
|
|
19
|
+
* @default 1024
|
|
20
|
+
*/
|
|
21
|
+
breakpoint?: number | undefined;
|
|
22
|
+
} & React.RefAttributes<HTMLInputElement>>;
|
|
23
|
+
export { CalendarInputResponsiveProps, CalendarInputMedia, CalendarInputResponsive };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { useMedia } from '@alfalab/hooks';
|
|
3
|
+
import { CalendarInputDesktop } from './desktop/Component.desktop.js';
|
|
4
|
+
import { CalendarInputMobile } from './mobile/Component.mobile.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated
|
|
8
|
+
* use UniversalDateInput instead
|
|
9
|
+
*/
|
|
10
|
+
const CalendarInputResponsive = forwardRef(({ breakpoint = 1024, ...restProps }, ref) => {
|
|
11
|
+
const [view] = useMedia([
|
|
12
|
+
['mobile', `(max-width: ${breakpoint - 1}px)`],
|
|
13
|
+
['desktop', `(min-width: ${breakpoint}px)`],
|
|
14
|
+
], 'desktop');
|
|
15
|
+
return view === 'desktop' ? (React.createElement(CalendarInputDesktop, { ...restProps, ref: ref })) : (React.createElement(CalendarInputMobile, { ...restProps, ref: ref }));
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export { CalendarInputResponsive };
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ChangeEvent, ElementType, MouseEvent } from "react";
|
|
4
|
+
import { CalendarDesktopProps } from "@alfalab/core-components-calendar/desktop";
|
|
5
|
+
import { CalendarMobileProps } from "@alfalab/core-components-calendar/mobile";
|
|
6
|
+
import { DateInputProps } from "@alfalab/core-components-date-input";
|
|
7
|
+
import { PopoverProps } from "@alfalab/core-components-popover";
|
|
8
|
+
type CalendarInputProps = Omit<DateInputProps, 'onChange' | 'mobileMode'> & {
|
|
9
|
+
/**
|
|
10
|
+
* Дополнительный класс
|
|
11
|
+
*/
|
|
12
|
+
className?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Дополнительный класс для инпута
|
|
15
|
+
*/
|
|
16
|
+
inputClassName?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Дополнительный класс для поповера
|
|
19
|
+
*/
|
|
20
|
+
popoverClassName?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Доп. пропсы для календаря
|
|
23
|
+
*/
|
|
24
|
+
calendarProps?: (CalendarDesktopProps & Record<string, unknown>) | (CalendarMobileProps & Record<string, unknown>);
|
|
25
|
+
/**
|
|
26
|
+
* Значение инпута (используется и для календаря)
|
|
27
|
+
*/
|
|
28
|
+
value?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Начальное значение инпута
|
|
31
|
+
*/
|
|
32
|
+
defaultValue?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Состояние открытия по умолчанию
|
|
35
|
+
*/
|
|
36
|
+
defaultOpen?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Месяц в календаре по умолчанию (timestamp)
|
|
39
|
+
*/
|
|
40
|
+
defaultMonth?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Минимальная дата, доступная для выбора (timestamp)
|
|
43
|
+
*/
|
|
44
|
+
minDate?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Максимальная дата, доступная для выбора (timestamp)
|
|
47
|
+
*/
|
|
48
|
+
maxDate?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Список событий
|
|
51
|
+
*/
|
|
52
|
+
events?: Array<Date | number>;
|
|
53
|
+
/**
|
|
54
|
+
* Список выходных
|
|
55
|
+
*/
|
|
56
|
+
offDays?: Array<Date | number>;
|
|
57
|
+
/**
|
|
58
|
+
* Определяет, как рендерить календарь — в поповере или снизу инпута
|
|
59
|
+
*/
|
|
60
|
+
calendarPosition?: 'static' | 'popover';
|
|
61
|
+
/**
|
|
62
|
+
* Запрещает поповеру менять свою позицию.
|
|
63
|
+
* Например, если места снизу недостаточно,то он все равно будет показан снизу
|
|
64
|
+
*/
|
|
65
|
+
preventFlip?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Управление нативным режимом на мобильных устройствах
|
|
68
|
+
*/
|
|
69
|
+
mobileMode?: 'native' | 'popover' | 'input';
|
|
70
|
+
/**
|
|
71
|
+
* Компонент календаря
|
|
72
|
+
*/
|
|
73
|
+
Calendar?: ElementType;
|
|
74
|
+
/**
|
|
75
|
+
* Обработчик изменения значения
|
|
76
|
+
*/
|
|
77
|
+
onChange?: (event: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLButtonElement> | null, payload: {
|
|
78
|
+
date: Date;
|
|
79
|
+
value: string;
|
|
80
|
+
}) => void;
|
|
81
|
+
/**
|
|
82
|
+
* Обработчик ввода в инпут
|
|
83
|
+
*/
|
|
84
|
+
onInputChange?: (event: ChangeEvent<HTMLInputElement>, payload: {
|
|
85
|
+
value: string;
|
|
86
|
+
date: Date;
|
|
87
|
+
}) => void;
|
|
88
|
+
/**
|
|
89
|
+
* Обработчик изменения календаря
|
|
90
|
+
*/
|
|
91
|
+
onCalendarChange?: CalendarDesktopProps['onChange'];
|
|
92
|
+
/**
|
|
93
|
+
* Обработчик открытия календаря
|
|
94
|
+
*/
|
|
95
|
+
onCalendarOpen?: () => void;
|
|
96
|
+
/**
|
|
97
|
+
* Обработчик закрытия календаря
|
|
98
|
+
*/
|
|
99
|
+
onCalendarClose?: () => void;
|
|
100
|
+
/**
|
|
101
|
+
* Позиционирование поповера с календарем
|
|
102
|
+
*/
|
|
103
|
+
popoverPosition?: PopoverProps['position'];
|
|
104
|
+
/**
|
|
105
|
+
* z-index Popover
|
|
106
|
+
*/
|
|
107
|
+
zIndexPopover?: PopoverProps['zIndex'];
|
|
108
|
+
/**
|
|
109
|
+
* Календарь будет принимать ширину инпута
|
|
110
|
+
*/
|
|
111
|
+
useAnchorWidth?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Отображение компонента в мобильном или десктопном виде
|
|
114
|
+
*/
|
|
115
|
+
view?: 'desktop' | 'mobile';
|
|
116
|
+
/**
|
|
117
|
+
* Запретить ввод с клавиатуры
|
|
118
|
+
*/
|
|
119
|
+
disableUserInput?: boolean;
|
|
120
|
+
};
|
|
121
|
+
declare const CalendarInput: React.ForwardRefExoticComponent<Omit<DateInputProps, "onChange" | "mobileMode"> & {
|
|
122
|
+
/**
|
|
123
|
+
* Дополнительный класс
|
|
124
|
+
*/
|
|
125
|
+
className?: string | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* Дополнительный класс для инпута
|
|
128
|
+
*/
|
|
129
|
+
inputClassName?: string | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* Дополнительный класс для поповера
|
|
132
|
+
*/
|
|
133
|
+
popoverClassName?: string | undefined;
|
|
134
|
+
/**
|
|
135
|
+
* Доп. пропсы для календаря
|
|
136
|
+
*/
|
|
137
|
+
calendarProps?: (CalendarDesktopProps & Record<string, unknown>) | ({
|
|
138
|
+
title?: string | undefined;
|
|
139
|
+
open: boolean;
|
|
140
|
+
onClose?: (() => void) | undefined;
|
|
141
|
+
allowSelectionFromEmptyRange?: boolean | undefined;
|
|
142
|
+
hasHeader?: boolean | undefined;
|
|
143
|
+
onApply?: (() => void) | undefined;
|
|
144
|
+
clickableMonth?: boolean | undefined;
|
|
145
|
+
} & {
|
|
146
|
+
onMonthTitleClick?: ((event: React.MouseEvent<HTMLSpanElement, globalThis.MouseEvent>) => void) | undefined;
|
|
147
|
+
yearsAmount?: number | undefined;
|
|
148
|
+
scrollableContainer?: HTMLElement | undefined;
|
|
149
|
+
} & Omit<CalendarDesktopProps, ("className" | "dataTestId" | "hasHeader" | "onMonthChange" | "defaultView" | "selectorView" | "rangeComplete" | "onYearClick" | "onPeriodClick" | "responsive" | "showCurrentYearSelector") | ("contentClassName" | "headerClassName")> & Pick<CalendarDesktopProps, "className" | "dataTestId" | "hasHeader" | "onMonthChange" | "defaultView" | "selectorView" | "rangeComplete" | "onYearClick" | "onPeriodClick" | "responsive" | "showCurrentYearSelector"> & Record<string, unknown>) | undefined;
|
|
150
|
+
/**
|
|
151
|
+
* Значение инпута (используется и для календаря)
|
|
152
|
+
*/
|
|
153
|
+
value?: string | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* Начальное значение инпута
|
|
156
|
+
*/
|
|
157
|
+
defaultValue?: string | undefined;
|
|
158
|
+
/**
|
|
159
|
+
* Состояние открытия по умолчанию
|
|
160
|
+
*/
|
|
161
|
+
defaultOpen?: boolean | undefined;
|
|
162
|
+
/**
|
|
163
|
+
* Месяц в календаре по умолчанию (timestamp)
|
|
164
|
+
*/
|
|
165
|
+
defaultMonth?: number | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Минимальная дата, доступная для выбора (timestamp)
|
|
168
|
+
*/
|
|
169
|
+
minDate?: number | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* Максимальная дата, доступная для выбора (timestamp)
|
|
172
|
+
*/
|
|
173
|
+
maxDate?: number | undefined;
|
|
174
|
+
/**
|
|
175
|
+
* Список событий
|
|
176
|
+
*/
|
|
177
|
+
events?: (number | Date)[] | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* Список выходных
|
|
180
|
+
*/
|
|
181
|
+
offDays?: (number | Date)[] | undefined;
|
|
182
|
+
/**
|
|
183
|
+
* Определяет, как рендерить календарь — в поповере или снизу инпута
|
|
184
|
+
*/
|
|
185
|
+
calendarPosition?: "static" | "popover" | undefined;
|
|
186
|
+
/**
|
|
187
|
+
* Запрещает поповеру менять свою позицию.
|
|
188
|
+
* Например, если места снизу недостаточно,то он все равно будет показан снизу
|
|
189
|
+
*/
|
|
190
|
+
preventFlip?: boolean | undefined;
|
|
191
|
+
/**
|
|
192
|
+
* Управление нативным режимом на мобильных устройствах
|
|
193
|
+
*/
|
|
194
|
+
mobileMode?: "input" | "native" | "popover" | undefined;
|
|
195
|
+
/**
|
|
196
|
+
* Компонент календаря
|
|
197
|
+
*/
|
|
198
|
+
Calendar?: React.ElementType<any> | undefined;
|
|
199
|
+
/**
|
|
200
|
+
* Обработчик изменения значения
|
|
201
|
+
*/
|
|
202
|
+
onChange?: ((event: ChangeEvent<HTMLInputElement> | MouseEvent<HTMLButtonElement> | null, payload: {
|
|
203
|
+
date: Date;
|
|
204
|
+
value: string;
|
|
205
|
+
}) => void) | undefined;
|
|
206
|
+
/**
|
|
207
|
+
* Обработчик ввода в инпут
|
|
208
|
+
*/
|
|
209
|
+
onInputChange?: ((event: ChangeEvent<HTMLInputElement>, payload: {
|
|
210
|
+
value: string;
|
|
211
|
+
date: Date;
|
|
212
|
+
}) => void) | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Обработчик изменения календаря
|
|
215
|
+
*/
|
|
216
|
+
onCalendarChange?: CalendarDesktopProps['onChange'];
|
|
217
|
+
/**
|
|
218
|
+
* Обработчик открытия календаря
|
|
219
|
+
*/
|
|
220
|
+
onCalendarOpen?: (() => void) | undefined;
|
|
221
|
+
/**
|
|
222
|
+
* Обработчик закрытия календаря
|
|
223
|
+
*/
|
|
224
|
+
onCalendarClose?: (() => void) | undefined;
|
|
225
|
+
/**
|
|
226
|
+
* Позиционирование поповера с календарем
|
|
227
|
+
*/
|
|
228
|
+
popoverPosition?: PopoverProps['position'];
|
|
229
|
+
/**
|
|
230
|
+
* z-index Popover
|
|
231
|
+
*/
|
|
232
|
+
zIndexPopover?: PopoverProps['zIndex'];
|
|
233
|
+
/**
|
|
234
|
+
* Календарь будет принимать ширину инпута
|
|
235
|
+
*/
|
|
236
|
+
useAnchorWidth?: boolean | undefined;
|
|
237
|
+
/**
|
|
238
|
+
* Отображение компонента в мобильном или десктопном виде
|
|
239
|
+
*/
|
|
240
|
+
view?: "desktop" | "mobile" | undefined;
|
|
241
|
+
/**
|
|
242
|
+
* Запретить ввод с клавиатуры
|
|
243
|
+
*/
|
|
244
|
+
disableUserInput?: boolean | undefined;
|
|
245
|
+
} & React.RefAttributes<HTMLInputElement>>;
|
|
246
|
+
export { CalendarInputProps, CalendarInput };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import React, { forwardRef, useState, useRef, useEffect } from 'react';
|
|
2
|
+
import mergeRefs from 'react-merge-refs';
|
|
3
|
+
import cn from 'classnames';
|
|
4
|
+
import { dateInLimits } from '@alfalab/core-components-calendar/moderncssm/shared';
|
|
5
|
+
import { parseDateString, DateInput, isCompleteDateInput, formatDate } from '@alfalab/core-components-date-input/moderncssm';
|
|
6
|
+
import { Popover } from '@alfalab/core-components-popover/moderncssm';
|
|
7
|
+
import { CalendarMIcon } from '@alfalab/icons-glyph/CalendarMIcon';
|
|
8
|
+
import { SUPPORTS_INPUT_TYPE_DATE } from '../../utils.js';
|
|
9
|
+
import styles from './index.module.css';
|
|
10
|
+
|
|
11
|
+
const CalendarInput = forwardRef(({ block = false, className, inputClassName, popoverClassName, defaultOpen = false, defaultMonth, defaultValue = '', calendarPosition = 'popover', value, dataTestId, calendarProps = {}, minDate = calendarProps.minDate, maxDate = calendarProps.maxDate, offDays = calendarProps.offDays || [], events = calendarProps.events || [], preventFlip, mobileMode = 'popover', wrapperRef = null, disabled, onChange = () => null, onInputChange, onCalendarChange, onCalendarOpen, onCalendarClose, onKeyDown, readOnly, disableUserInput = false, Calendar, popoverPosition = 'bottom-start', zIndexPopover, useAnchorWidth, rightAddons, error, view = 'desktop', ...restProps }, ref) => {
|
|
12
|
+
const calendarResponsive = calendarProps?.responsive ?? true;
|
|
13
|
+
const shouldRenderNative = SUPPORTS_INPUT_TYPE_DATE && mobileMode === 'native';
|
|
14
|
+
const shouldRenderOnlyInput = mobileMode === 'input';
|
|
15
|
+
const shouldRenderStatic = calendarPosition === 'static' && !shouldRenderOnlyInput;
|
|
16
|
+
const shouldRenderPopover = calendarPosition === 'popover' && !shouldRenderNative && !shouldRenderOnlyInput;
|
|
17
|
+
const [open, setOpen] = useState(false);
|
|
18
|
+
const [inputValue, setInputValue] = useState(value || defaultValue);
|
|
19
|
+
const calendarValue = inputValue ? parseDateString(inputValue).getTime() : undefined;
|
|
20
|
+
const checkInputValueIsValid = (newInputValue) => {
|
|
21
|
+
if (!newInputValue)
|
|
22
|
+
return false;
|
|
23
|
+
const dateValue = parseDateString(newInputValue).getTime();
|
|
24
|
+
return !!(dateValue &&
|
|
25
|
+
isCompleteDateInput(newInputValue) &&
|
|
26
|
+
dateInLimits(dateValue, minDate, maxDate) &&
|
|
27
|
+
!offDays.includes(dateValue));
|
|
28
|
+
};
|
|
29
|
+
const inputDisabled = disabled || readOnly;
|
|
30
|
+
const inputRef = useRef(null);
|
|
31
|
+
const inputWrapperRef = useRef(null);
|
|
32
|
+
const calendarRef = useRef(null);
|
|
33
|
+
const openCalendar = () => {
|
|
34
|
+
setOpen((prev) => {
|
|
35
|
+
if (!prev)
|
|
36
|
+
onCalendarOpen?.();
|
|
37
|
+
return true;
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const closeCalendar = () => {
|
|
41
|
+
setOpen((prev) => {
|
|
42
|
+
if (prev)
|
|
43
|
+
onCalendarClose?.();
|
|
44
|
+
return false;
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
const handleKeyDown = (event) => {
|
|
48
|
+
if (event.target.tagName === 'INPUT' && event.key === 'Enter') {
|
|
49
|
+
if (open) {
|
|
50
|
+
closeCalendar();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
openCalendar();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (event.key === 'Escape') {
|
|
57
|
+
closeCalendar();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const handleClick = (event) => {
|
|
61
|
+
if (!inputWrapperRef.current?.contains(event.target))
|
|
62
|
+
return;
|
|
63
|
+
if (!open)
|
|
64
|
+
openCalendar();
|
|
65
|
+
if (view === 'desktop' && inputRef.current) {
|
|
66
|
+
inputRef.current.focus();
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const handleFocus = (event) => {
|
|
70
|
+
if (view === 'desktop') {
|
|
71
|
+
if (!inputWrapperRef.current?.contains(event.target))
|
|
72
|
+
return;
|
|
73
|
+
openCalendar();
|
|
74
|
+
if (!open && event.target.tagName !== 'INPUT' && calendarRef.current) {
|
|
75
|
+
calendarRef.current.focus();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const handleBlur = (event) => {
|
|
80
|
+
if (view === 'desktop') {
|
|
81
|
+
const target = (event.relatedTarget || document.activeElement);
|
|
82
|
+
if (inputRef.current !== target &&
|
|
83
|
+
calendarRef.current?.contains(target) === false) {
|
|
84
|
+
closeCalendar();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const handleInputKeyDown = (event) => {
|
|
89
|
+
if (['ArrowDown', 'ArrowUp'].includes(event.key) && calendarRef.current) {
|
|
90
|
+
event.preventDefault();
|
|
91
|
+
calendarRef.current.focus();
|
|
92
|
+
}
|
|
93
|
+
if (onKeyDown)
|
|
94
|
+
onKeyDown(event);
|
|
95
|
+
};
|
|
96
|
+
const changeHandler = (event, newValue, newDate, initiator = 'input', shouldChange = true) => {
|
|
97
|
+
if (initiator === 'input' && event && onInputChange) {
|
|
98
|
+
onInputChange(event, { value: newValue, date: newDate });
|
|
99
|
+
}
|
|
100
|
+
if (initiator === 'calendar' && onCalendarChange) {
|
|
101
|
+
onCalendarChange(newDate.getTime());
|
|
102
|
+
}
|
|
103
|
+
setInputValue(newValue);
|
|
104
|
+
if (shouldChange) {
|
|
105
|
+
onChange(event, { date: newDate, value: newValue });
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const handleInputChange = (event, payload) => {
|
|
109
|
+
changeHandler(event, payload.value, payload.date, 'input', !payload.value || checkInputValueIsValid(payload.value));
|
|
110
|
+
};
|
|
111
|
+
const handleCalendarChange = (date) => {
|
|
112
|
+
if (date) {
|
|
113
|
+
changeHandler(null, formatDate(date), new Date(date), 'calendar');
|
|
114
|
+
}
|
|
115
|
+
if (view === 'desktop') {
|
|
116
|
+
closeCalendar();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const handleCalendarWrapperMouseDown = (event) => {
|
|
120
|
+
// Не дает инпуту терять фокус при выборе даты
|
|
121
|
+
event.preventDefault();
|
|
122
|
+
};
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
setOpen(defaultOpen);
|
|
125
|
+
}, [defaultOpen]);
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (typeof value !== 'undefined') {
|
|
128
|
+
setInputValue(value);
|
|
129
|
+
}
|
|
130
|
+
}, [value]);
|
|
131
|
+
const renderCalendar = () => (
|
|
132
|
+
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
133
|
+
React.createElement("div", { onMouseDown: handleCalendarWrapperMouseDown }, Calendar ? (React.createElement(Calendar, { ...calendarProps, responsive: calendarResponsive, open: open, onClose: closeCalendar, ref: calendarRef, defaultMonth: defaultMonth, value: checkInputValueIsValid(inputValue) ? calendarValue : undefined, onChange: handleCalendarChange, minDate: minDate, maxDate: maxDate, offDays: offDays, events: events })) : null));
|
|
134
|
+
return (
|
|
135
|
+
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
136
|
+
React.createElement("div", { className: cn(styles.component, className, {
|
|
137
|
+
[styles.block]: block,
|
|
138
|
+
}), tabIndex: -1, onKeyDown: inputDisabled ? undefined : handleKeyDown, onClick: inputDisabled ? undefined : handleClick, onFocus: inputDisabled ? undefined : handleFocus, onBlur: handleBlur, "data-test-id": dataTestId },
|
|
139
|
+
React.createElement(DateInput, { autoComplete: 'off', ...restProps, ref: mergeRefs([inputRef, ref]), wrapperRef: mergeRefs([wrapperRef, inputWrapperRef]), value: inputValue, defaultValue: defaultValue, disabled: disabled, inputClassName: inputClassName, readOnly: readOnly, mobileMode: mobileMode === 'native' ? 'native' : 'input', error: error, disableUserInput: disableUserInput, rightAddons: React.createElement(React.Fragment, null,
|
|
140
|
+
rightAddons,
|
|
141
|
+
shouldRenderPopover && (React.createElement(CalendarMIcon, { className: styles.calendarIcon }))), rightAddonsProps: { onMouseDown: (e) => e.preventDefault() }, onKeyDown: handleInputKeyDown, onChange: handleInputChange, block: true }),
|
|
142
|
+
shouldRenderStatic && renderCalendar(),
|
|
143
|
+
shouldRenderPopover &&
|
|
144
|
+
(view === 'desktop' ? (React.createElement(Popover, { open: open, useAnchorWidth: useAnchorWidth, anchorElement: inputWrapperRef.current, popperClassName: cn(styles.calendarContainer, {
|
|
145
|
+
[styles.calendarResponsive]: calendarResponsive,
|
|
146
|
+
}), className: popoverClassName, position: popoverPosition, offset: [0, 4], withTransition: false, preventFlip: preventFlip, zIndex: zIndexPopover }, renderCalendar())) : (renderCalendar()))));
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
export { CalendarInput };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Component";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CalendarInput } from './Component.js';
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* */
|
|
2
|
+
:root {
|
|
3
|
+
--calendar-width: 344px;
|
|
4
|
+
|
|
5
|
+
/* Кнопки выбора месяцев и годов */
|
|
6
|
+
|
|
7
|
+
/* Шапка */
|
|
8
|
+
|
|
9
|
+
/* День */
|
|
10
|
+
|
|
11
|
+
/* today */
|
|
12
|
+
|
|
13
|
+
/* highlighted */
|
|
14
|
+
|
|
15
|
+
/* holidays */
|
|
16
|
+
|
|
17
|
+
/* range */
|
|
18
|
+
|
|
19
|
+
/* selected */
|
|
20
|
+
|
|
21
|
+
/* disabled */
|
|
22
|
+
|
|
23
|
+
/* marker */
|
|
24
|
+
}
|
|
25
|
+
:root {
|
|
26
|
+
--calendar-input-icon-color: var(--color-light-neutral-translucent-700);
|
|
27
|
+
--calendar-input-popover-border-radius: var(--border-radius-m);
|
|
28
|
+
}
|
|
29
|
+
.component {
|
|
30
|
+
display: inline-block;
|
|
31
|
+
outline: none;
|
|
32
|
+
position: relative;
|
|
33
|
+
}
|
|
34
|
+
.block {
|
|
35
|
+
width: 100%;
|
|
36
|
+
}
|
|
37
|
+
.calendarContainer {
|
|
38
|
+
display: inline-block;
|
|
39
|
+
box-sizing: border-box;
|
|
40
|
+
border-radius: var(--calendar-input-popover-border-radius);
|
|
41
|
+
border: 1px solid var(--color-light-neutral-300)
|
|
42
|
+
}
|
|
43
|
+
@media (max-width: 374px) {
|
|
44
|
+
.calendarContainer {
|
|
45
|
+
width: 100%;
|
|
46
|
+
min-width: 288px
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
.calendarResponsive {
|
|
50
|
+
width: var(--calendar-width);
|
|
51
|
+
}
|
|
52
|
+
.calendarIcon {
|
|
53
|
+
width: 24px;
|
|
54
|
+
height: 24px;
|
|
55
|
+
display: block;
|
|
56
|
+
color: var(--calendar-input-icon-color)
|
|
57
|
+
}
|
|
58
|
+
.calendarIcon:not(:only-child) {
|
|
59
|
+
margin-right: var(--gap-4);
|
|
60
|
+
}
|
|
61
|
+
.nativeInput {
|
|
62
|
+
opacity: 0;
|
|
63
|
+
position: absolute;
|
|
64
|
+
top: 0;
|
|
65
|
+
left: 0;
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
appearance: none;
|
|
69
|
+
z-index: 1
|
|
70
|
+
}
|
|
71
|
+
.nativeInput::-webkit-calendar-picker-indicator {
|
|
72
|
+
display: none;
|
|
73
|
+
}
|
|
74
|
+
.nativeInput::-webkit-inner-spin-button {
|
|
75
|
+
display: none;
|
|
76
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { CalendarInputProps } from "../components/calendar-input/Component";
|
|
4
|
+
type CalendarInputDesktopProps = Omit<CalendarInputProps, 'view'>;
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated
|
|
7
|
+
* use UniversalDateInput instead
|
|
8
|
+
*/
|
|
9
|
+
declare const CalendarInputDesktop: React.ForwardRefExoticComponent<CalendarInputDesktopProps & React.RefAttributes<HTMLInputElement>>;
|
|
10
|
+
export { CalendarInputDesktopProps, CalendarInputDesktop };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { CalendarDesktop } from '@alfalab/core-components-calendar/moderncssm/desktop';
|
|
3
|
+
import { CalendarInput } from '../components/calendar-input/Component.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated
|
|
7
|
+
* use UniversalDateInput instead
|
|
8
|
+
*/
|
|
9
|
+
const CalendarInputDesktop = forwardRef((props, ref) => React.createElement(CalendarInput, { Calendar: CalendarDesktop, ...props, ref: ref }));
|
|
10
|
+
|
|
11
|
+
export { CalendarInputDesktop };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CalendarInputDesktop } from './Component.desktop.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CalendarInputResponsive as CalendarInput } from './Component.responsive.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { CalendarInputProps } from "../components/calendar-input/Component";
|
|
4
|
+
type CalendarInputMobileProps = Omit<CalendarInputProps, 'view'>;
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated
|
|
7
|
+
* use UniversalDateInput instead
|
|
8
|
+
*/
|
|
9
|
+
declare const CalendarInputMobile: React.ForwardRefExoticComponent<CalendarInputMobileProps & React.RefAttributes<HTMLInputElement>>;
|
|
10
|
+
export { CalendarInputMobileProps, CalendarInputMobile };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import { CalendarMobile } from '@alfalab/core-components-calendar/moderncssm/mobile';
|
|
3
|
+
import { CalendarInput } from '../components/calendar-input/Component.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated
|
|
7
|
+
* use UniversalDateInput instead
|
|
8
|
+
*/
|
|
9
|
+
const CalendarInputMobile = forwardRef((props, ref) => React.createElement(CalendarInput, { Calendar: CalendarMobile, view: 'mobile', ...props, ref: ref }));
|
|
10
|
+
|
|
11
|
+
export { CalendarInputMobile };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CalendarInputMobile } from './Component.mobile.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../utils";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isInputDateSupported, isValidInputValue, parseDateString } from '../utils.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const DATE_FORMAT = "dd.MM.yyyy";
|
|
2
|
+
declare const NATIVE_DATE_FORMAT = "yyyy-MM-dd";
|
|
3
|
+
declare const DATE_MASK: (string | RegExp)[];
|
|
4
|
+
declare const IS_BROWSER: boolean;
|
|
5
|
+
declare const SUPPORTS_INPUT_TYPE_DATE: boolean;
|
|
6
|
+
declare const formatDate: (date: Date | number, dateFormat?: string) => string;
|
|
7
|
+
declare const parseDateString: (value: string, dateFormat?: string) => Date;
|
|
8
|
+
/**
|
|
9
|
+
* Возвращает `true`, если поддерживается `input[type="date"]`
|
|
10
|
+
*/
|
|
11
|
+
declare function isInputDateSupported(): boolean;
|
|
12
|
+
declare const isValidInputValue: (newInputValue: string | undefined, minDate: number | undefined, maxDate: number | undefined, offDays?: Array<number | Date>) => boolean;
|
|
13
|
+
export { DATE_FORMAT, NATIVE_DATE_FORMAT, DATE_MASK, IS_BROWSER, SUPPORTS_INPUT_TYPE_DATE, formatDate, parseDateString, isInputDateSupported, isValidInputValue };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import format from 'date-fns/format';
|
|
2
|
+
import isSameDay from 'date-fns/isSameDay';
|
|
3
|
+
import parse from 'date-fns/parse';
|
|
4
|
+
import { dateInLimits } from '@alfalab/core-components-calendar/moderncssm/shared';
|
|
5
|
+
import { isCompleteDateInput } from '@alfalab/core-components-date-input/moderncssm';
|
|
6
|
+
|
|
7
|
+
const DATE_FORMAT = 'dd.MM.yyyy';
|
|
8
|
+
const NATIVE_DATE_FORMAT = 'yyyy-MM-dd';
|
|
9
|
+
const DATE_MASK = [/\d/, /\d/, '.', /\d/, /\d/, '.', /\d/, /\d/, /\d/, /\d/];
|
|
10
|
+
const IS_BROWSER = typeof window !== 'undefined';
|
|
11
|
+
const SUPPORTS_INPUT_TYPE_DATE = IS_BROWSER && isInputDateSupported();
|
|
12
|
+
const formatDate = (date, dateFormat = DATE_FORMAT) => format(date, dateFormat);
|
|
13
|
+
const parseDateString = (value, dateFormat = DATE_FORMAT) => parse(value, dateFormat, new Date());
|
|
14
|
+
/**
|
|
15
|
+
* Возвращает `true`, если поддерживается `input[type="date"]`
|
|
16
|
+
*/
|
|
17
|
+
function isInputDateSupported() {
|
|
18
|
+
const input = document.createElement('input');
|
|
19
|
+
const value = 'a';
|
|
20
|
+
input.setAttribute('type', 'date');
|
|
21
|
+
input.setAttribute('value', value);
|
|
22
|
+
return input.value !== value;
|
|
23
|
+
}
|
|
24
|
+
const isValidInputValue = (newInputValue, minDate, maxDate, offDays = []) => {
|
|
25
|
+
if (!newInputValue)
|
|
26
|
+
return false;
|
|
27
|
+
const dateValue = parseDateString(newInputValue).getTime();
|
|
28
|
+
return Boolean(dateValue &&
|
|
29
|
+
isCompleteDateInput(newInputValue) &&
|
|
30
|
+
dateInLimits(dateValue, minDate, maxDate) &&
|
|
31
|
+
!offDays.some((offDay) => isSameDay(offDay, dateValue)));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { DATE_FORMAT, DATE_MASK, IS_BROWSER, NATIVE_DATE_FORMAT, SUPPORTS_INPUT_TYPE_DATE, formatDate, isInputDateSupported, isValidInputValue, parseDateString };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfalab/core-components-calendar-input",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.3.0",
|
|
4
4
|
"description": "Calendar input component",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@alfalab/core-components-calendar": "^7.
|
|
19
|
-
"@alfalab/core-components-date-input": "^4.
|
|
20
|
-
"@alfalab/core-components-popover": "^6.
|
|
18
|
+
"@alfalab/core-components-calendar": "^7.11.0",
|
|
19
|
+
"@alfalab/core-components-date-input": "^4.4.0",
|
|
20
|
+
"@alfalab/core-components-popover": "^6.3.0",
|
|
21
21
|
"@alfalab/hooks": "^1.13.0",
|
|
22
22
|
"@alfalab/icons-glyph": "^2.139.0",
|
|
23
23
|
"classnames": "^2.3.1",
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
"react-merge-refs": "^1.1.0",
|
|
26
26
|
"tslib": "^2.4.0"
|
|
27
27
|
},
|
|
28
|
-
"themesVersion": "13.0
|
|
29
|
-
"varsVersion": "9.
|
|
28
|
+
"themesVersion": "13.1.0",
|
|
29
|
+
"varsVersion": "9.12.0"
|
|
30
30
|
}
|