Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listview display none #6357

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/@react-spectrum/list/stories/ListView.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,33 @@ function Demo(props) {
</ListView>
);
}

const manyItems = [];
for (let i = 0; i < 500; i++) {manyItems.push({key: i, name: `item ${i}`});}

function DisplayNoneComponent(args) {
const [isDisplay, setIsDisplay] = useState(false);
useEffect(() => {
const timeout = setTimeout(() => setIsDisplay(true), 10000);
return () => clearTimeout(timeout);
}, []);

return (
<div style={!isDisplay ? {display: 'none'} : null}>
<ListView aria-label="Many items" items={manyItems} width="300px" height="200px" {...args}>
{(item: any) => (
<Item key={item.key} textValue={item.name}>
<Text>
{item.name}
</Text>
</Item>
)}
</ListView>
</div>
);
}

export const DisplayNone: ListViewStory = {
render: (args) => <DisplayNoneComponent {...args} />,
name: 'display: none with many items'
};
2 changes: 1 addition & 1 deletion packages/@react-stately/layout/src/ListLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@ export class ListLayout<T> extends Layout<Node<T>> implements KeyboardDelegate,
let layoutNode = this.buildChild(node, 0, y);
y = layoutNode.layoutInfo.rect.maxY;
nodes.push(layoutNode);

if (node.type === 'item' && y > this.validRect.maxY) {
y += (this.collection.size - (nodes.length + skipped)) * rowHeight;
break;
Expand Down Expand Up @@ -383,6 +382,7 @@ export class ListLayout<T> extends Layout<Node<T>> implements KeyboardDelegate,
}

updateItemSize(key: Key, size: Size) {
if (size.height === 0) {return false;}
Copy link
Contributor Author

@richardbann richardbann May 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear if it is a safe change. Probably the height of a list item is 0 only if display:none set.
On the other hand if somehow the item size is small enough (say 1), react will throw the same exception even if the ListView is visible. This is because after render the size is calculated (1 in this case) and a re-render will add one more item to the visible item's list, which will notice it's size and render again... If the collection is large enough react will treat it as an infinite recursion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The page does not crash if padding is set to 1 on ListLayout, but this is not configurable. Can be verified by setting the padding in ListView.tsx.

let layoutInfo = this.layoutInfos.get(key);
// If no layoutInfo, item has been deleted/removed.
if (!layoutInfo) {
Expand Down