Skip to content

Commit

Permalink
move accessibilityCollectionItem logic to VirtList
Browse files Browse the repository at this point in the history
further info at fabOnReact/react-native-notes#6 (comment)
- Adds support for SectionList, VirtualizedList
- Sharing common logic between components

The accessibilityCollectionItem is calculated in the VirtualizedList and
passed as a 4th parameter to renderItem function

https://github.com/fabriziobertoglio1987/react-native-notes/blob/f49caa490eb2378466bfa3eeb672aa6eab5b65b7/Libraries/Lists/VirtualizedList.js#L1995-L2023
```javascript
renderItem({
  item,
    index,
    separators: this._separators,
    accessibilityCollectionItem,
});
```

adding accessibilityCollectionItem would make the FlatList cell or
VirtualizedList row announce row 1 column 1, row 2 column 2 ...
https://reactnative.dev/docs/next/flatlist#required-renderitem

The main difference between FlatList and VirtualizedList is that
FlatList can have numColumns > 1 and the computation of
accessibilityCollectionItem is changed in the FlatList based on the
numColumns value.

TODO
- Move logic to ScrollView and add support for ScrollView
- Add accessibilityCollectionItem prop to View. The user can change this
  prop and it is part of the public API
  • Loading branch information
fabOnReact committed Mar 14, 2022
1 parent f49caa4 commit 7514735
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 38 deletions.
29 changes: 4 additions & 25 deletions Libraries/Lists/FlatList.js
Original file line number Diff line number Diff line change
Expand Up @@ -600,13 +600,6 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
}
};

const defaultAccessibilityCollectionItem = {
rowSpan: 1,
columnIndex: 0,
columnSpan: 1,
heading: false,
};

return {
/* $FlowFixMe[invalid-computed-prop] (>=0.111.0 site=react_native_fb)
* This comment suppresses an error found when Flow v0.111 was deployed.
Expand All @@ -623,14 +616,13 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
{item.map((it, kk) => {
const itemIndex = index * numColumns + kk;
const accessibilityCollectionItem = {
...defaultAccessibilityCollectionItem,
rowIndex: index,
...info.accessibilityCollectionItem,
columnIndex: itemIndex % numColumns,
itemIndex: itemIndex,
};
const element = renderer({
item: it,
index: index * numColumns + kk,
index: itemIndex,
separators: info.separators,
accessibilityCollectionItem,
});
Expand All @@ -641,16 +633,7 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
</View>
);
} else {
const accessibilityCollectionItem = {
...defaultAccessibilityCollectionItem,
rowIndex: info.index,
itemIndex: info.index,
};

return renderer({
...info,
accessibilityCollectionItem,
});
return renderer(info);
}
},
};
Expand All @@ -670,11 +653,7 @@ class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
getItem={this._getItem}
getItemCount={this._getItemCount}
keyExtractor={this._keyExtractor}
numColumns={numColumnsOrDefault(this.props.numColumns)}
accessibilityRole={Platform.select({
android:
numColumnsOrDefault(this.props.numColumns) > 1 ? 'grid' : 'list',
})}
numColumns={numColumnsOrDefault(numColumns)}
ref={this._captureRef}
viewabilityConfigCallbackPairs={this._virtualizedListPairs}
removeClippedSubviews={removeClippedSubviewsOrDefault(
Expand Down
48 changes: 35 additions & 13 deletions Libraries/Lists/VirtualizedList.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const Batchinator = require('../Interaction/Batchinator');
const FillRateHelper = require('./FillRateHelper');
const ReactNative = require('../Renderer/shims/ReactNative');
const RefreshControl = require('../Components/RefreshControl/RefreshControl');
const Platform = require('../Utilities/Platform');
const ScrollView = require('../Components/ScrollView/ScrollView');
const StyleSheet = require('../StyleSheet/StyleSheet');
const View = require('../Components/View/View');
Expand Down Expand Up @@ -305,6 +306,11 @@ type Props = {|
...OptionalProps,
|};

// numColumnsOrDefault(this.props.numColumns)
function numColumnsOrDefault(numColumns: ?number) {
return numColumns ?? 1;
}

let _usedIndexForKey = false;
let _keylessItemComponentName: string = '';

Expand Down Expand Up @@ -1233,18 +1239,8 @@ class VirtualizedList extends React.PureComponent<Props, State> {
);
}

_getAccessibilityCollection = () => {
const accessibilityCollectionProps = {
itemCount: this.props.data ? this.props.data.length : 0,
rowCount: this.props.getItemCount(this.props.data),
columnCount: this.props.numColumns,
hierarchical: false,
};

return accessibilityCollectionProps;
};

_defaultRenderScrollComponent = props => {
const {getItemCount, data} = props;
const onRefresh = props.onRefresh;
if (this._isNestedWithSameOrientation()) {
// $FlowFixMe[prop-missing] - Typing ReactNativeComponent revealed errors
Expand All @@ -1256,11 +1252,22 @@ class VirtualizedList extends React.PureComponent<Props, State> {
JSON.stringify(props.refreshing ?? 'undefined') +
'`',
);
const numColumns = numColumnsOrDefault(props.numColumns);
const accessibilityRole = Platform.select({
android: numColumns > 1 ? 'grid' : 'list',
});
const accessibilityCollection = {
itemCount: data ? data.length : 0,
rowCount: getItemCount(data),
columnCount: numColumnsOrDefault(numColumns),
hierarchical: false,
};
return (
// $FlowFixMe[prop-missing] Invalid prop usage
<ScrollView
{...props}
accessibilityCollection={this._getAccessibilityCollection()}
accessibilityRole={accessibilityRole}
accessibilityCollection={accessibilityCollection}
refreshControl={
props.refreshControl == null ? (
<RefreshControl
Expand All @@ -1276,7 +1283,13 @@ class VirtualizedList extends React.PureComponent<Props, State> {
);
} else {
// $FlowFixMe[prop-missing] Invalid prop usage
return <ScrollView {...props} />;
return (
<ScrollView
accessibilityRole={accessibilityRole}
accessibilityCollection={accessibilityCollection}
{...props}
/>
);
}
};

Expand Down Expand Up @@ -2015,10 +2028,19 @@ class CellRenderer extends React.Component<
}

if (renderItem) {
const accessibilityCollectionItem = {
itemIndex: index,
rowIndex: index,
rowSpan: 1,
columnIndex: 0,
columnSpan: 1,
heading: false,
};
return renderItem({
item,
index,
separators: this._separators,
accessibilityCollectionItem,
});
}

Expand Down

0 comments on commit 7514735

Please sign in to comment.