@true-engineering/true-react-common-ui-kit 3.8.0 → 3.8.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 (117) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +6 -0
  3. package/dist/components/NewMoreMenu/NewMoreMenu.d.ts +1 -1
  4. package/dist/components/WithPopup/WithPopup.d.ts +2 -0
  5. package/dist/true-react-common-ui-kit.js +62 -60
  6. package/dist/true-react-common-ui-kit.js.map +1 -1
  7. package/dist/true-react-common-ui-kit.umd.cjs +62 -60
  8. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  9. package/package.json +1 -1
  10. package/src/components/AccountInfo/AccountInfo.stories.tsx +32 -32
  11. package/src/components/AccountInfo/AccountInfo.tsx +80 -80
  12. package/src/components/AddButton/AddButton.stories.tsx +21 -21
  13. package/src/components/AddButton/AddButton.tsx +52 -52
  14. package/src/components/Button/Button.stories.tsx +56 -56
  15. package/src/components/Button/Button.tsx +129 -129
  16. package/src/components/Checkbox/Checkbox.stories.tsx +28 -28
  17. package/src/components/Checkbox/Checkbox.tsx +85 -85
  18. package/src/components/CloseButton/CloseButton.tsx +34 -34
  19. package/src/components/Colors/Colors.stories.tsx +7 -7
  20. package/src/components/DateInput/DateInput.tsx +90 -90
  21. package/src/components/DateInput/constants.ts +2 -2
  22. package/src/components/DatePicker/DatePicker.tsx +308 -308
  23. package/src/components/Description/Description.stories.tsx +27 -27
  24. package/src/components/Description/Description.tsx +61 -61
  25. package/src/components/FiltersPane/FiltersPane.tsx +158 -158
  26. package/src/components/FiltersPane/components/Filter/Filter.tsx +203 -203
  27. package/src/components/FiltersPane/components/FilterValueView/FilterValueView.tsx +166 -166
  28. package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +210 -210
  29. package/src/components/FiltersPane/components/FilterWithPeriod/FilterWithPeriod.tsx +177 -177
  30. package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.tsx +167 -167
  31. package/src/components/Flag/Flag.stories.tsx +29 -29
  32. package/src/components/Flag/Flag.tsx +26 -26
  33. package/src/components/Flag/augment.d.ts +1 -1
  34. package/src/components/FlexibleTable/FlexibleTable.stories.tsx +267 -267
  35. package/src/components/FlexibleTable/FlexibleTable.styles.ts +110 -110
  36. package/src/components/FlexibleTable/FlexibleTable.tsx +271 -271
  37. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.styles.ts +38 -38
  38. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.tsx +83 -83
  39. package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.ts +25 -25
  40. package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.tsx +196 -196
  41. package/src/components/FlexibleTable/helpers.ts +13 -13
  42. package/src/components/FlexibleTable/types.ts +52 -52
  43. package/src/components/Icon/Icon.stories.tsx +86 -86
  44. package/src/components/Icon/complexIcons/augment.d.ts +1 -1
  45. package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
  46. package/src/components/Icon/complexIcons/index.ts +1 -1
  47. package/src/components/IncrementInput/IncrementInput.tsx +105 -105
  48. package/src/components/Input/Input.tsx +297 -297
  49. package/src/components/Input/types.ts +32 -32
  50. package/src/components/List/List.stories.tsx +70 -70
  51. package/src/components/List/List.tsx +33 -33
  52. package/src/components/List/components/ListItem/ListItem.tsx +57 -57
  53. package/src/components/Modal/Modal.stories.tsx +105 -105
  54. package/src/components/Modal/Modal.tsx +196 -196
  55. package/src/components/MoreMenu/MoreMenu.styles.ts +68 -68
  56. package/src/components/MultiSelect/MultiSelect.stories.tsx +46 -46
  57. package/src/components/MultiSelect/MultiSelect.tsx +106 -106
  58. package/src/components/MultiSelect/components/MultiSelectInput/MultiSelectInput.tsx +53 -53
  59. package/src/components/MultiSelectList/MultiSelectList.tsx +461 -461
  60. package/src/components/NewMoreMenu/NewMoreMenu.stories.tsx +1 -0
  61. package/src/components/NewMoreMenu/NewMoreMenu.tsx +3 -1
  62. package/src/components/Notification/Notification.stories.tsx +46 -46
  63. package/src/components/Notification/Notification.tsx +69 -69
  64. package/src/components/NumberInput/NumberInput.tsx +137 -137
  65. package/src/components/NumberInput/index.ts +1 -1
  66. package/src/components/PhoneInput/PhoneInput.tsx +214 -214
  67. package/src/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.tsx +155 -155
  68. package/src/components/PhoneInput/types.ts +16 -16
  69. package/src/components/RadioButton/RadioButton.stories.tsx +46 -46
  70. package/src/components/RadioButton/RadioButton.tsx +57 -57
  71. package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
  72. package/src/components/Select/CustomSelect.stories.tsx +217 -217
  73. package/src/components/Select/MultiSelect.stories.tsx +240 -240
  74. package/src/components/Select/Select.stories.tsx +235 -235
  75. package/src/components/Select/Select.tsx +580 -580
  76. package/src/components/Select/components/SelectList/SelectList.tsx +157 -157
  77. package/src/components/Select/components/SelectListItem/SelectListItem.tsx +68 -68
  78. package/src/components/Select/constants.ts +2 -2
  79. package/src/components/Select/types.ts +1 -1
  80. package/src/components/Selector/Selector.stories.tsx +62 -62
  81. package/src/components/Selector/Selector.styles.ts +164 -164
  82. package/src/components/Selector/Selector.tsx +115 -115
  83. package/src/components/Selector/index.ts +2 -2
  84. package/src/components/Selector/types.ts +12 -12
  85. package/src/components/Skeleton/Skeleton.stories.tsx +19 -19
  86. package/src/components/SmartInput/SmartInput.tsx +134 -134
  87. package/src/components/Status/Status.stories.tsx +73 -73
  88. package/src/components/Status/Status.styles.ts +143 -143
  89. package/src/components/Status/Status.tsx +49 -49
  90. package/src/components/Status/constants.ts +11 -11
  91. package/src/components/Status/index.ts +3 -3
  92. package/src/components/Status/types.ts +5 -5
  93. package/src/components/Switch/Switch.stories.tsx +40 -40
  94. package/src/components/Switch/Switch.tsx +75 -75
  95. package/src/components/TextArea/TextArea.tsx +180 -180
  96. package/src/components/TextButton/TextButton.stories.tsx +46 -46
  97. package/src/components/TextButton/TextButton.styles.ts +129 -129
  98. package/src/components/TextButton/TextButton.tsx +103 -103
  99. package/src/components/TextButton/index.ts +4 -4
  100. package/src/components/TextWithInfo/TextWithInfo.stories.tsx +53 -53
  101. package/src/components/TextWithInfo/TextWithInfo.tsx +62 -62
  102. package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
  103. package/src/components/ThemedPreloader/ThemedPreloader.stories.tsx +41 -41
  104. package/src/components/ThemedPreloader/ThemedPreloader.tsx +54 -54
  105. package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
  106. package/src/components/Toaster/Toaster.stories.tsx +30 -30
  107. package/src/components/Toaster/Toaster.tsx +108 -108
  108. package/src/components/Tooltip/Tooltip.stories.tsx +19 -19
  109. package/src/components/Tooltip/Tooltip.tsx +35 -35
  110. package/src/components/Tooltip/types.ts +1 -1
  111. package/src/components/WithPopup/WithPopup.stories.tsx +1 -0
  112. package/src/components/WithPopup/WithPopup.tsx +7 -1
  113. package/src/helpers/popper-helpers.ts +17 -17
  114. package/src/hooks/use-dropdown.ts +84 -84
  115. package/src/hooks/use-is-mounted.ts +15 -15
  116. package/src/theme/helpers.ts +76 -76
  117. package/src/vite-env.d.ts +1 -1
@@ -1,164 +1,164 @@
1
- import { CSSProperties } from 'react';
2
- import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
- import { colors, dimensions, ITweakStyles, createThemedStyles } from '../../theme';
4
-
5
- const SELECTOR_TOTAL_GAP = 4;
6
- const SELECTOR_BORDER_WIDTH = 1;
7
- export const SELECTOR_GAP = SELECTOR_TOTAL_GAP - SELECTOR_BORDER_WIDTH;
8
-
9
- export const getSelectorLineStyle = (activeElementData?: {
10
- clientWidth: number;
11
- offsetLeft: number;
12
- }): CSSProperties | undefined =>
13
- isNotEmpty(activeElementData)
14
- ? {
15
- width: activeElementData.clientWidth - SELECTOR_GAP * 2,
16
- transform: `translateX(${activeElementData.offsetLeft}px)`,
17
- }
18
- : undefined;
19
-
20
- export const useStyles = createThemedStyles('Selector', {
21
- root: {
22
- display: 'flex',
23
- alignItems: 'center',
24
- listStyle: 'none',
25
- position: 'relative',
26
- },
27
-
28
- disabled: {
29
- cursor: 'default',
30
-
31
- '& $optionText': {
32
- color: colors.FONT_LABEL,
33
- },
34
- },
35
-
36
- required: {
37
- '&::before': {
38
- top: '50%',
39
- left: -12,
40
- width: 6,
41
- height: 6,
42
- content: '""',
43
- position: 'absolute',
44
- transform: 'translate(0, -50%)',
45
- borderRadius: '50%',
46
- backgroundColor: colors.ORANGE_FOCUS,
47
- },
48
- },
49
-
50
- invalid: {},
51
-
52
- optionWrapper: {
53
- height: '100%',
54
- },
55
-
56
- option: {
57
- display: 'flex',
58
- alignItems: 'center',
59
- justifyContent: 'center',
60
- appearance: 'none',
61
- borderRadius: 0,
62
- padding: 0,
63
- border: 'none',
64
- cursor: 'pointer',
65
- width: '100%',
66
- },
67
-
68
- active: {
69
- cursor: 'default',
70
- },
71
-
72
- optionIcon: {
73
- width: 20,
74
- height: 20,
75
- },
76
-
77
- optionText: {},
78
-
79
- iconFromRight: {
80
- '& $option': {
81
- flexDirection: 'row-reverse',
82
- },
83
- },
84
-
85
- s: {},
86
-
87
- m: {},
88
-
89
- l: {},
90
-
91
- line: {},
92
-
93
- selector: {
94
- display: 'grid',
95
- gridAutoFlow: 'column',
96
- gridAutoColumns: '1fr',
97
- borderRadius: dimensions.BORDER_RADIUS_SMALL,
98
- backgroundColor: colors.BORDER_LIGHT,
99
- width: 'fit-content',
100
- position: 'relative',
101
- border: ['solid', SELECTOR_BORDER_WIDTH, 'transparent'],
102
-
103
- '& $line': {
104
- content: '""',
105
- position: 'absolute',
106
- left: SELECTOR_GAP,
107
- height: `calc(100% - ${SELECTOR_GAP * 2}px)`,
108
- backgroundColor: colors.CLASSIC_WHITE,
109
- borderRadius: dimensions.BORDER_RADIUS_SMALL,
110
- transition: '0.25s ease-in-out',
111
- transitionProperty: 'transform, width',
112
- },
113
-
114
- '&$invalid': {
115
- borderColor: colors.RED_WARNING,
116
- },
117
-
118
- '& $option': {
119
- gap: 6,
120
- position: 'relative',
121
- zIndex: 1,
122
- height: '100%',
123
- color: colors.FONT_MEDIUM,
124
- fontSize: 16,
125
- transition: 'color 0.25s ease-in-out',
126
- background: 'none',
127
-
128
- '&$s': {
129
- padding: [4, 8],
130
- fontSize: 10,
131
- lineHeight: '14px',
132
- },
133
-
134
- '&$m': {
135
- padding: [14, 18],
136
- },
137
-
138
- '&$l': {
139
- padding: [16, 24],
140
- },
141
-
142
- '&:hover, &:focus': {
143
- color: colors.FONT_MAIN,
144
- },
145
-
146
- '&$active': {
147
- color: colors.FONT_MAIN,
148
- },
149
- },
150
- },
151
-
152
- autoWidth: {
153
- '&$selector': {
154
- gridAutoColumns: 'auto',
155
-
156
- '& $line': {
157
- width: 'unset',
158
- transform: 'unset',
159
- },
160
- },
161
- },
162
- });
163
-
164
- export type ISelectorStyles = ITweakStyles<typeof useStyles>;
1
+ import { CSSProperties } from 'react';
2
+ import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
+ import { colors, dimensions, ITweakStyles, createThemedStyles } from '../../theme';
4
+
5
+ const SELECTOR_TOTAL_GAP = 4;
6
+ const SELECTOR_BORDER_WIDTH = 1;
7
+ export const SELECTOR_GAP = SELECTOR_TOTAL_GAP - SELECTOR_BORDER_WIDTH;
8
+
9
+ export const getSelectorLineStyle = (activeElementData?: {
10
+ clientWidth: number;
11
+ offsetLeft: number;
12
+ }): CSSProperties | undefined =>
13
+ isNotEmpty(activeElementData)
14
+ ? {
15
+ width: activeElementData.clientWidth - SELECTOR_GAP * 2,
16
+ transform: `translateX(${activeElementData.offsetLeft}px)`,
17
+ }
18
+ : undefined;
19
+
20
+ export const useStyles = createThemedStyles('Selector', {
21
+ root: {
22
+ display: 'flex',
23
+ alignItems: 'center',
24
+ listStyle: 'none',
25
+ position: 'relative',
26
+ },
27
+
28
+ disabled: {
29
+ cursor: 'default',
30
+
31
+ '& $optionText': {
32
+ color: colors.FONT_LABEL,
33
+ },
34
+ },
35
+
36
+ required: {
37
+ '&::before': {
38
+ top: '50%',
39
+ left: -12,
40
+ width: 6,
41
+ height: 6,
42
+ content: '""',
43
+ position: 'absolute',
44
+ transform: 'translate(0, -50%)',
45
+ borderRadius: '50%',
46
+ backgroundColor: colors.ORANGE_FOCUS,
47
+ },
48
+ },
49
+
50
+ invalid: {},
51
+
52
+ optionWrapper: {
53
+ height: '100%',
54
+ },
55
+
56
+ option: {
57
+ display: 'flex',
58
+ alignItems: 'center',
59
+ justifyContent: 'center',
60
+ appearance: 'none',
61
+ borderRadius: 0,
62
+ padding: 0,
63
+ border: 'none',
64
+ cursor: 'pointer',
65
+ width: '100%',
66
+ },
67
+
68
+ active: {
69
+ cursor: 'default',
70
+ },
71
+
72
+ optionIcon: {
73
+ width: 20,
74
+ height: 20,
75
+ },
76
+
77
+ optionText: {},
78
+
79
+ iconFromRight: {
80
+ '& $option': {
81
+ flexDirection: 'row-reverse',
82
+ },
83
+ },
84
+
85
+ s: {},
86
+
87
+ m: {},
88
+
89
+ l: {},
90
+
91
+ line: {},
92
+
93
+ selector: {
94
+ display: 'grid',
95
+ gridAutoFlow: 'column',
96
+ gridAutoColumns: '1fr',
97
+ borderRadius: dimensions.BORDER_RADIUS_SMALL,
98
+ backgroundColor: colors.BORDER_LIGHT,
99
+ width: 'fit-content',
100
+ position: 'relative',
101
+ border: ['solid', SELECTOR_BORDER_WIDTH, 'transparent'],
102
+
103
+ '& $line': {
104
+ content: '""',
105
+ position: 'absolute',
106
+ left: SELECTOR_GAP,
107
+ height: `calc(100% - ${SELECTOR_GAP * 2}px)`,
108
+ backgroundColor: colors.CLASSIC_WHITE,
109
+ borderRadius: dimensions.BORDER_RADIUS_SMALL,
110
+ transition: '0.25s ease-in-out',
111
+ transitionProperty: 'transform, width',
112
+ },
113
+
114
+ '&$invalid': {
115
+ borderColor: colors.RED_WARNING,
116
+ },
117
+
118
+ '& $option': {
119
+ gap: 6,
120
+ position: 'relative',
121
+ zIndex: 1,
122
+ height: '100%',
123
+ color: colors.FONT_MEDIUM,
124
+ fontSize: 16,
125
+ transition: 'color 0.25s ease-in-out',
126
+ background: 'none',
127
+
128
+ '&$s': {
129
+ padding: [4, 8],
130
+ fontSize: 10,
131
+ lineHeight: '14px',
132
+ },
133
+
134
+ '&$m': {
135
+ padding: [14, 18],
136
+ },
137
+
138
+ '&$l': {
139
+ padding: [16, 24],
140
+ },
141
+
142
+ '&:hover, &:focus': {
143
+ color: colors.FONT_MAIN,
144
+ },
145
+
146
+ '&$active': {
147
+ color: colors.FONT_MAIN,
148
+ },
149
+ },
150
+ },
151
+
152
+ autoWidth: {
153
+ '&$selector': {
154
+ gridAutoColumns: 'auto',
155
+
156
+ '& $line': {
157
+ width: 'unset',
158
+ transform: 'unset',
159
+ },
160
+ },
161
+ },
162
+ });
163
+
164
+ export type ISelectorStyles = ITweakStyles<typeof useStyles>;
@@ -1,115 +1,115 @@
1
- import { useEffect, useRef, useState } from 'react';
2
- import clsx from 'clsx';
3
- import {
4
- addDataTestId,
5
- getTestId,
6
- hasDuplicates,
7
- isNotEmpty,
8
- isReactNodeNotEmpty,
9
- } from '@true-engineering/true-react-platform-helpers';
10
- import { addDataAttributes } from '../../helpers';
11
- import { ICommonProps } from '../../types';
12
- import { renderIcon } from '../Icon';
13
- import { ISelectorOption, ISelectorValue } from './types';
14
- import { getSelectorLineStyle, useStyles, ISelectorStyles } from './Selector.styles';
15
-
16
- export interface ISelectorProps<V extends ISelectorValue> extends ICommonProps<ISelectorStyles> {
17
- options: Array<ISelectorOption<V>>;
18
- value?: V;
19
- /** @default false */
20
- isDisabled?: boolean;
21
- /** @default false */
22
- isRequired?: boolean;
23
- /** @default false */
24
- isInvalid?: boolean;
25
- /** @default true */
26
- hasSameOptionsWidth?: boolean;
27
- /** @default 'left' */
28
- iconPosition?: 'left' | 'right';
29
- /** @default 'l' */
30
- size?: 's' | 'm' | 'l';
31
- onChange: (value: V) => void;
32
- }
33
-
34
- export function Selector<V extends ISelectorValue>({
35
- options,
36
- value,
37
- isDisabled = false,
38
- isRequired = false,
39
- isInvalid = false,
40
- hasSameOptionsWidth = true,
41
- iconPosition = 'left',
42
- size = 'l',
43
- testId,
44
- data,
45
- tweakStyles,
46
- onChange,
47
- }: ISelectorProps<V>): JSX.Element {
48
- const classes = useStyles({ theme: tweakStyles });
49
- const optionsValues = options.map((opt) => opt.value);
50
-
51
- const [elementsData, setElementsData] = useState<HTMLElement[]>([]);
52
- const listRef = useRef<HTMLDivElement>(null);
53
-
54
- if (hasDuplicates(optionsValues)) {
55
- // eslint-disable-next-line no-console
56
- console.error('Selector: Значения options.value должны быть уникальными');
57
- }
58
-
59
- useEffect(() => {
60
- const listEl = listRef.current;
61
- if (listEl === null) {
62
- return;
63
- }
64
-
65
- setElementsData([...listEl.querySelectorAll<HTMLElement>(`.${classes.optionWrapper}`)]);
66
- }, [options, size]);
67
-
68
- const activeElementData = isNotEmpty(value)
69
- ? elementsData[optionsValues.indexOf(value)]
70
- : undefined;
71
-
72
- return (
73
- <div
74
- className={clsx(classes.root, classes.selector, {
75
- [classes.iconFromRight]: iconPosition === 'right',
76
- [classes.invalid]: isInvalid,
77
- [classes.required]: isRequired,
78
- [classes.autoWidth]: hasSameOptionsWidth,
79
- })}
80
- ref={listRef}
81
- {...addDataTestId(testId)}
82
- {...addDataAttributes(data)}
83
- >
84
- {isNotEmpty(activeElementData) && (
85
- <div className={classes.line} style={getSelectorLineStyle(activeElementData)} />
86
- )}
87
-
88
- {options.map((option) => {
89
- const optionId = option.value.toString();
90
- const isDisabledOption = option.isDisabled ?? isDisabled;
91
- const isActiveOption = option.value === value;
92
-
93
- return (
94
- <div key={optionId} className={classes.optionWrapper} {...addDataTestId(testId)}>
95
- <button
96
- type="button"
97
- className={clsx(classes.option, classes[size], {
98
- [classes.active]: isActiveOption,
99
- [classes.disabled]: isDisabledOption,
100
- })}
101
- disabled={isDisabledOption}
102
- onClick={!isDisabledOption ? () => onChange(option.value) : undefined}
103
- {...addDataTestId(getTestId(testId, optionId))}
104
- >
105
- {isReactNodeNotEmpty(option.icon) && (
106
- <div className={classes.optionIcon}>{renderIcon(option.icon)}</div>
107
- )}
108
- <div className={classes.optionText}>{option.label}</div>
109
- </button>
110
- </div>
111
- );
112
- })}
113
- </div>
114
- );
115
- }
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import clsx from 'clsx';
3
+ import {
4
+ addDataTestId,
5
+ getTestId,
6
+ hasDuplicates,
7
+ isNotEmpty,
8
+ isReactNodeNotEmpty,
9
+ } from '@true-engineering/true-react-platform-helpers';
10
+ import { addDataAttributes } from '../../helpers';
11
+ import { ICommonProps } from '../../types';
12
+ import { renderIcon } from '../Icon';
13
+ import { ISelectorOption, ISelectorValue } from './types';
14
+ import { getSelectorLineStyle, useStyles, ISelectorStyles } from './Selector.styles';
15
+
16
+ export interface ISelectorProps<V extends ISelectorValue> extends ICommonProps<ISelectorStyles> {
17
+ options: Array<ISelectorOption<V>>;
18
+ value?: V;
19
+ /** @default false */
20
+ isDisabled?: boolean;
21
+ /** @default false */
22
+ isRequired?: boolean;
23
+ /** @default false */
24
+ isInvalid?: boolean;
25
+ /** @default true */
26
+ hasSameOptionsWidth?: boolean;
27
+ /** @default 'left' */
28
+ iconPosition?: 'left' | 'right';
29
+ /** @default 'l' */
30
+ size?: 's' | 'm' | 'l';
31
+ onChange: (value: V) => void;
32
+ }
33
+
34
+ export function Selector<V extends ISelectorValue>({
35
+ options,
36
+ value,
37
+ isDisabled = false,
38
+ isRequired = false,
39
+ isInvalid = false,
40
+ hasSameOptionsWidth = true,
41
+ iconPosition = 'left',
42
+ size = 'l',
43
+ testId,
44
+ data,
45
+ tweakStyles,
46
+ onChange,
47
+ }: ISelectorProps<V>): JSX.Element {
48
+ const classes = useStyles({ theme: tweakStyles });
49
+ const optionsValues = options.map((opt) => opt.value);
50
+
51
+ const [elementsData, setElementsData] = useState<HTMLElement[]>([]);
52
+ const listRef = useRef<HTMLDivElement>(null);
53
+
54
+ if (hasDuplicates(optionsValues)) {
55
+ // eslint-disable-next-line no-console
56
+ console.error('Selector: Значения options.value должны быть уникальными');
57
+ }
58
+
59
+ useEffect(() => {
60
+ const listEl = listRef.current;
61
+ if (listEl === null) {
62
+ return;
63
+ }
64
+
65
+ setElementsData([...listEl.querySelectorAll<HTMLElement>(`.${classes.optionWrapper}`)]);
66
+ }, [options, size]);
67
+
68
+ const activeElementData = isNotEmpty(value)
69
+ ? elementsData[optionsValues.indexOf(value)]
70
+ : undefined;
71
+
72
+ return (
73
+ <div
74
+ className={clsx(classes.root, classes.selector, {
75
+ [classes.iconFromRight]: iconPosition === 'right',
76
+ [classes.invalid]: isInvalid,
77
+ [classes.required]: isRequired,
78
+ [classes.autoWidth]: hasSameOptionsWidth,
79
+ })}
80
+ ref={listRef}
81
+ {...addDataTestId(testId)}
82
+ {...addDataAttributes(data)}
83
+ >
84
+ {isNotEmpty(activeElementData) && (
85
+ <div className={classes.line} style={getSelectorLineStyle(activeElementData)} />
86
+ )}
87
+
88
+ {options.map((option) => {
89
+ const optionId = option.value.toString();
90
+ const isDisabledOption = option.isDisabled ?? isDisabled;
91
+ const isActiveOption = option.value === value;
92
+
93
+ return (
94
+ <div key={optionId} className={classes.optionWrapper} {...addDataTestId(testId)}>
95
+ <button
96
+ type="button"
97
+ className={clsx(classes.option, classes[size], {
98
+ [classes.active]: isActiveOption,
99
+ [classes.disabled]: isDisabledOption,
100
+ })}
101
+ disabled={isDisabledOption}
102
+ onClick={!isDisabledOption ? () => onChange(option.value) : undefined}
103
+ {...addDataTestId(getTestId(testId, optionId))}
104
+ >
105
+ {isReactNodeNotEmpty(option.icon) && (
106
+ <div className={classes.optionIcon}>{renderIcon(option.icon)}</div>
107
+ )}
108
+ <div className={classes.optionText}>{option.label}</div>
109
+ </button>
110
+ </div>
111
+ );
112
+ })}
113
+ </div>
114
+ );
115
+ }
@@ -1,2 +1,2 @@
1
- export * from './Selector';
2
- export type { ISelectorStyles } from './Selector.styles';
1
+ export * from './Selector';
2
+ export type { ISelectorStyles } from './Selector.styles';
@@ -1,12 +1,12 @@
1
- import { ReactNode } from 'react';
2
- import { IIcon } from '../Icon';
3
-
4
- export type ISelectorValue = string | number | boolean;
5
-
6
- export interface ISelectorOption<V> {
7
- label: ReactNode;
8
- icon?: IIcon;
9
- value: V;
10
- /** @default false */
11
- isDisabled?: boolean;
12
- }
1
+ import { ReactNode } from 'react';
2
+ import { IIcon } from '../Icon';
3
+
4
+ export type ISelectorValue = string | number | boolean;
5
+
6
+ export interface ISelectorOption<V> {
7
+ label: ReactNode;
8
+ icon?: IIcon;
9
+ value: V;
10
+ /** @default false */
11
+ isDisabled?: boolean;
12
+ }
@@ -1,19 +1,19 @@
1
- import { ComponentStory } from '@storybook/react';
2
- import { Skeleton } from './Skeleton';
3
-
4
- export default {
5
- title: 'Feedback/Skeleton',
6
- component: Skeleton,
7
- };
8
-
9
- const Template: ComponentStory<typeof Skeleton> = (args) => (
10
- <div style={{ padding: 32, backgroundColor: '#fff', width: 200 }}>
11
- <Skeleton {...args} />
12
- </div>
13
- );
14
-
15
- export const Default = Template.bind({});
16
-
17
- Default.args = {
18
- height: '20px',
19
- };
1
+ import { ComponentStory } from '@storybook/react';
2
+ import { Skeleton } from './Skeleton';
3
+
4
+ export default {
5
+ title: 'Feedback/Skeleton',
6
+ component: Skeleton,
7
+ };
8
+
9
+ const Template: ComponentStory<typeof Skeleton> = (args) => (
10
+ <div style={{ padding: 32, backgroundColor: '#fff', width: 200 }}>
11
+ <Skeleton {...args} />
12
+ </div>
13
+ );
14
+
15
+ export const Default = Template.bind({});
16
+
17
+ Default.args = {
18
+ height: '20px',
19
+ };