@true-engineering/true-react-common-ui-kit 2.2.0 → 2.3.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 (244) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +16 -0
  3. package/dist/components/Flag/augment.d.ts +1 -1
  4. package/dist/components/Icon/complexIcons/augment.d.ts +1 -1
  5. package/dist/components/Modal/Modal.d.ts +3 -3
  6. package/dist/true-react-common-ui-kit.js +151 -97
  7. package/dist/true-react-common-ui-kit.js.map +1 -1
  8. package/dist/true-react-common-ui-kit.umd.cjs +151 -97
  9. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  10. package/dist/vite-env.d.ts +1 -1
  11. package/package.json +93 -93
  12. package/src/components/AccountInfo/AccountInfo.stories.tsx +32 -32
  13. package/src/components/AccountInfo/AccountInfo.styles.ts +55 -55
  14. package/src/components/AccountInfo/AccountInfo.tsx +77 -77
  15. package/src/components/AccountInfo/index.ts +2 -2
  16. package/src/components/AddButton/AddButton.stories.tsx +21 -21
  17. package/src/components/AddButton/AddButton.styles.ts +34 -34
  18. package/src/components/AddButton/AddButton.tsx +48 -48
  19. package/src/components/AddButton/index.ts +2 -2
  20. package/src/components/Button/Button.stories.tsx +52 -52
  21. package/src/components/Button/Button.styles.ts +196 -196
  22. package/src/components/Button/Button.tsx +167 -167
  23. package/src/components/Button/index.ts +2 -2
  24. package/src/components/Checkbox/Checkbox.stories.tsx +32 -32
  25. package/src/components/Checkbox/Checkbox.styles.ts +62 -62
  26. package/src/components/Checkbox/Checkbox.tsx +105 -105
  27. package/src/components/Checkbox/index.ts +2 -2
  28. package/src/components/CloseButton/CloseButton.styles.ts +34 -34
  29. package/src/components/CloseButton/CloseButton.tsx +35 -35
  30. package/src/components/CloseButton/index.ts +2 -2
  31. package/src/components/Colors/Colors.stories.tsx +7 -7
  32. package/src/components/Colors/Colors.styles.ts +38 -38
  33. package/src/components/Colors/Colors.tsx +26 -26
  34. package/src/components/Colors/index.ts +2 -2
  35. package/src/components/CssBaseline/CssBaseline.styles.ts +15 -15
  36. package/src/components/CssBaseline/CssBaseline.tsx +15 -15
  37. package/src/components/CssBaseline/index.ts +2 -2
  38. package/src/components/DateInput/DateInput.stories.tsx +61 -61
  39. package/src/components/DateInput/DateInput.styles.ts +14 -14
  40. package/src/components/DateInput/DateInput.tsx +82 -82
  41. package/src/components/DateInput/constants.ts +2 -2
  42. package/src/components/DateInput/index.ts +3 -3
  43. package/src/components/DatePicker/DatePicker.stories.tsx +87 -87
  44. package/src/components/DatePicker/DatePicker.styles.ts +44 -44
  45. package/src/components/DatePicker/DatePicker.tsx +327 -327
  46. package/src/components/DatePicker/DatePickerHeader/DatePickerHeader.styles.ts +84 -84
  47. package/src/components/DatePicker/DatePickerHeader/DatePickerHeader.tsx +79 -79
  48. package/src/components/DatePicker/DatePickerHeader/index.ts +2 -2
  49. package/src/components/DatePicker/constants.ts +1 -1
  50. package/src/components/DatePicker/helpers.ts +23 -23
  51. package/src/components/DatePicker/index.ts +3 -3
  52. package/src/components/DatePicker/types.ts +45 -45
  53. package/src/components/Description/Description.stories.tsx +27 -27
  54. package/src/components/Description/Description.styles.ts +31 -31
  55. package/src/components/Description/Description.tsx +60 -60
  56. package/src/components/Description/index.ts +2 -2
  57. package/src/components/FiltersPane/FilterInterval/FilterInterval.styles.ts +64 -64
  58. package/src/components/FiltersPane/FilterInterval/FilterInterval.tsx +143 -143
  59. package/src/components/FiltersPane/FilterInterval/index.ts +1 -1
  60. package/src/components/FiltersPane/FilterMultiSelect/FilterMultiSelect.tsx +10 -10
  61. package/src/components/FiltersPane/FilterMultiSelect/index.ts +1 -1
  62. package/src/components/FiltersPane/FilterSelect/FilterSelect.styles.ts +143 -143
  63. package/src/components/FiltersPane/FilterSelect/FilterSelect.tsx +348 -348
  64. package/src/components/FiltersPane/FilterSelect/index.ts +1 -1
  65. package/src/components/FiltersPane/FilterSelect/locales.ts +37 -37
  66. package/src/components/FiltersPane/FilterValueView/FilterValueView.styles.tsx +15 -15
  67. package/src/components/FiltersPane/FilterValueView/FilterValueView.tsx +166 -166
  68. package/src/components/FiltersPane/FilterValueView/index.tsx +1 -1
  69. package/src/components/FiltersPane/FilterWithDates/FilterWithDates.styles.ts +60 -60
  70. package/src/components/FiltersPane/FilterWithDates/FilterWithDates.tsx +184 -184
  71. package/src/components/FiltersPane/FilterWithDates/index.ts +1 -1
  72. package/src/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.styles.ts +17 -17
  73. package/src/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.tsx +198 -198
  74. package/src/components/FiltersPane/FilterWithPeriod/index.ts +1 -1
  75. package/src/components/FiltersPane/FilterWrapper/FilterWrapper.styles.ts +110 -110
  76. package/src/components/FiltersPane/FilterWrapper/FilterWrapper.tsx +346 -346
  77. package/src/components/FiltersPane/FilterWrapper/index.ts +1 -1
  78. package/src/components/FiltersPane/FiltersPane.stories.tsx +295 -295
  79. package/src/components/FiltersPane/FiltersPane.styles.ts +71 -71
  80. package/src/components/FiltersPane/FiltersPane.tsx +151 -151
  81. package/src/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.styles.ts +109 -109
  82. package/src/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.tsx +155 -155
  83. package/src/components/FiltersPane/FiltersPaneSearch/index.ts +1 -1
  84. package/src/components/FiltersPane/index.ts +20 -20
  85. package/src/components/FiltersPane/locales.ts +107 -107
  86. package/src/components/FiltersPane/types.ts +112 -112
  87. package/src/components/Flag/Flag.stories.tsx +29 -29
  88. package/src/components/Flag/Flag.styles.ts +18 -18
  89. package/src/components/Flag/Flag.tsx +27 -27
  90. package/src/components/Flag/augment.d.ts +1 -1
  91. package/src/components/Flag/index.ts +2 -2
  92. package/src/components/FlexibleTable/FlexibleTable.stories.tsx +84 -84
  93. package/src/components/FlexibleTable/FlexibleTable.styles.ts +131 -131
  94. package/src/components/FlexibleTable/FlexibleTable.tsx +205 -205
  95. package/src/components/FlexibleTable/TableRow.tsx +152 -152
  96. package/src/components/FlexibleTable/TableValue.tsx +75 -75
  97. package/src/components/FlexibleTable/fixture-test.ts +254 -254
  98. package/src/components/FlexibleTable/index.ts +3 -3
  99. package/src/components/FlexibleTable/types.ts +52 -52
  100. package/src/components/Icon/ComplexIconBoilerplate.tsx +17 -17
  101. package/src/components/Icon/Icon.stories.tsx +85 -85
  102. package/src/components/Icon/Icon.styles.ts +10 -10
  103. package/src/components/Icon/Icon.tsx +32 -32
  104. package/src/components/Icon/IconBoilerplate.tsx +42 -42
  105. package/src/components/Icon/complexIcons/augment.d.ts +1 -1
  106. package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
  107. package/src/components/Icon/complexIcons/icons.ts +7 -7
  108. package/src/components/Icon/complexIcons/index.ts +1 -1
  109. package/src/components/Icon/icons/icons.ts +838 -838
  110. package/src/components/Icon/icons/index.ts +1 -1
  111. package/src/components/Icon/index.ts +4 -4
  112. package/src/components/IncrementInput/ChangeButton.tsx +33 -33
  113. package/src/components/IncrementInput/IncrementInput.stories.tsx +31 -31
  114. package/src/components/IncrementInput/IncrementInput.styles.ts +77 -77
  115. package/src/components/IncrementInput/IncrementInput.tsx +80 -80
  116. package/src/components/IncrementInput/index.ts +2 -2
  117. package/src/components/Input/Input.stories.tsx +86 -86
  118. package/src/components/Input/Input.styles.ts +307 -307
  119. package/src/components/Input/Input.tsx +311 -311
  120. package/src/components/Input/index.ts +2 -2
  121. package/src/components/List/List.stories.tsx +62 -62
  122. package/src/components/List/List.styles.ts +52 -52
  123. package/src/components/List/List.tsx +64 -64
  124. package/src/components/List/index.ts +2 -2
  125. package/src/components/Modal/Modal.stories.tsx +105 -105
  126. package/src/components/Modal/Modal.styles.ts +305 -305
  127. package/src/components/Modal/Modal.tsx +200 -186
  128. package/src/components/Modal/index.ts +2 -2
  129. package/src/components/MoreMenu/MoreMenu.stories.tsx +46 -46
  130. package/src/components/MoreMenu/MoreMenu.styles.ts +70 -70
  131. package/src/components/MoreMenu/MoreMenu.tsx +90 -90
  132. package/src/components/MoreMenu/index.ts +2 -2
  133. package/src/components/MultiSelect/MultiSelect.stories.tsx +46 -46
  134. package/src/components/MultiSelect/MultiSelect.styles.ts +55 -55
  135. package/src/components/MultiSelect/MultiSelect.tsx +89 -89
  136. package/src/components/MultiSelect/MultiSelectInput/MultiSelectInput.styles.ts +73 -73
  137. package/src/components/MultiSelect/MultiSelectInput/MultiSelectInput.tsx +51 -51
  138. package/src/components/MultiSelect/MultiSelectInput/index.ts +1 -1
  139. package/src/components/MultiSelect/index.ts +3 -3
  140. package/src/components/MultiSelectList/MultiSelectList.styles.ts +124 -124
  141. package/src/components/MultiSelectList/MultiSelectList.tsx +451 -451
  142. package/src/components/MultiSelectList/index.ts +2 -2
  143. package/src/components/MultiSelectList/locales.ts +37 -37
  144. package/src/components/Notification/Notification.stories.tsx +46 -46
  145. package/src/components/Notification/Notification.styles.ts +50 -50
  146. package/src/components/Notification/Notification.tsx +79 -79
  147. package/src/components/Notification/index.ts +2 -2
  148. package/src/components/NumberInput/NumberInput.stories.tsx +35 -35
  149. package/src/components/NumberInput/NumberInput.tsx +133 -133
  150. package/src/components/NumberInput/helpers.ts +86 -86
  151. package/src/components/NumberInput/index.ts +1 -1
  152. package/src/components/PhoneInput/PhoneInput.stories.tsx +70 -70
  153. package/src/components/PhoneInput/PhoneInput.styles.ts +84 -84
  154. package/src/components/PhoneInput/PhoneInput.tsx +194 -194
  155. package/src/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.stories.tsx +21 -21
  156. package/src/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.styles.ts +100 -100
  157. package/src/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.tsx +147 -147
  158. package/src/components/PhoneInput/PhoneInputCountryList/index.ts +2 -2
  159. package/src/components/PhoneInput/index.ts +6 -6
  160. package/src/components/PhoneInput/phone-info.ts +2147 -2147
  161. package/src/components/PhoneInput/types.ts +16 -16
  162. package/src/components/RadioButton/RadioButton.stories.tsx +46 -46
  163. package/src/components/RadioButton/RadioButton.styles.ts +37 -37
  164. package/src/components/RadioButton/RadioButton.tsx +55 -55
  165. package/src/components/RadioButton/index.ts +2 -2
  166. package/src/components/ScrollIntoViewIfNeeded/ScrollIntoViewIfNeeded.ts +61 -61
  167. package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
  168. package/src/components/SearchInput/SearchInput.stories.tsx +23 -23
  169. package/src/components/SearchInput/SearchInput.styles.ts +50 -50
  170. package/src/components/SearchInput/SearchInput.tsx +50 -50
  171. package/src/components/SearchInput/index.ts +2 -2
  172. package/src/components/Select/MultiSelect.stories.tsx +240 -240
  173. package/src/components/Select/Select.stories.tsx +235 -235
  174. package/src/components/Select/Select.styles.ts +96 -96
  175. package/src/components/Select/Select.tsx +575 -575
  176. package/src/components/Select/SelectList/SelectList.styles.ts +72 -72
  177. package/src/components/Select/SelectList/SelectList.tsx +158 -158
  178. package/src/components/Select/SelectList/index.ts +1 -1
  179. package/src/components/Select/SelectListItem/SelectListItem.styles.ts +14 -14
  180. package/src/components/Select/SelectListItem/SelectListItem.tsx +68 -68
  181. package/src/components/Select/constants.ts +2 -2
  182. package/src/components/Select/helpers.ts +26 -26
  183. package/src/components/Select/index.ts +4 -4
  184. package/src/components/Select/types.ts +1 -1
  185. package/src/components/SmartInput/SmartInput.stories.tsx +50 -50
  186. package/src/components/SmartInput/SmartInput.tsx +147 -147
  187. package/src/components/SmartInput/helpers.ts +85 -85
  188. package/src/components/SmartInput/index.ts +1 -1
  189. package/src/components/Switch/Switch.stories.tsx +40 -40
  190. package/src/components/Switch/Switch.styles.ts +75 -75
  191. package/src/components/Switch/Switch.tsx +83 -83
  192. package/src/components/Switch/index.ts +2 -2
  193. package/src/components/TextArea/TextArea.stories.tsx +35 -35
  194. package/src/components/TextArea/TextArea.styles.ts +153 -153
  195. package/src/components/TextArea/TextArea.tsx +165 -165
  196. package/src/components/TextArea/index.ts +2 -2
  197. package/src/components/TextWithInfo/TextWithInfo.stories.tsx +53 -53
  198. package/src/components/TextWithInfo/TextWithInfo.styles.ts +60 -60
  199. package/src/components/TextWithInfo/TextWithInfo.tsx +60 -60
  200. package/src/components/TextWithInfo/index.ts +2 -2
  201. package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
  202. package/src/components/TextWithTooltip/TextWithTooltip.styles.ts +19 -19
  203. package/src/components/TextWithTooltip/TextWithTooltip.tsx +143 -143
  204. package/src/components/TextWithTooltip/index.ts +2 -2
  205. package/src/components/ThemedPreloader/ThemedPreloader.stories.tsx +41 -41
  206. package/src/components/ThemedPreloader/ThemedPreloader.styles.ts +21 -21
  207. package/src/components/ThemedPreloader/ThemedPreloader.tsx +50 -50
  208. package/src/components/ThemedPreloader/components/DefaultPreloader/DefaultPreloader.tsx +29 -29
  209. package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
  210. package/src/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.styles.ts +54 -54
  211. package/src/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.tsx +18 -18
  212. package/src/components/ThemedPreloader/components/DotsPreloader/index.ts +2 -2
  213. package/src/components/ThemedPreloader/components/SvgPreloader/SvgPreloader.styles.ts +11 -11
  214. package/src/components/ThemedPreloader/components/SvgPreloader/SvgPreloader.tsx +25 -25
  215. package/src/components/ThemedPreloader/components/SvgPreloader/index.ts +2 -2
  216. package/src/components/ThemedPreloader/components/index.ts +2 -2
  217. package/src/components/ThemedPreloader/index.ts +2 -2
  218. package/src/components/Toaster/Toaster.stories.tsx +30 -30
  219. package/src/components/Toaster/Toaster.styles.ts +59 -59
  220. package/src/components/Toaster/Toaster.tsx +110 -110
  221. package/src/components/Toaster/index.ts +2 -2
  222. package/src/components/Tooltip/Tooltip.stories.tsx +19 -19
  223. package/src/components/Tooltip/Tooltip.styles.ts +45 -45
  224. package/src/components/Tooltip/Tooltip.tsx +35 -35
  225. package/src/components/Tooltip/index.ts +3 -3
  226. package/src/components/Tooltip/types.ts +1 -1
  227. package/src/components/index.ts +36 -36
  228. package/src/helpers/deprecated.ts +22 -22
  229. package/src/helpers/index.ts +4 -4
  230. package/src/helpers/misc.ts +158 -158
  231. package/src/helpers/phone.ts +87 -87
  232. package/src/helpers/popper-helpers.ts +17 -17
  233. package/src/helpers/snippets.tsx +6 -6
  234. package/src/hooks/index.ts +6 -6
  235. package/src/hooks/use-did-mount-effect.ts +18 -18
  236. package/src/hooks/use-dropdown.ts +82 -82
  237. package/src/hooks/use-is-mounted.ts +15 -15
  238. package/src/hooks/use-on-click-outside.ts +77 -77
  239. package/src/hooks/use-theme.ts +32 -32
  240. package/src/hooks/use-tweak-styles.ts +13 -13
  241. package/src/index.ts +6 -6
  242. package/src/theme.ts +149 -149
  243. package/src/types.ts +107 -107
  244. package/src/vite-env.d.ts +1 -1
@@ -1,84 +1,84 @@
1
- import { colors, dimensions } from '../../theme';
2
- import { ComponentStyles } from '../../types';
3
-
4
- const COUNTRY_SELECT_WIDTH = 80;
5
-
6
- export const styles = {
7
- root: {
8
- width: '100%',
9
- position: 'relative',
10
- boxSizing: 'border-box',
11
- },
12
-
13
- countrySelectContainer: {
14
- position: 'absolute',
15
- left: 1,
16
- top: 1,
17
- width: COUNTRY_SELECT_WIDTH,
18
- height: dimensions.CONTROL_HEIGHT - 2,
19
- display: 'flex',
20
- alignItems: 'center',
21
- justifyContent: 'center',
22
- borderRight: ['solid', 1, colors.BORDER_MAIN],
23
- transition: 'border-color 0.2s ease-in',
24
- cursor: 'pointer',
25
- zIndex: 2,
26
- },
27
-
28
- disabledCountrySelect: {
29
- cursor: 'default',
30
- },
31
-
32
- flag: {
33
- width: 22,
34
- height: 16,
35
- },
36
-
37
- arrow: {
38
- width: 20,
39
- color: colors.GREY_ACTIVE,
40
- marginLeft: 8,
41
- transition: 'transform .2s ease',
42
- },
43
-
44
- up: {
45
- transform: 'rotate(180deg)',
46
- },
47
-
48
- invalidArrow: {
49
- color: colors.RED_WARNING,
50
- },
51
-
52
- focusedBorder: {},
53
-
54
- invalidBorder: {
55
- borderColor: colors.RED_WARNING,
56
- },
57
-
58
- inputContainer: {
59
- position: 'relative',
60
- flex: 1,
61
- },
62
-
63
- flagListContainer: {
64
- position: 'absolute',
65
- width: '100%',
66
- top: dimensions.CONTROL_HEIGHT + 6,
67
- left: -1,
68
- zIndex: 3,
69
- },
70
-
71
- tweakInput: {
72
- inputWrapper: {
73
- paddingLeft: COUNTRY_SELECT_WIDTH,
74
- },
75
-
76
- label: {
77
- marginLeft: COUNTRY_SELECT_WIDTH,
78
- },
79
- },
80
-
81
- tweakCountryList: {},
82
- };
83
-
84
- export type PhoneInputStyles = ComponentStyles<typeof styles>;
1
+ import { colors, dimensions } from '../../theme';
2
+ import { ComponentStyles } from '../../types';
3
+
4
+ const COUNTRY_SELECT_WIDTH = 80;
5
+
6
+ export const styles = {
7
+ root: {
8
+ width: '100%',
9
+ position: 'relative',
10
+ boxSizing: 'border-box',
11
+ },
12
+
13
+ countrySelectContainer: {
14
+ position: 'absolute',
15
+ left: 1,
16
+ top: 1,
17
+ width: COUNTRY_SELECT_WIDTH,
18
+ height: dimensions.CONTROL_HEIGHT - 2,
19
+ display: 'flex',
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ borderRight: ['solid', 1, colors.BORDER_MAIN],
23
+ transition: 'border-color 0.2s ease-in',
24
+ cursor: 'pointer',
25
+ zIndex: 2,
26
+ },
27
+
28
+ disabledCountrySelect: {
29
+ cursor: 'default',
30
+ },
31
+
32
+ flag: {
33
+ width: 22,
34
+ height: 16,
35
+ },
36
+
37
+ arrow: {
38
+ width: 20,
39
+ color: colors.GREY_ACTIVE,
40
+ marginLeft: 8,
41
+ transition: 'transform .2s ease',
42
+ },
43
+
44
+ up: {
45
+ transform: 'rotate(180deg)',
46
+ },
47
+
48
+ invalidArrow: {
49
+ color: colors.RED_WARNING,
50
+ },
51
+
52
+ focusedBorder: {},
53
+
54
+ invalidBorder: {
55
+ borderColor: colors.RED_WARNING,
56
+ },
57
+
58
+ inputContainer: {
59
+ position: 'relative',
60
+ flex: 1,
61
+ },
62
+
63
+ flagListContainer: {
64
+ position: 'absolute',
65
+ width: '100%',
66
+ top: dimensions.CONTROL_HEIGHT + 6,
67
+ left: -1,
68
+ zIndex: 3,
69
+ },
70
+
71
+ tweakInput: {
72
+ inputWrapper: {
73
+ paddingLeft: COUNTRY_SELECT_WIDTH,
74
+ },
75
+
76
+ label: {
77
+ marginLeft: COUNTRY_SELECT_WIDTH,
78
+ },
79
+ },
80
+
81
+ tweakCountryList: {},
82
+ };
83
+
84
+ export type PhoneInputStyles = ComponentStyles<typeof styles>;
@@ -1,194 +1,194 @@
1
- import { FC, useState, useRef, useMemo } from 'react';
2
- import clsx from 'clsx';
3
- import {
4
- getCountryCodeFromPhone,
5
- getFullPhone,
6
- getPhoneMask,
7
- getPhoneObjFromString,
8
- findCountryByCode,
9
- } from '../../helpers';
10
- import { useOnClickOutsideWithRef, useTheme, useTweakStyles } from '../../hooks';
11
- import { Flag } from '../Flag';
12
- import { Icon } from '../Icon';
13
- import { IInputProps, Input } from '../Input';
14
- import { PhoneInputStyles, styles } from './PhoneInput.styles';
15
- import { PhoneInputCountryList } from './PhoneInputCountryList';
16
- import { IPhoneInfo, IPhoneValue } from './types';
17
-
18
- export interface IPhoneInputProps
19
- extends Omit<IInputProps, 'value' | 'onChange' | 'type' | 'mask' | 'units' | 'placeholder'> {
20
- tweakStyles?: PhoneInputStyles;
21
- locale?: string;
22
- codeSearchPlaceholder?: string;
23
- noMatchesLabel?: string;
24
- value?: IPhoneValue;
25
- onChange: (
26
- phone: IPhoneValue,
27
- event: React.MouseEvent | KeyboardEvent | React.FormEvent<HTMLInputElement>,
28
- ) => void;
29
- }
30
-
31
- const DEFAULT_VALUE: IPhoneValue = { phoneNumber: '', dialCode: '' };
32
-
33
- export const PhoneInput: FC<IPhoneInputProps> = ({
34
- locale = 'ru',
35
- value = DEFAULT_VALUE,
36
- onChange,
37
- testId,
38
- isDisabled,
39
- isInvalid,
40
- isActive,
41
- tweakStyles,
42
- codeSearchPlaceholder = 'Поиск',
43
- noMatchesLabel = 'Ничего не найдено',
44
- ...inputProps
45
- }) => {
46
- const { classes, componentStyles } = useTheme('PhoneInput', styles, tweakStyles);
47
-
48
- const list = useRef<HTMLDivElement>(null);
49
- const inputWrapper = useRef<HTMLDivElement>(null);
50
- const inputRef = useRef<HTMLInputElement>(null);
51
- const [isListOpen, setIsListOpen] = useState(false);
52
- const [isFocused, setFocused] = useState(false);
53
-
54
- const phoneWithCode = getFullPhone(value);
55
-
56
- const countryCode = useMemo(
57
- () => value?.countryCode ?? getCountryCodeFromPhone(phoneWithCode),
58
- [value.dialCode, value.phoneNumber],
59
- );
60
-
61
- const handleClose = () => {
62
- setIsListOpen(false);
63
- };
64
-
65
- const handleChange = (inputValue: string, event: React.FormEvent<HTMLInputElement>) => {
66
- // if (event.type === 'change') - нужно из-за InputMask
67
- // Помимо change, еще могут приходить focus и blur, когда input пустой и тогда происходят неприятные сайд-эффекты
68
- if (event.type === 'change') {
69
- const newValue = inputValue.replace(/[^0-9]/g, '');
70
- let selectedCountryCode = countryCode;
71
-
72
- const selectedCountry = findCountryByCode(countryCode);
73
-
74
- // Проверяем введенный номер на соответствие с selectedCountry
75
- // Если не соответствует, то пытаемся найти countryCode, для которой
76
- // данный номер будет валидным (функция getPhoneObjFromString)
77
- if (selectedCountry !== undefined) {
78
- // Сначала проверяем, что введенный телефон удовлетворяет одному
79
- // из fullCode для выбранной страны
80
- const isSomeFullCodeValid = selectedCountry.fullCodes.some((fullCode) => {
81
- if (newValue.length >= fullCode.length) {
82
- return newValue.startsWith(fullCode);
83
- } else {
84
- return fullCode.startsWith(newValue);
85
- }
86
- });
87
-
88
- // После проверяем, что введенный телефон удовлетворяет dialCode для выбранной страны
89
- const isDialCodeValid = newValue.startsWith(selectedCountry.dialCode);
90
-
91
- if (!isSomeFullCodeValid || !isDialCodeValid) {
92
- selectedCountryCode = undefined;
93
- }
94
- }
95
-
96
- onChange(getPhoneObjFromString(newValue, selectedCountryCode), event);
97
- }
98
- };
99
-
100
- const handleSelect = (newPhoneInfo: IPhoneInfo, event: React.MouseEvent | KeyboardEvent) => {
101
- if (newPhoneInfo.countryCode !== countryCode) {
102
- onChange(
103
- {
104
- phoneNumber: '',
105
- dialCode: newPhoneInfo.dialCode,
106
- countryCode: newPhoneInfo.countryCode,
107
- },
108
- event,
109
- );
110
- }
111
- handleClose();
112
-
113
- const input = inputRef?.current;
114
- if (input !== null) {
115
- input.focus();
116
- }
117
- };
118
-
119
- const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {
120
- setFocused(true);
121
- if (inputProps.onFocus !== undefined) {
122
- inputProps?.onFocus(event);
123
- }
124
- };
125
-
126
- const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
127
- setFocused(false);
128
- if (inputProps.onBlur !== undefined) {
129
- inputProps?.onBlur(event);
130
- }
131
- };
132
-
133
- useOnClickOutsideWithRef(list, handleClose, inputWrapper);
134
-
135
- const tweakInputStyles = useTweakStyles(componentStyles, tweakStyles, 'tweakInput');
136
-
137
- const tweakCountryListStyles = useTweakStyles(componentStyles, tweakStyles, 'tweakCountryList');
138
-
139
- return (
140
- <div className={classes.root} data-testid={testId}>
141
- <div
142
- className={clsx(classes.countrySelectContainer, {
143
- [classes.disabledCountrySelect]: isDisabled,
144
- [classes.invalidBorder]: isInvalid,
145
- [classes.focusedBorder]: isActive || isListOpen || isFocused,
146
- })}
147
- ref={inputWrapper}
148
- onClick={!isDisabled ? () => setIsListOpen(!isListOpen) : undefined}
149
- >
150
- <div className={classes.flag}>
151
- <Flag countryCode={countryCode} />
152
- </div>
153
- <div
154
- className={clsx(classes.arrow, {
155
- [classes.up]: isListOpen,
156
- [classes.invalidArrow]: isInvalid,
157
- })}
158
- >
159
- <Icon type="chevron-down" />
160
- </div>
161
- </div>
162
-
163
- <Input
164
- onChange={handleChange}
165
- value={phoneWithCode}
166
- mask={getPhoneMask(countryCode)}
167
- // alwaysShowMask={false}
168
- ref={inputRef}
169
- isDisabled={isDisabled}
170
- isInvalid={isInvalid}
171
- isActive={isListOpen || isActive}
172
- testId={testId !== undefined ? `${testId}-input` : undefined}
173
- onFocus={handleFocus}
174
- onBlur={handleBlur}
175
- tweakStyles={tweakInputStyles}
176
- {...inputProps}
177
- />
178
-
179
- {isListOpen && (
180
- <div className={classes.flagListContainer} ref={list}>
181
- <PhoneInputCountryList
182
- selectedCountryCode={countryCode}
183
- placeholder={codeSearchPlaceholder}
184
- onChange={handleSelect}
185
- closeList={handleClose}
186
- locale={locale}
187
- tweakStyles={tweakCountryListStyles}
188
- noMatchesLabel={noMatchesLabel}
189
- />
190
- </div>
191
- )}
192
- </div>
193
- );
194
- };
1
+ import { FC, useState, useRef, useMemo } from 'react';
2
+ import clsx from 'clsx';
3
+ import {
4
+ getCountryCodeFromPhone,
5
+ getFullPhone,
6
+ getPhoneMask,
7
+ getPhoneObjFromString,
8
+ findCountryByCode,
9
+ } from '../../helpers';
10
+ import { useOnClickOutsideWithRef, useTheme, useTweakStyles } from '../../hooks';
11
+ import { Flag } from '../Flag';
12
+ import { Icon } from '../Icon';
13
+ import { IInputProps, Input } from '../Input';
14
+ import { PhoneInputStyles, styles } from './PhoneInput.styles';
15
+ import { PhoneInputCountryList } from './PhoneInputCountryList';
16
+ import { IPhoneInfo, IPhoneValue } from './types';
17
+
18
+ export interface IPhoneInputProps
19
+ extends Omit<IInputProps, 'value' | 'onChange' | 'type' | 'mask' | 'units' | 'placeholder'> {
20
+ tweakStyles?: PhoneInputStyles;
21
+ locale?: string;
22
+ codeSearchPlaceholder?: string;
23
+ noMatchesLabel?: string;
24
+ value?: IPhoneValue;
25
+ onChange: (
26
+ phone: IPhoneValue,
27
+ event: React.MouseEvent | KeyboardEvent | React.FormEvent<HTMLInputElement>,
28
+ ) => void;
29
+ }
30
+
31
+ const DEFAULT_VALUE: IPhoneValue = { phoneNumber: '', dialCode: '' };
32
+
33
+ export const PhoneInput: FC<IPhoneInputProps> = ({
34
+ locale = 'ru',
35
+ value = DEFAULT_VALUE,
36
+ onChange,
37
+ testId,
38
+ isDisabled,
39
+ isInvalid,
40
+ isActive,
41
+ tweakStyles,
42
+ codeSearchPlaceholder = 'Поиск',
43
+ noMatchesLabel = 'Ничего не найдено',
44
+ ...inputProps
45
+ }) => {
46
+ const { classes, componentStyles } = useTheme('PhoneInput', styles, tweakStyles);
47
+
48
+ const list = useRef<HTMLDivElement>(null);
49
+ const inputWrapper = useRef<HTMLDivElement>(null);
50
+ const inputRef = useRef<HTMLInputElement>(null);
51
+ const [isListOpen, setIsListOpen] = useState(false);
52
+ const [isFocused, setFocused] = useState(false);
53
+
54
+ const phoneWithCode = getFullPhone(value);
55
+
56
+ const countryCode = useMemo(
57
+ () => value?.countryCode ?? getCountryCodeFromPhone(phoneWithCode),
58
+ [value.dialCode, value.phoneNumber],
59
+ );
60
+
61
+ const handleClose = () => {
62
+ setIsListOpen(false);
63
+ };
64
+
65
+ const handleChange = (inputValue: string, event: React.FormEvent<HTMLInputElement>) => {
66
+ // if (event.type === 'change') - нужно из-за InputMask
67
+ // Помимо change, еще могут приходить focus и blur, когда input пустой и тогда происходят неприятные сайд-эффекты
68
+ if (event.type === 'change') {
69
+ const newValue = inputValue.replace(/[^0-9]/g, '');
70
+ let selectedCountryCode = countryCode;
71
+
72
+ const selectedCountry = findCountryByCode(countryCode);
73
+
74
+ // Проверяем введенный номер на соответствие с selectedCountry
75
+ // Если не соответствует, то пытаемся найти countryCode, для которой
76
+ // данный номер будет валидным (функция getPhoneObjFromString)
77
+ if (selectedCountry !== undefined) {
78
+ // Сначала проверяем, что введенный телефон удовлетворяет одному
79
+ // из fullCode для выбранной страны
80
+ const isSomeFullCodeValid = selectedCountry.fullCodes.some((fullCode) => {
81
+ if (newValue.length >= fullCode.length) {
82
+ return newValue.startsWith(fullCode);
83
+ } else {
84
+ return fullCode.startsWith(newValue);
85
+ }
86
+ });
87
+
88
+ // После проверяем, что введенный телефон удовлетворяет dialCode для выбранной страны
89
+ const isDialCodeValid = newValue.startsWith(selectedCountry.dialCode);
90
+
91
+ if (!isSomeFullCodeValid || !isDialCodeValid) {
92
+ selectedCountryCode = undefined;
93
+ }
94
+ }
95
+
96
+ onChange(getPhoneObjFromString(newValue, selectedCountryCode), event);
97
+ }
98
+ };
99
+
100
+ const handleSelect = (newPhoneInfo: IPhoneInfo, event: React.MouseEvent | KeyboardEvent) => {
101
+ if (newPhoneInfo.countryCode !== countryCode) {
102
+ onChange(
103
+ {
104
+ phoneNumber: '',
105
+ dialCode: newPhoneInfo.dialCode,
106
+ countryCode: newPhoneInfo.countryCode,
107
+ },
108
+ event,
109
+ );
110
+ }
111
+ handleClose();
112
+
113
+ const input = inputRef?.current;
114
+ if (input !== null) {
115
+ input.focus();
116
+ }
117
+ };
118
+
119
+ const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {
120
+ setFocused(true);
121
+ if (inputProps.onFocus !== undefined) {
122
+ inputProps?.onFocus(event);
123
+ }
124
+ };
125
+
126
+ const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
127
+ setFocused(false);
128
+ if (inputProps.onBlur !== undefined) {
129
+ inputProps?.onBlur(event);
130
+ }
131
+ };
132
+
133
+ useOnClickOutsideWithRef(list, handleClose, inputWrapper);
134
+
135
+ const tweakInputStyles = useTweakStyles(componentStyles, tweakStyles, 'tweakInput');
136
+
137
+ const tweakCountryListStyles = useTweakStyles(componentStyles, tweakStyles, 'tweakCountryList');
138
+
139
+ return (
140
+ <div className={classes.root} data-testid={testId}>
141
+ <div
142
+ className={clsx(classes.countrySelectContainer, {
143
+ [classes.disabledCountrySelect]: isDisabled,
144
+ [classes.invalidBorder]: isInvalid,
145
+ [classes.focusedBorder]: isActive || isListOpen || isFocused,
146
+ })}
147
+ ref={inputWrapper}
148
+ onClick={!isDisabled ? () => setIsListOpen(!isListOpen) : undefined}
149
+ >
150
+ <div className={classes.flag}>
151
+ <Flag countryCode={countryCode} />
152
+ </div>
153
+ <div
154
+ className={clsx(classes.arrow, {
155
+ [classes.up]: isListOpen,
156
+ [classes.invalidArrow]: isInvalid,
157
+ })}
158
+ >
159
+ <Icon type="chevron-down" />
160
+ </div>
161
+ </div>
162
+
163
+ <Input
164
+ onChange={handleChange}
165
+ value={phoneWithCode}
166
+ mask={getPhoneMask(countryCode)}
167
+ // alwaysShowMask={false}
168
+ ref={inputRef}
169
+ isDisabled={isDisabled}
170
+ isInvalid={isInvalid}
171
+ isActive={isListOpen || isActive}
172
+ testId={testId !== undefined ? `${testId}-input` : undefined}
173
+ onFocus={handleFocus}
174
+ onBlur={handleBlur}
175
+ tweakStyles={tweakInputStyles}
176
+ {...inputProps}
177
+ />
178
+
179
+ {isListOpen && (
180
+ <div className={classes.flagListContainer} ref={list}>
181
+ <PhoneInputCountryList
182
+ selectedCountryCode={countryCode}
183
+ placeholder={codeSearchPlaceholder}
184
+ onChange={handleSelect}
185
+ closeList={handleClose}
186
+ locale={locale}
187
+ tweakStyles={tweakCountryListStyles}
188
+ noMatchesLabel={noMatchesLabel}
189
+ />
190
+ </div>
191
+ )}
192
+ </div>
193
+ );
194
+ };
@@ -1,21 +1,21 @@
1
- import { ComponentStory, ComponentMeta } from '@storybook/react';
2
- import PhoneInputCountryList from './PhoneInputCountryList';
3
-
4
- export default {
5
- title: 'Inputs/PhoneInput/PhoneInputCountryList',
6
- component: PhoneInputCountryList,
7
- args: {
8
- locale: 'ru',
9
- placeholder: 'Поиск',
10
- noMatchesLabel: 'Ничего не найдено',
11
- },
12
- parameters: {
13
- controls: {
14
- exclude: ['data', 'tweakStyles', 'testId'],
15
- },
16
- },
17
- } as ComponentMeta<typeof PhoneInputCountryList>;
18
-
19
- export const Default: ComponentStory<typeof PhoneInputCountryList> = (args) => (
20
- <PhoneInputCountryList {...args} />
21
- );
1
+ import { ComponentStory, ComponentMeta } from '@storybook/react';
2
+ import PhoneInputCountryList from './PhoneInputCountryList';
3
+
4
+ export default {
5
+ title: 'Inputs/PhoneInput/PhoneInputCountryList',
6
+ component: PhoneInputCountryList,
7
+ args: {
8
+ locale: 'ru',
9
+ placeholder: 'Поиск',
10
+ noMatchesLabel: 'Ничего не найдено',
11
+ },
12
+ parameters: {
13
+ controls: {
14
+ exclude: ['data', 'tweakStyles', 'testId'],
15
+ },
16
+ },
17
+ } as ComponentMeta<typeof PhoneInputCountryList>;
18
+
19
+ export const Default: ComponentStory<typeof PhoneInputCountryList> = (args) => (
20
+ <PhoneInputCountryList {...args} />
21
+ );