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.
@@ -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: 4px 8px 4px 32px;
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: var(--font-size);
233
- line-height: var(--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: 100%;
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
+ };
@@ -12,7 +12,7 @@ const Arrow = ({type, className, onClick, disabled}) => {
12
12
 
13
13
  useEffect(() => {
14
14
  if (ref.current) {
15
- //setColor(getStyles(ref.current, 'color'));
15
+ setColor(getStyles(ref.current, 'color'));
16
16
  };
17
17
  }, [ref.current]);
18
18
 
@@ -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;