diff --git a/src/components/SelectionList/ListItem/BaseListItem.tsx b/src/components/SelectionList/ListItem/BaseListItem.tsx index a41a9b93c161b..1810738698b0a 100644 --- a/src/components/SelectionList/ListItem/BaseListItem.tsx +++ b/src/components/SelectionList/ListItem/BaseListItem.tsx @@ -47,6 +47,7 @@ function BaseListItem({ shouldDisableHoverStyle, shouldStopMouseLeavePropagation = true, shouldShowRightCaret = false, + accessible, }: BaseListItemProps) { const theme = useTheme(); const styles = useThemeStyles(); @@ -113,7 +114,6 @@ function BaseListItem({ disabled={isDisabled && !item.isSelected} interactive={item.isInteractive} accessibilityLabel={item.accessibilityLabel ?? [item.text, item.text !== item.alternateText ? item.alternateText : undefined].filter(Boolean).join(', ')} - role={getButtonRole(true)} isNested hoverDimmingValue={1} pressDimmingValue={item.isInteractive === false ? 1 : variables.pressDimValue} @@ -134,9 +134,12 @@ function BaseListItem({ ]} onFocus={onFocus} onMouseLeave={handleMouseLeave} - tabIndex={item.tabIndex} + tabIndex={accessible === false ? -1 : item.tabIndex} wrapperStyle={pressableWrapperStyle} testID={testID} + accessible={accessible} + role={accessible === false ? CONST.ROLE.PRESENTATION : getButtonRole(true)} + sentryLabel={`BaseListItem-${keyForList}`} > ({ const icons = useMemoizedLazyExpensifyIcons(['ArrowRight', 'Folder', 'Tag'] as const); const theme = useTheme(); const styles = useThemeStyles(); + const {translate} = useLocalize(); const {didScreenTransitionEnd} = useScreenWrapperTransitionStatus(); const splitItem = item as unknown as SplitListItemType; @@ -83,6 +86,16 @@ function SplitListItem({ const isPercentageMode = splitItem.mode === CONST.TAB.SPLIT.PERCENTAGE; + // Build accessibility label for the grouped text content (date, merchant, category, tags) + const textContentAccessibilityLabel = [ + splitItem.headerText, + splitItem.merchant, + splitItem.category ? getDecodedCategoryName(splitItem.category) : undefined, + splitItem.tags?.at(0) ? getCommaSeparatedTagNameWithSanitizedColons(splitItem.tags.at(0) ?? '') : undefined, + ] + .filter(Boolean) + .join(', '); + return ( ({ keyForList={item.keyForList} onFocus={onFocus} pendingAction={item.pendingAction} + accessible={!splitItem.isEditable} > - - + + ({ {isBottomVisible && ( - + {!!splitItem.category && ( ({ {!splitItem.isEditable ? null : ( - + onSelectRow(item)} + accessibilityLabel={translate('common.edit')} + role="button" + style={styles.pointerEventsAuto} + sentryLabel="SplitListItem-EditButton" + > - + )} diff --git a/src/components/SelectionList/ListItem/types.ts b/src/components/SelectionList/ListItem/types.ts index 8301690764467..da4052bae2a46 100644 --- a/src/components/SelectionList/ListItem/types.ts +++ b/src/components/SelectionList/ListItem/types.ts @@ -314,6 +314,12 @@ type BaseListItemProps = CommonListItemProps & { /** Whether to call stopPropagation on the mouseleave event in BaseListItem */ shouldStopMouseLeavePropagation?: boolean; + + /** + * Whether the pressable should be accessible as a single element. + * When false, allows child elements (like TextInput) to be independently focusable by screen readers. + */ + accessible?: boolean; }; type SplitListItemType = ListItem &