intelicoreact 0.0.75 → 0.0.79
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Atomic/FormElements/Dropdown/Dropdown.js +2 -1
- package/dist/Atomic/FormElements/Input/Input.js +85 -46
- package/dist/Atomic/FormElements/Input/Input.stories.js +16 -22
- package/dist/Atomic/FormElements/InputDateRange/InputDateRange.scss +38 -6
- package/dist/Atomic/FormElements/NumericInput/NumericInput.js +254 -0
- package/dist/Atomic/FormElements/NumericInput/NumericInput.scss +135 -0
- package/dist/Atomic/FormElements/NumericInput/NumericInput.stories.js +121 -0
- package/dist/Atomic/UI/Arrow/Arrow.js +2 -1
- package/dist/Constants/index.constants.js +8 -0
- package/dist/Functions/inputExecutor.js +58 -0
- package/package.json +2 -2
- package/src/Atomic/FormElements/Dropdown/Dropdown.js +1 -1
- package/src/Atomic/FormElements/Input/Input.js +86 -36
- package/src/Atomic/FormElements/Input/Input.stories.js +40 -29
- package/src/Atomic/FormElements/InputDateRange/InputDateRange.scss +38 -6
- package/src/Atomic/FormElements/NumericInput/NumericInput.js +220 -0
- package/src/Atomic/FormElements/NumericInput/NumericInput.scss +135 -0
- package/src/Atomic/FormElements/NumericInput/NumericInput.stories.js +94 -0
- package/src/Atomic/UI/Arrow/Arrow.js +1 -1
- package/src/Constants/index.constants.js +41 -0
- package/src/Functions/inputExecutor.js +62 -0
- package/src/Functions/utils.js +4 -1
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import "~anme/scss/anme-mixins-media";
|
|
2
|
+
|
|
1
3
|
:root {
|
|
2
4
|
--input-height: 28px;
|
|
3
5
|
--label-line-height: 16px;
|
|
@@ -205,7 +207,7 @@
|
|
|
205
207
|
border: 1px solid var(--border-color);
|
|
206
208
|
border-radius: var(--border-radius);
|
|
207
209
|
background: #FFFFFF;
|
|
208
|
-
|
|
210
|
+
box-shadow: 0 4px 25px rgba(0, 0, 0, 0.25);
|
|
209
211
|
&_right-position-once-element {
|
|
210
212
|
justify-content: flex-end;
|
|
211
213
|
}
|
|
@@ -222,15 +224,15 @@
|
|
|
222
224
|
position: relative;
|
|
223
225
|
|
|
224
226
|
width: 100%;
|
|
225
|
-
padding:
|
|
227
|
+
padding: 0 20px 0 30px;
|
|
226
228
|
|
|
227
229
|
text-transform: capitalize;
|
|
228
230
|
white-space: nowrap;
|
|
229
231
|
font-style: normal;
|
|
230
232
|
font-weight: 300;
|
|
231
233
|
font-family: var(--font-family);
|
|
232
|
-
font-size:
|
|
233
|
-
line-height:
|
|
234
|
+
font-size: 12px;
|
|
235
|
+
line-height: 24px;
|
|
234
236
|
cursor: pointer;
|
|
235
237
|
|
|
236
238
|
display: flex;
|
|
@@ -242,6 +244,9 @@
|
|
|
242
244
|
// background-color: rgba(128, 128, 128, 0.1);
|
|
243
245
|
background-color: #F2F2F8;
|
|
244
246
|
}
|
|
247
|
+
&_active {
|
|
248
|
+
background: #f2f2f8;
|
|
249
|
+
}
|
|
245
250
|
|
|
246
251
|
&-icon-active {
|
|
247
252
|
position: absolute;
|
|
@@ -293,7 +298,7 @@
|
|
|
293
298
|
|
|
294
299
|
&>div:not(.date-picker__inputs-separator) {
|
|
295
300
|
width: 110px;
|
|
296
|
-
height: 100%;
|
|
301
|
+
min-height: 100%;
|
|
297
302
|
margin-right: 9px;
|
|
298
303
|
|
|
299
304
|
border: 1px solid var(--border-color);
|
|
@@ -323,6 +328,9 @@
|
|
|
323
328
|
.date-picker__inputs-separator {
|
|
324
329
|
margin-right: 9px;
|
|
325
330
|
}
|
|
331
|
+
input {
|
|
332
|
+
font-weight: 300;
|
|
333
|
+
}
|
|
326
334
|
}
|
|
327
335
|
|
|
328
336
|
&__date-input {
|
|
@@ -348,7 +356,7 @@
|
|
|
348
356
|
|
|
349
357
|
&>.dropdown__trigger {
|
|
350
358
|
width: 100%;
|
|
351
|
-
height:
|
|
359
|
+
height: 28px;
|
|
352
360
|
padding-left: 10px;
|
|
353
361
|
padding-right: 15px;
|
|
354
362
|
|
|
@@ -592,3 +600,27 @@
|
|
|
592
600
|
height: 100%;
|
|
593
601
|
}
|
|
594
602
|
}
|
|
603
|
+
|
|
604
|
+
@include lgDown {
|
|
605
|
+
.opened-part__intervals-list {
|
|
606
|
+
display: none;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
@include mdDown {
|
|
611
|
+
.date-picker__inputs-block {
|
|
612
|
+
flex-flow: wrap;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
.date-picker__header {
|
|
616
|
+
flex-flow: row wrap
|
|
617
|
+
}
|
|
618
|
+
.date-picker__calendars-wrapper {
|
|
619
|
+
display: block;
|
|
620
|
+
margin: auto;
|
|
621
|
+
}
|
|
622
|
+
.date-picker__calendars .range-calendar {
|
|
623
|
+
margin: 0!important;
|
|
624
|
+
width: 100%;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { Minus, Plus } from 'react-feather';
|
|
4
|
+
import InputMask from 'react-input-mask';
|
|
5
|
+
import { KEYBOARD_SERVICE_KEYS } from '../../../Constants/index.constants';
|
|
6
|
+
import { formatInput } from '../../../Functions/inputExecutor';
|
|
7
|
+
|
|
8
|
+
import './NumericInput.scss';
|
|
9
|
+
|
|
10
|
+
const NumericInput = ({
|
|
11
|
+
onChange,
|
|
12
|
+
disabled,
|
|
13
|
+
withDelete,
|
|
14
|
+
numStep = 1,
|
|
15
|
+
min = 0,
|
|
16
|
+
max,
|
|
17
|
+
value,
|
|
18
|
+
placeholder,
|
|
19
|
+
className,
|
|
20
|
+
type = 'number',
|
|
21
|
+
onBlur,
|
|
22
|
+
onFocus,
|
|
23
|
+
onKeyUp,
|
|
24
|
+
mask,
|
|
25
|
+
maskChar,
|
|
26
|
+
formatChars,
|
|
27
|
+
error,
|
|
28
|
+
icon,
|
|
29
|
+
symbolsLimit,
|
|
30
|
+
isNotBlinkErrors,
|
|
31
|
+
blinkTime,
|
|
32
|
+
isPriceInput
|
|
33
|
+
}) => {
|
|
34
|
+
const DEFAULT_BLINK_TIME = 200;
|
|
35
|
+
// STATES
|
|
36
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
37
|
+
const [isEditing, setEditing] = useState(false);
|
|
38
|
+
const inputRef = useRef(null);
|
|
39
|
+
const decRef = useRef(null);
|
|
40
|
+
const incRef = useRef(null);
|
|
41
|
+
const previousValueRef = useRef(value);
|
|
42
|
+
const [isAttemptToChange, setIsAttemptToChange] = useState(false);
|
|
43
|
+
const [isToHighlightError, setIsToHighlightError] = useState(false);
|
|
44
|
+
|
|
45
|
+
const [intMemoVal, setIntMemoVal] = useState(0);
|
|
46
|
+
|
|
47
|
+
const { onlyNumbers } = formatInput;
|
|
48
|
+
const { addCommas, removeComma } = formatInput.priceInput;
|
|
49
|
+
|
|
50
|
+
// HANDLES
|
|
51
|
+
const handle = {
|
|
52
|
+
change: (e) => {
|
|
53
|
+
let inputValue = e.target ? onlyNumbers(e.target.value) : e;
|
|
54
|
+
if (inputValue !== '') {
|
|
55
|
+
inputValue = parseFloat(inputValue) || '';
|
|
56
|
+
if (min && +min > inputValue) {
|
|
57
|
+
inputValue = min;
|
|
58
|
+
} else if (max && +max < inputValue) inputValue = max;
|
|
59
|
+
}
|
|
60
|
+
if (symbolsLimit) {
|
|
61
|
+
inputValue = inputValue.toString().substring(0, +symbolsLimit);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
setIntMemoVal(parseFloat(inputValue));
|
|
65
|
+
onChange(inputValue.toString());
|
|
66
|
+
},
|
|
67
|
+
toggleEdit: () => {
|
|
68
|
+
setEditing(!isEditing);
|
|
69
|
+
onChange('');
|
|
70
|
+
},
|
|
71
|
+
focus: (e) => {
|
|
72
|
+
setIsFocused(true);
|
|
73
|
+
if (isPriceInput) onChange(removeComma(value));
|
|
74
|
+
if (onFocus) onFocus(e);
|
|
75
|
+
},
|
|
76
|
+
blur: (e) => {
|
|
77
|
+
setIsFocused(false);
|
|
78
|
+
setEditing(false);
|
|
79
|
+
if (isPriceInput) {
|
|
80
|
+
if (!isFinite(value)) {
|
|
81
|
+
value = intMemoVal;
|
|
82
|
+
}
|
|
83
|
+
onChange(addCommas(value));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (onBlur) onBlur(e);
|
|
87
|
+
},
|
|
88
|
+
keyUp: (e) => {
|
|
89
|
+
if (!isNotBlinkErrors) {
|
|
90
|
+
const changedValue = '' + (value ?? '');
|
|
91
|
+
const previousValue = '' + (previousValueRef.current ?? '');
|
|
92
|
+
const currentSet = (() => {
|
|
93
|
+
if (previousValue.length < changedValue.length)
|
|
94
|
+
return value
|
|
95
|
+
.toString()
|
|
96
|
+
.slice(previousValue.length - changedValue.length);
|
|
97
|
+
else return changedValue.toString().includes(e.key) ? e.key : '';
|
|
98
|
+
})();
|
|
99
|
+
|
|
100
|
+
if (
|
|
101
|
+
!KEYBOARD_SERVICE_KEYS.includes(e.key) &&
|
|
102
|
+
changedValue === previousValue
|
|
103
|
+
)
|
|
104
|
+
setIsAttemptToChange(true);
|
|
105
|
+
|
|
106
|
+
if (KEYBOARD_SERVICE_KEYS.includes(e.key) || !currentSet)
|
|
107
|
+
previousValueRef.current = value;
|
|
108
|
+
else previousValueRef.current = previousValue + currentSet[0];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (onKeyUp) onKeyUp(e.keyCode, e.target.value);
|
|
112
|
+
},
|
|
113
|
+
decrement: () => {
|
|
114
|
+
handle.change(intMemoVal - +numStep);
|
|
115
|
+
},
|
|
116
|
+
increment: () => {
|
|
117
|
+
handle.change(intMemoVal + +numStep);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const handleClickOutside = (event) => {
|
|
122
|
+
if (
|
|
123
|
+
inputRef.current &&
|
|
124
|
+
!inputRef.current.contains(event.target) &&
|
|
125
|
+
!decRef.current.contains(event.target) &&
|
|
126
|
+
!incRef.current.contains(event.target)
|
|
127
|
+
) {
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
inputRef.current.focus();
|
|
130
|
+
inputRef.current.blur();
|
|
131
|
+
}, 0);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
if (!isNotBlinkErrors && isAttemptToChange) {
|
|
137
|
+
setIsAttemptToChange(false);
|
|
138
|
+
setIsToHighlightError(true);
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
setIsToHighlightError(false);
|
|
141
|
+
}, blinkTime || DEFAULT_BLINK_TIME);
|
|
142
|
+
}
|
|
143
|
+
}, [isAttemptToChange]);
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
document.addEventListener('click', handleClickOutside, true);
|
|
147
|
+
return () =>
|
|
148
|
+
document.removeEventListener('click', handleClickOutside, true);
|
|
149
|
+
}, []);
|
|
150
|
+
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
if (isNaN(intMemoVal)) setIntMemoVal(min || '');
|
|
153
|
+
}, [intMemoVal]);
|
|
154
|
+
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (isEditing || isFocused) inputRef.current.focus();
|
|
157
|
+
}, [isEditing, isFocused]);
|
|
158
|
+
|
|
159
|
+
const uniProps = {
|
|
160
|
+
className: `input ${className}`,
|
|
161
|
+
placeholder,
|
|
162
|
+
value: value || '',
|
|
163
|
+
disabled,
|
|
164
|
+
onChange: handle.change,
|
|
165
|
+
onFocus: handle.focus,
|
|
166
|
+
onBlur: handle.blur,
|
|
167
|
+
onKeyUp: handle.keyUp,
|
|
168
|
+
min,
|
|
169
|
+
max,
|
|
170
|
+
...(maskChar ? { maskChar } : {}),
|
|
171
|
+
...(formatChars ? { formatChars } : {})
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
function renderInput() {
|
|
175
|
+
return (
|
|
176
|
+
<>
|
|
177
|
+
<input {...uniProps} ref={inputRef} type={type} />
|
|
178
|
+
|
|
179
|
+
<div className='input__nums'>
|
|
180
|
+
<button
|
|
181
|
+
ref={decRef}
|
|
182
|
+
onClick={() => handle.decrement()}
|
|
183
|
+
className={cn(`input__num-btn`, { disabled: +value <= min })}
|
|
184
|
+
>
|
|
185
|
+
<Minus />
|
|
186
|
+
</button>
|
|
187
|
+
<button
|
|
188
|
+
ref={incRef}
|
|
189
|
+
onClick={() => handle.increment()}
|
|
190
|
+
className={cn(`input__num-btn`, { disabled: +value >= max })}
|
|
191
|
+
>
|
|
192
|
+
<Plus />
|
|
193
|
+
</button>
|
|
194
|
+
</div>
|
|
195
|
+
</>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return (
|
|
200
|
+
<div
|
|
201
|
+
className={cn(
|
|
202
|
+
`input__wrap`,
|
|
203
|
+
{ [`input__wrap_focus`]: isFocused },
|
|
204
|
+
{ [`input__wrap_error`]: error || isToHighlightError },
|
|
205
|
+
{ [`input__wrap_disabled`]: disabled }
|
|
206
|
+
)}
|
|
207
|
+
>
|
|
208
|
+
{renderInput()}
|
|
209
|
+
{icon}
|
|
210
|
+
{withDelete && (
|
|
211
|
+
<span
|
|
212
|
+
className={cn(`input__close`, { hidden: !value })}
|
|
213
|
+
onClick={handle.toggleEdit}
|
|
214
|
+
/>
|
|
215
|
+
)}
|
|
216
|
+
</div>
|
|
217
|
+
);
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
export default NumericInput;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
.input {
|
|
2
|
+
position: relative;
|
|
3
|
+
word-break: break-all;
|
|
4
|
+
border: none;
|
|
5
|
+
background: none;
|
|
6
|
+
padding: 0 10px;
|
|
7
|
+
width: 100%;
|
|
8
|
+
&::-webkit-outer-spin-button,
|
|
9
|
+
&::-webkit-inner-spin-button {
|
|
10
|
+
-webkit-appearance: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
&__wrap {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
border: 1px solid #e2e5ec;
|
|
17
|
+
box-sizing: border-box;
|
|
18
|
+
background-color: #fff;
|
|
19
|
+
height: 28px;
|
|
20
|
+
border-radius: 4px;
|
|
21
|
+
|
|
22
|
+
&_focus {
|
|
23
|
+
border-color: #6b81dd;
|
|
24
|
+
filter: drop-shadow(0px 0px 4px rgba(93, 120, 255, 0.5));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&_disabled {
|
|
28
|
+
background: #f7f8fa;
|
|
29
|
+
opacity: 0.5;
|
|
30
|
+
border-color: #a6acb1;
|
|
31
|
+
pointer-events: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&_error {
|
|
35
|
+
border-color: #f06d8d;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&_disabled {
|
|
40
|
+
background: #f7f8fa;
|
|
41
|
+
opacity: 0.5;
|
|
42
|
+
border-color: #a6acb1;
|
|
43
|
+
pointer-events: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
&_error {
|
|
47
|
+
border-color: #f06d8d;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
svg {
|
|
51
|
+
margin-right: 4px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&__input {
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
font-size: 13px;
|
|
59
|
+
font-weight: 400;
|
|
60
|
+
color: #1e1e2d;
|
|
61
|
+
border: none;
|
|
62
|
+
padding: 0 5px;
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&__close {
|
|
67
|
+
position: relative;
|
|
68
|
+
opacity: 0.6;
|
|
69
|
+
width: 14px;
|
|
70
|
+
height: 14px;
|
|
71
|
+
background: none;
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
margin-right: 4px;
|
|
74
|
+
visibility: hidden;
|
|
75
|
+
pointer-events: none;
|
|
76
|
+
&:hover {
|
|
77
|
+
opacity: 1;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&:before,
|
|
81
|
+
&:after {
|
|
82
|
+
content: '';
|
|
83
|
+
position: absolute;
|
|
84
|
+
top: 0;
|
|
85
|
+
left: 0;
|
|
86
|
+
right: 0;
|
|
87
|
+
margin: auto;
|
|
88
|
+
height: 14px;
|
|
89
|
+
width: 2px;
|
|
90
|
+
background-color: #9aa0b9;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&:before {
|
|
94
|
+
transform: rotate(45deg);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
&:after {
|
|
98
|
+
transform: rotate(-45deg);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&__nums {
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
height: 100%;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
&__num-btn {
|
|
109
|
+
cursor: pointer;
|
|
110
|
+
display: flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
justify-content: center;
|
|
113
|
+
height: 100%;
|
|
114
|
+
width: 24px;
|
|
115
|
+
border-left: 1px solid #e2e5ec;
|
|
116
|
+
background: none;
|
|
117
|
+
font-size: 20px;
|
|
118
|
+
user-select: none;
|
|
119
|
+
&.disabled {
|
|
120
|
+
opacity: 0.3;
|
|
121
|
+
}
|
|
122
|
+
svg {
|
|
123
|
+
margin-right: 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
&-label {
|
|
128
|
+
margin-bottom: 5px;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.input__wrap:hover .input__close {
|
|
133
|
+
visibility: visible;
|
|
134
|
+
pointer-events: all;
|
|
135
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { User } from 'react-feather';
|
|
3
|
+
import NumericInput from './NumericInput';
|
|
4
|
+
|
|
5
|
+
global.lng = 'en';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form Elements/NumericInput',
|
|
9
|
+
component: NumericInput,
|
|
10
|
+
argTypes: {
|
|
11
|
+
disabled: {
|
|
12
|
+
description: 'boolean'
|
|
13
|
+
},
|
|
14
|
+
isInitialFocus: {
|
|
15
|
+
description: 'boolean - if true, the input will be focused on mount'
|
|
16
|
+
},
|
|
17
|
+
error: {
|
|
18
|
+
description: 'text - coloring input if is errored'
|
|
19
|
+
},
|
|
20
|
+
isPriceInput: {
|
|
21
|
+
description: 'boolean - if true, the input will be styled as PriceInput'
|
|
22
|
+
},
|
|
23
|
+
withDelete: {
|
|
24
|
+
description: 'boolean - add clear-cross by hover'
|
|
25
|
+
},
|
|
26
|
+
numStep: {
|
|
27
|
+
description: 'number/text - plus/minus buttons factor (default: 1)'
|
|
28
|
+
},
|
|
29
|
+
min: {
|
|
30
|
+
description: 'number/text - minimal number for numeric input'
|
|
31
|
+
},
|
|
32
|
+
max: {
|
|
33
|
+
description: 'number/text - maximal number for numeric input'
|
|
34
|
+
},
|
|
35
|
+
placeholder: {
|
|
36
|
+
description: 'text'
|
|
37
|
+
},
|
|
38
|
+
type: {
|
|
39
|
+
description:
|
|
40
|
+
"'text', 'number', 'password', 'color', 'date', 'datetime-local', 'month', 'time', 'email', 'range'",
|
|
41
|
+
control: {
|
|
42
|
+
type: 'select',
|
|
43
|
+
options: [
|
|
44
|
+
'text',
|
|
45
|
+
'number',
|
|
46
|
+
'password',
|
|
47
|
+
'color',
|
|
48
|
+
'date',
|
|
49
|
+
'datetime-local',
|
|
50
|
+
'month',
|
|
51
|
+
'time',
|
|
52
|
+
'email',
|
|
53
|
+
'range'
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
icon: { description: 'JSX' },
|
|
58
|
+
value: { description: '(* - required prop)' },
|
|
59
|
+
className: { description: 'string' },
|
|
60
|
+
mask: {
|
|
61
|
+
description:
|
|
62
|
+
'string: force input to masked https://www.npmjs.com/package/react-input-mask'
|
|
63
|
+
},
|
|
64
|
+
symbolsLimit: {
|
|
65
|
+
description: 'Set limit of symbols in input, overhead will be ignored'
|
|
66
|
+
},
|
|
67
|
+
onBlur: { description: 'custom callback on blur' },
|
|
68
|
+
onFocus: { description: 'custom callback on focus' },
|
|
69
|
+
onKeyUp: { description: 'custom callback on keyup, returns event keyCode' }
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const Template = (args) => {
|
|
74
|
+
const [value, setValue] = useState('');
|
|
75
|
+
return <NumericInput {...args} value={value} onChange={setValue} />;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const NumericInputTemplate = Template.bind({});
|
|
79
|
+
|
|
80
|
+
NumericInputTemplate.args = {
|
|
81
|
+
type: 'text',
|
|
82
|
+
disabled: false,
|
|
83
|
+
error: '',
|
|
84
|
+
isPriceInput: false,
|
|
85
|
+
mask: '',
|
|
86
|
+
withDelete: true,
|
|
87
|
+
isNumeric: false,
|
|
88
|
+
numStep: 100,
|
|
89
|
+
min: '0',
|
|
90
|
+
max: '15000',
|
|
91
|
+
symbolsLimit: 2,
|
|
92
|
+
placeholder: 'Placeholder',
|
|
93
|
+
icon: <User />
|
|
94
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
export const KEYBOARD_SERVICE_KEYS = [
|
|
3
|
+
'Escape',
|
|
4
|
+
'F1',
|
|
5
|
+
'F2',
|
|
6
|
+
'F3',
|
|
7
|
+
'F4',
|
|
8
|
+
'F5',
|
|
9
|
+
'F6',
|
|
10
|
+
'F7',
|
|
11
|
+
'F8',
|
|
12
|
+
'F9',
|
|
13
|
+
'F10',
|
|
14
|
+
'F11',
|
|
15
|
+
'F12',
|
|
16
|
+
'Tab',
|
|
17
|
+
'CapsLock',
|
|
18
|
+
'Shift',
|
|
19
|
+
'Control',
|
|
20
|
+
'Meta',
|
|
21
|
+
'Option',
|
|
22
|
+
'Alt',
|
|
23
|
+
'ContextMenu',
|
|
24
|
+
'ArrowLeft',
|
|
25
|
+
'ArrowRight',
|
|
26
|
+
'ArrowUp',
|
|
27
|
+
'ArrowDown',
|
|
28
|
+
'NumLock',
|
|
29
|
+
'Backspace',
|
|
30
|
+
'Delete',
|
|
31
|
+
'Enter',
|
|
32
|
+
'Return',
|
|
33
|
+
'Insert',
|
|
34
|
+
'Home',
|
|
35
|
+
'End',
|
|
36
|
+
'PageUp',
|
|
37
|
+
'PageDown',
|
|
38
|
+
'PrintScreen',
|
|
39
|
+
'ScrollLock',
|
|
40
|
+
'Pause'
|
|
41
|
+
];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const formatInput = {
|
|
2
|
+
priceInput: {
|
|
3
|
+
addCommas: (value) => {
|
|
4
|
+
value = value.toString();
|
|
5
|
+
const isFraction = value.includes('.');
|
|
6
|
+
|
|
7
|
+
const valueBeforeDot = isFraction
|
|
8
|
+
? value.slice(0, value.indexOf('.'))
|
|
9
|
+
: value;
|
|
10
|
+
|
|
11
|
+
const intPart = valueBeforeDot
|
|
12
|
+
.split('')
|
|
13
|
+
.reverse()
|
|
14
|
+
.reduce(
|
|
15
|
+
(acc, item, idx) =>
|
|
16
|
+
idx % 3 === 0 && idx !== 0 ? [...acc, ',', item] : [...acc, item],
|
|
17
|
+
[]
|
|
18
|
+
)
|
|
19
|
+
.reverse()
|
|
20
|
+
.join('');
|
|
21
|
+
|
|
22
|
+
return isFraction ? intPart + value.slice(value.indexOf('.')) : intPart;
|
|
23
|
+
},
|
|
24
|
+
removeComma: (value) => {
|
|
25
|
+
return parseFloat(value.toString().replace(/\,/g, ''));
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
onlyNumbers: (value, isDot = false) => {
|
|
29
|
+
const val =
|
|
30
|
+
value.slice(0, 1) !== '0' && value.slice(0, 1) !== '.'
|
|
31
|
+
? value
|
|
32
|
+
: value.slice(1);
|
|
33
|
+
if (isDot) return twoDigitAfterDot(val.replace(/[^0-9.]/g, ''));
|
|
34
|
+
else return +val.toString().replace(/\D/g, '');
|
|
35
|
+
},
|
|
36
|
+
onlyString: (value) => {
|
|
37
|
+
return value.toString().replace(/[^a-z]/gi, '');
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
//обрезает числа после точки до 2х
|
|
42
|
+
// 342.23423432 -> 342.23
|
|
43
|
+
const twoDigitAfterDot = (value) => {
|
|
44
|
+
if (value.includes('.')) {
|
|
45
|
+
const valueAfterDot = value.slice(0, value.indexOf('.') + 3);
|
|
46
|
+
let rest = value.slice(value.indexOf('.') + 1, value.indexOf('.') + 3);
|
|
47
|
+
|
|
48
|
+
return allButTheFirstDotCutter(valueAfterDot);
|
|
49
|
+
} else {
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//обрезает все точки кроме первой.
|
|
55
|
+
//для фомата "2 цифры после точки"
|
|
56
|
+
// нельзя = 123...
|
|
57
|
+
// можно 123.99
|
|
58
|
+
function allButTheFirstDotCutter(str) {
|
|
59
|
+
return str.replace(/^([^.]*\.)(.*)$/, function (a, b, c) {
|
|
60
|
+
return b + c.replace(/\./g, '');
|
|
61
|
+
});
|
|
62
|
+
}
|
package/src/Functions/utils.js
CHANGED
|
@@ -5,7 +5,10 @@ export const handleObjectChange =
|
|
|
5
5
|
(data, prop = '', isNumber) => {
|
|
6
6
|
let value;
|
|
7
7
|
if (data?.target) {
|
|
8
|
-
value =
|
|
8
|
+
value =
|
|
9
|
+
data.target.type === 'checkbox'
|
|
10
|
+
? data.target.checked
|
|
11
|
+
: data.target.value;
|
|
9
12
|
} else value = data;
|
|
10
13
|
|
|
11
14
|
value = isNumber ? +value : value;
|