@qoretechnologies/reqore 0.35.1 → 0.35.2
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/__tests__/helpers/table.test.tsx +20 -0
- package/dist/components/ControlGroup/index.d.ts.map +1 -1
- package/dist/components/ControlGroup/index.js +1 -1
- package/dist/components/ControlGroup/index.js.map +1 -1
- package/dist/components/Dropdown/list.d.ts +1 -0
- package/dist/components/Dropdown/list.d.ts.map +1 -1
- package/dist/components/Dropdown/list.js.map +1 -1
- package/dist/components/Menu/divider.d.ts +1 -0
- package/dist/components/Menu/divider.d.ts.map +1 -1
- package/dist/components/Menu/divider.js +3 -2
- package/dist/components/Menu/divider.js.map +1 -1
- package/dist/components/Spacer/index.d.ts.map +1 -1
- package/dist/components/Spacer/index.js +1 -1
- package/dist/components/Spacer/index.js.map +1 -1
- package/dist/components/Table/body.d.ts +10 -3
- package/dist/components/Table/body.d.ts.map +1 -1
- package/dist/components/Table/body.js +40 -9
- package/dist/components/Table/body.js.map +1 -1
- package/dist/components/Table/cell.d.ts.map +1 -1
- package/dist/components/Table/cell.js +2 -2
- package/dist/components/Table/cell.js.map +1 -1
- package/dist/components/Table/header.d.ts +8 -7
- package/dist/components/Table/header.d.ts.map +1 -1
- package/dist/components/Table/header.js +34 -37
- package/dist/components/Table/header.js.map +1 -1
- package/dist/components/Table/headerCell.d.ts +2 -2
- package/dist/components/Table/headerCell.d.ts.map +1 -1
- package/dist/components/Table/headerCell.js +25 -7
- package/dist/components/Table/headerCell.js.map +1 -1
- package/dist/components/Table/helpers.d.ts +2 -0
- package/dist/components/Table/helpers.d.ts.map +1 -1
- package/dist/components/Table/helpers.js +28 -2
- package/dist/components/Table/helpers.js.map +1 -1
- package/dist/components/Table/index.d.ts +6 -1
- package/dist/components/Table/index.d.ts.map +1 -1
- package/dist/components/Table/index.js +167 -15
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/Table/row.d.ts.map +1 -1
- package/dist/components/Table/row.js +17 -28
- package/dist/components/Table/row.js.map +1 -1
- package/dist/constants/sizes.d.ts +15 -0
- package/dist/constants/sizes.d.ts.map +1 -1
- package/dist/constants/sizes.js +16 -1
- package/dist/constants/sizes.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ControlGroup/index.tsx +1 -0
- package/src/components/Dropdown/list.tsx +1 -0
- package/src/components/Menu/divider.tsx +31 -21
- package/src/components/Spacer/index.tsx +2 -2
- package/src/components/Table/body.tsx +81 -35
- package/src/components/Table/cell.tsx +4 -1
- package/src/components/Table/header.tsx +133 -124
- package/src/components/Table/headerCell.tsx +34 -8
- package/src/components/Table/helpers.ts +42 -2
- package/src/components/Table/index.tsx +213 -45
- package/src/components/Table/row.tsx +34 -53
- package/src/constants/sizes.ts +17 -0
- package/src/stories/Breadcrumbs/Breadcrumbs.stories.tsx +0 -3
- package/src/stories/Table/Table.stories.tsx +78 -0
- package/tests.json +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* @flow */
|
|
2
2
|
import { size as count, isArray } from 'lodash';
|
|
3
|
-
import React, { useCallback, useMemo, useState } from 'react';
|
|
3
|
+
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
4
4
|
import { useMeasure, useUpdateEffect } from 'react-use';
|
|
5
|
+
import styled, { css } from 'styled-components';
|
|
5
6
|
import { ReqoreMessage, ReqorePanel, ReqoreVerticalSpacer } from '../..';
|
|
6
7
|
import { TABLE_SIZE_TO_PX, TSizes } from '../../constants/sizes';
|
|
7
8
|
import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
|
|
@@ -17,9 +18,11 @@ import { IReqoreTableHeaderCellProps } from './headerCell';
|
|
|
17
18
|
import {
|
|
18
19
|
fixSort,
|
|
19
20
|
flipSortDirection,
|
|
21
|
+
getColumnsByPinType,
|
|
20
22
|
getColumnsCount,
|
|
21
23
|
getOnlyShownColumns,
|
|
22
24
|
getZoomActions,
|
|
25
|
+
hasGroupedColumns,
|
|
23
26
|
hasHiddenColumns,
|
|
24
27
|
prepareColumns,
|
|
25
28
|
sizeToZoom,
|
|
@@ -44,12 +47,16 @@ export interface IReqoreTableColumn extends IReqoreIntent {
|
|
|
44
47
|
show?: boolean;
|
|
45
48
|
grow?: 1 | 2 | 3 | 4;
|
|
46
49
|
width?: number;
|
|
50
|
+
minWidth?: number;
|
|
51
|
+
maxWidth?: number;
|
|
47
52
|
resizedWidth?: number;
|
|
48
53
|
align?: 'center' | 'left' | 'right';
|
|
54
|
+
pin?: 'left' | 'right';
|
|
49
55
|
|
|
50
56
|
resizable?: boolean;
|
|
51
57
|
sortable?: boolean;
|
|
52
58
|
hideable?: boolean;
|
|
59
|
+
pinnable?: boolean;
|
|
53
60
|
|
|
54
61
|
filterable?: boolean;
|
|
55
62
|
filterPlaceholder?: string;
|
|
@@ -59,12 +66,13 @@ export interface IReqoreTableColumn extends IReqoreIntent {
|
|
|
59
66
|
columns?: IReqoreTableColumn[];
|
|
60
67
|
component?: React.FC<IReqoreTableHeaderCellProps>;
|
|
61
68
|
actions?: IReqoreDropdownItem[];
|
|
62
|
-
} & IReqoreButtonProps
|
|
69
|
+
} & Omit<IReqoreButtonProps, 'maxWidth'>;
|
|
63
70
|
|
|
64
71
|
cell?: {
|
|
65
72
|
onClick?: (cellValue: any) => void;
|
|
66
73
|
tooltip?: (cellValue: any) => string | IReqoreTooltip;
|
|
67
74
|
content?: TReqoreTableColumnContent;
|
|
75
|
+
actions?: (data: IReqoreTableRowData) => IReqoreButtonProps[];
|
|
68
76
|
intent?: TReqoreIntent;
|
|
69
77
|
padded?: 'both' | 'horizontal' | 'vertical' | 'none';
|
|
70
78
|
};
|
|
@@ -131,6 +139,28 @@ export interface IReqoreTableSort {
|
|
|
131
139
|
direction?: 'asc' | 'desc';
|
|
132
140
|
}
|
|
133
141
|
|
|
142
|
+
const StyledTableWrapper = styled.div`
|
|
143
|
+
overflow: hidden;
|
|
144
|
+
|
|
145
|
+
${({ isPinned }) =>
|
|
146
|
+
isPinned
|
|
147
|
+
? css`
|
|
148
|
+
flex-shrink: 0;
|
|
149
|
+
`
|
|
150
|
+
: css`
|
|
151
|
+
width: 100%;
|
|
152
|
+
display: flex;
|
|
153
|
+
flex-flow: column;
|
|
154
|
+
flex: 1;
|
|
155
|
+
`};
|
|
156
|
+
`;
|
|
157
|
+
|
|
158
|
+
const StyledTablesWrapper = styled.div`
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-flow: row;
|
|
161
|
+
overflow: hidden;
|
|
162
|
+
`;
|
|
163
|
+
|
|
134
164
|
const ReqoreTable = ({
|
|
135
165
|
className,
|
|
136
166
|
height = 300,
|
|
@@ -146,7 +176,7 @@ const ReqoreTable = ({
|
|
|
146
176
|
customTheme,
|
|
147
177
|
onRowClick,
|
|
148
178
|
striped,
|
|
149
|
-
selectedRowIntent,
|
|
179
|
+
selectedRowIntent = 'info',
|
|
150
180
|
size = 'normal',
|
|
151
181
|
wrapperSize = 'normal',
|
|
152
182
|
intent,
|
|
@@ -164,13 +194,18 @@ const ReqoreTable = ({
|
|
|
164
194
|
onSelectClick,
|
|
165
195
|
...rest
|
|
166
196
|
}: IReqoreTableProps) => {
|
|
167
|
-
const
|
|
197
|
+
const leftTableRef = useRef<HTMLDivElement>(undefined);
|
|
198
|
+
const rightTableRef = useRef<HTMLDivElement>(undefined);
|
|
199
|
+
const mainTableRef = useRef<HTMLDivElement>(undefined);
|
|
200
|
+
const mainHeaderRef = useRef<HTMLDivElement>(undefined);
|
|
201
|
+
|
|
202
|
+
const [isScrolled, setIsScrolled] = useState<boolean>(false);
|
|
168
203
|
const [_data, setData] = useState<IReqoreTableData>(data || []);
|
|
169
204
|
const [_sort, setSort] = useState<IReqoreTableSort>(fixSort(sort));
|
|
170
|
-
const [_selected, setSelected] = useState<(string | number)[]>([]);
|
|
205
|
+
const [_selected, setSelected] = useState<(string | number)[]>(selected || []);
|
|
171
206
|
const [_selectedQuant, setSelectedQuant] = useState<'all' | 'none' | 'some'>('none');
|
|
172
207
|
const [columnModifiers, setColumnModifiers] = useState<{
|
|
173
|
-
[
|
|
208
|
+
[dataId: string]: { [modifier: string]: any };
|
|
174
209
|
}>({});
|
|
175
210
|
const [_internalColumns, setColumns] = useState<IReqoreTableColumn[]>(columns);
|
|
176
211
|
const [zoom, setZoom] = useState<number>(sizeToZoom[size]);
|
|
@@ -178,10 +213,74 @@ const ReqoreTable = ({
|
|
|
178
213
|
const [wrapperRef, sizes] = useMeasure();
|
|
179
214
|
const { query, preQuery, setQuery, setPreQuery } = useQueryWithDelay(filter, 300, onFilterChange);
|
|
180
215
|
|
|
181
|
-
const
|
|
182
|
-
()
|
|
183
|
-
|
|
184
|
-
|
|
216
|
+
const selectedIcon = useMemo(() => {
|
|
217
|
+
switch (_selectedQuant) {
|
|
218
|
+
case 'all':
|
|
219
|
+
return 'CheckboxCircleLine';
|
|
220
|
+
case 'some':
|
|
221
|
+
return 'IndeterminateCircleLine';
|
|
222
|
+
default:
|
|
223
|
+
return 'CheckboxBlankCircleLine';
|
|
224
|
+
}
|
|
225
|
+
}, [_selectedQuant]);
|
|
226
|
+
|
|
227
|
+
const finalColumns = useMemo(() => {
|
|
228
|
+
let fullColumns = [..._internalColumns];
|
|
229
|
+
|
|
230
|
+
if (selectable) {
|
|
231
|
+
fullColumns.unshift({
|
|
232
|
+
dataId: 'selectbox',
|
|
233
|
+
width: 50,
|
|
234
|
+
sortable: false,
|
|
235
|
+
hideable: false,
|
|
236
|
+
filterable: false,
|
|
237
|
+
resizable: false,
|
|
238
|
+
pin: 'left',
|
|
239
|
+
pinnable: false,
|
|
240
|
+
align: 'center',
|
|
241
|
+
|
|
242
|
+
header: {
|
|
243
|
+
icon: selectedIcon,
|
|
244
|
+
tooltip: 'Toggle selection on all data',
|
|
245
|
+
onClick: () => {
|
|
246
|
+
handleToggleSelectClick();
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
|
|
250
|
+
cell: {
|
|
251
|
+
padded: 'none',
|
|
252
|
+
actions: ({ _selectId }) => [
|
|
253
|
+
{
|
|
254
|
+
tooltip: selectToggleTooltip,
|
|
255
|
+
icon: !_selectId
|
|
256
|
+
? 'Forbid2Line'
|
|
257
|
+
: _selected?.find((s) => s === _selectId)
|
|
258
|
+
? 'CheckboxCircleLine'
|
|
259
|
+
: 'CheckboxBlankCircleLine',
|
|
260
|
+
intent: !_selectId
|
|
261
|
+
? 'muted'
|
|
262
|
+
: _selected?.find((s) => s === _selectId)
|
|
263
|
+
? selectedRowIntent
|
|
264
|
+
: undefined,
|
|
265
|
+
onClick: () => handleSelectClick(_selectId),
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return prepareColumns(fullColumns, columnModifiers, zoomToSize[zoom]);
|
|
273
|
+
}, [
|
|
274
|
+
_internalColumns,
|
|
275
|
+
columnModifiers,
|
|
276
|
+
zoom,
|
|
277
|
+
selectable,
|
|
278
|
+
_selectedQuant,
|
|
279
|
+
selectedIcon,
|
|
280
|
+
selectToggleTooltip,
|
|
281
|
+
_selected,
|
|
282
|
+
selectedRowIntent,
|
|
283
|
+
]);
|
|
185
284
|
|
|
186
285
|
const filters: { [key: string]: string } = useMemo(() => {
|
|
187
286
|
const getFilters = (columnsToTransform: IReqoreTableColumn[]) =>
|
|
@@ -353,6 +452,10 @@ const ReqoreTable = ({
|
|
|
353
452
|
};
|
|
354
453
|
|
|
355
454
|
finalColumns.forEach((column) => {
|
|
455
|
+
if (column.hideable === false) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
356
459
|
if (column.header?.columns) {
|
|
357
460
|
column.header?.columns.forEach((subColumn) => {
|
|
358
461
|
addColumn(subColumn);
|
|
@@ -406,6 +509,31 @@ const ReqoreTable = ({
|
|
|
406
509
|
});
|
|
407
510
|
}
|
|
408
511
|
|
|
512
|
+
if (isScrolled) {
|
|
513
|
+
finalActions.push({
|
|
514
|
+
icon: 'ArrowUpSFill',
|
|
515
|
+
tooltip: 'Scroll to top',
|
|
516
|
+
className: 'reqore-table-columns-scroll-top',
|
|
517
|
+
responsive: true,
|
|
518
|
+
onClick: () => {
|
|
519
|
+
mainTableRef.current?.scrollTo({
|
|
520
|
+
top: 0,
|
|
521
|
+
behavior: 'smooth',
|
|
522
|
+
});
|
|
523
|
+
leftTableRef.current?.scrollTo({
|
|
524
|
+
top: 0,
|
|
525
|
+
behavior: 'smooth',
|
|
526
|
+
});
|
|
527
|
+
rightTableRef.current?.scrollTo({
|
|
528
|
+
top: 0,
|
|
529
|
+
behavior: 'smooth',
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
setIsScrolled(false);
|
|
533
|
+
},
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
|
|
409
537
|
if (count(columnModifiers) || zoomable || filterable) {
|
|
410
538
|
finalActions.push({
|
|
411
539
|
icon: 'MoreLine',
|
|
@@ -437,6 +565,7 @@ const ReqoreTable = ({
|
|
|
437
565
|
zoomable,
|
|
438
566
|
zoom,
|
|
439
567
|
columnsList,
|
|
568
|
+
isScrolled,
|
|
440
569
|
]);
|
|
441
570
|
|
|
442
571
|
const badge = useMemo(() => {
|
|
@@ -453,12 +582,80 @@ const ReqoreTable = ({
|
|
|
453
582
|
return badgeList;
|
|
454
583
|
}, [transformedData, rest.badge]);
|
|
455
584
|
|
|
585
|
+
const refs = {
|
|
586
|
+
left: leftTableRef,
|
|
587
|
+
right: rightTableRef,
|
|
588
|
+
main: mainTableRef,
|
|
589
|
+
header: mainHeaderRef,
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
const columnsByType = useMemo(
|
|
593
|
+
() => ({
|
|
594
|
+
left: getColumnsByPinType(finalColumns, 'left'),
|
|
595
|
+
right: getColumnsByPinType(finalColumns, 'right'),
|
|
596
|
+
main: getColumnsByPinType(finalColumns, 'main'),
|
|
597
|
+
}),
|
|
598
|
+
[finalColumns]
|
|
599
|
+
);
|
|
600
|
+
|
|
601
|
+
const renderTable = (type: 'left' | 'main' | 'right' = 'main') => {
|
|
602
|
+
const tableColumns = columnsByType[type];
|
|
603
|
+
const isPinned = type === 'left' || type === 'right';
|
|
604
|
+
|
|
605
|
+
if (count(tableColumns) === 0) {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return (
|
|
610
|
+
<StyledTableWrapper isPinned={isPinned}>
|
|
611
|
+
<ReqoreTableHeader
|
|
612
|
+
size={zoomToSize[zoom]}
|
|
613
|
+
columns={tableColumns}
|
|
614
|
+
scrollable={type === 'main'}
|
|
615
|
+
ref={type === 'main' ? mainHeaderRef : undefined}
|
|
616
|
+
bodyRef={mainTableRef}
|
|
617
|
+
onSortChange={handleSortChange}
|
|
618
|
+
heightAsGroup={hasGroupedColumns(finalColumns)}
|
|
619
|
+
sortData={_sort}
|
|
620
|
+
hasVerticalScroll={count(transformedData) * TABLE_SIZE_TO_PX[size] > height}
|
|
621
|
+
onColumnsUpdate={handleColumnsUpdate}
|
|
622
|
+
onFilterChange={(dataId: string, value: any) => {
|
|
623
|
+
handleColumnsUpdate(dataId, 'filter', value);
|
|
624
|
+
}}
|
|
625
|
+
component={headerCellComponent}
|
|
626
|
+
/>
|
|
627
|
+
{count(transformedData) === 0 ? null : (
|
|
628
|
+
<ReqoreTableBody
|
|
629
|
+
ref={refs[type]}
|
|
630
|
+
refs={refs}
|
|
631
|
+
type={type}
|
|
632
|
+
data={transformedData}
|
|
633
|
+
columns={tableColumns}
|
|
634
|
+
height={fill ? sizes.height : height}
|
|
635
|
+
selectable={selectable}
|
|
636
|
+
onSelectClick={handleSelectClick}
|
|
637
|
+
onRowClick={onRowClick}
|
|
638
|
+
onScrollChange={(isScrolled) => setIsScrolled(isScrolled)}
|
|
639
|
+
selected={_selected}
|
|
640
|
+
selectedRowIntent={selectedRowIntent}
|
|
641
|
+
size={zoomToSize[zoom]}
|
|
642
|
+
striped={striped}
|
|
643
|
+
flat={rest.flat}
|
|
644
|
+
rowComponent={rowComponent}
|
|
645
|
+
cellComponent={bodyCellComponent}
|
|
646
|
+
/>
|
|
647
|
+
)}
|
|
648
|
+
</StyledTableWrapper>
|
|
649
|
+
);
|
|
650
|
+
};
|
|
651
|
+
|
|
456
652
|
return (
|
|
457
653
|
<ReqorePanel
|
|
458
654
|
transparent
|
|
459
655
|
flat
|
|
460
656
|
padded={false}
|
|
461
657
|
contentStyle={{ display: 'flex', flexFlow: 'column', overflow: 'hidden' }}
|
|
658
|
+
responsiveActions={false}
|
|
462
659
|
{...rest}
|
|
463
660
|
size={wrapperSize}
|
|
464
661
|
actions={tableActions}
|
|
@@ -468,23 +665,11 @@ const ReqoreTable = ({
|
|
|
468
665
|
getContentRef={wrapperRef}
|
|
469
666
|
badge={badge}
|
|
470
667
|
>
|
|
471
|
-
<
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
sortData={_sort}
|
|
477
|
-
selectable={selectable}
|
|
478
|
-
selectedQuant={_selectedQuant}
|
|
479
|
-
onToggleSelectClick={handleToggleSelectClick}
|
|
480
|
-
hasVerticalScroll={count(transformedData) * TABLE_SIZE_TO_PX[size] > height}
|
|
481
|
-
selectToggleTooltip={selectToggleTooltip}
|
|
482
|
-
onColumnsUpdate={handleColumnsUpdate}
|
|
483
|
-
onFilterChange={(dataId: string, value: any) => {
|
|
484
|
-
handleColumnsUpdate(dataId, 'filter', value);
|
|
485
|
-
}}
|
|
486
|
-
component={headerCellComponent}
|
|
487
|
-
/>
|
|
668
|
+
<StyledTablesWrapper className='reqore-table-wrapper'>
|
|
669
|
+
{renderTable('left')}
|
|
670
|
+
{renderTable()}
|
|
671
|
+
{renderTable('right')}
|
|
672
|
+
</StyledTablesWrapper>
|
|
488
673
|
{count(transformedData) === 0 ? (
|
|
489
674
|
<>
|
|
490
675
|
<ReqoreVerticalSpacer height={10} />
|
|
@@ -492,24 +677,7 @@ const ReqoreTable = ({
|
|
|
492
677
|
{emptyMessage}
|
|
493
678
|
</ReqoreMessage>
|
|
494
679
|
</>
|
|
495
|
-
) :
|
|
496
|
-
<ReqoreTableBody
|
|
497
|
-
data={transformedData}
|
|
498
|
-
columns={finalColumns}
|
|
499
|
-
setLeftScroll={setLeftScroll}
|
|
500
|
-
height={fill ? sizes.height : height}
|
|
501
|
-
selectable={selectable}
|
|
502
|
-
onSelectClick={handleSelectClick}
|
|
503
|
-
onRowClick={onRowClick}
|
|
504
|
-
selected={_selected}
|
|
505
|
-
selectedRowIntent={selectedRowIntent}
|
|
506
|
-
size={zoomToSize[zoom]}
|
|
507
|
-
striped={striped}
|
|
508
|
-
flat={rest.flat}
|
|
509
|
-
rowComponent={rowComponent}
|
|
510
|
-
cellComponent={bodyCellComponent}
|
|
511
|
-
/>
|
|
512
|
-
)}
|
|
680
|
+
) : null}
|
|
513
681
|
</ReqorePanel>
|
|
514
682
|
);
|
|
515
683
|
};
|
|
@@ -2,24 +2,18 @@
|
|
|
2
2
|
import { isFunction, isString } from 'lodash';
|
|
3
3
|
import React, { ReactElement, useState } from 'react';
|
|
4
4
|
import styled, { css } from 'styled-components';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
IReqoreTableData,
|
|
8
|
-
IReqoreTableRowClick,
|
|
9
|
-
TReqoreTableColumnContent,
|
|
10
|
-
} from '.';
|
|
11
|
-
import { ReqorePopover } from '../..';
|
|
5
|
+
import { IReqoreTableColumn, IReqoreTableData, IReqoreTableRowClick } from '.';
|
|
6
|
+
import { ReqoreButton, ReqoreControlGroup, ReqorePopover } from '../..';
|
|
12
7
|
import { SIZE_TO_PX, TSizes } from '../../constants/sizes';
|
|
13
8
|
import { IReqoreTheme, TReqoreIntent } from '../../constants/theme';
|
|
14
9
|
import { IReqoreTooltip } from '../../types/global';
|
|
15
10
|
import { TReqoreHexColor } from '../Effect';
|
|
16
11
|
import { ReqoreH4 } from '../Header';
|
|
17
|
-
import ReqoreIcon from '../Icon';
|
|
18
12
|
import { ReqoreP } from '../Paragraph';
|
|
19
13
|
import ReqoreTag from '../Tag';
|
|
20
14
|
import { TimeAgo } from '../TimeAgo';
|
|
21
15
|
import { IReqoreCustomTableBodyCell, ReqoreTableBodyCell } from './cell';
|
|
22
|
-
import {
|
|
16
|
+
import { getOnlyShownColumns } from './helpers';
|
|
23
17
|
|
|
24
18
|
export interface IReqoreTableRowOptions {
|
|
25
19
|
columns: IReqoreTableColumn[];
|
|
@@ -89,7 +83,7 @@ const ReqoreTableRow = ({
|
|
|
89
83
|
onRowClick,
|
|
90
84
|
striped,
|
|
91
85
|
size,
|
|
92
|
-
selectedRowIntent
|
|
86
|
+
selectedRowIntent,
|
|
93
87
|
flat,
|
|
94
88
|
cellComponent,
|
|
95
89
|
rowComponent,
|
|
@@ -104,10 +98,34 @@ const ReqoreTableRow = ({
|
|
|
104
98
|
const RowComponent = rowComponent || StyledTableRow;
|
|
105
99
|
|
|
106
100
|
const renderContent = (
|
|
107
|
-
|
|
101
|
+
cell: IReqoreTableColumn['cell'],
|
|
108
102
|
data: any,
|
|
109
|
-
dataId: string
|
|
103
|
+
dataId: string,
|
|
104
|
+
align?: 'center' | 'left' | 'right'
|
|
110
105
|
): ReactElement<any, any> => {
|
|
106
|
+
if (cell?.actions) {
|
|
107
|
+
return (
|
|
108
|
+
<ReqoreControlGroup size={size} stack fill fluid style={{ height: '100%' }} rounded={false}>
|
|
109
|
+
{cell.actions(data).map((action, index) => (
|
|
110
|
+
<ReqoreButton
|
|
111
|
+
key={index}
|
|
112
|
+
rounded={false}
|
|
113
|
+
iconsAlign={align === 'center' ? 'center' : 'sides'}
|
|
114
|
+
textAlign={align}
|
|
115
|
+
{...action}
|
|
116
|
+
onClick={(e) => {
|
|
117
|
+
e.stopPropagation();
|
|
118
|
+
|
|
119
|
+
action.onClick?.(e);
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
))}
|
|
123
|
+
</ReqoreControlGroup>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const content = cell?.content;
|
|
128
|
+
|
|
111
129
|
if (isFunction(content)) {
|
|
112
130
|
const Content = content;
|
|
113
131
|
|
|
@@ -156,7 +174,7 @@ const ReqoreTableRow = ({
|
|
|
156
174
|
|
|
157
175
|
const renderCells = (columns: IReqoreTableColumn[], data: IReqoreTableData) =>
|
|
158
176
|
getOnlyShownColumns(columns).map(
|
|
159
|
-
({ width, resizedWidth, grow, dataId, cell, header, align, intent }) => {
|
|
177
|
+
({ width, minWidth, maxWidth, resizedWidth, grow, dataId, cell, header, align, intent }) => {
|
|
160
178
|
if (header.columns) {
|
|
161
179
|
return renderCells(header.columns, data);
|
|
162
180
|
}
|
|
@@ -178,6 +196,8 @@ const ReqoreTableRow = ({
|
|
|
178
196
|
componentProps={
|
|
179
197
|
{
|
|
180
198
|
width: resizedWidth || width,
|
|
199
|
+
minWidth,
|
|
200
|
+
maxWidth,
|
|
181
201
|
grow,
|
|
182
202
|
align,
|
|
183
203
|
size,
|
|
@@ -209,7 +229,7 @@ const ReqoreTableRow = ({
|
|
|
209
229
|
}
|
|
210
230
|
{...tooltip}
|
|
211
231
|
>
|
|
212
|
-
{renderContent(cell
|
|
232
|
+
{renderContent(cell, data[index], dataId, align)}
|
|
213
233
|
</ReqorePopover>
|
|
214
234
|
);
|
|
215
235
|
}
|
|
@@ -230,45 +250,6 @@ const ReqoreTableRow = ({
|
|
|
230
250
|
setIsHovered(false);
|
|
231
251
|
}}
|
|
232
252
|
>
|
|
233
|
-
{selectable && (
|
|
234
|
-
<CellComponent
|
|
235
|
-
align='center'
|
|
236
|
-
width={calculateMinimumCellWidth(50, size)}
|
|
237
|
-
className='reqore-table-cell'
|
|
238
|
-
{...{
|
|
239
|
-
size,
|
|
240
|
-
striped,
|
|
241
|
-
disabled: data[index]._disabled,
|
|
242
|
-
selected: !!isSelected,
|
|
243
|
-
selectedIntent: selectedRowIntent,
|
|
244
|
-
flat,
|
|
245
|
-
even: index % 2 === 0 ? true : false,
|
|
246
|
-
intent: data[index]._intent,
|
|
247
|
-
hovered: isHovered,
|
|
248
|
-
interactiveCell: data[index]._selectId,
|
|
249
|
-
}}
|
|
250
|
-
onClick={
|
|
251
|
-
data[index]._selectId
|
|
252
|
-
? (e: React.MouseEvent<HTMLDivElement>) => {
|
|
253
|
-
e.stopPropagation();
|
|
254
|
-
onSelectClick(data[index]._selectId);
|
|
255
|
-
}
|
|
256
|
-
: undefined
|
|
257
|
-
}
|
|
258
|
-
>
|
|
259
|
-
<ReqoreIcon
|
|
260
|
-
icon={
|
|
261
|
-
!data[index]._selectId
|
|
262
|
-
? 'Forbid2Line'
|
|
263
|
-
: isSelected
|
|
264
|
-
? 'CheckboxCircleLine'
|
|
265
|
-
: 'CheckboxBlankCircleLine'
|
|
266
|
-
}
|
|
267
|
-
size={size}
|
|
268
|
-
style={{ opacity: !data[index]._selectId || !isSelected ? 0.4 : 1 }}
|
|
269
|
-
/>
|
|
270
|
-
</CellComponent>
|
|
271
|
-
)}
|
|
272
253
|
{renderCells(columns, data)}
|
|
273
254
|
</RowComponent>
|
|
274
255
|
);
|
package/src/constants/sizes.ts
CHANGED
|
@@ -11,6 +11,23 @@ export const ReqoreSizes = {
|
|
|
11
11
|
|
|
12
12
|
export const SIZES = ['tiny', 'small', 'normal', 'big', 'huge'] as const;
|
|
13
13
|
|
|
14
|
+
export const SIZE_TO_MODIFIER = {
|
|
15
|
+
tiny: 0.6,
|
|
16
|
+
small: 0.8,
|
|
17
|
+
normal: 1,
|
|
18
|
+
big: 1.2,
|
|
19
|
+
huge: 1.4,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const LINE_SIZE_TO_NUMBER = {
|
|
23
|
+
none: 0,
|
|
24
|
+
tiny: 1,
|
|
25
|
+
small: 1,
|
|
26
|
+
normal: 1.5,
|
|
27
|
+
big: 2,
|
|
28
|
+
huge: 3,
|
|
29
|
+
};
|
|
30
|
+
|
|
14
31
|
export const SIZE_TO_NUMBER = {
|
|
15
32
|
none: 0,
|
|
16
33
|
tiny: 1,
|
|
@@ -16,9 +16,6 @@ export default {
|
|
|
16
16
|
},
|
|
17
17
|
...SizeArg,
|
|
18
18
|
},
|
|
19
|
-
parameters: {
|
|
20
|
-
jest: ['breadcrumbs.test.tsx'],
|
|
21
|
-
},
|
|
22
19
|
} as ComponentMeta<typeof ReqoreBreadcrumbs & { withTabs?: boolean }>;
|
|
23
20
|
|
|
24
21
|
const Template: ComponentStory<typeof ReqoreBreadcrumbs & { withTabs?: boolean }> = (
|
|
@@ -20,6 +20,7 @@ const { createArg } = argManager<IReqoreTableProps>();
|
|
|
20
20
|
const defaultColumns: IReqoreTableColumn[] = [
|
|
21
21
|
{
|
|
22
22
|
dataId: 'id',
|
|
23
|
+
intent: 'info',
|
|
23
24
|
header: {
|
|
24
25
|
label: 'ID',
|
|
25
26
|
tooltip: 'Custom ID tooltip nice',
|
|
@@ -37,6 +38,8 @@ const defaultColumns: IReqoreTableColumn[] = [
|
|
|
37
38
|
columns: [
|
|
38
39
|
{
|
|
39
40
|
dataId: 'firstName',
|
|
41
|
+
minWidth: 50,
|
|
42
|
+
maxWidth: 500,
|
|
40
43
|
header: {
|
|
41
44
|
icon: 'SlideshowLine',
|
|
42
45
|
label: 'First Name',
|
|
@@ -158,6 +161,33 @@ const defaultColumns: IReqoreTableColumn[] = [
|
|
|
158
161
|
}),
|
|
159
162
|
},
|
|
160
163
|
},
|
|
164
|
+
{
|
|
165
|
+
dataId: 'actions',
|
|
166
|
+
header: {
|
|
167
|
+
icon: 'SettingsLine',
|
|
168
|
+
},
|
|
169
|
+
width: 100,
|
|
170
|
+
align: 'center',
|
|
171
|
+
pin: 'right',
|
|
172
|
+
|
|
173
|
+
cell: {
|
|
174
|
+
padded: 'none',
|
|
175
|
+
actions: () => [
|
|
176
|
+
{
|
|
177
|
+
icon: 'AddLine',
|
|
178
|
+
intent: 'info',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
icon: 'EditLine',
|
|
182
|
+
intent: 'warning',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
icon: 'DeleteBinLine',
|
|
186
|
+
intent: 'danger',
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
},
|
|
161
191
|
];
|
|
162
192
|
|
|
163
193
|
const defaultColumnsWithFilters = defaultColumns.map((column, index) => {
|
|
@@ -212,6 +242,41 @@ const defaultColumnsWithHiddenColumns = defaultColumns.map((column, index) => {
|
|
|
212
242
|
return column;
|
|
213
243
|
});
|
|
214
244
|
|
|
245
|
+
const defaultColumnsWithPinnedColumns = defaultColumns.map((column, index) => {
|
|
246
|
+
if (index === 0) {
|
|
247
|
+
return {
|
|
248
|
+
...column,
|
|
249
|
+
pin: 'left',
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (index === 1) {
|
|
254
|
+
return {
|
|
255
|
+
...column,
|
|
256
|
+
header: {
|
|
257
|
+
...column.header,
|
|
258
|
+
columns: column.header.columns.map((subColumn, subIndex) =>
|
|
259
|
+
subIndex === 1
|
|
260
|
+
? {
|
|
261
|
+
...subColumn,
|
|
262
|
+
pin: 'left',
|
|
263
|
+
}
|
|
264
|
+
: subColumn
|
|
265
|
+
),
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (index === 3) {
|
|
271
|
+
return {
|
|
272
|
+
...column,
|
|
273
|
+
pin: 'right',
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return column;
|
|
278
|
+
});
|
|
279
|
+
|
|
215
280
|
export default {
|
|
216
281
|
title: 'Collections/Table/Stories',
|
|
217
282
|
argTypes: {
|
|
@@ -330,11 +395,24 @@ HiddenColumns.args = {
|
|
|
330
395
|
columns: defaultColumnsWithHiddenColumns,
|
|
331
396
|
};
|
|
332
397
|
|
|
398
|
+
export const PinnedColumns = Template.bind({});
|
|
399
|
+
PinnedColumns.args = {
|
|
400
|
+
columns: defaultColumnsWithPinnedColumns,
|
|
401
|
+
zoomable: true,
|
|
402
|
+
filterable: true,
|
|
403
|
+
};
|
|
404
|
+
|
|
333
405
|
export const Selectable = Template.bind({});
|
|
334
406
|
Selectable.args = {
|
|
335
407
|
selectable: true,
|
|
336
408
|
};
|
|
337
409
|
|
|
410
|
+
export const PreselectedRows = Template.bind({});
|
|
411
|
+
PreselectedRows.args = {
|
|
412
|
+
selected: [274, 280],
|
|
413
|
+
selectable: true,
|
|
414
|
+
};
|
|
415
|
+
|
|
338
416
|
export const Zoomable = Template.bind({});
|
|
339
417
|
Zoomable.args = {
|
|
340
418
|
zoomable: true,
|