@true-engineering/true-react-common-ui-kit 4.0.0-alpha2 → 4.0.0-alpha21

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 (215) hide show
  1. package/README.md +11 -567
  2. package/dist/components/Button/Button.styles.d.ts +1 -1
  3. package/dist/components/Checkbox/Checkbox.styles.d.ts +1 -1
  4. package/dist/components/ControlWrapper/ControlWrapper.d.ts +2 -0
  5. package/dist/components/ControlWrapper/ControlWrapper.styles.d.ts +2 -1
  6. package/dist/components/ControlWrapper/index.d.ts +1 -0
  7. package/dist/components/ControlWrapper/types.d.ts +3 -0
  8. package/dist/components/DatePicker/DatePicker.d.ts +3 -3
  9. package/dist/components/DatePicker/DatePicker.styles.d.ts +1 -1
  10. package/dist/components/DatePicker/components/PopperContainer/PopperContainer.d.ts +2 -4
  11. package/dist/components/DatePicker/helpers.d.ts +3 -0
  12. package/dist/components/DatePicker/types.d.ts +5 -3
  13. package/dist/components/FiltersPane/FiltersPane.d.ts +7 -2
  14. package/dist/components/FiltersPane/components/Filter/Filter.d.ts +2 -2
  15. package/dist/components/FiltersPane/components/Filter/helpers.d.ts +4 -0
  16. package/dist/components/FiltersPane/components/FilterInterval/FilterInterval.styles.d.ts +1 -1
  17. package/dist/components/FiltersPane/components/FilterSelect/FilterSelect.styles.d.ts +1 -1
  18. package/dist/components/FiltersPane/components/FilterValueView/FilterValueView.d.ts +3 -1
  19. package/dist/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.d.ts +2 -2
  20. package/dist/components/FiltersPane/components/FilterWrapper/FilterWrapper.d.ts +2 -2
  21. package/dist/components/FiltersPane/types.d.ts +15 -5
  22. package/dist/components/Flag/customFlags/customFlags.d.ts +10 -0
  23. package/dist/components/Flag/customFlags/index.d.ts +1 -0
  24. package/dist/components/FlexibleTable/FlexibleTable.d.ts +4 -2
  25. package/dist/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.d.ts +4 -3
  26. package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.d.ts +6 -6
  27. package/dist/components/FlexibleTable/constants.d.ts +18 -2
  28. package/dist/components/FlexibleTable/types.d.ts +8 -8
  29. package/dist/components/Icon/icons-list.d.ts +1 -1
  30. package/dist/components/IconButton/IconButton.styles.d.ts +1 -1
  31. package/dist/components/IncrementInput/IncrementInput.styles.d.ts +1 -3
  32. package/dist/components/Input/Input.d.ts +3 -2
  33. package/dist/components/Input/InputBase.d.ts +2 -2
  34. package/dist/components/List/List.d.ts +1 -1
  35. package/dist/components/List/index.d.ts +2 -1
  36. package/dist/components/List/types.d.ts +4 -0
  37. package/dist/components/Modal/Modal.styles.d.ts +1 -1
  38. package/dist/components/Notification/Notification.styles.d.ts +1 -1
  39. package/dist/components/ScrollIntoViewIfNeeded/ScrollIntoViewIfNeeded.d.ts +1 -1
  40. package/dist/components/SearchInput/SearchInput.d.ts +2 -2
  41. package/dist/components/Select/Select.d.ts +5 -3
  42. package/dist/components/Select/Select.styles.d.ts +4 -4
  43. package/dist/components/Select/index.d.ts +1 -1
  44. package/dist/components/Status/Status.styles.d.ts +3 -2
  45. package/dist/components/Status/constants.d.ts +0 -1
  46. package/dist/components/Status/index.d.ts +1 -0
  47. package/dist/components/Status/types.d.ts +5 -2
  48. package/dist/components/TextArea/TextArea.d.ts +2 -5
  49. package/dist/components/TextArea/TextArea.styles.d.ts +1 -2
  50. package/dist/components/TextArea/index.d.ts +0 -1
  51. package/dist/components/TextButton/TextButton.styles.d.ts +1 -1
  52. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  53. package/dist/components/Tooltip/Tooltip.styles.d.ts +1 -1
  54. package/dist/components/WithMessages/WithMessages.styles.d.ts +1 -1
  55. package/dist/components/WithPopup/WithPopup.d.ts +21 -6
  56. package/dist/components/WithPopup/WithPopup.styles.d.ts +1 -1
  57. package/dist/components/WithPopup/helpers.d.ts +2 -0
  58. package/dist/components/WithPopup/types.d.ts +3 -0
  59. package/dist/components/WithTooltip/WithTooltip.styles.d.ts +1 -0
  60. package/dist/hooks/index.d.ts +1 -0
  61. package/dist/hooks/use-merge.d.ts +1 -0
  62. package/dist/hooks/use-mixed-styles.d.ts +3 -1
  63. package/dist/hooks/use-tweak-styles.d.ts +5 -5
  64. package/dist/style.css +78 -142
  65. package/dist/theme/Provider.d.ts +6 -3
  66. package/dist/theme/common.d.ts +4 -2
  67. package/dist/theme/create-themed-styles.d.ts +2 -0
  68. package/dist/theme/helpers.d.ts +9 -3
  69. package/dist/theme/index.d.ts +2 -0
  70. package/dist/theme/true-jss/ThemedStylesManager.d.ts +18 -0
  71. package/dist/theme/true-jss/TweakStylesManager.d.ts +34 -0
  72. package/dist/theme/true-jss/index.d.ts +2 -0
  73. package/dist/theme/true-jss/jss-context.d.ts +9 -0
  74. package/dist/theme/types.d.ts +5 -3
  75. package/dist/true-react-common-ui-kit.js +7580 -6523
  76. package/dist/true-react-common-ui-kit.js.map +1 -1
  77. package/dist/true-react-common-ui-kit.umd.cjs +7466 -6410
  78. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  79. package/dist/types.d.ts +10 -3
  80. package/package.json +4 -5
  81. package/src/components/ControlWrapper/ControlWrapper.stories.tsx +1 -1
  82. package/src/components/ControlWrapper/ControlWrapper.styles.ts +7 -6
  83. package/src/components/ControlWrapper/ControlWrapper.tsx +8 -2
  84. package/src/components/ControlWrapper/index.ts +1 -0
  85. package/src/components/ControlWrapper/types.ts +4 -0
  86. package/src/components/DatePicker/DatePicker.stories.tsx +2 -1
  87. package/src/components/DatePicker/DatePicker.styles.ts +3 -1
  88. package/src/components/DatePicker/DatePicker.tsx +12 -7
  89. package/src/components/DatePicker/components/PopperContainer/PopperContainer.tsx +4 -4
  90. package/src/components/DatePicker/helpers.ts +13 -1
  91. package/src/components/DatePicker/types.ts +9 -4
  92. package/src/components/FiltersPane/FiltersPane.stories.tsx +4 -2
  93. package/src/components/FiltersPane/FiltersPane.tsx +19 -13
  94. package/src/components/FiltersPane/components/Filter/Filter.tsx +24 -17
  95. package/src/components/FiltersPane/components/Filter/helpers.ts +18 -0
  96. package/src/components/FiltersPane/components/FilterValueView/FilterValueView.tsx +27 -22
  97. package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.ts +1 -0
  98. package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.tsx +3 -4
  99. package/src/components/FiltersPane/components/FilterWithPeriod/FilterWithPeriod.tsx +1 -1
  100. package/src/components/FiltersPane/components/FilterWrapper/FilterWrapper.tsx +7 -5
  101. package/src/components/FiltersPane/types.ts +23 -5
  102. package/src/components/Flag/Flag.stories.tsx +2 -1
  103. package/src/components/Flag/Flag.styles.ts +4 -0
  104. package/src/components/Flag/Flag.tsx +23 -9
  105. package/src/components/Flag/customFlags/AB.svg +1 -0
  106. package/src/components/Flag/customFlags/OS.svg +1 -0
  107. package/src/components/Flag/customFlags/augment.d.ts +1 -0
  108. package/src/components/Flag/customFlags/customFlags.ts +13 -0
  109. package/src/components/Flag/customFlags/index.ts +1 -0
  110. package/src/components/FlexibleTable/FlexibleTable.tsx +13 -12
  111. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.tsx +8 -5
  112. package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.tsx +13 -12
  113. package/src/components/FlexibleTable/constants.ts +6 -3
  114. package/src/components/FlexibleTable/types.ts +8 -12
  115. package/src/components/IncrementInput/IncrementInput.stories.tsx +2 -0
  116. package/src/components/IncrementInput/IncrementInput.styles.ts +31 -39
  117. package/src/components/IncrementInput/IncrementInput.tsx +28 -25
  118. package/src/components/Input/Input.tsx +5 -3
  119. package/src/components/Input/InputBase.tsx +29 -24
  120. package/src/components/List/List.tsx +5 -2
  121. package/src/components/List/index.ts +2 -1
  122. package/src/components/List/types.ts +5 -0
  123. package/src/components/NumberInput/NumberInput.stories.tsx +5 -1
  124. package/src/components/PhoneInput/PhoneInput.stories.tsx +2 -1
  125. package/src/components/PhoneInput/PhoneInput.tsx +5 -2
  126. package/src/components/SearchInput/SearchInput.tsx +20 -29
  127. package/src/components/Select/Select.tsx +12 -2
  128. package/src/components/Select/components/SelectList/SelectList.tsx +1 -1
  129. package/src/components/Select/index.ts +1 -1
  130. package/src/components/Status/Status.stories.tsx +54 -1
  131. package/src/components/Status/Status.styles.ts +2 -37
  132. package/src/components/Status/constants.ts +0 -10
  133. package/src/components/Status/index.ts +1 -1
  134. package/src/components/Status/types.ts +7 -3
  135. package/src/components/TextArea/TextArea.styles.ts +2 -6
  136. package/src/components/TextArea/TextArea.tsx +41 -20
  137. package/src/components/TextArea/index.ts +0 -1
  138. package/src/components/TextButton/TextButton.styles.ts +1 -0
  139. package/src/components/Tooltip/Tooltip.styles.ts +2 -0
  140. package/src/components/Tooltip/Tooltip.tsx +1 -1
  141. package/src/components/WithMessages/WithMessages.stories.tsx +1 -1
  142. package/src/components/WithPopup/WithPopup.stories.tsx +1 -0
  143. package/src/components/WithPopup/WithPopup.styles.ts +2 -0
  144. package/src/components/WithPopup/WithPopup.tsx +64 -16
  145. package/src/components/WithPopup/helpers.ts +9 -0
  146. package/src/components/WithPopup/types.ts +7 -0
  147. package/src/components/WithTooltip/WithTooltip.styles.ts +6 -0
  148. package/src/components/WithTooltip/WithTooltip.tsx +7 -2
  149. package/src/constants/phone-info.ts +20 -33
  150. package/src/helpers/phone.ts +19 -15
  151. package/src/hooks/index.ts +1 -0
  152. package/src/hooks/use-merge.ts +8 -0
  153. package/src/hooks/use-mixed-styles.ts +9 -11
  154. package/src/hooks/use-tweak-styles.ts +49 -27
  155. package/src/theme/Provider.tsx +10 -5
  156. package/src/theme/common.ts +5 -2
  157. package/src/theme/create-themed-styles.ts +78 -0
  158. package/src/theme/helpers.ts +39 -39
  159. package/src/theme/index.ts +2 -0
  160. package/src/theme/true-jss/ThemedStylesManager.ts +92 -0
  161. package/src/theme/true-jss/TweakStylesManager.ts +157 -0
  162. package/src/theme/true-jss/index.ts +2 -0
  163. package/src/theme/true-jss/jss-context.tsx +34 -0
  164. package/src/theme/types.ts +5 -3
  165. package/src/types.ts +17 -4
  166. package/dist/components/AccountInfo/AccountInfo.stories.d.ts +0 -6
  167. package/dist/components/AddButton/AddButton.stories.d.ts +0 -6
  168. package/dist/components/Button/Button.stories.d.ts +0 -6
  169. package/dist/components/Checkbox/Checkbox.stories.d.ts +0 -8
  170. package/dist/components/CloseButton/CloseButton.stories.d.ts +0 -5
  171. package/dist/components/Colors/Colors.stories.d.ts +0 -5
  172. package/dist/components/ControlWrapper/ControlWrapper.stories.d.ts +0 -6
  173. package/dist/components/DateInput/DateInput.stories.d.ts +0 -7
  174. package/dist/components/DatePicker/DatePicker.stories.d.ts +0 -7
  175. package/dist/components/Description/Description.stories.d.ts +0 -16
  176. package/dist/components/FileInput/FileInput.stories.d.ts +0 -7
  177. package/dist/components/FileItem/FileItem.stories.d.ts +0 -8
  178. package/dist/components/FiltersPane/FiltersPane.stories.d.ts +0 -31
  179. package/dist/components/Flag/Flag.stories.d.ts +0 -12
  180. package/dist/components/FlexibleTable/FlexibleTable.stories.d.ts +0 -19
  181. package/dist/components/Icon/Icon.stories.d.ts +0 -6
  182. package/dist/components/IconButton/IconButton.stories.d.ts +0 -6
  183. package/dist/components/IncrementInput/IncrementInput.stories.d.ts +0 -6
  184. package/dist/components/Input/Input.stories.d.ts +0 -25
  185. package/dist/components/List/List.stories.d.ts +0 -5
  186. package/dist/components/Modal/Modal.stories.d.ts +0 -29
  187. package/dist/components/MoreMenu/MoreMenu.stories.d.ts +0 -6
  188. package/dist/components/MultiSelect/MultiSelect.stories.d.ts +0 -13
  189. package/dist/components/NewMoreMenu/NewMoreMenu.stories.d.ts +0 -12
  190. package/dist/components/Notification/Notification.stories.d.ts +0 -8
  191. package/dist/components/NumberInput/NumberInput.stories.d.ts +0 -7
  192. package/dist/components/PhoneInput/PhoneInput.stories.d.ts +0 -28
  193. package/dist/components/PhoneInput/components/PhoneInputCountryList/PhoneInputCountryList.stories.d.ts +0 -5
  194. package/dist/components/RadioButton/RadioButton.stories.d.ts +0 -7
  195. package/dist/components/SearchInput/SearchInput.stories.d.ts +0 -6
  196. package/dist/components/Select/CustomSelect.stories.d.ts +0 -11
  197. package/dist/components/Select/MultiSelect.stories.d.ts +0 -15
  198. package/dist/components/Select/Select.stories.d.ts +0 -15
  199. package/dist/components/Selector/Selector.stories.d.ts +0 -7
  200. package/dist/components/Skeleton/Skeleton.stories.d.ts +0 -6
  201. package/dist/components/SmartInput/SmartInput.stories.d.ts +0 -18
  202. package/dist/components/Status/Status.stories.d.ts +0 -6
  203. package/dist/components/Switch/Switch.stories.d.ts +0 -16
  204. package/dist/components/TextArea/TextArea.stories.d.ts +0 -17
  205. package/dist/components/TextArea/types.d.ts +0 -2
  206. package/dist/components/TextButton/TextButton.stories.d.ts +0 -6
  207. package/dist/components/TextWithInfo/TextWithInfo.stories.d.ts +0 -12
  208. package/dist/components/TextWithTooltip/TextWithTooltip.stories.d.ts +0 -24
  209. package/dist/components/ThemedPreloader/ThemedPreloader.stories.d.ts +0 -17
  210. package/dist/components/Toaster/Toaster.stories.d.ts +0 -5
  211. package/dist/components/Tooltip/Tooltip.stories.d.ts +0 -5
  212. package/dist/components/WithMessages/WithMessages.stories.d.ts +0 -7
  213. package/dist/components/WithPopup/WithPopup.stories.d.ts +0 -16
  214. package/dist/components/WithTooltip/WithTooltip.stories.d.ts +0 -6
  215. package/src/components/TextArea/types.ts +0 -6
@@ -9,14 +9,17 @@ import { IDateRangeConfigItem, IFilterWithDatesValue, IPeriod } from '../../type
9
9
  import type { IFilterWrapperProps } from '../FilterWrapper';
10
10
  import { IFilterValueViewStyles, useStyles } from './FilterValueView.styles';
11
11
 
12
- export function FilterValueView<Values, Key extends keyof Values>({
12
+ export interface IFilterValueView<Values extends Record<string, unknown>, Key extends keyof Values>
13
+ extends Omit<IFilterWrapperProps<Values, Key>, 'filtersPaneRef' | 'tweakStyles' | 'onChange'>,
14
+ ICommonProps<IFilterValueViewStyles> {}
15
+
16
+ export function FilterValueView<Values extends Record<string, unknown>, Key extends keyof Values>({
17
+ value,
18
+ filter,
13
19
  locale,
14
20
  localeKey,
15
- filter,
16
- value,
17
21
  tweakStyles,
18
- }: Omit<IFilterWrapperProps<Values, Key>, 'onChange' | 'filtersPaneRef' | 'tweakStyles'> &
19
- ICommonProps<IFilterValueViewStyles>): JSX.Element {
22
+ }: IFilterValueView<Values, Key>): JSX.Element {
20
23
  const classes = useStyles({ theme: tweakStyles });
21
24
 
22
25
  const translatesLocaleKey = filter.localeKey ?? localeKey;
@@ -29,7 +32,7 @@ export function FilterValueView<Values, Key extends keyof Values>({
29
32
  return <></>;
30
33
  }
31
34
 
32
- if (filter.getSelectedValueView !== undefined) {
35
+ if (isNotEmpty(filter.getSelectedValueView)) {
33
36
  return <span className={classes.text}>{filter.getSelectedValueView(value)}</span>;
34
37
  }
35
38
 
@@ -94,7 +97,7 @@ export function FilterValueView<Values, Key extends keyof Values>({
94
97
  const intervalValueFrom = intervalValue[0];
95
98
  const intervalValueTo = intervalValue[1];
96
99
 
97
- const intervals = [];
100
+ const intervals: string[] = [];
98
101
  if (intervalValueFrom !== undefined) {
99
102
  intervals.push(`${translates.from.toLowerCase()} ${String(intervalValueFrom)}`);
100
103
  }
@@ -105,19 +108,6 @@ export function FilterValueView<Values, Key extends keyof Values>({
105
108
  return <span className={classes.text}>{intervals.join(' ')}</span>;
106
109
  }
107
110
 
108
- if (isMultiple) {
109
- return (
110
- <>
111
- {Array.isArray(value) && value.length > 0 && (
112
- <>
113
- <span className={classes.text}>{displayValue(value[0])}</span>
114
- <span className={classes.count}>{value.length > 1 && ` (+${value.length - 1})`}</span>
115
- </>
116
- )}
117
- </>
118
- );
119
- }
120
-
121
111
  if (isDate) {
122
112
  const { from, to, periodType, label } = value as unknown as IPeriod;
123
113
  const hasFrom = from !== undefined && from !== null;
@@ -127,7 +117,7 @@ export function FilterValueView<Values, Key extends keyof Values>({
127
117
  return <span className={classes.text}>{displayValue(label)}</span>;
128
118
  }
129
119
 
130
- const range = [];
120
+ const range: string[] = [];
131
121
  if (hasFrom) {
132
122
  if (!hasTo) {
133
123
  range.push(translates.from.toLowerCase());
@@ -146,12 +136,27 @@ export function FilterValueView<Values, Key extends keyof Values>({
146
136
  return <span className={classes.text}>{range.join(' ')}</span>;
147
137
  }
148
138
 
139
+ if (isMultiple) {
140
+ const convertValue = filter.getSelectedValue ?? displayValue;
141
+
142
+ return (
143
+ <>
144
+ {Array.isArray(value) && value.length > 0 && (
145
+ <>
146
+ <span className={classes.text}>{convertValue(value[0])}</span>
147
+ <span className={classes.count}>{value.length > 1 && ` (+${value.length - 1})`}</span>
148
+ </>
149
+ )}
150
+ </>
151
+ );
152
+ }
153
+
149
154
  if (isRange && Array.isArray(value)) {
150
155
  const rangeValue = value as unknown as number[];
151
156
  const rangeValueFrom = rangeValue[0];
152
157
  const rangeValueTo = rangeValue[1];
153
158
 
154
- const range = [];
159
+ const range: string[] = [];
155
160
  if (rangeValueFrom !== undefined) {
156
161
  range.push(`${translates.from.toLowerCase()} ${String(rangeValueFrom)}`);
157
162
  }
@@ -6,6 +6,7 @@ import { innerTextButtonStyles } from '../../FiltersPane.styles';
6
6
 
7
7
  export const useStyles = createThemedStyles('FilterWithDates', {
8
8
  root: {
9
+ width: 320,
9
10
  background: colors.CLASSIC_WHITE,
10
11
  position: 'relative',
11
12
  zIndex: 20,
@@ -1,7 +1,6 @@
1
1
  import { FC, useMemo, useRef, useState } from 'react';
2
2
  import { isAfter, isBefore } from 'date-fns';
3
- import enUS from 'date-fns/locale/en-US';
4
- import ru from 'date-fns/locale/ru';
3
+ import { enUS, ru } from 'date-fns/locale';
5
4
  import { getTestId, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
6
5
  import { addDataAttributes } from '../../../../helpers';
7
6
  import { useTweakStyles } from '../../../../hooks';
@@ -133,7 +132,7 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
133
132
  <div className={classes.containerItem}>
134
133
  <DatePicker
135
134
  selectedDate={value?.from}
136
- maxDate={value?.to}
135
+ maxDate={value?.to ?? undefined}
137
136
  label={translates.from}
138
137
  months={translates.months}
139
138
  locale={dateLocale}
@@ -149,7 +148,7 @@ export const FilterWithDates: FC<IFilterWithDatesProps> = ({
149
148
  selectedDate={value?.to}
150
149
  label={translates.to}
151
150
  months={translates.months}
152
- minDate={value?.from}
151
+ minDate={value?.from ?? undefined}
153
152
  locale={dateLocale}
154
153
  onChangeDate={handleChangeTo}
155
154
  tweakStyles={tweakEndDatePickerStyles}
@@ -151,7 +151,7 @@ export const FilterWithPeriod: FC<IFilterWithPeriodProps> = ({
151
151
  </div>
152
152
  )}
153
153
  {isDatePickerShown && (
154
- <div className={classes.picker} style={{ width: 320 }} ref={refDatePicker}>
154
+ <div className={classes.picker} ref={refDatePicker}>
155
155
  <FilterWithDates
156
156
  onStartBtnSubmit={() => {
157
157
  setIsDatePickerShown(false);
@@ -12,8 +12,10 @@ import { FilterValueView } from '../FilterValueView';
12
12
  import { isContentNotEmpty } from './helpers';
13
13
  import { useStyles, IFilterWrapperStyles } from './FilterWrapper.styles';
14
14
 
15
- export interface IFilterWrapperProps<Values, Key extends keyof Values>
16
- extends ICommonProps<IFilterWrapperStyles> {
15
+ export interface IFilterWrapperProps<
16
+ Values extends Record<string, unknown>,
17
+ Key extends keyof Values,
18
+ > extends ICommonProps<IFilterWrapperStyles> {
17
19
  filter: ConfigItem<Values[Key]>;
18
20
  value?: Values[Key];
19
21
  isDisabled?: boolean;
@@ -22,7 +24,7 @@ export interface IFilterWrapperProps<Values, Key extends keyof Values>
22
24
  onChange: <V>(value: V) => void;
23
25
  }
24
26
 
25
- export function FilterWrapper<Values, Key extends keyof Values>({
27
+ export function FilterWrapper<Values extends Record<string, unknown>, Key extends keyof Values>({
26
28
  filter,
27
29
  value,
28
30
  isDisabled,
@@ -105,8 +107,8 @@ export function FilterWrapper<Values, Key extends keyof Values>({
105
107
  <FilterValueView
106
108
  value={value}
107
109
  filter={filter}
108
- localeKey={localeKey}
109
110
  locale={locale}
111
+ localeKey={localeKey}
110
112
  testId={getTestId(testId, 'value')}
111
113
  tweakStyles={tweakFilterValueViewStyles}
112
114
  />
@@ -137,8 +139,8 @@ export function FilterWrapper<Values, Key extends keyof Values>({
137
139
  <Filter
138
140
  value={value}
139
141
  filter={filter}
140
- localeKey={localeKey}
141
142
  locale={locale}
143
+ localeKey={localeKey}
142
144
  onClose={onClose}
143
145
  onChange={onChange}
144
146
  testId={testId}
@@ -84,22 +84,40 @@ export type IDateRangeConfigItem<Value> = IConfigItemBasicBase<Value> & {
84
84
  dateFormat?: string;
85
85
  } & Omit<IFilterWithPeriodProps, 'value' | 'onChange' | 'setIsOpen'>;
86
86
 
87
- export type CustomComponent<Value> = FC<{
87
+ export interface ICustomComponentProps<Value> {
88
88
  value?: Value;
89
89
  onChange: (v?: Value) => void;
90
90
  onClose?: () => void;
91
91
  filter: ICustomConfigItem<Value>;
92
92
  localeKey?: IFilterLocaleKey;
93
93
  locale?: IPartialFilterLocale;
94
- }>;
94
+ }
95
+
96
+ export type CustomComponent<Value> = FC<ICustomComponentProps<Value>>;
97
+
98
+ export type ICustomValue<V> = V extends Array<infer T> ? T : never;
99
+
100
+ export interface ICustomRangeConfigItem<Value> extends IConfigItemBasicBase<Value> {
101
+ // eslint-disable-next-line @typescript-eslint/ban-types
102
+ [key: string & {}]: any;
103
+ type: 'custom';
104
+ component: CustomComponent<Value>;
105
+ valueViewType?: 'range';
106
+ }
95
107
 
96
- export interface ICustomConfigItem<Value> extends IConfigItemBasicBase<Value> {
97
- [key: string]: any;
108
+ export interface ICustomMultipleConfigItem<Value> extends IConfigItemBasicBase<Value> {
109
+ // eslint-disable-next-line @typescript-eslint/ban-types
110
+ [key: string & {}]: any;
98
111
  type: 'custom';
99
112
  component: CustomComponent<Value>;
100
- valueViewType?: 'range' | 'multiple';
113
+ valueViewType?: 'multiple';
114
+ getSelectedValue?: (v: ICustomValue<Value>) => ReactNode;
101
115
  }
102
116
 
117
+ export type ICustomConfigItem<Value> =
118
+ | ICustomRangeConfigItem<Value>
119
+ | ICustomMultipleConfigItem<Value>;
120
+
103
121
  export type ConfigItem<Value> =
104
122
  | ISelectConfigItem<Value>
105
123
  | IMultiSelectConfigItem<Value>
@@ -1,12 +1,13 @@
1
1
  import { countries } from 'country-flag-icons';
2
2
  import { ComponentStory } from '@storybook/react';
3
3
  import { Flag } from './Flag';
4
+ import { customFlags } from './customFlags';
4
5
 
5
6
  export default {
6
7
  title: 'Data Display/Flag',
7
8
  component: Flag,
8
9
  argTypes: {
9
- countryCode: { control: 'select', options: countries },
10
+ countryCode: { control: 'select', options: [...countries, ...Object.keys(customFlags)] },
10
11
  },
11
12
  };
12
13
 
@@ -2,6 +2,10 @@ import { colors, ITweakStyles, createThemedStyles } from '../../theme';
2
2
 
3
3
  export const useStyles = createThemedStyles('Flag', {
4
4
  root: {
5
+ display: 'flex',
6
+ width: '100%',
7
+ height: '100%',
8
+ boxSizing: 'border-box',
5
9
  // приходится хардкодить в компоненте, тк либа Flags выдает флаги с 2-3 пиксельным отступом снизу
6
10
  // если будет нужно, то можно вынести border на уровень пропсов
7
11
  border: [1, 'solid', colors.BORDER_MAIN],
@@ -3,6 +3,7 @@ import { hasFlag } from 'country-flag-icons';
3
3
  import Flags from 'country-flag-icons/react/3x2';
4
4
  import { ICommonProps } from '../../types';
5
5
  import { Icon } from '../Icon';
6
+ import { customFlags } from './customFlags';
6
7
  import { useStyles, IFlagStyles } from './Flag.styles';
7
8
 
8
9
  export interface IFlagProps extends Pick<ICommonProps<IFlagStyles>, 'tweakStyles'> {
@@ -12,15 +13,28 @@ export interface IFlagProps extends Pick<ICommonProps<IFlagStyles>, 'tweakStyles
12
13
 
13
14
  export const Flag: FC<IFlagProps> = ({ countryCode = '', tweakStyles }) => {
14
15
  const classes = useStyles({ theme: tweakStyles });
15
- const CC = countryCode.toUpperCase();
16
+ const countryFlagKey = countryCode.toUpperCase();
16
17
 
17
- const TheFlag = hasFlag(CC)
18
- ? Flags[CC as keyof typeof Flags]
19
- : () => (
20
- <div className={classes.noFlag}>
21
- <Icon type="minus" />
22
- </div>
23
- );
18
+ const hasFlagInLibrary = hasFlag(countryFlagKey);
24
19
 
25
- return <TheFlag className={classes.root} />;
20
+ if (hasFlagInLibrary) {
21
+ const FlagComponent = Flags[countryFlagKey as keyof typeof Flags];
22
+ return (
23
+ <div className={classes.root}>
24
+ <FlagComponent />
25
+ </div>
26
+ );
27
+ }
28
+
29
+ const CustomFlag = customFlags[countryFlagKey as keyof typeof customFlags];
30
+
31
+ if (CustomFlag !== undefined) {
32
+ return <div className={classes.root} dangerouslySetInnerHTML={{ __html: CustomFlag }} />;
33
+ }
34
+
35
+ return (
36
+ <div className={classes.noFlag}>
37
+ <Icon type="minus" />
38
+ </div>
39
+ );
26
40
  };
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 341.3"><path fill="#FFF" d="M0 0h512v341.3H0z"/><g fill="#6DA544"><path d="M0 0h512v48.8H0zM0 97.5h512v48.8H0zM0 195h512v48.8H0zM0 292.6h512v48.8H0z"/></g><path fill="#D80027" d="M0 0h256v146.3H0z"/><path fill="#FFF" d="m116.9 114.4-7.5-14.8V69.9L128 59l18.6 10.9v22.3l7.4-7.4 4.2 3-4.2 11.8-14.9 14.8z"/><circle fill="#FFF" cx="82" cy="82.8" r="5.4"/><circle fill="#FFF" cx="90.8" cy="61.7" r="5.4"/><circle fill="#FFF" cx="106.6" cy="46.2" r="5.4"/><circle fill="#FFF" cx="128" cy="40.8" r="5.4"/><circle fill="#FFF" cx="149.4" cy="46.2" r="5.4"/><circle fill="#FFF" cx="165.2" cy="61.7" r="5.4"/><circle fill="#FFF" cx="174" cy="82.8" r="5.4"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 450 300"><path fill="#FFF" d="M0 0h450v300H0z"/><path fill="red" d="M0 100h450v200H0z"/><path fill="#FFDF00" d="M0 200h450v100H0z"/></svg>
@@ -0,0 +1 @@
1
+ declare module '*.svg?raw';
@@ -0,0 +1,13 @@
1
+ import AB from './AB.svg?raw';
2
+ import OS from './OS.svg?raw';
3
+
4
+ export const customFlags = {
5
+ /**
6
+ * Абхазия
7
+ */
8
+ AB,
9
+ /**
10
+ * Южная осетия
11
+ */
12
+ OS,
13
+ };
@@ -0,0 +1 @@
1
+ export * from './customFlags';
@@ -34,10 +34,10 @@ export interface IFlexibleTableProps<
34
34
  | 'uniqueField'
35
35
  | 'rowAttributes'
36
36
  | 'isFirstColumnSticky'
37
- | 'isExpandableRowComponentInitiallyOpen'
38
37
  | 'expandableRowComponent'
39
38
  | 'onRowClick'
40
39
  | 'onRowHover'
40
+ | 'rowRef'
41
41
  > {
42
42
  content: Row[];
43
43
  /** @default 'table' */
@@ -62,6 +62,8 @@ export interface IFlexibleTableProps<
62
62
  nothingFoundContent?: ReactNode;
63
63
  /** @default true */
64
64
  shouldRenderHeader?: boolean;
65
+ /** @default false */
66
+ isExpandableRowComponentInitiallyOpen?: boolean | ((row: Row, index: number) => boolean);
65
67
  }
66
68
 
67
69
  export function FlexibleTable<
@@ -88,6 +90,7 @@ export function FlexibleTable<
88
90
  tweakStyles,
89
91
  shouldRenderHeader = true,
90
92
  onHeadClick,
93
+ isExpandableRowComponentInitiallyOpen: isRowInitiallyOpen,
91
94
  ...restProps
92
95
  }: IFlexibleTableProps<Row, HeaderContent, UniqueField>): JSX.Element {
93
96
  const classes = useStyles({ theme: tweakStyles });
@@ -105,11 +108,12 @@ export function FlexibleTable<
105
108
 
106
109
  const hasInfiniteScroll = isNotEmpty(infinityScrollConfig);
107
110
 
108
- const tableRowProps: Omit<
109
- IFlexibleTableRowProps<Row, HeaderContent, UniqueField>,
110
- 'item' | 'index'
111
- > = {
111
+ const getTableRowProps = (
112
+ item: Row,
113
+ index: number,
114
+ ): IFlexibleTableRowProps<Row, HeaderContent, UniqueField> => ({
112
115
  ...restProps,
116
+ item,
113
117
  renderMode,
114
118
  config,
115
119
  columns,
@@ -118,7 +122,8 @@ export function FlexibleTable<
118
122
  isFirstColumnSticky,
119
123
  isFocusable: isRowFocusable,
120
124
  tweakStyles: tweakTableRowStyles,
121
- };
125
+ isExpandableRowComponentInitiallyOpen: applyAction(isRowInitiallyOpen, item, index),
126
+ });
122
127
 
123
128
  const getDataScrollAttributeSetter = useCallback(
124
129
  (key: string, setter: (el: HTMLDivElement) => boolean) => (el?: HTMLDivElement) => {
@@ -267,9 +272,7 @@ export function FlexibleTable<
267
272
  )}
268
273
  <Table.Body className={classes.body}>
269
274
  {isLoading ? (
270
- indexMap(6, (i) => (
271
- <FlexibleTableRow {...tableRowProps} key={i} item={{} as Row} index={i} />
272
- ))
275
+ indexMap(6, (i) => <FlexibleTableRow {...getTableRowProps({} as Row, i)} key={i} />)
273
276
  ) : (
274
277
  <>
275
278
  {shouldShowNothingFound && (
@@ -282,11 +285,9 @@ export function FlexibleTable<
282
285
 
283
286
  {content.map((item, i) => (
284
287
  <FlexibleTableRow
285
- {...tableRowProps}
288
+ {...getTableRowProps(item, i)}
286
289
  isActive={activeRowsSet.has(i)}
287
290
  key={isNotEmpty(uniqueField) ? item[uniqueField] : i}
288
- item={item}
289
- index={i}
290
291
  />
291
292
  ))}
292
293
 
@@ -1,3 +1,4 @@
1
+ import { ReactNode, useCallback } from 'react';
1
2
  import clsx from 'clsx';
2
3
  import { applyAction, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
4
  import { addDataAttributes } from '../../../../helpers';
@@ -20,14 +21,11 @@ export interface IFlexibleTableCellProps<
20
21
  > extends Pick<ICommonProps<IFlexibleTableCellStyles>, 'tweakStyles'>,
21
22
  Pick<
22
23
  IValueComponentProps<Row, unknown>,
23
- | 'isFocusedRow'
24
- | 'isActiveRow'
25
- | 'isNestedComponentExpanded'
26
- | 'isRowNestedComponentExpanded'
27
- | 'onSetNestedComponent'
24
+ 'isFocusedRow' | 'isActiveRow' | 'isNestedComponentExpanded' | 'isRowNestedComponentExpanded'
28
25
  > {
29
26
  row: Row;
30
27
  columnName: keyof Row;
28
+ updateNestedComponent: (component: ReactNode, cellKey: keyof Row) => void;
31
29
  config: IFlexibleTableConfigType<Row, HeaderContent>;
32
30
  renderMode: IFlexibleTableRenderMode;
33
31
  isSecond?: boolean;
@@ -46,6 +44,7 @@ export function FlexibleTableCell<
46
44
  isSecond,
47
45
  isSticky: isOldSticky,
48
46
  isLoading,
47
+ updateNestedComponent,
49
48
  tweakStyles,
50
49
  ...valueComponentProps
51
50
  }: IFlexibleTableCellProps<Row, HeaderContent>): JSX.Element {
@@ -73,6 +72,10 @@ export function FlexibleTableCell<
73
72
 
74
73
  const cellComponentProps: IValueComponentProps<Row, Row[keyof Row]> = {
75
74
  ...valueComponentProps,
75
+ onSetNestedComponent: useCallback(
76
+ (node) => updateNestedComponent(node, columnName),
77
+ [columnName, updateNestedComponent],
78
+ ),
76
79
  value,
77
80
  row,
78
81
  };
@@ -1,9 +1,9 @@
1
- import { ReactNode, useState, memo, MouseEvent } from 'react';
1
+ import { ReactNode, useState, memo, MouseEvent, RefCallback, useCallback } from 'react';
2
2
  import clsx from 'clsx';
3
- import { applyAction, isEmpty, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
+ import { isEmpty, isNotEmpty } from '@true-engineering/true-react-platform-helpers';
4
4
  import { addDataAttributes } from '../../../../helpers';
5
5
  import { useTweakStyles } from '../../../../hooks';
6
- import { ICommonProps, IDataAttributes } from '../../../../types';
6
+ import { IDataAttributes, ITweakStylesProps } from '../../../../types';
7
7
  import { TableRenders } from '../../constants';
8
8
  import {
9
9
  ITableRow,
@@ -19,9 +19,8 @@ export interface IFlexibleTableRowProps<
19
19
  Row extends ITableRow,
20
20
  HeaderContent extends IHeaderContent<Row>,
21
21
  UniqueField extends keyof Row,
22
- > extends Pick<ICommonProps<IFlexibleTableRowStyles>, 'tweakStyles'> {
22
+ > extends ITweakStylesProps<IFlexibleTableRowStyles> {
23
23
  item: Row;
24
- index: number;
25
24
  uniqueField?: UniqueField;
26
25
  renderMode: IFlexibleTableRenderMode;
27
26
  /** @default false */
@@ -37,7 +36,8 @@ export interface IFlexibleTableRowProps<
37
36
  columns: Array<keyof Row & string>;
38
37
  rowAttributes?: Array<keyof Row>;
39
38
  /** @default false */
40
- isExpandableRowComponentInitiallyOpen?: boolean | ((row: Row, index: number) => boolean);
39
+ isExpandableRowComponentInitiallyOpen?: boolean;
40
+ rowRef?: RefCallback<HTMLTableRowElement>;
41
41
  /** Возвращает React-элемент, который отрисуется под строкой при нажатии на неё */
42
42
  expandableRowComponent?: (item: Row, isOpen: boolean, close: () => void) => ReactNode;
43
43
  onRowHover?: (id?: Row[UniqueField]) => void;
@@ -50,7 +50,6 @@ function FlexibleTableRowInner<
50
50
  UniqueField extends keyof Row,
51
51
  >({
52
52
  item,
53
- index,
54
53
  config,
55
54
  columns,
56
55
  uniqueField,
@@ -61,6 +60,7 @@ function FlexibleTableRowInner<
61
60
  isLoading = false,
62
61
  rowAttributes,
63
62
  isExpandableRowComponentInitiallyOpen = false,
63
+ rowRef,
64
64
  tweakStyles,
65
65
  expandableRowComponent,
66
66
  onRowHover,
@@ -75,8 +75,8 @@ function FlexibleTableRowInner<
75
75
  });
76
76
 
77
77
  const [isFocused, setFocused] = useState(false);
78
- const [nestedComponent, setNestedComponent] = useState<INestedComponent>(() => ({
79
- isOpen: applyAction(isExpandableRowComponentInitiallyOpen, item, index),
78
+ const [nestedComponent, setNestedComponent] = useState<INestedComponent<keyof Row>>(() => ({
79
+ isOpen: isExpandableRowComponentInitiallyOpen,
80
80
  }));
81
81
 
82
82
  const isEditable = !isLoading && (isNotEmpty(onRowClick) || isNotEmpty(onRowHover));
@@ -111,13 +111,13 @@ function FlexibleTableRowInner<
111
111
  setNestedComponent({ isOpen: false });
112
112
  };
113
113
 
114
- const updateNestedComponent = (component: ReactNode, cellKey: string) => {
114
+ const updateNestedComponent = useCallback((component: ReactNode, cellKey: keyof Row) => {
115
115
  if (isEmpty(component)) {
116
116
  closeNestedComponent();
117
117
  } else {
118
118
  setNestedComponent({ isOpen: true, component, cellKey });
119
119
  }
120
- };
120
+ }, []);
121
121
 
122
122
  const handleRowClick = () => {
123
123
  if (isNotEmpty(uniqueField)) {
@@ -139,6 +139,7 @@ function FlexibleTableRowInner<
139
139
  return (
140
140
  <>
141
141
  <Table.Row
142
+ ref={rowRef}
142
143
  className={clsx(classes.root, {
143
144
  [classes.active]: isActive,
144
145
  [classes.editable]: isEditable,
@@ -173,7 +174,7 @@ function FlexibleTableRowInner<
173
174
  isRowNestedComponentExpanded={
174
175
  isNestedComponentExpanded && isEmpty(nestedComponentCellKey)
175
176
  }
176
- onSetNestedComponent={(component) => updateNestedComponent(component, key)}
177
+ updateNestedComponent={updateNestedComponent}
177
178
  />
178
179
  ))}
179
180
  </Table.Row>
@@ -1,8 +1,11 @@
1
- import { IFlexibleTableRenderMode, IFlexibleTableRender } from './types';
1
+ import { IFlexibleTableRenderElement, IFlexibleTableRenderMode } from './types';
2
2
 
3
3
  export const DEFAULT_DATE_FORMAT = 'dd.MM.yyyy';
4
4
 
5
- export const TableRenders: Record<IFlexibleTableRenderMode, IFlexibleTableRender> = {
5
+ export const TableRenders = {
6
6
  table: { Root: 'table', Head: 'thead', Body: 'tbody', Row: 'tr', Header: 'th', Cell: 'td' },
7
7
  divs: { Root: 'div', Head: 'div', Body: 'div', Row: 'div', Header: 'div', Cell: 'div' },
8
- };
8
+ } satisfies Record<
9
+ IFlexibleTableRenderMode,
10
+ Record<IFlexibleTableRenderElement, keyof JSX.IntrinsicElements>
11
+ >;
@@ -2,11 +2,7 @@ import { CSSProperties, MouseEvent, ReactNode } from 'react';
2
2
  import { IRenderNode } from '../../types';
3
3
 
4
4
  export type IFlexibleTableRenderMode = 'table' | 'divs';
5
-
6
- export type IFlexibleTableRender = Record<
7
- 'Root' | 'Head' | 'Body' | 'Row' | 'Header' | 'Cell',
8
- keyof JSX.IntrinsicElements
9
- >;
5
+ export type IFlexibleTableRenderElement = 'Root' | 'Head' | 'Body' | 'Row' | 'Header' | 'Cell';
10
6
 
11
7
  // TODO: Заменить Record<string, any> на Record<string, unknown>
12
8
  export type ITableRow = Record<string, any>;
@@ -40,16 +36,16 @@ export interface IFlexibleTableRowConfig<
40
36
  title?: IRenderNode<ITitleComponentProps<HeaderContent[Key]>>;
41
37
  component?: IRenderNode<IValueComponentProps<Values, NonNullable<Values[Key]>>>;
42
38
  dateFormat?: string;
43
- minWidth?: string | number;
44
- width?: string | number;
45
- maxWidth?: string | number;
39
+ minWidth?: CSSProperties['minWidth'];
40
+ width?: CSSProperties['width'];
41
+ maxWidth?: CSSProperties['maxWidth'];
46
42
  /** @default 'left' */
47
43
  titleAlign?: CSSProperties['textAlign'];
48
44
  cellAlign?: CSSProperties['textAlign'];
49
45
  cellVerticalAlign?: CSSProperties['verticalAlign'];
50
46
  position?: CSSProperties['position'];
51
- right?: number;
52
- left?: number;
47
+ right?: CSSProperties['right'];
48
+ left?: CSSProperties['left'];
53
49
  shouldRenderDataId?: boolean;
54
50
  /**
55
51
  * Проверка, нужно ли отрисовать component
@@ -75,8 +71,8 @@ export interface IInfinityScrollConfig {
75
71
  onInfinityScroll: (skip: number) => void;
76
72
  }
77
73
 
78
- export interface INestedComponent {
74
+ export interface INestedComponent<T extends PropertyKey = string> {
79
75
  isOpen: boolean;
80
76
  component?: ReactNode;
81
- cellKey?: string;
77
+ cellKey?: T;
82
78
  }
@@ -26,4 +26,6 @@ Default.args = {
26
26
  isDisabled: false,
27
27
  isRequired: false,
28
28
  isReadonly: false,
29
+ icon: 'question',
30
+ isClearable: true,
29
31
  };