Skip to content

Commit 4669b74

Browse files
committed
Fix select all checkbox disabled state and other empty state issues when loading sentinel is provided
1 parent c1fd8af commit 4669b74

File tree

4 files changed

+20
-8
lines changed

4 files changed

+20
-8
lines changed

packages/@react-aria/table/src/useTableSelectionCheckbox.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function useTableSelectAllCheckbox<T>(state: TableState<T>): TableSelectA
6464
checkboxProps: {
6565
'aria-label': stringFormatter.format(selectionMode === 'single' ? 'select' : 'selectAll'),
6666
isSelected: isSelectAll,
67-
isDisabled: selectionMode !== 'multiple' || state.collection.size === 0,
67+
isDisabled: selectionMode !== 'multiple' || (state.collection.size === 0 || (state.collection.rows.length === 1 && state.collection.rows[0].type === 'loader')),
6868
isIndeterminate: !isEmpty && !isSelectAll,
6969
onChange: () => state.selectionManager.toggleSelectAll()
7070
}

packages/@react-spectrum/s2/src/TableView.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,11 @@ export class S2TableLayout<T> extends TableLayout<T> {
216216
let {layoutInfo} = layoutNode;
217217
layoutInfo.allowOverflow = true;
218218
layoutInfo.rect.width = this.virtualizer!.visibleRect.width;
219-
layoutInfo.isSticky = true;
219+
// If performing first load or empty, the body will be sticky so we don't want to apply sticky to the loader, otherwise it will
220+
// affect the positioning of the empty state renderer
221+
let collection = this.virtualizer!.collection;
222+
let isEmptyOrLoading = collection?.size === 0 || (collection.size === 1 && collection.getItem(collection.getFirstKey()!)!.type === 'loader');
223+
layoutInfo.isSticky = !isEmptyOrLoading;
220224
return layoutNode;
221225
}
222226

packages/react-aria-components/src/Table.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ export const TableBody = /*#__PURE__*/ createBranchComponent('tablebody', <T ext
980980
{...mergeProps(filterDOMProps(props as any), rowGroupProps)}
981981
{...renderProps}
982982
ref={ref}
983-
data-empty={collection.size === 0 || undefined}>
983+
data-empty={isEmpty || undefined}>
984984
{isDroppable && <RootDropIndicator />}
985985
<CollectionBranch
986986
collection={collection}

packages/react-aria-components/test/Table.test.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,18 +1838,18 @@ describe('Table', () => {
18381838
function LoadMoreTable({onLoadMore, isLoading, items}) {
18391839
return (
18401840
<ResizableTableContainer data-testid="scrollRegion">
1841-
<Table aria-label="Load more table">
1842-
<TableHeader>
1841+
<Table aria-label="Load more table" selectionMode="multiple">
1842+
<MyTableHeader>
18431843
<Column isRowHeader>Foo</Column>
18441844
<Column>Bar</Column>
1845-
</TableHeader>
1845+
</MyTableHeader>
18461846
<TableBody renderEmptyState={() => 'No results'}>
18471847
<Collection items={items}>
18481848
{(item) => (
1849-
<Row>
1849+
<MyRow>
18501850
<Cell>{item.foo}</Cell>
18511851
<Cell>{item.bar}</Cell>
1852-
</Row>
1852+
</MyRow>
18531853
)}
18541854
</Collection>
18551855
<UNSTABLE_TableLoadingSentinel isLoading={isLoading} onLoadMore={onLoadMore}>
@@ -1894,6 +1894,10 @@ describe('Table', () => {
18941894
expect(rows[1]).toHaveTextContent('No results');
18951895
expect(tree.queryByText('spinner')).toBeFalsy();
18961896
expect(tree.getByTestId('loadMoreSentinel')).toBeInTheDocument();
1897+
let body = tableTester.rowGroups[1];
1898+
expect(body).toHaveAttribute('data-empty', 'true');
1899+
let selectAll = tree.getAllByRole('checkbox')[0];
1900+
expect(selectAll).toBeDisabled();
18971901

18981902
// Even if the table is empty, providing isLoading will render the loader
18991903
tree.rerender(<LoadMoreTable items={[]} isLoading />);
@@ -1902,6 +1906,10 @@ describe('Table', () => {
19021906
expect(rows[2]).toHaveTextContent('No results');
19031907
expect(tree.queryByText('spinner')).toBeTruthy();
19041908
expect(tree.getByTestId('loadMoreSentinel')).toBeInTheDocument();
1909+
body = tableTester.rowGroups[1];
1910+
expect(body).toHaveAttribute('data-empty', 'true');
1911+
selectAll = tree.getAllByRole('checkbox')[0];
1912+
expect(selectAll).toBeDisabled();
19051913
});
19061914

19071915
it('should fire onLoadMore when intersecting with the sentinel', function () {

0 commit comments

Comments
 (0)