intelicoreact 0.0.76 → 0.0.81

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.
@@ -205,7 +205,7 @@
205
205
  border: 1px solid var(--border-color);
206
206
  border-radius: var(--border-radius);
207
207
  background: #FFFFFF;
208
-
208
+ box-shadow: 0 4px 25px rgba(0, 0, 0, 0.25);
209
209
  &_right-position-once-element {
210
210
  justify-content: flex-end;
211
211
  }
@@ -222,15 +222,15 @@
222
222
  position: relative;
223
223
 
224
224
  width: 100%;
225
- padding: 4px 8px 4px 32px;
225
+ padding: 0 20px 0 30px;
226
226
 
227
227
  text-transform: capitalize;
228
228
  white-space: nowrap;
229
229
  font-style: normal;
230
230
  font-weight: 300;
231
231
  font-family: var(--font-family);
232
- font-size: var(--font-size);
233
- line-height: var(--line-height);
232
+ font-size: 12px;
233
+ line-height: 24px;
234
234
  cursor: pointer;
235
235
 
236
236
  display: flex;
@@ -242,6 +242,9 @@
242
242
  // background-color: rgba(128, 128, 128, 0.1);
243
243
  background-color: #F2F2F8;
244
244
  }
245
+ &_active {
246
+ background: #f2f2f8;
247
+ }
245
248
 
246
249
  &-icon-active {
247
250
  position: absolute;
@@ -293,7 +296,7 @@
293
296
 
294
297
  &>div:not(.date-picker__inputs-separator) {
295
298
  width: 110px;
296
- height: 100%;
299
+ min-height: 100%;
297
300
  margin-right: 9px;
298
301
 
299
302
  border: 1px solid var(--border-color);
@@ -323,6 +326,9 @@
323
326
  .date-picker__inputs-separator {
324
327
  margin-right: 9px;
325
328
  }
329
+ input {
330
+ font-weight: 300;
331
+ }
326
332
  }
327
333
 
328
334
  &__date-input {
@@ -348,7 +354,7 @@
348
354
 
349
355
  &>.dropdown__trigger {
350
356
  width: 100%;
351
- height: 100%;
357
+ height: 28px;
352
358
  padding-left: 10px;
353
359
  padding-right: 15px;
354
360
 
@@ -592,3 +598,27 @@
592
598
  height: 100%;
593
599
  }
594
600
  }
601
+
602
+ @media screen and (max-width: 992px) {
603
+ .opened-part__intervals-list {
604
+ display: none;
605
+ }
606
+ }
607
+
608
+ @media screen and (max-width: 745px) {
609
+ .date-picker__inputs-block {
610
+ flex-flow: wrap;
611
+ }
612
+
613
+ .date-picker__header {
614
+ flex-flow: row wrap
615
+ }
616
+ .date-picker__calendars-wrapper {
617
+ display: block;
618
+ margin: auto;
619
+ }
620
+ .date-picker__calendars .range-calendar {
621
+ margin: 0!important;
622
+ width: 100%;
623
+ }
624
+ }
@@ -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
+ }
@@ -5,7 +5,10 @@ export const handleObjectChange =
5
5
  (data, prop = '', isNumber) => {
6
6
  let value;
7
7
  if (data?.target) {
8
- value = data.target.type === 'checkbox' ? data.target.checked : data.target.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;