@gravity-ui/date-components 2.0.1 → 2.2.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/dist/cjs/components/CalendarView/hooks/useCalendarProps.js +17 -0
- package/dist/cjs/components/CalendarView/i18n/en.json +4 -1
- package/dist/cjs/components/CalendarView/i18n/index.d.ts +1 -1
- package/dist/cjs/components/CalendarView/i18n/ru.json +4 -1
- package/dist/cjs/components/DateField/hooks/useBaseDateFieldState.d.ts +2 -2
- package/dist/cjs/components/DateField/hooks/useDateFieldProps.d.ts +2 -2
- package/dist/cjs/components/DateField/hooks/useDateFieldState.d.ts +1 -2
- package/dist/cjs/components/DateField/utils.js +2 -1
- package/dist/cjs/components/DatePicker/DatePicker.d.ts +3 -2
- package/dist/cjs/components/DatePicker/DatePicker.js +3 -1
- package/dist/cjs/components/DatePicker/MobileCalendar.css +1 -26
- package/dist/cjs/components/DatePicker/MobileCalendar.d.ts +0 -5
- package/dist/cjs/components/DatePicker/MobileCalendar.js +2 -9
- package/dist/cjs/components/DatePicker/StubButton.css +26 -0
- package/dist/cjs/components/DatePicker/StubButton.d.ts +8 -0
- package/dist/cjs/components/DatePicker/StubButton.js +12 -0
- package/dist/cjs/components/DatePicker/hooks/datePickerStateFactory.d.ts +49 -0
- package/dist/cjs/components/DatePicker/hooks/datePickerStateFactory.js +121 -0
- package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.d.ts +9 -5
- package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.js +4 -2
- package/dist/cjs/components/DatePicker/hooks/useDatePickerState.d.ts +2 -41
- package/dist/cjs/components/DatePicker/hooks/useDatePickerState.js +11 -131
- package/dist/cjs/components/DatePicker/{utils.js → utils/cn.js} +1 -1
- package/dist/cjs/components/DatePicker/utils/getDateTimeValue.d.ts +3 -0
- package/dist/cjs/components/DatePicker/utils/getDateTimeValue.js +10 -0
- package/dist/cjs/components/DatePicker/utils/index.d.ts +2 -0
- package/dist/cjs/components/DatePicker/utils/index.js +5 -0
- package/dist/cjs/components/RangeCalendar/RangeCalendar.d.ts +5 -10
- package/dist/cjs/components/RangeDateField/hooks/useRangeDateFieldState.d.ts +2 -2
- package/dist/cjs/components/RangeDatePicker/RangeDatePicker.css +22 -0
- package/dist/cjs/components/RangeDatePicker/RangeDatePicker.d.ts +6 -0
- package/dist/cjs/components/RangeDatePicker/RangeDatePicker.js +25 -0
- package/dist/cjs/components/RangeDatePicker/hooks/useRangeDatePickerState.d.ts +7 -0
- package/dist/cjs/components/RangeDatePicker/hooks/useRangeDatePickerState.js +28 -0
- package/dist/cjs/components/RangeDatePicker/index.d.ts +2 -0
- package/dist/cjs/components/RangeDatePicker/index.js +5 -0
- package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.js +4 -2
- package/dist/cjs/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.js +3 -3
- package/dist/esm/components/CalendarView/hooks/useCalendarProps.js +17 -0
- package/dist/esm/components/CalendarView/i18n/en.json +4 -1
- package/dist/esm/components/CalendarView/i18n/index.d.ts +1 -1
- package/dist/esm/components/CalendarView/i18n/ru.json +4 -1
- package/dist/esm/components/DateField/hooks/useBaseDateFieldState.d.ts +2 -2
- package/dist/esm/components/DateField/hooks/useDateFieldProps.d.ts +2 -2
- package/dist/esm/components/DateField/hooks/useDateFieldState.d.ts +1 -2
- package/dist/esm/components/DateField/utils.js +2 -1
- package/dist/esm/components/DatePicker/DatePicker.d.ts +3 -2
- package/dist/esm/components/DatePicker/DatePicker.js +5 -3
- package/dist/esm/components/DatePicker/MobileCalendar.css +1 -26
- package/dist/esm/components/DatePicker/MobileCalendar.d.ts +0 -5
- package/dist/esm/components/DatePicker/MobileCalendar.js +1 -7
- package/dist/esm/components/DatePicker/StubButton.css +26 -0
- package/dist/esm/components/DatePicker/StubButton.d.ts +8 -0
- package/dist/esm/components/DatePicker/StubButton.js +8 -0
- package/dist/esm/components/DatePicker/hooks/datePickerStateFactory.d.ts +49 -0
- package/dist/esm/components/DatePicker/hooks/datePickerStateFactory.js +116 -0
- package/dist/esm/components/DatePicker/hooks/useDatePickerProps.d.ts +9 -5
- package/dist/esm/components/DatePicker/hooks/useDatePickerProps.js +4 -2
- package/dist/esm/components/DatePicker/hooks/useDatePickerState.d.ts +2 -41
- package/dist/esm/components/DatePicker/hooks/useDatePickerState.js +11 -129
- package/dist/esm/components/DatePicker/utils/cn.js +2 -0
- package/dist/esm/components/DatePicker/utils/getDateTimeValue.d.ts +3 -0
- package/dist/esm/components/DatePicker/utils/getDateTimeValue.js +6 -0
- package/dist/esm/components/DatePicker/utils/index.d.ts +2 -0
- package/dist/esm/components/DatePicker/utils/index.js +2 -0
- package/dist/esm/components/RangeCalendar/RangeCalendar.d.ts +5 -10
- package/dist/esm/components/RangeDateField/hooks/useRangeDateFieldState.d.ts +2 -2
- package/dist/esm/components/RangeDatePicker/RangeDatePicker.css +22 -0
- package/dist/esm/components/RangeDatePicker/RangeDatePicker.d.ts +6 -0
- package/dist/esm/components/RangeDatePicker/RangeDatePicker.js +21 -0
- package/dist/esm/components/RangeDatePicker/hooks/useRangeDatePickerState.d.ts +7 -0
- package/dist/esm/components/RangeDatePicker/hooks/useRangeDatePickerState.js +25 -0
- package/dist/esm/components/RangeDatePicker/index.d.ts +2 -0
- package/dist/esm/components/RangeDatePicker/index.js +2 -0
- package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.js +6 -4
- package/dist/esm/components/RelativeRangeDatePicker/components/Presets/PresetsDoc.js +3 -3
- package/package.json +2 -2
- package/dist/esm/components/DatePicker/utils.js +0 -2
- /package/dist/cjs/components/DatePicker/{utils.d.ts → utils/cn.d.ts} +0 -0
- /package/dist/esm/components/DatePicker/{utils.d.ts → utils/cn.d.ts} +0 -0
|
@@ -34,6 +34,8 @@ function useCalendarProps(props, state) {
|
|
|
34
34
|
},
|
|
35
35
|
extraProps: {
|
|
36
36
|
'aria-disabled': modeDisabled ? 'true' : undefined,
|
|
37
|
+
'aria-description': getAriaDescriptionForModeButton(state.mode, state.availableModes),
|
|
38
|
+
'aria-live': 'polite',
|
|
37
39
|
},
|
|
38
40
|
children: title,
|
|
39
41
|
};
|
|
@@ -109,3 +111,18 @@ function useCalendarProps(props, state) {
|
|
|
109
111
|
};
|
|
110
112
|
}
|
|
111
113
|
exports.useCalendarProps = useCalendarProps;
|
|
114
|
+
function getAriaDescriptionForModeButton(mode, availableModes) {
|
|
115
|
+
const nextModeIndex = availableModes.indexOf(mode) + 1;
|
|
116
|
+
const isModeLast = nextModeIndex === availableModes.length;
|
|
117
|
+
if (isModeLast) {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
const ariaLabelMap = {
|
|
121
|
+
days: '',
|
|
122
|
+
months: (0, i18n_1.i18n)('Switch to months view'),
|
|
123
|
+
quarters: (0, i18n_1.i18n)('Switch to quarters view'),
|
|
124
|
+
years: (0, i18n_1.i18n)('Switch to years view'),
|
|
125
|
+
};
|
|
126
|
+
const nextMode = availableModes[nextModeIndex];
|
|
127
|
+
return ariaLabelMap[nextMode];
|
|
128
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const i18n: (key: "Previous" | "Next", params?: import("@gravity-ui/i18n").Params | undefined) => string;
|
|
1
|
+
export declare const i18n: (key: "Previous" | "Next" | "Switch to months view" | "Switch to quarters view" | "Switch to years view", params?: import("@gravity-ui/i18n").Params | undefined) => string;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"Previous": "Назад",
|
|
3
|
-
"Next": "Вперёд"
|
|
3
|
+
"Next": "Вперёд",
|
|
4
|
+
"Switch to months view": "Переключиться на просмотр по месяцам",
|
|
5
|
+
"Switch to quarters view": "Переключиться на просмотр по кварталам",
|
|
6
|
+
"Switch to years view": "Переключиться на просмотр по годам"
|
|
4
7
|
}
|
|
@@ -28,7 +28,7 @@ export type BaseDateFieldStateOptions<T = DateTime> = {
|
|
|
28
28
|
createPlaceholder: () => T;
|
|
29
29
|
setValueFromString: (str: string) => boolean;
|
|
30
30
|
};
|
|
31
|
-
export type
|
|
31
|
+
export type DateFieldState<T = DateTime> = {
|
|
32
32
|
/** The current field value. */
|
|
33
33
|
value: T | null;
|
|
34
34
|
/** Is no part of value is filled. */
|
|
@@ -94,4 +94,4 @@ export type BaseDateFieldState<T = DateTime> = {
|
|
|
94
94
|
onInput: (key: string) => void;
|
|
95
95
|
setValueFromString: (str: string) => boolean;
|
|
96
96
|
};
|
|
97
|
-
export declare function useBaseDateFieldState<T = DateTime>(props: BaseDateFieldStateOptions<T>):
|
|
97
|
+
export declare function useBaseDateFieldState<T = DateTime>(props: BaseDateFieldStateOptions<T>): DateFieldState<T>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
2
|
import type { TextInputProps } from '@gravity-ui/uikit';
|
|
3
3
|
import type { AccessibilityProps, DateFieldBase, TextInputProps as DateFieldTextInputProps, DomProps, FocusableProps, InputDOMProps, KeyboardEvents, StyleProps, TextInputExtendProps } from '../../types';
|
|
4
|
-
import type {
|
|
4
|
+
import type { DateFieldState } from './useBaseDateFieldState';
|
|
5
5
|
export interface DateFieldProps<T = DateTime> extends DateFieldBase<T>, DateFieldTextInputProps, TextInputExtendProps, DomProps, InputDOMProps, FocusableProps, KeyboardEvents, StyleProps, AccessibilityProps {
|
|
6
6
|
}
|
|
7
|
-
export declare function useDateFieldProps<T = DateTime>(state:
|
|
7
|
+
export declare function useDateFieldProps<T = DateTime>(state: DateFieldState<T>, props: DateFieldProps<T>): {
|
|
8
8
|
inputProps: TextInputProps;
|
|
9
9
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { DateFieldBase } from '../../types/datePicker';
|
|
2
|
-
import type {
|
|
2
|
+
import type { DateFieldState } from './useBaseDateFieldState';
|
|
3
3
|
export interface DateFieldStateOptions extends DateFieldBase {
|
|
4
4
|
}
|
|
5
|
-
export type DateFieldState = BaseDateFieldState;
|
|
6
5
|
export declare function useDateFieldState(props: DateFieldStateOptions): DateFieldState;
|
|
@@ -69,6 +69,7 @@ const formatTokenMap = {
|
|
|
69
69
|
function getDateSectionConfigFromFormatToken(formatToken) {
|
|
70
70
|
const config = formatTokenMap[formatToken];
|
|
71
71
|
if (!config) {
|
|
72
|
+
// eslint-disable-next-line no-console
|
|
72
73
|
console.error([
|
|
73
74
|
`The token "${formatToken}" is not supported by the Date field.`,
|
|
74
75
|
'Please try using another token.',
|
|
@@ -193,7 +194,7 @@ function addSegment(section, date, amount) {
|
|
|
193
194
|
var _a;
|
|
194
195
|
let val = (_a = section.value) !== null && _a !== void 0 ? _a : 0;
|
|
195
196
|
if (section.type === 'dayPeriod') {
|
|
196
|
-
val = date.hour() + (date.hour()
|
|
197
|
+
val = date.hour() + (date.hour() >= 12 ? -12 : 12);
|
|
197
198
|
}
|
|
198
199
|
else {
|
|
199
200
|
val = val + amount;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
3
|
import type { CalendarProps } from '../Calendar';
|
|
3
4
|
import type { AccessibilityProps, DateFieldBase, DomProps, FocusableProps, InputDOMProps, KeyboardEvents, StyleProps, TextInputProps } from '../types';
|
|
4
5
|
import './DatePicker.css';
|
|
5
|
-
export interface DatePickerProps extends DateFieldBase
|
|
6
|
-
children?: (props: CalendarProps) => React.ReactNode;
|
|
6
|
+
export interface DatePickerProps<T = DateTime> extends DateFieldBase<T>, TextInputProps, FocusableProps, KeyboardEvents, DomProps, InputDOMProps, StyleProps, AccessibilityProps {
|
|
7
|
+
children?: (props: CalendarProps<T>) => React.ReactNode;
|
|
7
8
|
}
|
|
8
9
|
export declare function DatePicker({ className, ...props }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,6 +9,7 @@ const uikit_1 = require("@gravity-ui/uikit");
|
|
|
9
9
|
const Calendar_1 = require("../Calendar");
|
|
10
10
|
const DateField_1 = require("../DateField");
|
|
11
11
|
const MobileCalendar_1 = require("./MobileCalendar");
|
|
12
|
+
const StubButton_1 = require("./StubButton");
|
|
12
13
|
const useDatePickerProps_1 = require("./hooks/useDatePickerProps");
|
|
13
14
|
const useDatePickerState_1 = require("./hooks/useDatePickerState");
|
|
14
15
|
const utils_1 = require("./utils");
|
|
@@ -19,7 +20,8 @@ function DatePicker(_a) {
|
|
|
19
20
|
const state = (0, useDatePickerState_1.useDatePickerState)(props);
|
|
20
21
|
const { groupProps, fieldProps, calendarButtonProps, popupProps, calendarProps, timeInputProps } = (0, useDatePickerProps_1.useDatePickerProps)(state, props);
|
|
21
22
|
const isMobile = (0, uikit_1.useMobile)();
|
|
22
|
-
|
|
23
|
+
const isOnlyTime = state.hasTime && !state.hasDate;
|
|
24
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: (0, utils_1.b)(null, className) }, groupProps, { children: [isMobile ? ((0, jsx_runtime_1.jsx)(MobileCalendar_1.MobileCalendar, { props: props, state: state })) : (!isOnlyTime && ((0, jsx_runtime_1.jsx)("div", { ref: anchorRef, className: (0, utils_1.b)('popup-anchor'), children: (0, jsx_runtime_1.jsx)(uikit_1.Popup, Object.assign({ anchorRef: anchorRef }, popupProps, { children: (0, jsx_runtime_1.jsxs)("div", { className: (0, utils_1.b)('popup-content'), children: [typeof props.children === 'function' ? (props.children(calendarProps)) : ((0, jsx_runtime_1.jsx)(Calendar_1.Calendar, Object.assign({}, calendarProps))), state.hasTime && ((0, jsx_runtime_1.jsx)("div", { className: (0, utils_1.b)('time-field-wrapper'), children: (0, jsx_runtime_1.jsx)(DateField_1.DateField, Object.assign({}, timeInputProps)) }))] }) })) }))), (0, jsx_runtime_1.jsx)(uikit_1.TextInput, Object.assign({}, fieldProps, { className: (0, utils_1.b)('field', { mobile: isMobile }), hasClear: !isMobile && fieldProps.hasClear, endContent: (0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [!isMobile && !isOnlyTime && ((0, jsx_runtime_1.jsx)(uikit_1.Button, Object.assign({}, calendarButtonProps, { children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Calendar }) }))), !isMobile && isOnlyTime && ((0, jsx_runtime_1.jsx)(StubButton_1.StubButton, { size: calendarButtonProps.size, icon: icons_1.Clock })), isMobile && ((0, jsx_runtime_1.jsx)(StubButton_1.StubButton, { size: calendarButtonProps.size, icon: isOnlyTime ? icons_1.Clock : icons_1.Calendar }))] }) })), (0, jsx_runtime_1.jsx)("input", { type: "text", hidden: true, name: props.name, value: state.value ? state.value.toISOString() : '',
|
|
23
25
|
// Ignore React warning
|
|
24
26
|
onChange: () => { } })] })));
|
|
25
27
|
}
|
|
@@ -1,29 +1,4 @@
|
|
|
1
1
|
.g-date-mobile-calendar {
|
|
2
|
-
position: relative;
|
|
3
|
-
display: inline-block;
|
|
4
|
-
width: 24px;
|
|
5
|
-
height: 24px;
|
|
6
|
-
}
|
|
7
|
-
.g-date-mobile-calendar_size_xs {
|
|
8
|
-
width: 20px;
|
|
9
|
-
height: 20px;
|
|
10
|
-
}
|
|
11
|
-
.g-date-mobile-calendar_size_m {
|
|
12
|
-
width: 28px;
|
|
13
|
-
height: 28px;
|
|
14
|
-
}
|
|
15
|
-
.g-date-mobile-calendar_size_l {
|
|
16
|
-
width: 36px;
|
|
17
|
-
height: 36px;
|
|
18
|
-
}
|
|
19
|
-
.g-date-mobile-calendar__button {
|
|
20
|
-
position: absolute;
|
|
21
|
-
inset: 0;
|
|
22
|
-
display: flex;
|
|
23
|
-
justify-content: center;
|
|
24
|
-
align-items: center;
|
|
25
|
-
}
|
|
26
|
-
.g-date-mobile-calendar__input {
|
|
27
2
|
position: absolute;
|
|
28
3
|
z-index: 1;
|
|
29
4
|
inset-block-start: 0;
|
|
@@ -37,7 +12,7 @@
|
|
|
37
12
|
opacity: 0;
|
|
38
13
|
border: none;
|
|
39
14
|
}
|
|
40
|
-
.g-date-mobile-
|
|
15
|
+
.g-date-mobile-calendar::-webkit-calendar-picker-indicator {
|
|
41
16
|
position: absolute;
|
|
42
17
|
inset-block-start: 0;
|
|
43
18
|
inset-inline-start: 0;
|
|
@@ -6,9 +6,4 @@ interface MobileCalendarProps {
|
|
|
6
6
|
state: DatePickerState;
|
|
7
7
|
}
|
|
8
8
|
export declare function MobileCalendar({ props, state }: MobileCalendarProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
-
interface MobileCalendarIconProps {
|
|
10
|
-
props: DatePickerProps;
|
|
11
|
-
state: DatePickerState;
|
|
12
|
-
}
|
|
13
|
-
export declare function MobileCalendarIcon({ props }: MobileCalendarIconProps): import("react/jsx-runtime").JSX.Element;
|
|
14
9
|
export {};
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.MobileCalendar = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const date_utils_1 = require("@gravity-ui/date-utils");
|
|
6
|
-
const icons_1 = require("@gravity-ui/icons");
|
|
7
|
-
const uikit_1 = require("@gravity-ui/uikit");
|
|
8
6
|
const cn_1 = require("../../utils/cn");
|
|
9
7
|
const dates_1 = require("../utils/dates");
|
|
10
|
-
const getButtonSizeForInput_1 = require("../utils/getButtonSizeForInput");
|
|
11
8
|
require("./MobileCalendar.css");
|
|
12
9
|
const b = (0, cn_1.block)('mobile-calendar');
|
|
13
10
|
function MobileCalendar({ props, state }) {
|
|
@@ -19,7 +16,7 @@ function MobileCalendar({ props, state }) {
|
|
|
19
16
|
else if (state.hasTime) {
|
|
20
17
|
type = 'time';
|
|
21
18
|
}
|
|
22
|
-
return ((0, jsx_runtime_1.jsx)("input", { className: b(
|
|
19
|
+
return ((0, jsx_runtime_1.jsx)("input", { className: b(), disabled: props.disabled, type: type, value: formatNative(state.dateFieldState.displayValue, type), id: props.id, min: formatNative((_a = props.minValue) === null || _a === void 0 ? void 0 : _a.timeZone(state.timeZone), type), max: formatNative((_b = props.maxValue) === null || _b === void 0 ? void 0 : _b.timeZone(state.timeZone), type), tabIndex: -1, onChange: (e) => {
|
|
23
20
|
var _a, _b;
|
|
24
21
|
if (props.readOnly) {
|
|
25
22
|
return;
|
|
@@ -57,10 +54,6 @@ function MobileCalendar({ props, state }) {
|
|
|
57
54
|
} }));
|
|
58
55
|
}
|
|
59
56
|
exports.MobileCalendar = MobileCalendar;
|
|
60
|
-
function MobileCalendarIcon({ props }) {
|
|
61
|
-
return ((0, jsx_runtime_1.jsx)("span", { className: b({ size: (0, getButtonSizeForInput_1.getButtonSizeForInput)(props.size) }), children: (0, jsx_runtime_1.jsx)("span", { className: b('button'), children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Calendar }) }) }));
|
|
62
|
-
}
|
|
63
|
-
exports.MobileCalendarIcon = MobileCalendarIcon;
|
|
64
57
|
function getDateFormat(type) {
|
|
65
58
|
switch (type) {
|
|
66
59
|
case 'time': {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.g-date-stub-button {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: inline-block;
|
|
4
|
+
width: 24px;
|
|
5
|
+
height: 24px;
|
|
6
|
+
}
|
|
7
|
+
.g-date-stub-button_size_xs {
|
|
8
|
+
width: 20px;
|
|
9
|
+
height: 20px;
|
|
10
|
+
}
|
|
11
|
+
.g-date-stub-button_size_m {
|
|
12
|
+
width: 28px;
|
|
13
|
+
height: 28px;
|
|
14
|
+
}
|
|
15
|
+
.g-date-stub-button_size_l {
|
|
16
|
+
width: 36px;
|
|
17
|
+
height: 36px;
|
|
18
|
+
}
|
|
19
|
+
.g-date-stub-button__icon {
|
|
20
|
+
position: absolute;
|
|
21
|
+
inset: 0;
|
|
22
|
+
display: flex;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
align-items: center;
|
|
25
|
+
color: var(--g-color-text-secondary);
|
|
26
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ButtonSize, IconData } from '@gravity-ui/uikit';
|
|
2
|
+
import './StubButton.css';
|
|
3
|
+
interface StubButtonProps {
|
|
4
|
+
size?: ButtonSize;
|
|
5
|
+
icon: IconData;
|
|
6
|
+
}
|
|
7
|
+
export declare function StubButton({ size, icon }: StubButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StubButton = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
6
|
+
const cn_1 = require("../../utils/cn");
|
|
7
|
+
require("./StubButton.css");
|
|
8
|
+
const b = (0, cn_1.block)('stub-button');
|
|
9
|
+
function StubButton({ size, icon }) {
|
|
10
|
+
return ((0, jsx_runtime_1.jsx)("span", { className: b({ size }), children: (0, jsx_runtime_1.jsx)("span", { className: b('icon'), children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icon }) }) }));
|
|
11
|
+
}
|
|
12
|
+
exports.StubButton = StubButton;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
|
+
import type { DateFieldState } from '../../DateField';
|
|
3
|
+
import type { DateFieldBase } from '../../types';
|
|
4
|
+
export interface DatePickerState<T = DateTime> {
|
|
5
|
+
/** The currently selected date. */
|
|
6
|
+
value: T | null;
|
|
7
|
+
/** Sets the selected date. */
|
|
8
|
+
setValue: (value: T | null) => void;
|
|
9
|
+
/**
|
|
10
|
+
* The date portion of the value. This may be set prior to `value` if the user has
|
|
11
|
+
* selected a date but has not yet selected a time.
|
|
12
|
+
*/
|
|
13
|
+
dateValue: T | null;
|
|
14
|
+
/** Sets the date portion of the value. */
|
|
15
|
+
setDateValue: (value: T) => void;
|
|
16
|
+
/**
|
|
17
|
+
* The time portion of the value. This may be set prior to `value` if the user has
|
|
18
|
+
* selected a time but has not yet selected a date.
|
|
19
|
+
*/
|
|
20
|
+
timeValue: T | null;
|
|
21
|
+
/** Sets the time portion of the value. */
|
|
22
|
+
setTimeValue: (value: T | null) => void;
|
|
23
|
+
/** Whether the field is read only. */
|
|
24
|
+
readOnly?: boolean;
|
|
25
|
+
/** Whether the field is disabled. */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Format of the date when rendered in the input. */
|
|
28
|
+
format: string;
|
|
29
|
+
/** Whether the date picker supports selecting a date. */
|
|
30
|
+
hasDate: boolean;
|
|
31
|
+
/** Whether the date picker supports selecting a time. */
|
|
32
|
+
hasTime: boolean;
|
|
33
|
+
/** Format of the time when rendered in the input. */
|
|
34
|
+
timeFormat?: string;
|
|
35
|
+
timeZone: string;
|
|
36
|
+
/** Whether the calendar popover is currently open. */
|
|
37
|
+
isOpen: boolean;
|
|
38
|
+
/** Sets whether the calendar popover is open. */
|
|
39
|
+
setOpen: (isOpen: boolean) => void;
|
|
40
|
+
dateFieldState: DateFieldState<T>;
|
|
41
|
+
}
|
|
42
|
+
export interface DatePickerStateFactoryOptions<T, O extends DateFieldBase<T>> {
|
|
43
|
+
getPlaceholderTime: (placeholderValue: DateTime | undefined, timeZone?: string) => T;
|
|
44
|
+
mergeDateTime: (date: T, time: T) => T;
|
|
45
|
+
setTimezone: (date: T, timeZone: string) => T;
|
|
46
|
+
getDateTime: (date: T | null | undefined) => DateTime | undefined;
|
|
47
|
+
useDateFieldState: (props: O) => DateFieldState<T>;
|
|
48
|
+
}
|
|
49
|
+
export declare function datePickerStateFactory<T, O extends DateFieldBase<T>>({ getPlaceholderTime, mergeDateTime, setTimezone, getDateTime, useDateFieldState, }: DatePickerStateFactoryOptions<T, O>): (props: O) => DatePickerState<T>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.datePickerStateFactory = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
6
|
+
const uikit_1 = require("@gravity-ui/uikit");
|
|
7
|
+
const useDefaultTimeZone_1 = require("../../utils/useDefaultTimeZone");
|
|
8
|
+
function datePickerStateFactory({ getPlaceholderTime, mergeDateTime, setTimezone, getDateTime, useDateFieldState, }) {
|
|
9
|
+
return function useDatePickerState(props) {
|
|
10
|
+
var _a;
|
|
11
|
+
const { disabled, readOnly } = props;
|
|
12
|
+
const [isOpen, setOpen] = react_1.default.useState(false);
|
|
13
|
+
const [value, setValue] = (0, uikit_1.useControlledState)(props.value, (_a = props.defaultValue) !== null && _a !== void 0 ? _a : null, props.onUpdate);
|
|
14
|
+
const [selectedDateInner, setSelectedDate] = react_1.default.useState(null);
|
|
15
|
+
const [selectedTimeInner, setSelectedTime] = react_1.default.useState(null);
|
|
16
|
+
const inputTimeZone = (0, useDefaultTimeZone_1.useDefaultTimeZone)(getDateTime(props.value) || getDateTime(props.defaultValue) || props.placeholderValue);
|
|
17
|
+
const timeZone = props.timeZone || inputTimeZone;
|
|
18
|
+
let selectedDate = selectedDateInner;
|
|
19
|
+
let selectedTime = selectedTimeInner;
|
|
20
|
+
const format = props.format || 'L';
|
|
21
|
+
const commitValue = (date, time) => {
|
|
22
|
+
if (disabled || readOnly) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
setValue(setTimezone(mergeDateTime(date, time), inputTimeZone));
|
|
26
|
+
setSelectedDate(null);
|
|
27
|
+
setSelectedTime(null);
|
|
28
|
+
};
|
|
29
|
+
const dateFieldState = useDateFieldState(Object.assign(Object.assign({}, props), { value,
|
|
30
|
+
onUpdate(date) {
|
|
31
|
+
if (date) {
|
|
32
|
+
commitValue(date, date);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
setValue(null);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
disabled,
|
|
39
|
+
readOnly, validationState: props.validationState, minValue: props.minValue, maxValue: props.maxValue, isDateUnavailable: props.isDateUnavailable, format, placeholderValue: props.placeholderValue, timeZone }));
|
|
40
|
+
const timeFormat = react_1.default.useMemo(() => {
|
|
41
|
+
const hasSeconds = dateFieldState.sections.some((s) => s.type === 'second');
|
|
42
|
+
return hasSeconds ? 'LTS' : 'LT';
|
|
43
|
+
}, [dateFieldState.sections]);
|
|
44
|
+
if (value) {
|
|
45
|
+
selectedDate = setTimezone(value, timeZone);
|
|
46
|
+
if (dateFieldState.hasTime) {
|
|
47
|
+
selectedTime = setTimezone(value, timeZone);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Intercept setValue to make sure the Time section is not changed by date selection in Calendar
|
|
51
|
+
const selectDate = (newValue) => {
|
|
52
|
+
if (disabled || readOnly) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const shouldClose = !dateFieldState.hasTime;
|
|
56
|
+
if (dateFieldState.hasTime) {
|
|
57
|
+
if (selectedTime || shouldClose) {
|
|
58
|
+
commitValue(newValue, selectedTime || newValue);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
setSelectedDate(newValue);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
commitValue(newValue, newValue);
|
|
66
|
+
}
|
|
67
|
+
if (shouldClose) {
|
|
68
|
+
setOpen(false);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const selectTime = (newValue) => {
|
|
72
|
+
if (disabled || readOnly) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const newTime = newValue !== null && newValue !== void 0 ? newValue : getPlaceholderTime(props.placeholderValue, timeZone);
|
|
76
|
+
if (selectedDate) {
|
|
77
|
+
commitValue(selectedDate, newTime);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
setSelectedTime(newTime);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
if (dateFieldState.hasTime && !selectedTime) {
|
|
84
|
+
selectedTime = dateFieldState.displayValue;
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
value,
|
|
88
|
+
setValue(newDate) {
|
|
89
|
+
if (props.readOnly || props.disabled) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (newDate) {
|
|
93
|
+
setValue(setTimezone(newDate, inputTimeZone));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
setValue(null);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
dateValue: selectedDate,
|
|
100
|
+
timeValue: selectedTime,
|
|
101
|
+
setDateValue: selectDate,
|
|
102
|
+
setTimeValue: selectTime,
|
|
103
|
+
disabled,
|
|
104
|
+
readOnly,
|
|
105
|
+
format,
|
|
106
|
+
hasDate: dateFieldState.hasDate,
|
|
107
|
+
hasTime: dateFieldState.hasTime,
|
|
108
|
+
timeFormat,
|
|
109
|
+
timeZone,
|
|
110
|
+
isOpen,
|
|
111
|
+
setOpen(newIsOpen) {
|
|
112
|
+
if (!newIsOpen && !value && selectedDate && dateFieldState.hasTime) {
|
|
113
|
+
commitValue(selectedDate, selectedTime || getPlaceholderTime(props.placeholderValue, props.timeZone));
|
|
114
|
+
}
|
|
115
|
+
setOpen(newIsOpen);
|
|
116
|
+
},
|
|
117
|
+
dateFieldState,
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
exports.datePickerStateFactory = datePickerStateFactory;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
3
|
import type { ButtonProps, PopupProps, TextInputProps } from '@gravity-ui/uikit';
|
|
3
|
-
import type {
|
|
4
|
+
import type { CalendarInstance, CalendarProps } from '../../Calendar';
|
|
4
5
|
import type { DateFieldProps } from '../../DateField';
|
|
6
|
+
import type { RangeValue } from '../../types';
|
|
5
7
|
import type { DatePickerProps } from '../DatePicker';
|
|
6
8
|
import type { DatePickerState } from './useDatePickerState';
|
|
7
|
-
interface
|
|
9
|
+
interface InnerDatePickerProps<T = DateTime> {
|
|
8
10
|
groupProps: React.HTMLAttributes<unknown> & {
|
|
9
11
|
ref: React.Ref<any>;
|
|
10
12
|
};
|
|
@@ -13,8 +15,10 @@ interface InnerRelativeDatePickerProps {
|
|
|
13
15
|
ref: React.Ref<HTMLButtonElement>;
|
|
14
16
|
};
|
|
15
17
|
popupProps: PopupProps;
|
|
16
|
-
calendarProps:
|
|
17
|
-
|
|
18
|
+
calendarProps: CalendarProps<T> & {
|
|
19
|
+
ref: React.Ref<CalendarInstance>;
|
|
20
|
+
};
|
|
21
|
+
timeInputProps: DateFieldProps<T>;
|
|
18
22
|
}
|
|
19
|
-
export declare function useDatePickerProps(state: DatePickerState
|
|
23
|
+
export declare function useDatePickerProps<T extends DateTime | RangeValue<DateTime>>(state: DatePickerState<T>, { onFocus, onBlur, ...props }: DatePickerProps<T>): InnerDatePickerProps<T>;
|
|
20
24
|
export {};
|
|
@@ -8,6 +8,7 @@ const DateField_1 = require("../../DateField");
|
|
|
8
8
|
const getButtonSizeForInput_1 = require("../../utils/getButtonSizeForInput");
|
|
9
9
|
const mergeProps_1 = require("../../utils/mergeProps");
|
|
10
10
|
const i18n_1 = require("../i18n");
|
|
11
|
+
const utils_1 = require("../utils");
|
|
11
12
|
function useDatePickerProps(state, _a) {
|
|
12
13
|
var { onFocus, onBlur } = _a, props = tslib_1.__rest(_a, ["onFocus", "onBlur"]);
|
|
13
14
|
const [isActive, setActive] = react_1.default.useState(false);
|
|
@@ -33,9 +34,10 @@ function useDatePickerProps(state, _a) {
|
|
|
33
34
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
34
35
|
});
|
|
35
36
|
}
|
|
37
|
+
const onlyTime = state.hasTime && !state.hasDate;
|
|
36
38
|
return {
|
|
37
39
|
groupProps: Object.assign(Object.assign({ ref: groupRef, tabIndex: -1, role: 'group' }, focusWithinProps), { style: props.style, 'aria-disabled': state.disabled || undefined, onKeyDown: (e) => {
|
|
38
|
-
if (e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
|
|
40
|
+
if (!onlyTime && e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
|
|
39
41
|
e.preventDefault();
|
|
40
42
|
e.stopPropagation();
|
|
41
43
|
state.setOpen(true);
|
|
@@ -96,7 +98,7 @@ function useDatePickerProps(state, _a) {
|
|
|
96
98
|
},
|
|
97
99
|
timeInputProps: {
|
|
98
100
|
value: state.timeValue,
|
|
99
|
-
placeholderValue: state.dateFieldState.displayValue,
|
|
101
|
+
placeholderValue: (0, utils_1.getDateTimeValue)(state.dateFieldState.displayValue),
|
|
100
102
|
onUpdate: state.setTimeValue,
|
|
101
103
|
format: state.timeFormat,
|
|
102
104
|
readOnly: state.readOnly,
|
|
@@ -1,45 +1,6 @@
|
|
|
1
1
|
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
|
-
import type { DateFieldState } from '../../DateField';
|
|
3
2
|
import type { DateFieldBase } from '../../types';
|
|
4
|
-
export type
|
|
5
|
-
export interface DatePickerState {
|
|
6
|
-
/** The currently selected date. */
|
|
7
|
-
value: DateTime | null;
|
|
8
|
-
/** Sets the selected date. */
|
|
9
|
-
setValue: (value: DateTime | null) => void;
|
|
10
|
-
/**
|
|
11
|
-
* The date portion of the value. This may be set prior to `value` if the user has
|
|
12
|
-
* selected a date but has not yet selected a time.
|
|
13
|
-
*/
|
|
14
|
-
dateValue: DateTime | null;
|
|
15
|
-
/** Sets the date portion of the value. */
|
|
16
|
-
setDateValue: (value: DateTime) => void;
|
|
17
|
-
/**
|
|
18
|
-
* The time portion of the value. This may be set prior to `value` if the user has
|
|
19
|
-
* selected a time but has not yet selected a date.
|
|
20
|
-
*/
|
|
21
|
-
timeValue: DateTime | null;
|
|
22
|
-
/** Sets the time portion of the value. */
|
|
23
|
-
setTimeValue: (value: DateTime | null) => void;
|
|
24
|
-
/** Whether the field is read only. */
|
|
25
|
-
readOnly?: boolean;
|
|
26
|
-
/** Whether the field is disabled. */
|
|
27
|
-
disabled?: boolean;
|
|
28
|
-
/** Format of the date when rendered in the input. */
|
|
29
|
-
format: string;
|
|
30
|
-
/** Whether the date picker supports selecting a date. */
|
|
31
|
-
hasDate: boolean;
|
|
32
|
-
/** Whether the date picker supports selecting a time. */
|
|
33
|
-
hasTime: boolean;
|
|
34
|
-
/** Format of the time when rendered in the input. */
|
|
35
|
-
timeFormat?: string;
|
|
36
|
-
timeZone: string;
|
|
37
|
-
/** Whether the calendar popover is currently open. */
|
|
38
|
-
isOpen: boolean;
|
|
39
|
-
/** Sets whether the calendar popover is open. */
|
|
40
|
-
setOpen: (isOpen: boolean) => void;
|
|
41
|
-
dateFieldState: DateFieldState;
|
|
42
|
-
}
|
|
3
|
+
export type { DatePickerState } from './datePickerStateFactory';
|
|
43
4
|
export interface DatePickerStateOptions extends DateFieldBase {
|
|
44
5
|
}
|
|
45
|
-
export declare
|
|
6
|
+
export declare const useDatePickerState: (props: import("../../DateField").DateFieldStateOptions) => import("./datePickerStateFactory").DatePickerState<DateTime>;
|