@skbkontur/react-ui 6.1.7-c386f.0 → 6.1.7-e032b.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/Button/Button.d.ts +1 -1
- package/components/Button/Button.js +4 -7
- package/components/Button/Button.js.map +1 -1
- package/components/FxInput/FxInputRestoreBtn.js +1 -1
- package/components/FxInput/FxInputRestoreBtn.js.map +1 -1
- package/components/Switcher/Switcher.js +0 -2
- package/components/Switcher/Switcher.js.map +1 -1
- package/components/TimePicker/TimePicker.d.ts +24 -23
- package/components/TimePicker/TimePicker.js +196 -132
- package/components/TimePicker/TimePicker.js.map +1 -1
- package/components/TimePicker/TimePickerItems.d.ts +1 -1
- package/components/TimePicker/TimePickerItems.js +5 -8
- package/components/TimePicker/TimePickerItems.js.map +1 -1
- package/components/TimePicker/TimePickerMobilePopup.d.ts +1 -2
- package/components/TimePicker/TimePickerMobilePopup.js +3 -3
- package/components/TimePicker/TimePickerMobilePopup.js.map +1 -1
- package/components/TimePicker/TimePickerPopup.d.ts +1 -1
- package/components/TimePicker/TimePickerPopup.js +2 -2
- package/components/TimePicker/TimePickerPopup.js.map +1 -1
- package/components/TimePicker/helpers/TimePicker.constants.d.ts +2 -1
- package/components/TimePicker/helpers/TimePicker.constants.js +2 -7
- package/components/TimePicker/helpers/TimePicker.constants.js.map +1 -1
- package/components/TimePicker/helpers/TimePicker.editing.d.ts +1 -5
- package/components/TimePicker/helpers/TimePicker.editing.js +8 -35
- package/components/TimePicker/helpers/TimePicker.editing.js.map +1 -1
- package/components/TimePicker/helpers/TimePicker.shared.d.ts +13 -24
- package/components/TimePicker/helpers/TimePicker.shared.js +13 -27
- package/components/TimePicker/helpers/TimePicker.shared.js.map +1 -1
- package/components/TimePicker/helpers/TimePicker.value.d.ts +3 -13
- package/components/TimePicker/helpers/TimePicker.value.js +13 -43
- package/components/TimePicker/helpers/TimePicker.value.js.map +1 -1
- package/components/TimePicker/helpers/scrollSelectedItemIntoView.d.ts +2 -0
- package/components/TimePicker/helpers/scrollSelectedItemIntoView.js +2 -0
- package/components/TimePicker/helpers/scrollSelectedItemIntoView.js.map +1 -1
- package/components/TimePicker/helpers/validateTimePicker.js +2 -4
- package/components/TimePicker/helpers/validateTimePicker.js.map +1 -1
- package/components/TimePicker/hooks/useTimePickerDropdown.js +9 -25
- package/components/TimePicker/hooks/useTimePickerDropdown.js.map +1 -1
- package/components/TimePicker/hooks/useTimePickerSource.js +2 -1
- package/components/TimePicker/hooks/useTimePickerSource.js.map +1 -1
- package/components/TimePicker/hooks/useTimePickerValue.d.ts +9 -4
- package/components/TimePicker/hooks/useTimePickerValue.js +22 -23
- package/components/TimePicker/hooks/useTimePickerValue.js.map +1 -1
- package/components/TimePicker/index.d.ts +1 -1
- package/components/TimePicker/index.js.map +1 -1
- package/internal/NativeTimeInput/NativeTimeInput.utils.d.ts +2 -0
- package/internal/NativeTimeInput/NativeTimeInput.utils.js +4 -8
- package/internal/NativeTimeInput/NativeTimeInput.utils.js.map +1 -1
- package/internal/TimeInput/TimeFragments.d.ts +0 -1
- package/internal/TimeInput/TimeFragments.js +27 -6
- package/internal/TimeInput/TimeFragments.js.map +1 -1
- package/internal/TimeInput/TimeFragments.styles.d.ts +14 -0
- package/internal/TimeInput/TimeFragments.styles.js +36 -9
- package/internal/TimeInput/TimeFragments.styles.js.map +1 -1
- package/internal/TimeInput/TimeInput.d.ts +0 -1
- package/internal/TimeInput/TimeInput.js +0 -1
- package/internal/TimeInput/TimeInput.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import warning from 'warning';
|
|
2
2
|
import { DIGIT_REGEXP, EMPTY_SEGMENT, EMPTY_VALUE, NON_DIGIT_REGEXP, TIME_LIKE_DIGITS_REGEXP, TIME_LIKE_SEGMENTS_REGEXP, TIME_SEPARATOR, ZERO_PAD_CHAR, } from './TimePicker.constants.js';
|
|
3
3
|
import { getDigits, getDisplaySegments, getTimeSegments, normalizeTimeSegment, sanitizeSegment, getTimeItemLabel, getTimeItemValue, isTimeItemDisabled, isTimeItem, isTimeItemObject, } from './TimePicker.shared.js';
|
|
4
|
-
/** Проверяет,
|
|
4
|
+
/** Проверяет, что в display-значении нет ни одной введенной цифры. */
|
|
5
5
|
export var isTimeDisplayEmpty = function (value) { return !DIGIT_REGEXP.test(value); };
|
|
6
|
-
/** Приводит значение поля — элемент, строку или пустое значение — к строке времени. */
|
|
7
6
|
export var getTimeValueString = function (value) {
|
|
8
7
|
if (value === null || value === undefined) {
|
|
9
8
|
return EMPTY_VALUE;
|
|
@@ -58,26 +57,6 @@ export var sanitizeTimeItems = function (items, format) {
|
|
|
58
57
|
return true;
|
|
59
58
|
});
|
|
60
59
|
};
|
|
61
|
-
/**
|
|
62
|
-
* Оставляет в списке только первый элемент для каждого времени.
|
|
63
|
-
* Времена сравниваются после нормализации к текущему формату,
|
|
64
|
-
* поэтому в формате `HH:mm` элементы `12:00` и `12:00:30` считаются одинаковыми.
|
|
65
|
-
* React-элементы не участвуют в сравнении и остаются на своих местах.
|
|
66
|
-
*/
|
|
67
|
-
export var dedupeTimeItems = function (items, format) {
|
|
68
|
-
var usedValues = new Set();
|
|
69
|
-
return items.filter(function (item) {
|
|
70
|
-
if (!isTimeItem(item)) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
var normalizedValue = normalizeTimeValue(getTimeItemValue(item), format);
|
|
74
|
-
if (usedValues.has(normalizedValue)) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
usedValues.add(normalizedValue);
|
|
78
|
-
return true;
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
60
|
/**
|
|
82
61
|
* Проверяет, выходит ли значение за диапазон `minTime`/`maxTime` после нормализации.
|
|
83
62
|
* Пустое значение не считается выходящим за диапазон. Если `minTime > maxTime`, диапазон трактуется как переходящий через полночь.
|
|
@@ -116,24 +95,21 @@ var normalizeTimeRangeValue = function (value, format) {
|
|
|
116
95
|
return normalizedValue === EMPTY_VALUE ? undefined : normalizedValue;
|
|
117
96
|
};
|
|
118
97
|
/**
|
|
119
|
-
* Преобразует display-значение в
|
|
98
|
+
* Преобразует display-значение в промежуточное значение для `onInputValueChange`.
|
|
120
99
|
* Заполненные сегменты дополняются до двух цифр, пропущенные сегменты до последнего заполненного становятся `00`.
|
|
121
100
|
*/
|
|
122
101
|
export var serializeTimeValue = function (value, format) {
|
|
123
|
-
var serializedSegments = getDisplaySegments(value, format).map(function (segmentValue) {
|
|
102
|
+
var serializedSegments = takeFilledSegments(getDisplaySegments(value, format).map(function (segmentValue) {
|
|
124
103
|
var digits = getDigits(segmentValue);
|
|
125
|
-
return digits ? digits.padStart(EMPTY_SEGMENT.length,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return
|
|
132
|
-
|
|
133
|
-
.map(function (segmentValue) { return segmentValue || '00'; })
|
|
134
|
-
.join(TIME_SEPARATOR);
|
|
104
|
+
return digits ? digits.padStart(EMPTY_SEGMENT.length, ZERO_PAD_CHAR) : EMPTY_VALUE;
|
|
105
|
+
}));
|
|
106
|
+
return serializedSegments.map(function (segmentValue) { return segmentValue || '00'; }).join(TIME_SEPARATOR);
|
|
107
|
+
};
|
|
108
|
+
/** Отбрасывает незаполненный хвост сегментов: ведущие пустые сегменты остаются на своих местах. */
|
|
109
|
+
var takeFilledSegments = function (segments) {
|
|
110
|
+
var lastFilledIndex = segments.reduce(function (result, segmentValue, index) { return (segmentValue ? index : result); }, -1);
|
|
111
|
+
return segments.slice(0, lastFilledIndex + 1);
|
|
135
112
|
};
|
|
136
|
-
/** Возвращает display-значение с плейсхолдерами из partial или committed value. */
|
|
137
113
|
export var getTimeDisplayValue = function (value, format) {
|
|
138
114
|
if (value === EMPTY_VALUE) {
|
|
139
115
|
return EMPTY_VALUE;
|
|
@@ -196,7 +172,6 @@ export var getTimeSegmentValue = function (value, segment, format) {
|
|
|
196
172
|
var index = getTimeSegments(format).indexOf(segment);
|
|
197
173
|
return (_a = segments[index]) !== null && _a !== void 0 ? _a : EMPTY_SEGMENT;
|
|
198
174
|
};
|
|
199
|
-
/** Возвращает полностью пустое display-значение для выбранной точности времени. */
|
|
200
175
|
export var getEmptyDisplayValue = function (precision) {
|
|
201
176
|
return getTimeSegments(precision)
|
|
202
177
|
.map(function () { return EMPTY_SEGMENT; })
|
|
@@ -209,15 +184,10 @@ export var getEmptyDisplayValue = function (precision) {
|
|
|
209
184
|
* Это нужно для посегментного сравнения в `filterTimeItems` и передается как есть в пользовательскую `source`.
|
|
210
185
|
*/
|
|
211
186
|
export var getTimeFilterQuery = function (value, format) {
|
|
212
|
-
|
|
213
|
-
var lastFilledIndex = segments.reduce(function (result, segmentValue, index) { return (segmentValue ? index : result); }, -1);
|
|
214
|
-
if (lastFilledIndex < 0) {
|
|
215
|
-
return EMPTY_VALUE;
|
|
216
|
-
}
|
|
217
|
-
return segments.slice(0, lastFilledIndex + 1).join(TIME_SEPARATOR);
|
|
187
|
+
return takeFilledSegments(getDisplaySegments(value, format).map(getDigits)).join(TIME_SEPARATOR);
|
|
218
188
|
};
|
|
219
189
|
/**
|
|
220
|
-
*
|
|
190
|
+
* Фильтрует элементы по запросу из поля ввода.
|
|
221
191
|
* Сравнивает запрос посегментно: введенные цифры сегмента должны быть префиксом соответствующего сегмента элемента.
|
|
222
192
|
* Пустой запрос возвращает все элементы.
|
|
223
193
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimePicker.value.js","sourceRoot":"","sources":["TimePicker.value.ts"],"names":[],"mappings":"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","sourcesContent":["import warning from 'warning';\n\nimport {\n DIGIT_REGEXP,\n EMPTY_SEGMENT,\n EMPTY_VALUE,\n NON_DIGIT_REGEXP,\n TIME_LIKE_DIGITS_REGEXP,\n TIME_LIKE_SEGMENTS_REGEXP,\n TIME_SEPARATOR,\n ZERO_PAD_CHAR,\n} from './TimePicker.constants.js';\nimport {\n getDigits,\n getDisplaySegments,\n getTimeSegments,\n normalizeTimeSegment,\n sanitizeSegment,\n getTimeItemLabel,\n getTimeItemValue,\n isTimeItemDisabled,\n type TimeFormat,\n type TimeItemValue,\n type TimePickerExtendedItem,\n type TimePickerMenuItem,\n type TimeSegment,\n isTimeItem,\n isTimeItemObject,\n} from './TimePicker.shared.js';\n\n/** Проверяет, содержит ли display-значение хотя бы одну введенную цифру. */\nexport const isTimeDisplayEmpty = (value: string): boolean => !DIGIT_REGEXP.test(value);\n\n/** Приводит значение поля — элемент, строку или пустое значение — к строке времени. */\nexport const getTimeValueString = (value: TimeItemValue | null | undefined): string => {\n if (value === null || value === undefined) {\n return EMPTY_VALUE;\n }\n\n return getTimeItemValue(value);\n};\n\n/**\n * Разбирает элементы источника для отрисовки: достает время и подпись,\n * а `disabled` дополняет проверкой диапазона `minTime`/`maxTime`.\n * Исходный элемент сохраняется как есть — именно он уходит в `onValueChange`.\n * React-элементы остаются на своих местах.\n */\nexport const resolveTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n format: TimeFormat,\n minTime?: string,\n maxTime?: string,\n): Array<TimePickerMenuItem<T>> =>\n items.map((item) => {\n if (!isTimeItem(item)) {\n return item;\n }\n\n const value = getTimeItemValue(item);\n\n return {\n item,\n value,\n label: getTimeItemLabel(item),\n disabled: isTimeItemDisabled(item) || isTimeValueOutOfRange(value, format, minTime, maxTime),\n };\n });\n\n/**\n * Оставляет только элементы, которые компонент умеет показать в меню.\n * Пустые значения — результат условного рендера вроде `isVisible && item` или `items.length && item` —\n * молча отбрасываются, а элементы, из которых не получается собрать время, отбрасываются с предупреждением.\n */\nexport const sanitizeTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n format: TimeFormat,\n): Array<TimePickerExtendedItem<T>> => {\n if (!Array.isArray(items)) {\n warning(false, '[TimePicker]: the source function is expected to return an array or a Promise of an array.');\n\n return [];\n }\n\n return items.filter((item) => {\n if (!item) {\n return false;\n }\n\n if (!isTimeItem(item)) {\n return true;\n }\n\n if (isTimeItemObject(item) && typeof item.value !== 'string') {\n warning(false, '[TimePicker]: a source item is expected to be a time string or an object with a time value.');\n\n return false;\n }\n\n if (normalizeTimeValue(getTimeItemValue(item), format) === EMPTY_VALUE) {\n warning(false, `[TimePicker]: the source item value \"${getTimeItemValue(item)}\" is not a time.`);\n\n return false;\n }\n\n return true;\n });\n};\n\n/**\n * Оставляет в списке только первый элемент для каждого времени.\n * Времена сравниваются после нормализации к текущему формату,\n * поэтому в формате `HH:mm` элементы `12:00` и `12:00:30` считаются одинаковыми.\n * React-элементы не участвуют в сравнении и остаются на своих местах.\n */\nexport const dedupeTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n format: TimeFormat,\n): Array<TimePickerExtendedItem<T>> => {\n const usedValues = new Set<string>();\n\n return items.filter((item) => {\n if (!isTimeItem(item)) {\n return true;\n }\n\n const normalizedValue = normalizeTimeValue(getTimeItemValue(item), format);\n\n if (usedValues.has(normalizedValue)) {\n return false;\n }\n\n usedValues.add(normalizedValue);\n\n return true;\n });\n};\n\n/**\n * Проверяет, выходит ли значение за диапазон `minTime`/`maxTime` после нормализации.\n * Пустое значение не считается выходящим за диапазон. Если `minTime > maxTime`, диапазон трактуется как переходящий через полночь.\n */\nexport const isTimeValueOutOfRange = (\n value: string,\n format: TimeFormat,\n minTime?: string,\n maxTime?: string,\n): boolean => {\n const normalizedValue = normalizeTimeValue(value, format);\n\n if (normalizedValue === EMPTY_VALUE) {\n return false;\n }\n\n const normalizedMinTime = normalizeTimeRangeValue(minTime, format);\n const normalizedMaxTime = normalizeTimeRangeValue(maxTime, format);\n\n if (normalizedMinTime && normalizedMaxTime && normalizedMinTime > normalizedMaxTime) {\n return normalizedValue < normalizedMinTime && normalizedValue > normalizedMaxTime;\n }\n\n return (\n (normalizedMinTime !== undefined && normalizedValue < normalizedMinTime) ||\n (normalizedMaxTime !== undefined && normalizedValue > normalizedMaxTime)\n );\n};\n\n/**\n * Нормализует display-значение в committed-форму `HH:mm[:ss]`.\n * Частично заполненные сегменты дополняются и ограничиваются максимумами сегментов.\n */\nexport const normalizeTimeValue = (value: string, format: TimeFormat): string => {\n if (isTimeDisplayEmpty(value)) {\n return EMPTY_VALUE;\n }\n\n const displaySegments = getDisplaySegments(value, format);\n\n return getTimeSegments(format)\n .map((segment, index) => normalizeTimeSegment(displaySegments[index], segment))\n .join(TIME_SEPARATOR);\n};\n\nconst normalizeTimeRangeValue = (value: string | undefined, format: TimeFormat): string | undefined => {\n if (!value) {\n return undefined;\n }\n\n const normalizedValue = normalizeTimeValue(value, format);\n\n return normalizedValue === EMPTY_VALUE ? undefined : normalizedValue;\n};\n\n/**\n * Преобразует display-значение в partial raw value для `onValueChange`.\n * Заполненные сегменты дополняются до двух цифр, пропущенные сегменты до последнего заполненного становятся `00`.\n */\nexport const serializeTimeValue = (value: string, format: TimeFormat): string => {\n const serializedSegments = getDisplaySegments(value, format).map((segmentValue) => {\n const digits = getDigits(segmentValue);\n\n return digits ? digits.padStart(EMPTY_SEGMENT.length, '0') : EMPTY_VALUE;\n });\n\n const lastFilledIndex = serializedSegments.reduce(\n (result, segmentValue, index) => (segmentValue ? index : result),\n -1,\n );\n\n if (lastFilledIndex < 0) {\n return EMPTY_VALUE;\n }\n\n return serializedSegments\n .slice(0, lastFilledIndex + 1)\n .map((segmentValue) => segmentValue || '00')\n .join(TIME_SEPARATOR);\n};\n\n/** Возвращает display-значение с плейсхолдерами из partial или committed value. */\nexport const getTimeDisplayValue = (value: string, format: TimeFormat): string => {\n if (value === EMPTY_VALUE) {\n return EMPTY_VALUE;\n }\n\n return getDisplaySegments(value, format).join(TIME_SEPARATOR);\n};\n\n/**\n * Возвращает display-значение внешнего `value`.\n * Сегменты, записанные одной цифрой, дополняются нулем, поэтому `9:00` показывается как `09:00` —\n * так же, как компонент показывает время элементов источника.\n * Значение без разделителя остается частично введенным: `1` — это первая цифра часов, а не `01:00`.\n */\nexport const getExternalTimeDisplayValue = (value: string, format: TimeFormat): string => {\n if (!value.includes(TIME_SEPARATOR)) {\n return getTimeDisplayValue(value, format);\n }\n\n const paddedSegments = value.split(TIME_SEPARATOR).map((segmentValue) => {\n const digits = getDigits(segmentValue);\n\n return digits ? digits.padStart(EMPTY_SEGMENT.length, ZERO_PAD_CHAR) : EMPTY_VALUE;\n });\n\n return getTimeDisplayValue(paddedSegments.join(TIME_SEPARATOR), format);\n};\n\n/** Заменяет значение выбранного сегмента, сохраняя остальные сегменты display-значения без изменений. */\nexport const replaceTimeSegment = (\n value: string,\n segment: TimeSegment,\n nextSegmentValue: string,\n format: TimeFormat,\n): string => {\n const segments = getDisplaySegments(value, format);\n const index = getTimeSegments(format).indexOf(segment);\n\n segments[index] = sanitizeSegment(nextSegmentValue);\n\n return segments.join(TIME_SEPARATOR);\n};\n\n/**\n * Проверяет, что вставленное значение похоже на время:\n * это либо сегменты из одной-двух цифр через любой разделитель — `12:30`, `9:5`, `1:23:45`, `12.30`, —\n * либо цифры подряд — `9`, `1230`, `123045`.\n * Строки, из которых время собралось бы случайно — `2026-08-01`, `hello 42`, — временем не считаются.\n */\nexport const isTimeLikePastedValue = (value: string): boolean => {\n const trimmedValue = value.trim();\n\n return TIME_LIKE_SEGMENTS_REGEXP.test(trimmedValue) || TIME_LIKE_DIGITS_REGEXP.test(trimmedValue);\n};\n\n/**\n * Парсит вставленное пользователем значение и сразу преобразует его в committed-форму.\n * Значение, не похожее на время, отдается как пустое: такую вставку компонент считает некорректным вводом.\n */\nexport const parsePastedTimeValue = (value: string, format: TimeFormat): string => {\n const trimmedValue = value.trim();\n\n if (!DIGIT_REGEXP.test(trimmedValue) || !isTimeLikePastedValue(trimmedValue)) {\n return EMPTY_VALUE;\n }\n\n // Разделители сегментов приводятся к одному виду, чтобы `9.5` разбирался так же, как `9:5`.\n const normalizedSeparators = TIME_LIKE_SEGMENTS_REGEXP.test(trimmedValue)\n ? trimmedValue.split(NON_DIGIT_REGEXP).join(TIME_SEPARATOR)\n : trimmedValue;\n\n const segments = getDisplaySegments(normalizedSeparators, format);\n\n return normalizeTimeValue(segments.join(TIME_SEPARATOR), format);\n};\n\n/** Возвращает текущее display-значение сегмента или пустой сегмент, если индекс отсутствует. */\nexport const getTimeSegmentValue = (value: string, segment: TimeSegment, format: TimeFormat): string => {\n const segments = getDisplaySegments(value, format);\n const index = getTimeSegments(format).indexOf(segment);\n\n return segments[index] ?? EMPTY_SEGMENT;\n};\n\n/** Возвращает полностью пустое display-значение для выбранной точности времени. */\nexport const getEmptyDisplayValue = (precision: TimeFormat): string =>\n getTimeSegments(precision)\n .map(() => EMPTY_SEGMENT)\n .join(TIME_SEPARATOR);\n\n/**\n * Преобразует display-значение в поисковый запрос для фильтрации элементов.\n * Сегменты содержат только введенные цифры, незаполненный хвост отбрасывается: `12:3_` => `12:3`, `1_:__` => `1`.\n * Позиции сегментов сохраняются, поэтому ведущие незаполненные сегменты остаются пустыми: `__:34` => `:34`.\n * Это нужно для посегментного сравнения в `filterTimeItems` и передается как есть в пользовательскую `source`.\n */\nexport const getTimeFilterQuery = (value: string, format: TimeFormat): string => {\n const segments = getDisplaySegments(value, format).map(getDigits);\n\n const lastFilledIndex = segments.reduce((result, segmentValue, index) => (segmentValue ? index : result), -1);\n\n if (lastFilledIndex < 0) {\n return EMPTY_VALUE;\n }\n\n return segments.slice(0, lastFilledIndex + 1).join(TIME_SEPARATOR);\n};\n\n/**\n * Дефолтная функция фильтрации элементов по запросу из поля ввода.\n * Сравнивает запрос посегментно: введенные цифры сегмента должны быть префиксом соответствующего сегмента элемента.\n * Пустой запрос возвращает все элементы.\n */\nexport const filterTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n query: string,\n format: TimeFormat,\n): Array<TimePickerExtendedItem<T>> => {\n const querySegments = query.split(TIME_SEPARATOR).map(getDigits);\n\n if (querySegments.every((segmentValue) => !segmentValue)) {\n return items;\n }\n\n return items.filter((item) => {\n if (!isTimeItem(item)) {\n return true;\n }\n\n const itemSegments = getDisplaySegments(normalizeTimeValue(getTimeItemValue(item), format), format);\n\n return querySegments.every(\n (segmentValue, index) => !segmentValue || (itemSegments[index] ?? EMPTY_VALUE).startsWith(segmentValue),\n );\n });\n};\n"]}
|
|
1
|
+
{"version":3,"file":"TimePicker.value.js","sourceRoot":"","sources":["TimePicker.value.ts"],"names":[],"mappings":"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","sourcesContent":["import warning from 'warning';\n\nimport {\n DIGIT_REGEXP,\n EMPTY_SEGMENT,\n EMPTY_VALUE,\n NON_DIGIT_REGEXP,\n TIME_LIKE_DIGITS_REGEXP,\n TIME_LIKE_SEGMENTS_REGEXP,\n TIME_SEPARATOR,\n ZERO_PAD_CHAR,\n} from './TimePicker.constants.js';\nimport {\n getDigits,\n getDisplaySegments,\n getTimeSegments,\n normalizeTimeSegment,\n sanitizeSegment,\n getTimeItemLabel,\n getTimeItemValue,\n isTimeItemDisabled,\n type TimeFormat,\n type TimeItemValue,\n type TimePickerExtendedItem,\n type TimePickerMenuItem,\n type TimeSegment,\n isTimeItem,\n isTimeItemObject,\n} from './TimePicker.shared.js';\n\n/** Проверяет, что в display-значении нет ни одной введенной цифры. */\nexport const isTimeDisplayEmpty = (value: string): boolean => !DIGIT_REGEXP.test(value);\n\nexport const getTimeValueString = (value: TimeItemValue | null | undefined): string => {\n if (value === null || value === undefined) {\n return EMPTY_VALUE;\n }\n\n return getTimeItemValue(value);\n};\n\n/**\n * Разбирает элементы источника для отрисовки: достает время и подпись,\n * а `disabled` дополняет проверкой диапазона `minTime`/`maxTime`.\n * Исходный элемент сохраняется как есть — именно он уходит в `onValueChange`.\n * React-элементы остаются на своих местах.\n */\nexport const resolveTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n format: TimeFormat,\n minTime?: string,\n maxTime?: string,\n): Array<TimePickerMenuItem<T>> =>\n items.map((item) => {\n if (!isTimeItem(item)) {\n return item;\n }\n\n const value = getTimeItemValue(item);\n\n return {\n item,\n value,\n label: getTimeItemLabel(item),\n disabled: isTimeItemDisabled(item) || isTimeValueOutOfRange(value, format, minTime, maxTime),\n };\n });\n\n/**\n * Оставляет только элементы, которые компонент умеет показать в меню.\n * Пустые значения — результат условного рендера вроде `isVisible && item` или `items.length && item` —\n * молча отбрасываются, а элементы, из которых не получается собрать время, отбрасываются с предупреждением.\n */\nexport const sanitizeTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n format: TimeFormat,\n): Array<TimePickerExtendedItem<T>> => {\n if (!Array.isArray(items)) {\n warning(false, '[TimePicker]: the source function is expected to return an array or a Promise of an array.');\n\n return [];\n }\n\n return items.filter((item) => {\n if (!item) {\n return false;\n }\n\n if (!isTimeItem(item)) {\n return true;\n }\n\n if (isTimeItemObject(item) && typeof item.value !== 'string') {\n warning(false, '[TimePicker]: a source item is expected to be a time string or an object with a time value.');\n\n return false;\n }\n\n if (normalizeTimeValue(getTimeItemValue(item), format) === EMPTY_VALUE) {\n warning(false, `[TimePicker]: the source item value \"${getTimeItemValue(item)}\" is not a time.`);\n\n return false;\n }\n\n return true;\n });\n};\n\n/**\n * Проверяет, выходит ли значение за диапазон `minTime`/`maxTime` после нормализации.\n * Пустое значение не считается выходящим за диапазон. Если `minTime > maxTime`, диапазон трактуется как переходящий через полночь.\n */\nexport const isTimeValueOutOfRange = (\n value: string,\n format: TimeFormat,\n minTime?: string,\n maxTime?: string,\n): boolean => {\n const normalizedValue = normalizeTimeValue(value, format);\n\n if (normalizedValue === EMPTY_VALUE) {\n return false;\n }\n\n const normalizedMinTime = normalizeTimeRangeValue(minTime, format);\n const normalizedMaxTime = normalizeTimeRangeValue(maxTime, format);\n\n if (normalizedMinTime && normalizedMaxTime && normalizedMinTime > normalizedMaxTime) {\n return normalizedValue < normalizedMinTime && normalizedValue > normalizedMaxTime;\n }\n\n return (\n (normalizedMinTime !== undefined && normalizedValue < normalizedMinTime) ||\n (normalizedMaxTime !== undefined && normalizedValue > normalizedMaxTime)\n );\n};\n\n/**\n * Нормализует display-значение в committed-форму `HH:mm[:ss]`.\n * Частично заполненные сегменты дополняются и ограничиваются максимумами сегментов.\n */\nexport const normalizeTimeValue = (value: string, format: TimeFormat): string => {\n if (isTimeDisplayEmpty(value)) {\n return EMPTY_VALUE;\n }\n\n const displaySegments = getDisplaySegments(value, format);\n\n return getTimeSegments(format)\n .map((segment, index) => normalizeTimeSegment(displaySegments[index], segment))\n .join(TIME_SEPARATOR);\n};\n\nconst normalizeTimeRangeValue = (value: string | undefined, format: TimeFormat): string | undefined => {\n if (!value) {\n return undefined;\n }\n\n const normalizedValue = normalizeTimeValue(value, format);\n\n return normalizedValue === EMPTY_VALUE ? undefined : normalizedValue;\n};\n\n/**\n * Преобразует display-значение в промежуточное значение для `onInputValueChange`.\n * Заполненные сегменты дополняются до двух цифр, пропущенные сегменты до последнего заполненного становятся `00`.\n */\nexport const serializeTimeValue = (value: string, format: TimeFormat): string => {\n const serializedSegments = takeFilledSegments(\n getDisplaySegments(value, format).map((segmentValue) => {\n const digits = getDigits(segmentValue);\n\n return digits ? digits.padStart(EMPTY_SEGMENT.length, ZERO_PAD_CHAR) : EMPTY_VALUE;\n }),\n );\n\n return serializedSegments.map((segmentValue) => segmentValue || '00').join(TIME_SEPARATOR);\n};\n\n/** Отбрасывает незаполненный хвост сегментов: ведущие пустые сегменты остаются на своих местах. */\nconst takeFilledSegments = (segments: string[]): string[] => {\n const lastFilledIndex = segments.reduce((result, segmentValue, index) => (segmentValue ? index : result), -1);\n\n return segments.slice(0, lastFilledIndex + 1);\n};\n\nexport const getTimeDisplayValue = (value: string, format: TimeFormat): string => {\n if (value === EMPTY_VALUE) {\n return EMPTY_VALUE;\n }\n\n return getDisplaySegments(value, format).join(TIME_SEPARATOR);\n};\n\n/**\n * Возвращает display-значение внешнего `value`.\n * Сегменты, записанные одной цифрой, дополняются нулем, поэтому `9:00` показывается как `09:00` —\n * так же, как компонент показывает время элементов источника.\n * Значение без разделителя остается частично введенным: `1` — это первая цифра часов, а не `01:00`.\n */\nexport const getExternalTimeDisplayValue = (value: string, format: TimeFormat): string => {\n if (!value.includes(TIME_SEPARATOR)) {\n return getTimeDisplayValue(value, format);\n }\n\n const paddedSegments = value.split(TIME_SEPARATOR).map((segmentValue) => {\n const digits = getDigits(segmentValue);\n\n return digits ? digits.padStart(EMPTY_SEGMENT.length, ZERO_PAD_CHAR) : EMPTY_VALUE;\n });\n\n return getTimeDisplayValue(paddedSegments.join(TIME_SEPARATOR), format);\n};\n\n/** Заменяет значение выбранного сегмента, сохраняя остальные сегменты display-значения без изменений. */\nexport const replaceTimeSegment = (\n value: string,\n segment: TimeSegment,\n nextSegmentValue: string,\n format: TimeFormat,\n): string => {\n const segments = getDisplaySegments(value, format);\n const index = getTimeSegments(format).indexOf(segment);\n\n segments[index] = sanitizeSegment(nextSegmentValue);\n\n return segments.join(TIME_SEPARATOR);\n};\n\n/**\n * Проверяет, что вставленное значение похоже на время:\n * это либо сегменты из одной-двух цифр через любой разделитель — `12:30`, `9:5`, `1:23:45`, `12.30`, —\n * либо цифры подряд — `9`, `1230`, `123045`.\n * Строки, из которых время собралось бы случайно — `2026-08-01`, `hello 42`, — временем не считаются.\n */\nexport const isTimeLikePastedValue = (value: string): boolean => {\n const trimmedValue = value.trim();\n\n return TIME_LIKE_SEGMENTS_REGEXP.test(trimmedValue) || TIME_LIKE_DIGITS_REGEXP.test(trimmedValue);\n};\n\n/**\n * Парсит вставленное пользователем значение и сразу преобразует его в committed-форму.\n * Значение, не похожее на время, отдается как пустое: такую вставку компонент считает некорректным вводом.\n */\nexport const parsePastedTimeValue = (value: string, format: TimeFormat): string => {\n const trimmedValue = value.trim();\n\n if (!DIGIT_REGEXP.test(trimmedValue) || !isTimeLikePastedValue(trimmedValue)) {\n return EMPTY_VALUE;\n }\n\n // Разделители сегментов приводятся к одному виду, чтобы `9.5` разбирался так же, как `9:5`.\n const normalizedSeparators = TIME_LIKE_SEGMENTS_REGEXP.test(trimmedValue)\n ? trimmedValue.split(NON_DIGIT_REGEXP).join(TIME_SEPARATOR)\n : trimmedValue;\n\n const segments = getDisplaySegments(normalizedSeparators, format);\n\n return normalizeTimeValue(segments.join(TIME_SEPARATOR), format);\n};\n\n/** Возвращает текущее display-значение сегмента или пустой сегмент, если индекс отсутствует. */\nexport const getTimeSegmentValue = (value: string, segment: TimeSegment, format: TimeFormat): string => {\n const segments = getDisplaySegments(value, format);\n const index = getTimeSegments(format).indexOf(segment);\n\n return segments[index] ?? EMPTY_SEGMENT;\n};\n\nexport const getEmptyDisplayValue = (precision: TimeFormat): string =>\n getTimeSegments(precision)\n .map(() => EMPTY_SEGMENT)\n .join(TIME_SEPARATOR);\n\n/**\n * Преобразует display-значение в поисковый запрос для фильтрации элементов.\n * Сегменты содержат только введенные цифры, незаполненный хвост отбрасывается: `12:3_` => `12:3`, `1_:__` => `1`.\n * Позиции сегментов сохраняются, поэтому ведущие незаполненные сегменты остаются пустыми: `__:34` => `:34`.\n * Это нужно для посегментного сравнения в `filterTimeItems` и передается как есть в пользовательскую `source`.\n */\nexport const getTimeFilterQuery = (value: string, format: TimeFormat): string =>\n takeFilledSegments(getDisplaySegments(value, format).map(getDigits)).join(TIME_SEPARATOR);\n\n/**\n * Фильтрует элементы по запросу из поля ввода.\n * Сравнивает запрос посегментно: введенные цифры сегмента должны быть префиксом соответствующего сегмента элемента.\n * Пустой запрос возвращает все элементы.\n */\nexport const filterTimeItems = <T extends TimeItemValue>(\n items: Array<TimePickerExtendedItem<T>>,\n query: string,\n format: TimeFormat,\n): Array<TimePickerExtendedItem<T>> => {\n const querySegments = query.split(TIME_SEPARATOR).map(getDigits);\n\n if (querySegments.every((segmentValue) => !segmentValue)) {\n return items;\n }\n\n return items.filter((item) => {\n if (!isTimeItem(item)) {\n return true;\n }\n\n const itemSegments = getDisplaySegments(normalizeTimeValue(getTimeItemValue(item), format), format);\n\n return querySegments.every(\n (segmentValue, index) => !segmentValue || (itemSegments[index] ?? EMPTY_VALUE).startsWith(segmentValue),\n );\n });\n};\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Прокручивает ближайший scrollable-контейнер так, чтобы выбранный элемент оказался ближе к центру viewport контейнера.
|
|
3
|
+
* Отличается от библиотечной `scrollYCenterIntoNearestScrollable` тем, что смещение считается от текущего `scrollTop`:
|
|
4
|
+
* центр — это дельта относительно контейнера, поэтому библиотечная версия верна только для непрокрученного меню.
|
|
3
5
|
*/
|
|
4
6
|
export declare const scrollSelectedItemIntoView: (element: HTMLElement) => void;
|
|
@@ -2,6 +2,8 @@ import { findNearestScrollableParent } from '../../../lib/dom/scrollYCenterIntoN
|
|
|
2
2
|
import { getOwnerGlobalObject, isBrowser } from '../../../lib/globalObject.js';
|
|
3
3
|
/**
|
|
4
4
|
* Прокручивает ближайший scrollable-контейнер так, чтобы выбранный элемент оказался ближе к центру viewport контейнера.
|
|
5
|
+
* Отличается от библиотечной `scrollYCenterIntoNearestScrollable` тем, что смещение считается от текущего `scrollTop`:
|
|
6
|
+
* центр — это дельта относительно контейнера, поэтому библиотечная версия верна только для непрокрученного меню.
|
|
5
7
|
*/
|
|
6
8
|
export var scrollSelectedItemIntoView = function (element) {
|
|
7
9
|
var globalObject = getOwnerGlobalObject(element);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scrollSelectedItemIntoView.js","sourceRoot":"","sources":["scrollSelectedItemIntoView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,wDAAwD,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE/E
|
|
1
|
+
{"version":3,"file":"scrollSelectedItemIntoView.js","sourceRoot":"","sources":["scrollSelectedItemIntoView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,wDAAwD,CAAC;AACrG,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAE/E;;;;GAIG;AACH,MAAM,CAAC,IAAM,0BAA0B,GAAG,UAAC,OAAoB;IAC7D,IAAM,YAAY,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAEnD,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,IAAM,MAAM,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAEpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,IAAM,WAAW,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;IACpD,IAAM,UAAU,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAElD,IAAM,YAAY,GAAG,WAAW,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC;IACtD,IAAM,eAAe,GAAG,WAAW,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/D,IAAM,eAAe,GAAG,CAAC,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAE7D,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,SAAS,GAAG,eAAe,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC","sourcesContent":["import { findNearestScrollableParent } from '../../../lib/dom/scrollYCenterIntoNearestScrollable.js';\nimport { getOwnerGlobalObject, isBrowser } from '../../../lib/globalObject.js';\n\n/**\n * Прокручивает ближайший scrollable-контейнер так, чтобы выбранный элемент оказался ближе к центру viewport контейнера.\n * Отличается от библиотечной `scrollYCenterIntoNearestScrollable` тем, что смещение считается от текущего `scrollTop`:\n * центр — это дельта относительно контейнера, поэтому библиотечная версия верна только для непрокрученного меню.\n */\nexport const scrollSelectedItemIntoView = (element: HTMLElement): void => {\n const globalObject = getOwnerGlobalObject(element);\n\n if (!isBrowser(globalObject)) {\n return;\n }\n\n const parent = findNearestScrollableParent(element);\n\n if (!parent) {\n return;\n }\n\n const elementRect = element.getBoundingClientRect();\n const parentRect = parent.getBoundingClientRect();\n\n const scrollTopPos = elementRect.top - parentRect.top;\n const scrollBottomPos = elementRect.bottom - parentRect.bottom;\n const scrollCenterPos = (scrollTopPos + scrollBottomPos) / 2;\n\n if (scrollCenterPos !== 0) {\n parent.scrollTo({ top: parent.scrollTop + scrollCenterPos });\n }\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getTimeValueString, isTimeValueOutOfRange, normalizeTimeValue } from './TimePicker.value.js';
|
|
2
2
|
export var validateTimePicker = function (value, options) {
|
|
3
3
|
if (options === void 0) { options = {}; }
|
|
4
4
|
var timeValue = getTimeValueString(value);
|
|
@@ -6,9 +6,7 @@ export var validateTimePicker = function (value, options) {
|
|
|
6
6
|
return false;
|
|
7
7
|
}
|
|
8
8
|
var _a = options.format, format = _a === void 0 ? 'HH:mm' : _a, minTime = options.minTime, maxTime = options.maxTime;
|
|
9
|
-
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
9
|
+
// Нормализованное значение уже канонично, поэтому отдельная проверка display-формы не нужна.
|
|
12
10
|
if (normalizeTimeValue(timeValue, format) !== timeValue) {
|
|
13
11
|
return false;
|
|
14
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateTimePicker.js","sourceRoot":"","sources":["validateTimePicker.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"validateTimePicker.js","sourceRoot":"","sources":["validateTimePicker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAQtG,MAAM,CAAC,IAAM,kBAAkB,GAAG,UAChC,KAAkC,EAClC,OAAyC;IAAzC,wBAAA,EAAA,YAAyC;IAEzC,IAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAE5C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,IAAA,KAAuC,OAAO,OAA9B,EAAhB,MAAM,mBAAG,OAAO,KAAA,EAAE,OAAO,GAAc,OAAO,QAArB,EAAE,OAAO,GAAK,OAAO,QAAZ,CAAa;IAEvD,6FAA6F;IAC7F,IAAI,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC,CAAC","sourcesContent":["import type { Nullable } from '../../../typings/utility-types.js';\nimport type { TimeFormat, TimeItem } from './TimePicker.shared.js';\nimport { getTimeValueString, isTimeValueOutOfRange, normalizeTimeValue } from './TimePicker.value.js';\n\nexport interface TimePickerValidationOptions {\n format?: TimeFormat;\n minTime?: string;\n maxTime?: string;\n}\n\nexport const validateTimePicker = (\n value: Nullable<string | TimeItem>,\n options: TimePickerValidationOptions = {},\n): boolean => {\n const timeValue = getTimeValueString(value);\n\n if (!timeValue) {\n return false;\n }\n\n const { format = 'HH:mm', minTime, maxTime } = options;\n\n // Нормализованное значение уже канонично, поэтому отдельная проверка display-формы не нужна.\n if (normalizeTimeValue(timeValue, format) !== timeValue) {\n return false;\n }\n\n return !isTimeValueOutOfRange(timeValue, format, minTime, maxTime);\n};\n"]}
|
|
@@ -39,37 +39,21 @@ export var useTimePickerDropdown = function (options) {
|
|
|
39
39
|
});
|
|
40
40
|
}, [items]);
|
|
41
41
|
var tryNavigateItems = useCallback(function (step) {
|
|
42
|
+
var _a, _b;
|
|
42
43
|
if (!hasDropdown || !isDropdownOpened) {
|
|
43
44
|
return false;
|
|
44
45
|
}
|
|
45
|
-
var enabledIndexes = items
|
|
46
|
-
.map(function (item, index) { return ({ item: item, index: index }); })
|
|
47
|
-
.filter(function (_a) {
|
|
48
|
-
var item = _a.item;
|
|
49
|
-
return isHighlightableMenuItem(item);
|
|
50
|
-
})
|
|
51
|
-
.map(function (_a) {
|
|
52
|
-
var index = _a.index;
|
|
53
|
-
return index;
|
|
54
|
-
});
|
|
46
|
+
var enabledIndexes = items.flatMap(function (item, index) { return (isHighlightableMenuItem(item) ? index : []); });
|
|
55
47
|
if (enabledIndexes.length === 0) {
|
|
56
48
|
return false;
|
|
57
49
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
setHighlightedItemIndex(step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]);
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
var currentIndex = enabledIndexes.indexOf(highlightedItemIndex);
|
|
71
|
-
var nextEnabledIndex = enabledIndexes[currentIndex + step];
|
|
72
|
-
setHighlightedItemIndex(nextEnabledIndex !== null && nextEnabledIndex !== void 0 ? nextEnabledIndex : (step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]));
|
|
50
|
+
/**
|
|
51
|
+
* Навигация идет от выделенного элемента, а если его нет — от выбранного значения.
|
|
52
|
+
* Отсутствующий и заблокированный элементы дают `-1`, и тогда шаг вниз попадает на первый элемент,
|
|
53
|
+
* а шаг вверх выходит за начало и по фолбэку ниже уходит на последний.
|
|
54
|
+
*/
|
|
55
|
+
var currentIndex = enabledIndexes.indexOf((_a = highlightedItemIndex !== null && highlightedItemIndex !== void 0 ? highlightedItemIndex : selectedItemIndex) !== null && _a !== void 0 ? _a : -1);
|
|
56
|
+
setHighlightedItemIndex((_b = enabledIndexes[currentIndex + step]) !== null && _b !== void 0 ? _b : (step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]));
|
|
73
57
|
return true;
|
|
74
58
|
}, [hasDropdown, highlightedItemIndex, isDropdownOpened, selectedItemIndex, items]);
|
|
75
59
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTimePickerDropdown.js","sourceRoot":"","sources":["useTimePickerDropdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EACL,uBAAuB,EACvB,cAAc,GAGf,MAAM,iCAAiC,CAAC;AAwBzC,MAAM,CAAC,IAAM,qBAAqB,GAAG,UACnC,OAAwC;IAEhC,IAAA,WAAW,GACjB,OAAO,YADU,EAAE,QAAQ,GAC3B,OAAO,SADoB,EAAE,KAAK,GAClC,OAAO,MAD2B,EAAE,iBAAiB,GACrD,OAAO,kBAD8C,EAAE,gBAAgB,GACvE,OAAO,iBADgE,EAAE,gBAAgB,GACzF,OAAO,iBADkF,EAAE,mBAAmB,GAC9G,OAAO,oBADuG,CACtG;IAEJ,IAAA,KAAkD,QAAQ,CAAgB,IAAI,CAAC,EAA9E,oBAAoB,QAAA,EAAE,uBAAuB,QAAiC,CAAC;IACtF,IAAM,uBAAuB,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IAE5D,IAAM,YAAY,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,IAAI,QAAQ,EAAE,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAEjD,IAAM,aAAa,GAAG,WAAW,CAAC;QAChC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAE1B,IAAM,oBAAoB,GAAG,WAAW,CAAC;QACvC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC;QACR,IAAI,uBAAuB,CAAC,OAAO,KAAK,gBAAgB,EAAE,CAAC;YACzD,OAAO;QACT,CAAC;QAED,uBAAuB,CAAC,OAAO,GAAG,gBAAgB,CAAC;QAEnD,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;YAC9B,uBAAuB,CAAC,IAAI,CAAC,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,IAAM,qBAAqB,GAAG,KAAK,CAAC,SAAS,CAAC,UAAC,IAAI,IAAK,OAAA,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAtC,CAAsC,CAAC,CAAC;QAChG,uBAAuB,CAAC,qBAAqB,IAAI,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrF,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;IAE9B,SAAS,CAAC;QACR,uBAAuB,CAAC,UAAC,OAAO;YAC9B,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,OAAO,CAAC;YACjB,CAAC;YAED,IAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;YAE5B,OAAO,CAAC,IAAI,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;QAClE,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,IAAM,gBAAgB,GAAG,WAAW,CAClC,UAAC,IAAY
|
|
1
|
+
{"version":3,"file":"useTimePickerDropdown.js","sourceRoot":"","sources":["useTimePickerDropdown.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport {\n isHighlightableMenuItem,\n isTimeMenuItem,\n type TimeItemValue,\n type TimePickerMenuItem,\n} from '../helpers/TimePicker.shared.js';\n\ninterface UseTimePickerDropdownOptions<T extends TimeItemValue> {\n hasDropdown: boolean;\n disabled?: boolean;\n items: Array<TimePickerMenuItem<T>>;\n selectedItemIndex: number | null;\n autoHighlightKey: string | null;\n /**\n * Состоянием открытости владеет компонент: от него зависит запрос элементов,\n * а элементы, в свою очередь, нужны этому хуку для навигации.\n */\n isDropdownOpened: boolean;\n setIsDropdownOpened(isOpened: boolean): void;\n}\n\ninterface UseTimePickerDropdownResult {\n highlightedItemIndex: number | null;\n openDropdown(): void;\n closeDropdown(): void;\n resetHighlightedItem(): void;\n tryNavigateItems(step: 1 | -1): boolean;\n}\n\nexport const useTimePickerDropdown = <T extends TimeItemValue>(\n options: UseTimePickerDropdownOptions<T>,\n): UseTimePickerDropdownResult => {\n const { hasDropdown, disabled, items, selectedItemIndex, autoHighlightKey, isDropdownOpened, setIsDropdownOpened } =\n options;\n\n const [highlightedItemIndex, setHighlightedItemIndex] = useState<number | null>(null);\n const lastAutoHighlightKeyRef = useRef<string | null>(null);\n\n const openDropdown = useCallback(() => {\n if (!hasDropdown || disabled) {\n return;\n }\n\n setIsDropdownOpened(true);\n }, [disabled, hasDropdown, setIsDropdownOpened]);\n\n const closeDropdown = useCallback(() => {\n setIsDropdownOpened(false);\n setHighlightedItemIndex(null);\n }, [setIsDropdownOpened]);\n\n const resetHighlightedItem = useCallback(() => {\n setHighlightedItemIndex(null);\n }, []);\n\n useEffect(() => {\n if (lastAutoHighlightKeyRef.current === autoHighlightKey) {\n return;\n }\n\n lastAutoHighlightKeyRef.current = autoHighlightKey;\n\n if (autoHighlightKey === null) {\n setHighlightedItemIndex(null);\n return;\n }\n\n const firstEnabledItemIndex = items.findIndex((item) => isTimeMenuItem(item) && !item.disabled);\n setHighlightedItemIndex(firstEnabledItemIndex >= 0 ? firstEnabledItemIndex : null);\n }, [autoHighlightKey, items]);\n\n useEffect(() => {\n setHighlightedItemIndex((current) => {\n if (current === null) {\n return current;\n }\n\n const item = items[current];\n\n return !item || !isHighlightableMenuItem(item) ? null : current;\n });\n }, [items]);\n\n const tryNavigateItems = useCallback(\n (step: 1 | -1) => {\n if (!hasDropdown || !isDropdownOpened) {\n return false;\n }\n\n const enabledIndexes = items.flatMap((item, index) => (isHighlightableMenuItem(item) ? index : []));\n\n if (enabledIndexes.length === 0) {\n return false;\n }\n\n /**\n * Навигация идет от выделенного элемента, а если его нет — от выбранного значения.\n * Отсутствующий и заблокированный элементы дают `-1`, и тогда шаг вниз попадает на первый элемент,\n * а шаг вверх выходит за начало и по фолбэку ниже уходит на последний.\n */\n const currentIndex = enabledIndexes.indexOf(highlightedItemIndex ?? selectedItemIndex ?? -1);\n\n setHighlightedItemIndex(\n enabledIndexes[currentIndex + step] ??\n (step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]),\n );\n\n return true;\n },\n [hasDropdown, highlightedItemIndex, isDropdownOpened, selectedItemIndex, items],\n );\n\n return {\n highlightedItemIndex,\n openDropdown,\n closeDropdown,\n resetHighlightedItem,\n tryNavigateItems,\n };\n};\n"]}
|
|
@@ -52,7 +52,8 @@ export var useTimePickerSource = function (options) {
|
|
|
52
52
|
setFetchedItems(EMPTY_ITEMS);
|
|
53
53
|
setFetchedQuery(null);
|
|
54
54
|
}, [isDropdownOpened, isSourceFunction]);
|
|
55
|
-
|
|
55
|
+
// Ссылка стабильна и без мемоизации: у массива это он сам, у функции — общая пустая коллекция.
|
|
56
|
+
var sourceItems = Array.isArray(source) ? source : EMPTY_ITEMS;
|
|
56
57
|
var items = useMemo(function () { return sanitizeTimeItems(isSourceFunction ? fetchedItems : sourceItems, format); }, [fetchedItems, format, isSourceFunction, sourceItems]);
|
|
57
58
|
return { items: items, fetchedQuery: fetchedQuery, isLoading: isLoading };
|
|
58
59
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTimePickerSource.js","sourceRoot":"","sources":["useTimePickerSource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAQ7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,kFAAkF;AAClF,IAAM,WAAW,GAAY,EAAE,CAAC;AAkBhC;;;;;;;;;GASG;AACH,MAAM,CAAC,IAAM,mBAAmB,GAAG,UACjC,OAAsC;IAE9B,IAAA,MAAM,GAA4C,OAAO,OAAnD,EAAE,MAAM,GAAoC,OAAO,OAA3C,EAAE,gBAAgB,GAAkB,OAAO,iBAAzB,EAAE,WAAW,GAAK,OAAO,YAAZ,CAAa;IAElE,IAAM,gBAAgB,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC;IAEhD,IAAA,KAAkC,QAAQ,CAAmC,EAAE,CAAC,EAA/E,YAAY,QAAA,EAAE,eAAe,QAAkD,CAAC;IACjF,IAAA,KAAkC,QAAQ,CAAgB,IAAI,CAAC,EAA9D,YAAY,QAAA,EAAE,eAAe,QAAiC,CAAC;IAChE,IAAA,KAA4B,QAAQ,CAAC,KAAK,CAAC,EAA1C,SAAS,QAAA,EAAE,YAAY,QAAmB,CAAC;IAElD,IAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;IAE3B,SAAS,CAAC;QACR,IAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC;QAExC,IAAI,OAAO,aAAa,KAAK,UAAU,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC7D,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,YAAY,CAAC,IAAI,CAAC,CAAC;QAEnB,IAAI,OAAO,CAAmC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,EAAnC,CAAmC,CAAC,CAAC,IAAI,CAClG,UAAC,SAAS;YACR,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,eAAe,CAAC,SAAS,CAAC,CAAC;gBAC3B,eAAe,CAAC,WAAW,CAAC,CAAC;gBAC7B,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,EACD;YACE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,eAAe,CAAC,EAAE,CAAC,CAAC;gBACpB,eAAe,CAAC,WAAW,CAAC,CAAC;gBAC7B,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CACF,CAAC;QAEF,OAAO;YACL,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEtD,SAAS,CAAC;QACR,IAAI,gBAAgB,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,eAAe,CAAC,WAAW,CAAC,CAAC;QAC7B,eAAe,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC,EAAE,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEzC,IAAM,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"useTimePickerSource.js","sourceRoot":"","sources":["useTimePickerSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\n\nimport type {\n TimeFormat,\n TimeItemValue,\n TimePickerExtendedItem,\n TimePickerSource,\n} from '../helpers/TimePicker.shared.js';\nimport { sanitizeTimeItems } from '../helpers/TimePicker.value.js';\n\n/** Общая пустая коллекция элементов: не создает новую ссылку на каждый рендер. */\nconst EMPTY_ITEMS: never[] = [];\n\ninterface UseTimePickerSourceOptions<T extends TimeItemValue> {\n source?: TimePickerSource<T>;\n format: TimeFormat;\n isDropdownOpened: boolean;\n /** Текущий запрос: введенные цифры сегментов с сохранением их позиций. */\n filterQuery: string;\n}\n\ninterface UseTimePickerSourceResult<T extends TimeItemValue> {\n /** Элементы источника, готовые к фильтрации и отрисовке. */\n items: Array<TimePickerExtendedItem<T>>;\n /** Запрос, для которого получены текущие элементы функции-источника. */\n fetchedQuery: string | null;\n isLoading: boolean;\n}\n\n/**\n * Отдает элементы выпадающего списка из массива или функции-источника.\n *\n * Функция вызывается только для открытого меню и на каждый новый запрос;\n * ответ на устаревший запрос отбрасывается, а отказ трактуется как пустой результат.\n * При закрытии меню результаты функции сбрасываются, чтобы следующее открытие\n * не показывало элементы для старого запроса.\n * Замена самой функции уже открытый список не перезапрашивает: актуальная функция\n * используется при следующем запросе.\n */\nexport const useTimePickerSource = <T extends TimeItemValue>(\n options: UseTimePickerSourceOptions<T>,\n): UseTimePickerSourceResult<T> => {\n const { source, format, isDropdownOpened, filterQuery } = options;\n\n const isSourceFunction = typeof source === 'function';\n\n const [fetchedItems, setFetchedItems] = useState<Array<TimePickerExtendedItem<T>>>([]);\n const [fetchedQuery, setFetchedQuery] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n const sourceRef = useRef(source);\n sourceRef.current = source;\n\n useEffect(() => {\n const currentSource = sourceRef.current;\n\n if (typeof currentSource !== 'function' || !isDropdownOpened) {\n setIsLoading(false);\n return;\n }\n\n let cancelled = false;\n\n setIsLoading(true);\n\n new Promise<Array<TimePickerExtendedItem<T>>>((resolve) => resolve(currentSource(filterQuery))).then(\n (nextItems) => {\n if (!cancelled) {\n setFetchedItems(nextItems);\n setFetchedQuery(filterQuery);\n setIsLoading(false);\n }\n },\n () => {\n if (!cancelled) {\n setFetchedItems([]);\n setFetchedQuery(filterQuery);\n setIsLoading(false);\n }\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [filterQuery, isDropdownOpened, isSourceFunction]);\n\n useEffect(() => {\n if (isDropdownOpened || !isSourceFunction) {\n return;\n }\n\n setFetchedItems(EMPTY_ITEMS);\n setFetchedQuery(null);\n }, [isDropdownOpened, isSourceFunction]);\n\n // Ссылка стабильна и без мемоизации: у массива это он сам, у функции — общая пустая коллекция.\n const sourceItems = Array.isArray(source) ? source : EMPTY_ITEMS;\n\n const items = useMemo(\n () => sanitizeTimeItems(isSourceFunction ? fetchedItems : sourceItems, format),\n [fetchedItems, format, isSourceFunction, sourceItems],\n );\n\n return { items, fetchedQuery, isLoading };\n};\n"]}
|
|
@@ -21,13 +21,18 @@ interface UseTimePickerValueOptions {
|
|
|
21
21
|
interface UseTimePickerValueResult {
|
|
22
22
|
editingValue: string;
|
|
23
23
|
editingValueRef: RefObject<string>;
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Последнее закоммиченное время в нормализованной форме.
|
|
26
|
+
* Правка значения его не меняет, поэтому в меню отмечено выбранным именно значение поля,
|
|
27
|
+
* а не время, которое пользователь набирает.
|
|
28
|
+
*/
|
|
29
|
+
committedValue: string;
|
|
25
30
|
updateEditingValue(value: string): void;
|
|
26
|
-
commitEditingValue():
|
|
31
|
+
commitEditingValue(): void;
|
|
27
32
|
/** Коммитит значение, введенное пользователем. Не эмитит повторно то же самое время. */
|
|
28
|
-
commitValue(value: string, item?: TimeItemValue | null):
|
|
33
|
+
commitValue(value: string, item?: TimeItemValue | null): void;
|
|
29
34
|
/** Коммитит элемент, выбранный в выпадающем меню. Эмитит всегда, так как это явное действие пользователя. */
|
|
30
|
-
commitItem(item: TimeItemValue):
|
|
35
|
+
commitItem(item: TimeItemValue): void;
|
|
31
36
|
}
|
|
32
37
|
export declare const useTimePickerValue: (options: UseTimePickerValueOptions) => UseTimePickerValueResult;
|
|
33
38
|
export {};
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import warning from 'warning';
|
|
3
|
-
import { EMPTY_VALUE } from '../helpers/TimePicker.constants.js';
|
|
4
3
|
import { getTimeItemValue } from '../helpers/TimePicker.shared.js';
|
|
5
|
-
import { getExternalTimeDisplayValue,
|
|
4
|
+
import { getExternalTimeDisplayValue, normalizeTimeValue, serializeTimeValue } from '../helpers/TimePicker.value.js';
|
|
6
5
|
export var useTimePickerValue = function (options) {
|
|
7
6
|
var externalValue = options.externalValue, isValueControlled = options.isValueControlled, format = options.format, isInputFocused = options.isInputFocused, onCommitValue = options.onCommitValue, onInputValueChange = options.onInputValueChange;
|
|
8
7
|
var externalEditingValue = getExternalTimeDisplayValue(externalValue, format);
|
|
9
8
|
var _a = useState(externalEditingValue), editingValue = _a[0], setEditingValueState = _a[1];
|
|
9
|
+
var _b = useState(function () { return normalizeTimeValue(externalValue, format); }), committedValue = _b[0], setCommittedValue = _b[1];
|
|
10
10
|
var editingValueRef = useRef(editingValue);
|
|
11
|
+
/** Последнее значение, отданное в `onInputValueChange`, — как есть, без нормализации. */
|
|
11
12
|
var emittedInputValueRef = useRef(externalValue);
|
|
12
|
-
var emittedValueRef = useRef(externalValue);
|
|
13
|
-
var lastEmittedValueRef = useRef(externalValue);
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* и поле коммитило бы его заново, собирая элемент вместо исходного.
|
|
19
|
-
* Остальные счетчики хранят значение как есть: с ними сравнивают частичное значение и то,
|
|
20
|
-
* что вернул родитель.
|
|
14
|
+
* Последнее закоммиченное время в нормализованной форме.
|
|
15
|
+
* Форма именно нормализованная, иначе внешнее `9:00` или `09:00:00` в формате `HH:mm`
|
|
16
|
+
* выглядело бы как изменение и поле коммитило бы его заново, собирая элемент вместо исходного.
|
|
21
17
|
*/
|
|
18
|
+
var emittedValueRef = useRef(externalValue);
|
|
22
19
|
var syncEmittedValues = useCallback(function (nextValue) {
|
|
23
20
|
emittedInputValueRef.current = nextValue;
|
|
24
21
|
emittedValueRef.current = normalizeTimeValue(nextValue, format);
|
|
25
|
-
lastEmittedValueRef.current = nextValue;
|
|
26
22
|
}, [format]);
|
|
27
23
|
var setEditingValue = useCallback(function (nextEditingValue) {
|
|
28
24
|
editingValueRef.current = nextEditingValue;
|
|
@@ -31,14 +27,12 @@ export var useTimePickerValue = function (options) {
|
|
|
31
27
|
var emitInputValue = useCallback(function (nextValue) {
|
|
32
28
|
if (emittedInputValueRef.current !== nextValue) {
|
|
33
29
|
emittedInputValueRef.current = nextValue;
|
|
34
|
-
lastEmittedValueRef.current = nextValue;
|
|
35
30
|
onInputValueChange === null || onInputValueChange === void 0 ? void 0 : onInputValueChange(nextValue);
|
|
36
31
|
}
|
|
37
32
|
}, [onInputValueChange]);
|
|
38
33
|
var emitValue = useCallback(function (nextValue, item) {
|
|
39
34
|
emittedInputValueRef.current = nextValue;
|
|
40
35
|
emittedValueRef.current = nextValue;
|
|
41
|
-
lastEmittedValueRef.current = nextValue;
|
|
42
36
|
onCommitValue(nextValue, item);
|
|
43
37
|
}, [onCommitValue]);
|
|
44
38
|
var updateEditingValue = useCallback(function (nextEditingValue) {
|
|
@@ -49,23 +43,19 @@ export var useTimePickerValue = function (options) {
|
|
|
49
43
|
if (item === void 0) { item = null; }
|
|
50
44
|
var normalizedValue = normalizeTimeValue(nextValue, format);
|
|
51
45
|
setEditingValue(normalizedValue);
|
|
46
|
+
setCommittedValue(normalizedValue);
|
|
52
47
|
if (emittedValueRef.current !== normalizedValue) {
|
|
53
48
|
emitValue(normalizedValue, item);
|
|
54
49
|
}
|
|
55
|
-
return normalizedValue;
|
|
56
50
|
}, [emitValue, format, setEditingValue]);
|
|
57
51
|
var commitItem = useCallback(function (item) {
|
|
58
52
|
var normalizedValue = normalizeTimeValue(getTimeItemValue(item), format);
|
|
59
53
|
setEditingValue(normalizedValue);
|
|
54
|
+
setCommittedValue(normalizedValue);
|
|
60
55
|
emitValue(normalizedValue, item);
|
|
61
|
-
return normalizedValue;
|
|
62
56
|
}, [emitValue, format, setEditingValue]);
|
|
63
57
|
var commitEditingValue = useCallback(function () {
|
|
64
|
-
|
|
65
|
-
if (isTimeDisplayEmpty(currentEditingValue)) {
|
|
66
|
-
return commitValue(EMPTY_VALUE);
|
|
67
|
-
}
|
|
68
|
-
return commitValue(currentEditingValue);
|
|
58
|
+
commitValue(editingValueRef.current);
|
|
69
59
|
}, [commitValue, editingValueRef]);
|
|
70
60
|
var initialIsValueControlledRef = useRef(isValueControlled);
|
|
71
61
|
useEffect(function () {
|
|
@@ -79,15 +69,24 @@ export var useTimePickerValue = function (options) {
|
|
|
79
69
|
if (!isValueControlled) {
|
|
80
70
|
return;
|
|
81
71
|
}
|
|
82
|
-
if (!isInputFocused || externalValue !==
|
|
72
|
+
if (!isInputFocused || externalValue !== emittedInputValueRef.current) {
|
|
83
73
|
setEditingValue(externalEditingValue);
|
|
84
74
|
}
|
|
75
|
+
setCommittedValue(normalizeTimeValue(externalValue, format));
|
|
85
76
|
syncEmittedValues(externalValue);
|
|
86
|
-
}, [
|
|
77
|
+
}, [
|
|
78
|
+
externalEditingValue,
|
|
79
|
+
externalValue,
|
|
80
|
+
format,
|
|
81
|
+
isInputFocused,
|
|
82
|
+
isValueControlled,
|
|
83
|
+
setEditingValue,
|
|
84
|
+
syncEmittedValues,
|
|
85
|
+
]);
|
|
87
86
|
return {
|
|
88
87
|
editingValue: editingValue,
|
|
89
88
|
editingValueRef: editingValueRef,
|
|
90
|
-
|
|
89
|
+
committedValue: committedValue,
|
|
91
90
|
updateEditingValue: updateEditingValue,
|
|
92
91
|
commitEditingValue: commitEditingValue,
|
|
93
92
|
commitValue: commitValue,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTimePickerValue.js","sourceRoot":"","sources":["useTimePickerValue.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RefObject } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport warning from 'warning';\n\nimport { EMPTY_VALUE } from '../helpers/TimePicker.constants.js';\nimport { getTimeItemValue, type TimeFormat, type TimeItemValue } from '../helpers/TimePicker.shared.js';\nimport {\n getExternalTimeDisplayValue,\n isTimeDisplayEmpty,\n normalizeTimeValue,\n serializeTimeValue,\n} from '../helpers/TimePicker.value.js';\n\ninterface UseTimePickerValueOptions {\n isInputFocused: boolean;\n /** Внешнее значение, приведенное к строке времени. */\n externalValue: string;\n /**\n * Значением управляет родитель: проп `value` задан.\n * Если проп не задан, компонент неконтролируемый и хранит значение сам,\n * поэтому внешнее пустое значение не должно затирать введенное пользователем.\n */\n isValueControlled: boolean;\n format: TimeFormat;\n /**\n * Вызывается при коммите значения: получает нормализованное время\n * и элемент из `source`, если значение выбрано в выпадающем меню.\n */\n onCommitValue(value: string, item: TimeItemValue | null): void;\n onInputValueChange?(value: string): void;\n}\n\ninterface UseTimePickerValueResult {\n editingValue: string;\n editingValueRef: RefObject<string>;\n setEditingValue(value: string): void;\n updateEditingValue(value: string): void;\n commitEditingValue(): string;\n /** Коммитит значение, введенное пользователем. Не эмитит повторно то же самое время. */\n commitValue(value: string, item?: TimeItemValue | null): string;\n /** Коммитит элемент, выбранный в выпадающем меню. Эмитит всегда, так как это явное действие пользователя. */\n commitItem(item: TimeItemValue): string;\n}\n\nexport const useTimePickerValue = (options: UseTimePickerValueOptions): UseTimePickerValueResult => {\n const { externalValue, isValueControlled, format, isInputFocused, onCommitValue, onInputValueChange } = options;\n\n const externalEditingValue = getExternalTimeDisplayValue(externalValue, format);\n\n const [editingValue, setEditingValueState] = useState<string>(externalEditingValue);\n\n const editingValueRef = useRef(editingValue);\n const emittedInputValueRef = useRef(externalValue);\n const emittedValueRef = useRef(externalValue);\n const lastEmittedValueRef = useRef(externalValue);\n\n /**\n * Синхронизирует счетчики отданных значений с внешним значением.\n * Коммит сравнивает время в нормализованной форме, поэтому счетчик закоммиченного значения хранит ее:\n * иначе внешнее `9:00` или `09:00:00` в формате `HH:mm` выглядело бы как изменение\n * и поле коммитило бы его заново, собирая элемент вместо исходного.\n * Остальные счетчики хранят значение как есть: с ними сравнивают частичное значение и то,\n * что вернул родитель.\n */\n const syncEmittedValues = useCallback(\n (nextValue: string) => {\n emittedInputValueRef.current = nextValue;\n emittedValueRef.current = normalizeTimeValue(nextValue, format);\n lastEmittedValueRef.current = nextValue;\n },\n [format],\n );\n\n const setEditingValue = useCallback((nextEditingValue: string) => {\n editingValueRef.current = nextEditingValue;\n setEditingValueState(nextEditingValue);\n }, []);\n\n const emitInputValue = useCallback(\n (nextValue: string) => {\n if (emittedInputValueRef.current !== nextValue) {\n emittedInputValueRef.current = nextValue;\n lastEmittedValueRef.current = nextValue;\n onInputValueChange?.(nextValue);\n }\n },\n [onInputValueChange],\n );\n\n const emitValue = useCallback(\n (nextValue: string, item: TimeItemValue | null) => {\n emittedInputValueRef.current = nextValue;\n emittedValueRef.current = nextValue;\n lastEmittedValueRef.current = nextValue;\n onCommitValue(nextValue, item);\n },\n [onCommitValue],\n );\n\n const updateEditingValue = useCallback(\n (nextEditingValue: string) => {\n setEditingValue(nextEditingValue);\n emitInputValue(serializeTimeValue(nextEditingValue, format));\n },\n [emitInputValue, format, setEditingValue],\n );\n\n const commitValue = useCallback(\n (nextValue: string, item: TimeItemValue | null = null): string => {\n const normalizedValue = normalizeTimeValue(nextValue, format);\n\n setEditingValue(normalizedValue);\n\n if (emittedValueRef.current !== normalizedValue) {\n emitValue(normalizedValue, item);\n }\n\n return normalizedValue;\n },\n [emitValue, format, setEditingValue],\n );\n\n const commitItem = useCallback(\n (item: TimeItemValue): string => {\n const normalizedValue = normalizeTimeValue(getTimeItemValue(item), format);\n\n setEditingValue(normalizedValue);\n emitValue(normalizedValue, item);\n\n return normalizedValue;\n },\n [emitValue, format, setEditingValue],\n );\n\n const commitEditingValue = useCallback((): string => {\n const currentEditingValue = editingValueRef.current;\n\n if (isTimeDisplayEmpty(currentEditingValue)) {\n return commitValue(EMPTY_VALUE);\n }\n\n return commitValue(currentEditingValue);\n }, [commitValue, editingValueRef]);\n\n const initialIsValueControlledRef = useRef(isValueControlled);\n\n useEffect(() => {\n warning(\n initialIsValueControlledRef.current === isValueControlled,\n isValueControlled\n ? '[TimePicker]: a component is changing an uncontrolled value to be controlled. ' +\n 'Decide between using a controlled or uncontrolled value for the lifetime of the component.'\n : '[TimePicker]: a component is changing a controlled value to be uncontrolled. ' +\n 'Pass an empty string or null instead of undefined to keep the value controlled.',\n );\n }, [isValueControlled]);\n\n useEffect(() => {\n if (!isValueControlled) {\n return;\n }\n\n if (!isInputFocused || externalValue !== lastEmittedValueRef.current) {\n setEditingValue(externalEditingValue);\n }\n\n syncEmittedValues(externalValue);\n }, [externalEditingValue, externalValue, isInputFocused, isValueControlled, setEditingValue, syncEmittedValues]);\n\n return {\n editingValue,\n editingValueRef,\n setEditingValue,\n updateEditingValue,\n commitEditingValue,\n commitValue,\n commitItem,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"useTimePickerValue.js","sourceRoot":"","sources":["useTimePickerValue.ts"],"names":[],"mappings":"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","sourcesContent":["import type { RefObject } from 'react';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport warning from 'warning';\n\nimport { getTimeItemValue, type TimeFormat, type TimeItemValue } from '../helpers/TimePicker.shared.js';\nimport { getExternalTimeDisplayValue, normalizeTimeValue, serializeTimeValue } from '../helpers/TimePicker.value.js';\n\ninterface UseTimePickerValueOptions {\n isInputFocused: boolean;\n /** Внешнее значение, приведенное к строке времени. */\n externalValue: string;\n /**\n * Значением управляет родитель: проп `value` задан.\n * Если проп не задан, компонент неконтролируемый и хранит значение сам,\n * поэтому внешнее пустое значение не должно затирать введенное пользователем.\n */\n isValueControlled: boolean;\n format: TimeFormat;\n /**\n * Вызывается при коммите значения: получает нормализованное время\n * и элемент из `source`, если значение выбрано в выпадающем меню.\n */\n onCommitValue(value: string, item: TimeItemValue | null): void;\n onInputValueChange?(value: string): void;\n}\n\ninterface UseTimePickerValueResult {\n editingValue: string;\n editingValueRef: RefObject<string>;\n /**\n * Последнее закоммиченное время в нормализованной форме.\n * Правка значения его не меняет, поэтому в меню отмечено выбранным именно значение поля,\n * а не время, которое пользователь набирает.\n */\n committedValue: string;\n updateEditingValue(value: string): void;\n commitEditingValue(): void;\n /** Коммитит значение, введенное пользователем. Не эмитит повторно то же самое время. */\n commitValue(value: string, item?: TimeItemValue | null): void;\n /** Коммитит элемент, выбранный в выпадающем меню. Эмитит всегда, так как это явное действие пользователя. */\n commitItem(item: TimeItemValue): void;\n}\n\nexport const useTimePickerValue = (options: UseTimePickerValueOptions): UseTimePickerValueResult => {\n const { externalValue, isValueControlled, format, isInputFocused, onCommitValue, onInputValueChange } = options;\n\n const externalEditingValue = getExternalTimeDisplayValue(externalValue, format);\n\n const [editingValue, setEditingValueState] = useState<string>(externalEditingValue);\n const [committedValue, setCommittedValue] = useState<string>(() => normalizeTimeValue(externalValue, format));\n\n const editingValueRef = useRef(editingValue);\n /** Последнее значение, отданное в `onInputValueChange`, — как есть, без нормализации. */\n const emittedInputValueRef = useRef(externalValue);\n /**\n * Последнее закоммиченное время в нормализованной форме.\n * Форма именно нормализованная, иначе внешнее `9:00` или `09:00:00` в формате `HH:mm`\n * выглядело бы как изменение и поле коммитило бы его заново, собирая элемент вместо исходного.\n */\n const emittedValueRef = useRef(externalValue);\n\n const syncEmittedValues = useCallback(\n (nextValue: string) => {\n emittedInputValueRef.current = nextValue;\n emittedValueRef.current = normalizeTimeValue(nextValue, format);\n },\n [format],\n );\n\n const setEditingValue = useCallback((nextEditingValue: string) => {\n editingValueRef.current = nextEditingValue;\n setEditingValueState(nextEditingValue);\n }, []);\n\n const emitInputValue = useCallback(\n (nextValue: string) => {\n if (emittedInputValueRef.current !== nextValue) {\n emittedInputValueRef.current = nextValue;\n onInputValueChange?.(nextValue);\n }\n },\n [onInputValueChange],\n );\n\n const emitValue = useCallback(\n (nextValue: string, item: TimeItemValue | null) => {\n emittedInputValueRef.current = nextValue;\n emittedValueRef.current = nextValue;\n onCommitValue(nextValue, item);\n },\n [onCommitValue],\n );\n\n const updateEditingValue = useCallback(\n (nextEditingValue: string) => {\n setEditingValue(nextEditingValue);\n emitInputValue(serializeTimeValue(nextEditingValue, format));\n },\n [emitInputValue, format, setEditingValue],\n );\n\n const commitValue = useCallback(\n (nextValue: string, item: TimeItemValue | null = null) => {\n const normalizedValue = normalizeTimeValue(nextValue, format);\n\n setEditingValue(normalizedValue);\n setCommittedValue(normalizedValue);\n\n if (emittedValueRef.current !== normalizedValue) {\n emitValue(normalizedValue, item);\n }\n },\n [emitValue, format, setEditingValue],\n );\n\n const commitItem = useCallback(\n (item: TimeItemValue) => {\n const normalizedValue = normalizeTimeValue(getTimeItemValue(item), format);\n\n setEditingValue(normalizedValue);\n setCommittedValue(normalizedValue);\n emitValue(normalizedValue, item);\n },\n [emitValue, format, setEditingValue],\n );\n\n const commitEditingValue = useCallback(() => {\n commitValue(editingValueRef.current);\n }, [commitValue, editingValueRef]);\n\n const initialIsValueControlledRef = useRef(isValueControlled);\n\n useEffect(() => {\n warning(\n initialIsValueControlledRef.current === isValueControlled,\n isValueControlled\n ? '[TimePicker]: a component is changing an uncontrolled value to be controlled. ' +\n 'Decide between using a controlled or uncontrolled value for the lifetime of the component.'\n : '[TimePicker]: a component is changing a controlled value to be uncontrolled. ' +\n 'Pass an empty string or null instead of undefined to keep the value controlled.',\n );\n }, [isValueControlled]);\n\n useEffect(() => {\n if (!isValueControlled) {\n return;\n }\n\n if (!isInputFocused || externalValue !== emittedInputValueRef.current) {\n setEditingValue(externalEditingValue);\n }\n\n setCommittedValue(normalizeTimeValue(externalValue, format));\n syncEmittedValues(externalValue);\n }, [\n externalEditingValue,\n externalValue,\n format,\n isInputFocused,\n isValueControlled,\n setEditingValue,\n syncEmittedValues,\n ]);\n\n return {\n editingValue,\n editingValueRef,\n committedValue,\n updateEditingValue,\n commitEditingValue,\n commitValue,\n commitItem,\n };\n};\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from './TimePicker.js';
|
|
2
2
|
export { TimePickerDataTids } from './helpers/TimePicker.constants.js';
|
|
3
3
|
export type { TimePickerValidationOptions } from './helpers/validateTimePicker.js';
|
|
4
|
-
export type { TimeFormat, TimeSegment, TimeItem, TimeItemValue, TimePickerExtendedItem, TimePickerMenuItem, TimePickerResolvedItem, TimePickerSource, TimePickerValue, TimePickerValueToItem, } from './helpers/TimePicker.shared.js';
|
|
4
|
+
export type { TimeFormat, TimeSegment, TimeItem, TimeItemValue, TimePickerExtendedItem, TimePickerMenuElement, TimePickerMenuItem, TimePickerResolvedItem, TimePickerSource, TimePickerValue, TimePickerValueToItem, } from './helpers/TimePicker.shared.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC","sourcesContent":["export * from './TimePicker.js';\nexport { TimePickerDataTids } from './helpers/TimePicker.constants.js';\nexport type { TimePickerValidationOptions } from './helpers/validateTimePicker.js';\nexport type {\n TimeFormat,\n TimeSegment,\n TimeItem,\n TimeItemValue,\n TimePickerExtendedItem,\n TimePickerMenuItem,\n TimePickerResolvedItem,\n TimePickerSource,\n TimePickerValue,\n TimePickerValueToItem,\n} from './helpers/TimePicker.shared.js';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC","sourcesContent":["export * from './TimePicker.js';\nexport { TimePickerDataTids } from './helpers/TimePicker.constants.js';\nexport type { TimePickerValidationOptions } from './helpers/validateTimePicker.js';\nexport type {\n TimeFormat,\n TimeSegment,\n TimeItem,\n TimeItemValue,\n TimePickerExtendedItem,\n TimePickerMenuElement,\n TimePickerMenuItem,\n TimePickerResolvedItem,\n TimePickerSource,\n TimePickerValue,\n TimePickerValueToItem,\n} from './helpers/TimePicker.shared.js';\n"]}
|