@skbkontur/react-ui 6.2.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/components/Group/Group.js +3 -2
  3. package/components/Group/Group.js.map +1 -1
  4. package/components/Input/Input.d.ts +1 -1
  5. package/components/Input/Input.js.map +1 -1
  6. package/components/MenuItem/MenuItem.d.ts +1 -1
  7. package/components/MenuItem/MenuItem.js.map +1 -1
  8. package/components/Switcher/Switcher.d.ts +1 -1
  9. package/components/Switcher/Switcher.js +1 -1
  10. package/components/Switcher/Switcher.js.map +1 -1
  11. package/components/TimePicker/TimeClockIcon.d.ts +3 -0
  12. package/components/TimePicker/TimeClockIcon.js +11 -0
  13. package/components/TimePicker/TimeClockIcon.js.map +1 -0
  14. package/components/TimePicker/TimePicker.d.ts +144 -0
  15. package/components/TimePicker/TimePicker.js +795 -0
  16. package/components/TimePicker/TimePicker.js.map +1 -0
  17. package/components/TimePicker/TimePicker.styles.d.ts +12 -0
  18. package/components/TimePicker/TimePicker.styles.js +39 -0
  19. package/components/TimePicker/TimePicker.styles.js.map +1 -0
  20. package/components/TimePicker/TimePickerItems.d.ts +23 -0
  21. package/components/TimePicker/TimePickerItems.js +115 -0
  22. package/components/TimePicker/TimePickerItems.js.map +1 -0
  23. package/components/TimePicker/TimePickerMobilePopup.d.ts +48 -0
  24. package/components/TimePicker/TimePickerMobilePopup.js +45 -0
  25. package/components/TimePicker/TimePickerMobilePopup.js.map +1 -0
  26. package/components/TimePicker/TimePickerPopup.d.ts +26 -0
  27. package/components/TimePicker/TimePickerPopup.js +18 -0
  28. package/components/TimePicker/TimePickerPopup.js.map +1 -0
  29. package/components/TimePicker/helpers/TimePicker.constants.d.ts +31 -0
  30. package/components/TimePicker/helpers/TimePicker.constants.js +34 -0
  31. package/components/TimePicker/helpers/TimePicker.constants.js.map +1 -0
  32. package/components/TimePicker/helpers/TimePicker.editing.d.ts +19 -0
  33. package/components/TimePicker/helpers/TimePicker.editing.js +74 -0
  34. package/components/TimePicker/helpers/TimePicker.editing.js.map +1 -0
  35. package/components/TimePicker/helpers/TimePicker.layout.d.ts +6 -0
  36. package/components/TimePicker/helpers/TimePicker.layout.js +49 -0
  37. package/components/TimePicker/helpers/TimePicker.layout.js.map +1 -0
  38. package/components/TimePicker/helpers/TimePicker.selection.d.ts +5 -0
  39. package/components/TimePicker/helpers/TimePicker.selection.js +23 -0
  40. package/components/TimePicker/helpers/TimePicker.selection.js.map +1 -0
  41. package/components/TimePicker/helpers/TimePicker.shared.d.ts +71 -0
  42. package/components/TimePicker/helpers/TimePicker.shared.js +90 -0
  43. package/components/TimePicker/helpers/TimePicker.shared.js.map +1 -0
  44. package/components/TimePicker/helpers/TimePicker.value.d.ts +69 -0
  45. package/components/TimePicker/helpers/TimePicker.value.js +225 -0
  46. package/components/TimePicker/helpers/TimePicker.value.js.map +1 -0
  47. package/components/TimePicker/helpers/scrollSelectedItemIntoView.d.ts +6 -0
  48. package/components/TimePicker/helpers/scrollSelectedItemIntoView.js +26 -0
  49. package/components/TimePicker/helpers/scrollSelectedItemIntoView.js.map +1 -0
  50. package/components/TimePicker/helpers/validateTimePicker.d.ts +8 -0
  51. package/components/TimePicker/helpers/validateTimePicker.js +16 -0
  52. package/components/TimePicker/helpers/validateTimePicker.js.map +1 -0
  53. package/components/TimePicker/index.d.ts +4 -0
  54. package/components/TimePicker/index.js +3 -0
  55. package/components/TimePicker/index.js.map +1 -0
  56. package/components/TimePicker/locale/index.d.ts +4 -0
  57. package/components/TimePicker/locale/index.js +9 -0
  58. package/components/TimePicker/locale/index.js.map +1 -0
  59. package/components/TimePicker/locale/locales/en.d.ts +2 -0
  60. package/components/TimePicker/locale/locales/en.js +7 -0
  61. package/components/TimePicker/locale/locales/en.js.map +1 -0
  62. package/components/TimePicker/locale/locales/ru.d.ts +2 -0
  63. package/components/TimePicker/locale/locales/ru.js +7 -0
  64. package/components/TimePicker/locale/locales/ru.js.map +1 -0
  65. package/components/TimePicker/locale/types.d.ts +6 -0
  66. package/components/TimePicker/locale/types.js +2 -0
  67. package/components/TimePicker/locale/types.js.map +1 -0
  68. package/index.d.ts +1 -0
  69. package/index.js +1 -0
  70. package/index.js.map +1 -1
  71. package/internal/NativeTimeInput/NativeTimeInput.d.ts +20 -0
  72. package/internal/NativeTimeInput/NativeTimeInput.js +30 -0
  73. package/internal/NativeTimeInput/NativeTimeInput.js.map +1 -0
  74. package/internal/NativeTimeInput/NativeTimeInput.styles.d.ts +3 -0
  75. package/internal/NativeTimeInput/NativeTimeInput.styles.js +15 -0
  76. package/internal/NativeTimeInput/NativeTimeInput.styles.js.map +1 -0
  77. package/internal/NativeTimeInput/NativeTimeInput.utils.d.ts +9 -0
  78. package/internal/NativeTimeInput/NativeTimeInput.utils.js +24 -0
  79. package/internal/NativeTimeInput/NativeTimeInput.utils.js.map +1 -0
  80. package/internal/NativeTimeInput/index.d.ts +1 -0
  81. package/internal/NativeTimeInput/index.js +2 -0
  82. package/internal/NativeTimeInput/index.js.map +1 -0
  83. package/internal/TimeInput/TimeFragments.d.ts +14 -0
  84. package/internal/TimeInput/TimeFragments.js +94 -0
  85. package/internal/TimeInput/TimeFragments.js.map +1 -0
  86. package/internal/TimeInput/TimeFragments.styles.d.ts +32 -0
  87. package/internal/TimeInput/TimeFragments.styles.js +78 -0
  88. package/internal/TimeInput/TimeFragments.styles.js.map +1 -0
  89. package/internal/TimeInput/TimeInput.d.ts +21 -0
  90. package/internal/TimeInput/TimeInput.js +104 -0
  91. package/internal/TimeInput/TimeInput.js.map +1 -0
  92. package/internal/TimeInput/TimeInput.styles.d.ts +7 -0
  93. package/internal/TimeInput/TimeInput.styles.js +24 -0
  94. package/internal/TimeInput/TimeInput.styles.js.map +1 -0
  95. package/internal/TimeInput/index.d.ts +1 -0
  96. package/internal/TimeInput/index.js +2 -0
  97. package/internal/TimeInput/index.js.map +1 -0
  98. package/internal/TimePicker/useTimePickerDropdown.d.ts +23 -0
  99. package/internal/TimePicker/useTimePickerDropdown.js +67 -0
  100. package/internal/TimePicker/useTimePickerDropdown.js.map +1 -0
  101. package/internal/TimePicker/useTimePickerSelection.d.ts +18 -0
  102. package/internal/TimePicker/useTimePickerSelection.js +66 -0
  103. package/internal/TimePicker/useTimePickerSelection.js.map +1 -0
  104. package/internal/TimePicker/useTimePickerSource.d.ts +29 -0
  105. package/internal/TimePicker/useTimePickerSource.js +67 -0
  106. package/internal/TimePicker/useTimePickerSource.js.map +1 -0
  107. package/internal/TimePicker/useTimePickerValue.d.ts +35 -0
  108. package/internal/TimePicker/useTimePickerValue.js +94 -0
  109. package/internal/TimePicker/useTimePickerValue.js.map +1 -0
  110. package/internal/icons2022/TimeClockIcon/TimeClockIcon16Light.d.ts +2 -0
  111. package/internal/icons2022/TimeClockIcon/TimeClockIcon16Light.js +20 -0
  112. package/internal/icons2022/TimeClockIcon/TimeClockIcon16Light.js.map +1 -0
  113. package/internal/icons2022/TimeClockIcon/TimeClockIcon20Light.d.ts +2 -0
  114. package/internal/icons2022/TimeClockIcon/TimeClockIcon20Light.js +20 -0
  115. package/internal/icons2022/TimeClockIcon/TimeClockIcon20Light.js.map +1 -0
  116. package/internal/icons2022/TimeClockIcon/TimeClockIcon24Regular.d.ts +2 -0
  117. package/internal/icons2022/TimeClockIcon/TimeClockIcon24Regular.js +20 -0
  118. package/internal/icons2022/TimeClockIcon/TimeClockIcon24Regular.js.map +1 -0
  119. package/internal/themes/BasicTheme.d.ts +34 -0
  120. package/internal/themes/BasicTheme.js +90 -0
  121. package/internal/themes/BasicTheme.js.map +1 -1
  122. package/internal/themes/DarkTheme6_0.js +3 -0
  123. package/internal/themes/DarkTheme6_0.js.map +1 -1
  124. package/internal/themes/DarkTheme6_2.d.ts +1 -0
  125. package/internal/themes/DarkTheme6_2.js +30 -0
  126. package/internal/themes/DarkTheme6_2.js.map +1 -0
  127. package/internal/themes/DarkTheme6_3.d.ts +1 -0
  128. package/internal/themes/DarkTheme6_3.js +30 -0
  129. package/internal/themes/DarkTheme6_3.js.map +1 -0
  130. package/internal/themes/LightTheme6_2.d.ts +1 -0
  131. package/internal/themes/LightTheme6_2.js +30 -0
  132. package/internal/themes/LightTheme6_2.js.map +1 -0
  133. package/internal/themes/LightTheme6_3.d.ts +1 -0
  134. package/internal/themes/LightTheme6_3.js +30 -0
  135. package/internal/themes/LightTheme6_3.js.map +1 -0
  136. package/lib/locale/types.d.ts +2 -0
  137. package/lib/locale/types.js.map +1 -1
  138. package/lib/theming/ThemeVersions.d.ts +1 -1
  139. package/lib/theming/ThemeVersions.js.map +1 -1
  140. package/lib/theming/themes/DarkTheme.d.ts +2 -0
  141. package/lib/theming/themes/DarkTheme.js +5 -1
  142. package/lib/theming/themes/DarkTheme.js.map +1 -1
  143. package/lib/theming/themes/LightTheme.d.ts +2 -0
  144. package/lib/theming/themes/LightTheme.js +5 -1
  145. package/lib/theming/themes/LightTheme.js.map +1 -1
  146. package/lib/utils.d.ts +2 -0
  147. package/lib/utils.js +1 -0
  148. package/lib/utils.js.map +1 -1
  149. package/package.json +11 -3
@@ -0,0 +1,24 @@
1
+ var DEFAULT_NATIVE_MIN_TIME = '00:00:00';
2
+ var DEFAULT_NATIVE_MAX_TIME = '23:59:59';
3
+ var padTimePart = function (value) { return (value !== null && value !== void 0 ? value : '00').padStart(2, '0'); };
4
+ var normalizeNativeTime = function (value, format) {
5
+ var _a = value.split(':'), hours = _a[0], minutes = _a[1], seconds = _a[2];
6
+ var normalizedTime = "".concat(padTimePart(hours), ":").concat(padTimePart(minutes), ":").concat(padTimePart(seconds));
7
+ return format === 'HH:mm' ? normalizedTime.slice(0, 5) : normalizedTime;
8
+ };
9
+ /** Приводит время компонента к форме нативного инпута. Пустое значение отдается как отсутствующее. */
10
+ export var getTimeForNative = function (componentTime, format) {
11
+ return componentTime ? normalizeNativeTime(componentTime, format) : undefined;
12
+ };
13
+ /** Приводит время нативного инпута к форме компонента. Пустое значение отдается пустой строкой. */
14
+ export var getTimeForComponent = function (nativeTime, format) {
15
+ return nativeTime ? normalizeNativeTime(nativeTime, format) : '';
16
+ };
17
+ export var getDefaultMinTime = function (format) {
18
+ return format === 'HH:mm' ? DEFAULT_NATIVE_MIN_TIME.slice(0, 5) : DEFAULT_NATIVE_MIN_TIME;
19
+ };
20
+ export var getDefaultMaxTime = function (format) {
21
+ return format === 'HH:mm' ? DEFAULT_NATIVE_MAX_TIME.slice(0, 5) : DEFAULT_NATIVE_MAX_TIME;
22
+ };
23
+ export var getNativeTimeStep = function (format) { return (format === 'HH:mm' ? 60 : 1); };
24
+ //# sourceMappingURL=NativeTimeInput.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeTimeInput.utils.js","sourceRoot":"","sources":["NativeTimeInput.utils.ts"],"names":[],"mappings":"AAGA,IAAM,uBAAuB,GAAG,UAAU,CAAC;AAC3C,IAAM,uBAAuB,GAAG,UAAU,CAAC;AAE3C,IAAM,WAAW,GAAG,UAAC,KAAyB,IAAa,OAAA,CAAC,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAhC,CAAgC,CAAC;AAE5F,IAAM,mBAAmB,GAAG,UAAC,KAAa,EAAE,MAAkB;IACtD,IAAA,KAA4B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAA3C,KAAK,QAAA,EAAE,OAAO,QAAA,EAAE,OAAO,QAAoB,CAAC;IAEnD,IAAM,cAAc,GAAG,UAAG,WAAW,CAAC,KAAK,CAAC,cAAI,WAAW,CAAC,OAAO,CAAC,cAAI,WAAW,CAAC,OAAO,CAAC,CAAE,CAAC;IAE/F,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;AAC1E,CAAC,CAAC;AAEF,sGAAsG;AACtG,MAAM,CAAC,IAAM,gBAAgB,GAAG,UAAC,aAA+B,EAAE,MAAkB;IAClF,OAAA,aAAa,CAAC,CAAC,CAAC,mBAAmB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;AAAtE,CAAsE,CAAC;AAEzE,mGAAmG;AACnG,MAAM,CAAC,IAAM,mBAAmB,GAAG,UAAC,UAA4B,EAAE,MAAkB;IAClF,OAAA,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;AAAzD,CAAyD,CAAC;AAE5D,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,MAAkB;IAClD,OAAA,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;AAAlF,CAAkF,CAAC;AAErF,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,MAAkB;IAClD,OAAA,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;AAAlF,CAAkF,CAAC;AAErF,MAAM,CAAC,IAAM,iBAAiB,GAAG,UAAC,MAAkB,IAAa,OAAA,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAA7B,CAA6B,CAAC","sourcesContent":["import type { TimeFormat } from '../../components/TimePicker/index.js';\nimport type { Nullable } from '../../typings/utility-types.js';\n\nconst DEFAULT_NATIVE_MIN_TIME = '00:00:00';\nconst DEFAULT_NATIVE_MAX_TIME = '23:59:59';\n\nconst padTimePart = (value: string | undefined): string => (value ?? '00').padStart(2, '0');\n\nconst normalizeNativeTime = (value: string, format: TimeFormat): string => {\n const [hours, minutes, seconds] = value.split(':');\n\n const normalizedTime = `${padTimePart(hours)}:${padTimePart(minutes)}:${padTimePart(seconds)}`;\n\n return format === 'HH:mm' ? normalizedTime.slice(0, 5) : normalizedTime;\n};\n\n/** Приводит время компонента к форме нативного инпута. Пустое значение отдается как отсутствующее. */\nexport const getTimeForNative = (componentTime: Nullable<string>, format: TimeFormat): string | undefined =>\n componentTime ? normalizeNativeTime(componentTime, format) : undefined;\n\n/** Приводит время нативного инпута к форме компонента. Пустое значение отдается пустой строкой. */\nexport const getTimeForComponent = (nativeTime: Nullable<string>, format: TimeFormat): string =>\n nativeTime ? normalizeNativeTime(nativeTime, format) : '';\n\nexport const getDefaultMinTime = (format: TimeFormat): string =>\n format === 'HH:mm' ? DEFAULT_NATIVE_MIN_TIME.slice(0, 5) : DEFAULT_NATIVE_MIN_TIME;\n\nexport const getDefaultMaxTime = (format: TimeFormat): string =>\n format === 'HH:mm' ? DEFAULT_NATIVE_MAX_TIME.slice(0, 5) : DEFAULT_NATIVE_MAX_TIME;\n\nexport const getNativeTimeStep = (format: TimeFormat): number => (format === 'HH:mm' ? 60 : 1);\n"]}
@@ -0,0 +1 @@
1
+ export * from './NativeTimeInput.js';
@@ -0,0 +1,2 @@
1
+ export * from './NativeTimeInput.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC","sourcesContent":["export * from './NativeTimeInput.js';\n"]}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import type { TimeFormat, TimeSegment } from '../../components/TimePicker/index.js';
3
+ import type { SizeProp } from '../../lib/types/props.js';
4
+ export interface TimeFragmentsRef {
5
+ getSegment(el: HTMLElement | EventTarget | null): TimeSegment | null;
6
+ getRootNode(): HTMLSpanElement | null;
7
+ }
8
+ export interface TimeFragmentsProps {
9
+ value: string;
10
+ format: TimeFormat;
11
+ size: SizeProp;
12
+ onSelectSegment?(segment: TimeSegment, event: React.MouseEvent<HTMLSpanElement>): void;
13
+ }
14
+ export declare const TimeFragments: import("../../lib/forwardRefAndName.js").ReactUIComponentWithRef<TimeFragmentsRef, TimeFragmentsProps> & Record<never, never>;
@@ -0,0 +1,94 @@
1
+ import React, { useCallback, useContext, useImperativeHandle, useRef } from 'react';
2
+ import { TIME_PLACEHOLDER_CHAR, TIME_SEPARATOR } from '../../components/TimePicker/helpers/TimePicker.constants.js';
3
+ import { getDisplaySegments, getTimeSegments } from '../../components/TimePicker/helpers/TimePicker.shared.js';
4
+ import { forwardRefAndName } from '../../lib/forwardRefAndName.js';
5
+ import { useEmotion, useStyles } from '../../lib/renderEnvironment/index.js';
6
+ import { ThemeContext } from '../../lib/theming/ThemeContext.js';
7
+ import { getStyles } from './TimeFragments.styles.js';
8
+ var getEmptyPlaceholderClassName = function (styles, theme, size, format) {
9
+ if (format === 'HH:mm:ss') {
10
+ switch (size) {
11
+ case 'large':
12
+ return styles.emptyPlaceholderWithSecondsLarge(theme);
13
+ case 'medium':
14
+ return styles.emptyPlaceholderWithSecondsMedium(theme);
15
+ case 'small':
16
+ default:
17
+ return styles.emptyPlaceholderWithSecondsSmall(theme);
18
+ }
19
+ }
20
+ switch (size) {
21
+ case 'large':
22
+ return styles.emptyPlaceholderLarge(theme);
23
+ case 'medium':
24
+ return styles.emptyPlaceholderMedium(theme);
25
+ case 'small':
26
+ default:
27
+ return styles.emptyPlaceholderSmall(theme);
28
+ }
29
+ };
30
+ var getSeparatorSizeClassName = function (styles, theme, size) {
31
+ switch (size) {
32
+ case 'large':
33
+ return styles.separatorLarge(theme);
34
+ case 'medium':
35
+ return styles.separatorMedium(theme);
36
+ case 'small':
37
+ default:
38
+ return styles.separatorSmall(theme);
39
+ }
40
+ };
41
+ export var TimeFragments = forwardRefAndName('TimeFragments', function (props, ref) {
42
+ var _a;
43
+ var value = props.value, format = props.format, size = props.size, onSelectSegment = props.onSelectSegment;
44
+ var theme = useContext(ThemeContext);
45
+ var cx = useEmotion().cx;
46
+ var styles = useStyles(getStyles);
47
+ var rootRef = useRef(null);
48
+ var rootClassName = cx(styles.root(), styles.selected(theme), (_a = {},
49
+ _a[getEmptyPlaceholderClassName(styles, theme, size, format)] = !value,
50
+ _a));
51
+ var maskClassName = styles.mask(theme);
52
+ var separatorSizeClassName = getSeparatorSizeClassName(styles, theme, size);
53
+ var getSegment = useCallback(function (el) {
54
+ var _a;
55
+ var rootNode = rootRef.current;
56
+ if (!rootNode || !el) {
57
+ return null;
58
+ }
59
+ var fragments = Array.from(rootNode.querySelectorAll('[data-fragment]'));
60
+ var segments = getTimeSegments(format);
61
+ var index = fragments.findIndex(function (fragment) { return fragment === el || fragment.contains(el); });
62
+ return index >= 0 ? ((_a = segments[index]) !== null && _a !== void 0 ? _a : null) : null;
63
+ }, [format]);
64
+ useImperativeHandle(ref, function () { return ({
65
+ getSegment: getSegment,
66
+ getRootNode: function () { return rootRef.current; },
67
+ }); }, [getSegment]);
68
+ var segments = getTimeSegments(format);
69
+ var displaySegments = getDisplaySegments(value, format);
70
+ return (React.createElement("span", { ref: rootRef, className: rootClassName }, value
71
+ ? segments.flatMap(function (segment, index) {
72
+ var _a;
73
+ var _b;
74
+ var segmentValue = (_b = displaySegments[index]) !== null && _b !== void 0 ? _b : '';
75
+ var valueMask = Array.from(segmentValue)
76
+ .filter(function (char) { return char !== TIME_PLACEHOLDER_CHAR; })
77
+ .join('');
78
+ var placeholderLength = segmentValue.length - valueMask.length;
79
+ var nodes = [
80
+ React.createElement("span", { key: segment, "data-fragment": '', className: styles.segment(), onMouseUp: function (event) { return onSelectSegment === null || onSelectSegment === void 0 ? void 0 : onSelectSegment(segment, event); } },
81
+ valueMask,
82
+ React.createElement("span", { className: maskClassName }, Array(placeholderLength).fill(TIME_PLACEHOLDER_CHAR).join(''))),
83
+ ];
84
+ if (index < segments.length - 1) {
85
+ nodes.push(React.createElement("span", { key: "separator-".concat(index), "data-separator": '', className: cx(maskClassName, styles.separator(), separatorSizeClassName, (_a = {},
86
+ _a[styles.separatorFilled()] = !segmentValue.includes(TIME_PLACEHOLDER_CHAR),
87
+ _a)) },
88
+ React.createElement("span", { "aria-hidden": true, className: styles.separatorText() }, TIME_SEPARATOR)));
89
+ }
90
+ return nodes;
91
+ })
92
+ : null));
93
+ });
94
+ //# sourceMappingURL=TimeFragments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeFragments.js","sourceRoot":"","sources":["TimeFragments.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback, useContext, useImperativeHandle, useRef } from 'react';\n\nimport { TIME_PLACEHOLDER_CHAR, TIME_SEPARATOR } from '../../components/TimePicker/helpers/TimePicker.constants.js';\nimport { getDisplaySegments, getTimeSegments } from '../../components/TimePicker/helpers/TimePicker.shared.js';\nimport type { TimeFormat, TimeSegment } from '../../components/TimePicker/index.js';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport { useEmotion, useStyles } from '../../lib/renderEnvironment/index.js';\nimport type { Theme } from '../../lib/theming/Theme.js';\nimport { ThemeContext } from '../../lib/theming/ThemeContext.js';\nimport type { SizeProp } from '../../lib/types/props.js';\nimport { getStyles } from './TimeFragments.styles.js';\n\nexport interface TimeFragmentsRef {\n getSegment(el: HTMLElement | EventTarget | null): TimeSegment | null;\n getRootNode(): HTMLSpanElement | null;\n}\n\nexport interface TimeFragmentsProps {\n value: string;\n format: TimeFormat;\n size: SizeProp;\n\n onSelectSegment?(segment: TimeSegment, event: React.MouseEvent<HTMLSpanElement>): void;\n}\n\nconst getEmptyPlaceholderClassName = (\n styles: ReturnType<typeof getStyles>,\n theme: Theme,\n size: SizeProp,\n format: TimeFormat,\n): string => {\n if (format === 'HH:mm:ss') {\n switch (size) {\n case 'large':\n return styles.emptyPlaceholderWithSecondsLarge(theme);\n case 'medium':\n return styles.emptyPlaceholderWithSecondsMedium(theme);\n case 'small':\n default:\n return styles.emptyPlaceholderWithSecondsSmall(theme);\n }\n }\n\n switch (size) {\n case 'large':\n return styles.emptyPlaceholderLarge(theme);\n case 'medium':\n return styles.emptyPlaceholderMedium(theme);\n case 'small':\n default:\n return styles.emptyPlaceholderSmall(theme);\n }\n};\n\nconst getSeparatorSizeClassName = (styles: ReturnType<typeof getStyles>, theme: Theme, size: SizeProp): string => {\n switch (size) {\n case 'large':\n return styles.separatorLarge(theme);\n case 'medium':\n return styles.separatorMedium(theme);\n case 'small':\n default:\n return styles.separatorSmall(theme);\n }\n};\n\nexport const TimeFragments = forwardRefAndName<TimeFragmentsRef, TimeFragmentsProps>('TimeFragments', (props, ref) => {\n const { value, format, size, onSelectSegment } = props;\n\n const theme = useContext(ThemeContext);\n\n const { cx } = useEmotion();\n\n const styles = useStyles(getStyles);\n\n const rootRef = useRef<HTMLSpanElement>(null);\n\n const rootClassName = cx(styles.root(), styles.selected(theme), {\n [getEmptyPlaceholderClassName(styles, theme, size, format)]: !value,\n });\n const maskClassName = styles.mask(theme);\n const separatorSizeClassName = getSeparatorSizeClassName(styles, theme, size);\n\n const getSegment = useCallback(\n (el: HTMLElement | EventTarget | null): TimeSegment | null => {\n const rootNode = rootRef.current;\n\n if (!rootNode || !el) {\n return null;\n }\n\n const fragments: HTMLSpanElement[] = Array.from(rootNode.querySelectorAll('[data-fragment]'));\n const segments = getTimeSegments(format);\n\n const index = fragments.findIndex((fragment) => fragment === el || fragment.contains(el as HTMLSpanElement));\n\n return index >= 0 ? (segments[index] ?? null) : null;\n },\n [format],\n );\n\n useImperativeHandle(\n ref,\n () => ({\n getSegment,\n getRootNode: () => rootRef.current,\n }),\n [getSegment],\n );\n\n const segments = getTimeSegments(format);\n const displaySegments = getDisplaySegments(value, format);\n\n return (\n <span ref={rootRef} className={rootClassName}>\n {value\n ? segments.flatMap((segment, index) => {\n const segmentValue = displaySegments[index] ?? '';\n\n const valueMask = Array.from(segmentValue)\n .filter((char) => char !== TIME_PLACEHOLDER_CHAR)\n .join('');\n\n const placeholderLength = segmentValue.length - valueMask.length;\n\n const nodes = [\n <span\n key={segment}\n data-fragment={''}\n className={styles.segment()}\n onMouseUp={(event) => onSelectSegment?.(segment, event)}\n >\n {valueMask}\n <span className={maskClassName}>{Array(placeholderLength).fill(TIME_PLACEHOLDER_CHAR).join('')}</span>\n </span>,\n ];\n\n if (index < segments.length - 1) {\n nodes.push(\n <span\n key={`separator-${index}`}\n data-separator={''}\n className={cx(maskClassName, styles.separator(), separatorSizeClassName, {\n [styles.separatorFilled()]: !segmentValue.includes(TIME_PLACEHOLDER_CHAR),\n })}\n >\n <span aria-hidden className={styles.separatorText()}>\n {TIME_SEPARATOR}\n </span>\n </span>,\n );\n }\n\n return nodes;\n })\n : null}\n </span>\n );\n});\n"]}
@@ -0,0 +1,32 @@
1
+ import type { Theme } from '../../lib/theming/Theme.js';
2
+ export declare const getStyles: import("../../lib/theming/Emotion.js").StylesGetter<{
3
+ root(): string;
4
+ /**
5
+ * Резервируют место под время, когда значения нет: без этого поле с suffix
6
+ * сужается на ширину времени, а при вводе снова расширяется.
7
+ * Плейсхолдер уходит в псевдоэлемент — он занимает ту же ширину, что и время,
8
+ * но не попадает в текст поля и не читается скринридером.
9
+ * Отступы разделителей есть только у отрисованного времени, поэтому их добавляем сюда сами:
10
+ * по одному `letter-spacing` на каждый разделитель — один в формате `HH:mm` и два в `HH:mm:ss`.
11
+ */
12
+ emptyPlaceholderSmall(t: Theme): string;
13
+ emptyPlaceholderMedium(t: Theme): string;
14
+ emptyPlaceholderLarge(t: Theme): string;
15
+ emptyPlaceholderWithSecondsSmall(t: Theme): string;
16
+ emptyPlaceholderWithSecondsMedium(t: Theme): string;
17
+ emptyPlaceholderWithSecondsLarge(t: Theme): string;
18
+ selected(t: Theme): string;
19
+ mask(t: Theme): string;
20
+ segment(): string;
21
+ separator(): string;
22
+ /**
23
+ * Разделитель рисует псевдоэлемент, а сам текст только держит место и попадает в выделение.
24
+ * В задизейбленном поле `-webkit-text-fill-color` приходит по наследству и перебивает `color`,
25
+ * поэтому гасим и его — иначе двоеточие отрисуется дважды.
26
+ */
27
+ separatorText(): string;
28
+ separatorSmall(t: Theme): string;
29
+ separatorMedium(t: Theme): string;
30
+ separatorLarge(t: Theme): string;
31
+ separatorFilled(): string;
32
+ }>;
@@ -0,0 +1,78 @@
1
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
2
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
3
+ return cooked;
4
+ };
5
+ import { getEmptyDisplayValue } from '../../components/TimePicker/helpers/TimePicker.value.js';
6
+ import { memoizeGetStyles } from '../../lib/theming/Emotion.js';
7
+ export var getStyles = memoizeGetStyles(function (_a) {
8
+ var css = _a.css;
9
+ return ({
10
+ root: function () {
11
+ return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n cursor: text;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n "], ["\n cursor: text;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n "])));
12
+ },
13
+ /**
14
+ * Резервируют место под время, когда значения нет: без этого поле с suffix
15
+ * сужается на ширину времени, а при вводе снова расширяется.
16
+ * Плейсхолдер уходит в псевдоэлемент — он занимает ту же ширину, что и время,
17
+ * но не попадает в текст поля и не читается скринридером.
18
+ * Отступы разделителей есть только у отрисованного времени, поэтому их добавляем сюда сами:
19
+ * по одному `letter-spacing` на каждый разделитель — один в формате `HH:mm` и два в `HH:mm:ss`.
20
+ */
21
+ emptyPlaceholderSmall: function (t) {
22
+ return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: ", ";\n }\n "], ["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: ", ";\n }\n "])), getEmptyDisplayValue('HH:mm'), t.timePickerSeparatorPaddingXSmall);
23
+ },
24
+ emptyPlaceholderMedium: function (t) {
25
+ return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: ", ";\n }\n "], ["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: ", ";\n }\n "])), getEmptyDisplayValue('HH:mm'), t.timePickerSeparatorPaddingXMedium);
26
+ },
27
+ emptyPlaceholderLarge: function (t) {
28
+ return css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: ", ";\n }\n "], ["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: ", ";\n }\n "])), getEmptyDisplayValue('HH:mm'), t.timePickerSeparatorPaddingXLarge);
29
+ },
30
+ emptyPlaceholderWithSecondsSmall: function (t) {
31
+ return css(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: calc(", " * 2);\n }\n "], ["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: calc(", " * 2);\n }\n "])), getEmptyDisplayValue('HH:mm:ss'), t.timePickerSeparatorPaddingXSmall);
32
+ },
33
+ emptyPlaceholderWithSecondsMedium: function (t) {
34
+ return css(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: calc(", " * 2);\n }\n "], ["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: calc(", " * 2);\n }\n "])), getEmptyDisplayValue('HH:mm:ss'), t.timePickerSeparatorPaddingXMedium);
35
+ },
36
+ emptyPlaceholderWithSecondsLarge: function (t) {
37
+ return css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: calc(", " * 2);\n }\n "], ["\n &::before {\n content: '", "';\n visibility: hidden;\n padding-right: calc(", " * 2);\n }\n "])), getEmptyDisplayValue('HH:mm:ss'), t.timePickerSeparatorPaddingXLarge);
38
+ },
39
+ selected: function (t) {
40
+ var getSelection = function (background, color) {
41
+ return (background || color) &&
42
+ "& ::selection {\n background: ".concat(background, ";\n color: ").concat(color, ";\n }");
43
+ };
44
+ return css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n cursor: text;\n ", "\n "], ["\n cursor: text;\n ", "\n "])), getSelection(t.timePickerSelectedBgColor, t.timePickerSelectedTextColor));
45
+ },
46
+ mask: function (t) {
47
+ return css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n color: ", ";\n "], ["\n color: ", ";\n "])), t.timePickerMaskColor);
48
+ },
49
+ segment: function () {
50
+ return css(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n display: inline;\n white-space: pre;\n "], ["\n display: inline;\n white-space: pre;\n "])));
51
+ },
52
+ separator: function () {
53
+ return css(templateObject_11 || (templateObject_11 = __makeTemplateObject(["\n display: inline;\n position: relative;\n\n /*\n * \u041E\u0442\u0440\u0438\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u0446\u0435\u043D\u0442\u0440\u0438\u0440\u0443\u0435\u043C \u043F\u043E \u0441\u0442\u0440\u043E\u043A\u0435: \u0443 \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u043E\u0433\u043E \u043F\u0441\u0435\u0432\u0434\u043E\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\n * \u0441\u0432\u043E\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u0441 \u043F\u043E\u043B\u0443\u043B\u0438\u0434\u0438\u043D\u0433\u043E\u043C, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043E\u0442 \u0432\u0435\u0440\u0445\u043D\u0435\u0433\u043E \u043A\u0440\u0430\u044F \u043E\u043D \u043E\u043A\u0430\u0437\u0430\u043B\u0441\u044F \u0431\u044B \u043D\u0438\u0436\u0435 \u0442\u0435\u043A\u0441\u0442\u0430 \u0441\u0435\u0433\u043C\u0435\u043D\u0442\u043E\u0432.\n */\n &::before {\n content: ':';\n content: ':' / '';\n position: absolute;\n left: 50%;\n top: 50%;\n width: 100%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n letter-spacing: normal;\n text-align: center;\n }\n "], ["\n display: inline;\n position: relative;\n\n /*\n * \u041E\u0442\u0440\u0438\u0441\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C \u0446\u0435\u043D\u0442\u0440\u0438\u0440\u0443\u0435\u043C \u043F\u043E \u0441\u0442\u0440\u043E\u043A\u0435: \u0443 \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u043E\u0433\u043E \u043F\u0441\u0435\u0432\u0434\u043E\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\n * \u0441\u0432\u043E\u044F \u0441\u0442\u0440\u043E\u043A\u0430 \u0441 \u043F\u043E\u043B\u0443\u043B\u0438\u0434\u0438\u043D\u0433\u043E\u043C, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043E\u0442 \u0432\u0435\u0440\u0445\u043D\u0435\u0433\u043E \u043A\u0440\u0430\u044F \u043E\u043D \u043E\u043A\u0430\u0437\u0430\u043B\u0441\u044F \u0431\u044B \u043D\u0438\u0436\u0435 \u0442\u0435\u043A\u0441\u0442\u0430 \u0441\u0435\u0433\u043C\u0435\u043D\u0442\u043E\u0432.\n */\n &::before {\n content: ':';\n content: ':' / '';\n position: absolute;\n left: 50%;\n top: 50%;\n width: 100%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n letter-spacing: normal;\n text-align: center;\n }\n "])));
54
+ },
55
+ /**
56
+ * Разделитель рисует псевдоэлемент, а сам текст только держит место и попадает в выделение.
57
+ * В задизейбленном поле `-webkit-text-fill-color` приходит по наследству и перебивает `color`,
58
+ * поэтому гасим и его — иначе двоеточие отрисуется дважды.
59
+ */
60
+ separatorText: function () {
61
+ return css(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n color: transparent;\n -webkit-text-fill-color: transparent;\n "], ["\n color: transparent;\n -webkit-text-fill-color: transparent;\n "])));
62
+ },
63
+ separatorSmall: function (t) {
64
+ return css(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n letter-spacing: ", ";\n\n &::before {\n margin-top: ", ";\n }\n "], ["\n letter-spacing: ", ";\n\n &::before {\n margin-top: ", ";\n }\n "])), t.timePickerSeparatorPaddingXSmall, t.timePickerSeparatorOffsetTopSmall);
65
+ },
66
+ separatorMedium: function (t) {
67
+ return css(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n letter-spacing: ", ";\n\n &::before {\n margin-top: ", ";\n }\n "], ["\n letter-spacing: ", ";\n\n &::before {\n margin-top: ", ";\n }\n "])), t.timePickerSeparatorPaddingXMedium, t.timePickerSeparatorOffsetTopMedium);
68
+ },
69
+ separatorLarge: function (t) {
70
+ return css(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n letter-spacing: ", ";\n\n &::before {\n margin-top: ", ";\n }\n "], ["\n letter-spacing: ", ";\n\n &::before {\n margin-top: ", ";\n }\n "])), t.timePickerSeparatorPaddingXLarge, t.timePickerSeparatorOffsetTopLarge);
71
+ },
72
+ separatorFilled: function () {
73
+ return css(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n color: inherit;\n "], ["\n color: inherit;\n "])));
74
+ },
75
+ });
76
+ });
77
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9, templateObject_10, templateObject_11, templateObject_12, templateObject_13, templateObject_14, templateObject_15, templateObject_16;
78
+ //# sourceMappingURL=TimeFragments.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeFragments.styles.js","sourceRoot":"","sources":["TimeFragments.styles.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Emotion } from '@emotion/css/create-instance';\n\nimport { getEmptyDisplayValue } from '../../components/TimePicker/helpers/TimePicker.value.js';\nimport { memoizeGetStyles } from '../../lib/theming/Emotion.js';\nimport type { Theme } from '../../lib/theming/Theme.js';\n\nexport const getStyles = memoizeGetStyles(({ css }: Emotion) => ({\n root() {\n return css`\n cursor: text;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n `;\n },\n\n /**\n * Резервируют место под время, когда значения нет: без этого поле с suffix\n * сужается на ширину времени, а при вводе снова расширяется.\n * Плейсхолдер уходит в псевдоэлемент — он занимает ту же ширину, что и время,\n * но не попадает в текст поля и не читается скринридером.\n * Отступы разделителей есть только у отрисованного времени, поэтому их добавляем сюда сами:\n * по одному `letter-spacing` на каждый разделитель — один в формате `HH:mm` и два в `HH:mm:ss`.\n */\n emptyPlaceholderSmall(t: Theme) {\n return css`\n &::before {\n content: '${getEmptyDisplayValue('HH:mm')}';\n visibility: hidden;\n padding-right: ${t.timePickerSeparatorPaddingXSmall};\n }\n `;\n },\n\n emptyPlaceholderMedium(t: Theme) {\n return css`\n &::before {\n content: '${getEmptyDisplayValue('HH:mm')}';\n visibility: hidden;\n padding-right: ${t.timePickerSeparatorPaddingXMedium};\n }\n `;\n },\n\n emptyPlaceholderLarge(t: Theme) {\n return css`\n &::before {\n content: '${getEmptyDisplayValue('HH:mm')}';\n visibility: hidden;\n padding-right: ${t.timePickerSeparatorPaddingXLarge};\n }\n `;\n },\n\n emptyPlaceholderWithSecondsSmall(t: Theme) {\n return css`\n &::before {\n content: '${getEmptyDisplayValue('HH:mm:ss')}';\n visibility: hidden;\n padding-right: calc(${t.timePickerSeparatorPaddingXSmall} * 2);\n }\n `;\n },\n\n emptyPlaceholderWithSecondsMedium(t: Theme) {\n return css`\n &::before {\n content: '${getEmptyDisplayValue('HH:mm:ss')}';\n visibility: hidden;\n padding-right: calc(${t.timePickerSeparatorPaddingXMedium} * 2);\n }\n `;\n },\n\n emptyPlaceholderWithSecondsLarge(t: Theme) {\n return css`\n &::before {\n content: '${getEmptyDisplayValue('HH:mm:ss')}';\n visibility: hidden;\n padding-right: calc(${t.timePickerSeparatorPaddingXLarge} * 2);\n }\n `;\n },\n\n selected(t: Theme) {\n const getSelection = (background: string, color: string) =>\n (background || color) &&\n `& ::selection {\n background: ${background};\n color: ${color};\n }`;\n\n return css`\n cursor: text;\n ${getSelection(t.timePickerSelectedBgColor, t.timePickerSelectedTextColor)}\n `;\n },\n\n mask(t: Theme) {\n return css`\n color: ${t.timePickerMaskColor};\n `;\n },\n\n segment() {\n return css`\n display: inline;\n white-space: pre;\n `;\n },\n\n separator() {\n return css`\n display: inline;\n position: relative;\n\n /*\n * Отрисованный разделитель центрируем по строке: у абсолютного псевдоэлемента\n * своя строка с полулидингом, поэтому от верхнего края он оказался бы ниже текста сегментов.\n */\n &::before {\n content: ':';\n content: ':' / '';\n position: absolute;\n left: 50%;\n top: 50%;\n width: 100%;\n transform: translate(-50%, -50%);\n pointer-events: none;\n letter-spacing: normal;\n text-align: center;\n }\n `;\n },\n\n /**\n * Разделитель рисует псевдоэлемент, а сам текст только держит место и попадает в выделение.\n * В задизейбленном поле `-webkit-text-fill-color` приходит по наследству и перебивает `color`,\n * поэтому гасим и его — иначе двоеточие отрисуется дважды.\n */\n separatorText() {\n return css`\n color: transparent;\n -webkit-text-fill-color: transparent;\n `;\n },\n\n separatorSmall(t: Theme) {\n return css`\n letter-spacing: ${t.timePickerSeparatorPaddingXSmall};\n\n &::before {\n margin-top: ${t.timePickerSeparatorOffsetTopSmall};\n }\n `;\n },\n\n separatorMedium(t: Theme) {\n return css`\n letter-spacing: ${t.timePickerSeparatorPaddingXMedium};\n\n &::before {\n margin-top: ${t.timePickerSeparatorOffsetTopMedium};\n }\n `;\n },\n\n separatorLarge(t: Theme) {\n return css`\n letter-spacing: ${t.timePickerSeparatorPaddingXLarge};\n\n &::before {\n margin-top: ${t.timePickerSeparatorOffsetTopLarge};\n }\n `;\n },\n\n separatorFilled() {\n return css`\n color: inherit;\n `;\n },\n}));\n"]}
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import type { InputProps } from '../../components/Input/index.js';
3
+ import { type TimeFormat, type TimeSegment } from '../../components/TimePicker/helpers/TimePicker.shared.js';
4
+ export interface TimeInputRef {
5
+ focus(): void;
6
+ blur(): void;
7
+ blink(): void;
8
+ isAllSelected(): boolean;
9
+ getSegment(el: HTMLElement | EventTarget | null): TimeSegment | null;
10
+ selectSegment(segment: TimeSegment): void;
11
+ selectAll(): void;
12
+ getNode(): HTMLElement | null;
13
+ }
14
+ export interface TimeInputProps extends Omit<InputProps, 'type' | 'value' | 'onValueChange' | 'inputMode'> {
15
+ hasDropdown?: boolean;
16
+ format: TimeFormat;
17
+ value: string;
18
+ 'aria-placeholder'?: string;
19
+ onSelectSegment?(segment: TimeSegment, event: React.MouseEvent<HTMLSpanElement>): void;
20
+ }
21
+ export declare const TimeInput: import("../../lib/forwardRefAndName.js").ReactUIComponentWithRef<TimeInputRef, TimeInputProps> & Record<never, never>;
@@ -0,0 +1,104 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ import React, { useContext, useEffect, useImperativeHandle, useRef } from 'react';
24
+ import { getTimePickerInputMinWidth, getTimePickerSuffixMargin, } from '../../components/TimePicker/helpers/TimePicker.layout.js';
25
+ import { getTimeSegments, } from '../../components/TimePicker/helpers/TimePicker.shared.js';
26
+ import { TimeClockIcon } from '../../components/TimePicker/TimeClockIcon.js';
27
+ import { forwardRefAndName } from '../../lib/forwardRefAndName.js';
28
+ import { useEmotion, useStyles } from '../../lib/renderEnvironment/index.js';
29
+ import { ThemeContext } from '../../lib/theming/ThemeContext.js';
30
+ import { InputLikeText } from '../InputLikeText/index.js';
31
+ import { TimeFragments } from './TimeFragments.js';
32
+ import { getStyles } from './TimeInput.styles.js';
33
+ export var TimeInput = forwardRefAndName('TimeInput', function (props, ref) {
34
+ var _a;
35
+ var _b = props.hasDropdown, hasDropdown = _b === void 0 ? false : _b, _c = props.size, size = _c === void 0 ? 'small' : _c, disabled = props.disabled, autoFocus = props.autoFocus, suffix = props.suffix, style = props.style, width = props.width, corners = props.corners, rightIcon = props.rightIcon, format = props.format, value = props.value, onSelectSegment = props.onSelectSegment, rest = __rest(props, ["hasDropdown", "size", "disabled", "autoFocus", "suffix", "style", "width", "corners", "rightIcon", "format", "value", "onSelectSegment"]);
36
+ var theme = useContext(ThemeContext);
37
+ var cx = useEmotion().cx;
38
+ var styles = useStyles(getStyles);
39
+ var inputLikeTextRef = useRef(null);
40
+ var fragmentsRef = useRef(null);
41
+ useImperativeHandle(ref, function () { return ({
42
+ focus: function () { var _a; return (_a = inputLikeTextRef.current) === null || _a === void 0 ? void 0 : _a.focus(); },
43
+ blur: function () { var _a; return (_a = inputLikeTextRef.current) === null || _a === void 0 ? void 0 : _a.blur(); },
44
+ blink: function () { var _a; return (_a = inputLikeTextRef.current) === null || _a === void 0 ? void 0 : _a.blink(); },
45
+ getNode: function () { var _a, _b; return (_b = (_a = inputLikeTextRef.current) === null || _a === void 0 ? void 0 : _a.getNode()) !== null && _b !== void 0 ? _b : null; },
46
+ getSegment: function (el) { var _a, _b; return (_b = (_a = fragmentsRef.current) === null || _a === void 0 ? void 0 : _a.getSegment(el)) !== null && _b !== void 0 ? _b : null; },
47
+ selectAll: function () {
48
+ var _a, _b, _c;
49
+ var rootNode = (_b = (_a = fragmentsRef.current) === null || _a === void 0 ? void 0 : _a.getRootNode()) !== null && _b !== void 0 ? _b : null;
50
+ if (!rootNode) {
51
+ return;
52
+ }
53
+ (_c = inputLikeTextRef.current) === null || _c === void 0 ? void 0 : _c.selectInnerNode(rootNode, 0, rootNode.childNodes.length);
54
+ },
55
+ isAllSelected: function () {
56
+ var _a, _b, _c, _d, _e;
57
+ var rootNode = (_b = (_a = fragmentsRef.current) === null || _a === void 0 ? void 0 : _a.getRootNode()) !== null && _b !== void 0 ? _b : null;
58
+ if (!rootNode) {
59
+ return false;
60
+ }
61
+ var selection = (_d = (_c = rootNode.ownerDocument.defaultView) === null || _c === void 0 ? void 0 : _c.getSelection()) !== null && _d !== void 0 ? _d : null;
62
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
63
+ return false;
64
+ }
65
+ var range = selection.getRangeAt(0);
66
+ var text = (_e = rootNode.textContent) !== null && _e !== void 0 ? _e : '';
67
+ return (range.toString() === text && rootNode.contains(range.startContainer) && rootNode.contains(range.endContainer));
68
+ },
69
+ selectSegment: function (segment) {
70
+ var _a, _b, _c;
71
+ var rootNode = (_b = (_a = fragmentsRef.current) === null || _a === void 0 ? void 0 : _a.getRootNode()) !== null && _b !== void 0 ? _b : null;
72
+ if (!rootNode) {
73
+ return;
74
+ }
75
+ var segmentIndex = getTimeSegments(format).indexOf(segment);
76
+ var start = segmentIndex < 0 ? 0 : segmentIndex * 2;
77
+ var end = start + 1;
78
+ (_c = inputLikeTextRef.current) === null || _c === void 0 ? void 0 : _c.selectInnerNode(rootNode, start, end);
79
+ },
80
+ }); }, [format]);
81
+ useEffect(function () {
82
+ if (!autoFocus || disabled) {
83
+ return;
84
+ }
85
+ var timer = setTimeout(function () {
86
+ var _a;
87
+ (_a = inputLikeTextRef.current) === null || _a === void 0 ? void 0 : _a.focus();
88
+ }, 0);
89
+ return function () {
90
+ clearTimeout(timer);
91
+ };
92
+ }, []);
93
+ var resolvedRightIcon = rightIcon === undefined ? (React.createElement("span", { className: cx(styles.rightIcon(), (_a = {},
94
+ _a[styles.rightIconDefault(theme)] = !disabled,
95
+ _a[styles.rightIconDisabled(theme)] = disabled,
96
+ _a[styles.rightIconInteractive()] = hasDropdown && !disabled,
97
+ _a)) },
98
+ React.createElement(TimeClockIcon, { size: size }))) : (rightIcon);
99
+ var suffixMarginLeft = getTimePickerSuffixMargin(size, theme);
100
+ var inputMinWidth = getTimePickerInputMinWidth(size, format, resolvedRightIcon !== null, theme);
101
+ return (React.createElement(InputLikeText, __assign({ ref: inputLikeTextRef }, rest, { takeContentWidth: true, disabled: disabled, size: size, inputMode: 'numeric', width: width !== null && width !== void 0 ? width : 'auto', suffix: suffix && React.createElement("span", { style: { marginLeft: suffixMarginLeft } }, suffix), style: __assign(__assign(__assign({}, style), { minWidth: inputMinWidth }), corners), rightIcon: resolvedRightIcon, value: value }),
102
+ React.createElement(TimeFragments, { ref: fragmentsRef, format: format, size: size, value: value, onSelectSegment: onSelectSegment })));
103
+ });
104
+ //# sourceMappingURL=TimeInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeInput.js","sourceRoot":"","sources":["TimeInput.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAGlF,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,0DAA0D,CAAC;AAClE,OAAO,EACL,eAAe,GAGhB,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAqBlD,MAAM,CAAC,IAAM,SAAS,GAAG,iBAAiB,CAA+B,WAAW,EAAE,UAAC,KAAK,EAAE,GAAG;;IAE7F,IAAA,KAaE,KAAK,YAbY,EAAnB,WAAW,mBAAG,KAAK,KAAA,EACnB,KAYE,KAAK,KAZO,EAAd,IAAI,mBAAG,OAAO,KAAA,EACd,QAAQ,GAWN,KAAK,SAXC,EACR,SAAS,GAUP,KAAK,UAVE,EACT,MAAM,GASJ,KAAK,OATD,EACN,KAAK,GAQH,KAAK,MARF,EACL,KAAK,GAOH,KAAK,MAPF,EACL,OAAO,GAML,KAAK,QANA,EACP,SAAS,GAKP,KAAK,UALE,EACT,MAAM,GAIJ,KAAK,OAJD,EACN,KAAK,GAGH,KAAK,MAHF,EACL,eAAe,GAEb,KAAK,gBAFQ,EACZ,IAAI,UACL,KAAK,EAdH,0IAcL,CADQ,CACC;IAEV,IAAM,KAAK,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAE/B,IAAA,EAAE,GAAK,UAAU,EAAE,GAAjB,CAAkB;IAE5B,IAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAEpC,IAAM,gBAAgB,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IACrD,IAAM,YAAY,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEpD,mBAAmB,CACjB,GAAG,EACH,cAAM,OAAA,CAAC;QACL,KAAK,EAAE,sBAAM,OAAA,MAAA,gBAAgB,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAA,EAAA;QAC9C,IAAI,EAAE,sBAAM,OAAA,MAAA,gBAAgB,CAAC,OAAO,0CAAE,IAAI,EAAE,CAAA,EAAA;QAC5C,KAAK,EAAE,sBAAM,OAAA,MAAA,gBAAgB,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAA,EAAA;QAC9C,OAAO,EAAE,0BAAM,OAAA,MAAA,MAAA,gBAAgB,CAAC,OAAO,0CAAE,OAAO,EAAE,mCAAI,IAAI,CAAA,EAAA;QAC1D,UAAU,EAAE,UAAC,EAAE,gBAAK,OAAA,MAAA,MAAA,YAAY,CAAC,OAAO,0CAAE,UAAU,CAAC,EAAE,CAAC,mCAAI,IAAI,CAAA,EAAA;QAChE,SAAS,EAAE;;YACT,IAAM,QAAQ,GAAG,MAAA,MAAA,YAAY,CAAC,OAAO,0CAAE,WAAW,EAAE,mCAAI,IAAI,CAAC;YAE7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,MAAA,gBAAgB,CAAC,OAAO,0CAAE,eAAe,CAAC,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACrF,CAAC;QAED,aAAa,EAAE;;YACb,IAAM,QAAQ,GAAG,MAAA,MAAA,YAAY,CAAC,OAAO,0CAAE,WAAW,EAAE,mCAAI,IAAI,CAAC;YAE7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAM,SAAS,GAAG,MAAA,MAAA,QAAQ,CAAC,aAAa,CAAC,WAAW,0CAAE,YAAY,EAAE,mCAAI,IAAI,CAAC;YAE7E,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,UAAU,KAAK,CAAC,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;gBACtE,OAAO,KAAK,CAAC;YACf,CAAC;YAED,IAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YACtC,IAAM,IAAI,GAAG,MAAA,QAAQ,CAAC,WAAW,mCAAI,EAAE,CAAC;YAExC,OAAO,CACL,KAAK,CAAC,QAAQ,EAAE,KAAK,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAC9G,CAAC;QACJ,CAAC;QAED,aAAa,EAAE,UAAC,OAAO;;YACrB,IAAM,QAAQ,GAAG,MAAA,MAAA,YAAY,CAAC,OAAO,0CAAE,WAAW,EAAE,mCAAI,IAAI,CAAC;YAE7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YAED,IAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC9D,IAAM,KAAK,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC;YACtD,IAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC;YAEtB,MAAA,gBAAgB,CAAC,OAAO,0CAAE,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAClE,CAAC;KACF,CAAC,EAlDI,CAkDJ,EACF,CAAC,MAAM,CAAC,CACT,CAAC;IAEF,SAAS,CAAC;QACR,IAAI,CAAC,SAAS,IAAI,QAAQ,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,IAAM,KAAK,GAAG,UAAU,CAAC;;YACvB,MAAA,gBAAgB,CAAC,OAAO,0CAAE,KAAK,EAAE,CAAC;QACpC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEN,OAAO;YACL,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAM,iBAAiB,GACrB,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,CACxB,8BACE,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE;YAC9B,GAAC,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAG,CAAC,QAAQ;YAC3C,GAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAG,QAAQ;YAC3C,GAAC,MAAM,CAAC,oBAAoB,EAAE,IAAG,WAAW,IAAI,CAAC,QAAQ;gBACzD;QAEF,oBAAC,aAAa,IAAC,IAAI,EAAE,IAAI,GAAI,CACxB,CACR,CAAC,CAAC,CAAC,CACF,SAAS,CACV,CAAC;IACJ,IAAM,gBAAgB,GAAG,yBAAyB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAChE,IAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,KAAK,IAAI,EAAE,KAAK,CAAC,CAAC;IAElG,OAAO,CACL,oBAAC,aAAa,aACZ,GAAG,EAAE,gBAAgB,IACjB,IAAI,IACR,gBAAgB,QAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,MAAM,EACtB,MAAM,EAAE,MAAM,IAAI,8BAAM,KAAK,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,IAAG,MAAM,CAAQ,EAChF,KAAK,iCAAO,KAAK,KAAE,QAAQ,EAAE,aAAa,KAAK,OAAO,GACtD,SAAS,EAAE,iBAAiB,EAC5B,KAAK,EAAE,KAAK;QAEZ,oBAAC,aAAa,IAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,eAAe,GAAI,CAClG,CACjB,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import React, { useContext, useEffect, useImperativeHandle, useRef } from 'react';\n\nimport type { InputProps } from '../../components/Input/index.js';\nimport {\n getTimePickerInputMinWidth,\n getTimePickerSuffixMargin,\n} from '../../components/TimePicker/helpers/TimePicker.layout.js';\nimport {\n getTimeSegments,\n type TimeFormat,\n type TimeSegment,\n} from '../../components/TimePicker/helpers/TimePicker.shared.js';\nimport { TimeClockIcon } from '../../components/TimePicker/TimeClockIcon.js';\nimport { forwardRefAndName } from '../../lib/forwardRefAndName.js';\nimport { useEmotion, useStyles } from '../../lib/renderEnvironment/index.js';\nimport { ThemeContext } from '../../lib/theming/ThemeContext.js';\nimport { InputLikeText } from '../InputLikeText/index.js';\nimport type { TimeFragmentsRef } from './TimeFragments.js';\nimport { TimeFragments } from './TimeFragments.js';\nimport { getStyles } from './TimeInput.styles.js';\n\nexport interface TimeInputRef {\n focus(): void;\n blur(): void;\n blink(): void;\n isAllSelected(): boolean;\n getSegment(el: HTMLElement | EventTarget | null): TimeSegment | null;\n selectSegment(segment: TimeSegment): void;\n selectAll(): void;\n getNode(): HTMLElement | null;\n}\n\nexport interface TimeInputProps extends Omit<InputProps, 'type' | 'value' | 'onValueChange' | 'inputMode'> {\n hasDropdown?: boolean;\n format: TimeFormat;\n value: string;\n 'aria-placeholder'?: string;\n onSelectSegment?(segment: TimeSegment, event: React.MouseEvent<HTMLSpanElement>): void;\n}\n\nexport const TimeInput = forwardRefAndName<TimeInputRef, TimeInputProps>('TimeInput', (props, ref) => {\n const {\n hasDropdown = false,\n size = 'small',\n disabled,\n autoFocus,\n suffix,\n style,\n width,\n corners,\n rightIcon,\n format,\n value,\n onSelectSegment,\n ...rest\n } = props;\n\n const theme = useContext(ThemeContext);\n\n const { cx } = useEmotion();\n\n const styles = useStyles(getStyles);\n\n const inputLikeTextRef = useRef<InputLikeText>(null);\n const fragmentsRef = useRef<TimeFragmentsRef>(null);\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => inputLikeTextRef.current?.focus(),\n blur: () => inputLikeTextRef.current?.blur(),\n blink: () => inputLikeTextRef.current?.blink(),\n getNode: () => inputLikeTextRef.current?.getNode() ?? null,\n getSegment: (el) => fragmentsRef.current?.getSegment(el) ?? null,\n selectAll: () => {\n const rootNode = fragmentsRef.current?.getRootNode() ?? null;\n\n if (!rootNode) {\n return;\n }\n\n inputLikeTextRef.current?.selectInnerNode(rootNode, 0, rootNode.childNodes.length);\n },\n\n isAllSelected: () => {\n const rootNode = fragmentsRef.current?.getRootNode() ?? null;\n\n if (!rootNode) {\n return false;\n }\n\n const selection = rootNode.ownerDocument.defaultView?.getSelection() ?? null;\n\n if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {\n return false;\n }\n\n const range = selection.getRangeAt(0);\n const text = rootNode.textContent ?? '';\n\n return (\n range.toString() === text && rootNode.contains(range.startContainer) && rootNode.contains(range.endContainer)\n );\n },\n\n selectSegment: (segment) => {\n const rootNode = fragmentsRef.current?.getRootNode() ?? null;\n\n if (!rootNode) {\n return;\n }\n\n const segmentIndex = getTimeSegments(format).indexOf(segment);\n const start = segmentIndex < 0 ? 0 : segmentIndex * 2;\n const end = start + 1;\n\n inputLikeTextRef.current?.selectInnerNode(rootNode, start, end);\n },\n }),\n [format],\n );\n\n useEffect(() => {\n if (!autoFocus || disabled) {\n return;\n }\n\n const timer = setTimeout(() => {\n inputLikeTextRef.current?.focus();\n }, 0);\n\n return () => {\n clearTimeout(timer);\n };\n }, []);\n\n const resolvedRightIcon =\n rightIcon === undefined ? (\n <span\n className={cx(styles.rightIcon(), {\n [styles.rightIconDefault(theme)]: !disabled,\n [styles.rightIconDisabled(theme)]: disabled,\n [styles.rightIconInteractive()]: hasDropdown && !disabled,\n })}\n >\n <TimeClockIcon size={size} />\n </span>\n ) : (\n rightIcon\n );\n const suffixMarginLeft = getTimePickerSuffixMargin(size, theme);\n const inputMinWidth = getTimePickerInputMinWidth(size, format, resolvedRightIcon !== null, theme);\n\n return (\n <InputLikeText\n ref={inputLikeTextRef}\n {...rest}\n takeContentWidth\n disabled={disabled}\n size={size}\n inputMode={'numeric'}\n width={width ?? 'auto'}\n suffix={suffix && <span style={{ marginLeft: suffixMarginLeft }}>{suffix}</span>}\n style={{ ...style, minWidth: inputMinWidth, ...corners }}\n rightIcon={resolvedRightIcon}\n value={value}\n >\n <TimeFragments ref={fragmentsRef} format={format} size={size} value={value} onSelectSegment={onSelectSegment} />\n </InputLikeText>\n );\n});\n"]}
@@ -0,0 +1,7 @@
1
+ import type { Theme } from '../../lib/theming/Theme.js';
2
+ export declare const getStyles: import("../../lib/theming/Emotion.js").StylesGetter<{
3
+ rightIcon(): string;
4
+ rightIconInteractive(): string;
5
+ rightIconDefault(t: Theme): string;
6
+ rightIconDisabled(t: Theme): string;
7
+ }>;
@@ -0,0 +1,24 @@
1
+ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
2
+ if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
3
+ return cooked;
4
+ };
5
+ import { memoizeGetStyles } from '../../lib/theming/Emotion.js';
6
+ export var getStyles = memoizeGetStyles(function (_a) {
7
+ var css = _a.css;
8
+ return ({
9
+ rightIcon: function () {
10
+ return css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n user-select: none;\n "], ["\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n user-select: none;\n "])));
11
+ },
12
+ rightIconInteractive: function () {
13
+ return css(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n cursor: pointer;\n "], ["\n cursor: pointer;\n "])));
14
+ },
15
+ rightIconDefault: function (t) {
16
+ return css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n color: ", ";\n "], ["\n color: ", ";\n "])), t.textColorDefault);
17
+ },
18
+ rightIconDisabled: function (t) {
19
+ return css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n color: ", ";\n "], ["\n color: ", ";\n "])), t.inputTextColorDisabled);
20
+ },
21
+ });
22
+ });
23
+ var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
24
+ //# sourceMappingURL=TimeInput.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimeInput.styles.js","sourceRoot":"","sources":["TimeInput.styles.ts"],"names":[],"mappings":";;;;AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,MAAM,CAAC,IAAM,SAAS,GAAG,gBAAgB,CAAC,UAAC,EAAgB;QAAd,GAAG,SAAA;IAAgB,OAAA,CAAC;QAC/D,SAAS;YACP,OAAO,GAAG,kNAAA,+IAMT,KAAC;QACJ,CAAC;QAED,oBAAoB;YAClB,OAAO,GAAG,mGAAA,gCAET,KAAC;QACJ,CAAC;QAED,gBAAgB,YAAC,CAAQ;YACvB,OAAO,GAAG,+FAAA,iBACC,EAAkB,SAC5B,KADU,CAAC,CAAC,gBAAgB,EAC3B;QACJ,CAAC;QAED,iBAAiB,YAAC,CAAQ;YACxB,OAAO,GAAG,+FAAA,iBACC,EAAwB,SAClC,KADU,CAAC,CAAC,sBAAsB,EACjC;QACJ,CAAC;KACF,CAAC;AA5B8D,CA4B9D,CAAC,CAAC","sourcesContent":["import type { Emotion } from '@emotion/css/create-instance';\n\nimport { memoizeGetStyles } from '../../lib/theming/Emotion.js';\nimport type { Theme } from '../../lib/theming/Theme.js';\n\nexport const getStyles = memoizeGetStyles(({ css }: Emotion) => ({\n rightIcon() {\n return css`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n user-select: none;\n `;\n },\n\n rightIconInteractive() {\n return css`\n cursor: pointer;\n `;\n },\n\n rightIconDefault(t: Theme) {\n return css`\n color: ${t.textColorDefault};\n `;\n },\n\n rightIconDisabled(t: Theme) {\n return css`\n color: ${t.inputTextColorDisabled};\n `;\n },\n}));\n"]}
@@ -0,0 +1 @@
1
+ export * from './TimeInput.js';
@@ -0,0 +1,2 @@
1
+ export * from './TimeInput.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './TimeInput.js';\n"]}
@@ -0,0 +1,23 @@
1
+ import { type TimeItemValue, type TimePickerMenuItem } from '../../components/TimePicker/helpers/TimePicker.shared.js';
2
+ interface UseTimePickerDropdownOptions<T extends TimeItemValue> {
3
+ hasDropdown: boolean;
4
+ disabled?: boolean;
5
+ items: Array<TimePickerMenuItem<T>>;
6
+ selectedItemIndex: number | null;
7
+ autoHighlightKey: string | null;
8
+ /**
9
+ * Состоянием открытости владеет компонент: от него зависит запрос элементов,
10
+ * а элементы, в свою очередь, нужны этому хуку для навигации.
11
+ */
12
+ isDropdownOpened: boolean;
13
+ setIsDropdownOpened(isOpened: boolean): void;
14
+ }
15
+ interface UseTimePickerDropdownResult {
16
+ highlightedItemIndex: number | null;
17
+ openDropdown(): void;
18
+ closeDropdown(): void;
19
+ resetHighlightedItem(): void;
20
+ tryNavigateItems(step: 1 | -1): boolean;
21
+ }
22
+ export declare const useTimePickerDropdown: <T extends TimeItemValue>(options: UseTimePickerDropdownOptions<T>) => UseTimePickerDropdownResult;
23
+ export {};
@@ -0,0 +1,67 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { isHighlightableMenuItem, isTimeMenuItem, } from '../../components/TimePicker/helpers/TimePicker.shared.js';
3
+ export var useTimePickerDropdown = function (options) {
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];
6
+ var lastAutoHighlightKeyRef = useRef(null);
7
+ var openDropdown = useCallback(function () {
8
+ if (!hasDropdown || disabled) {
9
+ return;
10
+ }
11
+ setIsDropdownOpened(true);
12
+ }, [disabled, hasDropdown, setIsDropdownOpened]);
13
+ var closeDropdown = useCallback(function () {
14
+ setIsDropdownOpened(false);
15
+ setHighlightedItemIndex(null);
16
+ }, [setIsDropdownOpened]);
17
+ var resetHighlightedItem = useCallback(function () {
18
+ setHighlightedItemIndex(null);
19
+ }, []);
20
+ useEffect(function () {
21
+ if (lastAutoHighlightKeyRef.current === autoHighlightKey) {
22
+ return;
23
+ }
24
+ lastAutoHighlightKeyRef.current = autoHighlightKey;
25
+ if (autoHighlightKey === null) {
26
+ setHighlightedItemIndex(null);
27
+ return;
28
+ }
29
+ var firstEnabledItemIndex = items.findIndex(function (item) { return isTimeMenuItem(item) && !item.disabled; });
30
+ setHighlightedItemIndex(firstEnabledItemIndex >= 0 ? firstEnabledItemIndex : null);
31
+ }, [autoHighlightKey, items]);
32
+ useEffect(function () {
33
+ setHighlightedItemIndex(function (current) {
34
+ if (current === null) {
35
+ return current;
36
+ }
37
+ var item = items[current];
38
+ return !item || !isHighlightableMenuItem(item) ? null : current;
39
+ });
40
+ }, [items]);
41
+ var tryNavigateItems = useCallback(function (step) {
42
+ var _a, _b;
43
+ if (!hasDropdown || !isDropdownOpened) {
44
+ return false;
45
+ }
46
+ var enabledIndexes = items.flatMap(function (item, index) { return (isHighlightableMenuItem(item) ? index : []); });
47
+ if (enabledIndexes.length === 0) {
48
+ return false;
49
+ }
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]));
57
+ return true;
58
+ }, [hasDropdown, highlightedItemIndex, isDropdownOpened, selectedItemIndex, items]);
59
+ return {
60
+ highlightedItemIndex: highlightedItemIndex,
61
+ openDropdown: openDropdown,
62
+ closeDropdown: closeDropdown,
63
+ resetHighlightedItem: resetHighlightedItem,
64
+ tryNavigateItems: tryNavigateItems,
65
+ };
66
+ };
67
+ //# sourceMappingURL=useTimePickerDropdown.js.map