Skip to content

Commit 5e6236d

Browse files
committed
fix aria-rowindex
1 parent fe146d3 commit 5e6236d

File tree

4 files changed

+29
-10
lines changed

4 files changed

+29
-10
lines changed

packages/@react-aria/gridlist/src/useGridListItem.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,10 @@ export function useGridListItem<T>(props: AriaGridListItemOptions, state: ListSt
291291
});
292292

293293
if (isVirtualized) {
294-
rowProps['aria-rowindex'] = node.index + 1;
294+
let {collection} = state;
295+
let nodes = [...collection];
296+
// TODO: refactor ListCollection to store an absolute index of a node's position?
297+
rowProps['aria-rowindex'] = nodes.find(node => node.type === 'section') ? [...collection.getKeys()].filter((key) => collection.getItem(key)?.type !== 'section').findIndex((key) => key === node.key) + 1 : node.index + 1;
295298
}
296299

297300
let gridCellProps = {

packages/@react-aria/gridlist/src/useGridListSection.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {DOMAttributes} from '@react-types/shared';
13+
import {DOMAttributes, Node as RSNode} from '@react-types/shared';
14+
import type {ListState} from '@react-stately/list';
1415
import {useLabels, useSlotId} from '@react-aria/utils';
1516

1617
export interface AriaGridListSectionProps {
1718
/** An accessibility label for the section. Required if `heading` is not present. */
18-
'aria-label'?: string
19+
'aria-label'?: string,
20+
/** Whether the list row is contained in a virtual scroller. */
21+
isVirtualized?: boolean,
22+
/** An object representing the list item. Contains all the relevant information that makes up the list row. */
23+
node: RSNode<unknown>
1924
}
2025

2126
export interface GridListSectionAria {
@@ -34,17 +39,26 @@ export interface GridListSectionAria {
3439
* See `useGridList` for more details about grid list.
3540
* @param props - Props for the section.
3641
*/
37-
export function useGridListSection(props: AriaGridListSectionProps): GridListSectionAria {
38-
let {'aria-label': ariaLabel} = props;
42+
export function useGridListSection<T>(props: AriaGridListSectionProps, state: ListState<T>): GridListSectionAria {
43+
let {'aria-label': ariaLabel, isVirtualized, node} = props;
3944
let headingId = useSlotId();
4045
let labelProps = useLabels({
4146
'aria-label': ariaLabel,
4247
'aria-labelledby': headingId
4348
});
49+
let rowIndex: number | undefined = undefined;
50+
51+
if (isVirtualized) {
52+
let {collection} = state;
53+
let filteredCollection = [...collection.getKeys()].filter((key) => collection.getItem(key)?.type !== 'header');
54+
let prevItem = node.prevKey ? state.collection.getItem(node.prevKey) : undefined;
55+
rowIndex = prevItem ? filteredCollection.findIndex((key) => key === prevItem.key) + 2 : node.index + 1;
56+
}
4457

4558
return {
4659
rowProps: {
47-
role: 'row'
60+
role: 'row',
61+
'aria-rowindex': rowIndex
4862
},
4963
rowHeaderProps: {
5064
id: headingId,

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,11 +571,13 @@ export interface GridListSectionProps<T> extends SectionProps<T> {}
571571
export const GridListSection = /*#__PURE__*/ createBranchComponent('section', <T extends object>(props: GridListSectionProps<T>, ref: ForwardedRef<HTMLElement>, item: Node<T>) => {
572572
let state = useContext(ListStateContext)!;
573573
let {dragAndDropHooks, dropState} = useContext(DragAndDropContext)!;
574-
let {CollectionBranch} = useContext(CollectionRendererContext);
574+
let {CollectionBranch, isVirtualized} = useContext(CollectionRendererContext);
575575
let headingRef = useRef(null);
576576
let {rowHeaderProps, rowProps, rowGroupProps} = useGridListSection({
577-
'aria-label': props['aria-label'] ?? undefined
578-
});
577+
'aria-label': props['aria-label'] ?? undefined,
578+
isVirtualized,
579+
node: item
580+
}, state);
579581
let renderProps = useRenderProps({
580582
defaultClassName: 'react-aria-GridListSection',
581583
className: props.className,

packages/react-aria-components/stories/GridList.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ export function VirtualizedGridListSection() {
212212
let sections: {id: string, name: string, children: {id: string, name: string}[]}[] = [];
213213
for (let s = 0; s < 10; s++) {
214214
let items: {id: string, name: string}[] = [];
215-
for (let i = 0; i < 100; i++) {
215+
for (let i = 0; i < 3; i++) {
216216
items.push({id: `item_${s}_${i}`, name: `Section ${s}, Item ${i}`});
217217
}
218218
sections.push({id: `section_${s}`, name: `Section ${s}`, children: items});

0 commit comments

Comments
 (0)