Skip to content

Commit

Permalink
Prevent toggling loading on tables from re-mounting visible rows (#…
Browse files Browse the repository at this point in the history
…2754)

* Removed EuiLoadingTableBody & moved its logic into EuiBasicTable to prevent re-rendering the whole table when loading is set to true

* Updated first table example to test loading toggle

* Revert "Updated first table example to test loading toggle"

This reverts commit 7942eee.

* changelog
  • Loading branch information
chandlerprall authored Jan 13, 2020
1 parent f6a5ece commit 7fb9865
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 115 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ No public interface changes since `18.1.0`.

- Changed `EuiRadio` and `EuiCheckbox` labels to be `inline-block` ([#2739](https://github.com/elastic/eui/pull/2739))
- Fixed `EuiCheckboxGroup`'s `options` type to fully extend the `EuiCheckbox` type ([#2739](https://github.com/elastic/eui/pull/2739))
- Fixed `EuiBasicTable` & `EuiInMemoryTable` to not un- and re-mount rows when toggling `loading` prop ([#2754](https://github.com/elastic/eui/pull/2754))

## [`18.0.0`](https://github.com/elastic/eui/tree/v18.0.0)

Expand Down
76 changes: 57 additions & 19 deletions src/components/basic_table/__snapshots__/basic_table.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ exports[`EuiBasicTable cellProps renders cells with custom props from a callback
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -175,7 +177,9 @@ exports[`EuiBasicTable cellProps renders rows with custom props from an object 1
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -530,7 +534,9 @@ exports[`EuiBasicTable footers do not render without a column footer definition
Age
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -769,7 +775,9 @@ exports[`EuiBasicTable footers render with pagination, selection, sorting, and f
Age
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelectable={true}
isSelected={false}
Expand Down Expand Up @@ -1031,7 +1039,9 @@ exports[`EuiBasicTable itemIdToExpandedRowMap renders an expanded row 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
aria-owns="row_1_expansion"
isSelected={false}
Expand Down Expand Up @@ -1157,7 +1167,9 @@ exports[`EuiBasicTable rowProps renders rows with custom props from a callback 1
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiKeyboardAccessible>
<EuiTableRow
className="customRowClass"
Expand Down Expand Up @@ -1284,7 +1296,9 @@ exports[`EuiBasicTable rowProps renders rows with custom props from an object 1`
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiKeyboardAccessible>
<EuiTableRow
className="customClass"
Expand Down Expand Up @@ -1411,7 +1425,9 @@ exports[`EuiBasicTable with pagination - 2nd page 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -1517,7 +1533,9 @@ exports[`EuiBasicTable with pagination 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -1733,7 +1751,9 @@ exports[`EuiBasicTable with pagination and selection 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelectable={true}
isSelected={false}
Expand Down Expand Up @@ -1889,7 +1909,9 @@ exports[`EuiBasicTable with pagination, hiding the per page options 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -2048,7 +2070,9 @@ exports[`EuiBasicTable with pagination, selection and sorting 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelectable={true}
isSelected={false}
Expand Down Expand Up @@ -2245,7 +2269,9 @@ exports[`EuiBasicTable with pagination, selection, sorting and a single record a
Actions
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
hasActions={true}
isSelectable={true}
Expand Down Expand Up @@ -2523,7 +2549,9 @@ exports[`EuiBasicTable with pagination, selection, sorting and column dataType 1
Count
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelectable={true}
isSelected={false}
Expand Down Expand Up @@ -2714,7 +2742,9 @@ exports[`EuiBasicTable with pagination, selection, sorting and column renderer 1
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelectable={true}
isSelected={false}
Expand Down Expand Up @@ -2911,7 +2941,9 @@ exports[`EuiBasicTable with pagination, selection, sorting and multiple record a
Actions
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
hasActions={true}
isSelectable={true}
Expand Down Expand Up @@ -3207,7 +3239,9 @@ exports[`EuiBasicTable with pagination, selection, sorting, column renderer and
Count
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelectable={true}
isSelected={false}
Expand Down Expand Up @@ -3363,7 +3397,9 @@ exports[`EuiBasicTable with sortable columns and sorting disabled 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down Expand Up @@ -3492,7 +3528,9 @@ exports[`EuiBasicTable with sorting 1`] = `
Name
</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<EuiTableRow
isSelected={false}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ exports[`EuiInMemoryTable behavior pagination 1`] = `
</tr>
</thead>
</EuiTableHeader>
<EuiTableBody>
<EuiTableBody
bodyRef={[Function]}
>
<tbody>
<EuiTableRow
isSelected={false}
Expand Down

This file was deleted.

71 changes: 66 additions & 5 deletions src/components/basic_table/basic_table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import { ExpandedItemActions } from './expanded_item_actions';

import { Pagination, PaginationBar } from './pagination_bar';
import { EuiIcon } from '../icon';
import { LoadingTableBody } from './loading_table_body';
import { EuiKeyboardAccessible, EuiScreenReaderOnly } from '../accessibility';
import { EuiI18n } from '../i18n';
import { EuiDelayRender } from '../delay_render';
Expand Down Expand Up @@ -258,10 +257,75 @@ export class EuiBasicTable<T = any> extends Component<
return null;
}

// used for moving in & out of `loading` state
private cleanups: Array<() => void> = [];
private tbody: HTMLTableSectionElement | null = null;

state = {
selection: [],
};

componentDidMount() {
if (this.props.loading && this.tbody) this.addLoadingListeners(this.tbody);
}

componentDidUpdate(prevProps: EuiBasicTableProps<T>) {
if (prevProps.loading !== this.props.loading) {
if (this.props.loading && this.tbody) {
this.addLoadingListeners(this.tbody);
} else {
this.removeLoadingListeners();
}
}
}

componentWillUnmount() {
this.removeLoadingListeners();
}

private setTbody = (tbody: HTMLTableSectionElement | null) => {
// remove listeners from an existing element
this.removeLoadingListeners();

// update the ref
this.tbody = tbody;

// if loading, add listeners
if (this.props.loading === true && tbody) {
this.addLoadingListeners(tbody);
}
};

private addLoadingListeners = (tbody: HTMLTableSectionElement) => {
const listener = (event: Event) => {
event.stopPropagation();
event.preventDefault();
};
[
'mousedown',
'mouseup',
'mouseover',
'mouseout',
'mouseenter',
'mouseleave',
'click',
'dblclick',
'keydown',
'keyup',
'keypress',
].forEach(event => {
tbody.addEventListener(event, listener, true);
this.cleanups.push(() => {
tbody.removeEventListener(event, listener, true);
});
});
};

private removeLoadingListeners = () => {
this.cleanups.forEach(cleanup => cleanup());
this.cleanups.length = 0;
};

buildCriteria(props: EuiBasicTableProps<T>): Criteria<T> {
const criteria: Criteria<T> = {};
if (hasPagination(props)) {
Expand Down Expand Up @@ -702,10 +766,7 @@ export class EuiBasicTable<T = any> extends Component<
: index;
return this.renderItemRow(item, tableItemIndex);
});
if (this.props.loading) {
return <LoadingTableBody>{rows}</LoadingTableBody>;
}
return <EuiTableBody>{rows}</EuiTableBody>;
return <EuiTableBody bodyRef={this.setTbody}>{rows}</EuiTableBody>;
}

renderErrorBody(error: string) {
Expand Down
20 changes: 0 additions & 20 deletions src/components/basic_table/loading_table_body.test.tsx

This file was deleted.

Loading

0 comments on commit 7fb9865

Please sign in to comment.