@alfalab/core-components-number-input 1.3.0 → 2.0.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 (90) hide show
  1. package/Component.desktop.d.ts +1 -1
  2. package/Component.desktop.js +9 -1
  3. package/Component.mobile.d.ts +1 -1
  4. package/Component.mobile.js +9 -1
  5. package/Component.responsive.d.ts +1 -1
  6. package/Component.responsive.js +14 -1
  7. package/components/number-input/Component.d.ts +21 -46
  8. package/components/number-input/Component.js +87 -84
  9. package/components/number-input/index.css +30 -0
  10. package/components/number-input/index.js +8 -0
  11. package/components/steppers/Component.d.ts +14 -0
  12. package/components/steppers/Component.js +33 -0
  13. package/components/steppers/index.css +32 -0
  14. package/components/steppers/index.d.ts +1 -0
  15. package/components/steppers/index.js +15 -0
  16. package/cssm/Component.desktop.d.ts +1 -1
  17. package/cssm/Component.desktop.js +11 -1
  18. package/cssm/Component.mobile.d.ts +1 -1
  19. package/cssm/Component.mobile.js +11 -1
  20. package/cssm/Component.responsive.d.ts +1 -1
  21. package/cssm/Component.responsive.js +16 -1
  22. package/cssm/components/number-input/Component.d.ts +21 -46
  23. package/cssm/components/number-input/Component.js +87 -84
  24. package/cssm/components/number-input/index.js +10 -0
  25. package/cssm/components/number-input/index.module.css +29 -0
  26. package/cssm/components/steppers/Component.d.ts +14 -0
  27. package/cssm/components/steppers/Component.js +32 -0
  28. package/cssm/components/steppers/index.d.ts +1 -0
  29. package/cssm/components/steppers/index.js +16 -0
  30. package/cssm/components/steppers/index.module.css +31 -0
  31. package/cssm/desktop/index.js +10 -0
  32. package/cssm/index.js +11 -0
  33. package/cssm/mobile/index.js +10 -0
  34. package/cssm/utils.d.ts +19 -9
  35. package/cssm/utils.js +244 -21
  36. package/desktop/index.js +8 -0
  37. package/esm/Component.desktop.d.ts +1 -1
  38. package/esm/Component.desktop.js +9 -1
  39. package/esm/Component.mobile.d.ts +1 -1
  40. package/esm/Component.mobile.js +9 -1
  41. package/esm/Component.responsive.d.ts +1 -1
  42. package/esm/Component.responsive.js +15 -2
  43. package/esm/components/number-input/Component.d.ts +21 -46
  44. package/esm/components/number-input/Component.js +88 -86
  45. package/esm/components/number-input/index.css +30 -0
  46. package/esm/components/number-input/index.js +8 -0
  47. package/esm/components/steppers/Component.d.ts +14 -0
  48. package/esm/components/steppers/Component.js +24 -0
  49. package/esm/components/steppers/index.css +32 -0
  50. package/esm/components/steppers/index.d.ts +1 -0
  51. package/esm/components/steppers/index.js +7 -0
  52. package/esm/desktop/index.js +8 -0
  53. package/esm/index.js +9 -0
  54. package/esm/mobile/index.js +8 -0
  55. package/esm/utils.d.ts +19 -9
  56. package/esm/utils.js +236 -19
  57. package/index.js +9 -0
  58. package/mobile/index.js +8 -0
  59. package/modern/Component.desktop.d.ts +1 -1
  60. package/modern/Component.desktop.js +9 -1
  61. package/modern/Component.mobile.d.ts +1 -1
  62. package/modern/Component.mobile.js +9 -1
  63. package/modern/Component.responsive.d.ts +1 -1
  64. package/modern/Component.responsive.js +13 -1
  65. package/modern/components/number-input/Component.d.ts +21 -46
  66. package/modern/components/number-input/Component.js +84 -86
  67. package/modern/components/number-input/index.css +30 -0
  68. package/modern/components/number-input/index.js +8 -0
  69. package/modern/components/steppers/Component.d.ts +14 -0
  70. package/modern/components/steppers/Component.js +23 -0
  71. package/modern/components/steppers/index.css +32 -0
  72. package/modern/components/steppers/index.d.ts +1 -0
  73. package/modern/components/steppers/index.js +7 -0
  74. package/modern/desktop/index.js +8 -0
  75. package/modern/index.js +9 -0
  76. package/modern/mobile/index.js +8 -0
  77. package/modern/utils.d.ts +19 -9
  78. package/modern/utils.js +223 -18
  79. package/package.json +9 -2
  80. package/src/Component.desktop.tsx +2 -2
  81. package/src/Component.mobile.tsx +2 -2
  82. package/src/Component.responsive.tsx +16 -2
  83. package/src/components/number-input/Component.tsx +195 -129
  84. package/src/components/number-input/index.module.css +18 -0
  85. package/src/components/steppers/Component.tsx +64 -0
  86. package/src/components/steppers/index.module.css +21 -0
  87. package/src/components/steppers/index.ts +1 -0
  88. package/src/utils.ts +302 -24
  89. package/utils.d.ts +19 -9
  90. package/utils.js +244 -21
package/esm/utils.js CHANGED
@@ -1,29 +1,246 @@
1
- var SIGNS = ['-', '+'];
1
+ import { maskitoTransform } from '@maskito/core';
2
+ import { fnUtils } from '@alfalab/core-components-shared/esm';
3
+
4
+ /* eslint-disable no-param-reassign */
5
+ var MINUS_SIGN = '-';
2
6
  var SEPARATORS = [',', '.'];
3
- function createSeparatorsRegExp() {
4
- return new RegExp("[".concat(SEPARATORS.map(function (s) { return "\\".concat(s); }).join(''), "]"), 'g');
7
+ var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
8
+ var MIN_SAFE_INTEGER = -MAX_SAFE_INTEGER;
9
+ var MAX_DIGITS = 15; // с 16 уже упираемся в MAX_SAFE_INTEGER
10
+ function parseNumber(value) {
11
+ if (value === void 0) { value = ''; }
12
+ if (typeof value === 'number')
13
+ return value;
14
+ var pseudoSeparatorsRegExp = new RegExp("[".concat(SEPARATORS.join(''), "]"), 'gi');
15
+ return value
16
+ ? parseFloat(value
17
+ .replace(new RegExp("[^".concat(MINUS_SIGN).concat(SEPARATORS.join(''), "0-9]"), 'gi'), '')
18
+ .replace(pseudoSeparatorsRegExp, '.'))
19
+ : NaN;
5
20
  }
6
- var getNumberRegExp = function (fractionLength) {
7
- var reStr = '[0-9]+';
21
+ /**
22
+ * Преобразовать число в строку с заменой экспоненты на десятичную дробь
23
+ */
24
+ function stringifyNumberWithoutExp(value) {
25
+ var valueString = String(value);
26
+ var _a = valueString.split('e-'), numberPart = _a[0], expPart = _a[1];
27
+ var valueWithoutExp = valueString;
28
+ if (expPart) {
29
+ var _b = numberPart.split('.'), fractionalPart = _b[1];
30
+ var decimalDigits = Number(expPart) + ((fractionalPart === null || fractionalPart === void 0 ? void 0 : fractionalPart.length) || 0);
31
+ valueWithoutExp = value.toFixed(decimalDigits);
32
+ }
33
+ return valueWithoutExp;
34
+ }
35
+ var getNumberRegExp = function (min, fractionLength) {
36
+ var reStr = '[0-9]*';
37
+ if (min < 0) {
38
+ reStr = "(\\".concat(MINUS_SIGN, ")?").concat(reStr);
39
+ }
8
40
  if (fractionLength !== 0) {
9
- reStr = "".concat(reStr, "[").concat(SEPARATORS.map(function (s) { return "\\".concat(s); }).join(''), "]?[0-9]{0,").concat(fractionLength || Number.MAX_SAFE_INTEGER, "}");
41
+ reStr = "".concat(reStr, "[").concat(SEPARATORS.map(function (s) { return "\\".concat(s); }).join(''), "]?[0-9]{0,").concat(fractionLength || MAX_DIGITS, "}");
10
42
  }
11
43
  return new RegExp("^".concat(reStr, "$"));
12
44
  };
45
+ function createMaskOptions(_a) {
46
+ var separator = _a.separator, fractionLength = _a.fractionLength, min = _a.min, max = _a.max;
47
+ return {
48
+ mask: getNumberRegExp(min, fractionLength),
49
+ preprocessors: [
50
+ createPseudoSeparatorPreprocessor(separator),
51
+ createNotEmptyIntegerPartPreprocessor({ separator: separator, fractionLength: fractionLength }),
52
+ createZeroFractionLengthPreprocessor(fractionLength, separator),
53
+ createRepeatedSeparatorPreprocessor(separator),
54
+ ],
55
+ postprocessors: [
56
+ createLeadingZeroesValidationPostprocessor(separator),
57
+ createMinMaxPostprocessor({ min: min, max: max, separator: separator }),
58
+ ],
59
+ plugins: [createNotEmptyPartsPlugin(separator), createMinMaxPlugin({ min: min, max: max })],
60
+ };
61
+ }
13
62
  /**
14
- * Проверка вводимых значений.
63
+ * Заполняет целочисленную часть при вводе separator.
64
+ * @example Type , => 0,
15
65
  */
16
- var getAllowedValue = function (_a) {
17
- var _b = _a.value, value = _b === void 0 ? '' : _b, fractionLength = _a.fractionLength, separator = _a.separator, allowSigns = _a.allowSigns;
18
- var sign = allowSigns && SIGNS.some(function (s) { return s === value[0]; }) ? value[0] : '';
19
- var testedValue = sign ? value.slice(1) : value;
20
- if (getNumberRegExp(fractionLength).test(testedValue)) {
21
- return value;
66
+ function createNotEmptyIntegerPartPreprocessor(_a) {
67
+ var separator = _a.separator, fractionLength = _a.fractionLength;
68
+ var startWithDecimalSepRegExp = new RegExp("^\\D*\\".concat(separator));
69
+ return function (_a) {
70
+ var elementState = _a.elementState, data = _a.data;
71
+ var value = elementState.value, selection = elementState.selection;
72
+ var from = selection[0];
73
+ if (fractionLength <= 0 ||
74
+ value.includes(separator) ||
75
+ !data.match(startWithDecimalSepRegExp)) {
76
+ return { elementState: elementState, data: data };
77
+ }
78
+ var digitsBeforeCursor = value.slice(0, from).match(/\d+/);
79
+ return {
80
+ elementState: elementState,
81
+ data: digitsBeforeCursor ? data : "0".concat(data),
82
+ };
83
+ };
84
+ }
85
+ /**
86
+ * Не позволяет вводить невалидный разделитель.
87
+ */
88
+ function createPseudoSeparatorPreprocessor(separator) {
89
+ var pseudoSeparatorsRegExp = new RegExp("[".concat(SEPARATORS.join(''), "]"), 'gi');
90
+ return function (_a) {
91
+ var elementState = _a.elementState, data = _a.data;
92
+ var value = elementState.value, selection = elementState.selection;
93
+ return {
94
+ elementState: {
95
+ selection: selection,
96
+ value: value.replace(pseudoSeparatorsRegExp, separator),
97
+ },
98
+ data: data.replace(pseudoSeparatorsRegExp, separator),
99
+ };
100
+ };
101
+ }
102
+ /**
103
+ * Помогает верно обрезать значения при вставке, если fractionLength===0
104
+ * @example paste 123,123 -> 123
105
+ */
106
+ function createZeroFractionLengthPreprocessor(fractionLength, separator) {
107
+ if (fractionLength > 0) {
108
+ return function (state) { return state; };
22
109
  }
23
- var _c = testedValue
24
- .split(separator)
25
- .map(function (v) { return v.replace(/[^0-9]/g, ''); }), majorPart = _c[0], minorPart = _c[1];
26
- return "".concat(sign).concat(majorPart).concat(minorPart ? separator + minorPart.slice(0, fractionLength) : '');
27
- };
110
+ var decimalPartRegExp = new RegExp("\\".concat(separator, ".*$"), 'g');
111
+ return function (_a) {
112
+ var elementState = _a.elementState, data = _a.data;
113
+ var value = elementState.value, selection = elementState.selection;
114
+ var from = selection[0], to = selection[1];
115
+ var newValue = value.replace(decimalPartRegExp, '');
116
+ return {
117
+ elementState: {
118
+ selection: [Math.min(from, newValue.length), Math.min(to, newValue.length)],
119
+ value: newValue,
120
+ },
121
+ data: data.replace(decimalPartRegExp, ''),
122
+ };
123
+ };
124
+ }
125
+ /**
126
+ * Запрещает вводить второй сепаратор
127
+ */
128
+ function createRepeatedSeparatorPreprocessor(separator) {
129
+ return function (_a) {
130
+ var elementState = _a.elementState, data = _a.data;
131
+ var value = elementState.value, selection = elementState.selection;
132
+ var from = selection[0], to = selection[1];
133
+ return {
134
+ elementState: elementState,
135
+ data: !value.includes(separator) || value.slice(from, to + 1).includes(separator)
136
+ ? data
137
+ : data.replace(new RegExp("\\".concat(separator)), ''),
138
+ };
139
+ };
140
+ }
141
+ /**
142
+ * Удаляет лишние нули в начале целой части.
143
+ * @example 0,|00005 => Backspace => |5
144
+ * @example -0,|00005 => Backspace => -|5
145
+ * @example "000000" => 0|
146
+ * @example 0| => Type "5" => 5|
147
+ */
148
+ function createLeadingZeroesValidationPostprocessor(separator) {
149
+ var trimLeadingZeroes = function (value) {
150
+ return value
151
+ .replace(new RegExp('^(\\D+)?0+(?=0)'), '$1')
152
+ .replace(new RegExp('^(\\D+)?0+(?=[1-9])'), '$1');
153
+ };
154
+ var countTrimmedZeroesBefore = function (value, index) {
155
+ var valueBefore = value.slice(0, index);
156
+ var followedByZero = value.slice(index).startsWith('0');
157
+ return (valueBefore.length - trimLeadingZeroes(valueBefore).length + (followedByZero ? 1 : 0));
158
+ };
159
+ return function (_a) {
160
+ var value = _a.value, selection = _a.selection;
161
+ var from = selection[0], to = selection[1];
162
+ var hasSeparator = value.includes(separator);
163
+ var _b = value.split(separator), integerPart = _b[0], _c = _b[1], decimalPart = _c === void 0 ? '' : _c;
164
+ var zeroTrimmedIntegerPart = trimLeadingZeroes(integerPart);
165
+ if (integerPart === zeroTrimmedIntegerPart) {
166
+ return { value: value, selection: selection };
167
+ }
168
+ var newFrom = from - countTrimmedZeroesBefore(value, from);
169
+ var newTo = to - countTrimmedZeroesBefore(value, to);
170
+ return {
171
+ value: zeroTrimmedIntegerPart + (hasSeparator ? separator : '') + decimalPart,
172
+ selection: [Math.max(newFrom, 0), Math.max(newTo, 0)],
173
+ };
174
+ };
175
+ }
176
+ /**
177
+ * Валидирует значение с учетом min max значений.
178
+ * Работает совместно с createMinMaxPlugin
179
+ */
180
+ function createMinMaxPostprocessor(_a) {
181
+ var min = _a.min, max = _a.max, separator = _a.separator;
182
+ return function (_a) {
183
+ var value = _a.value, selection = _a.selection;
184
+ var parsedNumber = parseNumber(value);
185
+ var limitedValue =
186
+ /**
187
+ * Здесь невозможно ограничить нижнюю границу, если пользователь вводит положительное число.
188
+ * То же самое для верхней границы и отрицательного числа.
189
+ * Если min=5, то без этого условия не получится ввести 40, похожая ситуация и с отрицательным max
190
+ */
191
+ parsedNumber > 0 ? Math.min(parsedNumber, max) : Math.max(parsedNumber, min);
192
+ if (!Number.isNaN(parsedNumber) && limitedValue !== parsedNumber) {
193
+ var newValue = "".concat(limitedValue).replace('.', separator);
194
+ return {
195
+ value: newValue,
196
+ selection: [newValue.length, newValue.length],
197
+ };
198
+ }
199
+ return {
200
+ value: value,
201
+ selection: selection,
202
+ };
203
+ };
204
+ }
205
+ function createMinMaxPlugin(_a) {
206
+ var min = _a.min, max = _a.max;
207
+ return function (element, options) {
208
+ var listener = function () {
209
+ var parsedNumber = parseNumber(element.value);
210
+ var clampedNumber = fnUtils.clamp(parsedNumber, min, max);
211
+ if (!Number.isNaN(parsedNumber) && parsedNumber !== clampedNumber) {
212
+ element.value = maskitoTransform(stringifyNumberWithoutExp(clampedNumber), options);
213
+ element.dispatchEvent(new Event('input', { bubbles: true }));
214
+ }
215
+ };
216
+ var evListenerOptions = { capture: true };
217
+ element.addEventListener('blur', listener, evListenerOptions);
218
+ return function () { return element.removeEventListener('blur', listener, evListenerOptions); };
219
+ };
220
+ }
221
+ function createNotEmptyPartsPlugin(separator) {
222
+ return function (element) {
223
+ var listener = function () {
224
+ var newValue = element.value
225
+ // 0,9000000 -> 0,9
226
+ .replace(new RegExp("(\\".concat(separator, "\\d*?)(0+$)")), '$1')
227
+ // ,2 => 0,2
228
+ .replace(new RegExp("^(\\D+)?\\".concat(separator)), "$10".concat(separator))
229
+ // 0, -> 0
230
+ .replace(new RegExp("\\".concat(separator, "$")), '')
231
+ // -0 -> 0
232
+ .replace(new RegExp("^".concat(MINUS_SIGN, "0$")), '0')
233
+ // - -> ''
234
+ .replace(new RegExp("^".concat(MINUS_SIGN, "$")), '');
235
+ if (newValue !== element.value) {
236
+ element.value = newValue;
237
+ element.dispatchEvent(new Event('input', { bubbles: true }));
238
+ }
239
+ };
240
+ var evListenerOptions = { capture: true };
241
+ element.addEventListener('blur', listener, evListenerOptions);
242
+ return function () { return element.removeEventListener('blur', listener, evListenerOptions); };
243
+ };
244
+ }
28
245
 
29
- export { SEPARATORS, SIGNS, createSeparatorsRegExp, getAllowedValue };
246
+ export { MAX_DIGITS, MAX_SAFE_INTEGER, MINUS_SIGN, MIN_SAFE_INTEGER, SEPARATORS, createMaskOptions, createMinMaxPlugin, createNotEmptyPartsPlugin, parseNumber, stringifyNumberWithoutExp };
package/index.js CHANGED
@@ -6,9 +6,18 @@ var Component_responsive = require('./Component.responsive.js');
6
6
  require('tslib');
7
7
  require('react');
8
8
  require('@alfalab/core-components-input');
9
+ require('@alfalab/core-components-mq');
9
10
  require('./components/number-input/Component.js');
10
11
  require('react-merge-refs');
12
+ require('@maskito/core');
13
+ require('@maskito/react');
14
+ require('classnames');
15
+ require('@alfalab/core-components-shared');
11
16
  require('./utils.js');
17
+ require('./components/steppers/Component.js');
18
+ require('@alfalab/core-components-icon-button');
19
+ require('@alfalab/icons-glyph/MinusMIcon');
20
+ require('@alfalab/icons-glyph/PlusMediumMIcon');
12
21
 
13
22
 
14
23
 
package/mobile/index.js CHANGED
@@ -8,7 +8,15 @@ require('react');
8
8
  require('@alfalab/core-components-input/mobile');
9
9
  require('../components/number-input/Component.js');
10
10
  require('react-merge-refs');
11
+ require('@maskito/core');
12
+ require('@maskito/react');
13
+ require('classnames');
14
+ require('@alfalab/core-components-shared');
11
15
  require('../utils.js');
16
+ require('../components/steppers/Component.js');
17
+ require('@alfalab/core-components-icon-button');
18
+ require('@alfalab/icons-glyph/MinusMIcon');
19
+ require('@alfalab/icons-glyph/PlusMediumMIcon');
12
20
 
13
21
 
14
22
 
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import React from 'react';
3
3
  import { NumberInputProps } from "./components/number-input/index";
4
- type NumberInputDesktopProps = Omit<NumberInputProps, 'Input' | 'breakpoint'>;
4
+ type NumberInputDesktopProps = Omit<NumberInputProps, 'Input' | 'breakpoint' | 'view'>;
5
5
  declare const NumberInputDesktop: React.ForwardRefExoticComponent<NumberInputDesktopProps & React.RefAttributes<HTMLInputElement>>;
6
6
  export { NumberInputDesktopProps, NumberInputDesktop };
@@ -2,8 +2,16 @@ import React, { forwardRef } from 'react';
2
2
  import { InputDesktop } from '@alfalab/core-components-input/modern/desktop';
3
3
  import { NumberInput } from './components/number-input/Component.js';
4
4
  import 'react-merge-refs';
5
+ import '@maskito/core';
6
+ import '@maskito/react';
7
+ import 'classnames';
8
+ import '@alfalab/core-components-shared/modern';
5
9
  import './utils.js';
10
+ import './components/steppers/Component.js';
11
+ import '@alfalab/core-components-icon-button/modern';
12
+ import '@alfalab/icons-glyph/MinusMIcon';
13
+ import '@alfalab/icons-glyph/PlusMediumMIcon';
6
14
 
7
- const NumberInputDesktop = forwardRef((props, ref) => React.createElement(NumberInput, { ...props, Input: InputDesktop, ref: ref }));
15
+ const NumberInputDesktop = forwardRef((props, ref) => React.createElement(NumberInput, { ...props, Input: InputDesktop, ref: ref, view: 'desktop' }));
8
16
 
9
17
  export { NumberInputDesktop };
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import React from 'react';
3
3
  import { NumberInputProps } from "./components/number-input/index";
4
- type NumberInputMobileProps = Omit<NumberInputProps, 'Input' | 'breakpoint'>;
4
+ type NumberInputMobileProps = Omit<NumberInputProps, 'Input' | 'breakpoint' | 'view'>;
5
5
  declare const NumberInputMobile: React.ForwardRefExoticComponent<NumberInputMobileProps & React.RefAttributes<HTMLInputElement>>;
6
6
  export { NumberInputMobileProps, NumberInputMobile };
@@ -2,8 +2,16 @@ import React, { forwardRef } from 'react';
2
2
  import { InputMobile } from '@alfalab/core-components-input/modern/mobile';
3
3
  import { NumberInput } from './components/number-input/Component.js';
4
4
  import 'react-merge-refs';
5
+ import '@maskito/core';
6
+ import '@maskito/react';
7
+ import 'classnames';
8
+ import '@alfalab/core-components-shared/modern';
5
9
  import './utils.js';
10
+ import './components/steppers/Component.js';
11
+ import '@alfalab/core-components-icon-button/modern';
12
+ import '@alfalab/icons-glyph/MinusMIcon';
13
+ import '@alfalab/icons-glyph/PlusMediumMIcon';
6
14
 
7
- const NumberInputMobile = forwardRef((props, ref) => React.createElement(NumberInput, { ...props, Input: InputMobile, ref: ref }));
15
+ const NumberInputMobile = forwardRef((props, ref) => React.createElement(NumberInput, { ...props, Input: InputMobile, ref: ref, view: 'mobile' }));
8
16
 
9
17
  export { NumberInputMobile };
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import React from 'react';
3
3
  import { NumberInputProps } from "./components/number-input/index";
4
- type NumberInputResponsiveProps = Omit<NumberInputProps, 'Input'>;
4
+ type NumberInputResponsiveProps = Omit<NumberInputProps, 'Input' | 'view'>;
5
5
  declare const NumberInputResponsive: React.ForwardRefExoticComponent<NumberInputResponsiveProps & React.RefAttributes<HTMLInputElement>>;
6
6
  export { NumberInputResponsiveProps, NumberInputResponsive };
@@ -1,9 +1,21 @@
1
1
  import React, { forwardRef } from 'react';
2
2
  import { Input } from '@alfalab/core-components-input/modern';
3
+ import { useMatchMedia } from '@alfalab/core-components-mq/modern';
3
4
  import { NumberInput } from './components/number-input/Component.js';
4
5
  import 'react-merge-refs';
6
+ import '@maskito/core';
7
+ import '@maskito/react';
8
+ import 'classnames';
9
+ import '@alfalab/core-components-shared/modern';
5
10
  import './utils.js';
11
+ import './components/steppers/Component.js';
12
+ import '@alfalab/core-components-icon-button/modern';
13
+ import '@alfalab/icons-glyph/MinusMIcon';
14
+ import '@alfalab/icons-glyph/PlusMediumMIcon';
6
15
 
7
- const NumberInputResponsive = forwardRef((props, ref) => React.createElement(NumberInput, { ...props, Input: Input, ref: ref }));
16
+ const NumberInputResponsive = forwardRef(({ breakpoint = 1024, defaultMatchMediaValue, ...restProps }, ref) => {
17
+ const [isDesktop] = useMatchMedia(`(min-width: ${breakpoint}px)`, defaultMatchMediaValue);
18
+ return (React.createElement(NumberInput, { ...restProps, Input: Input, ref: ref, view: isDesktop ? 'desktop' : 'mobile', breakpoint: breakpoint, defaultMatchMediaValue: defaultMatchMediaValue }));
19
+ });
8
20
 
9
21
  export { NumberInputResponsive };
@@ -1,80 +1,55 @@
1
1
  /// <reference types="react" />
2
2
  import React from 'react';
3
+ import { ChangeEvent, FC, Ref } from "react";
3
4
  import { InputProps } from "@alfalab/core-components-input";
4
- type NumberInputProps = Omit<InputProps, 'value' | 'onChange' | 'type'> & {
5
+ interface NumberInputProps extends Omit<InputProps, 'value' | 'onChange' | 'type' | 'defaultValue'> {
5
6
  /**
6
7
  * Значение поля ввода
7
8
  */
8
9
  value?: string | number | null;
9
10
  /**
10
- * Учитывать знаки '+' и '-'
11
+ * Значение по-умолчанию
11
12
  */
12
- allowSigns?: boolean;
13
+ defaultValue?: string | number | null;
13
14
  /**
14
15
  * Разделитель ',' или '.'
15
16
  */
16
17
  separator?: '.' | ',';
17
18
  /**
18
19
  * Количество символов после разделителя
20
+ * Если указан проп step, то всегда 0
19
21
  */
20
22
  fractionLength?: number;
21
23
  /**
22
- * Компонент инпута
24
+ * Шаг инкремента/декремента. Используйте только целочисленные значения
23
25
  */
24
- Input: React.FC<InputProps & {
25
- ref?: React.Ref<HTMLInputElement>;
26
- }>;
26
+ step?: number;
27
27
  /**
28
- * Обработчик события изменения значения
28
+ * Минимальное значение
29
+ * @default Number.MIN_SAFE_INTEGER
29
30
  */
30
- onChange?: (e: React.ChangeEvent<HTMLInputElement>, payload: {
31
- /**
32
- * Числовое значение инпута
33
- */
34
- value: number | null;
35
- /**
36
- * Строковое значение инпута
37
- * Используйте для изменения значения инпута
38
- */
39
- valueString: string;
40
- }) => void;
41
- };
42
- declare const NumberInput: React.ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange" | "type"> & {
31
+ min?: number;
43
32
  /**
44
- * Значение поля ввода
33
+ * Максимальное значение
34
+ * @default Number.MAX_SAFE_INTEGER
45
35
  */
46
- value?: string | number | null | undefined;
36
+ max?: number;
47
37
  /**
48
- * Учитывать знаки '+' и '-'
38
+ * Отображение компонента в мобильном или десктопном виде
49
39
  */
50
- allowSigns?: boolean | undefined;
51
- /**
52
- * Разделитель ',' или '.'
53
- */
54
- separator?: "," | "." | undefined;
55
- /**
56
- * Количество символов после разделителя
57
- */
58
- fractionLength?: number | undefined;
40
+ view?: 'desktop' | 'mobile';
59
41
  /**
60
42
  * Компонент инпута
61
43
  */
62
- Input: React.FC<InputProps & {
63
- ref?: React.Ref<HTMLInputElement>;
44
+ Input: FC<InputProps & {
45
+ ref?: Ref<HTMLInputElement>;
64
46
  }>;
65
47
  /**
66
48
  * Обработчик события изменения значения
67
49
  */
68
- onChange?: ((e: React.ChangeEvent<HTMLInputElement>, payload: {
69
- /**
70
- * Числовое значение инпута
71
- */
50
+ onChange?: (e: ChangeEvent<HTMLInputElement> | null, payload: {
72
51
  value: number | null;
73
- /**
74
- * Строковое значение инпута
75
- * Используйте для изменения значения инпута
76
- */
77
- valueString: string;
78
- }) => void) | undefined;
79
- } & React.RefAttributes<HTMLInputElement>>;
52
+ }) => void;
53
+ }
54
+ declare const NumberInput: React.ForwardRefExoticComponent<NumberInputProps & React.RefAttributes<HTMLInputElement>>;
80
55
  export { NumberInputProps, NumberInput };