@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.
- package/LICENSE +201 -201
- package/dist/components/Checkbox/Checkbox.d.ts +1 -1
- package/dist/components/FiltersPane/components/FilterSelect/FilterSelect.d.ts +1 -5
- package/dist/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.d.ts +1 -3
- package/dist/components/Flag/augment.d.ts +1 -1
- package/dist/components/FlexibleTable/FlexibleTable.d.ts +6 -2
- package/dist/components/FlexibleTable/FlexibleTable.styles.d.ts +1 -1
- package/dist/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.d.ts +1 -1
- package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.d.ts +1 -1
- package/dist/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.d.ts +1 -1
- package/dist/components/FlexibleTable/helpers.d.ts +3 -0
- package/dist/components/FlexibleTable/types.d.ts +1 -1
- package/dist/components/Icon/complexIcons/augment.d.ts +1 -1
- package/dist/components/List/List.d.ts +2 -2
- package/dist/components/List/types.d.ts +2 -2
- package/dist/components/MultiSelectList/MultiSelectList.d.ts +1 -2
- package/dist/components/Skeleton/Skeleton.d.ts +7 -0
- package/dist/components/Skeleton/Skeleton.styles.d.ts +3 -0
- package/dist/components/Skeleton/index.d.ts +2 -0
- package/dist/components/Switch/Switch.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/helpers/phone.d.ts +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/use-merged-refs.d.ts +2 -0
- package/dist/theme/types.d.ts +2 -1
- package/dist/true-react-common-ui-kit.js +1162 -819
- package/dist/true-react-common-ui-kit.js.map +1 -1
- package/dist/true-react-common-ui-kit.umd.cjs +1161 -818
- package/dist/true-react-common-ui-kit.umd.cjs.map +1 -1
- package/dist/vite-env.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/AddButton/AddButton.stories.tsx +21 -21
- package/src/components/Checkbox/Checkbox.tsx +1 -1
- package/src/components/Colors/Colors.stories.tsx +7 -7
- package/src/components/DateInput/DateInput.tsx +1 -9
- package/src/components/DateInput/constants.ts +2 -2
- package/src/components/DatePicker/DatePicker.stories.tsx +1 -0
- package/src/components/DatePicker/DatePicker.tsx +1 -3
- package/src/components/FiltersPane/FiltersPane.stories.tsx +0 -8
- package/src/components/FiltersPane/components/FilterInterval/FilterInterval.styles.ts +2 -1
- package/src/components/FiltersPane/components/FilterSelect/FilterSelect.styles.ts +3 -1
- package/src/components/FiltersPane/components/FilterSelect/FilterSelect.tsx +1 -6
- package/src/components/FiltersPane/components/FilterWithDates/FilterWithDates.styles.ts +2 -1
- package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.styles.ts +1 -0
- package/src/components/FiltersPane/components/FiltersPaneSearch/FiltersPaneSearch.tsx +1 -4
- package/src/components/FiltersPane/types.ts +1 -1
- package/src/components/Flag/augment.d.ts +1 -1
- package/src/components/FlexibleTable/FlexibleTable.stories.tsx +15 -12
- package/src/components/FlexibleTable/FlexibleTable.styles.ts +9 -10
- package/src/components/FlexibleTable/FlexibleTable.tsx +124 -60
- package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.styles.ts +4 -0
- package/src/components/FlexibleTable/components/FlexibleTableCell/FlexibleTableCell.tsx +25 -27
- package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.styles.ts +4 -0
- package/src/components/FlexibleTable/components/FlexibleTableRow/FlexibleTableRow.tsx +12 -11
- package/src/components/FlexibleTable/helpers.ts +15 -0
- package/src/components/FlexibleTable/types.ts +1 -1
- package/src/components/Icon/complexIcons/augment.d.ts +1 -1
- package/src/components/Icon/complexIcons/avatarGreen.svg +57 -57
- package/src/components/Icon/complexIcons/index.ts +1 -1
- package/src/components/List/List.tsx +6 -6
- package/src/components/List/types.ts +2 -2
- package/src/components/MoreMenu/MoreMenu.stories.tsx +46 -46
- package/src/components/MultiSelectList/MultiSelectList.styles.ts +4 -0
- package/src/components/MultiSelectList/MultiSelectList.tsx +1 -3
- package/src/components/NumberInput/index.ts +1 -1
- package/src/components/PhoneInput/types.ts +16 -16
- package/src/components/ScrollIntoViewIfNeeded/index.ts +1 -1
- package/src/components/Select/constants.ts +2 -2
- package/src/components/Select/types.ts +1 -1
- package/src/components/Skeleton/Skeleton.stories.tsx +19 -0
- package/src/components/Skeleton/Skeleton.styles.ts +46 -0
- package/src/components/Skeleton/Skeleton.tsx +12 -0
- package/src/components/Skeleton/index.ts +2 -0
- package/src/components/Switch/Switch.tsx +2 -2
- package/src/components/TextWithTooltip/TextWithTooltip.stories.tsx +58 -58
- package/src/components/ThemedPreloader/components/DefaultPreloader/index.ts +1 -1
- package/src/components/Tooltip/types.ts +1 -1
- package/src/components/index.ts +1 -0
- package/src/helpers/phone.ts +1 -1
- package/src/helpers/popper-helpers.ts +17 -17
- package/src/hooks/index.ts +1 -0
- package/src/hooks/use-is-mounted.ts +15 -15
- package/src/hooks/use-merged-refs.ts +4 -0
- package/src/theme/types.ts +2 -0
- package/src/vite-env.d.ts +1 -1
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { ReactNode, RefObject, useCallback, useEffect,
|
|
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
|
|
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 =
|
|
101
|
-
if (scrollContainer
|
|
147
|
+
const scrollContainer = scrollRef.current;
|
|
148
|
+
if (isEmpty(scrollContainer) || !isHorizontallyScrollable) {
|
|
102
149
|
return;
|
|
103
150
|
}
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
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.
|
|
136
|
-
isFirstColumnSticky &&
|
|
137
|
-
|
|
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
|
-
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
|
-
import {
|
|
3
|
+
import { isNotEmpty } from '@true-engineering/true-react-platform-helpers';
|
|
4
4
|
import type { ICommonProps } from '../../../../types';
|
|
5
|
-
import {
|
|
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
|
|
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
|
|
37
|
-
|
|
38
|
-
let content = null;
|
|
36
|
+
const { component, cellAlign, position, right, left, cellVerticalAlign } =
|
|
37
|
+
config[columnName] ?? {};
|
|
39
38
|
|
|
40
|
-
|
|
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:
|
|
62
|
-
position: isSticky ? 'sticky' :
|
|
63
|
-
right
|
|
64
|
-
left: isSticky ? 0 :
|
|
65
|
-
verticalAlign:
|
|
46
|
+
textAlign: cellAlign,
|
|
47
|
+
position: isSticky ? 'sticky' : position,
|
|
48
|
+
right,
|
|
49
|
+
left: isSticky ? 0 : left,
|
|
50
|
+
verticalAlign: cellVerticalAlign,
|
|
66
51
|
}}
|
|
67
52
|
>
|
|
68
|
-
{
|
|
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
|
}
|
|
@@ -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
|
|
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
|
|
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(
|
|
100
|
+
const items = enabledColumns ?? Object.keys(config);
|
|
100
101
|
|
|
101
102
|
return (
|
|
102
103
|
<>
|
|
103
104
|
<tr
|
|
104
|
-
className={clsx(
|
|
105
|
-
classes.
|
|
106
|
-
|
|
107
|
-
(onRowClick
|
|
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,
|
|
124
|
+
{items.map((key, i) => (
|
|
124
125
|
<FlexibleTableCell
|
|
125
126
|
columnName={key}
|
|
126
|
-
isSticky={isFirstColumnSticky &&
|
|
127
|
-
isSecond={isFirstColumnSticky &&
|
|
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
|
}
|