@true-engineering/true-react-common-ui-kit 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (85) hide show
  1. package/LICENSE +201 -201
  2. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  3. package/dist/components/FiltersPane/components/FilterSelect/FilterSelect.d.ts +1 -5
  4. package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.d.ts +1 -3
  5. package/dist/components/Flag/augment.d.ts +1 -1
  6. package/dist/components/FlexibleTable/FlexibleTable.d.ts +6 -2
  7. package/dist/components/FlexibleTable/FlexibleTable.styles.d.ts +1 -1
  8. package/dist/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.d.ts +1 -1
  9. package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.d.ts +1 -1
  10. package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.d.ts +1 -1
  11. package/dist/components/FlexibleTable/helpers.d.ts +3 -0
  12. package/dist/components/FlexibleTable/types.d.ts +1 -1
  13. package/dist/components/Icon/complexIcons/augment.d.ts +1 -1
  14. package/dist/components/List/List.d.ts +2 -2
  15. package/dist/components/List/types.d.ts +2 -2
  16. package/dist/components/MultiSelectList/MultiSelectList.d.ts +1 -2
  17. package/dist/components/Skeleton/Skeleton.d.ts +7 -0
  18. package/dist/components/Skeleton/Skeleton.styles.d.ts +3 -0
  19. package/dist/components/Skeleton/index.d.ts +2 -0
  20. package/dist/components/Switch/Switch.d.ts +1 -1
  21. package/dist/components/index.d.ts +1 -0
  22. package/dist/helpers/phone.d.ts +1 -1
  23. package/dist/hooks/index.d.ts +1 -0
  24. package/dist/hooks/use-merged-refs.d.ts +2 -0
  25. package/dist/theme/types.d.ts +2 -1
  26. package/dist/true-react-common-ui-kit.js +1162 -819
  27. package/dist/true-react-common-ui-kit.js.map +1 -1
  28. package/dist/true-react-common-ui-kit.umd.cjs +1161 -818
  29. package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
  30. package/dist/vite-env.d.ts +1 -1
  31. package/package.json +1 -1
  32. package/src/components/AddButton/AddButton.stories.tsx +21 -21
  33. package/src/components/Checkbox/Checkbox.tsx +1 -1
  34. package/src/components/Colors/Colors.stories.tsx +7 -7
  35. package/src/components/DateInput/DateInput.tsx +1 -9
  36. package/src/components/DateInput/constants.ts +2 -2
  37. package/src/components/DatePicker/DatePicker.stories.tsx +1 -0
  38. package/src/components/DatePicker/DatePicker.tsx +1 -3
  39. package/src/components/FiltersPane/FiltersPane.stories.tsx +0 -8
  40. package/src/components/FiltersPane/components/FilterInterval/FilterInterval.styles.ts +2 -1
  41. package/src/components/FiltersPane/components/FilterSelect/FilterSelect.styles.ts +3 -1
  42. package/src/components/FiltersPane/components/FilterSelect/FilterSelect.tsx +1 -6
  43. package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.ts +2 -1
  44. package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.ts +1 -0
  45. package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.tsx +1 -4
  46. package/src/components/FiltersPane/types.ts +1 -1
  47. package/src/components/Flag/augment.d.ts +1 -1
  48. package/src/components/FlexibleTable/FlexibleTable.stories.tsx +15 -12
  49. package/src/components/FlexibleTable/FlexibleTable.styles.ts +9 -10
  50. package/src/components/FlexibleTable/FlexibleTable.tsx +124 -60
  51. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.styles.ts +4 -0
  52. package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.tsx +25 -27
  53. package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.ts +4 -0
  54. package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.tsx +12 -11
  55. package/src/components/FlexibleTable/helpers.ts +15 -0
  56. package/src/components/FlexibleTable/types.ts +1 -1
  57. package/src/components/Icon/complexIcons/augment.d.ts +1 -1
  58. package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
  59. package/src/components/Icon/complexIcons/index.ts +1 -1
  60. package/src/components/List/List.tsx +6 -6
  61. package/src/components/List/types.ts +2 -2
  62. package/src/components/MoreMenu/MoreMenu.stories.tsx +46 -46
  63. package/src/components/MultiSelectList/MultiSelectList.styles.ts +4 -0
  64. package/src/components/MultiSelectList/MultiSelectList.tsx +1 -3
  65. package/src/components/NumberInput/index.ts +1 -1
  66. package/src/components/PhoneInput/types.ts +16 -16
  67. package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
  68. package/src/components/Select/constants.ts +2 -2
  69. package/src/components/Select/types.ts +1 -1
  70. package/src/components/Skeleton/Skeleton.stories.tsx +19 -0
  71. package/src/components/Skeleton/Skeleton.styles.ts +46 -0
  72. package/src/components/Skeleton/Skeleton.tsx +12 -0
  73. package/src/components/Skeleton/index.ts +2 -0
  74. package/src/components/Switch/Switch.tsx +2 -2
  75. package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
  76. package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
  77. package/src/components/Tooltip/types.ts +1 -1
  78. package/src/components/index.ts +1 -0
  79. package/src/helpers/phone.ts +1 -1
  80. package/src/helpers/popper-helpers.ts +17 -17
  81. package/src/hooks/index.ts +1 -0
  82. package/src/hooks/use-is-mounted.ts +15 -15
  83. package/src/hooks/use-merged-refs.ts +4 -0
  84. package/src/theme/types.ts +2 -0
  85. package/src/vite-env.d.ts +1 -1
@@ -1,10 +1,19 @@
1
- import { ReactNode, RefObject, useCallback, useEffect, useRef, useState } from 'react';
1
+ import { ReactNode, RefObject, useCallback, useEffect, useMemo, useRef } from 'react';
2
2
  import clsx from 'clsx';
3
+ import {
4
+ addDataTestId,
5
+ indexMap,
6
+ isArrayNotEmpty,
7
+ isEmpty,
8
+ isNotEmpty,
9
+ } from '@true-engineering/true-react-platform-helpers';
3
10
  import { addDataAttributes } from '../../helpers';
4
- import { useTweakStyles } from '../../hooks';
11
+ import { useMergedRefs, useTweakStyles } from '../../hooks';
5
12
  import { ICommonProps } from '../../types';
13
+ import { Skeleton } from '../Skeleton';
6
14
  import { ThemedPreloader } from '../ThemedPreloader';
7
15
  import { FlexibleTableRow } from './components';
16
+ import { hasHorizontalScrollBar } from './helpers';
8
17
  import { IFlexibleTableConfigType, IInfinityScrollConfig, ITitleComponent } from './types';
9
18
  import { useStyles, IFlexibleTableStyles } from './FlexibleTable.styles';
10
19
 
@@ -15,12 +24,16 @@ export interface IFlexibleTableProps<Values extends Record<string, any>>
15
24
  headerContent?: Partial<Record<keyof Values, any>>;
16
25
  enabledColumns?: Array<keyof Values>;
17
26
  activeRows?: number[];
18
- config?: IFlexibleTableConfigType<Values>;
27
+ config: IFlexibleTableConfigType<Values>;
19
28
  isHorizontallyScrollable?: boolean;
20
29
  isFirstColumnSticky?: boolean;
21
30
  infinityScrollConfig?: IInfinityScrollConfig;
31
+ /**
32
+ * @default Индекс строки
33
+ */
22
34
  uniqueField?: keyof Values;
23
35
  onHeadClick?: (column: keyof Values) => void;
36
+ isLoading?: boolean;
24
37
  // TODO: Заменить string на Generic Values[uniqueField]
25
38
  onRowClick?: (id: string) => void;
26
39
  onRowHover?: (id?: string) => void;
@@ -42,6 +55,7 @@ export function FlexibleTable<Values extends Record<string, any>>({
42
55
  isFirstColumnSticky,
43
56
  infinityScrollConfig,
44
57
  uniqueField,
58
+ isLoading,
45
59
  onHeadClick,
46
60
  onRowHover,
47
61
  onRowClick,
@@ -59,11 +73,44 @@ export function FlexibleTable<Values extends Record<string, any>>({
59
73
  currentComponentName: 'FlexibleTable',
60
74
  });
61
75
 
62
- const [isHorizontallyScrolled, setIsHorizontallyScrolled] = useState(false);
63
-
64
76
  const observer = useRef<IntersectionObserver>();
65
77
  const scrollRef = useRef<HTMLDivElement>(null);
66
78
 
79
+ const showedColumns = useMemo(
80
+ () => enabledColumns ?? Object.keys(config),
81
+ [enabledColumns, config],
82
+ );
83
+
84
+ const getDataScrollAttributeSetter = useCallback(
85
+ (key: string, setter: (el: HTMLDivElement) => boolean) => (el?: HTMLDivElement) => {
86
+ if (isHorizontallyScrollable && isNotEmpty(el) && setter(el)) {
87
+ el.dataset[key] = 'true';
88
+ } else {
89
+ el?.removeAttribute(`data-${key}`);
90
+ }
91
+ },
92
+ [isHorizontallyScrollable],
93
+ );
94
+
95
+ // Когда таблица имеет скроллбар - добавляем аттрибут scrollable
96
+ const setHasScrollBarAttribute = useCallback(
97
+ getDataScrollAttributeSetter('scrollable', hasHorizontalScrollBar),
98
+ [getDataScrollAttributeSetter],
99
+ );
100
+
101
+ // Когда таблица проскроллена - добавляем аттрибут scrolled
102
+ const setIsScrolledAttribute = useCallback(
103
+ getDataScrollAttributeSetter('scrolled', (el) => el.scrollLeft > 0),
104
+ [getDataScrollAttributeSetter],
105
+ );
106
+
107
+ const ref = useMergedRefs([
108
+ refForScroll,
109
+ scrollRef,
110
+ setHasScrollBarAttribute,
111
+ setIsScrolledAttribute,
112
+ ]);
113
+
67
114
  const initIntersectionObserver = useCallback(
68
115
  (node: HTMLDivElement) => {
69
116
  if (infinityScrollConfig) {
@@ -97,29 +144,34 @@ export function FlexibleTable<Values extends Record<string, any>>({
97
144
  );
98
145
 
99
146
  useEffect(() => {
100
- const scrollContainer = (refForScroll ?? scrollRef).current;
101
- if (scrollContainer === null || !isHorizontallyScrollable || !isFirstColumnSticky) {
147
+ const scrollContainer = scrollRef.current;
148
+ if (isEmpty(scrollContainer) || !isHorizontallyScrollable) {
102
149
  return;
103
150
  }
104
- const scrollHandler = (e: Event) => {
105
- setIsHorizontallyScrolled((e.target as HTMLDivElement).scrollLeft > 0);
151
+
152
+ const scrollHandler = () => {
153
+ setIsScrolledAttribute(scrollContainer);
154
+ };
155
+
156
+ const resizeHandler = () => {
157
+ setHasScrollBarAttribute(scrollContainer);
106
158
  };
159
+
107
160
  scrollContainer.addEventListener('scroll', scrollHandler);
108
- return () => scrollContainer.removeEventListener('scroll', scrollHandler);
109
- }, [scrollRef]);
161
+ window.addEventListener('resize', resizeHandler);
162
+
163
+ return () => {
164
+ scrollContainer.removeEventListener('scroll', scrollHandler);
165
+ window.removeEventListener('resize', resizeHandler);
166
+ };
167
+ }, [scrollRef, setIsScrolledAttribute, setHasScrollBarAttribute]);
110
168
 
111
169
  return (
112
- <div
113
- ref={refForScroll ?? scrollRef}
114
- className={clsx(
115
- isHorizontallyScrollable && classes.scroll,
116
- isHorizontallyScrolled && classes.horizontallyScrolled,
117
- )}
118
- >
119
- <table className={classes.root} data-testid={testId} {...addDataAttributes(data)}>
170
+ <div ref={ref} className={clsx({ [classes.scroll]: isHorizontallyScrollable })}>
171
+ <table className={classes.root} {...addDataTestId(testId)} {...addDataAttributes(data)}>
120
172
  <thead>
121
173
  <tr className={classes.headerRow}>
122
- {(enabledColumns || Object.keys(content[0])).map((key, idx) => {
174
+ {showedColumns.map((key, i) => {
123
175
  const itemConfig = config?.[key];
124
176
 
125
177
  let titleContent = itemConfig?.title ?? '';
@@ -131,11 +183,10 @@ export function FlexibleTable<Values extends Record<string, any>>({
131
183
 
132
184
  return (
133
185
  <th
134
- className={clsx(
135
- classes.header,
136
- isFirstColumnSticky && idx === 0 && classes.headerSticky,
137
- isFirstColumnSticky && idx === 1 && classes.headerSecond,
138
- )}
186
+ className={clsx(classes.header, {
187
+ [classes.headerSticky]: isFirstColumnSticky && i === 0,
188
+ [classes.headerSecond]: isFirstColumnSticky && i === 1,
189
+ })}
139
190
  style={{
140
191
  minWidth: itemConfig?.minWidth,
141
192
  width: itemConfig?.width,
@@ -152,42 +203,55 @@ export function FlexibleTable<Values extends Record<string, any>>({
152
203
  </tr>
153
204
  </thead>
154
205
  <tbody>
155
- {content.length === 0 &&
156
- nothingFoundContent !== undefined &&
157
- !infinityScrollConfig?.isLoading &&
158
- (infinityScrollConfig?.isLastPage === undefined || infinityScrollConfig.isLastPage) && (
159
- <tr>
160
- <td colSpan={(enabledColumns || Object.keys(content[0])).length}>
161
- {nothingFoundContent}
162
- </td>
206
+ {isLoading ? (
207
+ indexMap(6, (i) => (
208
+ <tr key={i}>
209
+ {showedColumns.map((_, j) => (
210
+ <td key={j} className={classes.skeleton}>
211
+ <Skeleton />
212
+ </td>
213
+ ))}
163
214
  </tr>
164
- )}
165
-
166
- {content.map((item, idx) => (
167
- <FlexibleTableRow
168
- item={item}
169
- uniqueField={uniqueField}
170
- isActive={activeRows?.includes(idx) ?? false}
171
- isFirstColumnSticky={isFirstColumnSticky}
172
- onRowClick={onRowClick}
173
- onRowHover={onRowHover}
174
- enabledColumns={enabledColumns}
175
- config={config}
176
- key={uniqueField ? item[uniqueField] : idx}
177
- rowAttributes={rowAttributes}
178
- tweakStyles={tweakTableRowStyles}
179
- expandableRowComponent={expandableRowComponent}
180
- />
181
- ))}
182
-
183
- {infinityScrollConfig !== undefined && !infinityScrollConfig.isLastPage && (
184
- <tr>
185
- <td colSpan={(enabledColumns || Object.keys(content[0])).length}>
186
- <div ref={initIntersectionObserver} className={classes.loader}>
187
- <ThemedPreloader type="dots" />
188
- </div>
189
- </td>
190
- </tr>
215
+ ))
216
+ ) : (
217
+ <>
218
+ {!isArrayNotEmpty(content) &&
219
+ nothingFoundContent !== undefined &&
220
+ !infinityScrollConfig?.isLoading &&
221
+ (infinityScrollConfig?.isLastPage === undefined ||
222
+ infinityScrollConfig.isLastPage) && (
223
+ <tr>
224
+ <td colSpan={showedColumns.length}>{nothingFoundContent}</td>
225
+ </tr>
226
+ )}
227
+
228
+ {content.map((item, i) => (
229
+ <FlexibleTableRow
230
+ item={item}
231
+ uniqueField={uniqueField}
232
+ isActive={activeRows?.includes(i) ?? false}
233
+ isFirstColumnSticky={isFirstColumnSticky}
234
+ onRowClick={onRowClick}
235
+ onRowHover={onRowHover}
236
+ enabledColumns={enabledColumns}
237
+ config={config}
238
+ key={isNotEmpty(uniqueField) ? item[uniqueField] : i}
239
+ rowAttributes={rowAttributes}
240
+ tweakStyles={tweakTableRowStyles}
241
+ expandableRowComponent={expandableRowComponent}
242
+ />
243
+ ))}
244
+
245
+ {infinityScrollConfig !== undefined && !infinityScrollConfig.isLastPage && (
246
+ <tr>
247
+ <td colSpan={showedColumns.length}>
248
+ <div ref={initIntersectionObserver} className={classes.loader}>
249
+ <ThemedPreloader type="dots" />
250
+ </div>
251
+ </td>
252
+ </tr>
253
+ )}
254
+ </>
191
255
  )}
192
256
  </tbody>
193
257
  </table>
@@ -18,6 +18,10 @@ export const useStyles = createThemedStyles('FlexibleTableCell', {
18
18
  paddingLeft: 24,
19
19
  paddingRight: 12,
20
20
  ...getTransition(['box-shadow']),
21
+
22
+ '[data-scrolled] &': {
23
+ boxShadow: '4px 0 4px rgba(0, 0, 0, 0.05)',
24
+ },
21
25
  },
22
26
 
23
27
  second: {
@@ -1,8 +1,8 @@
1
1
  import { ReactNode } from 'react';
2
2
  import clsx from 'clsx';
3
- import { format } from 'date-fns';
3
+ import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
4
4
  import type { ICommonProps } from '../../../../types';
5
- import { DEFAULT_DATE_FORMAT } from '../../constants';
5
+ import { formatCellContent } from '../../helpers';
6
6
  import type { IFlexibleTableConfigType } from '../../types';
7
7
  import { useStyles, IFlexibleTableCellStyles } from './FlexibleTableCell.styles';
8
8
 
@@ -10,7 +10,7 @@ export interface IFlexibleTableCellProps<Values extends Record<string, any>>
10
10
  extends Pick<ICommonProps<IFlexibleTableCellStyles>, 'tweakStyles'> {
11
11
  item: Values;
12
12
  columnName: keyof Values;
13
- config?: IFlexibleTableConfigType<Values>;
13
+ config: IFlexibleTableConfigType<Values>;
14
14
  isFocusedRow?: boolean;
15
15
  isSecond?: boolean;
16
16
  isSticky?: boolean;
@@ -33,39 +33,37 @@ function FlexibleTableCell<Values extends Record<string, any>>({
33
33
  }: IFlexibleTableCellProps<Values>): JSX.Element {
34
34
  const classes = useStyles({ theme: tweakStyles });
35
35
 
36
- const itemConfig = config?.[columnName];
37
- const value = item[columnName];
38
- let content = null;
36
+ const { component, cellAlign, position, right, left, cellVerticalAlign } =
37
+ config[columnName] ?? {};
39
38
 
40
- if (itemConfig?.component) {
41
- const ValueComponent = itemConfig?.component;
42
- content = ValueComponent({
43
- value,
44
- row: item,
45
- isFocusedRow,
46
- isNestedComponentExpanded,
47
- isRowNestedComponentExpanded,
48
- onSetNestedComponent,
49
- });
50
- } else if (typeof value === 'string' || typeof value === 'number') {
51
- content = value;
52
- } else if ((value as any) instanceof Date) {
53
- content = format(value, itemConfig?.dateFormat || DEFAULT_DATE_FORMAT);
54
- }
39
+ const value = item[columnName];
55
40
 
56
41
  return (
57
42
  <td
58
43
  key={columnName as string}
59
44
  className={clsx(classes.root, { [classes.sticky]: isSticky, [classes.second]: isSecond })}
60
45
  style={{
61
- textAlign: itemConfig?.cellAlign,
62
- position: isSticky ? 'sticky' : itemConfig?.position,
63
- right: itemConfig?.right,
64
- left: isSticky ? 0 : itemConfig?.left,
65
- verticalAlign: itemConfig?.cellVerticalAlign,
46
+ textAlign: cellAlign,
47
+ position: isSticky ? 'sticky' : position,
48
+ right,
49
+ left: isSticky ? 0 : left,
50
+ verticalAlign: cellVerticalAlign,
66
51
  }}
67
52
  >
68
- {content}
53
+ {isNotEmpty(value) && (
54
+ <>
55
+ {isNotEmpty(component)
56
+ ? component({
57
+ value,
58
+ row: item,
59
+ isFocusedRow,
60
+ isNestedComponentExpanded,
61
+ isRowNestedComponentExpanded,
62
+ onSetNestedComponent,
63
+ })
64
+ : formatCellContent(value, config[columnName])}
65
+ </>
66
+ )}
69
67
  </td>
70
68
  );
71
69
  }
@@ -11,6 +11,10 @@ export const useStyles = createThemedStyles('FlexibleTableRow', {
11
11
  editable: {
12
12
  cursor: 'pointer',
13
13
  },
14
+
15
+ clickable: {
16
+ cursor: 'pointer',
17
+ },
14
18
  });
15
19
 
16
20
  export type IFlexibleTableRowStyles = ITweakStyles<
@@ -1,5 +1,6 @@
1
1
  import { ReactNode, useState, memo } from 'react';
2
2
  import clsx from 'clsx';
3
+ import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
4
  import { addDataAttributes } from '../../../../helpers';
4
5
  import { useTweakStyles } from '../../../../hooks';
5
6
  import { ICommonProps, IDataAttributes } from '../../../../types';
@@ -14,7 +15,7 @@ export interface IFlexibleTableRowProps<Values extends Record<string, any>>
14
15
  uniqueField?: keyof Values;
15
16
  isFirstColumnSticky?: boolean;
16
17
  isActive: boolean;
17
- config?: IFlexibleTableConfigType<Values>;
18
+ config: IFlexibleTableConfigType<Values>;
18
19
  enabledColumns?: Array<keyof Values>;
19
20
  rowAttributes?: Array<keyof Values>;
20
21
  expandableRowComponent?(item: Values, isOpen: boolean, close: () => void): ReactNode;
@@ -81,7 +82,7 @@ function FlexibleTableRowInner<Values extends Record<string, any>>({
81
82
  onRowClick?.(item[uniqueField]);
82
83
  }
83
84
 
84
- if (expandableRowComponent !== undefined) {
85
+ if (isNotEmpty(expandableRowComponent)) {
85
86
  const newNestedComponent = expandableRowComponent(item, true, closeNestedComponent);
86
87
 
87
88
  if (!nestedComponent.isOpen && newNestedComponent !== null) {
@@ -96,16 +97,16 @@ function FlexibleTableRowInner<Values extends Record<string, any>>({
96
97
  }
97
98
  };
98
99
 
99
- const items = enabledColumns ?? Object.keys(item);
100
+ const items = enabledColumns ?? Object.keys(config);
100
101
 
101
102
  return (
102
103
  <>
103
104
  <tr
104
- className={clsx(
105
- classes.root,
106
- isActive && classes.active,
107
- (onRowClick !== undefined || onRowHover !== undefined) && classes.editable,
108
- )}
105
+ className={clsx(classes.root, {
106
+ [classes.active]: isActive,
107
+ [classes.editable]: isNotEmpty(onRowClick) || isNotEmpty(onRowHover),
108
+ [classes.clickable]: isNotEmpty(onRowClick) || isNotEmpty(expandableRowComponent),
109
+ })}
109
110
  onMouseEnter={(e) => {
110
111
  if (uniqueField !== undefined && onRowHover !== undefined) {
111
112
  e.stopPropagation();
@@ -120,11 +121,11 @@ function FlexibleTableRowInner<Values extends Record<string, any>>({
120
121
  isExpandableComponentActive: nestedComponent.isOpen ? true : undefined,
121
122
  })}
122
123
  >
123
- {items.map((key, idx) => (
124
+ {items.map((key, i) => (
124
125
  <FlexibleTableCell
125
126
  columnName={key}
126
- isSticky={isFirstColumnSticky && idx === 0}
127
- isSecond={isFirstColumnSticky && idx === 1}
127
+ isSticky={isFirstColumnSticky && i === 0}
128
+ isSecond={isFirstColumnSticky && i === 1}
128
129
  key={key as string}
129
130
  item={item}
130
131
  config={config}
@@ -0,0 +1,15 @@
1
+ import { format } from 'date-fns';
2
+ import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
3
+ import { DEFAULT_DATE_FORMAT } from './constants';
4
+ import { IFlexibleTableConfigType } from './types';
5
+
6
+ export const hasHorizontalScrollBar = (el: HTMLElement | null | undefined): boolean =>
7
+ isNotEmpty(el) && el.scrollWidth !== el.clientWidth;
8
+
9
+ export const formatCellContent = <Values>(
10
+ value: unknown,
11
+ config?: IFlexibleTableConfigType<Values>[keyof Values],
12
+ ): string =>
13
+ value instanceof Date
14
+ ? format(value as Date, config?.dateFormat ?? DEFAULT_DATE_FORMAT)
15
+ : String(value);
@@ -23,7 +23,7 @@ export type IFlexibleTableConfigType<Values> = {
23
23
  [Key in keyof Values]?: {
24
24
  title?: ReactNode;
25
25
  titleComponent?: ITitleComponent<unknown>;
26
- component?: IValueComponent<Values, Values[Key]>;
26
+ component?: IValueComponent<Values, NonNullable<Values[Key]>>;
27
27
  dateFormat?: string;
28
28
  minWidth?: string | number;
29
29
  width?: string | number;
@@ -1 +1 @@
1
- declare module '*.svg?raw';
1
+ declare module '*.svg?raw';
@@ -1,58 +1,58 @@
1
- <svg
2
- width="100%"
3
- height="100%"
4
- viewBox="0 0 32 32"
5
- fill="none"
6
- xmlns="http://www.w3.org/2000/svg"
7
- >
8
- <circle opacity="0.5" cx="16" cy="16" r="16" fill="#DDE3ED" />
9
- <mask
10
- id="mask0_0_12744"
11
- style="mask-type: 'alpha';"
12
- maskUnits="userSpaceOnUse"
13
- x="0"
14
- y="0"
15
- width="32"
16
- height="32"
17
- >
18
- <circle cx="16" cy="16" r="16" fill="white" />
19
- </mask>
20
- <g mask="url(#mask0_0_12744)">
21
- <circle cx="16" cy="29" r="13" fill="url(#paint0_linear_0_12744)" />
22
- <mask
23
- id="mask1_0_12744"
24
- style="mask-type: 'alpha';"
25
- maskUnits="userSpaceOnUse"
26
- x="3"
27
- y="16"
28
- width="26"
29
- height="26"
30
- >
31
- <circle cx="16" cy="29" r="13" fill="white" />
32
- </mask>
33
- <g mask="url(#mask1_0_12744)">
34
- <ellipse
35
- cx="16"
36
- cy="17.5"
37
- rx="6"
38
- ry="7.5"
39
- fill="#505F79"
40
- fill-opacity="0.204983"
41
- />
42
- </g>
43
- </g>
44
- <ellipse cx="16" cy="13" rx="6" ry="7" fill="white" />
45
- <defs>
46
- <linearGradient
47
- id="paint0_linear_0_12744"
48
- x1="13.347"
49
- y1="46.279"
50
- x2="33.5318"
51
- y2="30.8088"
52
- gradientUnits="userSpaceOnUse"
53
- >
54
- <stop stop-color="#ABD229" />
55
- <stop offset="1" stop-color="#9CD03F" />
56
- </linearGradient>
57
- </defs>
1
+ <svg
2
+ width="100%"
3
+ height="100%"
4
+ viewBox="0 0 32 32"
5
+ fill="none"
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ >
8
+ <circle opacity="0.5" cx="16" cy="16" r="16" fill="#DDE3ED" />
9
+ <mask
10
+ id="mask0_0_12744"
11
+ style="mask-type: 'alpha';"
12
+ maskUnits="userSpaceOnUse"
13
+ x="0"
14
+ y="0"
15
+ width="32"
16
+ height="32"
17
+ >
18
+ <circle cx="16" cy="16" r="16" fill="white" />
19
+ </mask>
20
+ <g mask="url(#mask0_0_12744)">
21
+ <circle cx="16" cy="29" r="13" fill="url(#paint0_linear_0_12744)" />
22
+ <mask
23
+ id="mask1_0_12744"
24
+ style="mask-type: 'alpha';"
25
+ maskUnits="userSpaceOnUse"
26
+ x="3"
27
+ y="16"
28
+ width="26"
29
+ height="26"
30
+ >
31
+ <circle cx="16" cy="29" r="13" fill="white" />
32
+ </mask>
33
+ <g mask="url(#mask1_0_12744)">
34
+ <ellipse
35
+ cx="16"
36
+ cy="17.5"
37
+ rx="6"
38
+ ry="7.5"
39
+ fill="#505F79"
40
+ fill-opacity="0.204983"
41
+ />
42
+ </g>
43
+ </g>
44
+ <ellipse cx="16" cy="13" rx="6" ry="7" fill="white" />
45
+ <defs>
46
+ <linearGradient
47
+ id="paint0_linear_0_12744"
48
+ x1="13.347"
49
+ y1="46.279"
50
+ x2="33.5318"
51
+ y2="30.8088"
52
+ gradientUnits="userSpaceOnUse"
53
+ >
54
+ <stop stop-color="#ABD229" />
55
+ <stop offset="1" stop-color="#9CD03F" />
56
+ </linearGradient>
57
+ </defs>
58
58
  </svg>
@@ -1 +1 @@
1
- export * from './icons';
1
+ export * from './icons';
@@ -1,4 +1,4 @@
1
- import { FC, Fragment } from 'react';
1
+ import { FC, Fragment, MouseEvent } from 'react';
2
2
  import clsx from 'clsx';
3
3
  import {
4
4
  addDataTestId,
@@ -13,15 +13,15 @@ import { useStyles, IListStyles } from './List.styles';
13
13
 
14
14
  export interface IListProps extends ICommonProps<IListStyles> {
15
15
  items: IListItem[];
16
- onClick?(): void;
16
+ onClick?(event: MouseEvent): void;
17
17
  }
18
18
 
19
19
  export const List: FC<IListProps> = ({ items, testId, data, tweakStyles, onClick }) => {
20
20
  const classes = useStyles({ theme: tweakStyles });
21
21
 
22
- const handleItemClick = (item: IListItem) => {
23
- item.onClick();
24
- onClick?.();
22
+ const handleItemClick = (event: MouseEvent, item: IListItem) => {
23
+ item.onClick(event);
24
+ onClick?.(event);
25
25
  };
26
26
 
27
27
  return (
@@ -34,7 +34,7 @@ export const List: FC<IListProps> = ({ items, testId, data, tweakStyles, onClick
34
34
  [classes.disabledItem]: item.disabled,
35
35
  [classes.withIconGap]: item.withIconGap,
36
36
  })}
37
- onClick={item.disabled ? undefined : () => handleItemClick(item)}
37
+ onClick={item.disabled ? undefined : (event) => handleItemClick(event, item)}
38
38
  {...addDataTestId(item.testId ?? getTestId(testId, `item-${idx}`))}
39
39
  {...(item.disabled && addDataAttributes({ disabled: item.disabled }))}
40
40
  >
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import { ReactNode, MouseEvent } from 'react';
2
2
  import { IIcon } from '../../types';
3
3
 
4
4
  export interface IListItem {
@@ -9,5 +9,5 @@ export interface IListItem {
9
9
  shouldDrawSpacerBelow?: boolean;
10
10
  withIconGap?: boolean;
11
11
  testId?: string;
12
- onClick(): void;
12
+ onClick(event: MouseEvent): void;
13
13
  }