Skip to content

Commit

Permalink
feat(AnalyticalTable): horizontal scrolling (#199)
Browse files Browse the repository at this point in the history
[ci skip]
  • Loading branch information
Lukas742 authored and MarcusNotheis committed Oct 21, 2019
1 parent 88b2a44 commit 0ad70bc
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const styles = ({ parameters }: JSSTheme) => ({
tbody: {
position: 'relative',
zIndex: 0,
overflowX: 'auto',
backgroundColor: parameters.sapUiListBackground,
'&$selectable $tr:hover': {
backgroundColor: parameters.sapUiListHoverBackground
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
>
<header
class="AnalyticalTable--tableHeaderRow-"
style="grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--th-"
Expand Down Expand Up @@ -343,15 +343,15 @@ exports[`AnalyticalTable Tree Table 1`] = `
</div>
</header>
<div
style="position: relative; height: 220px; overflow: auto; will-change: transform; direction: ltr;"
style="position: relative; height: 220px; width: 240px; overflow: auto; will-change: transform; direction: ltr;"
>
<div
class="AnalyticalTable--tbody- AnalyticalTable--selectable-"
style="height: 220px; width: 100%;"
>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 0px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 0px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand All @@ -372,7 +372,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 44px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 44px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand Down Expand Up @@ -417,7 +417,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 88px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 88px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand All @@ -434,7 +434,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 132px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 132px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand All @@ -451,7 +451,7 @@ exports[`AnalyticalTable Tree Table 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 176px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 176px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand Down Expand Up @@ -493,7 +493,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
>
<header
class="AnalyticalTable--tableHeaderRow-"
style="grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--th-"
Expand Down Expand Up @@ -732,15 +732,15 @@ exports[`AnalyticalTable test Asc desc 1`] = `
</div>
</header>
<div
style="position: relative; height: 220px; overflow: auto; will-change: transform; direction: ltr;"
style="position: relative; height: 220px; width: 240px; overflow: auto; will-change: transform; direction: ltr;"
>
<div
class="AnalyticalTable--tbody-"
style="height: 220px; width: 100%;"
>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 0px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 0px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand Down Expand Up @@ -785,7 +785,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 44px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 44px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand Down Expand Up @@ -830,7 +830,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 88px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 88px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand All @@ -847,7 +847,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 132px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 132px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand All @@ -864,7 +864,7 @@ exports[`AnalyticalTable test Asc desc 1`] = `
</div>
<div
class="AnalyticalTable--tr-"
style="position: absolute; left: 0px; top: 176px; height: 44px; width: 100%; grid-template-columns: minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr) minmax(30px, 1fr);"
style="position: absolute; left: 0px; top: 176px; height: 44px; width: 100%; grid-template-columns: minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr) minmax(60px, 1fr);"
>
<div
class="AnalyticalTable--tableCell-"
Expand Down
39 changes: 34 additions & 5 deletions packages/main/src/components/AnalyticalTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import React, {
Ref,
useCallback,
useEffect,
useMemo
useMemo,
useRef,
useState
} from 'react';
import { createUseStyles, useTheme } from 'react-jss';
import { useExpanded, useFilters, useGroupBy, useSortBy, useTable } from 'react-table';
Expand All @@ -29,12 +31,13 @@ import { useTableCellStyling } from './hooks/useTableCellStyling';
import { useTableHeaderGroupStyling } from './hooks/useTableHeaderGroupStyling';
import { useTableHeaderStyling } from './hooks/useTableHeaderStyling';
import { useTableRowStyling } from './hooks/useTableRowStyling';
import { useTableScrollHandles } from './hooks/useTableScrollHandles';
import { useTableStyling } from './hooks/useTableStyling';
import { makeTemplateColumns } from './hooks/utils';
import { LoadingComponent } from './LoadingComponent';
import { TitleBar } from './TitleBar';
import { VirtualTableBody } from './virtualization/VirtualTableBody';
import { useTableScrollHandles } from './hooks/useTableScrollHandles';
import { Device } from '@ui5/webcomponents-react-base/lib/Device';

export interface ColumnConfiguration {
accessor?: string;
Expand Down Expand Up @@ -107,10 +110,12 @@ const defaultFilterMethod = (filter, row) => {
return new RegExp(filter.value, 'gi').test(String(row[filter.id]));
};

const DEFAULT_COLUMN_WIDTH = 60;

const defaultColumn: any = {
Filter: DefaultFilterComponent,
canResize: true,
minWidth: 30,
minWidth: DEFAULT_COLUMN_WIDTH,
width: '1fr',
vAlign: VerticalAlign.Middle,
Aggregated: () => null,
Expand Down Expand Up @@ -143,6 +148,7 @@ const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<
} = props;
const theme = useTheme() as JSSTheme;
const classes = useStyles({ ...props, ...theme });
const [tableWidth, setTableWidth] = useState(null);

const [selectedRowPath, onRowClicked] = useRowSelection(onRowSelected, selectedRowKey);
const [resizedColumns, onColumnSizeChanged] = useResizeColumns();
Expand Down Expand Up @@ -204,7 +210,6 @@ const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<
const onGroupByChanged = useCallback(
(e) => {
const { column, isGrouped } = e.getParameters();

let groupedColumns = [];
if (isGrouped) {
groupedColumns = [...tableState.groupBy, column.id];
Expand All @@ -227,11 +232,31 @@ const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<
[tableState.groupBy, onGroup]
);

const headerRef = useRef(null);
const onWindowResize = useCallback(() => {
if (headerRef.current) {
setTableWidth(headerRef.current.scrollWidth);
}
}, [setTableWidth, headerRef.current]);

useEffect(() => {
Device.resize.attachHandler(onWindowResize, null);
return () => {
Device.resize.detachHandler(onWindowResize, null);
};
}, [onWindowResize]);

useEffect(() => {
if (headerRef.current) {
setTableWidth(headerRef.current.scrollWidth);
}
}, [headerRef, setTableWidth, resizedColumns]);

return (
<div className={className} style={style} title={tooltip} ref={analyticalTableRef}>
{title && <TitleBar>{title}</TitleBar>}
{typeof renderExtension === 'function' && <div>{renderExtension()}</div>}
<div className={tableContainerClasses.valueOf()}>
<div className={tableContainerClasses.valueOf()} ref={headerRef}>
<div {...getTableProps()}>
{headerGroups.map((headerGroup) => {
let headerProps = {};
Expand All @@ -258,6 +283,10 @@ const AnalyticalTable: FC<TableProps> = forwardRef((props: TableProps, ref: Ref<
})}
<VirtualTableBody
{...props}
isTreeTable={isTreeTable}
defaultColumnWidth={DEFAULT_COLUMN_WIDTH}
resizedColumns={resizedColumns}
tableWidth={tableWidth}
tableBodyClasses={tableBodyClasses}
rowContainerStyling={rowContainerStyling}
prepareRow={prepareRow}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export const VirtualTableBody = (props) => {
selectedRow,
selectable,
reactWindowRef,
tableWidth,
defaultColumnWidth,
resizedColumns,
isTreeTable
} = props;

Expand Down Expand Up @@ -99,10 +102,23 @@ export const VirtualTableBody = (props) => {
};
}, [rows, visibleRows, minRows, props.rowHeight]);

const columnsWidth = useMemo(() => {
const aggregatedWidth = columns
.map((item) => {
if (resizedColumns.hasOwnProperty(item.accessor)) {
return resizedColumns[item.accessor];
}
return item.minWidth ? item.minWidth : defaultColumnWidth;
})
.reduce((el, acc) => el + acc);
return tableWidth > aggregatedWidth ? null : aggregatedWidth;
}, [columns, tableWidth, resizedColumns]);

return (
<FixedSizeList
ref={reactWindowRef}
height={listHeight}
width={columnsWidth}
itemCount={itemCount}
itemSize={rowHeight}
innerRef={innerDivRef}
Expand Down

0 comments on commit 0ad70bc

Please sign in to comment.