@true-engineering/true-react-common-ui-kit 3.45.1 → 4.0.0-alpha0
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/README.md +0 -40
- package/dist/components/CloseButton/CloseButton.d.ts +1 -1
- package/dist/components/ControlGroup/ControlGroup.d.ts +10 -0
- package/dist/components/ControlGroup/ControlGroup.stories.d.ts +7 -0
- package/dist/components/ControlGroup/ControlGroup.styles.d.ts +3 -0
- package/dist/components/ControlGroup/index.d.ts +2 -0
- package/dist/components/ControlWrapper/ControlWrapper.d.ts +27 -0
- package/dist/components/ControlWrapper/ControlWrapper.stories.d.ts +6 -0
- package/dist/components/ControlWrapper/ControlWrapper.styles.d.ts +6 -0
- package/dist/components/ControlWrapper/index.d.ts +2 -0
- package/dist/components/DateInput/DateInput.d.ts +3 -3
- package/dist/components/DatePicker/components/DatePickerHeader/DatePickerHeader.styles.d.ts +1 -1
- package/dist/components/DatePicker/types.d.ts +1 -1
- package/dist/components/FiltersPane/FiltersPane.stories.d.ts +1 -2
- package/dist/components/FiltersPane/components/FilterWithDates/FilterWithDates.d.ts +1 -1
- package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.d.ts +1 -2
- package/dist/components/Input/Input.d.ts +5 -52
- package/dist/components/Input/Input.stories.d.ts +4 -13
- package/dist/components/Input/Input.styles.d.ts +5 -4
- package/dist/components/Input/InputBase.d.ts +24 -0
- package/dist/components/Input/index.d.ts +1 -0
- package/dist/components/Input/types.d.ts +3 -4
- package/dist/components/NumberInput/NumberInput.d.ts +3 -3
- package/dist/components/PhoneInput/PhoneInput.d.ts +3 -3
- package/dist/components/PhoneInput/PhoneInput.stories.d.ts +2 -2
- package/dist/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.d.ts +3 -2
- package/dist/components/PhoneInput/types.d.ts +2 -0
- package/dist/components/SearchInput/SearchInput.d.ts +1 -3
- package/dist/components/SearchInput/SearchInput.stories.d.ts +11 -1
- package/dist/components/SearchInput/SearchInput.styles.d.ts +1 -1
- package/dist/components/Select/Select.d.ts +5 -5
- package/dist/components/Select/Select.styles.d.ts +17 -16
- package/dist/components/Select/types.d.ts +3 -0
- package/dist/components/SmartInput/SmartInput.d.ts +3 -3
- package/dist/components/TextArea/TextArea.d.ts +5 -14
- package/dist/components/TextArea/TextArea.styles.d.ts +8 -2
- package/dist/components/WithPopup/WithPopup.d.ts +3 -10
- package/dist/components/WithPopup/WithPopup.styles.d.ts +1 -1
- package/dist/components/WithPopup/types.d.ts +0 -3
- package/dist/components/WithTooltip/WithTooltip.styles.d.ts +0 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/theme/common.d.ts +13 -5
- package/dist/theme/types.d.ts +4 -2
- package/dist/true-react-common-ui-kit.js +1184 -1029
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +1164 -1009
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/dist/types.d.ts +2 -1
- package/package.json +1 -1
- package/src/components/Button/Button.stories.tsx +4 -8
- package/src/components/CloseButton/CloseButton.tsx +4 -4
- package/src/components/ControlGroup/ControlGroup.stories.tsx +40 -0
- package/src/components/ControlGroup/ControlGroup.styles.ts +46 -0
- package/src/components/ControlGroup/ControlGroup.tsx +55 -0
- package/src/components/ControlGroup/index.ts +2 -0
- package/src/components/ControlWrapper/ControlWrapper.stories.tsx +45 -0
- package/src/components/ControlWrapper/ControlWrapper.styles.ts +185 -0
- package/src/components/ControlWrapper/ControlWrapper.tsx +151 -0
- package/src/components/ControlWrapper/index.ts +2 -0
- package/src/components/DateInput/DateInput.styles.ts +2 -7
- package/src/components/DateInput/DateInput.tsx +4 -4
- package/src/components/DatePicker/DatePicker.tsx +3 -3
- package/src/components/DatePicker/components/DatePickerHeader/DatePickerHeader.styles.ts +7 -41
- package/src/components/DatePicker/components/DatePickerHeader/DatePickerHeader.tsx +18 -26
- package/src/components/DatePicker/types.ts +1 -1
- package/src/components/FileItem/FileItem.stories.tsx +4 -8
- package/src/components/FiltersPane/FiltersPane.stories.tsx +0 -4
- package/src/components/FiltersPane/components/FilterInterval/FilterInterval.styles.ts +9 -7
- package/src/components/FiltersPane/components/FilterInterval/FilterInterval.tsx +1 -8
- package/src/components/FiltersPane/components/FilterSelect/FilterSelect.styles.ts +7 -5
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +7 -9
- package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.ts +12 -17
- package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.tsx +2 -5
- package/src/components/IconButton/IconButton.stories.tsx +5 -5
- package/src/components/IncrementInput/IncrementInput.stories.tsx +0 -2
- package/src/components/IncrementInput/IncrementInput.styles.ts +9 -9
- package/src/components/Input/Input.stories.tsx +17 -25
- package/src/components/Input/Input.styles.ts +50 -260
- package/src/components/Input/Input.tsx +22 -285
- package/src/components/Input/InputBase.tsx +250 -0
- package/src/components/Input/index.ts +1 -0
- package/src/components/Input/types.ts +3 -32
- package/src/components/MultiSelectList/MultiSelectList.styles.ts +7 -5
- package/src/components/Notification/Notification.stories.tsx +2 -6
- package/src/components/NumberInput/NumberInput.stories.tsx +0 -2
- package/src/components/NumberInput/NumberInput.tsx +4 -7
- package/src/components/PhoneInput/PhoneInput.stories.tsx +6 -10
- package/src/components/PhoneInput/PhoneInput.styles.ts +13 -10
- package/src/components/PhoneInput/PhoneInput.tsx +9 -12
- package/src/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.styles.ts +6 -4
- package/src/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.tsx +6 -6
- package/src/components/PhoneInput/types.ts +4 -0
- package/src/components/SearchInput/SearchInput.stories.tsx +1 -0
- package/src/components/SearchInput/SearchInput.styles.ts +17 -27
- package/src/components/SearchInput/SearchInput.tsx +13 -34
- package/src/components/Select/CustomSelect.stories.tsx +6 -9
- package/src/components/Select/MultiSelect.stories.tsx +4 -12
- package/src/components/Select/Select.stories.tsx +3 -11
- package/src/components/Select/Select.styles.ts +28 -42
- package/src/components/Select/Select.tsx +73 -81
- package/src/components/Select/types.ts +5 -0
- package/src/components/SmartInput/SmartInput.stories.tsx +0 -1
- package/src/components/SmartInput/SmartInput.tsx +4 -4
- package/src/components/Status/Status.stories.tsx +3 -7
- package/src/components/TextArea/TextArea.stories.tsx +1 -3
- package/src/components/TextArea/TextArea.styles.ts +27 -126
- package/src/components/TextArea/TextArea.tsx +86 -112
- package/src/components/TextButton/TextButton.stories.tsx +4 -8
- package/src/components/WithPopup/WithPopup.stories.tsx +0 -1
- package/src/components/WithPopup/WithPopup.styles.ts +0 -2
- package/src/components/WithPopup/WithPopup.tsx +10 -36
- package/src/components/WithPopup/types.ts +0 -7
- package/src/components/WithTooltip/WithTooltip.styles.ts +0 -6
- package/src/components/WithTooltip/WithTooltip.tsx +2 -7
- package/src/components/index.ts +2 -0
- package/src/theme/common.ts +15 -6
- package/src/theme/types.ts +8 -4
- package/src/types.ts +3 -0
- package/dist/components/Input/constants.d.ts +0 -1
- package/dist/components/WithPopup/helpers.d.ts +0 -2
- package/src/components/Input/constants.ts +0 -1
- package/src/components/WithPopup/helpers.ts +0 -9
|
@@ -1,308 +1,98 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createThemedStyles, ITweakStyles } from '../../theme';
|
|
2
|
+
import { IControlGroupStyles } from '../ControlGroup';
|
|
3
|
+
import { IControlWrapperStyles } from '../ControlWrapper';
|
|
3
4
|
|
|
4
|
-
const
|
|
5
|
-
export const AUTOSIZE_MAX_WIDTH = 480;
|
|
5
|
+
const PADDING_WITH_UNITS = 8;
|
|
6
6
|
|
|
7
7
|
export const useStyles = createThemedStyles('Input', {
|
|
8
|
-
root: {
|
|
9
|
-
width: '100%',
|
|
10
|
-
boxSizing: 'border-box',
|
|
11
|
-
position: 'relative',
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
inputWrapper: {
|
|
15
|
-
display: 'flex',
|
|
16
|
-
width: '100%',
|
|
17
|
-
height: dimensions.CONTROL_HEIGHT,
|
|
18
|
-
boxSizing: 'border-box',
|
|
19
|
-
transition: animations.defaultTransition,
|
|
20
|
-
transitionProperty: 'border-color',
|
|
21
|
-
backgroundColor: 'white',
|
|
22
|
-
position: 'relative',
|
|
23
|
-
},
|
|
24
|
-
|
|
25
8
|
inputContent: {
|
|
9
|
+
height: 'var(--control-height)',
|
|
10
|
+
padding: [0, 'var(--control-padding)'],
|
|
26
11
|
fontSize: 16,
|
|
27
12
|
fontFamily: 'inherit',
|
|
28
|
-
padding: [0, PADDING_X],
|
|
29
13
|
},
|
|
30
14
|
|
|
31
15
|
input: {
|
|
32
16
|
extend: 'inputContent',
|
|
33
17
|
width: '100%',
|
|
34
|
-
height: '100%',
|
|
35
18
|
outline: 'none',
|
|
36
|
-
boxSizing: 'border-box',
|
|
37
19
|
outlineStyle: 'none',
|
|
38
|
-
|
|
39
|
-
transitionProperty: 'background-color',
|
|
20
|
+
boxSizing: 'border-box',
|
|
40
21
|
border: 'none',
|
|
41
22
|
background: 'none',
|
|
23
|
+
color: 'black',
|
|
42
24
|
|
|
43
|
-
'
|
|
44
|
-
|
|
25
|
+
'&[readonly]': {
|
|
26
|
+
cursor: 'default',
|
|
45
27
|
},
|
|
46
28
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
WebkitAppearance: 'none',
|
|
50
|
-
margin: 0,
|
|
29
|
+
'&::placeholder': {
|
|
30
|
+
opacity: 1,
|
|
51
31
|
},
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
autosize: {
|
|
55
|
-
display: 'inline-grid',
|
|
56
|
-
verticalAlign: 'top',
|
|
57
|
-
alignItems: 'center',
|
|
58
|
-
justifyContent: 'start',
|
|
59
32
|
|
|
60
|
-
'
|
|
61
|
-
|
|
62
|
-
minWidth: '1em',
|
|
63
|
-
gridArea: '1 / 2',
|
|
64
|
-
font: 'inherit',
|
|
65
|
-
justifySelf: 'stretch',
|
|
33
|
+
'&::-webkit-date-and-time-value': {
|
|
34
|
+
textAlign: 'left',
|
|
66
35
|
},
|
|
67
36
|
|
|
68
|
-
'
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
37
|
+
MozAppearance: 'textfield',
|
|
38
|
+
'&::-webkit-inner-spin-button,&::-webkit-outer-spin-button,&::-webkit-calendar-picker-indicator':
|
|
39
|
+
{
|
|
40
|
+
display: 'none',
|
|
41
|
+
WebkitAppearance: 'none',
|
|
42
|
+
margin: 0,
|
|
43
|
+
},
|
|
74
44
|
},
|
|
75
45
|
|
|
76
|
-
|
|
46
|
+
autoSizeWrapper: {
|
|
77
47
|
position: 'relative',
|
|
78
|
-
zIndex: 1,
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
unitsWrapper: {
|
|
82
|
-
extend: 'inputContent',
|
|
83
|
-
position: 'absolute',
|
|
84
|
-
left: 0,
|
|
85
|
-
height: '100%',
|
|
86
|
-
boxSizing: 'border-box',
|
|
87
48
|
display: 'flex',
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
fakeValue: {
|
|
93
|
-
visibility: 'hidden',
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
units: {
|
|
97
|
-
paddingLeft: 4,
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
withFloatingLabel: {
|
|
101
|
-
paddingTop: 18,
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
floatingLabelWithoutPadding: {
|
|
105
|
-
paddingTop: 18,
|
|
106
|
-
paddingLeft: 0,
|
|
49
|
+
minWidth: 0,
|
|
50
|
+
zIndex: 0,
|
|
51
|
+
flexGrow: 1,
|
|
107
52
|
},
|
|
108
53
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
activeLabel: {
|
|
112
|
-
display: 'none',
|
|
113
|
-
|
|
114
|
-
'&$floating': {
|
|
115
|
-
display: 'block',
|
|
116
|
-
transform: 'scale(0.75) translateY(-120%)',
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
required: {
|
|
121
|
-
'&:before': {
|
|
122
|
-
content: '""',
|
|
123
|
-
position: 'absolute',
|
|
124
|
-
left: -12,
|
|
125
|
-
top: '50%',
|
|
126
|
-
transform: 'translate(0, -50%)',
|
|
127
|
-
width: 6,
|
|
128
|
-
height: 6,
|
|
129
|
-
borderRadius: '50%',
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
label: {
|
|
54
|
+
autoSized: {
|
|
134
55
|
position: 'absolute',
|
|
135
|
-
|
|
136
|
-
left: PADDING_X,
|
|
137
|
-
top: '50%',
|
|
138
|
-
transformOrigin: 'top left',
|
|
139
|
-
transform: 'translateY(-50%)',
|
|
140
|
-
transition: animations.defaultTransition,
|
|
141
|
-
transitionProperty: 'transform, color',
|
|
142
|
-
fontSize: 16,
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
floatingWithoutPadding: {
|
|
56
|
+
top: 0,
|
|
146
57
|
left: 0,
|
|
58
|
+
height: '100%',
|
|
147
59
|
},
|
|
148
60
|
|
|
149
|
-
|
|
150
|
-
'
|
|
151
|
-
|
|
152
|
-
position: 'absolute',
|
|
153
|
-
right: -8,
|
|
154
|
-
top: 4,
|
|
155
|
-
transform: 'translate(0, -50%)',
|
|
156
|
-
width: 6,
|
|
157
|
-
height: 6,
|
|
158
|
-
borderRadius: '50%',
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
|
|
162
|
-
activeIcon: {
|
|
163
|
-
cursor: 'pointer',
|
|
164
|
-
},
|
|
165
|
-
|
|
166
|
-
'border-top': {
|
|
167
|
-
borderRadius: 0,
|
|
168
|
-
borderWidth: [1, 0, 0, 0],
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
'border-bottom': {
|
|
172
|
-
borderRadius: 0,
|
|
173
|
-
borderWidth: [0, 0, 1, 0],
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
'border-left': {
|
|
177
|
-
borderRadius: 0,
|
|
178
|
-
borderWidth: [0, 0, 0, 1],
|
|
179
|
-
},
|
|
180
|
-
|
|
181
|
-
'border-right': {
|
|
182
|
-
borderRadius: 0,
|
|
183
|
-
borderWidth: [0, 1, 0, 0],
|
|
184
|
-
},
|
|
185
|
-
|
|
186
|
-
top: {
|
|
187
|
-
borderBottomLeftRadius: 0,
|
|
188
|
-
borderBottomRightRadius: 0,
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
bottom: {
|
|
192
|
-
borderTopLeftRadius: 0,
|
|
193
|
-
borderTopRightRadius: 0,
|
|
194
|
-
},
|
|
195
|
-
|
|
196
|
-
'top-left': {
|
|
197
|
-
borderTopRightRadius: 0,
|
|
198
|
-
borderBottomLeftRadius: 0,
|
|
199
|
-
borderBottomRightRadius: 0,
|
|
200
|
-
},
|
|
201
|
-
|
|
202
|
-
'top-right': {
|
|
203
|
-
borderTopLeftRadius: 0,
|
|
204
|
-
borderBottomLeftRadius: 0,
|
|
205
|
-
borderBottomRightRadius: 0,
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
'bottom-left': {
|
|
209
|
-
borderTopLeftRadius: 0,
|
|
210
|
-
borderTopRightRadius: 0,
|
|
211
|
-
borderBottomRightRadius: 0,
|
|
212
|
-
},
|
|
213
|
-
|
|
214
|
-
'bottom-right': {
|
|
215
|
-
borderTopLeftRadius: 0,
|
|
216
|
-
borderTopRightRadius: 0,
|
|
217
|
-
borderBottomLeftRadius: 0,
|
|
218
|
-
},
|
|
219
|
-
|
|
220
|
-
left: {
|
|
221
|
-
borderTopRightRadius: 0,
|
|
222
|
-
borderBottomRightRadius: 0,
|
|
223
|
-
},
|
|
224
|
-
|
|
225
|
-
right: {
|
|
226
|
-
borderTopLeftRadius: 0,
|
|
227
|
-
borderBottomLeftRadius: 0,
|
|
228
|
-
},
|
|
229
|
-
|
|
230
|
-
middle: {
|
|
231
|
-
borderRadius: 0,
|
|
232
|
-
},
|
|
233
|
-
|
|
234
|
-
controls: {
|
|
235
|
-
display: 'flex',
|
|
236
|
-
gridArea: '1 / 3',
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
icon: {
|
|
240
|
-
display: 'flex',
|
|
241
|
-
alignItems: 'center',
|
|
242
|
-
padding: [0, 4],
|
|
243
|
-
width: 20,
|
|
244
|
-
transition: animations.defaultTransition,
|
|
245
|
-
transitionProperty: 'color',
|
|
246
|
-
boxSizing: 'content-box',
|
|
61
|
+
withUnits: {
|
|
62
|
+
extend: 'autoSized',
|
|
63
|
+
paddingRight: `calc(${PADDING_WITH_UNITS}px + var(--units-width) - 1px)`,
|
|
247
64
|
|
|
248
|
-
'
|
|
249
|
-
paddingRight:
|
|
65
|
+
'& + $fakeValue': {
|
|
66
|
+
paddingRight: PADDING_WITH_UNITS,
|
|
250
67
|
},
|
|
251
|
-
|
|
252
|
-
'& + $units': {
|
|
253
|
-
marginLeft: 4,
|
|
254
|
-
},
|
|
255
|
-
},
|
|
256
|
-
|
|
257
|
-
clearIcon: {
|
|
258
|
-
extend: 'icon',
|
|
259
|
-
},
|
|
260
|
-
|
|
261
|
-
inputIcon: {
|
|
262
|
-
extend: 'icon',
|
|
263
68
|
},
|
|
264
69
|
|
|
265
|
-
|
|
266
|
-
paddingRight: 4,
|
|
267
|
-
},
|
|
268
|
-
|
|
269
|
-
withControls: {},
|
|
270
|
-
|
|
271
|
-
invalid: {},
|
|
272
|
-
|
|
273
|
-
disabled: {},
|
|
274
|
-
|
|
275
|
-
invalidLabel: {},
|
|
276
|
-
|
|
277
|
-
error: {
|
|
278
|
-
fontSize: 12,
|
|
279
|
-
},
|
|
70
|
+
withLabel: {},
|
|
280
71
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
72
|
+
fakeValue: {
|
|
73
|
+
extend: 'inputContent',
|
|
74
|
+
visibility: 'hidden',
|
|
75
|
+
maxWidth: '100%',
|
|
76
|
+
overflow: 'hidden',
|
|
77
|
+
minWidth: 8,
|
|
285
78
|
},
|
|
286
79
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
left: -1,
|
|
291
|
-
padding: [4, 8],
|
|
292
|
-
zIndex: 1,
|
|
80
|
+
units: {
|
|
81
|
+
alignSelf: 'center',
|
|
82
|
+
paddingRight: 'var(--control-padding)',
|
|
293
83
|
},
|
|
294
84
|
|
|
295
|
-
|
|
296
|
-
paddingTop: 4,
|
|
297
|
-
paddingLeft: 13,
|
|
298
|
-
},
|
|
85
|
+
focusedInput: {},
|
|
299
86
|
|
|
300
|
-
|
|
87
|
+
disabledInput: {},
|
|
301
88
|
|
|
302
|
-
|
|
89
|
+
invalidInput: {},
|
|
303
90
|
});
|
|
304
91
|
|
|
305
92
|
export type IInputStyles = ITweakStyles<
|
|
306
93
|
typeof useStyles,
|
|
307
|
-
{
|
|
94
|
+
{
|
|
95
|
+
tweakControlWrapper: IControlWrapperStyles;
|
|
96
|
+
tweakControlGroup: IControlGroupStyles;
|
|
97
|
+
}
|
|
308
98
|
>;
|
|
@@ -1,296 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
forwardRef,
|
|
3
|
-
useRef,
|
|
4
|
-
useState,
|
|
5
|
-
MutableRefObject,
|
|
6
|
-
FormEvent,
|
|
7
|
-
FocusEvent,
|
|
8
|
-
MouseEvent,
|
|
9
|
-
InputHTMLAttributes,
|
|
10
|
-
ReactNode,
|
|
11
|
-
} from 'react';
|
|
12
|
-
import InputMask from 'react-input-mask';
|
|
13
|
-
import clsx from 'clsx';
|
|
14
|
-
import {
|
|
15
|
-
addDataTestId,
|
|
16
|
-
isReactNodeNotEmpty,
|
|
17
|
-
isStringNotEmpty,
|
|
18
|
-
} from '@true-engineering/true-react-platform-helpers';
|
|
19
|
-
import { addDataAttributes } from '../../helpers';
|
|
1
|
+
import { forwardRef } from 'react';
|
|
20
2
|
import { useTweakStyles } from '../../hooks';
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import { ThemedPreloader } from '../ThemedPreloader';
|
|
24
|
-
import { DEFAULT_SIZE } from './constants';
|
|
25
|
-
import { IInputHTMLBaseProps, IReactInputMaskProps } from './types';
|
|
26
|
-
import { useStyles, IInputStyles } from './Input.styles';
|
|
3
|
+
import { ControlGroup, IControlGroupProps } from '../ControlGroup';
|
|
4
|
+
import { IInputBaseProps, InputBase } from './InputBase';
|
|
27
5
|
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
IReactInputMaskProps,
|
|
31
|
-
IInputHTMLBaseProps {
|
|
32
|
-
value?: string;
|
|
33
|
-
label?: ReactNode;
|
|
34
|
-
/** @default false */
|
|
35
|
-
isDisabled?: boolean;
|
|
36
|
-
/** @default true */
|
|
37
|
-
hasFloatingLabel?: boolean;
|
|
38
|
-
/** @default false */
|
|
39
|
-
isReadonly?: boolean;
|
|
40
|
-
/** @default false */
|
|
41
|
-
isInvalid?: boolean;
|
|
42
|
-
/** @default false */
|
|
43
|
-
isActive?: boolean;
|
|
44
|
-
/** @default false */
|
|
45
|
-
isClearable?: boolean;
|
|
46
|
-
infoMessage?: string;
|
|
47
|
-
errorMessage?: string;
|
|
48
|
-
/** @default 'bottom' */
|
|
49
|
-
errorPosition?: 'top' | 'bottom';
|
|
50
|
-
inlineStyle?:
|
|
51
|
-
| 'top'
|
|
52
|
-
| 'bottom'
|
|
53
|
-
| 'top-left'
|
|
54
|
-
| 'top-right'
|
|
55
|
-
| 'bottom-left'
|
|
56
|
-
| 'bottom-right'
|
|
57
|
-
| 'left'
|
|
58
|
-
| 'right'
|
|
59
|
-
| 'middle';
|
|
60
|
-
border?: 'top' | 'bottom' | 'left' | 'right';
|
|
61
|
-
/** @default false */
|
|
62
|
-
isRequired?: boolean;
|
|
63
|
-
/** @default false */
|
|
64
|
-
isLoading?: boolean;
|
|
65
|
-
/**
|
|
66
|
-
* Должна ли ширина input'а подстраиваться под ширину контента
|
|
67
|
-
* @default false
|
|
68
|
-
*/
|
|
69
|
-
isAutoSizeable?: boolean;
|
|
70
|
-
/**
|
|
71
|
-
* Ширина input'а по умолчанию. Используется только вместе с `isAutoSizeable` равному `true`
|
|
72
|
-
* @default 6
|
|
73
|
-
*/
|
|
74
|
-
defaultSize?: number;
|
|
75
|
-
iconType?: IIcon;
|
|
76
|
-
units?: string;
|
|
77
|
-
/** @default false */
|
|
78
|
-
hasRequiredLabel?: boolean;
|
|
79
|
-
/** @default false */
|
|
80
|
-
shouldFocusOnMount?: boolean;
|
|
81
|
-
/** @default false */
|
|
82
|
-
shouldAlwaysShowPlaceholder?: boolean;
|
|
83
|
-
onChange: (value: string, event: FormEvent<HTMLInputElement>) => void;
|
|
84
|
-
onIconClick?: () => void;
|
|
85
|
-
}
|
|
6
|
+
export type IInputProps = IInputBaseProps &
|
|
7
|
+
Pick<IControlGroupProps, 'infoMessage' | 'errorMessage'>;
|
|
86
8
|
|
|
87
9
|
export const Input = forwardRef<HTMLInputElement, IInputProps>(
|
|
88
|
-
(
|
|
89
|
-
{
|
|
90
|
-
value = '',
|
|
91
|
-
label,
|
|
92
|
-
placeholder,
|
|
93
|
-
type = 'text',
|
|
94
|
-
isDisabled,
|
|
95
|
-
isReadonly = false,
|
|
96
|
-
hasFloatingLabel = true,
|
|
97
|
-
isInvalid = false,
|
|
98
|
-
isActive = false,
|
|
99
|
-
isClearable = false,
|
|
100
|
-
infoMessage,
|
|
101
|
-
errorMessage,
|
|
102
|
-
errorPosition = 'bottom',
|
|
103
|
-
inlineStyle,
|
|
104
|
-
border,
|
|
105
|
-
isRequired = false,
|
|
106
|
-
isLoading = false,
|
|
107
|
-
isAutoSizeable = false,
|
|
108
|
-
defaultSize = DEFAULT_SIZE,
|
|
109
|
-
iconType,
|
|
110
|
-
hasRequiredLabel,
|
|
111
|
-
data,
|
|
10
|
+
({ infoMessage, errorMessage, isInvalid, testId, tweakStyles, ...inputProps }, ref) => {
|
|
11
|
+
const tweakControlGroupStyles = useTweakStyles({
|
|
112
12
|
tweakStyles,
|
|
113
|
-
|
|
114
|
-
units,
|
|
115
|
-
testId,
|
|
116
|
-
onChange,
|
|
117
|
-
onFocus,
|
|
118
|
-
onBlur,
|
|
119
|
-
onIconClick,
|
|
120
|
-
// Пропсы react-input-mask
|
|
121
|
-
mask,
|
|
122
|
-
maskPlaceholder,
|
|
123
|
-
alwaysShowMask,
|
|
124
|
-
shouldAlwaysShowPlaceholder = false,
|
|
125
|
-
beforeMaskedStateChange,
|
|
126
|
-
...inputProps
|
|
127
|
-
},
|
|
128
|
-
ref,
|
|
129
|
-
) => {
|
|
130
|
-
const classes = useStyles({ theme: tweakStyles });
|
|
131
|
-
|
|
132
|
-
const tweakPreloaderStyles = useTweakStyles({
|
|
133
|
-
tweakStyles,
|
|
134
|
-
className: 'tweakPreloader',
|
|
135
|
-
currentComponentName: 'Input',
|
|
13
|
+
className: 'tweakControlGroup',
|
|
136
14
|
});
|
|
137
15
|
|
|
138
|
-
const [isFocused, setFocused] = useState(false);
|
|
139
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
140
|
-
|
|
141
|
-
const handleChange = (event: FormEvent<HTMLInputElement>) => {
|
|
142
|
-
onChange(event.currentTarget.value, event);
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
const handleFocus = (event: FocusEvent<HTMLInputElement>) => {
|
|
146
|
-
setFocused(true);
|
|
147
|
-
onFocus?.(event);
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
const handleBlur = (event: FocusEvent<HTMLInputElement>) => {
|
|
151
|
-
setFocused(false);
|
|
152
|
-
onBlur?.(event);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// для SmartInput нужен event, иначе onChange не вызовется
|
|
156
|
-
const handleOnInputClear = async (event: MouseEvent<HTMLDivElement>) => {
|
|
157
|
-
// await не убирать (важно для порядка выполнения (сначала onChange, затем focus)
|
|
158
|
-
await onChange('', event as any);
|
|
159
|
-
const input = (ref as MutableRefObject<HTMLInputElement>) ?? inputRef;
|
|
160
|
-
input.current?.focus();
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const hasFocus = isFocused || isActive;
|
|
164
|
-
const hasClearIcon = isClearable && value.length > 0;
|
|
165
|
-
const hasControls = hasClearIcon || iconType !== undefined || isLoading;
|
|
166
|
-
const hasValue = value !== undefined && value !== '';
|
|
167
|
-
const hasUnits = units !== undefined && units !== '';
|
|
168
|
-
const hasLabel = isReactNodeNotEmpty(label);
|
|
169
|
-
const isLabelActive = (hasFocus && !isReadonly) || hasValue || shouldAlwaysShowPlaceholder;
|
|
170
|
-
const hasPlaceholder = (!hasLabel || isLabelActive) && isStringNotEmpty(placeholder);
|
|
171
|
-
const shouldShowUnits = (hasValue || (isFocused && !hasPlaceholder)) && hasUnits;
|
|
172
|
-
|
|
173
|
-
const props: InputHTMLAttributes<HTMLInputElement> = {
|
|
174
|
-
...inputProps,
|
|
175
|
-
...addDataTestId(testId),
|
|
176
|
-
className: clsx(classes.input, {
|
|
177
|
-
[classes.withFloatingLabel]: hasFloatingLabel && hasLabel,
|
|
178
|
-
[classes.withIcons]: hasControls,
|
|
179
|
-
[classes.withControls]: hasControls,
|
|
180
|
-
[classes.withUnits]: shouldShowUnits,
|
|
181
|
-
[classes.floatingLabelWithoutPadding]: hasFloatingLabel && hasLabel && border === 'bottom',
|
|
182
|
-
}),
|
|
183
|
-
onFocus: handleFocus,
|
|
184
|
-
onBlur: handleBlur,
|
|
185
|
-
onChange: handleChange,
|
|
186
|
-
value,
|
|
187
|
-
type,
|
|
188
|
-
disabled: isDisabled,
|
|
189
|
-
placeholder: hasPlaceholder ? placeholder : undefined,
|
|
190
|
-
autoFocus: shouldFocusOnMount,
|
|
191
|
-
readOnly: isReadonly,
|
|
192
|
-
size: isAutoSizeable ? defaultSize : undefined,
|
|
193
|
-
};
|
|
194
|
-
|
|
195
16
|
return (
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
data-value={isAutoSizeable ? value : undefined}
|
|
211
|
-
{...addDataAttributes(data)}
|
|
212
|
-
>
|
|
213
|
-
{mask === undefined ? (
|
|
214
|
-
<input ref={ref ?? inputRef} {...props} />
|
|
215
|
-
) : (
|
|
216
|
-
<InputMask
|
|
217
|
-
// Баг в типизации react-input-mask
|
|
218
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
219
|
-
// @ts-ignore: No overload matches this call
|
|
220
|
-
ref={ref ?? inputRef}
|
|
221
|
-
mask={mask}
|
|
222
|
-
maskPlaceholder={maskPlaceholder}
|
|
223
|
-
alwaysShowMask={alwaysShowMask}
|
|
224
|
-
beforeMaskedStateChange={beforeMaskedStateChange}
|
|
225
|
-
{...props}
|
|
226
|
-
/>
|
|
227
|
-
)}
|
|
228
|
-
{hasLabel && (
|
|
229
|
-
<span
|
|
230
|
-
className={clsx(classes.label, {
|
|
231
|
-
[classes.invalidLabel]: isInvalid,
|
|
232
|
-
[classes.requiredLabel]: hasRequiredLabel && !isRequired,
|
|
233
|
-
[classes.activeLabel]: isLabelActive,
|
|
234
|
-
[classes.floating]: hasFloatingLabel,
|
|
235
|
-
// Обсуждаемо, сделал так, потому что не хочется создавать новую пропсу, на каждый чих в стилях
|
|
236
|
-
[classes.floatingWithoutPadding]: hasFloatingLabel && border === 'bottom',
|
|
237
|
-
})}
|
|
238
|
-
>
|
|
239
|
-
{label}
|
|
240
|
-
</span>
|
|
241
|
-
)}
|
|
242
|
-
|
|
243
|
-
{shouldShowUnits && (
|
|
244
|
-
<div
|
|
245
|
-
className={clsx(classes.unitsWrapper, {
|
|
246
|
-
[classes.withFloatingLabel]: hasFloatingLabel && hasLabel,
|
|
247
|
-
})}
|
|
248
|
-
>
|
|
249
|
-
<span className={classes.fakeValue}>{value}</span>
|
|
250
|
-
<span className={classes.units}>{units}</span>
|
|
251
|
-
</div>
|
|
252
|
-
)}
|
|
253
|
-
|
|
254
|
-
{hasControls && (
|
|
255
|
-
<div className={classes.controls}>
|
|
256
|
-
{isLoading && (
|
|
257
|
-
<div className={clsx(classes.inputIcon, classes.loading)}>
|
|
258
|
-
<ThemedPreloader tweakStyles={tweakPreloaderStyles} />
|
|
259
|
-
</div>
|
|
260
|
-
)}
|
|
261
|
-
|
|
262
|
-
{!isDisabled && hasClearIcon && (
|
|
263
|
-
<div
|
|
264
|
-
// .clearIcon extend .icon
|
|
265
|
-
className={clsx(classes.clearIcon, classes.activeIcon)}
|
|
266
|
-
// превентим блур с инпута (важно)
|
|
267
|
-
onMouseDown={(event) => event.preventDefault()}
|
|
268
|
-
onClick={handleOnInputClear}
|
|
269
|
-
>
|
|
270
|
-
<Icon type="close" />
|
|
271
|
-
</div>
|
|
272
|
-
)}
|
|
273
|
-
{isReactNodeNotEmpty(iconType) && (
|
|
274
|
-
<div
|
|
275
|
-
// .inputIcon extend .icon
|
|
276
|
-
className={clsx(classes.inputIcon, {
|
|
277
|
-
[classes.activeIcon]: !isDisabled && onIconClick !== undefined,
|
|
278
|
-
})}
|
|
279
|
-
onClick={!isDisabled ? onIconClick : undefined}
|
|
280
|
-
>
|
|
281
|
-
{renderIcon(iconType)}
|
|
282
|
-
</div>
|
|
283
|
-
)}
|
|
284
|
-
</div>
|
|
285
|
-
)}
|
|
286
|
-
</div>
|
|
287
|
-
{isStringNotEmpty(infoMessage) && <div className={classes.info}>{infoMessage}</div>}
|
|
288
|
-
{isStringNotEmpty(errorMessage) && (
|
|
289
|
-
<div className={clsx(classes.error, classes[`error-${errorPosition}`])}>
|
|
290
|
-
{errorMessage}
|
|
291
|
-
</div>
|
|
292
|
-
)}
|
|
293
|
-
</div>
|
|
17
|
+
<ControlGroup
|
|
18
|
+
errorMessage={errorMessage}
|
|
19
|
+
infoMessage={infoMessage}
|
|
20
|
+
testId={testId}
|
|
21
|
+
tweakStyles={tweakControlGroupStyles}
|
|
22
|
+
>
|
|
23
|
+
<InputBase
|
|
24
|
+
{...inputProps}
|
|
25
|
+
ref={ref}
|
|
26
|
+
testId={testId}
|
|
27
|
+
tweakStyles={tweakStyles}
|
|
28
|
+
isInvalid={isInvalid}
|
|
29
|
+
/>
|
|
30
|
+
</ControlGroup>
|
|
294
31
|
);
|
|
295
32
|
},
|
|
296
33
|
);
|