@skbkontur/react-ui 6.1.7-1c902.0 → 6.1.7-4c72d.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.
Files changed (72) hide show
  1. package/components/MenuItem/MenuItem.d.ts +1 -1
  2. package/components/MenuItem/MenuItem.js +0 -1
  3. package/components/MenuItem/MenuItem.js.map +1 -1
  4. package/components/MenuItem/MenuItem.styles.d.ts +0 -1
  5. package/components/MenuItem/MenuItem.styles.js +7 -10
  6. package/components/MenuItem/MenuItem.styles.js.map +1 -1
  7. package/components/TimePicker/TimePicker.d.ts +44 -25
  8. package/components/TimePicker/TimePicker.js +373 -191
  9. package/components/TimePicker/TimePicker.js.map +1 -1
  10. package/components/TimePicker/TimePicker.styles.d.ts +3 -1
  11. package/components/TimePicker/TimePicker.styles.js +9 -3
  12. package/components/TimePicker/TimePicker.styles.js.map +1 -1
  13. package/components/TimePicker/TimePickerItems.d.ts +5 -1
  14. package/components/TimePicker/TimePickerItems.js +39 -29
  15. package/components/TimePicker/TimePickerItems.js.map +1 -1
  16. package/components/TimePicker/TimePickerMobilePopup.d.ts +5 -2
  17. package/components/TimePicker/TimePickerMobilePopup.js +4 -4
  18. package/components/TimePicker/TimePickerMobilePopup.js.map +1 -1
  19. package/components/TimePicker/TimePickerPopup.d.ts +5 -1
  20. package/components/TimePicker/TimePickerPopup.js +4 -4
  21. package/components/TimePicker/TimePickerPopup.js.map +1 -1
  22. package/components/TimePicker/helpers/TimePicker.constants.d.ts +8 -1
  23. package/components/TimePicker/helpers/TimePicker.constants.js +8 -7
  24. package/components/TimePicker/helpers/TimePicker.constants.js.map +1 -1
  25. package/components/TimePicker/helpers/TimePicker.editing.d.ts +1 -5
  26. package/components/TimePicker/helpers/TimePicker.editing.js +8 -35
  27. package/components/TimePicker/helpers/TimePicker.editing.js.map +1 -1
  28. package/components/TimePicker/helpers/TimePicker.shared.d.ts +20 -22
  29. package/components/TimePicker/helpers/TimePicker.shared.js +27 -24
  30. package/components/TimePicker/helpers/TimePicker.shared.js.map +1 -1
  31. package/components/TimePicker/helpers/TimePicker.value.d.ts +22 -11
  32. package/components/TimePicker/helpers/TimePicker.value.js +69 -37
  33. package/components/TimePicker/helpers/TimePicker.value.js.map +1 -1
  34. package/components/TimePicker/helpers/scrollSelectedItemIntoView.d.ts +2 -0
  35. package/components/TimePicker/helpers/scrollSelectedItemIntoView.js +2 -0
  36. package/components/TimePicker/helpers/scrollSelectedItemIntoView.js.map +1 -1
  37. package/components/TimePicker/helpers/validateTimePicker.js +2 -4
  38. package/components/TimePicker/helpers/validateTimePicker.js.map +1 -1
  39. package/components/TimePicker/hooks/useTimePickerDropdown.d.ts +6 -1
  40. package/components/TimePicker/hooks/useTimePickerDropdown.js +15 -33
  41. package/components/TimePicker/hooks/useTimePickerDropdown.js.map +1 -1
  42. package/components/TimePicker/hooks/useTimePickerSource.d.ts +29 -0
  43. package/components/TimePicker/hooks/useTimePickerSource.js +67 -0
  44. package/components/TimePicker/hooks/useTimePickerSource.js.map +1 -0
  45. package/components/TimePicker/hooks/useTimePickerValue.d.ts +15 -4
  46. package/components/TimePicker/hooks/useTimePickerValue.js +40 -20
  47. package/components/TimePicker/hooks/useTimePickerValue.js.map +1 -1
  48. package/components/TimePicker/index.d.ts +3 -1
  49. package/components/TimePicker/index.js +1 -0
  50. package/components/TimePicker/index.js.map +1 -1
  51. package/components/TimePicker/locale/locales/en.js +2 -0
  52. package/components/TimePicker/locale/locales/en.js.map +1 -1
  53. package/components/TimePicker/locale/locales/ru.js +2 -0
  54. package/components/TimePicker/locale/locales/ru.js.map +1 -1
  55. package/components/TimePicker/locale/types.d.ts +2 -0
  56. package/components/TimePicker/locale/types.js.map +1 -1
  57. package/internal/NativeTimeInput/NativeTimeInput.d.ts +4 -0
  58. package/internal/NativeTimeInput/NativeTimeInput.js +7 -2
  59. package/internal/NativeTimeInput/NativeTimeInput.js.map +1 -1
  60. package/internal/NativeTimeInput/NativeTimeInput.utils.d.ts +2 -0
  61. package/internal/NativeTimeInput/NativeTimeInput.utils.js +4 -8
  62. package/internal/NativeTimeInput/NativeTimeInput.utils.js.map +1 -1
  63. package/internal/TimeInput/TimeFragments.d.ts +0 -1
  64. package/internal/TimeInput/TimeFragments.js +30 -8
  65. package/internal/TimeInput/TimeFragments.js.map +1 -1
  66. package/internal/TimeInput/TimeFragments.styles.d.ts +15 -0
  67. package/internal/TimeInput/TimeFragments.styles.js +39 -9
  68. package/internal/TimeInput/TimeFragments.styles.js.map +1 -1
  69. package/internal/TimeInput/TimeInput.d.ts +0 -1
  70. package/internal/TimeInput/TimeInput.js +0 -1
  71. package/internal/TimeInput/TimeInput.js.map +1 -1
  72. package/package.json +1 -1
@@ -1,20 +1,19 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { isTimeMenuItem } from '../helpers/TimePicker.shared.js';
2
+ import { isHighlightableMenuItem, isTimeMenuItem, } from '../helpers/TimePicker.shared.js';
3
3
  export var useTimePickerDropdown = function (options) {
4
- var hasDropdown = options.hasDropdown, disabled = options.disabled, items = options.items, selectedItemIndex = options.selectedItemIndex, autoHighlightKey = options.autoHighlightKey;
5
- var _a = useState(false), isDropdownOpened = _a[0], setIsDropdownOpened = _a[1];
6
- var _b = useState(null), highlightedItemIndex = _b[0], setHighlightedItemIndex = _b[1];
4
+ var hasDropdown = options.hasDropdown, disabled = options.disabled, items = options.items, selectedItemIndex = options.selectedItemIndex, autoHighlightKey = options.autoHighlightKey, isDropdownOpened = options.isDropdownOpened, setIsDropdownOpened = options.setIsDropdownOpened;
5
+ var _a = useState(null), highlightedItemIndex = _a[0], setHighlightedItemIndex = _a[1];
7
6
  var lastAutoHighlightKeyRef = useRef(null);
8
7
  var openDropdown = useCallback(function () {
9
8
  if (!hasDropdown || disabled) {
10
9
  return;
11
10
  }
12
11
  setIsDropdownOpened(true);
13
- }, [disabled, hasDropdown]);
12
+ }, [disabled, hasDropdown, setIsDropdownOpened]);
14
13
  var closeDropdown = useCallback(function () {
15
14
  setIsDropdownOpened(false);
16
15
  setHighlightedItemIndex(null);
17
- }, []);
16
+ }, [setIsDropdownOpened]);
18
17
  var resetHighlightedItem = useCallback(function () {
19
18
  setHighlightedItemIndex(null);
20
19
  }, []);
@@ -36,45 +35,28 @@ export var useTimePickerDropdown = function (options) {
36
35
  return current;
37
36
  }
38
37
  var item = items[current];
39
- return !item || !isTimeMenuItem(item) || item.disabled ? null : current;
38
+ return !item || !isHighlightableMenuItem(item) ? null : current;
40
39
  });
41
40
  }, [items]);
42
41
  var tryNavigateItems = useCallback(function (step) {
42
+ var _a, _b;
43
43
  if (!hasDropdown || !isDropdownOpened) {
44
44
  return false;
45
45
  }
46
- var enabledIndexes = items
47
- .map(function (item, index) { return ({ item: item, index: index }); })
48
- .filter(function (_a) {
49
- var item = _a.item;
50
- return isTimeMenuItem(item) && !item.disabled;
51
- })
52
- .map(function (_a) {
53
- var index = _a.index;
54
- return index;
55
- });
46
+ var enabledIndexes = items.flatMap(function (item, index) { return (isHighlightableMenuItem(item) ? index : []); });
56
47
  if (enabledIndexes.length === 0) {
57
48
  return false;
58
49
  }
59
- if (highlightedItemIndex === null) {
60
- if (selectedItemIndex !== null) {
61
- var selectedEnabledIndex = enabledIndexes.indexOf(selectedItemIndex);
62
- if (selectedEnabledIndex >= 0) {
63
- var nextEnabledIndex_1 = enabledIndexes[selectedEnabledIndex + step];
64
- setHighlightedItemIndex(nextEnabledIndex_1 !== null && nextEnabledIndex_1 !== void 0 ? nextEnabledIndex_1 : (step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]));
65
- return true;
66
- }
67
- }
68
- setHighlightedItemIndex(step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]);
69
- return true;
70
- }
71
- var currentIndex = enabledIndexes.indexOf(highlightedItemIndex);
72
- var nextEnabledIndex = enabledIndexes[currentIndex + step];
73
- 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]));
74
57
  return true;
75
58
  }, [hasDropdown, highlightedItemIndex, isDropdownOpened, selectedItemIndex, items]);
76
59
  return {
77
- isDropdownOpened: isDropdownOpened,
78
60
  highlightedItemIndex: highlightedItemIndex,
79
61
  openDropdown: openDropdown,
80
62
  closeDropdown: closeDropdown,
@@ -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,EAAE,cAAc,EAA+C,MAAM,iCAAiC,CAAC;AAmB9G,MAAM,CAAC,IAAM,qBAAqB,GAAG,UACnC,OAAwC;IAEhC,IAAA,WAAW,GAA2D,OAAO,YAAlE,EAAE,QAAQ,GAAiD,OAAO,SAAxD,EAAE,KAAK,GAA0C,OAAO,MAAjD,EAAE,iBAAiB,GAAuB,OAAO,kBAA9B,EAAE,gBAAgB,GAAK,OAAO,iBAAZ,CAAa;IAEhF,IAAA,KAA0C,QAAQ,CAAC,KAAK,CAAC,EAAxD,gBAAgB,QAAA,EAAE,mBAAmB,QAAmB,CAAC;IAC1D,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,CAAC,CAAC,CAAC;IAE5B,IAAM,aAAa,GAAG,WAAW,CAAC;QAChC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,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,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1E,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,IAAM,gBAAgB,GAAG,WAAW,CAClC,UAAC,IAAY;QACX,IAAI,CAAC,WAAW,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAM,cAAc,GAAG,KAAK;aACzB,GAAG,CAAC,UAAC,IAAI,EAAE,KAAK,IAAK,OAAA,CAAC,EAAE,IAAI,MAAA,EAAE,KAAK,OAAA,EAAE,CAAC,EAAjB,CAAiB,CAAC;aACvC,MAAM,CAAC,UAAC,EAAQ;gBAAN,IAAI,UAAA;YAAO,OAAA,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAtC,CAAsC,CAAC;aAC5D,GAAG,CAAC,UAAC,EAAS;gBAAP,KAAK,WAAA;YAAO,OAAA,KAAK;QAAL,CAAK,CAAC,CAAC;QAE7B,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,oBAAoB,KAAK,IAAI,EAAE,CAAC;YAClC,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;gBAC/B,IAAM,oBAAoB,GAAG,cAAc,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;gBAEvE,IAAI,oBAAoB,IAAI,CAAC,EAAE,CAAC;oBAC9B,IAAM,kBAAgB,GAAG,cAAc,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;oBAErE,uBAAuB,CACrB,kBAAgB,aAAhB,kBAAgB,cAAhB,kBAAgB,GAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAC/F,CAAC;oBACF,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YAED,uBAAuB,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;YAClG,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAClE,IAAM,gBAAgB,GAAG,cAAc,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;QAE7D,uBAAuB,CACrB,gBAAgB,aAAhB,gBAAgB,cAAhB,gBAAgB,GAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAC/F,CAAC;QAEF,OAAO,IAAI,CAAC;IACd,CAAC,EACD,CAAC,WAAW,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAChF,CAAC;IAEF,OAAO;QACL,gBAAgB,kBAAA;QAChB,oBAAoB,sBAAA;QACpB,YAAY,cAAA;QACZ,aAAa,eAAA;QACb,oBAAoB,sBAAA;QACpB,gBAAgB,kBAAA;KACjB,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { isTimeMenuItem, type TimeItemValue, type TimePickerMenuItem } 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\ninterface UseTimePickerDropdownResult {\n isDropdownOpened: boolean;\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 } = options;\n\n const [isDropdownOpened, setIsDropdownOpened] = useState(false);\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]);\n\n const closeDropdown = useCallback(() => {\n setIsDropdownOpened(false);\n setHighlightedItemIndex(null);\n }, []);\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 || !isTimeMenuItem(item) || item.disabled ? 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\n .map((item, index) => ({ item, index }))\n .filter(({ item }) => isTimeMenuItem(item) && !item.disabled)\n .map(({ index }) => index);\n\n if (enabledIndexes.length === 0) {\n return false;\n }\n\n if (highlightedItemIndex === null) {\n if (selectedItemIndex !== null) {\n const selectedEnabledIndex = enabledIndexes.indexOf(selectedItemIndex);\n\n if (selectedEnabledIndex >= 0) {\n const nextEnabledIndex = enabledIndexes[selectedEnabledIndex + step];\n\n setHighlightedItemIndex(\n nextEnabledIndex ?? (step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]),\n );\n return true;\n }\n }\n\n setHighlightedItemIndex(step > 0 ? enabledIndexes[0] : enabledIndexes[enabledIndexes.length - 1]);\n return true;\n }\n\n const currentIndex = enabledIndexes.indexOf(highlightedItemIndex);\n const nextEnabledIndex = enabledIndexes[currentIndex + step];\n\n setHighlightedItemIndex(\n nextEnabledIndex ?? (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 isDropdownOpened,\n highlightedItemIndex,\n openDropdown,\n closeDropdown,\n resetHighlightedItem,\n tryNavigateItems,\n };\n};\n"]}
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"]}
@@ -0,0 +1,29 @@
1
+ import type { TimeFormat, TimeItemValue, TimePickerExtendedItem, TimePickerSource } from '../helpers/TimePicker.shared.js';
2
+ interface UseTimePickerSourceOptions<T extends TimeItemValue> {
3
+ source?: TimePickerSource<T>;
4
+ format: TimeFormat;
5
+ isDropdownOpened: boolean;
6
+ /** Текущий запрос: введенные цифры сегментов с сохранением их позиций. */
7
+ filterQuery: string;
8
+ }
9
+ interface UseTimePickerSourceResult<T extends TimeItemValue> {
10
+ /** Элементы источника, готовые к фильтрации и отрисовке. */
11
+ items: Array<TimePickerExtendedItem<T>>;
12
+ /** Запрос, для которого получены текущие элементы функции-источника. */
13
+ fetchedQuery: string | null;
14
+ isLoading: boolean;
15
+ isFailed: boolean;
16
+ retry: () => void;
17
+ }
18
+ /**
19
+ * Отдает элементы выпадающего списка из массива или функции-источника.
20
+ *
21
+ * Функция вызывается только для открытого меню и на каждый новый запрос;
22
+ * ответ на устаревший запрос отбрасывается, а отказ можно повторить через `retry`.
23
+ * При закрытии меню результаты функции сбрасываются, чтобы следующее открытие
24
+ * не показывало элементы для старого запроса.
25
+ * Замена самой функции уже открытый список не перезапрашивает: актуальная функция
26
+ * используется при следующем запросе.
27
+ */
28
+ export declare const useTimePickerSource: <T extends TimeItemValue>(options: UseTimePickerSourceOptions<T>) => UseTimePickerSourceResult<T>;
29
+ export {};
@@ -0,0 +1,67 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { sanitizeTimeItems } from '../helpers/TimePicker.value.js';
3
+ /** Общая пустая коллекция элементов: не создает новую ссылку на каждый рендер. */
4
+ var EMPTY_ITEMS = [];
5
+ /**
6
+ * Отдает элементы выпадающего списка из массива или функции-источника.
7
+ *
8
+ * Функция вызывается только для открытого меню и на каждый новый запрос;
9
+ * ответ на устаревший запрос отбрасывается, а отказ можно повторить через `retry`.
10
+ * При закрытии меню результаты функции сбрасываются, чтобы следующее открытие
11
+ * не показывало элементы для старого запроса.
12
+ * Замена самой функции уже открытый список не перезапрашивает: актуальная функция
13
+ * используется при следующем запросе.
14
+ */
15
+ export var useTimePickerSource = function (options) {
16
+ var source = options.source, format = options.format, isDropdownOpened = options.isDropdownOpened, filterQuery = options.filterQuery;
17
+ var isSourceFunction = typeof source === 'function';
18
+ var _a = useState([]), fetchedItems = _a[0], setFetchedItems = _a[1];
19
+ var _b = useState(null), fetchedQuery = _b[0], setFetchedQuery = _b[1];
20
+ var _c = useState(false), isLoading = _c[0], setIsLoading = _c[1];
21
+ var _d = useState(false), isFailed = _d[0], setIsFailed = _d[1];
22
+ var _e = useState(0), requestVersion = _e[0], setRequestVersion = _e[1];
23
+ var sourceRef = useRef(source);
24
+ sourceRef.current = source;
25
+ useEffect(function () {
26
+ var currentSource = sourceRef.current;
27
+ if (typeof currentSource !== 'function' || !isDropdownOpened) {
28
+ setIsLoading(false);
29
+ setIsFailed(false);
30
+ return;
31
+ }
32
+ var cancelled = false;
33
+ setIsLoading(true);
34
+ setIsFailed(false);
35
+ new Promise(function (resolve) { return resolve(currentSource(filterQuery)); }).then(function (nextItems) {
36
+ if (!cancelled) {
37
+ setFetchedItems(nextItems);
38
+ setFetchedQuery(filterQuery);
39
+ setIsLoading(false);
40
+ setIsFailed(false);
41
+ }
42
+ }, function () {
43
+ if (!cancelled) {
44
+ setFetchedItems([]);
45
+ setFetchedQuery(null);
46
+ setIsLoading(false);
47
+ setIsFailed(true);
48
+ }
49
+ });
50
+ return function () {
51
+ cancelled = true;
52
+ };
53
+ }, [filterQuery, isDropdownOpened, isSourceFunction, requestVersion]);
54
+ useEffect(function () {
55
+ if (isDropdownOpened || !isSourceFunction) {
56
+ return;
57
+ }
58
+ setFetchedItems(EMPTY_ITEMS);
59
+ setFetchedQuery(null);
60
+ }, [isDropdownOpened, isSourceFunction]);
61
+ // Ссылка стабильна и без мемоизации: у массива это он сам, у функции — общая пустая коллекция.
62
+ var sourceItems = Array.isArray(source) ? source : EMPTY_ITEMS;
63
+ var items = useMemo(function () { return sanitizeTimeItems(isSourceFunction ? fetchedItems : sourceItems, format); }, [fetchedItems, format, isSourceFunction, sourceItems]);
64
+ var retry = useCallback(function () { return setRequestVersion(function (version) { return version + 1; }); }, []);
65
+ return { items: items, fetchedQuery: fetchedQuery, isLoading: isLoading, isFailed: isFailed, retry: retry };
66
+ };
67
+ //# sourceMappingURL=useTimePickerSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimePickerSource.js","sourceRoot":"","sources":["useTimePickerSource.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, 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 isFailed: boolean;\n retry: () => void;\n}\n\n/**\n * Отдает элементы выпадающего списка из массива или функции-источника.\n *\n * Функция вызывается только для открытого меню и на каждый новый запрос;\n * ответ на устаревший запрос отбрасывается, а отказ можно повторить через `retry`.\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 const [isFailed, setIsFailed] = useState(false);\n const [requestVersion, setRequestVersion] = useState(0);\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 setIsFailed(false);\n return;\n }\n\n let cancelled = false;\n\n setIsLoading(true);\n setIsFailed(false);\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 setIsFailed(false);\n }\n },\n () => {\n if (!cancelled) {\n setFetchedItems([]);\n setFetchedQuery(null);\n setIsLoading(false);\n setIsFailed(true);\n }\n },\n );\n\n return () => {\n cancelled = true;\n };\n }, [filterQuery, isDropdownOpened, isSourceFunction, requestVersion]);\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 const retry = useCallback(() => setRequestVersion((version) => version + 1), []);\n\n return { items, fetchedQuery, isLoading, isFailed, retry };\n};\n"]}
@@ -4,6 +4,12 @@ interface UseTimePickerValueOptions {
4
4
  isInputFocused: boolean;
5
5
  /** Внешнее значение, приведенное к строке времени. */
6
6
  externalValue: string;
7
+ /**
8
+ * Значением управляет родитель: проп `value` задан.
9
+ * Если проп не задан, компонент неконтролируемый и хранит значение сам,
10
+ * поэтому внешнее пустое значение не должно затирать введенное пользователем.
11
+ */
12
+ isValueControlled: boolean;
7
13
  format: TimeFormat;
8
14
  /**
9
15
  * Вызывается при коммите значения: получает нормализованное время
@@ -15,13 +21,18 @@ interface UseTimePickerValueOptions {
15
21
  interface UseTimePickerValueResult {
16
22
  editingValue: string;
17
23
  editingValueRef: RefObject<string>;
18
- setEditingValue(value: string): void;
24
+ /**
25
+ * Последнее закоммиченное время в нормализованной форме.
26
+ * Правка значения его не меняет, поэтому в меню отмечено выбранным именно значение поля,
27
+ * а не время, которое пользователь набирает.
28
+ */
29
+ committedValue: string;
19
30
  updateEditingValue(value: string): void;
20
- commitEditingValue(): string;
31
+ commitEditingValue(): void;
21
32
  /** Коммитит значение, введенное пользователем. Не эмитит повторно то же самое время. */
22
- commitValue(value: string, item?: TimeItemValue | null): string;
33
+ commitValue(value: string, item?: TimeItemValue | null): void;
23
34
  /** Коммитит элемент, выбранный в выпадающем меню. Эмитит всегда, так как это явное действие пользователя. */
24
- commitItem(item: TimeItemValue): string;
35
+ commitItem(item: TimeItemValue): void;
25
36
  }
26
37
  export declare const useTimePickerValue: (options: UseTimePickerValueOptions) => UseTimePickerValueResult;
27
38
  export {};
@@ -1,20 +1,25 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
- import { EMPTY_VALUE } from '../helpers/TimePicker.constants.js';
2
+ import warning from 'warning';
3
3
  import { getTimeItemValue } from '../helpers/TimePicker.shared.js';
4
- import { getTimeDisplayValue, isTimeDisplayEmpty, normalizeTimeValue, serializeTimeValue, } from '../helpers/TimePicker.value.js';
4
+ import { getExternalTimeDisplayValue, normalizeTimeValue, serializeTimeValue } from '../helpers/TimePicker.value.js';
5
5
  export var useTimePickerValue = function (options) {
6
- var externalValue = options.externalValue, format = options.format, isInputFocused = options.isInputFocused, onCommitValue = options.onCommitValue, onInputValueChange = options.onInputValueChange;
7
- var externalEditingValue = getTimeDisplayValue(externalValue, format);
6
+ var externalValue = options.externalValue, isValueControlled = options.isValueControlled, format = options.format, isInputFocused = options.isInputFocused, onCommitValue = options.onCommitValue, onInputValueChange = options.onInputValueChange;
7
+ var externalEditingValue = getExternalTimeDisplayValue(externalValue, format);
8
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];
9
10
  var editingValueRef = useRef(editingValue);
11
+ /** Последнее значение, отданное в `onInputValueChange`, — как есть, без нормализации. */
10
12
  var emittedInputValueRef = useRef(externalValue);
13
+ /**
14
+ * Последнее закоммиченное время в нормализованной форме.
15
+ * Форма именно нормализованная, иначе внешнее `9:00` или `09:00:00` в формате `HH:mm`
16
+ * выглядело бы как изменение и поле коммитило бы его заново, собирая элемент вместо исходного.
17
+ */
11
18
  var emittedValueRef = useRef(externalValue);
12
- var lastEmittedValueRef = useRef(externalValue);
13
19
  var syncEmittedValues = useCallback(function (nextValue) {
14
20
  emittedInputValueRef.current = nextValue;
15
- emittedValueRef.current = nextValue;
16
- lastEmittedValueRef.current = nextValue;
17
- }, []);
21
+ emittedValueRef.current = normalizeTimeValue(nextValue, format);
22
+ }, [format]);
18
23
  var setEditingValue = useCallback(function (nextEditingValue) {
19
24
  editingValueRef.current = nextEditingValue;
20
25
  setEditingValueState(nextEditingValue);
@@ -22,13 +27,12 @@ export var useTimePickerValue = function (options) {
22
27
  var emitInputValue = useCallback(function (nextValue) {
23
28
  if (emittedInputValueRef.current !== nextValue) {
24
29
  emittedInputValueRef.current = nextValue;
25
- lastEmittedValueRef.current = nextValue;
26
30
  onInputValueChange === null || onInputValueChange === void 0 ? void 0 : onInputValueChange(nextValue);
27
31
  }
28
32
  }, [onInputValueChange]);
29
33
  var emitValue = useCallback(function (nextValue, item) {
34
+ emittedInputValueRef.current = nextValue;
30
35
  emittedValueRef.current = nextValue;
31
- lastEmittedValueRef.current = nextValue;
32
36
  onCommitValue(nextValue, item);
33
37
  }, [onCommitValue]);
34
38
  var updateEditingValue = useCallback(function (nextEditingValue) {
@@ -39,34 +43,50 @@ export var useTimePickerValue = function (options) {
39
43
  if (item === void 0) { item = null; }
40
44
  var normalizedValue = normalizeTimeValue(nextValue, format);
41
45
  setEditingValue(normalizedValue);
46
+ setCommittedValue(normalizedValue);
42
47
  if (emittedValueRef.current !== normalizedValue) {
43
48
  emitValue(normalizedValue, item);
44
49
  }
45
- return normalizedValue;
46
50
  }, [emitValue, format, setEditingValue]);
47
51
  var commitItem = useCallback(function (item) {
48
52
  var normalizedValue = normalizeTimeValue(getTimeItemValue(item), format);
49
53
  setEditingValue(normalizedValue);
54
+ setCommittedValue(normalizedValue);
50
55
  emitValue(normalizedValue, item);
51
- return normalizedValue;
52
56
  }, [emitValue, format, setEditingValue]);
53
57
  var commitEditingValue = useCallback(function () {
54
- var currentEditingValue = editingValueRef.current;
55
- if (isTimeDisplayEmpty(currentEditingValue)) {
56
- return commitValue(EMPTY_VALUE);
57
- }
58
- return commitValue(currentEditingValue);
58
+ commitValue(editingValueRef.current);
59
59
  }, [commitValue, editingValueRef]);
60
+ var initialIsValueControlledRef = useRef(isValueControlled);
61
+ useEffect(function () {
62
+ warning(initialIsValueControlledRef.current === isValueControlled, isValueControlled
63
+ ? '[TimePicker]: a component is changing an uncontrolled value to be controlled. ' +
64
+ 'Decide between using a controlled or uncontrolled value for the lifetime of the component.'
65
+ : '[TimePicker]: a component is changing a controlled value to be uncontrolled. ' +
66
+ 'Pass an empty string or null instead of undefined to keep the value controlled.');
67
+ }, [isValueControlled]);
60
68
  useEffect(function () {
61
- if (!isInputFocused || externalValue !== lastEmittedValueRef.current) {
69
+ if (!isValueControlled) {
70
+ return;
71
+ }
72
+ if (!isInputFocused || externalValue !== emittedInputValueRef.current) {
62
73
  setEditingValue(externalEditingValue);
63
74
  }
75
+ setCommittedValue(normalizeTimeValue(externalValue, format));
64
76
  syncEmittedValues(externalValue);
65
- }, [externalEditingValue, externalValue, isInputFocused, setEditingValue, syncEmittedValues]);
77
+ }, [
78
+ externalEditingValue,
79
+ externalValue,
80
+ format,
81
+ isInputFocused,
82
+ isValueControlled,
83
+ setEditingValue,
84
+ syncEmittedValues,
85
+ ]);
66
86
  return {
67
87
  editingValue: editingValue,
68
88
  editingValueRef: editingValueRef,
69
- setEditingValue: setEditingValue,
89
+ committedValue: committedValue,
70
90
  updateEditingValue: updateEditingValue,
71
91
  commitEditingValue: commitEditingValue,
72
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';\n\nimport { EMPTY_VALUE } from '../helpers/TimePicker.constants.js';\nimport { getTimeItemValue, type TimeFormat, type TimeItemValue } from '../helpers/TimePicker.shared.js';\nimport {\n getTimeDisplayValue,\n isTimeDisplayEmpty,\n normalizeTimeValue,\n serializeTimeValue,\n} from '../helpers/TimePicker.value.js';\n\ninterface UseTimePickerValueOptions {\n isInputFocused: boolean;\n /** Внешнее значение, приведенное к строке времени. */\n externalValue: string;\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, format, isInputFocused, onCommitValue, onInputValueChange } = options;\n\n const externalEditingValue = getTimeDisplayValue(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 const syncEmittedValues = useCallback((nextValue: string) => {\n emittedInputValueRef.current = nextValue;\n emittedValueRef.current = nextValue;\n lastEmittedValueRef.current = nextValue;\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 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 useEffect(() => {\n if (!isInputFocused || externalValue !== lastEmittedValueRef.current) {\n setEditingValue(externalEditingValue);\n }\n\n syncEmittedValues(externalValue);\n }, [externalEditingValue, externalValue, isInputFocused, 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,2 +1,4 @@
1
1
  export * from './TimePicker.js';
2
- export type { TimeFormat, TimeSegment, TimeItem, TimeItemValue, TimePickerExtendedItem, TimePickerMenuItem, TimePickerResolvedItem, TimePickerSource, TimePickerValue, TimePickerValueToItem, } from './helpers/TimePicker.shared.js';
2
+ export { TimePickerDataTids } from './helpers/TimePicker.constants.js';
3
+ export type { TimePickerValidationOptions } from './helpers/validateTimePicker.js';
4
+ export type { TimeFormat, TimeSegment, TimeItem, TimeItemValue, TimePickerExtendedItem, TimePickerMenuElement, TimePickerMenuItem, TimePickerResolvedItem, TimePickerSource, TimePickerValue, TimePickerValueToItem, } from './helpers/TimePicker.shared.js';
@@ -1,2 +1,3 @@
1
1
  export * from './TimePicker.js';
2
+ export { TimePickerDataTids } from './helpers/TimePicker.constants.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC","sourcesContent":["export * from './TimePicker.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"]}
@@ -1,5 +1,7 @@
1
1
  export var componentsLocales = {
2
2
  ariaPlaceholderHHMM: 'hh:mm',
3
3
  ariaPlaceholderHHMMSS: 'hh:mm:ss',
4
+ errorNetworkButton: 'Refresh',
5
+ errorNetworkMessage: 'Something went wrong. Check your internet connection and try again',
4
6
  };
5
7
  //# sourceMappingURL=en.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"en.js","sourceRoot":"","sources":["en.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,IAAM,iBAAiB,GAAqB;IACjD,mBAAmB,EAAE,OAAO;IAC5B,qBAAqB,EAAE,UAAU;CAClC,CAAC","sourcesContent":["import type { TimePickerLocale } from '../types.js';\n\nexport const componentsLocales: TimePickerLocale = {\n ariaPlaceholderHHMM: 'hh:mm',\n ariaPlaceholderHHMMSS: 'hh:mm:ss',\n};\n"]}
1
+ {"version":3,"file":"en.js","sourceRoot":"","sources":["en.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,IAAM,iBAAiB,GAAqB;IACjD,mBAAmB,EAAE,OAAO;IAC5B,qBAAqB,EAAE,UAAU;IACjC,kBAAkB,EAAE,SAAS;IAC7B,mBAAmB,EAAE,oEAAoE;CAC1F,CAAC","sourcesContent":["import type { TimePickerLocale } from '../types.js';\n\nexport const componentsLocales: TimePickerLocale = {\n ariaPlaceholderHHMM: 'hh:mm',\n ariaPlaceholderHHMMSS: 'hh:mm:ss',\n errorNetworkButton: 'Refresh',\n errorNetworkMessage: 'Something went wrong. Check your internet connection and try again',\n};\n"]}
@@ -1,5 +1,7 @@
1
1
  export var componentsLocales = {
2
2
  ariaPlaceholderHHMM: 'чч:мм',
3
3
  ariaPlaceholderHHMMSS: 'чч:мм:сс',
4
+ errorNetworkButton: 'Обновить',
5
+ errorNetworkMessage: 'Что-то пошло не так. Проверьте соединение с интернетом и попробуйте еще раз',
4
6
  };
5
7
  //# sourceMappingURL=ru.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ru.js","sourceRoot":"","sources":["ru.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,IAAM,iBAAiB,GAAqB;IACjD,mBAAmB,EAAE,OAAO;IAC5B,qBAAqB,EAAE,UAAU;CAClC,CAAC","sourcesContent":["import type { TimePickerLocale } from '../types.js';\n\nexport const componentsLocales: TimePickerLocale = {\n ariaPlaceholderHHMM: 'чч:мм',\n ariaPlaceholderHHMMSS: 'чч:мм:сс',\n};\n"]}
1
+ {"version":3,"file":"ru.js","sourceRoot":"","sources":["ru.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,IAAM,iBAAiB,GAAqB;IACjD,mBAAmB,EAAE,OAAO;IAC5B,qBAAqB,EAAE,UAAU;IACjC,kBAAkB,EAAE,UAAU;IAC9B,mBAAmB,EAAE,6EAA6E;CACnG,CAAC","sourcesContent":["import type { TimePickerLocale } from '../types.js';\n\nexport const componentsLocales: TimePickerLocale = {\n ariaPlaceholderHHMM: 'чч:мм',\n ariaPlaceholderHHMMSS: 'чч:мм:сс',\n errorNetworkButton: 'Обновить',\n errorNetworkMessage: 'Что-то пошло не так. Проверьте соединение с интернетом и попробуйте еще раз',\n};\n"]}
@@ -1,4 +1,6 @@
1
1
  export interface TimePickerLocale {
2
2
  ariaPlaceholderHHMM: string;
3
3
  ariaPlaceholderHHMMSS: string;
4
+ errorNetworkButton: string;
5
+ errorNetworkMessage: string;
4
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["export interface TimePickerLocale {\n ariaPlaceholderHHMM: string;\n ariaPlaceholderHHMMSS: string;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["export interface TimePickerLocale {\n ariaPlaceholderHHMM: string;\n ariaPlaceholderHHMMSS: string;\n errorNetworkButton: string;\n errorNetworkMessage: string;\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import React from 'react';
1
2
  import type { TimeFormat } from '../../components/TimePicker/index.js';
2
3
  import type { Nullable } from '../../typings/utility-types.js';
3
4
  export interface NativeTimeInputProps {
@@ -8,9 +9,12 @@ export interface NativeTimeInputProps {
8
9
  minTime?: Nullable<string>;
9
10
  maxTime?: Nullable<string>;
10
11
  onValueChange?(value: string): void;
12
+ onBlur?(event: React.FocusEvent<HTMLInputElement>): void;
11
13
  }
12
14
  export interface NativeTimeInputRef {
13
15
  focus(): void;
16
+ blur(): void;
14
17
  click(): void;
18
+ getNode(): HTMLInputElement | null;
15
19
  }
16
20
  export declare const NativeTimeInput: import("../../lib/forwardRefAndName.js").ReactUIComponentWithRef<NativeTimeInputRef, NativeTimeInputProps> & Record<never, never>;
@@ -5,7 +5,7 @@ import { getJsStyles } from './NativeTimeInput.styles.js';
5
5
  import { getDefaultMaxTime, getDefaultMinTime, getNativeTimeStep, getTimeForComponent, getTimeForNative, } from './NativeTimeInput.utils.js';
6
6
  export var NativeTimeInput = forwardRefAndName('NativeTimeInput', function (props, ref) {
7
7
  var _a;
8
- var value = props.value, minTime = props.minTime, maxTime = props.maxTime, format = props.format, disabled = props.disabled, onValueChange = props.onValueChange, dataTid = props["data-tid"];
8
+ var value = props.value, minTime = props.minTime, maxTime = props.maxTime, format = props.format, disabled = props.disabled, onValueChange = props.onValueChange, onBlur = props.onBlur, dataTid = props["data-tid"];
9
9
  var jsStyles = getJsStyles(useEmotion());
10
10
  var inputRef = useRef(null);
11
11
  useImperativeHandle(ref, function () { return ({
@@ -13,12 +13,17 @@ export var NativeTimeInput = forwardRefAndName('NativeTimeInput', function (prop
13
13
  var _a;
14
14
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
15
15
  },
16
+ blur: function () {
17
+ var _a;
18
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.blur();
19
+ },
16
20
  click: function () {
17
21
  var _a;
18
22
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
19
23
  },
24
+ getNode: function () { return inputRef.current; },
20
25
  }); }, []);
21
- return (React.createElement("input", { type: 'time', "data-tid": dataTid, ref: inputRef, disabled: disabled, className: jsStyles.inputTypeTime(), tabIndex: -1, step: getNativeTimeStep(format), min: minTime ? getTimeForNative(minTime, format) : getDefaultMinTime(format), max: maxTime ? getTimeForNative(maxTime, format) : getDefaultMaxTime(format), value: (_a = getTimeForNative(value, format)) !== null && _a !== void 0 ? _a : '', onChange: function (event) {
26
+ return (React.createElement("input", { type: 'time', "data-tid": dataTid, ref: inputRef, disabled: disabled, className: jsStyles.inputTypeTime(), tabIndex: -1, step: getNativeTimeStep(format), min: minTime ? getTimeForNative(minTime, format) : getDefaultMinTime(format), max: maxTime ? getTimeForNative(maxTime, format) : getDefaultMaxTime(format), value: (_a = getTimeForNative(value, format)) !== null && _a !== void 0 ? _a : '', onBlur: onBlur, onChange: function (event) {
22
27
  onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(getTimeForComponent(event.target.value, format));
23
28
  } }));
24
29
  });
@@ -1 +1 @@
1
- {"version":3,"file":"NativeTimeInput.js","sourceRoot":"","sources":["NativeTimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AAiBpC,MAAM,CAAC,IAAM,eAAe,GAAG,iBAAiB,CAC9C,iBAAiB,EACjB,UAAC,KAAK,EAAE,GAAG;;IACD,IAAA,KAAK,GAA6E,KAAK,MAAlF,EAAE,OAAO,GAAoE,KAAK,QAAzE,EAAE,OAAO,GAA2D,KAAK,QAAhE,EAAE,MAAM,GAAmD,KAAK,OAAxD,EAAE,QAAQ,GAAyC,KAAK,SAA9C,EAAE,aAAa,GAA0B,KAAK,cAA/B,EAAc,OAAO,GAAK,KAAK,YAAV,CAAW;IAEhG,IAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3C,IAAM,QAAQ,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;IAEvD,mBAAmB,CACjB,GAAG,EACH,cAAM,OAAA,CAAC;QACL,KAAK;;YACH,MAAA,QAAQ,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QACD,KAAK;;YACH,MAAA,QAAQ,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;KACF,CAAC,EAPI,CAOJ,EACF,EAAE,CACH,CAAC;IAEF,OAAO,CACL,+BACE,IAAI,EAAE,MAAM,cACF,OAAO,EACjB,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,QAAQ,CAAC,aAAa,EAAE,EACnC,QAAQ,EAAE,CAAC,CAAC,EACZ,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAC/B,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAC5E,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAC5E,KAAK,EAAE,MAAA,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,mCAAI,EAAE,EAC5C,QAAQ,EAAE,UAAC,KAAK;YACd,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QACnE,CAAC,GACD,CACH,CAAC;AACJ,CAAC,CACF,CAAC","sourcesContent":["import React, { useImperativeHandle, useRef } from 'react';\n\nimport type { TimeFormat } from '../../components/TimePicker/index.js';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport { useEmotion } from '../../lib/renderEnvironment/index.js';\nimport type { Nullable } from '../../typings/utility-types.js';\nimport { getJsStyles } from './NativeTimeInput.styles.js';\nimport {\n getDefaultMaxTime,\n getDefaultMinTime,\n getNativeTimeStep,\n getTimeForComponent,\n getTimeForNative,\n} from './NativeTimeInput.utils.js';\n\nexport interface NativeTimeInputProps {\n 'data-tid'?: string;\n disabled?: boolean;\n format: TimeFormat;\n value: Nullable<string>;\n minTime?: Nullable<string>;\n maxTime?: Nullable<string>;\n onValueChange?(value: string): void;\n}\n\nexport interface NativeTimeInputRef {\n focus(): void;\n click(): void;\n}\n\nexport const NativeTimeInput = forwardRefAndName<NativeTimeInputRef, NativeTimeInputProps>(\n 'NativeTimeInput',\n (props, ref) => {\n const { value, minTime, maxTime, format, disabled, onValueChange, 'data-tid': dataTid } = props;\n\n const jsStyles = getJsStyles(useEmotion());\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n useImperativeHandle(\n ref,\n () => ({\n focus() {\n inputRef.current?.focus();\n },\n click() {\n inputRef.current?.click();\n },\n }),\n [],\n );\n\n return (\n <input\n type={'time'}\n data-tid={dataTid}\n ref={inputRef}\n disabled={disabled}\n className={jsStyles.inputTypeTime()}\n tabIndex={-1}\n step={getNativeTimeStep(format)}\n min={minTime ? getTimeForNative(minTime, format) : getDefaultMinTime(format)}\n max={maxTime ? getTimeForNative(maxTime, format) : getDefaultMaxTime(format)}\n value={getTimeForNative(value, format) ?? ''}\n onChange={(event) => {\n onValueChange?.(getTimeForComponent(event.target.value, format));\n }}\n />\n );\n },\n);\n"]}
1
+ {"version":3,"file":"NativeTimeInput.js","sourceRoot":"","sources":["NativeTimeInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AAoBpC,MAAM,CAAC,IAAM,eAAe,GAAG,iBAAiB,CAC9C,iBAAiB,EACjB,UAAC,KAAK,EAAE,GAAG;;IACD,IAAA,KAAK,GAAqF,KAAK,MAA1F,EAAE,OAAO,GAA4E,KAAK,QAAjF,EAAE,OAAO,GAAmE,KAAK,QAAxE,EAAE,MAAM,GAA2D,KAAK,OAAhE,EAAE,QAAQ,GAAiD,KAAK,SAAtD,EAAE,aAAa,GAAkC,KAAK,cAAvC,EAAE,MAAM,GAA0B,KAAK,OAA/B,EAAc,OAAO,GAAK,KAAK,YAAV,CAAW;IAExG,IAAM,QAAQ,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;IAC3C,IAAM,QAAQ,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;IAEvD,mBAAmB,CACjB,GAAG,EACH,cAAM,OAAA,CAAC;QACL,KAAK;;YACH,MAAA,QAAQ,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI;;YACF,MAAA,QAAQ,CAAC,OAAO,0CAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QACD,KAAK;;YACH,MAAA,QAAQ,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,EAAE,cAAM,OAAA,QAAQ,CAAC,OAAO,EAAhB,CAAgB;KAChC,CAAC,EAXI,CAWJ,EACF,EAAE,CACH,CAAC;IAEF,OAAO,CACL,+BACE,IAAI,EAAE,MAAM,cACF,OAAO,EACjB,GAAG,EAAE,QAAQ,EACb,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,QAAQ,CAAC,aAAa,EAAE,EACnC,QAAQ,EAAE,CAAC,CAAC,EACZ,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAC/B,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAC5E,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAC5E,KAAK,EAAE,MAAA,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,mCAAI,EAAE,EAC5C,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,UAAC,KAAK;YACd,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QACnE,CAAC,GACD,CACH,CAAC;AACJ,CAAC,CACF,CAAC","sourcesContent":["import React, { useImperativeHandle, useRef } from 'react';\n\nimport type { TimeFormat } from '../../components/TimePicker/index.js';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport { useEmotion } from '../../lib/renderEnvironment/index.js';\nimport type { Nullable } from '../../typings/utility-types.js';\nimport { getJsStyles } from './NativeTimeInput.styles.js';\nimport {\n getDefaultMaxTime,\n getDefaultMinTime,\n getNativeTimeStep,\n getTimeForComponent,\n getTimeForNative,\n} from './NativeTimeInput.utils.js';\n\nexport interface NativeTimeInputProps {\n 'data-tid'?: string;\n disabled?: boolean;\n format: TimeFormat;\n value: Nullable<string>;\n minTime?: Nullable<string>;\n maxTime?: Nullable<string>;\n onValueChange?(value: string): void;\n onBlur?(event: React.FocusEvent<HTMLInputElement>): void;\n}\n\nexport interface NativeTimeInputRef {\n focus(): void;\n blur(): void;\n click(): void;\n getNode(): HTMLInputElement | null;\n}\n\nexport const NativeTimeInput = forwardRefAndName<NativeTimeInputRef, NativeTimeInputProps>(\n 'NativeTimeInput',\n (props, ref) => {\n const { value, minTime, maxTime, format, disabled, onValueChange, onBlur, 'data-tid': dataTid } = props;\n\n const jsStyles = getJsStyles(useEmotion());\n const inputRef = useRef<HTMLInputElement | null>(null);\n\n useImperativeHandle(\n ref,\n () => ({\n focus() {\n inputRef.current?.focus();\n },\n blur() {\n inputRef.current?.blur();\n },\n click() {\n inputRef.current?.click();\n },\n getNode: () => inputRef.current,\n }),\n [],\n );\n\n return (\n <input\n type={'time'}\n data-tid={dataTid}\n ref={inputRef}\n disabled={disabled}\n className={jsStyles.inputTypeTime()}\n tabIndex={-1}\n step={getNativeTimeStep(format)}\n min={minTime ? getTimeForNative(minTime, format) : getDefaultMinTime(format)}\n max={maxTime ? getTimeForNative(maxTime, format) : getDefaultMaxTime(format)}\n value={getTimeForNative(value, format) ?? ''}\n onBlur={onBlur}\n onChange={(event) => {\n onValueChange?.(getTimeForComponent(event.target.value, format));\n }}\n />\n );\n },\n);\n"]}
@@ -1,6 +1,8 @@
1
1
  import type { TimeFormat } from '../../components/TimePicker/index.js';
2
2
  import type { Nullable } from '../../typings/utility-types.js';
3
+ /** Приводит время компонента к форме нативного инпута. Пустое значение отдается как отсутствующее. */
3
4
  export declare const getTimeForNative: (componentTime: Nullable<string>, format: TimeFormat) => string | undefined;
5
+ /** Приводит время нативного инпута к форме компонента. Пустое значение отдается пустой строкой. */
4
6
  export declare const getTimeForComponent: (nativeTime: Nullable<string>, format: TimeFormat) => string;
5
7
  export declare const getDefaultMinTime: (format: TimeFormat) => string;
6
8
  export declare const getDefaultMaxTime: (format: TimeFormat) => string;
@@ -6,17 +6,13 @@ var normalizeNativeTime = function (value, format) {
6
6
  var normalizedTime = "".concat(padTimePart(hours), ":").concat(padTimePart(minutes), ":").concat(padTimePart(seconds));
7
7
  return format === 'HH:mm' ? normalizedTime.slice(0, 5) : normalizedTime;
8
8
  };
9
+ /** Приводит время компонента к форме нативного инпута. Пустое значение отдается как отсутствующее. */
9
10
  export var getTimeForNative = function (componentTime, format) {
10
- if (!componentTime) {
11
- return undefined;
12
- }
13
- return normalizeNativeTime(componentTime, format);
11
+ return componentTime ? normalizeNativeTime(componentTime, format) : undefined;
14
12
  };
13
+ /** Приводит время нативного инпута к форме компонента. Пустое значение отдается пустой строкой. */
15
14
  export var getTimeForComponent = function (nativeTime, format) {
16
- if (!nativeTime) {
17
- return '';
18
- }
19
- return normalizeNativeTime(nativeTime, format);
15
+ return nativeTime ? normalizeNativeTime(nativeTime, format) : '';
20
16
  };
21
17
  export var getDefaultMinTime = function (format) {
22
18
  return format === 'HH:mm' ? DEFAULT_NATIVE_MIN_TIME.slice(0, 5) : DEFAULT_NATIVE_MIN_TIME;