Skip to content

Commit f322bd0

Browse files
feat(AnalyticalTable): Add prop selectionMode (#258)
Allows different selection modes via `TableSelectionMode` enum with values `NONE`, `SINGLE_SELECT`, `MULTI_SELECT` BREAKING CHANGE: Replace prop `selectable` with `selectionMode`
1 parent 6f44a72 commit f322bd0

16 files changed

+188
-177
lines changed

packages/main/src/components/AnalyticalTable/AnalyticalTable.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { mountThemedComponent } from '@shared/tests/utils';
22
import { AnalyticalTable } from '@ui5/webcomponents-react/lib/AnalyticalTable';
3+
import { TableSelectionMode } from '@ui5/webcomponents-react/lib/TableSelectionMode';
34
import React from 'react';
4-
import { act } from 'react-dom/test-utils';
55

66
const columns = [
77
{
@@ -172,7 +172,7 @@ describe('AnalyticalTable', () => {
172172
filterable={true}
173173
visibleRows={15}
174174
minRows={5}
175-
selectable={true}
175+
selectionMode={TableSelectionMode.SINGLE_SELECT}
176176
subRowsKey="subRows"
177177
isTreeTable={true}
178178
/>

packages/main/src/components/AnalyticalTable/ColumnHeader/ColumnHeaderModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ export const ColumnHeaderModal: FC<ColumnHeaderModalProperties> = (props) => {
104104
{showFilter && !column.isGrouped && (
105105
<CustomListItem type={ListItemTypes.Inactive}>
106106
<FlexBox alignItems={FlexBoxAlignItems.Center} style={{ padding: '0px 1rem' }}>
107-
<Icon name="filter" style={{ paddingRight: '1rem' }} />
108-
<Filter column={column} />
107+
<Icon name="filter" style={{ paddingRight: '0.5rem', minWidth: '1rem', minHeight: '1rem' }} />
108+
<Filter column={column} popoverRef={popoverRef} />
109109
</FlexBox>
110110
</CustomListItem>
111111
)}

packages/main/src/components/AnalyticalTable/__snapshots__/AnalyticalTable.test.tsx.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,7 +1569,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
15691569
<ui5-icon
15701570
class=""
15711571
name="filter"
1572-
style="padding-right: 1rem;"
1572+
style="padding-right: 0.5rem; min-width: 1rem; min-height: 1rem;"
15731573
/>
15741574
<ui5-input
15751575
class=""
@@ -1657,7 +1657,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
16571657
<ui5-icon
16581658
class=""
16591659
name="filter"
1660-
style="padding-right: 1rem;"
1660+
style="padding-right: 0.5rem; min-width: 1rem; min-height: 1rem;"
16611661
/>
16621662
<ui5-input
16631663
class=""
@@ -1745,7 +1745,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
17451745
<ui5-icon
17461746
class=""
17471747
name="filter"
1748-
style="padding-right: 1rem;"
1748+
style="padding-right: 0.5rem; min-width: 1rem; min-height: 1rem;"
17491749
/>
17501750
<ui5-input
17511751
class=""
@@ -1834,7 +1834,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
18341834
<ui5-icon
18351835
class=""
18361836
name="filter"
1837-
style="padding-right: 1rem;"
1837+
style="padding-right: 0.5rem; min-width: 1rem; min-height: 1rem;"
18381838
/>
18391839
<ui5-input
18401840
class=""

packages/main/src/components/AnalyticalTable/demo/demo.stories.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { action } from '@storybook/addon-actions';
2-
import { array, boolean, number, text, object } from '@storybook/addon-knobs';
2+
import { array, boolean, number, object, select, text } from '@storybook/addon-knobs';
33
import { AnalyticalTable } from '@ui5/webcomponents-react/lib/AnalyticalTable';
44
import { Button } from '@ui5/webcomponents-react/lib/Button';
5+
import { TableSelectionMode } from '@ui5/webcomponents-react/lib/TableSelectionMode';
56
import { TextAlign } from '@ui5/webcomponents-react/lib/TextAlign';
67
import { Title } from '@ui5/webcomponents-react/lib/Title';
78
import React from 'react';
@@ -71,7 +72,11 @@ export const defaultTable = () => {
7172
visibleRows={number('visibleRows', 5)}
7273
minRows={number('minRows', 5)}
7374
groupable={boolean('groupable', true)}
74-
selectable={boolean('selectable', true)}
75+
selectionMode={select<TableSelectionMode>(
76+
'selectionMode',
77+
TableSelectionMode,
78+
TableSelectionMode.SINGLE_SELECT
79+
)}
7580
onRowSelected={action('onRowSelected')}
7681
onSort={action('onSort')}
7782
onGroup={action('onGroup')}
@@ -101,7 +106,7 @@ export const treeTable = () => {
101106
filterable={boolean('filterable', true)}
102107
visibleRows={number('visibleRows', 15)}
103108
minRows={number('minRows', 5)}
104-
selectable={boolean('selectable', true)}
109+
selectionMode={select<TableSelectionMode>('selectionMode', TableSelectionMode, TableSelectionMode.SINGLE_SELECT)}
105110
onRowSelected={action('onRowSelected')}
106111
onSort={action('onSort')}
107112
onRowExpandChange={action('onRowExpandChange')}

packages/main/src/components/AnalyticalTable/hooks/useTableCellStyling.ts

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,57 @@ import { VerticalAlign } from '@ui5/webcomponents-react/lib/VerticalAlign';
33
import { CSSProperties } from 'react';
44
import { PluginHook } from 'react-table';
55

6-
export const useTableCellStyling = (classes, rowHeight) => {
7-
const hook: PluginHook<{}> = (instance) => {
8-
instance.getCellProps.push((cellProps, { cell: { column } }) => {
9-
const style: CSSProperties = {};
6+
export const useTableCellStyling: PluginHook<{}> = (hooks) => {
7+
hooks.getCellProps.push((cellProps, { cell: { column }, instance }) => {
8+
const { classes, rowHeight } = instance.webComponentsReactProperties;
9+
const style: CSSProperties = {};
1010

11-
if (rowHeight) {
12-
style.height = `${rowHeight}px`;
13-
}
11+
if (rowHeight) {
12+
style.height = `${rowHeight}px`;
13+
}
1414

15-
switch (column.hAlign) {
16-
case TextAlign.Begin:
17-
style.textAlign = 'start';
18-
break;
19-
case TextAlign.Center:
20-
style.textAlign = 'center';
21-
break;
22-
case TextAlign.End:
23-
style.textAlign = 'end';
24-
break;
25-
case TextAlign.Left:
26-
style.textAlign = 'left';
27-
break;
28-
case TextAlign.Right:
29-
style.textAlign = 'right';
30-
break;
31-
}
32-
switch (column.vAlign) {
33-
case VerticalAlign.Bottom:
34-
style.verticalAlign = 'bottom';
35-
break;
36-
case VerticalAlign.Middle:
37-
style.verticalAlign = 'middle';
38-
break;
39-
case VerticalAlign.Top:
40-
style.verticalAlign = 'top';
41-
break;
42-
}
15+
switch (column.hAlign) {
16+
case TextAlign.Begin:
17+
style.textAlign = 'start';
18+
break;
19+
case TextAlign.Center:
20+
style.textAlign = 'center';
21+
break;
22+
case TextAlign.End:
23+
style.textAlign = 'end';
24+
break;
25+
case TextAlign.Left:
26+
style.textAlign = 'left';
27+
break;
28+
case TextAlign.Right:
29+
style.textAlign = 'right';
30+
break;
31+
}
32+
switch (column.vAlign) {
33+
case VerticalAlign.Bottom:
34+
style.verticalAlign = 'bottom';
35+
break;
36+
case VerticalAlign.Middle:
37+
style.verticalAlign = 'middle';
38+
break;
39+
case VerticalAlign.Top:
40+
style.verticalAlign = 'top';
41+
break;
42+
}
4343

44-
let className = classes.tableCell;
45-
if (column.className) {
46-
className += ` ${column.className}`;
47-
}
44+
let className = classes.tableCell;
45+
if (column.className) {
46+
className += ` ${column.className}`;
47+
}
4848

49-
return {
50-
...cellProps,
51-
className,
52-
style: {
53-
...cellProps.style,
54-
style
55-
}
56-
};
57-
});
58-
};
59-
hook.pluginName = 'useTableCellStyling';
60-
return hook;
49+
return {
50+
...cellProps,
51+
className,
52+
style: {
53+
...cellProps.style,
54+
style
55+
}
56+
};
57+
});
6158
};
59+
useTableCellStyling.pluginName = 'useTableCellStyling';
Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import { PluginHook } from 'react-table';
22

3-
export const useTableHeaderGroupStyling = (classes) => {
4-
const hook: PluginHook<{}> = (instance) => {
5-
instance.getHeaderGroupProps.push((headerGroupProps) => {
6-
return {
7-
...headerGroupProps,
8-
className: classes.tableHeaderRow
9-
};
10-
});
11-
};
12-
hook.pluginName = 'useTableHeaderGroupStyling';
13-
return hook;
3+
export const useTableHeaderGroupStyling: PluginHook<{}> = (hooks) => {
4+
hooks.getHeaderGroupProps.push((headerGroupProps, { instance }) => {
5+
const { classes } = instance.webComponentsReactProperties;
6+
return {
7+
...headerGroupProps,
8+
className: classes.tableHeaderRow
9+
};
10+
});
1411
};
12+
useTableHeaderGroupStyling.pluginName = 'useTableHeaderGroupStyling';
Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
import { PluginHook } from 'react-table';
22

3-
export const useTableHeaderStyling = (classes) => {
4-
const hook: PluginHook<{}> = (instance) => {
5-
instance.getHeaderProps.push((columnProps, { column }) => {
6-
return {
7-
...columnProps,
8-
className: classes.th,
9-
column,
10-
style: {
11-
...columnProps.style,
12-
position: 'absolute' // TODO should be removed at some point in time
13-
}
14-
};
15-
});
16-
return instance;
17-
};
18-
hook.pluginName = 'useTableHeaderStyling';
19-
return hook;
3+
export const useTableHeaderStyling: PluginHook<{}> = (hooks) => {
4+
hooks.getHeaderProps.push((columnProps, { instance, column }) => {
5+
const { classes } = instance.webComponentsReactProperties;
6+
return {
7+
...columnProps,
8+
className: classes.th,
9+
column,
10+
style: {
11+
...columnProps.style,
12+
position: 'absolute' // TODO should be removed at some point in time
13+
}
14+
};
15+
});
2016
};
17+
useTableHeaderStyling.pluginName = 'useTableHeaderStyling';
Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,45 @@
11
import { Event } from '@ui5/webcomponents-react-base/lib/Event';
2+
import { TableSelectionMode } from '@ui5/webcomponents-react/lib/TableSelectionMode';
23

34
const ROW_SELECTION_ATTRIBUTE = 'data-is-selected';
45

5-
export const useTableRowStyling = (classes, selectable, onRowSelected) => {
6-
const hook = (instance) => {
7-
instance.getRowProps.push((passedRowProps, { row }) => {
8-
let className = classes.tr;
9-
if (row.isGrouped) {
10-
className += ` ${classes.tableGroupHeader}`;
11-
}
6+
export const useTableRowStyling = (hooks) => {
7+
hooks.getRowProps.push((passedRowProps, { instance, row }) => {
8+
const { classes, selectionMode, onRowSelected } = instance.webComponentsReactProperties;
9+
let className = classes.tr;
10+
if (row.isGrouped) {
11+
className += ` ${classes.tableGroupHeader}`;
12+
}
1213

13-
const rowProps: any = {
14-
...passedRowProps,
15-
className,
16-
role: 'row'
17-
};
14+
const rowProps: any = {
15+
...passedRowProps,
16+
className,
17+
role: 'row'
18+
};
19+
if ([TableSelectionMode.SINGLE_SELECT, TableSelectionMode.MULTI_SELECT].includes(selectionMode)) {
20+
rowProps.onClick = (e) => {
21+
if (row.isGrouped) {
22+
return;
23+
}
1824

19-
if (selectable) {
20-
rowProps.onClick = (e) => {
21-
if (row.isGrouped) {
22-
return;
23-
}
25+
row.toggleRowSelected();
2426

25-
row.toggleRowSelected();
26-
if (typeof onRowSelected === 'function') {
27-
onRowSelected(Event.of(null, e, { row, isSelected: !row.isSelected }));
28-
}
29-
const clickedRow = e.currentTarget as HTMLDivElement;
30-
if (clickedRow.hasAttribute(ROW_SELECTION_ATTRIBUTE)) {
31-
clickedRow.removeAttribute(ROW_SELECTION_ATTRIBUTE);
32-
} else {
33-
clickedRow.setAttribute(ROW_SELECTION_ATTRIBUTE, '');
34-
}
35-
};
36-
if (row.isSelected) {
37-
rowProps['data-is-selected'] = '';
27+
if (typeof onRowSelected === 'function') {
28+
onRowSelected(Event.of(null, e, { row, isSelected: !row.isSelected }));
3829
}
39-
}
40-
return rowProps;
41-
});
42-
43-
return instance;
44-
};
4530

46-
hook.pluginName = 'useTableRowStyling';
47-
return hook;
31+
if (selectionMode === TableSelectionMode.SINGLE_SELECT) {
32+
instance.selectedFlatRows.forEach(({ id }) => {
33+
instance.toggleRowSelected(id, false);
34+
});
35+
}
36+
};
37+
if (row.isSelected) {
38+
rowProps[ROW_SELECTION_ATTRIBUTE] = '';
39+
}
40+
}
41+
return rowProps;
42+
});
4843
};
44+
45+
useTableRowStyling.pluginName = 'useTableRowStyling';
Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
import { PluginHook } from 'react-table';
2-
3-
export const useTableStyling = (classes) => {
4-
const hook: PluginHook<{}> = (tableHooks) => {
5-
tableHooks.getTableProps.push((tableProps) => {
6-
return {
7-
...tableProps,
8-
className: classes.table
9-
};
10-
});
11-
};
12-
hook.pluginName = 'useTableStyling';
13-
return hook;
1+
export const useTableStyling = (tableHooks) => {
2+
tableHooks.getTableProps.push((tableProps, { instance }) => {
3+
const { classes } = instance.webComponentsReactProperties;
4+
return {
5+
...tableProps,
6+
className: classes.table
7+
};
8+
});
149
};
10+
useTableStyling.pluginName = 'useTableStyling';

0 commit comments

Comments
 (0)