Skip to content

Commit 79aa5e5

Browse files
authored
Fix TableView infinite resize (#3474)
1 parent 769a91a commit 79aa5e5

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

packages/@react-spectrum/table/stories/Table.stories.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {HidingColumnsAllowsResizing} from './HidingColumnsAllowsResizing';
2828
import {IllustratedMessage} from '@react-spectrum/illustratedmessage';
2929
import {Link} from '@react-spectrum/link';
3030
import {LoadingState, SelectionMode} from '@react-types/shared';
31+
import NoSearchResults from '@spectrum-icons/illustrations/NoSearchResults';
3132
import {Radio, RadioGroup} from '@react-spectrum/radio';
3233
import React, {Key, useState} from 'react';
3334
import {SearchField} from '@react-spectrum/searchfield';
@@ -1361,6 +1362,15 @@ storiesOf('TableView', module)
13611362
() => (
13621363
<HidingColumnsAllowsResizing />
13631364
)
1365+
)
1366+
.add(
1367+
'zoom resizing table',
1368+
() => (
1369+
<div style={{position: 'absolute', height: 'calc(100vh-32px)', width: 'calc(100vw - 32px)'}}>
1370+
<ZoomResizing />
1371+
</div>
1372+
),
1373+
{description: {data: 'Using browser zoom should not trigger an infinite resizing loop. CMD+"+" to zoom in and CMD+"-" to zoom out.'}}
13641374
);
13651375

13661376
function AsyncLoadingExample(props) {
@@ -1709,3 +1719,46 @@ export function TableWithBreadcrumbs() {
17091719
</Flex>
17101720
);
17111721
}
1722+
1723+
1724+
function EmptyState() {
1725+
return (
1726+
<IllustratedMessage>
1727+
<NoSearchResults />
1728+
<Heading>No results</Heading>
1729+
</IllustratedMessage>
1730+
);
1731+
}
1732+
1733+
function ZoomResizing() {
1734+
const [child, setChild] = useState('loader');
1735+
1736+
return (
1737+
<div className="App" style={{height: '100vh'}}>
1738+
<RadioGroup
1739+
label="Child type"
1740+
orientation="horizontal"
1741+
value={child}
1742+
onChange={setChild}>
1743+
<Radio value="loader">Loading state</Radio>
1744+
<Radio value="empty">Empty state</Radio>
1745+
</RadioGroup>
1746+
<Flex height="100%">
1747+
<TableView
1748+
height="100%"
1749+
width="100%"
1750+
renderEmptyState={child === 'empty' ? () => <EmptyState /> : undefined}>
1751+
<TableHeader>
1752+
<Column>column</Column>
1753+
</TableHeader>
1754+
<TableBody
1755+
items={[]}
1756+
loadingState={child === 'loader' ? 'loading' : undefined}>
1757+
{(item) => <Row>{(column) => <Cell>{item[column]}</Cell>}</Row>}
1758+
</TableBody>
1759+
</TableView>
1760+
</Flex>
1761+
</div>
1762+
);
1763+
}
1764+

packages/@react-stately/layout/src/TableLayout.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ export class TableLayout<T> extends ListLayout<T> {
191191
}
192192

193193
if (this.isLoading) {
194-
let rect = new Rect(0, y, width || this.virtualizer.visibleRect.width, children.length === 0 ? this.virtualizer.visibleRect.height : 60);
194+
// Add some margin around the loader to ensure that scrollbars don't flicker in and out.
195+
let rect = new Rect(40, Math.max(y, 40), (width || this.virtualizer.visibleRect.width) - 80, children.length === 0 ? this.virtualizer.visibleRect.height - 80 : 60);
195196
let loader = new LayoutInfo('loader', 'loader', rect);
196197
loader.parentKey = 'body';
197198
loader.isSticky = children.length === 0;
@@ -200,7 +201,7 @@ export class TableLayout<T> extends ListLayout<T> {
200201
y = loader.rect.maxY;
201202
width = Math.max(width, rect.width);
202203
} else if (children.length === 0) {
203-
let rect = new Rect(0, y, this.virtualizer.visibleRect.width, this.virtualizer.visibleRect.height);
204+
let rect = new Rect(40, Math.max(y, 40), this.virtualizer.visibleRect.width - 80, this.virtualizer.visibleRect.height - 80);
204205
let empty = new LayoutInfo('empty', 'empty', rect);
205206
empty.parentKey = 'body';
206207
empty.isSticky = true;

0 commit comments

Comments
 (0)