Skip to content

Commit

Permalink
Simplify table markup and remove unnecessary events and layout updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dmfalke committed Dec 9, 2024
1 parent a628d62 commit f7d40a9
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { debounce } from 'lodash';

import MesaTooltip from './MesaTooltip';
import Events from '../Utils/Events';
import { MESA_SCROLL_EVENT, MESA_REFLOW_EVENT } from '../Ui/MesaContants';

class AnchoredTooltip extends React.Component {
constructor(props) {
Expand All @@ -19,8 +18,6 @@ class AnchoredTooltip extends React.Component {
this.listeners = {
scroll: Events.add('scroll', this.updatePosition),
resize: Events.add('resize', this.updatePosition),
MesaScroll: Events.add(MESA_SCROLL_EVENT, this.updatePosition),
MesaReflow: Events.add(MESA_REFLOW_EVENT, this.updatePosition),
};
}

Expand Down
131 changes: 38 additions & 93 deletions packages/libs/coreui/src/components/Mesa/Ui/DataTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,19 @@ import { defaultMemoize } from 'reselect';
import HeadingRow from './HeadingRow';
import DataRowList from './DataRowList';
import { makeClassifier, combineWidths } from '../Utils/Utils';
import { MESA_SCROLL_EVENT, MESA_REFLOW_EVENT } from './MesaContants';

const dataTableClass = makeClassifier('DataTable');

class DataTable extends React.Component {
constructor(props) {
super(props);
this.widthCache = {};
this.state = { dynamicWidths: null, tableWrapperWidth: null };
this.widthCache = [];
this.renderStickyTable = this.renderStickyTable.bind(this);
this.componentDidMount = this.componentDidMount.bind(this);
this.getInnerCellWidth = this.getInnerCellWidth.bind(this);
this.hasSelectionColumn = this.hasSelectionColumn.bind(this);
this.hasExpansionColumn = this.hasExpansionColumn.bind(this);
this.shouldUseStickyHeader = this.shouldUseStickyHeader.bind(this);
this.makeFirstNColumnsSticky = this.makeFirstNColumnsSticky.bind(this);
this.handleTableBodyScroll = this.handleTableBodyScroll.bind(this);
this.setDynamicWidths = this.setDynamicWidths.bind(this);
this.resizeId = -1;
this.mainRef = null;
Expand All @@ -40,7 +37,7 @@ class DataTable extends React.Component {
}

makeFirstNColumnsSticky(columns, n) {
const { dynamicWidths } = this.state;
const dynamicWidths = this.widthCache;

if (n <= columns.length) {
const stickyColumns = columns.slice(0, n).map((column, index) => {
Expand Down Expand Up @@ -95,14 +92,16 @@ class DataTable extends React.Component {
}

attachLoadEventHandlers() {
if (this.bodyNode == null) return;
this.bodyNode.querySelectorAll('img, iframe, object').forEach((node) => {
if (node.complete) return;
node.addEventListener('load', (event) => {
const el = event.target.offsetParent || event.target;
if (el.scrollWidth > el.clientWidth) this.setDynamicWidths();
if (this.contentTable == null) return;
this.contentTable
.querySelectorAll('img, iframe, object')
.forEach((node) => {
if (node.complete) return;
node.addEventListener('load', (event) => {
const el = event.target.offsetParent || event.target;
if (el.scrollWidth > el.clientWidth) this.setDynamicWidths();
});
});
});
}

attachResizeHandler() {
Expand All @@ -123,11 +122,9 @@ class DataTable extends React.Component {
if (this.props.rows.length === 0 || this.props.filteredRows.length === 0)
return;

this.setState({ dynamicWidths: null, tableWrapperWidth: null }, () => {
this.widthCache = {};
const { columns } = this.props;
const hasSelectionColumn = this.hasSelectionColumn();
const { contentTable, getInnerCellWidth } = this;
this.setState({ dynamicWidths: null }, () => {
this.widthCache = [];
const { contentTable } = this;
if (!contentTable) return;
const contentCells = Array.from(
contentTable.querySelectorAll('tbody > tr:first-child > td')
Expand All @@ -137,26 +134,18 @@ class DataTable extends React.Component {
return;
}

if (hasSelectionColumn) {
contentCells.shift();
}

const dynamicWidths = columns.map(
(c, i) =>
getInnerCellWidth(contentCells[i], c) -
(hasSelectionColumn && !i ? 1 : 0)
this.widthCache = contentCells.map(
(cell) => cell.getBoundingClientRect().width
);
this.setState({ dynamicWidths }, () => {
window.dispatchEvent(new CustomEvent(MESA_REFLOW_EVENT));
const tableWrapperWidth = this.bodyNode && this.bodyNode.clientWidth;
this.setState({ tableWrapperWidth });
});
});
}

getInnerCellWidth(cell, { key }) {
if (key && key in this.widthCache) return this.widthCache[key];
return (this.widthCache[key] = cell.clientWidth);
hasExpansionColumn() {
const { options, eventHandlers } = this.props;
return (
typeof options.childRow === 'function' &&
typeof eventHandlers.onExpandedRowsChange === 'function'
);
}

hasSelectionColumn() {
Expand All @@ -168,12 +157,6 @@ class DataTable extends React.Component {
);
}

handleTableBodyScroll() {
const offset = this.bodyNode.scrollLeft;
this.headerNode.scrollLeft = offset;
window.dispatchEvent(new CustomEvent(MESA_SCROLL_EVENT));
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

renderStickyTable() {
Expand All @@ -187,30 +170,15 @@ class DataTable extends React.Component {
uiState,
headerWrapperStyle,
} = this.props;
const { dynamicWidths } = this.state;
const stickyColumns = options.useStickyFirstNColumns
const newColumns = options.useStickyFirstNColumns
? this.makeFirstNColumnsSticky(columns, options.useStickyFirstNColumns)
: columns;
const newColumns =
stickyColumns.every(({ width }) => width) ||
!dynamicWidths ||
dynamicWidths.length == 0
? stickyColumns
: makeColumnsWithDynamicWidths({
columns: stickyColumns,
dynamicWidths,
});
const wrapperStyle = {
maxHeight: options ? options.tableBodyMaxHeight : null,
minWidth: dynamicWidths
? combineWidths(columns.map(({ width }) => width))
: null,
};
const headerWrapperStyleMerged = {
display: dynamicWidths == null ? 'none' : 'block',
...headerWrapperStyle,
const tableStyle = {
tableLayout: 'auto',
};
const tableLayout = { tableLayout: dynamicWidths ? 'fixed' : 'auto' };
const tableProps = {
options,
rows,
Expand All @@ -223,36 +191,21 @@ class DataTable extends React.Component {
return (
<div ref={(node) => (this.mainRef = node)} className="MesaComponent">
<div
className={dataTableClass(
null,
options.useStickyHeader ? 'Sticky' : null
)}
className={dataTableClass(null, [
options.useStickyHeader ? 'Sticky' : undefined,
options.marginContent ? 'HasMargin' : undefined,
])}
style={wrapperStyle}
>
<div
style={headerWrapperStyleMerged}
ref={(node) => (this.headerNode = node)}
className={dataTableClass('Header')}
>
<table cellSpacing={0} cellPadding={0} style={{ ...tableLayout }}>
<HeadingRow {...tableProps} />
</table>
</div>
<div
ref={(node) => (this.bodyNode = node)}
className={dataTableClass('Body')}
onScroll={this.handleTableBodyScroll}
<table
cellSpacing={0}
cellPadding={0}
style={tableStyle}
ref={(node) => (this.contentTable = node)}
>
<table
cellSpacing={0}
cellPadding={0}
style={tableLayout}
ref={(node) => (this.contentTable = node)}
>
{dynamicWidths == null ? <HeadingRow {...tableProps} /> : null}
<DataRowList {...tableProps} />
</table>
</div>
<HeadingRow {...tableProps} />
<DataRowList {...tableProps} />
</table>
{this.props.options.marginContent && (
<div className={dataTableClass('Margin')}>
{this.props.options.marginContent}
Expand Down Expand Up @@ -289,12 +242,4 @@ DataTable.propTypes = {
eventHandlers: PropTypes.objectOf(PropTypes.func),
};

const makeColumnsWithDynamicWidths = defaultMemoize(
({ columns, dynamicWidths }) =>
columns.map((column, index) =>
Object.assign({}, column, { width: dynamicWidths[index] })
),
(a, b) => a.columns === b.columns && isEqual(a.dynamicWidths, b.dynamicWidths)
);

export default DataTable;
20 changes: 6 additions & 14 deletions packages/libs/coreui/src/components/Mesa/Ui/ExpansionCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,13 @@ export default function ExpansionCell({
const title = 'Show or hide all row details';

return (
<th className="wdk-DataTableCell wdk-DataTableCell__childRowToggle">
<th className="HeadingCell ChildRowToggle">
{inert ? null : areAllRowsExpanded ? (
<button
className="wdk-DataTableCellExpand"
title={title}
onClick={handler}
>
<button title={title} onClick={handler}>
<ArrowDown />
</button>
) : (
<button
className="wdk-DataTableCellExpand"
title={title}
onClick={handler}
>
<button title={title} onClick={handler}>
<ArrowRight />
</button>
)}
Expand All @@ -82,13 +74,13 @@ export default function ExpansionCell({
};

return (
<td className="wdk-DataTable wdk-DataTableCell__childRowToggle">
<td className="ChildRowToggle">
{inert ? null : isExpanded ? (
<button className="wdk-DataTableCellExpand" onClick={handler}>
<button onClick={handler}>
<ArrowDown />
</button>
) : (
<button className="wdk-DataTableCellExpand" onClick={handler}>
<button onClick={handler}>
<ArrowRight />
</button>
)}
Expand Down
3 changes: 0 additions & 3 deletions packages/libs/coreui/src/components/Mesa/Ui/HeadingCell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Icon from '../Components/Icon';
import HelpTrigger from '../Components/HelpTrigger';
import { makeClassifier } from '../Utils/Utils';
import Events, { EventsFactory } from '../Utils/Events';
import { MESA_SCROLL_EVENT, MESA_REFLOW_EVENT } from './MesaContants';

const headingCellClass = makeClassifier('HeadingCell');

Expand Down Expand Up @@ -42,8 +41,6 @@ class HeadingCell extends React.PureComponent {
this.listeners = {
scroll: Events.add('scroll', this.updateOffset),
resize: Events.add('resize', this.updateOffset),
MesaScroll: Events.add(MESA_SCROLL_EVENT, this.updateOffset),
MesaReflow: Events.add(MESA_REFLOW_EVENT, this.updateOffset),
};
}

Expand Down
3 changes: 3 additions & 0 deletions packages/libs/coreui/src/components/Mesa/style/Cells.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
$StickyColumnBorderColor: rgb(204, 204, 204);

.MesaComponent {
tr {
white-space: break-spaces;
}
th {
background-color: #e2e2e2;
transition: background 0.25s;
Expand Down
Loading

0 comments on commit f7d40a9

Please sign in to comment.