@invoicebox/ui 0.1.0-alpha.320 → 0.1.0-alpha.321

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 (165) hide show
  1. package/dist/components/common/AppCardLink/index.js +2 -1
  2. package/dist/components/common/BgCard/index.js +2 -1
  3. package/dist/components/common/BgCard/styles.js +2 -1
  4. package/dist/components/common/Calendar/index.js +2 -1
  5. package/dist/components/common/Calendar/index.stories.js +2 -1
  6. package/dist/components/common/Calendar/styles.js +2 -1
  7. package/dist/components/common/Divider/index.js +2 -1
  8. package/dist/components/common/Drawer/index.js +2 -1
  9. package/dist/components/common/Drawer/index.stories.js +2 -1
  10. package/dist/components/common/Drawer/styles.js +2 -1
  11. package/dist/components/common/Dropdown/index.js +2 -1
  12. package/dist/components/common/Dropdown/styles.js +9 -8
  13. package/dist/components/common/EntityAutocompleteOptionsDrawer/index.js +2 -1
  14. package/dist/components/common/EntityAutocompleteOptionsDrawer/index.stories.js +2 -1
  15. package/dist/components/common/Flag/index.js +2 -1
  16. package/dist/components/common/Flag/styles.js +2 -1
  17. package/dist/components/common/InvoiceboxSpinner/index.js +2 -1
  18. package/dist/components/common/InvoiceboxSpinner/styles.js +2 -1
  19. package/dist/components/common/PointsLoader/index.js +2 -1
  20. package/dist/components/common/QRCode/index.js +2 -2
  21. package/dist/components/common/ReadOnlyLabelValueField/index.js +2 -1
  22. package/dist/components/common/Scrollbar/index.js +2 -1
  23. package/dist/components/common/Scrollbar/styles.js +2 -1
  24. package/dist/components/common/SecondaryButton/index.js +4 -3
  25. package/dist/components/common/SecondaryButton/styles.js +2 -1
  26. package/dist/components/common/Skeleton/index.js +2 -1
  27. package/dist/components/common/Skeleton/styles.js +2 -1
  28. package/dist/components/common/Toast/index.js +2 -1
  29. package/dist/components/common/Tooltip/index.js +2 -1
  30. package/dist/components/common/Typography/index.js +4 -3
  31. package/dist/components/common/WarningIcon/index.js +2 -1
  32. package/dist/components/form/Autocomplete/components/Autocomplete/index.js +2 -1
  33. package/dist/components/form/Autocomplete/components/Autocomplete/index.stories.js +2 -1
  34. package/dist/components/form/Autocomplete/components/OrganizationAutocompleteItem/index.js +2 -1
  35. package/dist/components/form/Checkbox/index.js +4 -3
  36. package/dist/components/form/Checkbox/index.stories.js +2 -1
  37. package/dist/components/form/CodeInput/index.js +2 -1
  38. package/dist/components/form/CodeInput/index.stories.js +2 -1
  39. package/dist/components/form/CountrySelect/components/CountryItem/index.js +2 -1
  40. package/dist/components/form/CountrySelect/index.js +4 -3
  41. package/dist/components/form/CurrencyInput/CoreCurrencyInput/index.js +2 -1
  42. package/dist/components/form/CurrencyInput/CoreCurrencyInput/index.stories.js +2 -1
  43. package/dist/components/form/CurrencyInput/CurrencyInputNumber/index.js +2 -2
  44. package/dist/components/form/CurrencyInput/CurrencyInputNumber/index.stories.js +2 -1
  45. package/dist/components/form/CurrencyInput/CurrencyInputString/index.js +2 -2
  46. package/dist/components/form/CurrencyInput/CurrencyInputString/index.stories.js +2 -1
  47. package/dist/components/form/DateInput/components/CalendarIcon/index.js +2 -1
  48. package/dist/components/form/DateInput/components/MobileDrawerDateCalendar/index.js +2 -1
  49. package/dist/components/form/DateInput/components/MobileDrawerDateCalendar/index.stories.js +2 -1
  50. package/dist/components/form/DateInput/index.js +2 -1
  51. package/dist/components/form/DateInput/index.stories.js +2 -1
  52. package/dist/components/form/DateInput/logic.d.ts +1 -0
  53. package/dist/components/form/DateInput/logic.js +11 -0
  54. package/dist/components/form/DateTimeInput/components/MobileDatePicker/index.d.ts +12 -0
  55. package/dist/components/form/DateTimeInput/components/MobileDatePicker/index.js +83 -0
  56. package/dist/components/form/DateTimeInput/components/MobileDatePicker/index.stories.d.ts +6 -0
  57. package/dist/components/form/DateTimeInput/components/MobileDatePicker/index.stories.js +48 -0
  58. package/dist/components/form/DateTimeInput/components/MobileDatePicker/logic.d.ts +11 -0
  59. package/dist/components/form/DateTimeInput/components/MobileDatePicker/logic.js +92 -0
  60. package/dist/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/index.d.ts +4 -0
  61. package/dist/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/index.js +42 -22
  62. package/dist/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/index.stories.js +2 -1
  63. package/dist/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/styles.d.ts +1 -2
  64. package/dist/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/styles.js +4 -8
  65. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/components/WheelColumn/index.d.ts +14 -0
  66. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/components/WheelColumn/index.js +259 -0
  67. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/components/WheelColumn/styles.d.ts +12 -0
  68. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/components/WheelColumn/styles.js +35 -0
  69. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/constants.d.ts +11 -0
  70. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/constants.js +40 -0
  71. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/index.d.ts +12 -0
  72. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/index.js +48 -0
  73. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/index.stories.d.ts +5 -0
  74. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/index.stories.js +47 -0
  75. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/palette.d.ts +9 -0
  76. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/palette.js +17 -0
  77. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/styles.d.ts +12 -0
  78. package/dist/components/form/DateTimeInput/components/MobileWheelPicker/styles.js +39 -0
  79. package/dist/components/form/DateTimeInput/components/TimePicker/index.d.ts +1 -0
  80. package/dist/components/form/DateTimeInput/components/TimePicker/index.js +34 -16
  81. package/dist/components/form/DateTimeInput/components/TimePicker/index.stories.d.ts +1 -0
  82. package/dist/components/form/DateTimeInput/components/TimePicker/index.stories.js +31 -17
  83. package/dist/components/form/DateTimeInput/components/TimePicker/styles.d.ts +0 -4
  84. package/dist/components/form/DateTimeInput/components/TimePicker/styles.js +2 -13
  85. package/dist/components/form/DateTimeInput/index.js +22 -4
  86. package/dist/components/form/DateTimeInput/index.stories.js +2 -1
  87. package/dist/components/form/InputLabel/index.js +2 -1
  88. package/dist/components/form/InputLabel/styles.js +2 -1
  89. package/dist/components/form/ModernPlaceholder/index.js +2 -1
  90. package/dist/components/form/PhoneInput/index.js +2 -1
  91. package/dist/components/form/PhoneInput/index.stories.js +2 -1
  92. package/dist/components/form/PositiveIntegerInput/index.js +2 -1
  93. package/dist/components/form/PositiveIntegerInput/index.stories.js +2 -1
  94. package/dist/components/form/PositiveIntegerInput/styles.js +2 -1
  95. package/dist/components/form/PureInput/index.js +4 -3
  96. package/dist/components/form/PureInput/styles.js +2 -2
  97. package/dist/components/form/ResetButton/index.js +2 -1
  98. package/dist/components/form/SearchInput/index.js +2 -1
  99. package/dist/components/form/SearchInput/index.stories.js +2 -1
  100. package/dist/components/form/Select/components/Input/index.js +2 -1
  101. package/dist/components/form/Select/components/Loader/index.js +2 -1
  102. package/dist/components/form/Select/components/MultipleValue/index.js +2 -1
  103. package/dist/components/form/Select/components/MultipleValue/styles.js +2 -1
  104. package/dist/components/form/Select/index.js +2 -1
  105. package/dist/components/form/Select/index.stories.js +2 -1
  106. package/dist/components/form/Select/styles.js +2 -1
  107. package/dist/components/form/TagsInput/index.js +2 -1
  108. package/dist/components/form/TagsInput/index.stories.js +2 -1
  109. package/dist/components/form/TagsInput/styles.js +2 -2
  110. package/dist/components/form/TextInput/index.js +2 -1
  111. package/dist/components/form/TextInput/index.stories.js +2 -1
  112. package/dist/components/form/Toggle/index.js +4 -3
  113. package/dist/components/form/Toggle/index.stories.js +2 -1
  114. package/dist/components/form/Toggle/styles.js +10 -10
  115. package/dist/components/form/_hooks/useInputStyles.js +2 -1
  116. package/dist/components/form/common/DrawerHeader/index.d.ts +2 -0
  117. package/dist/components/form/common/DrawerHeader/index.js +15 -5
  118. package/dist/components/form/common/DrawerHeader/styles.d.ts +4 -0
  119. package/dist/components/form/common/DrawerHeader/styles.js +17 -7
  120. package/dist/esm/components/common/Dropdown/styles.js +7 -7
  121. package/dist/esm/components/common/QRCode/index.js +2 -2
  122. package/dist/esm/components/common/SecondaryButton/index.js +2 -2
  123. package/dist/esm/components/common/Typography/index.js +2 -2
  124. package/dist/esm/components/form/Checkbox/index.js +2 -2
  125. package/dist/esm/components/form/CountrySelect/index.js +2 -2
  126. package/dist/esm/components/form/CurrencyInput/CurrencyInputNumber/index.js +2 -2
  127. package/dist/esm/components/form/CurrencyInput/CurrencyInputString/index.js +2 -2
  128. package/dist/esm/components/form/DateInput/logic.js +11 -0
  129. package/dist/esm/components/form/DateTimeInput/components/MobileDatePicker/index.js +74 -0
  130. package/dist/esm/components/form/DateTimeInput/components/MobileDatePicker/index.stories.js +39 -0
  131. package/dist/esm/components/form/DateTimeInput/components/MobileDatePicker/logic.js +86 -0
  132. package/dist/esm/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/index.js +40 -21
  133. package/dist/esm/components/form/DateTimeInput/components/MobileDrawerDateTimeCalendar/styles.js +3 -7
  134. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/components/WheelColumn/index.js +250 -0
  135. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/components/WheelColumn/styles.js +28 -0
  136. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/constants.js +34 -0
  137. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/index.js +32 -0
  138. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/index.stories.js +38 -0
  139. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/palette.js +10 -0
  140. package/dist/esm/components/form/DateTimeInput/components/MobileWheelPicker/styles.js +32 -0
  141. package/dist/esm/components/form/DateTimeInput/components/TimePicker/index.js +32 -15
  142. package/dist/esm/components/form/DateTimeInput/components/TimePicker/index.stories.js +29 -15
  143. package/dist/esm/components/form/DateTimeInput/components/TimePicker/styles.js +1 -12
  144. package/dist/esm/components/form/DateTimeInput/index.js +21 -4
  145. package/dist/esm/components/form/PureInput/index.js +2 -2
  146. package/dist/esm/components/form/PureInput/styles.js +2 -2
  147. package/dist/esm/components/form/TagsInput/styles.js +2 -2
  148. package/dist/esm/components/form/Toggle/index.js +2 -2
  149. package/dist/esm/components/form/Toggle/styles.js +10 -10
  150. package/dist/esm/components/form/common/DrawerHeader/index.js +13 -4
  151. package/dist/esm/components/form/common/DrawerHeader/styles.js +16 -6
  152. package/dist/esm/palette/context.js +2 -0
  153. package/dist/esm/palette/provider.js +2 -0
  154. package/dist/hooks/useUnupdatableHandler/index.stories.js +2 -1
  155. package/dist/palette/context.d.ts +2 -0
  156. package/dist/palette/context.js +48 -46
  157. package/dist/palette/provider.js +50 -47
  158. package/dist/palette/usePalette.d.ts +1 -0
  159. package/package.json +1 -1
  160. package/dist/components/form/DateTimeInput/components/MobileNumbersColumn/index.d.ts +0 -8
  161. package/dist/components/form/DateTimeInput/components/MobileNumbersColumn/index.js +0 -201
  162. package/dist/components/form/DateTimeInput/components/MobileNumbersColumn/styles.d.ts +0 -7
  163. package/dist/components/form/DateTimeInput/components/MobileNumbersColumn/styles.js +0 -27
  164. package/dist/esm/components/form/DateTimeInput/components/MobileNumbersColumn/index.js +0 -193
  165. package/dist/esm/components/form/DateTimeInput/components/MobileNumbersColumn/styles.js +0 -19
@@ -0,0 +1,74 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef } from 'react';
2
+ import { MobileWheelPicker, WheelColumn } from '../MobileWheelPicker';
3
+ import { datePickerLogic } from './logic';
4
+ var DAY_COLUMN_WIDTH = 56;
5
+ var MONTH_COLUMN_WIDTH = 116;
6
+ var YEAR_COLUMN_WIDTH = 76;
7
+
8
+ /**
9
+ * Барабанный выбор даты «как в ОС»: день / месяц / год.
10
+ * Время не трогаем — его добавляет вызывающий код, как это делает Calendar.
11
+ */
12
+ export var MobileDatePicker = function MobileDatePicker(_ref) {
13
+ var value = _ref.value,
14
+ onChange = _ref.onChange,
15
+ minDate = _ref.minDate,
16
+ maxDate = _ref.maxDate;
17
+ var fallbackDate = useMemo(function () {
18
+ var today = new Date();
19
+ return datePickerLogic.clampDate(today.getFullYear(), today.getMonth(), today.getDate(), minDate, maxDate);
20
+ // eslint-disable-next-line react-hooks/exhaustive-deps
21
+ }, [minDate === null || minDate === void 0 ? void 0 : minDate.getTime(), maxDate === null || maxDate === void 0 ? void 0 : maxDate.getTime()]);
22
+ var currentDate = value || fallbackDate;
23
+ var year = currentDate.getFullYear();
24
+ var month = currentDate.getMonth();
25
+ var day = currentDate.getDate();
26
+
27
+ // В нативном пикере значение есть всегда: пустое поле открывается на сегодня,
28
+ // и «Готово» сразу доступно. Поднимаем стартовую дату наверх один раз.
29
+ var didInitRef = useRef(false);
30
+ useEffect(function () {
31
+ if (didInitRef.current || value) return;
32
+ didInitRef.current = true;
33
+ onChange(fallbackDate);
34
+ }, [value, fallbackDate, onChange]);
35
+ var yearOptions = useMemo(function () {
36
+ return datePickerLogic.getYearOptions(minDate, maxDate);
37
+ }, [minDate, maxDate]);
38
+ var monthOptions = useMemo(function () {
39
+ return datePickerLogic.getMonthOptions(year, minDate, maxDate);
40
+ }, [year, minDate, maxDate]);
41
+ var dayOptions = useMemo(function () {
42
+ return datePickerLogic.getDayOptions(year, month, minDate, maxDate);
43
+ }, [year, month, minDate, maxDate]);
44
+ var handleDayChange = useCallback(function (newDay) {
45
+ return onChange(datePickerLogic.clampDate(year, month, newDay, minDate, maxDate));
46
+ }, [maxDate, minDate, month, onChange, year]);
47
+ var handleMonthChange = useCallback(function (newMonth) {
48
+ return onChange(datePickerLogic.clampDate(year, newMonth, day, minDate, maxDate));
49
+ }, [day, maxDate, minDate, onChange, year]);
50
+ var handleYearChange = useCallback(function (newYear) {
51
+ return onChange(datePickerLogic.clampDate(newYear, month, day, minDate, maxDate));
52
+ }, [day, maxDate, minDate, month, onChange]);
53
+ return /*#__PURE__*/React.createElement(MobileWheelPicker, {
54
+ label: 'Дата'
55
+ }, /*#__PURE__*/React.createElement(WheelColumn, {
56
+ label: 'День',
57
+ options: dayOptions,
58
+ value: day,
59
+ onChange: handleDayChange,
60
+ width: DAY_COLUMN_WIDTH
61
+ }), /*#__PURE__*/React.createElement(WheelColumn, {
62
+ label: 'Месяц',
63
+ options: monthOptions,
64
+ value: month,
65
+ onChange: handleMonthChange,
66
+ width: MONTH_COLUMN_WIDTH
67
+ }), /*#__PURE__*/React.createElement(WheelColumn, {
68
+ label: 'Год',
69
+ options: yearOptions,
70
+ value: year,
71
+ onChange: handleYearChange,
72
+ width: YEAR_COLUMN_WIDTH
73
+ }));
74
+ };
@@ -0,0 +1,39 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
5
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
6
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
7
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
8
+ import React, { useState } from 'react';
9
+ import { MobileDatePicker } from '.';
10
+ var meta = {
11
+ title: 'form/DateTimeInput/_components/MobileDatePicker',
12
+ component: MobileDatePicker,
13
+ tags: ['autodocs']
14
+ };
15
+ export default meta;
16
+ var Render = function Render(args) {
17
+ var _useState = useState(args.value),
18
+ _useState2 = _slicedToArray(_useState, 2),
19
+ value = _useState2[0],
20
+ setValue = _useState2[1];
21
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(MobileDatePicker, _extends({}, args, {
22
+ value: value,
23
+ onChange: setValue
24
+ })), /*#__PURE__*/React.createElement("div", null, value ? value.toDateString() : 'не выбрано'));
25
+ };
26
+ export var Default = {
27
+ args: {
28
+ value: null
29
+ },
30
+ render: Render
31
+ };
32
+ export var WithMinAndMaxDate = {
33
+ args: {
34
+ value: null,
35
+ minDate: new Date(2024, 5, 10),
36
+ maxDate: new Date(2026, 8, 25)
37
+ },
38
+ render: Render
39
+ };
@@ -0,0 +1,86 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
3
+ function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
4
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
6
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ // Родительный падеж — барабан читается как одна строка: «20 июня 1986».
8
+ export var MONTHS = ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'];
9
+
10
+ // Диапазон лет по умолчанию, когда minDate/maxDate не заданы.
11
+ var YEARS_BACK = 100;
12
+ var YEARS_FORWARD = 100;
13
+ var clampNumber = function clampNumber(value, min, max) {
14
+ return Math.min(Math.max(value, min), max);
15
+ };
16
+ var range = function range(from, to) {
17
+ return to < from ? [from] : new Array(to - from + 1).fill(0).map(function (item, index) {
18
+ return from + index;
19
+ });
20
+ };
21
+ var DatePickerLogic = /*#__PURE__*/function () {
22
+ function DatePickerLogic() {
23
+ _classCallCheck(this, DatePickerLogic);
24
+ }
25
+ return _createClass(DatePickerLogic, [{
26
+ key: "getDaysInMonth",
27
+ value: function getDaysInMonth(year, month) {
28
+ // Нулевой день следующего месяца — последний день текущего.
29
+ return new Date(year, month + 1, 0).getDate();
30
+ }
31
+ }, {
32
+ key: "getYearOptions",
33
+ value: function getYearOptions(minDate, maxDate) {
34
+ var currentYear = new Date().getFullYear();
35
+ var from = minDate ? minDate.getFullYear() : currentYear - YEARS_BACK;
36
+ var to = maxDate ? maxDate.getFullYear() : currentYear + YEARS_FORWARD;
37
+ return range(from, to).map(function (year) {
38
+ return {
39
+ value: year,
40
+ label: year.toString()
41
+ };
42
+ });
43
+ }
44
+ }, {
45
+ key: "getMonthOptions",
46
+ value: function getMonthOptions(year, minDate, maxDate) {
47
+ var from = minDate && year === minDate.getFullYear() ? minDate.getMonth() : 0;
48
+ var to = maxDate && year === maxDate.getFullYear() ? maxDate.getMonth() : 11;
49
+ return range(from, to).map(function (month) {
50
+ return {
51
+ value: month,
52
+ label: MONTHS[month]
53
+ };
54
+ });
55
+ }
56
+ }, {
57
+ key: "getDayOptions",
58
+ value: function getDayOptions(year, month, minDate, maxDate) {
59
+ var isMinMonth = !!minDate && year === minDate.getFullYear() && month === minDate.getMonth();
60
+ var isMaxMonth = !!maxDate && year === maxDate.getFullYear() && month === maxDate.getMonth();
61
+ var from = isMinMonth && minDate ? minDate.getDate() : 1;
62
+ var to = isMaxMonth && maxDate ? maxDate.getDate() : this.getDaysInMonth(year, month);
63
+ return range(from, to).map(function (day) {
64
+ return {
65
+ value: day,
66
+ label: day.toString()
67
+ };
68
+ });
69
+ }
70
+
71
+ // Приводит произвольную комбинацию колонок к дате внутри minDate/maxDate:
72
+ // сначала год, затем месяц (он зависит от года), затем день (зависит от обоих).
73
+ }, {
74
+ key: "clampDate",
75
+ value: function clampDate(year, month, day, minDate, maxDate) {
76
+ var yearOptions = this.getYearOptions(minDate, maxDate);
77
+ var safeYear = clampNumber(year, yearOptions[0].value, yearOptions[yearOptions.length - 1].value);
78
+ var monthOptions = this.getMonthOptions(safeYear, minDate, maxDate);
79
+ var safeMonth = clampNumber(month, monthOptions[0].value, monthOptions[monthOptions.length - 1].value);
80
+ var dayOptions = this.getDayOptions(safeYear, safeMonth, minDate, maxDate);
81
+ var safeDay = clampNumber(day, dayOptions[0].value, dayOptions[dayOptions.length - 1].value);
82
+ return new Date(safeYear, safeMonth, safeDay);
83
+ }
84
+ }]);
85
+ }();
86
+ export var datePickerLogic = new DatePickerLogic();
@@ -7,26 +7,43 @@ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
7
  import React, { useState } from 'react';
8
8
  import { Drawer } from '../../../../common/Drawer';
9
9
  import * as S from './styles';
10
- import { Calendar } from '../../../../common/Calendar';
11
10
  import { TimePicker } from '../TimePicker';
11
+ import { MobileDatePicker } from '../MobileDatePicker';
12
12
  import { logic } from '../../../DateInput/logic';
13
13
  import { DrawerHeader } from '../../../common/DrawerHeader';
14
- export var MobileDrawerDateTimeCalendar = function MobileDrawerDateTimeCalendar(_ref) {
15
- var isOpen = _ref.isOpen,
16
- onClose = _ref.onClose,
17
- maxDate = _ref.maxDate,
18
- minDate = _ref.minDate,
19
- onCalendarChange = _ref.onCalendarChange,
20
- calendarDropdownValue = _ref.calendarDropdownValue,
21
- afterSubmit = _ref.afterSubmit,
22
- onSubmit = _ref.onSubmit,
23
- onTimeChange = _ref.onTimeChange,
24
- maxTime = _ref.maxTime,
25
- minTime = _ref.minTime;
14
+ // Барабан времени должен открываться на допустимом значении: иначе после выбора даты
15
+ // «Готово» остаётся недоступным, пока пользователь вручную не прокрутит часы.
16
+ var clampTime = function clampTime(_ref, minTime, maxTime) {
17
+ var _ref2 = _slicedToArray(_ref, 2),
18
+ hour = _ref2[0],
19
+ minute = _ref2[1];
20
+ if (minTime && (hour < minTime[0] || hour === minTime[0] && minute < minTime[1])) return minTime;
21
+ if (maxTime && (hour > maxTime[0] || hour === maxTime[0] && minute > maxTime[1])) return maxTime;
22
+ return [hour, minute];
23
+ };
24
+
25
+ /**
26
+ * Ввод даты и времени барабанами, как в системных пикерах: сначала шаг с датой,
27
+ * затем шаг со временем. «Отмена» закрывает шторку целиком, правая кнопка ведёт вперёд.
28
+ */
29
+ export var MobileDrawerDateTimeCalendar = function MobileDrawerDateTimeCalendar(_ref3) {
30
+ var isOpen = _ref3.isOpen,
31
+ onClose = _ref3.onClose,
32
+ maxDate = _ref3.maxDate,
33
+ minDate = _ref3.minDate,
34
+ onCalendarChange = _ref3.onCalendarChange,
35
+ calendarDropdownValue = _ref3.calendarDropdownValue,
36
+ afterSubmit = _ref3.afterSubmit,
37
+ onSubmit = _ref3.onSubmit,
38
+ onTimeChange = _ref3.onTimeChange,
39
+ maxTime = _ref3.maxTime,
40
+ minTime = _ref3.minTime;
26
41
  var _useState = useState(true),
27
42
  _useState2 = _slicedToArray(_useState, 2),
28
43
  isDateStep = _useState2[0],
29
44
  setIsDateStep = _useState2[1];
45
+ var currentHour = (calendarDropdownValue === null || calendarDropdownValue === void 0 ? void 0 : calendarDropdownValue.getHours()) || 0;
46
+ var currentMinute = (calendarDropdownValue === null || calendarDropdownValue === void 0 ? void 0 : calendarDropdownValue.getMinutes()) || 0;
30
47
  var handleClose = function handleClose() {
31
48
  onClose();
32
49
  setIsDateStep(true);
@@ -34,14 +51,14 @@ export var MobileDrawerDateTimeCalendar = function MobileDrawerDateTimeCalendar(
34
51
  var handleDone = function handleDone() {
35
52
  if (isDateStep) {
36
53
  setIsDateStep(false);
54
+ var safeTime = clampTime([currentHour, currentMinute], minTime, maxTime);
55
+ if (safeTime[0] !== currentHour || safeTime[1] !== currentMinute) onTimeChange(safeTime);
37
56
  } else {
38
57
  onSubmit();
39
58
  afterSubmit();
40
59
  setIsDateStep(true);
41
60
  }
42
61
  };
43
- var currentHour = (calendarDropdownValue === null || calendarDropdownValue === void 0 ? void 0 : calendarDropdownValue.getHours()) || 0;
44
- var currentMinute = (calendarDropdownValue === null || calendarDropdownValue === void 0 ? void 0 : calendarDropdownValue.getMinutes()) || 0;
45
62
  return /*#__PURE__*/React.createElement(Drawer, {
46
63
  onClose: handleClose,
47
64
  isOpen: isOpen,
@@ -49,15 +66,17 @@ export var MobileDrawerDateTimeCalendar = function MobileDrawerDateTimeCalendar(
49
66
  }, /*#__PURE__*/React.createElement(DrawerHeader, {
50
67
  onClose: handleClose,
51
68
  onSubmit: handleDone,
52
- label: isDateStep ? 'Выберите дату' : 'Выберите время',
53
- isSubmitDisabled: isDateStep ? !calendarDropdownValue : !calendarDropdownValue || !logic.isBetweenMinAndMax(calendarDropdownValue, minDate, maxDate)
54
- }), isDateStep ? /*#__PURE__*/React.createElement(S.MobileCalendarWrapper, null, /*#__PURE__*/React.createElement(Calendar, {
69
+ closeLabel: 'Отмена',
70
+ submitLabel: isDateStep ? 'Далее' : 'Готово',
71
+ label: isDateStep ? 'Дата' : 'Время',
72
+ isSubmitDisabled: !calendarDropdownValue || !isDateStep && !logic.isBetweenMinAndMax(calendarDropdownValue, minDate, maxDate)
73
+ }), /*#__PURE__*/React.createElement(S.PickerWrapper, null, isDateStep ? /*#__PURE__*/React.createElement(MobileDatePicker, {
55
74
  value: calendarDropdownValue,
56
75
  onChange: onCalendarChange,
57
76
  minDate: minDate,
58
- maxDate: maxDate,
59
- isLargeMobileSize: true
60
- })) : /*#__PURE__*/React.createElement(S.TimePickerWrapper, null, /*#__PURE__*/React.createElement(TimePicker, {
77
+ maxDate: maxDate
78
+ }) : /*#__PURE__*/React.createElement(TimePicker, {
79
+ isMobile: true,
61
80
  value: [currentHour, currentMinute],
62
81
  onChange: onTimeChange,
63
82
  maxTime: maxTime,
@@ -1,9 +1,5 @@
1
1
  import styled from 'styled-components';
2
- export var MobileCalendarWrapper = styled.div.withConfig({
3
- displayName: "styles__MobileCalendarWrapper",
2
+ export var PickerWrapper = styled.div.withConfig({
3
+ displayName: "styles__PickerWrapper",
4
4
  componentId: "sc-vw0y4c-0"
5
- })(["padding:18px 16px 30px;display:flex;justify-content:center;"]);
6
- export var TimePickerWrapper = styled.div.withConfig({
7
- displayName: "styles__TimePickerWrapper",
8
- componentId: "sc-vw0y4c-1"
9
- })(["padding-bottom:30px;display:flex;justify-content:center;"]);
5
+ })(["padding:20px 16px 30px;display:flex;justify-content:center;"]);
@@ -0,0 +1,250 @@
1
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
2
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
4
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
5
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ import * as S from './styles';
9
+ import { DRAG_THRESHOLD, FRAME_MS, FRICTION_PER_FRAME, ITEM_HEIGHT, MAX_VELOCITY, MIN_VELOCITY, SETTLE_MS, STALE_DRAG_MS } from '../../constants';
10
+ import { useComponentPalette } from '../../../../../../../palette';
11
+ // Затухание строк по мере удаления от центра — имитация барабана из нативных пикеров.
12
+ var OPACITY_STEPS = [1, 0.75, 0.45, 0.28, 0.18];
13
+ var INCLINE_STEPS = [0, 22, 42, 58, 68];
14
+ var SCALE_STEPS = [1, 0.94, 0.87, 0.82, 0.78];
15
+ var getIndexByScrollTop = function getIndexByScrollTop(scrollTop, count) {
16
+ return Math.min(Math.max(Math.round(scrollTop / ITEM_HEIGHT), 0), Math.max(count - 1, 0));
17
+ };
18
+ var clampVelocity = function clampVelocity(velocity) {
19
+ return Math.min(Math.max(velocity, -MAX_VELOCITY), MAX_VELOCITY);
20
+ };
21
+ export var WheelColumn = function WheelColumn(_ref) {
22
+ var _options$activeIndex;
23
+ var options = _ref.options,
24
+ value = _ref.value,
25
+ onChange = _ref.onChange,
26
+ label = _ref.label,
27
+ _ref$align = _ref.align,
28
+ align = _ref$align === void 0 ? 'center' : _ref$align,
29
+ width = _ref.width;
30
+ var palette = useComponentPalette('mobileWheelPicker');
31
+ var containerRef = useRef(null);
32
+ var rafRef = useRef(null);
33
+ var settleRef = useRef(null);
34
+ var isUserScrollingRef = useRef(false);
35
+ var isMountedRef = useRef(false);
36
+ var dragRef = useRef(null);
37
+ var inertiaRef = useRef(null);
38
+ var isClickSuppressedRef = useRef(false);
39
+ var valueIndex = useMemo(function () {
40
+ var index = options.findIndex(function (option) {
41
+ return option.value === value;
42
+ });
43
+ return index === -1 ? 0 : index;
44
+ }, [options, value]);
45
+ var _useState = useState(valueIndex),
46
+ _useState2 = _slicedToArray(_useState, 2),
47
+ activeIndex = _useState2[0],
48
+ setActiveIndex = _useState2[1];
49
+
50
+ // Подписка на скролл вешается один раз: пересоздание слушателя сбрасывало бы
51
+ // таймер остановки барабана, и onChange мог не долететь до родителя.
52
+ var optionsRef = useRef(options);
53
+ var valueRef = useRef(value);
54
+ var onChangeRef = useRef(onChange);
55
+ useEffect(function () {
56
+ optionsRef.current = options;
57
+ valueRef.current = value;
58
+ onChangeRef.current = onChange;
59
+ });
60
+
61
+ // Подсветка следует за значением, когда его меняют снаружи (например, клампят день после смены месяца).
62
+ useEffect(function () {
63
+ return setActiveIndex(valueIndex);
64
+ }, [valueIndex]);
65
+
66
+ // Доводим барабан до выбранного значения. Пока палец на экране не вмешиваемся,
67
+ // иначе перерисовка родителя дёргала бы скролл из-под пользователя.
68
+ useEffect(function () {
69
+ var container = containerRef.current;
70
+ if (!container || isUserScrollingRef.current) return;
71
+ var top = valueIndex * ITEM_HEIGHT;
72
+ if (Math.abs(container.scrollTop - top) < 1) return;
73
+ container.scrollTo({
74
+ top: top,
75
+ behavior: isMountedRef.current ? 'smooth' : 'auto'
76
+ });
77
+ }, [valueIndex, options.length]);
78
+ useEffect(function () {
79
+ isMountedRef.current = true;
80
+ }, []);
81
+ useEffect(function () {
82
+ var container = containerRef.current;
83
+ if (!container) return undefined;
84
+ var handleScroll = function handleScroll() {
85
+ isUserScrollingRef.current = true;
86
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
87
+ rafRef.current = requestAnimationFrame(function () {
88
+ // setState с тем же индексом React отбрасывает, поэтому перерисовка
89
+ // происходит не на каждый кадр, а только при переходе на новую строку.
90
+ setActiveIndex(getIndexByScrollTop(container.scrollTop, optionsRef.current.length));
91
+ });
92
+ if (settleRef.current) clearTimeout(settleRef.current);
93
+ settleRef.current = setTimeout(function () {
94
+ isUserScrollingRef.current = false;
95
+ var index = getIndexByScrollTop(container.scrollTop, optionsRef.current.length);
96
+ setActiveIndex(index);
97
+ var option = optionsRef.current[index];
98
+ if (option && option.value !== valueRef.current) onChangeRef.current(option.value);
99
+ }, SETTLE_MS);
100
+ };
101
+ container.addEventListener('scroll', handleScroll, {
102
+ passive: true
103
+ });
104
+ return function () {
105
+ container.removeEventListener('scroll', handleScroll);
106
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
107
+ if (settleRef.current) clearTimeout(settleRef.current);
108
+ };
109
+ }, []);
110
+ var stopInertia = useCallback(function () {
111
+ if (!inertiaRef.current) return;
112
+ cancelAnimationFrame(inertiaRef.current);
113
+ inertiaRef.current = null;
114
+ }, []);
115
+ useEffect(function () {
116
+ return stopInertia;
117
+ }, [stopInertia]);
118
+
119
+ // Пока барабан ведёт палец или инерция, залипание выключено: браузер иначе
120
+ // отматывал бы scrollTop обратно к ближайшей строке на каждый кадр.
121
+ var setSnapEnabled = useCallback(function (isEnabled) {
122
+ var container = containerRef.current;
123
+ if (container) container.style.scrollSnapType = isEnabled ? '' : 'none';
124
+ }, []);
125
+
126
+ // Барабан остановился — возвращаем залипание и доводим до строки. onChange
127
+ // отправит общий обработчик скролла, когда доводка закончится.
128
+ var finishDrag = useCallback(function () {
129
+ var container = containerRef.current;
130
+ if (!container) return;
131
+ setSnapEnabled(true);
132
+ var index = getIndexByScrollTop(container.scrollTop, optionsRef.current.length);
133
+ container.scrollTo({
134
+ top: index * ITEM_HEIGHT,
135
+ behavior: 'smooth'
136
+ });
137
+ }, [setSnapEnabled]);
138
+ var startInertia = useCallback(function (initialVelocity) {
139
+ var container = containerRef.current;
140
+ if (!container) return;
141
+ var velocity = initialVelocity;
142
+ var previousTime = performance.now();
143
+ var _step = function step(now) {
144
+ // Кадр мог быть пропущен (вкладка в фоне) — не даём барабану прыгнуть.
145
+ var elapsed = Math.min(now - previousTime, 50);
146
+ previousTime = now;
147
+ var shift = velocity * elapsed;
148
+ var scrollTopBefore = container.scrollTop;
149
+ container.scrollTop = scrollTopBefore - shift;
150
+ velocity *= Math.pow(FRICTION_PER_FRAME, elapsed / FRAME_MS);
151
+
152
+ // scrollTop не сдвинулся, хотя должен был — упёрлись в край списка.
153
+ var isStuck = Math.abs(shift) >= 1 && container.scrollTop === scrollTopBefore;
154
+ if (Math.abs(velocity) < MIN_VELOCITY || isStuck) {
155
+ inertiaRef.current = null;
156
+ finishDrag();
157
+ return;
158
+ }
159
+ inertiaRef.current = requestAnimationFrame(_step);
160
+ };
161
+ inertiaRef.current = requestAnimationFrame(_step);
162
+ }, [finishDrag]);
163
+ var handlePointerDown = useCallback(function (event) {
164
+ var _event$currentTarget$, _event$currentTarget;
165
+ // Толчок по крутящемуся барабану ловит его — как в нативных пикерах.
166
+ stopInertia();
167
+ setSnapEnabled(false);
168
+ isClickSuppressedRef.current = false;
169
+ isUserScrollingRef.current = true;
170
+ dragRef.current = {
171
+ pointerId: event.pointerId,
172
+ startY: event.clientY,
173
+ lastY: event.clientY,
174
+ lastTime: event.timeStamp,
175
+ velocity: 0,
176
+ isMoved: false
177
+ };
178
+ (_event$currentTarget$ = (_event$currentTarget = event.currentTarget).setPointerCapture) === null || _event$currentTarget$ === void 0 || _event$currentTarget$.call(_event$currentTarget, event.pointerId);
179
+ }, [setSnapEnabled, stopInertia]);
180
+ var handlePointerMove = useCallback(function (event) {
181
+ var drag = dragRef.current;
182
+ var container = containerRef.current;
183
+ if (!drag || !container || drag.pointerId !== event.pointerId) return;
184
+ var shift = event.clientY - drag.lastY;
185
+ var elapsed = event.timeStamp - drag.lastTime;
186
+ container.scrollTop -= shift;
187
+
188
+ // Скорость сглаживаем: дрожание пальца в конце жеста иначе гасит бросок.
189
+ if (elapsed > 0) drag.velocity = drag.velocity * 0.7 + shift / elapsed * 0.3;
190
+ if (Math.abs(event.clientY - drag.startY) > DRAG_THRESHOLD) drag.isMoved = true;
191
+ drag.lastY = event.clientY;
192
+ drag.lastTime = event.timeStamp;
193
+ }, []);
194
+ var handlePointerUp = useCallback(function (event) {
195
+ var drag = dragRef.current;
196
+ if (!drag || drag.pointerId !== event.pointerId) return;
197
+ dragRef.current = null;
198
+ isClickSuppressedRef.current = drag.isMoved;
199
+
200
+ // Палец замер перед отпусканием — это доводка, а не бросок.
201
+ var isStale = event.timeStamp - drag.lastTime > STALE_DRAG_MS;
202
+ var velocity = isStale ? 0 : clampVelocity(drag.velocity);
203
+ if (Math.abs(velocity) < MIN_VELOCITY) {
204
+ finishDrag();
205
+ return;
206
+ }
207
+ startInertia(velocity);
208
+ }, [finishDrag, startInertia]);
209
+ var handleItemClick = useCallback(function (index) {
210
+ var _containerRef$current;
211
+ if (isClickSuppressedRef.current) return;
212
+ (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 || _containerRef$current.scrollTo({
213
+ top: index * ITEM_HEIGHT,
214
+ behavior: 'smooth'
215
+ });
216
+ }, []);
217
+ var activeValue = (_options$activeIndex = options[activeIndex]) === null || _options$activeIndex === void 0 ? void 0 : _options$activeIndex.value;
218
+ return /*#__PURE__*/React.createElement(S.Wrapper, {
219
+ ref: containerRef,
220
+ $align: align,
221
+ style: width ? {
222
+ width: width
223
+ } : undefined,
224
+ role: "listbox",
225
+ "aria-label": label,
226
+ tabIndex: -1,
227
+ onPointerDown: handlePointerDown,
228
+ onPointerMove: handlePointerMove,
229
+ onPointerUp: handlePointerUp,
230
+ onPointerCancel: handlePointerUp
231
+ }, options.map(function (option, index) {
232
+ var step = Math.min(Math.abs(index - activeIndex), OPACITY_STEPS.length - 1);
233
+ var isActive = index === activeIndex;
234
+ return /*#__PURE__*/React.createElement(S.Item, {
235
+ key: option.value,
236
+ type: "button",
237
+ role: "option",
238
+ "aria-selected": option.value === activeValue,
239
+ onClick: function onClick() {
240
+ return handleItemClick(index);
241
+ },
242
+ $color: palette.value,
243
+ $colorActive: palette.valueActive,
244
+ $isActive: isActive,
245
+ $opacity: OPACITY_STEPS[step],
246
+ $incline: INCLINE_STEPS[step],
247
+ $scale: SCALE_STEPS[step]
248
+ }, option.label);
249
+ }));
250
+ };
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components';
2
+ import { reducedMotion } from '../../../../../../../utils/reducedMotion';
3
+ import { EDGE_PADDING, ITEM_HEIGHT } from '../../constants';
4
+ export var Wrapper = styled.div.withConfig({
5
+ displayName: "styles__Wrapper",
6
+ componentId: "sc-xvigbn-0"
7
+ })(["height:100%;flex-shrink:0;box-sizing:border-box;padding:", "px 0;overflow-y:scroll;overscroll-behavior:contain;scroll-snap-type:y mandatory;-webkit-overflow-scrolling:touch;text-align:", ";touch-action:none;user-select:none;-webkit-user-select:none;cursor:grab;&:active{cursor:grabbing;}scrollbar-width:none;-ms-overflow-style:none;&::-webkit-scrollbar{display:none;}"], EDGE_PADDING, function (_ref) {
8
+ var $align = _ref.$align;
9
+ return $align;
10
+ });
11
+ export var Item = styled.button.withConfig({
12
+ displayName: "styles__Item",
13
+ componentId: "sc-xvigbn-1"
14
+ })(["display:block;width:100%;height:", "px;padding:0;margin:0;border:none;background:transparent;cursor:pointer;outline:none;white-space:nowrap;scroll-snap-align:center;font:inherit;text-align:inherit;line-height:", "px;color:", ";opacity:", ";transform:rotateX(", "deg) scale(", ");backface-visibility:hidden;transition:opacity 0.12s ease,transform 0.12s ease,color 0.12s ease;", ""], ITEM_HEIGHT, ITEM_HEIGHT, function (_ref2) {
15
+ var $isActive = _ref2.$isActive,
16
+ $color = _ref2.$color,
17
+ $colorActive = _ref2.$colorActive;
18
+ return $isActive ? $colorActive : $color;
19
+ }, function (_ref3) {
20
+ var $opacity = _ref3.$opacity;
21
+ return $opacity;
22
+ }, function (_ref4) {
23
+ var $incline = _ref4.$incline;
24
+ return $incline;
25
+ }, function (_ref5) {
26
+ var $scale = _ref5.$scale;
27
+ return $scale;
28
+ }, reducedMotion);
@@ -0,0 +1,34 @@
1
+ // Геометрия барабана. Все вычисления скролла завязаны на эти константы:
2
+ // scrollTop выбранного элемента === index * ITEM_HEIGHT (см. getIndexByScrollTop).
3
+ export var ITEM_HEIGHT = 34;
4
+
5
+ // Нечётное число, чтобы выбранный элемент оказался ровно по центру колонки.
6
+ export var VISIBLE_ITEMS = 5;
7
+ export var WHEEL_HEIGHT = ITEM_HEIGHT * VISIBLE_ITEMS;
8
+
9
+ // Сколько пустого места нужно сверху и снизу, чтобы крайние элементы вставали в центр.
10
+ export var EDGE_PADDING = ITEM_HEIGHT * ((VISIBLE_ITEMS - 1) / 2);
11
+
12
+ // Пауза без событий скролла, после которой считаем, что барабан остановился.
13
+ export var SETTLE_MS = 140;
14
+
15
+ // --- Инерция ---
16
+ // Барабан крутится сам после броска. Нативный fling есть только у тач-скролла, поэтому
17
+ // перетаскивание ведём сами: так «толчок» работает и пальцем, и мышью, и одинаково
18
+ // ощущается на всех платформах.
19
+
20
+ // Доля скорости, сохраняемая за кадр при 60fps. Меньше — барабан встаёт резче.
21
+ export var FRICTION_PER_FRAME = 0.94;
22
+ export var FRAME_MS = 1000 / 60;
23
+
24
+ // Скорость в px/ms, ниже которой барабан считаем остановившимся.
25
+ export var MIN_VELOCITY = 0.02;
26
+
27
+ // Потолок броска: без него резкий свайп улетал бы на сотни строк.
28
+ export var MAX_VELOCITY = 4;
29
+
30
+ // Сдвиг в px, после которого жест перестаёт быть кликом по строке.
31
+ export var DRAG_THRESHOLD = 4;
32
+
33
+ // Если перед отпусканием палец простоял дольше — это не бросок, а точная доводка.
34
+ export var STALE_DRAG_MS = 80;