@gravity-ui/date-components 1.1.0 → 1.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/Calendar/Calendar.css +37 -37
- package/dist/cjs/components/Calendar/Calendar.js +2 -4
- package/dist/cjs/components/Calendar/CalendarBase.js +2 -4
- package/dist/cjs/components/Calendar/RangeCalendar.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useCalendarCellProps.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useCalendarGridProps.js +11 -0
- package/dist/cjs/components/Calendar/hooks/useCalendarProps.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useCalendarState.js +2 -4
- package/dist/cjs/components/Calendar/hooks/useRangeCalendarState.js +13 -21
- package/dist/cjs/components/Calendar/i18n/index.js +3 -5
- package/dist/cjs/components/Calendar/index.js +8 -21
- package/dist/cjs/components/DateField/DateField.js +3 -16
- package/dist/cjs/components/DateField/hooks/useDateFieldProps.js +25 -20
- package/dist/cjs/components/DateField/hooks/useDateFieldState.js +23 -167
- package/dist/cjs/components/DateField/i18n/index.js +3 -5
- package/dist/cjs/components/DateField/index.js +4 -17
- package/dist/cjs/components/DateField/utils.d.ts +14 -3
- package/dist/cjs/components/DateField/utils.js +172 -3
- package/dist/cjs/components/DatePicker/DatePicker.css +6 -0
- package/dist/cjs/components/DatePicker/DatePicker.d.ts +2 -2
- package/dist/cjs/components/DatePicker/DatePicker.js +8 -48
- package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.d.ts +20 -0
- package/dist/cjs/components/DatePicker/hooks/useDatePickerProps.js +121 -0
- package/dist/cjs/components/DatePicker/hooks/useDatePickerState.d.ts +4 -5
- package/dist/cjs/components/DatePicker/hooks/useDatePickerState.js +17 -4
- package/dist/cjs/components/DatePicker/i18n/index.js +3 -5
- package/dist/cjs/components/DatePicker/index.d.ts +1 -0
- package/dist/cjs/components/DatePicker/index.js +4 -16
- package/dist/cjs/components/RelativeDateField/RelativeDateField.js +2 -4
- package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldProps.js +2 -4
- package/dist/cjs/components/RelativeDateField/hooks/useRelativeDateFieldState.js +2 -4
- package/dist/cjs/components/RelativeDateField/index.js +4 -17
- package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.css +1 -0
- package/dist/cjs/components/RelativeDatePicker/RelativeDatePicker.js +2 -4
- package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +32 -43
- package/dist/cjs/components/RelativeDatePicker/hooks/useRelativeDatePickerState.js +2 -4
- package/dist/cjs/components/RelativeDatePicker/i18n/index.js +3 -5
- package/dist/cjs/components/RelativeDatePicker/index.js +4 -17
- package/dist/cjs/components/hooks/useControlledState.js +2 -4
- package/dist/cjs/components/index.js +6 -19
- package/dist/cjs/index.js +2 -15
- package/dist/esm/components/Calendar/Calendar.css +37 -37
- package/dist/esm/components/Calendar/hooks/useCalendarGridProps.js +11 -0
- package/dist/esm/components/Calendar/hooks/useRangeCalendarState.js +11 -16
- package/dist/esm/components/DateField/DateField.js +1 -11
- package/dist/esm/components/DateField/hooks/useDateFieldProps.js +24 -17
- package/dist/esm/components/DateField/hooks/useDateFieldState.js +19 -161
- package/dist/esm/components/DateField/utils.d.ts +14 -3
- package/dist/esm/components/DateField/utils.js +165 -2
- package/dist/esm/components/DatePicker/DatePicker.css +6 -0
- package/dist/esm/components/DatePicker/DatePicker.d.ts +2 -2
- package/dist/esm/components/DatePicker/DatePicker.js +9 -46
- package/dist/esm/components/DatePicker/hooks/useDatePickerProps.d.ts +20 -0
- package/dist/esm/components/DatePicker/hooks/useDatePickerProps.js +117 -0
- package/dist/esm/components/DatePicker/hooks/useDatePickerState.d.ts +4 -5
- package/dist/esm/components/DatePicker/hooks/useDatePickerState.js +15 -0
- package/dist/esm/components/DatePicker/index.d.ts +1 -0
- package/dist/esm/components/DatePicker/index.js +1 -0
- package/dist/esm/components/RelativeDatePicker/RelativeDatePicker.css +1 -0
- package/dist/esm/components/RelativeDatePicker/hooks/useRelativeDatePickerProps.js +30 -38
- package/package.json +37 -33
- package/dist/cjs/components/DatePicker/DesktopCalendar.d.ts +0 -17
- package/dist/cjs/components/DatePicker/DesktopCalendar.js +0 -65
- package/dist/esm/components/DatePicker/DesktopCalendar.d.ts +0 -17
- package/dist/esm/components/DatePicker/DesktopCalendar.js +0 -57
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.useDateFieldState = void 0;
|
|
7
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
8
6
|
const date_utils_1 = require("@gravity-ui/date-utils");
|
|
9
7
|
const useControlledState_1 = require("../../hooks/useControlledState");
|
|
10
8
|
const dates_1 = require("../../utils/dates");
|
|
@@ -19,11 +17,6 @@ const EDITABLE_SEGMENTS = {
|
|
|
19
17
|
dayPeriod: true,
|
|
20
18
|
weekday: true,
|
|
21
19
|
};
|
|
22
|
-
const TYPE_MAPPING = {
|
|
23
|
-
weekday: 'day',
|
|
24
|
-
day: 'date',
|
|
25
|
-
dayPeriod: 'hour',
|
|
26
|
-
};
|
|
27
20
|
const PAGE_STEP = {
|
|
28
21
|
year: 5,
|
|
29
22
|
month: 2,
|
|
@@ -69,10 +62,7 @@ function useDateFieldState(props) {
|
|
|
69
62
|
? value
|
|
70
63
|
: placeholderDate;
|
|
71
64
|
const sectionsState = useSectionsState(sections, displayValue, validSegments);
|
|
72
|
-
const [selectedSections, setSelectedSections] = react_1.default.useState(
|
|
73
|
-
var _a, _b;
|
|
74
|
-
return (_b = (_a = sectionsState.editableSections[0]) === null || _a === void 0 ? void 0 : _a.previousEditableSection) !== null && _b !== void 0 ? _b : -1;
|
|
75
|
-
});
|
|
65
|
+
const [selectedSections, setSelectedSections] = react_1.default.useState(-1);
|
|
76
66
|
const selectedSectionIndexes = react_1.default.useMemo(() => {
|
|
77
67
|
if (selectedSections === -1) {
|
|
78
68
|
return null;
|
|
@@ -97,9 +87,14 @@ function useDateFieldState(props) {
|
|
|
97
87
|
return;
|
|
98
88
|
}
|
|
99
89
|
if (Object.keys(validSegments).length >= Object.keys(allSegments).length) {
|
|
100
|
-
|
|
90
|
+
if (!value || !newValue.isSame(value)) {
|
|
91
|
+
setDate(newValue);
|
|
92
|
+
}
|
|
101
93
|
}
|
|
102
94
|
else {
|
|
95
|
+
if (value) {
|
|
96
|
+
setDate(null);
|
|
97
|
+
}
|
|
103
98
|
setPlaceholderDate(newValue);
|
|
104
99
|
}
|
|
105
100
|
}
|
|
@@ -115,12 +110,12 @@ function useDateFieldState(props) {
|
|
|
115
110
|
}
|
|
116
111
|
function setSection(section, amount) {
|
|
117
112
|
markValid(section.type);
|
|
118
|
-
setValue(setSegment(section, displayValue, amount));
|
|
113
|
+
setValue((0, utils_1.setSegment)(section, displayValue, amount));
|
|
119
114
|
}
|
|
120
115
|
function adjustSection(sectionIndex, amount) {
|
|
121
116
|
const section = sectionsState.editableSections[sectionIndex];
|
|
122
117
|
if (validSegments[section.type]) {
|
|
123
|
-
setValue(addSegment(section, displayValue, amount));
|
|
118
|
+
setValue((0, utils_1.addSegment)(section, displayValue, amount));
|
|
124
119
|
}
|
|
125
120
|
else {
|
|
126
121
|
markValid(section.type);
|
|
@@ -138,7 +133,8 @@ function useDateFieldState(props) {
|
|
|
138
133
|
isEmpty: Object.keys(validSegments).length === 0,
|
|
139
134
|
displayValue,
|
|
140
135
|
setValue,
|
|
141
|
-
|
|
136
|
+
// use ltr direction context to get predictable navigation inside input
|
|
137
|
+
text: '\u2066' + sectionsState.editableSections.map((s) => s.textValue).join('') + '\u2069',
|
|
142
138
|
readOnly: props.readOnly,
|
|
143
139
|
disabled: props.disabled,
|
|
144
140
|
sections: sectionsState.editableSections,
|
|
@@ -285,12 +281,9 @@ function useDateFieldState(props) {
|
|
|
285
281
|
}
|
|
286
282
|
}
|
|
287
283
|
else {
|
|
288
|
-
const type = getDurationUnitFromSectionType(section.type);
|
|
284
|
+
const type = (0, utils_1.getDurationUnitFromSectionType)(section.type);
|
|
289
285
|
currentValue = displayValue.set(type, placeholder[type]());
|
|
290
286
|
}
|
|
291
|
-
if (value) {
|
|
292
|
-
setDate(null);
|
|
293
|
-
}
|
|
294
287
|
setValue(currentValue);
|
|
295
288
|
},
|
|
296
289
|
clearAll() {
|
|
@@ -308,7 +301,6 @@ function useDateFieldState(props) {
|
|
|
308
301
|
timeZone: props.timeZone,
|
|
309
302
|
}));
|
|
310
303
|
},
|
|
311
|
-
// eslint-disable-next-line complexity
|
|
312
304
|
onInput(key) {
|
|
313
305
|
if (this.readOnly || this.disabled) {
|
|
314
306
|
return;
|
|
@@ -417,6 +409,7 @@ function useDateFieldState(props) {
|
|
|
417
409
|
}
|
|
418
410
|
},
|
|
419
411
|
setValueFromString(str) {
|
|
412
|
+
enteredKeys.current = '';
|
|
420
413
|
let date = parseDate({ input: str, format, timeZone: props.timeZone });
|
|
421
414
|
if ((0, date_utils_1.isValid)(date)) {
|
|
422
415
|
if (props.timeZone && !isDateStringWithTimeZone(str)) {
|
|
@@ -441,64 +434,6 @@ function parseDate(options) {
|
|
|
441
434
|
function isDateStringWithTimeZone(str) {
|
|
442
435
|
return /z$/i.test(str) || /[+-]\d\d:\d\d$/.test(str);
|
|
443
436
|
}
|
|
444
|
-
function addSegment(section, date, amount) {
|
|
445
|
-
var _a;
|
|
446
|
-
let val = (_a = section.value) !== null && _a !== void 0 ? _a : 0;
|
|
447
|
-
if (section.type === 'dayPeriod') {
|
|
448
|
-
val = date.hour() + (date.hour() > 12 ? -12 : 12);
|
|
449
|
-
}
|
|
450
|
-
else {
|
|
451
|
-
val = val + amount;
|
|
452
|
-
const min = section.minValue;
|
|
453
|
-
const max = section.maxValue;
|
|
454
|
-
if (typeof min === 'number' && typeof max === 'number') {
|
|
455
|
-
const length = max - min + 1;
|
|
456
|
-
val = ((val - min + length) % length) + min;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
const type = getDurationUnitFromSectionType(section.type);
|
|
460
|
-
return date.set(type, val);
|
|
461
|
-
}
|
|
462
|
-
function setSegment(section, date, amount) {
|
|
463
|
-
const type = section.type;
|
|
464
|
-
switch (type) {
|
|
465
|
-
case 'day':
|
|
466
|
-
case 'weekday':
|
|
467
|
-
case 'month':
|
|
468
|
-
case 'year': {
|
|
469
|
-
return date.set(getDurationUnitFromSectionType(type), amount);
|
|
470
|
-
}
|
|
471
|
-
case 'dayPeriod': {
|
|
472
|
-
const hours = date.hour();
|
|
473
|
-
const wasPM = hours >= 12;
|
|
474
|
-
const isPM = amount >= 12;
|
|
475
|
-
if (isPM === wasPM) {
|
|
476
|
-
return date;
|
|
477
|
-
}
|
|
478
|
-
return date.set('hour', wasPM ? hours - 12 : hours + 12);
|
|
479
|
-
}
|
|
480
|
-
case 'hour': {
|
|
481
|
-
// In 12 hour time, ensure that AM/PM does not change
|
|
482
|
-
let sectionAmount = amount;
|
|
483
|
-
if (section.minValue === 12 || section.maxValue === 11) {
|
|
484
|
-
const hours = date.hour();
|
|
485
|
-
const wasPM = hours >= 12;
|
|
486
|
-
if (!wasPM && sectionAmount === 12) {
|
|
487
|
-
sectionAmount = 0;
|
|
488
|
-
}
|
|
489
|
-
if (wasPM && sectionAmount < 12) {
|
|
490
|
-
sectionAmount += 12;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
return date.set('hour', sectionAmount);
|
|
494
|
-
}
|
|
495
|
-
case 'minute':
|
|
496
|
-
case 'second': {
|
|
497
|
-
return date.set(type, amount);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
return date;
|
|
501
|
-
}
|
|
502
437
|
function getCurrentEditableSectionIndex(sections, selectedSections) {
|
|
503
438
|
const currentIndex = selectedSections === 'all' || selectedSections === -1 ? 0 : selectedSections;
|
|
504
439
|
const section = sections[currentIndex];
|
|
@@ -539,7 +474,7 @@ function useSectionsState(sections, value, validSegments) {
|
|
|
539
474
|
return state;
|
|
540
475
|
}
|
|
541
476
|
function getEditableSections(sections, value, validSegments) {
|
|
542
|
-
let position =
|
|
477
|
+
let position = 1;
|
|
543
478
|
const newSections = [];
|
|
544
479
|
let previousEditableSection = -1;
|
|
545
480
|
for (let i = 0; i < sections.length; i++) {
|
|
@@ -548,9 +483,15 @@ function getEditableSections(sections, value, validSegments) {
|
|
|
548
483
|
let renderedValue = section.placeholder;
|
|
549
484
|
if ((isEditable && validSegments[section.type]) || section.type === 'timeZoneName') {
|
|
550
485
|
renderedValue = value.format(section.format);
|
|
486
|
+
if (section.contentType === 'digit' &&
|
|
487
|
+
renderedValue.length < section.placeholder.length) {
|
|
488
|
+
renderedValue = renderedValue.padStart(section.placeholder.length, '0');
|
|
489
|
+
}
|
|
551
490
|
}
|
|
491
|
+
// use bidirectional context to allow the browser autodetect text direction
|
|
492
|
+
renderedValue = '\u2068' + renderedValue + '\u2069';
|
|
552
493
|
const sectionLength = renderedValue.length;
|
|
553
|
-
const newSection = Object.assign(Object.assign(Object.assign({}, section), { value:
|
|
494
|
+
const newSection = Object.assign(Object.assign(Object.assign({}, section), { value: (0, utils_1.getSectionValue)(section, value), textValue: renderedValue, start: position, end: position + sectionLength, modified: false, previousEditableSection, nextEditableSection: previousEditableSection }), (0, utils_1.getSectionLimits)(section, value));
|
|
554
495
|
newSections.push(newSection);
|
|
555
496
|
if (isEditable) {
|
|
556
497
|
for (let j = Math.max(0, previousEditableSection); j <= i; j++) {
|
|
@@ -568,88 +509,3 @@ function getEditableSections(sections, value, validSegments) {
|
|
|
568
509
|
}
|
|
569
510
|
return newSections;
|
|
570
511
|
}
|
|
571
|
-
function getValue(date, type) {
|
|
572
|
-
switch (type) {
|
|
573
|
-
case 'year':
|
|
574
|
-
case 'month':
|
|
575
|
-
case 'hour':
|
|
576
|
-
case 'minute':
|
|
577
|
-
case 'second': {
|
|
578
|
-
return date[type]();
|
|
579
|
-
}
|
|
580
|
-
case 'day': {
|
|
581
|
-
return date.date();
|
|
582
|
-
}
|
|
583
|
-
case 'weekday': {
|
|
584
|
-
return date.day();
|
|
585
|
-
}
|
|
586
|
-
case 'dayPeriod': {
|
|
587
|
-
return date.hour() >= 12 ? 12 : 0;
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
return undefined;
|
|
591
|
-
}
|
|
592
|
-
function isHour12(section) {
|
|
593
|
-
if (section.type === 'hour') {
|
|
594
|
-
return (0, date_utils_1.dateTime)().set('hour', 15).format(section.format) !== '15';
|
|
595
|
-
}
|
|
596
|
-
return false;
|
|
597
|
-
}
|
|
598
|
-
function getSectionLimits(date, type, options) {
|
|
599
|
-
switch (type) {
|
|
600
|
-
case 'year': {
|
|
601
|
-
return {
|
|
602
|
-
minValue: 1,
|
|
603
|
-
maxValue: 9999,
|
|
604
|
-
};
|
|
605
|
-
}
|
|
606
|
-
case 'month': {
|
|
607
|
-
return {
|
|
608
|
-
minValue: 0,
|
|
609
|
-
maxValue: 11,
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
|
-
case 'weekday': {
|
|
613
|
-
return {
|
|
614
|
-
minValue: 0,
|
|
615
|
-
maxValue: 6,
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
case 'day': {
|
|
619
|
-
return {
|
|
620
|
-
minValue: 1,
|
|
621
|
-
maxValue: date ? date.daysInMonth() : 31,
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
case 'hour': {
|
|
625
|
-
if (options.hour12) {
|
|
626
|
-
const isPM = date.hour() >= 12;
|
|
627
|
-
return {
|
|
628
|
-
minValue: isPM ? 12 : 0,
|
|
629
|
-
maxValue: isPM ? 23 : 11,
|
|
630
|
-
};
|
|
631
|
-
}
|
|
632
|
-
return {
|
|
633
|
-
minValue: 0,
|
|
634
|
-
maxValue: 23,
|
|
635
|
-
};
|
|
636
|
-
}
|
|
637
|
-
case 'minute':
|
|
638
|
-
case 'second': {
|
|
639
|
-
return {
|
|
640
|
-
minValue: 0,
|
|
641
|
-
maxValue: 59,
|
|
642
|
-
};
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
return {};
|
|
646
|
-
}
|
|
647
|
-
function getDurationUnitFromSectionType(type) {
|
|
648
|
-
if (type === 'literal' || type === 'timeZoneName' || type === 'unknown') {
|
|
649
|
-
throw new Error(`${type} section does not have duration unit.`);
|
|
650
|
-
}
|
|
651
|
-
if (type in TYPE_MAPPING) {
|
|
652
|
-
return TYPE_MAPPING[type];
|
|
653
|
-
}
|
|
654
|
-
return type;
|
|
655
|
-
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.i18n = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
7
5
|
const i18n_1 = require("@gravity-ui/uikit/i18n");
|
|
8
6
|
const cn_1 = require("../../../utils/cn");
|
|
9
|
-
const en_json_1 = __importDefault(require("./en.json"));
|
|
10
|
-
const ru_json_1 = __importDefault(require("./ru.json"));
|
|
7
|
+
const en_json_1 = tslib_1.__importDefault(require("./en.json"));
|
|
8
|
+
const ru_json_1 = tslib_1.__importDefault(require("./ru.json"));
|
|
11
9
|
exports.i18n = (0, i18n_1.addComponentKeysets)({ en: en_json_1.default, ru: ru_json_1.default }, `${cn_1.NAMESPACE}date-field`);
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./hooks/
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./DateField"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./hooks/useDateFieldState"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./hooks/useDateFieldProps"), exports);
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const CtrlCmd: string;
|
|
1
|
+
import type { DateTime } from '@gravity-ui/date-utils';
|
|
2
|
+
import type { DateFieldSection, DateFieldSectionType, DateFieldSectionWithoutPosition } from './types';
|
|
4
3
|
export declare function expandFormat(format: string): string;
|
|
4
|
+
export declare function getSectionLimits(section: DateFieldSectionWithoutPosition, date: DateTime): {
|
|
5
|
+
minValue: number;
|
|
6
|
+
maxValue: number;
|
|
7
|
+
} | {
|
|
8
|
+
minValue?: undefined;
|
|
9
|
+
maxValue?: undefined;
|
|
10
|
+
};
|
|
11
|
+
export declare function getSectionValue(sections: DateFieldSectionWithoutPosition, date: DateTime): number | undefined;
|
|
12
|
+
export declare function getDurationUnitFromSectionType(type: DateFieldSectionType): "year" | "month" | "day" | "date" | "hour" | "minute" | "second";
|
|
13
|
+
export declare function addSegment(section: DateFieldSection, date: DateTime, amount: number): DateTime;
|
|
14
|
+
export declare function setSegment(section: DateFieldSection, date: DateTime, amount: number): DateTime;
|
|
5
15
|
export declare function splitFormatIntoSections(format: string): DateFieldSectionWithoutPosition[];
|
|
16
|
+
export declare function cleanString(dirtyString: string): string;
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.splitFormatIntoSections = exports.
|
|
3
|
+
exports.cleanString = exports.splitFormatIntoSections = exports.setSegment = exports.addSegment = exports.getDurationUnitFromSectionType = exports.getSectionValue = exports.getSectionLimits = exports.expandFormat = void 0;
|
|
4
4
|
const date_utils_1 = require("@gravity-ui/date-utils");
|
|
5
5
|
const i18n_1 = require("./i18n");
|
|
6
|
-
exports.isMac = window.navigator.userAgent.indexOf('Macintosh') >= 0;
|
|
7
|
-
exports.CtrlCmd = exports.isMac ? 'metaKey' : 'ctrlKey';
|
|
8
6
|
function expandFormat(format) {
|
|
9
7
|
const localeFormats = date_utils_1.settings.getLocaleData().formats;
|
|
10
8
|
const getShortLocalizedFormatFromLongLocalizedFormat = (formatBis) => formatBis.replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g, (_, escapeSequence, localizedFormat) => escapeSequence || localizedFormat.slice(1));
|
|
@@ -81,6 +79,173 @@ function getDateSectionConfigFromFormatToken(formatToken) {
|
|
|
81
79
|
function isFourDigitYearFormat(format) {
|
|
82
80
|
return (0, date_utils_1.dateTime)().format(format).length === 4;
|
|
83
81
|
}
|
|
82
|
+
function isHour12(format) {
|
|
83
|
+
return (0, date_utils_1.dateTime)().set('hour', 15).format(format) !== '15';
|
|
84
|
+
}
|
|
85
|
+
function getSectionLimits(section, date) {
|
|
86
|
+
const { type, format } = section;
|
|
87
|
+
switch (type) {
|
|
88
|
+
case 'year': {
|
|
89
|
+
const isFourDigit = isFourDigitYearFormat(format);
|
|
90
|
+
return {
|
|
91
|
+
minValue: isFourDigit ? 1 : 0,
|
|
92
|
+
maxValue: isFourDigit ? 9999 : 99,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
case 'month': {
|
|
96
|
+
return {
|
|
97
|
+
minValue: 0,
|
|
98
|
+
maxValue: 11,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
case 'weekday': {
|
|
102
|
+
return {
|
|
103
|
+
minValue: 0,
|
|
104
|
+
maxValue: 6,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
case 'day': {
|
|
108
|
+
return {
|
|
109
|
+
minValue: 1,
|
|
110
|
+
maxValue: date ? date.daysInMonth() : 31,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
case 'hour': {
|
|
114
|
+
if (isHour12(format)) {
|
|
115
|
+
const isPM = date.hour() >= 12;
|
|
116
|
+
return {
|
|
117
|
+
minValue: isPM ? 12 : 0,
|
|
118
|
+
maxValue: isPM ? 23 : 11,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
minValue: 0,
|
|
123
|
+
maxValue: 23,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
case 'minute':
|
|
127
|
+
case 'second': {
|
|
128
|
+
return {
|
|
129
|
+
minValue: 0,
|
|
130
|
+
maxValue: 59,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
exports.getSectionLimits = getSectionLimits;
|
|
137
|
+
function getSectionValue(sections, date) {
|
|
138
|
+
const type = sections.type;
|
|
139
|
+
switch (type) {
|
|
140
|
+
case 'year': {
|
|
141
|
+
return isFourDigitYearFormat(sections.format)
|
|
142
|
+
? date.year()
|
|
143
|
+
: Number(date.format(sections.format));
|
|
144
|
+
}
|
|
145
|
+
case 'month':
|
|
146
|
+
case 'hour':
|
|
147
|
+
case 'minute':
|
|
148
|
+
case 'second': {
|
|
149
|
+
return date[type]();
|
|
150
|
+
}
|
|
151
|
+
case 'day': {
|
|
152
|
+
return date.date();
|
|
153
|
+
}
|
|
154
|
+
case 'weekday': {
|
|
155
|
+
return date.day();
|
|
156
|
+
}
|
|
157
|
+
case 'dayPeriod': {
|
|
158
|
+
return date.hour() >= 12 ? 12 : 0;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
exports.getSectionValue = getSectionValue;
|
|
164
|
+
const TYPE_MAPPING = {
|
|
165
|
+
weekday: 'day',
|
|
166
|
+
day: 'date',
|
|
167
|
+
dayPeriod: 'hour',
|
|
168
|
+
};
|
|
169
|
+
function getDurationUnitFromSectionType(type) {
|
|
170
|
+
if (type === 'literal' || type === 'timeZoneName' || type === 'unknown') {
|
|
171
|
+
throw new Error(`${type} section does not have duration unit.`);
|
|
172
|
+
}
|
|
173
|
+
if (type in TYPE_MAPPING) {
|
|
174
|
+
return TYPE_MAPPING[type];
|
|
175
|
+
}
|
|
176
|
+
return type;
|
|
177
|
+
}
|
|
178
|
+
exports.getDurationUnitFromSectionType = getDurationUnitFromSectionType;
|
|
179
|
+
function addSegment(section, date, amount) {
|
|
180
|
+
var _a;
|
|
181
|
+
let val = (_a = section.value) !== null && _a !== void 0 ? _a : 0;
|
|
182
|
+
if (section.type === 'dayPeriod') {
|
|
183
|
+
val = date.hour() + (date.hour() > 12 ? -12 : 12);
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
val = val + amount;
|
|
187
|
+
const min = section.minValue;
|
|
188
|
+
const max = section.maxValue;
|
|
189
|
+
if (typeof min === 'number' && typeof max === 'number') {
|
|
190
|
+
const length = max - min + 1;
|
|
191
|
+
val = ((val - min + length) % length) + min;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (section.type === 'year' && !isFourDigitYearFormat(section.format)) {
|
|
195
|
+
val = (0, date_utils_1.dateTime)({ input: `${val}`.padStart(2, '0'), format: section.format }).year();
|
|
196
|
+
}
|
|
197
|
+
const type = getDurationUnitFromSectionType(section.type);
|
|
198
|
+
return date.set(type, val);
|
|
199
|
+
}
|
|
200
|
+
exports.addSegment = addSegment;
|
|
201
|
+
function setSegment(section, date, amount) {
|
|
202
|
+
const type = section.type;
|
|
203
|
+
switch (type) {
|
|
204
|
+
case 'year': {
|
|
205
|
+
return date.set('year', isFourDigitYearFormat(section.format)
|
|
206
|
+
? amount
|
|
207
|
+
: (0, date_utils_1.dateTime)({
|
|
208
|
+
input: `${amount}`.padStart(2, '0'),
|
|
209
|
+
format: section.format,
|
|
210
|
+
}).year());
|
|
211
|
+
}
|
|
212
|
+
case 'day':
|
|
213
|
+
case 'weekday':
|
|
214
|
+
case 'month': {
|
|
215
|
+
return date.set(getDurationUnitFromSectionType(type), amount);
|
|
216
|
+
}
|
|
217
|
+
case 'dayPeriod': {
|
|
218
|
+
const hours = date.hour();
|
|
219
|
+
const wasPM = hours >= 12;
|
|
220
|
+
const isPM = amount >= 12;
|
|
221
|
+
if (isPM === wasPM) {
|
|
222
|
+
return date;
|
|
223
|
+
}
|
|
224
|
+
return date.set('hour', wasPM ? hours - 12 : hours + 12);
|
|
225
|
+
}
|
|
226
|
+
case 'hour': {
|
|
227
|
+
// In 12 hour time, ensure that AM/PM does not change
|
|
228
|
+
let sectionAmount = amount;
|
|
229
|
+
if (section.minValue === 12 || section.maxValue === 11) {
|
|
230
|
+
const hours = date.hour();
|
|
231
|
+
const wasPM = hours >= 12;
|
|
232
|
+
if (!wasPM && sectionAmount === 12) {
|
|
233
|
+
sectionAmount = 0;
|
|
234
|
+
}
|
|
235
|
+
if (wasPM && sectionAmount < 12) {
|
|
236
|
+
sectionAmount += 12;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return date.set('hour', sectionAmount);
|
|
240
|
+
}
|
|
241
|
+
case 'minute':
|
|
242
|
+
case 'second': {
|
|
243
|
+
return date.set(type, amount);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return date;
|
|
247
|
+
}
|
|
248
|
+
exports.setSegment = setSegment;
|
|
84
249
|
function doesSectionHaveLeadingZeros(contentType, sectionType, format) {
|
|
85
250
|
if (contentType !== 'digit') {
|
|
86
251
|
return false;
|
|
@@ -250,3 +415,7 @@ function getSectionOptions(section, token) {
|
|
|
250
415
|
}
|
|
251
416
|
return undefined;
|
|
252
417
|
}
|
|
418
|
+
function cleanString(dirtyString) {
|
|
419
|
+
return dirtyString.replace(/[\u2066\u2067\u2068\u2069]/g, '');
|
|
420
|
+
}
|
|
421
|
+
exports.cleanString = cleanString;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
.g-date-date-picker {
|
|
2
2
|
position: relative;
|
|
3
3
|
display: inline-block;
|
|
4
|
+
outline: none;
|
|
4
5
|
}
|
|
5
6
|
.g-date-date-picker__field {
|
|
6
7
|
width: 100%;
|
|
@@ -8,6 +9,11 @@
|
|
|
8
9
|
.g-date-date-picker__field_mobile {
|
|
9
10
|
pointer-events: none;
|
|
10
11
|
}
|
|
12
|
+
.g-date-date-picker__popup-anchor {
|
|
13
|
+
position: absolute;
|
|
14
|
+
z-index: -1;
|
|
15
|
+
inset: 0;
|
|
16
|
+
}
|
|
11
17
|
.g-date-date-picker__popup-content {
|
|
12
18
|
outline: none;
|
|
13
19
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type
|
|
2
|
+
import { type CalendarProps } from '../Calendar';
|
|
3
3
|
import type { AccessibilityProps, DateFieldBase, DomProps, FocusableProps, KeyboardEvents, StyleProps, TextInputProps } from '../types';
|
|
4
4
|
import './DatePicker.css';
|
|
5
5
|
export interface DatePickerProps extends DateFieldBase, TextInputProps, FocusableProps, KeyboardEvents, DomProps, StyleProps, AccessibilityProps {
|
|
6
6
|
children?: (props: CalendarProps) => React.ReactNode;
|
|
7
7
|
}
|
|
8
|
-
export declare function DatePicker({ value, defaultValue, onUpdate, className,
|
|
8
|
+
export declare function DatePicker({ value, defaultValue, onUpdate, className, ...props }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,66 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
3
|
exports.DatePicker = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
18
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
19
|
-
const react_1 = __importDefault(require("react"));
|
|
6
|
+
const react_1 = tslib_1.__importDefault(require("react"));
|
|
7
|
+
const icons_1 = require("@gravity-ui/icons");
|
|
20
8
|
const uikit_1 = require("@gravity-ui/uikit");
|
|
9
|
+
const Calendar_1 = require("../Calendar");
|
|
21
10
|
const DateField_1 = require("../DateField");
|
|
22
|
-
const DesktopCalendar_1 = require("./DesktopCalendar");
|
|
23
11
|
const MobileCalendar_1 = require("./MobileCalendar");
|
|
12
|
+
const useDatePickerProps_1 = require("./hooks/useDatePickerProps");
|
|
24
13
|
const useDatePickerState_1 = require("./hooks/useDatePickerState");
|
|
25
14
|
const utils_1 = require("./utils");
|
|
26
15
|
require("./DatePicker.css");
|
|
27
16
|
function DatePicker(_a) {
|
|
28
|
-
var { value, defaultValue, onUpdate, className
|
|
17
|
+
var { value, defaultValue, onUpdate, className } = _a, props = tslib_1.__rest(_a, ["value", "defaultValue", "onUpdate", "className"]);
|
|
29
18
|
const anchorRef = react_1.default.useRef(null);
|
|
30
19
|
const state = (0, useDatePickerState_1.useDatePickerState)(Object.assign(Object.assign({}, props), { value,
|
|
31
20
|
defaultValue,
|
|
32
21
|
onUpdate }));
|
|
22
|
+
const { groupProps, fieldProps, calendarButtonProps, popupProps, calendarProps, timeInputProps } = (0, useDatePickerProps_1.useDatePickerProps)(state, props);
|
|
33
23
|
const [isMobile] = (0, uikit_1.useMobile)();
|
|
34
|
-
|
|
35
|
-
const { focusWithinProps } = (0, uikit_1.useFocusWithin)({
|
|
36
|
-
onFocusWithin: onFocus,
|
|
37
|
-
onBlurWithin: onBlur,
|
|
38
|
-
onFocusWithinChange(isFocusWithin) {
|
|
39
|
-
setActive(isFocusWithin);
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
const fieldState = (0, DateField_1.useDateFieldState)({
|
|
43
|
-
value: state.value,
|
|
44
|
-
onUpdate: state.setValue,
|
|
45
|
-
disabled: state.disabled,
|
|
46
|
-
readOnly: state.readOnly,
|
|
47
|
-
validationState: props.validationState,
|
|
48
|
-
minValue: props.minValue,
|
|
49
|
-
maxValue: props.maxValue,
|
|
50
|
-
isDateUnavailable: props.isDateUnavailable,
|
|
51
|
-
format: state.format,
|
|
52
|
-
placeholderValue: props.placeholderValue,
|
|
53
|
-
timeZone: props.timeZone,
|
|
54
|
-
});
|
|
55
|
-
const { inputProps } = (0, DateField_1.useDateFieldProps)(fieldState, props);
|
|
56
|
-
return (
|
|
57
|
-
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
|
58
|
-
(0, jsx_runtime_1.jsxs)("div", Object.assign({ ref: anchorRef, className: (0, utils_1.b)(null, className), style: props.style }, focusWithinProps, { role: "group", "aria-disabled": state.disabled || undefined, onKeyDown: (e) => {
|
|
59
|
-
if (e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
|
|
60
|
-
e.preventDefault();
|
|
61
|
-
e.stopPropagation();
|
|
62
|
-
state.setOpen(true);
|
|
63
|
-
}
|
|
64
|
-
}, children: [isMobile ? ((0, jsx_runtime_1.jsx)(MobileCalendar_1.MobileCalendar, { props: props, state: state })) : ((0, jsx_runtime_1.jsx)(DesktopCalendar_1.DesktopCalendar, { anchorRef: anchorRef, props: props, state: state, renderCalendar: children })), (0, jsx_runtime_1.jsx)(uikit_1.TextInput, Object.assign({}, inputProps, { value: fieldState.isEmpty && !isActive && props.placeholder ? '' : inputProps.value, className: (0, utils_1.b)('field', { mobile: isMobile }), hasClear: !isMobile && inputProps.hasClear, rightContent: isMobile ? ((0, jsx_runtime_1.jsx)(MobileCalendar_1.MobileCalendarIcon, { props: props, state: state })) : ((0, jsx_runtime_1.jsx)(DesktopCalendar_1.DesktopCalendarButton, { props: props, state: state })) }))] })));
|
|
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 })) : ((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, rightContent: isMobile ? ((0, jsx_runtime_1.jsx)(MobileCalendar_1.MobileCalendarIcon, { props: props, state: state })) : ((0, jsx_runtime_1.jsx)(uikit_1.Button, Object.assign({}, calendarButtonProps, { children: (0, jsx_runtime_1.jsx)(uikit_1.Icon, { data: icons_1.Calendar }) }))) }))] })));
|
|
65
25
|
}
|
|
66
26
|
exports.DatePicker = DatePicker;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ButtonProps, PopupProps, TextInputProps } from '@gravity-ui/uikit';
|
|
3
|
+
import type { Calendar } from '../../Calendar';
|
|
4
|
+
import type { DateFieldProps } from '../../DateField';
|
|
5
|
+
import type { DatePickerProps } from '../DatePicker';
|
|
6
|
+
import type { DatePickerState } from './useDatePickerState';
|
|
7
|
+
interface InnerRelativeDatePickerProps {
|
|
8
|
+
groupProps: React.HTMLAttributes<unknown> & {
|
|
9
|
+
ref: React.Ref<any>;
|
|
10
|
+
};
|
|
11
|
+
fieldProps: TextInputProps;
|
|
12
|
+
calendarButtonProps: ButtonProps & {
|
|
13
|
+
ref: React.Ref<HTMLButtonElement>;
|
|
14
|
+
};
|
|
15
|
+
popupProps: PopupProps;
|
|
16
|
+
calendarProps: React.ComponentProps<typeof Calendar>;
|
|
17
|
+
timeInputProps: DateFieldProps;
|
|
18
|
+
}
|
|
19
|
+
export declare function useDatePickerProps(state: DatePickerState, { onFocus, onBlur, ...props }: DatePickerProps): InnerRelativeDatePickerProps;
|
|
20
|
+
export {};
|