@true-engineering/true-react-common-ui-kit 2.0.1 → 2.1.1

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 (275) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +17 -0
  3. package/dist/components/Button/Button.d.ts +36 -1
  4. package/dist/components/Checkbox/Checkbox.d.ts +15 -2
  5. package/dist/components/DatePicker/DatePicker.d.ts +4 -5
  6. package/dist/components/DatePicker/types.d.ts +1 -1
  7. package/dist/components/FiltersPane/FilterMultiSelect/FilterMultiSelect.d.ts +1 -1
  8. package/dist/components/FiltersPane/FilterSelect/FilterSelect.d.ts +13 -1
  9. package/dist/components/FiltersPane/FilterWithDates/FilterWithDates.d.ts +1 -1
  10. package/dist/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.d.ts +1 -1
  11. package/dist/components/FiltersPane/FilterWrapper/FilterWrapper.d.ts +1 -1
  12. package/dist/components/FiltersPane/FiltersPane.d.ts +2 -2
  13. package/dist/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.d.ts +1 -1
  14. package/dist/components/FiltersPane/types.d.ts +1 -1
  15. package/dist/components/Flag/augment.d.ts +1 -1
  16. package/dist/components/FlexibleTable/FlexibleTable.d.ts +1 -1
  17. package/dist/components/FlexibleTable/TableRow.d.ts +1 -1
  18. package/dist/components/Icon/Icon.d.ts +2 -2
  19. package/dist/components/Icon/complexIcons/augment.d.ts +1 -1
  20. package/dist/components/Input/Input.d.ts +18 -1
  21. package/dist/components/MoreMenu/MoreMenu.d.ts +3 -0
  22. package/dist/components/MultiSelect/MultiSelectInput/MultiSelectInput.d.ts +1 -1
  23. package/dist/components/MultiSelectList/MultiSelectList.d.ts +1 -1
  24. package/dist/components/Notification/Notification.d.ts +6 -0
  25. package/dist/components/PhoneInput/PhoneInput.d.ts +1 -1
  26. package/dist/components/RadioButton/RadioButton.d.ts +4 -3
  27. package/dist/components/Select/Select.d.ts +3 -3
  28. package/dist/components/Switch/Switch.d.ts +10 -4
  29. package/dist/components/TextWithTooltip/TextWithTooltip.d.ts +1 -1
  30. package/dist/components/ThemedPreloader/ThemedPreloader.d.ts +3 -0
  31. package/dist/components/Toaster/Toaster.d.ts +13 -0
  32. package/dist/components/Tooltip/Tooltip.d.ts +6 -0
  33. package/dist/helpers/snippets.d.ts +1 -1
  34. package/dist/helpers/utils.d.ts +15 -1
  35. package/dist/true-react-common-ui-kit.js +3873 -3875
  36. package/dist/true-react-common-ui-kit.js.map +1 -1
  37. package/dist/true-react-common-ui-kit.umd.cjs +3893 -3895
  38. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  39. package/dist/types.d.ts +3 -0
  40. package/dist/vite-env.d.ts +1 -1
  41. package/package.json +2 -1
  42. package/src/components/AccountInfo/AccountInfo.stories.tsx +32 -35
  43. package/src/components/AccountInfo/AccountInfo.styles.ts +55 -55
  44. package/src/components/AccountInfo/AccountInfo.tsx +77 -106
  45. package/src/components/AccountInfo/index.ts +2 -2
  46. package/src/components/AddButton/AddButton.stories.tsx +21 -21
  47. package/src/components/AddButton/AddButton.styles.ts +34 -34
  48. package/src/components/AddButton/AddButton.tsx +48 -49
  49. package/src/components/AddButton/index.ts +2 -2
  50. package/src/components/Button/Button.stories.tsx +52 -61
  51. package/src/components/Button/Button.styles.ts +196 -196
  52. package/src/components/Button/Button.tsx +187 -207
  53. package/src/components/Button/index.ts +2 -2
  54. package/src/components/Checkbox/Checkbox.stories.tsx +32 -35
  55. package/src/components/Checkbox/Checkbox.styles.ts +62 -62
  56. package/src/components/Checkbox/Checkbox.tsx +100 -106
  57. package/src/components/Checkbox/index.ts +2 -2
  58. package/src/components/CloseButton/CloseButton.styles.ts +34 -34
  59. package/src/components/CloseButton/CloseButton.tsx +35 -37
  60. package/src/components/CloseButton/index.ts +2 -2
  61. package/src/components/Colors/Colors.stories.tsx +7 -7
  62. package/src/components/Colors/Colors.styles.ts +38 -38
  63. package/src/components/Colors/Colors.tsx +26 -34
  64. package/src/components/Colors/index.ts +2 -2
  65. package/src/components/CssBaseline/CssBaseline.styles.ts +15 -15
  66. package/src/components/CssBaseline/CssBaseline.tsx +15 -17
  67. package/src/components/CssBaseline/index.ts +2 -2
  68. package/src/components/DateInput/DateInput.stories.tsx +61 -67
  69. package/src/components/DateInput/DateInput.styles.ts +14 -14
  70. package/src/components/DateInput/DateInput.tsx +82 -101
  71. package/src/components/DateInput/constants.ts +2 -2
  72. package/src/components/DateInput/index.ts +3 -3
  73. package/src/components/DatePicker/DatePicker.stories.tsx +87 -90
  74. package/src/components/DatePicker/DatePicker.styles.ts +44 -44
  75. package/src/components/DatePicker/DatePicker.tsx +322 -354
  76. package/src/components/DatePicker/DatePickerHeader/DatePickerHeader.styles.ts +84 -84
  77. package/src/components/DatePicker/DatePickerHeader/DatePickerHeader.tsx +79 -80
  78. package/src/components/DatePicker/DatePickerHeader/index.ts +2 -2
  79. package/src/components/DatePicker/constants.ts +1 -1
  80. package/src/components/DatePicker/helpers.ts +19 -24
  81. package/src/components/DatePicker/index.ts +3 -3
  82. package/src/components/DatePicker/types.ts +45 -40
  83. package/src/components/Description/Description.stories.tsx +27 -29
  84. package/src/components/Description/Description.styles.ts +31 -31
  85. package/src/components/Description/Description.tsx +60 -69
  86. package/src/components/Description/index.ts +2 -2
  87. package/src/components/FiltersPane/FilterInterval/FilterInterval.styles.ts +64 -64
  88. package/src/components/FiltersPane/FilterInterval/FilterInterval.tsx +143 -162
  89. package/src/components/FiltersPane/FilterInterval/index.ts +1 -1
  90. package/src/components/FiltersPane/FilterMultiSelect/FilterMultiSelect.tsx +10 -14
  91. package/src/components/FiltersPane/FilterMultiSelect/index.ts +1 -1
  92. package/src/components/FiltersPane/FilterSelect/FilterSelect.styles.ts +143 -144
  93. package/src/components/FiltersPane/FilterSelect/FilterSelect.tsx +347 -397
  94. package/src/components/FiltersPane/FilterSelect/index.ts +1 -1
  95. package/src/components/FiltersPane/FilterSelect/locales.ts +37 -37
  96. package/src/components/FiltersPane/FilterValueView/FilterValueView.styles.tsx +15 -15
  97. package/src/components/FiltersPane/FilterValueView/FilterValueView.tsx +166 -186
  98. package/src/components/FiltersPane/FilterValueView/index.tsx +1 -1
  99. package/src/components/FiltersPane/FilterWithDates/FilterWithDates.styles.ts +60 -60
  100. package/src/components/FiltersPane/FilterWithDates/FilterWithDates.tsx +183 -210
  101. package/src/components/FiltersPane/FilterWithDates/index.ts +1 -1
  102. package/src/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.styles.ts +17 -17
  103. package/src/components/FiltersPane/FilterWithPeriod/FilterWithPeriod.tsx +198 -231
  104. package/src/components/FiltersPane/FilterWithPeriod/index.ts +1 -1
  105. package/src/components/FiltersPane/FilterWrapper/FilterWrapper.styles.ts +110 -110
  106. package/src/components/FiltersPane/FilterWrapper/FilterWrapper.tsx +346 -360
  107. package/src/components/FiltersPane/FilterWrapper/index.ts +1 -1
  108. package/src/components/FiltersPane/FiltersPane.stories.tsx +295 -308
  109. package/src/components/FiltersPane/FiltersPane.styles.ts +71 -71
  110. package/src/components/FiltersPane/FiltersPane.tsx +151 -193
  111. package/src/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.styles.ts +109 -109
  112. package/src/components/FiltersPane/FiltersPaneSearch/FiltersPaneSearch.tsx +155 -175
  113. package/src/components/FiltersPane/FiltersPaneSearch/index.ts +1 -1
  114. package/src/components/FiltersPane/index.ts +20 -20
  115. package/src/components/FiltersPane/locales.ts +107 -107
  116. package/src/components/FiltersPane/types.ts +112 -126
  117. package/src/components/Flag/Flag.stories.tsx +29 -29
  118. package/src/components/Flag/Flag.styles.ts +18 -18
  119. package/src/components/Flag/Flag.tsx +27 -28
  120. package/src/components/Flag/augment.d.ts +1 -1
  121. package/src/components/Flag/index.ts +2 -2
  122. package/src/components/FlexibleTable/FlexibleTable.stories.tsx +3 -5
  123. package/src/components/FlexibleTable/FlexibleTable.styles.ts +131 -131
  124. package/src/components/FlexibleTable/FlexibleTable.tsx +205 -243
  125. package/src/components/FlexibleTable/TableRow.tsx +152 -171
  126. package/src/components/FlexibleTable/TableValue.tsx +75 -81
  127. package/src/components/FlexibleTable/fixture-test.ts +254 -254
  128. package/src/components/FlexibleTable/index.ts +3 -3
  129. package/src/components/FlexibleTable/types.ts +52 -58
  130. package/src/components/Icon/ComplexIconBoilerplate.tsx +17 -17
  131. package/src/components/Icon/Icon.stories.tsx +85 -88
  132. package/src/components/Icon/Icon.styles.ts +10 -10
  133. package/src/components/Icon/Icon.tsx +32 -34
  134. package/src/components/Icon/IconBoilerplate.tsx +42 -42
  135. package/src/components/Icon/complexIcons/augment.d.ts +1 -1
  136. package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
  137. package/src/components/Icon/complexIcons/icons.ts +7 -7
  138. package/src/components/Icon/complexIcons/index.ts +1 -1
  139. package/src/components/Icon/icons/icons.ts +838 -838
  140. package/src/components/Icon/icons/index.ts +1 -1
  141. package/src/components/Icon/index.ts +4 -4
  142. package/src/components/IncrementInput/ChangeButton.tsx +33 -34
  143. package/src/components/IncrementInput/IncrementInput.stories.tsx +31 -34
  144. package/src/components/IncrementInput/IncrementInput.styles.ts +77 -77
  145. package/src/components/IncrementInput/IncrementInput.tsx +79 -95
  146. package/src/components/IncrementInput/index.ts +2 -2
  147. package/src/components/Input/Input.stories.tsx +86 -92
  148. package/src/components/Input/Input.styles.ts +307 -307
  149. package/src/components/Input/Input.tsx +306 -321
  150. package/src/components/Input/index.ts +2 -2
  151. package/src/components/List/List.stories.tsx +62 -62
  152. package/src/components/List/List.styles.ts +52 -52
  153. package/src/components/List/List.tsx +61 -82
  154. package/src/components/List/index.ts +2 -2
  155. package/src/components/Modal/Modal.stories.tsx +105 -113
  156. package/src/components/Modal/Modal.styles.ts +305 -308
  157. package/src/components/Modal/Modal.tsx +181 -210
  158. package/src/components/Modal/index.ts +2 -2
  159. package/src/components/MoreMenu/MoreMenu.stories.tsx +46 -46
  160. package/src/components/MoreMenu/MoreMenu.styles.ts +70 -70
  161. package/src/components/MoreMenu/MoreMenu.tsx +89 -102
  162. package/src/components/MoreMenu/index.ts +2 -2
  163. package/src/components/MultiSelect/MultiSelect.stories.tsx +46 -46
  164. package/src/components/MultiSelect/MultiSelect.styles.ts +55 -55
  165. package/src/components/MultiSelect/MultiSelect.tsx +89 -98
  166. package/src/components/MultiSelect/MultiSelectInput/MultiSelectInput.styles.ts +73 -73
  167. package/src/components/MultiSelect/MultiSelectInput/MultiSelectInput.tsx +51 -62
  168. package/src/components/MultiSelect/MultiSelectInput/index.ts +1 -1
  169. package/src/components/MultiSelect/index.ts +3 -3
  170. package/src/components/MultiSelectList/MultiSelectList.styles.ts +124 -125
  171. package/src/components/MultiSelectList/MultiSelectList.tsx +451 -519
  172. package/src/components/MultiSelectList/index.ts +2 -2
  173. package/src/components/MultiSelectList/locales.ts +37 -37
  174. package/src/components/Notification/Notification.stories.tsx +46 -51
  175. package/src/components/Notification/Notification.styles.ts +50 -50
  176. package/src/components/Notification/Notification.tsx +75 -84
  177. package/src/components/Notification/index.ts +2 -2
  178. package/src/components/NumberInput/NumberInput.stories.tsx +35 -36
  179. package/src/components/NumberInput/NumberInput.tsx +133 -154
  180. package/src/components/NumberInput/helpers.ts +85 -87
  181. package/src/components/NumberInput/index.ts +1 -1
  182. package/src/components/PhoneInput/PhoneInput.stories.tsx +70 -71
  183. package/src/components/PhoneInput/PhoneInput.styles.ts +84 -84
  184. package/src/components/PhoneInput/PhoneInput.tsx +194 -223
  185. package/src/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.stories.tsx +21 -21
  186. package/src/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.styles.ts +100 -100
  187. package/src/components/PhoneInput/PhoneInputCountryList/PhoneInputCountryList.tsx +147 -171
  188. package/src/components/PhoneInput/PhoneInputCountryList/index.ts +2 -2
  189. package/src/components/PhoneInput/index.ts +6 -6
  190. package/src/components/PhoneInput/phone-info.ts +2147 -2167
  191. package/src/components/PhoneInput/types.ts +16 -16
  192. package/src/components/RadioButton/RadioButton.stories.tsx +46 -46
  193. package/src/components/RadioButton/RadioButton.styles.ts +37 -37
  194. package/src/components/RadioButton/RadioButton.tsx +54 -56
  195. package/src/components/RadioButton/index.ts +2 -2
  196. package/src/components/ScrollIntoViewIfNeeded/ScrollIntoViewIfNeeded.ts +61 -66
  197. package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
  198. package/src/components/SearchInput/SearchInput.stories.tsx +23 -24
  199. package/src/components/SearchInput/SearchInput.styles.ts +50 -50
  200. package/src/components/SearchInput/SearchInput.tsx +49 -63
  201. package/src/components/SearchInput/index.ts +2 -2
  202. package/src/components/Select/MultiSelect.stories.tsx +240 -263
  203. package/src/components/Select/Select.stories.tsx +235 -258
  204. package/src/components/Select/Select.styles.ts +96 -96
  205. package/src/components/Select/Select.tsx +49 -108
  206. package/src/components/Select/SelectList/SelectList.styles.ts +72 -72
  207. package/src/components/Select/SelectList/SelectList.tsx +152 -165
  208. package/src/components/Select/SelectList/index.ts +1 -1
  209. package/src/components/Select/SelectListItem/SelectListItem.styles.ts +14 -14
  210. package/src/components/Select/SelectListItem/SelectListItem.tsx +67 -73
  211. package/src/components/Select/constants.ts +2 -2
  212. package/src/components/Select/helpers.ts +26 -29
  213. package/src/components/Select/index.ts +4 -4
  214. package/src/components/Select/types.ts +1 -1
  215. package/src/components/SmartInput/SmartInput.stories.tsx +50 -63
  216. package/src/components/SmartInput/SmartInput.tsx +147 -180
  217. package/src/components/SmartInput/helpers.ts +85 -85
  218. package/src/components/SmartInput/index.ts +1 -1
  219. package/src/components/Switch/Switch.stories.tsx +40 -40
  220. package/src/components/Switch/Switch.styles.ts +75 -75
  221. package/src/components/Switch/Switch.tsx +82 -89
  222. package/src/components/Switch/index.ts +2 -2
  223. package/src/components/TextArea/TextArea.stories.tsx +35 -35
  224. package/src/components/TextArea/TextArea.styles.ts +153 -153
  225. package/src/components/TextArea/TextArea.tsx +165 -178
  226. package/src/components/TextArea/index.ts +2 -2
  227. package/src/components/TextWithInfo/TextWithInfo.stories.tsx +53 -53
  228. package/src/components/TextWithInfo/TextWithInfo.styles.ts +60 -60
  229. package/src/components/TextWithInfo/TextWithInfo.tsx +60 -67
  230. package/src/components/TextWithInfo/index.ts +2 -2
  231. package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
  232. package/src/components/TextWithTooltip/TextWithTooltip.styles.ts +19 -19
  233. package/src/components/TextWithTooltip/TextWithTooltip.tsx +143 -163
  234. package/src/components/TextWithTooltip/index.ts +2 -2
  235. package/src/components/ThemedPreloader/ThemedPreloader.stories.tsx +41 -41
  236. package/src/components/ThemedPreloader/ThemedPreloader.styles.ts +21 -21
  237. package/src/components/ThemedPreloader/ThemedPreloader.tsx +50 -56
  238. package/src/components/ThemedPreloader/components/DefaultPreloader/DefaultPreloader.tsx +29 -34
  239. package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
  240. package/src/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.styles.ts +54 -54
  241. package/src/components/ThemedPreloader/components/DotsPreloader/DotsPreloader.tsx +18 -18
  242. package/src/components/ThemedPreloader/components/DotsPreloader/index.ts +2 -2
  243. package/src/components/ThemedPreloader/components/SvgPreloader/SvgPreloader.styles.ts +11 -11
  244. package/src/components/ThemedPreloader/components/SvgPreloader/SvgPreloader.tsx +25 -32
  245. package/src/components/ThemedPreloader/components/SvgPreloader/index.ts +2 -2
  246. package/src/components/ThemedPreloader/components/index.ts +2 -2
  247. package/src/components/ThemedPreloader/index.ts +2 -2
  248. package/src/components/Toaster/Toaster.stories.tsx +30 -34
  249. package/src/components/Toaster/Toaster.styles.ts +59 -59
  250. package/src/components/Toaster/Toaster.tsx +105 -113
  251. package/src/components/Toaster/index.ts +2 -2
  252. package/src/components/Tooltip/Tooltip.stories.tsx +19 -21
  253. package/src/components/Tooltip/Tooltip.styles.ts +45 -45
  254. package/src/components/Tooltip/Tooltip.tsx +35 -40
  255. package/src/components/Tooltip/index.ts +3 -3
  256. package/src/components/Tooltip/types.ts +1 -1
  257. package/src/components/index.ts +36 -36
  258. package/src/helpers/colors.ts +3 -2
  259. package/src/helpers/dateHelpers/date-helpers.ts +9 -9
  260. package/src/helpers/index.ts +4 -4
  261. package/src/helpers/phone.ts +87 -106
  262. package/src/helpers/popper-helpers.ts +17 -17
  263. package/src/helpers/snippets.tsx +5 -5
  264. package/src/helpers/utils.ts +231 -261
  265. package/src/hooks/index.ts +6 -6
  266. package/src/hooks/use-did-mount-effect.ts +18 -21
  267. package/src/hooks/use-dropdown.ts +82 -85
  268. package/src/hooks/use-is-mounted.ts +15 -15
  269. package/src/hooks/use-on-click-outside.ts +77 -92
  270. package/src/hooks/use-theme.ts +32 -36
  271. package/src/hooks/use-tweak-styles.ts +13 -14
  272. package/src/index.ts +6 -6
  273. package/src/theme.ts +149 -155
  274. package/src/types.ts +98 -105
  275. package/src/vite-env.d.ts +1 -1
@@ -1,261 +1,231 @@
1
- import { IDataAttributes } from '../types';
2
- import { HTMLAttributes, KeyboardEvent, MouseEvent } from 'react';
3
-
4
- export const transformToKebab = (string: string): string => {
5
- let result = '';
6
- string.split('').forEach((char) => {
7
- if (char.toLowerCase() === char) {
8
- result += char;
9
- } else {
10
- result += `-${char.toLowerCase()}`;
11
- }
12
- });
13
-
14
- return result;
15
- };
16
-
17
- export const hasExactParent = (element: Element, parent: Element): boolean => {
18
- if (element === parent) {
19
- return true; // Found the exact parent
20
- }
21
-
22
- const parentNode = getParentNode(element);
23
-
24
- if (parentNode === element) {
25
- return false; // Reached the top-level HTML element or Shadow DOM host
26
- }
27
-
28
- return hasExactParent(parentNode, parent);
29
- };
30
-
31
- export const getParentNode = (
32
- element: Element | ShadowRoot | Document,
33
- ): Element =>
34
- element.nodeName === 'HTML' || element === document
35
- ? (element as Element)
36
- : (element.parentNode as Element) ?? (element as ShadowRoot).host;
37
-
38
- export const getStyleComputedProperty = (
39
- element: Element,
40
- ): Partial<CSSStyleDeclaration> =>
41
- element.nodeType !== 1 ? {} : getComputedStyle(element, null);
42
-
43
- export const getScrollParent = (element: Element | Document): Element => {
44
- if (!element) {
45
- return document.body;
46
- }
47
-
48
- switch (element.nodeName) {
49
- case 'HTML':
50
- case 'BODY':
51
- return (element as Element).ownerDocument.body;
52
- case '#document':
53
- return (element as Document).body;
54
- }
55
-
56
- const { overflow, overflowX, overflowY } =
57
- getStyleComputedProperty(element as Element) ?? {};
58
- if (
59
- /(auto|scroll|overlay)/.test(
60
- (overflow ?? '') + (overflowY ?? '') + (overflowX ?? ''),
61
- )
62
- ) {
63
- return element as Element;
64
- }
65
- return getScrollParent(getParentNode(element as Element));
66
- };
67
-
68
- export const isElementOffScreen = (
69
- element: HTMLElement,
70
- input?: HTMLElement,
71
- ): boolean => {
72
- const el = element;
73
- const scrollParent = getScrollParent(element);
74
-
75
- const { scrollHeight: scrollHeightWithElement } = scrollParent;
76
- el.hidden = true;
77
- const { scrollHeight: scrollHeightWithoutElement } = scrollParent;
78
- el.hidden = false;
79
-
80
- const isOffscreen = scrollHeightWithElement !== scrollHeightWithoutElement;
81
-
82
- if (isOffscreen && input !== undefined) {
83
- const elRect = el.getBoundingClientRect();
84
- const scrollParentRect = scrollParent.getBoundingClientRect();
85
- const topOffset = elRect.top - scrollParentRect.top;
86
- if (input.clientHeight + el.clientHeight > topOffset) {
87
- return false;
88
- }
89
- }
90
-
91
- return isOffscreen;
92
- };
93
-
94
- export const getNumberInRange = (
95
- value: number,
96
- min = -Infinity,
97
- max = Infinity,
98
- ): number => Math.min(max, Math.max(min, value));
99
-
100
- const DEFAULT_THOUSANDS_SEPARATOR = '\u2009';
101
-
102
- export const formatStringNumber = (
103
- val?: string,
104
- separator = DEFAULT_THOUSANDS_SEPARATOR,
105
- ): string => {
106
- if (val === undefined) {
107
- return '';
108
- }
109
- const parts = val.split('.');
110
-
111
- parts[0] = parts[0]
112
- // убрать лидирующие нули
113
- .replace(/^0+(?=\d)/, '')
114
- // проставить сепараторы тысяч
115
- .replace(/\B(?=(\d{3})+(?!\d))/g, separator);
116
- return (parts[1] ?? '').length > 0 ? parts.join('.') : parts[0];
117
- };
118
-
119
- export const formatNumber = (
120
- val?: number,
121
- separator = DEFAULT_THOUSANDS_SEPARATOR,
122
- ): string => {
123
- if (val === undefined || isNaN(val)) {
124
- return '';
125
- }
126
- return formatStringNumber(String(val), separator);
127
- };
128
-
129
- export const removeStringFormat = (val?: string): string =>
130
- (val ?? '').replace(',', '.').replace(/\s/g, '');
131
-
132
- export const stringToNumber = (val?: string): number | undefined => {
133
- const trimmed = removeStringFormat(val);
134
- if (trimmed === '') {
135
- return undefined;
136
- }
137
- const num = Number(trimmed);
138
- return isNaN(num) ? undefined : num;
139
- };
140
-
141
- export const setCaretPosition = (
142
- elem: HTMLInputElement,
143
- caretPos: number | null,
144
- ): void => {
145
- if (caretPos === null || elem === null) {
146
- return;
147
- }
148
- if (elem.selectionStart) {
149
- elem.focus();
150
- elem.setSelectionRange(caretPos, caretPos);
151
- } else {
152
- elem.focus();
153
- }
154
- };
155
-
156
- export const isSpaceChar = (char?: string): boolean =>
157
- char !== undefined && char.match(/\s/) !== null;
158
-
159
- export const isInt = (n: number): boolean => n % 1 === 0;
160
-
161
- export const getNumberLength = (n?: number): number =>
162
- n === undefined || isNaN(n) ? 0 : n.toString().length;
163
-
164
- // TODO: Не должен проверять строку, т.к. под это есть отдельный хелпер
165
- /**
166
- * Проверяет, что `val` не `null`, не `undefined` и не пустая строка
167
- */
168
- export const isNotEmpty = <T>(val: T | null | undefined): val is T =>
169
- typeof val === 'string'
170
- ? val.trim() !== ''
171
- : val !== null && val !== undefined;
172
-
173
- /**
174
- * Проверяет, что переданное значение `null` или `undefined`
175
- */
176
- export const isEmpty = <T>(
177
- val: T | null | undefined,
178
- ): val is null | undefined => val === null || val === undefined;
179
-
180
- /**
181
- * Проверяет, что передана непустая строка
182
- */
183
- export const isStringNotEmpty = <T extends string>(
184
- value: T | undefined | null,
185
- ): value is T => (value ?? '').trim() !== '';
186
-
187
- export const trimStringToMaxLength = (val: string, maxLength: number) =>
188
- val.length > maxLength ? val.slice(0, maxLength) : val;
189
-
190
- export const addDataAttributes = (
191
- data: IDataAttributes = {},
192
- ): IDataAttributes =>
193
- Object.fromEntries(
194
- Object.entries(data).map(([key, value]) =>
195
- isNotEmpty(value) ? [`data-${transformToKebab(key)}`, value] : [],
196
- ),
197
- );
198
-
199
- export const addDataTestId = (
200
- ...args: Parameters<typeof getTestId>
201
- ): { 'data-testid': string } | undefined => {
202
- const testId = getTestId(...args);
203
- return isNotEmpty(testId) ? { 'data-testid': testId } : undefined;
204
- };
205
-
206
- export const getTestId = (
207
- testId: string | undefined,
208
- postfix?: string | number,
209
- ): string | undefined => {
210
- if (!isNotEmpty(testId)) {
211
- return undefined;
212
- }
213
- return isNotEmpty(postfix) ? `${testId}-${postfix}` : testId;
214
- };
215
-
216
- export const getSelectKeyHandler =
217
- (cb: (e: KeyboardEvent) => void): ((e: KeyboardEvent) => void) =>
218
- (e) => {
219
- if (e.code === 'Enter' || e.code === 'NumpadEnter') {
220
- cb(e);
221
- }
222
- };
223
-
224
- export const addClickHandler = (
225
- cb?: (e: MouseEvent | KeyboardEvent) => void,
226
- hasAction = true,
227
- ): HTMLAttributes<unknown> =>
228
- hasAction && isNotEmpty(cb)
229
- ? {
230
- tabIndex: 0,
231
- onClick: cb as (e: MouseEvent) => void,
232
- onKeyDown: getSelectKeyHandler(cb),
233
- }
234
- : {
235
- tabIndex: -1,
236
- };
237
-
238
- /**
239
- * Позволяет создать текстовый фильтр для набора items
240
- * @param getter - функция возвращающая набор строковых значений из каждого item,
241
- * по которым должен осуществляться поиск
242
- */
243
- export const createFilter =
244
- <T>(
245
- getter: (item: T) => Array<string | undefined>,
246
- compareFn?: (item: string, query: string) => boolean,
247
- ): ((items: T[], query: string) => T[]) =>
248
- (items, query) =>
249
- items.filter((item) => {
250
- const possibleValues = getter(item).reduce(
251
- (acc, cur) => [
252
- ...acc,
253
- ...(isStringNotEmpty(cur) ? [cur.toLowerCase()] : []),
254
- ],
255
- [] as string[],
256
- );
257
- const queryString = query.toLowerCase().trim();
258
- return possibleValues.some((v) =>
259
- (compareFn ?? (() => v?.includes(queryString)))(v, queryString),
260
- );
261
- });
1
+ import { HTMLAttributes, KeyboardEvent, MouseEvent } from 'react';
2
+ import { IDataAttributes } from '../types';
3
+
4
+ export const transformToKebab = (string: string): string => {
5
+ let result = '';
6
+ string.split('').forEach((char) => {
7
+ if (char.toLowerCase() === char) {
8
+ result += char;
9
+ } else {
10
+ result += `-${char.toLowerCase()}`;
11
+ }
12
+ });
13
+
14
+ return result;
15
+ };
16
+
17
+ export const hasExactParent = (element: Element, parent: Element): boolean => {
18
+ if (element === parent) {
19
+ return true; // Found the exact parent
20
+ }
21
+
22
+ const parentNode = getParentNode(element);
23
+
24
+ if (parentNode === element) {
25
+ return false; // Reached the top-level HTML element or Shadow DOM host
26
+ }
27
+
28
+ return hasExactParent(parentNode, parent);
29
+ };
30
+
31
+ export const getParentNode = (element: Element | ShadowRoot | Document): Element =>
32
+ element.nodeName === 'HTML' || element === document
33
+ ? (element as Element)
34
+ : (element.parentNode as Element) ?? (element as ShadowRoot).host;
35
+
36
+ export const getStyleComputedProperty = (element: Element): Partial<CSSStyleDeclaration> =>
37
+ element.nodeType !== 1 ? {} : getComputedStyle(element, null);
38
+
39
+ export const getScrollParent = (element: Element | Document): Element => {
40
+ if (!element) {
41
+ return document.body;
42
+ }
43
+
44
+ switch (element.nodeName) {
45
+ case 'HTML':
46
+ case 'BODY':
47
+ return (element as Element).ownerDocument.body;
48
+ case '#document':
49
+ return (element as Document).body;
50
+ }
51
+
52
+ const { overflow, overflowX, overflowY } = getStyleComputedProperty(element as Element) ?? {};
53
+ if (/(auto|scroll|overlay)/.test((overflow ?? '') + (overflowY ?? '') + (overflowX ?? ''))) {
54
+ return element as Element;
55
+ }
56
+ return getScrollParent(getParentNode(element as Element));
57
+ };
58
+
59
+ export const isElementOffScreen = (element: HTMLElement, input?: HTMLElement): boolean => {
60
+ const el = element;
61
+ const scrollParent = getScrollParent(element);
62
+
63
+ const { scrollHeight: scrollHeightWithElement } = scrollParent;
64
+ el.hidden = true;
65
+ const { scrollHeight: scrollHeightWithoutElement } = scrollParent;
66
+ el.hidden = false;
67
+
68
+ const isOffscreen = scrollHeightWithElement !== scrollHeightWithoutElement;
69
+
70
+ if (isOffscreen && input !== undefined) {
71
+ const elRect = el.getBoundingClientRect();
72
+ const scrollParentRect = scrollParent.getBoundingClientRect();
73
+ const topOffset = elRect.top - scrollParentRect.top;
74
+ if (input.clientHeight + el.clientHeight > topOffset) {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ return isOffscreen;
80
+ };
81
+
82
+ export const getNumberInRange = (value: number, min = -Infinity, max = Infinity): number =>
83
+ Math.min(max, Math.max(min, value));
84
+
85
+ const DEFAULT_THOUSANDS_SEPARATOR = '\u2009';
86
+
87
+ export const formatStringNumber = (
88
+ val?: string,
89
+ separator = DEFAULT_THOUSANDS_SEPARATOR,
90
+ ): string => {
91
+ if (val === undefined) {
92
+ return '';
93
+ }
94
+ const parts = val.split('.');
95
+
96
+ parts[0] = parts[0]
97
+ // убрать лидирующие нули
98
+ .replace(/^0+(?=\d)/, '')
99
+ // проставить сепараторы тысяч
100
+ .replace(/\B(?=(\d{3})+(?!\d))/g, separator);
101
+ return (parts[1] ?? '').length > 0 ? parts.join('.') : parts[0];
102
+ };
103
+
104
+ export const formatNumber = (val?: number, separator = DEFAULT_THOUSANDS_SEPARATOR): string => {
105
+ if (val === undefined || isNaN(val)) {
106
+ return '';
107
+ }
108
+ return formatStringNumber(String(val), separator);
109
+ };
110
+
111
+ export const removeStringFormat = (val?: string): string =>
112
+ (val ?? '').replace(',', '.').replace(/\s/g, '');
113
+
114
+ export const stringToNumber = (val?: string): number | undefined => {
115
+ const trimmed = removeStringFormat(val);
116
+ if (trimmed === '') {
117
+ return undefined;
118
+ }
119
+ const num = Number(trimmed);
120
+ return isNaN(num) ? undefined : num;
121
+ };
122
+
123
+ export const setCaretPosition = (elem: HTMLInputElement, caretPos: number | null): void => {
124
+ if (caretPos === null || elem === null) {
125
+ return;
126
+ }
127
+ if (elem.selectionStart) {
128
+ elem.focus();
129
+ elem.setSelectionRange(caretPos, caretPos);
130
+ } else {
131
+ elem.focus();
132
+ }
133
+ };
134
+
135
+ export const isSpaceChar = (char?: string): boolean =>
136
+ char !== undefined && char.match(/\s/) !== null;
137
+
138
+ export const isInt = (n: number): boolean => n % 1 === 0;
139
+
140
+ export const getNumberLength = (n?: number): number =>
141
+ n === undefined || isNaN(n) ? 0 : n.toString().length;
142
+
143
+ // TODO: Не должен проверять строку, т.к. под это есть отдельный хелпер
144
+ /**
145
+ * Проверяет, что `val` не `null`, не `undefined` и не пустая строка
146
+ */
147
+ export const isNotEmpty = <T>(val: T | null | undefined): val is T =>
148
+ typeof val === 'string' ? val.trim() !== '' : val !== null && val !== undefined;
149
+
150
+ /**
151
+ * Проверяет, что переданное значение `null` или `undefined`
152
+ */
153
+ export const isEmpty = <T>(val: T | null | undefined): val is null | undefined =>
154
+ val === null || val === undefined;
155
+
156
+ /**
157
+ * Проверяет, что передана непустая строка
158
+ */
159
+ export const isStringNotEmpty = <T extends string>(value: T | undefined | null): value is T =>
160
+ (value ?? '').trim() !== '';
161
+
162
+ export const trimStringToMaxLength = (val: string, maxLength: number) =>
163
+ val.length > maxLength ? val.slice(0, maxLength) : val;
164
+
165
+ export const addDataAttributes = (data: IDataAttributes = {}): IDataAttributes =>
166
+ Object.fromEntries(
167
+ Object.entries(data).map(([key, value]) =>
168
+ isNotEmpty(value) ? [`data-${transformToKebab(key)}`, value] : [],
169
+ ),
170
+ );
171
+
172
+ export const addDataTestId = (
173
+ ...args: Parameters<typeof getTestId>
174
+ ): { 'data-testid': string } | undefined => {
175
+ const testId = getTestId(...args);
176
+ return isNotEmpty(testId) ? { 'data-testid': testId } : undefined;
177
+ };
178
+
179
+ export const getTestId = (
180
+ testId: string | undefined,
181
+ postfix?: string | number,
182
+ ): string | undefined => {
183
+ if (!isNotEmpty(testId)) {
184
+ return undefined;
185
+ }
186
+ return isNotEmpty(postfix) ? `${testId}-${postfix}` : testId;
187
+ };
188
+
189
+ export const getSelectKeyHandler =
190
+ (cb: (e: KeyboardEvent) => void): ((e: KeyboardEvent) => void) =>
191
+ (e) => {
192
+ if (e.code === 'Enter' || e.code === 'NumpadEnter') {
193
+ cb(e);
194
+ }
195
+ };
196
+
197
+ export const addClickHandler = (
198
+ cb?: (e: MouseEvent | KeyboardEvent) => void,
199
+ hasAction = true,
200
+ ): HTMLAttributes<unknown> =>
201
+ hasAction && isNotEmpty(cb)
202
+ ? {
203
+ tabIndex: 0,
204
+ onClick: cb as (e: MouseEvent) => void,
205
+ onKeyDown: getSelectKeyHandler(cb),
206
+ }
207
+ : {
208
+ tabIndex: -1,
209
+ };
210
+
211
+ /**
212
+ * Позволяет создать текстовый фильтр для набора items
213
+ * @param getter - функция возвращающая набор строковых значений из каждого item,
214
+ * по которым должен осуществляться поиск
215
+ */
216
+ export const createFilter =
217
+ <T>(
218
+ getter: (item: T) => Array<string | undefined>,
219
+ compareFn?: (item: string, query: string) => boolean,
220
+ ): ((items: T[], query: string) => T[]) =>
221
+ (items, query) =>
222
+ items.filter((item) => {
223
+ const possibleValues = getter(item).reduce(
224
+ (acc, cur) => [...acc, ...(isStringNotEmpty(cur) ? [cur.toLowerCase()] : [])],
225
+ [] as string[],
226
+ );
227
+ const queryString = query.toLowerCase().trim();
228
+ return possibleValues.some((v) =>
229
+ (compareFn ?? (() => v?.includes(queryString)))(v, queryString),
230
+ );
231
+ });
@@ -1,6 +1,6 @@
1
- export * from './use-is-mounted';
2
- export * from './use-on-click-outside';
3
- export * from './use-theme';
4
- export * from './use-dropdown';
5
- export * from './use-tweak-styles';
6
- export * from './use-did-mount-effect';
1
+ export * from './use-is-mounted';
2
+ export * from './use-on-click-outside';
3
+ export * from './use-theme';
4
+ export * from './use-dropdown';
5
+ export * from './use-tweak-styles';
6
+ export * from './use-did-mount-effect';
@@ -1,21 +1,18 @@
1
- import { DependencyList, EffectCallback, useEffect, useRef } from 'react';
2
-
3
- export const useDidMountEffect = (
4
- effect: EffectCallback,
5
- dependencies: DependencyList,
6
- ): void => {
7
- const isMountedRef = useRef(false);
8
- useEffect(() => {
9
- let unmount: ReturnType<EffectCallback>;
10
- if (isMountedRef.current) {
11
- unmount = effect();
12
- } else {
13
- isMountedRef.current = true;
14
- }
15
- return () => {
16
- if (unmount !== undefined) {
17
- unmount();
18
- }
19
- };
20
- }, dependencies);
21
- };
1
+ import { DependencyList, EffectCallback, useEffect, useRef } from 'react';
2
+
3
+ export const useDidMountEffect = (effect: EffectCallback, dependencies: DependencyList): void => {
4
+ const isMountedRef = useRef(false);
5
+ useEffect(() => {
6
+ let unmount: ReturnType<EffectCallback>;
7
+ if (isMountedRef.current) {
8
+ unmount = effect();
9
+ } else {
10
+ isMountedRef.current = true;
11
+ }
12
+ return () => {
13
+ if (unmount !== undefined) {
14
+ unmount();
15
+ }
16
+ };
17
+ }, dependencies);
18
+ };