Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9395a01
Fix #76903: Include category name in switch label
rushatgabhane Jan 8, 2026
0c08105
Fix #76907: Include subtitle in toggle switch label
rushatgabhane Jan 8, 2026
c073d9c
Fix #76908: Fix disabled state announcement order in pressables
rushatgabhane Jan 8, 2026
a2e84b5
Fix #76910: Always return button role instead of presentation
rushatgabhane Jan 8, 2026
e40af86
Fix #76911: Include alternate text in list item labels
rushatgabhane Jan 8, 2026
2dfbcae
Fix #76947: Remove redundant floating action text from labels
rushatgabhane Jan 8, 2026
72e3a03
Fix #76949: Add descriptive label to copilot learn more link
rushatgabhane Jan 8, 2026
abf2c59
Fix #76952: Add context to banner close button label
rushatgabhane Jan 8, 2026
8366313
Fix #76959: Add context to popover menu back button
rushatgabhane Jan 8, 2026
2d3cdbd
Fix #76961: Add custom accessibility label for select all checkbox
rushatgabhane Jan 8, 2026
4f326fc
Fix #77534, #77541, #77546: Add combobox role and accessibility state…
rushatgabhane Jan 8, 2026
79fa700
Fix #77561: Add button role to calendar picker controls
rushatgabhane Jan 8, 2026
cee5adf
Fix #77570: Remove presentation role from amount input
rushatgabhane Jan 8, 2026
28ed4b9
Add accessibilityLabel prop to MenuItem
rushatgabhane Jan 8, 2026
daf55cd
Fix #77498: Update FAB button label to "Open actions menu"
rushatgabhane Jan 8, 2026
1f25add
Merge branch 'main' into a11y/keyboard-inputs
rushatgabhane Jan 19, 2026
5f4c11e
run pretty
rushatgabhane Jan 19, 2026
188227e
Revert "Fix #77534, #77541, #77546: Add combobox role and accessibili…
rushatgabhane Jan 19, 2026
b9aefb8
Revert "Fix #76908: Fix disabled state announcement order in pressables"
rushatgabhane Jan 19, 2026
f7ef12d
rm unused accessibilitylabel
rushatgabhane Jan 19, 2026
fe4c4ef
Revert "rm unused accessibilitylabel"
rushatgabhane Jan 19, 2026
b961b29
use accessiblity label
rushatgabhane Jan 19, 2026
4e979ca
only include alternate text if it differs
rushatgabhane Jan 19, 2026
6a46491
swapping when shouldShowDescriptionOnTop
rushatgabhane Jan 19, 2026
a3ba3d0
Revert "Fix #76961: Add custom accessibility label for select all che…
rushatgabhane Jan 21, 2026
4ba6543
fix #76907
rushatgabhane Jan 21, 2026
2f40523
fix #76911 - pass subtitle to selection list
rushatgabhane Jan 21, 2026
53f10a9
fix string case
rushatgabhane Jan 21, 2026
4c6a214
add memoized accessibility label for report fields
rushatgabhane Jan 21, 2026
933a6a2
use reportFieldsAccessibilityLabel for switch
rushatgabhane Jan 21, 2026
bb6dd4b
fix merge
rushatgabhane Jan 21, 2026
df176d2
fix merge
rushatgabhane Jan 21, 2026
38911b3
fix merge
rushatgabhane Jan 22, 2026
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
1 change: 0 additions & 1 deletion src/components/AmountTextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ function AmountTextInput({
submitBehavior="submit"
selection={selection}
onSelectionChange={onSelectionChange}
role={CONST.ROLE.PRESENTATION}
onKeyPress={onKeyPress as (event: TextInputKeyPressEvent) => void}
touchableInputWrapperStyle={touchableInputWrapperStyle}
// On iPad, even if the soft keyboard is hidden, the keyboard suggestion is still shown.
Expand Down
2 changes: 1 addition & 1 deletion src/components/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function Banner({
<PressableWithFeedback
onPress={onClose}
role={CONST.ROLE.BUTTON}
accessibilityLabel={translate('common.close')}
accessibilityLabel={text ? `${translate('common.close')}, ${text}` : translate('common.close')}
>
<Icon
src={expensifyIcons.Close}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button/utils/index.web.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CONST from '@src/CONST';
import type {GetButtonRole} from './types';

const getButtonRole: GetButtonRole = (isNested) => (isNested ? CONST.ROLE.PRESENTATION : CONST.ROLE.BUTTON);
const getButtonRole: GetButtonRole = () => CONST.ROLE.BUTTON;

// eslint-disable-next-line import/prefer-default-export
export {getButtonRole};
4 changes: 4 additions & 0 deletions src/components/DatePicker/CalendarPicker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ function CalendarPicker({
disabled={years.length <= 1}
testID="currentYearButton"
accessibilityLabel={translate('common.currentYear')}
role={CONST.ROLE.BUTTON}
>
<Text
style={themeStyles.sidebarLinkTextBold}
Expand All @@ -219,6 +220,7 @@ function CalendarPicker({
onPress={moveToPrevMonth}
hoverDimmingValue={1}
accessibilityLabel={translate('common.previous')}
role={CONST.ROLE.BUTTON}
>
<ArrowIcon
disabled={!hasAvailableDatesPrevMonth}
Expand All @@ -232,6 +234,7 @@ function CalendarPicker({
onPress={moveToNextMonth}
hoverDimmingValue={1}
accessibilityLabel={translate('common.next')}
role={CONST.ROLE.BUTTON}
>
<ArrowIcon disabled={!hasAvailableDatesNextMonth} />
</PressableWithFeedback>
Expand Down Expand Up @@ -279,6 +282,7 @@ function CalendarPicker({
tabIndex={day ? 0 : -1}
accessible={!!day}
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
role={CONST.ROLE.BUTTON}
>
{({hovered, pressed}) => (
<DayComponent
Expand Down
7 changes: 6 additions & 1 deletion src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ type MenuItemBaseProps = ForwardedFSClassProps &
/** Text to display for the item */
title?: string;

/** Accessibility label for the menu item */
accessibilityLabel?: string;

/** Component to display as the title */
titleComponent?: ReactElement;

Expand Down Expand Up @@ -484,6 +487,7 @@ function MenuItem({
focused = false,
disabled = false,
title,
accessibilityLabel,
titleComponent,
titleContainerStyle,
subtitle,
Expand Down Expand Up @@ -567,6 +571,7 @@ function MenuItem({
const isCompact = viewMode === CONST.OPTION_MODE.COMPACT;
const isDeleted = style && Array.isArray(style) ? style.includes(styles.offlineFeedbackDeleted) : false;
const descriptionVerticalMargin = shouldShowDescriptionOnTop ? styles.mb1 : styles.mt1;
const defaultAccessibilityLabel = (shouldShowDescriptionOnTop ? [description, title] : [title, description]).filter(Boolean).join(', ');

const combinedTitleTextStyle = StyleUtils.combineStyles<TextStyle>(
[
Expand Down Expand Up @@ -754,7 +759,7 @@ function MenuItem({
disabled={disabled || isExecuting}
ref={mergeRefs(ref, popoverAnchor)}
role={role}
accessibilityLabel={title ? title.toString() : ''}
accessibilityLabel={accessibilityLabel ?? defaultAccessibilityLabel}
accessible={shouldBeAccessible}
tabIndex={tabIndex}
onFocus={onFocus}
Expand Down
6 changes: 5 additions & 1 deletion src/components/PopoverMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {GestureResponderEvent, LayoutChangeEvent, StyleProp, TextStyle, Vie
import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager';
import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import usePrevious from '@hooks/usePrevious';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useStyleUtils from '@hooks/useStyleUtils';
Expand Down Expand Up @@ -287,6 +288,7 @@ function BasePopoverMenu({
const styles = useThemeStyles();
const theme = useTheme();
const StyleUtils = useStyleUtils();
const {translate} = useLocalize();
// We need to use isSmallScreenWidth instead of shouldUseNarrowLayout to apply correct popover styles
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth} = useResponsiveLayout();
Expand Down Expand Up @@ -344,6 +346,7 @@ function BasePopoverMenu({
const previousMenuItems = getPreviousSubMenu();
const previouslySelectedItem = previousMenuItems[enteredSubMenuIndexes[enteredSubMenuIndexes.length - 1]];
const hasBackButtonText = !!previouslySelectedItem?.backButtonText;
const backButtonTitle = hasBackButtonText ? previouslySelectedItem?.backButtonText : previouslySelectedItem?.text;

return (
<MenuItem
Expand All @@ -352,7 +355,8 @@ function BasePopoverMenu({
iconFill={(isHovered) => (isHovered ? theme.iconHovered : theme.icon)}
style={hasBackButtonText ? styles.pv0 : undefined}
additionalIconStyles={[{width: variables.iconSizeSmall, height: variables.iconSizeSmall}, styles.opacitySemiTransparent, styles.mr1]}
title={hasBackButtonText ? previouslySelectedItem?.backButtonText : previouslySelectedItem?.text}
title={backButtonTitle}
accessibilityLabel={`${translate('common.goBack')}, ${backButtonTitle}`}
titleStyle={hasBackButtonText ? styles.createMenuHeaderText : undefined}
shouldShowBasicTitle={hasBackButtonText}
shouldCheckActionAllowedOnPress={false}
Expand Down
2 changes: 1 addition & 1 deletion src/components/SelectionList/ListItem/BaseListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function BaseListItem<TItem extends ListItem>({
}}
disabled={isDisabled && !item.isSelected}
interactive={item.isInteractive}
accessibilityLabel={item.accessibilityLabel ?? item.text ?? ''}
accessibilityLabel={item.accessibilityLabel ?? [item.text, item.text !== item.alternateText ? item.alternateText : undefined].filter(Boolean).join(', ')}
role={getButtonRole(true)}
isNested
hoverDimmingValue={1}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function BaseListItem<TItem extends ListItem>({
}}
disabled={isDisabled && !item.isSelected}
interactive={item.isInteractive}
accessibilityLabel={item.text ?? ''}
accessibilityLabel={[item.text, item.text !== item.alternateText ? item.alternateText : undefined].filter(Boolean).join(', ')}
Copy link
Contributor

@Pujan92 Pujan92 Jan 20, 2026

Choose a reason for hiding this comment

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

We also need to add alternateText in SelectionList -> BaseListItem to fix issue #76911

accessibilityLabel={item.text ?? ''}

Copy link
Member Author

@rushatgabhane rushatgabhane Jan 21, 2026

Choose a reason for hiding this comment

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

thank you, fixed!

2f40523

role={getButtonRole(true)}
isNested
hoverDimmingValue={1}
Expand Down
2 changes: 1 addition & 1 deletion src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Etwas suchen …',
buttonMySettings: 'Meine Einstellungen',
fabNewChat: 'Chat starten',
fabNewChatExplained: 'Chat starten (Schwebende Aktion)',
fabNewChatExplained: 'Aktionsmenü öffnen',
fabScanReceiptExplained: 'Beleg scannen (Schwebende Aktion)',
chatPinned: 'Chat angeheftet',
draftedMessage: 'Entwurfsnachricht',
Expand Down
4 changes: 2 additions & 2 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -955,8 +955,8 @@ const translations = {
buttonFind: 'Find something...',
buttonMySettings: 'My settings',
fabNewChat: 'Start chat',
fabNewChatExplained: 'Start chat (Floating action)',
fabScanReceiptExplained: 'Scan receipt (Floating action)',
fabNewChatExplained: 'Open actions menu',
fabScanReceiptExplained: 'Scan receipt',
chatPinned: 'Chat pinned',
draftedMessage: 'Drafted message',
listOfChatMessages: 'List of chat messages',
Expand Down
4 changes: 2 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -698,8 +698,8 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Encuentre algo...',
buttonMySettings: 'Mi configuración',
fabNewChat: 'Iniciar chat',
fabNewChatExplained: 'Iniciar chat (Acción flotante)',
fabScanReceiptExplained: 'Escanear recibo (Acción flotante)',
fabNewChatExplained: 'Abrir menú de acciones',
fabScanReceiptExplained: 'Escanear recibo',
chatPinned: 'Chat fijado',
draftedMessage: 'Mensaje borrador',
listOfChatMessages: 'Lista de mensajes del chat',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Rechercher quelque chose...',
buttonMySettings: 'Mes paramètres',
fabNewChat: 'Démarrer le chat',
fabNewChatExplained: 'Démarrer le chat (Action flottante)',
fabNewChatExplained: "Ouvrir le menu d'actions",
fabScanReceiptExplained: 'Scanner un reçu (Action flottante)',
chatPinned: 'Discussion épinglée',
draftedMessage: 'Message rédigé',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Trova qualcosa...',
buttonMySettings: 'Le mie impostazioni',
fabNewChat: 'Avvia chat',
fabNewChatExplained: 'Avvia chat (Azione flottante)',
fabNewChatExplained: 'Apri menu azioni',
fabScanReceiptExplained: 'Scansiona ricevuta (Azione flottante)',
chatPinned: 'Chat fissata',
draftedMessage: 'Messaggio in bozza',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: '何かを検索…',
buttonMySettings: 'マイ設定',
fabNewChat: 'チャットを開始',
fabNewChatExplained: 'チャットを開始 (フローティングアクション)',
fabNewChatExplained: 'アクションメニューを開く',
fabScanReceiptExplained: '領収書をスキャン',
chatPinned: 'ピン留めされたチャット',
draftedMessage: '下書きメッセージ',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Zoek iets...',
buttonMySettings: 'Mijn instellingen',
fabNewChat: 'Chat starten',
fabNewChatExplained: 'Chat starten (zwevende actie)',
fabNewChatExplained: 'Actiemenu openen',
fabScanReceiptExplained: 'Bon scannen (Zwevende actie)',
chatPinned: 'Chat vastgezet',
draftedMessage: 'Conceptbericht',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Znajdź coś...',
buttonMySettings: 'Moje ustawienia',
fabNewChat: 'Rozpocznij czat',
fabNewChatExplained: 'Rozpocznij czat (Akcja pływająca)',
fabNewChatExplained: 'Otwórz menu akcji',
fabScanReceiptExplained: 'Zeskanuj paragon (Akcja pływająca)',
chatPinned: 'Czat przypięty',
draftedMessage: 'Wiadomość robocza',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: 'Encontre algo...',
buttonMySettings: 'Minhas configurações',
fabNewChat: 'Iniciar chat',
fabNewChatExplained: 'Iniciar chat (Ação flutuante)',
fabNewChatExplained: 'Abrir menu de ações',
fabScanReceiptExplained: 'Digitalizar recibo (Ação flutuante)',
chatPinned: 'Conversa fixada',
draftedMessage: 'Mensagem rascunhada',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ const translations: TranslationDeepObject<typeof en> = {
buttonFind: '查找内容…',
buttonMySettings: '我的设置',
fabNewChat: '开始聊天',
fabNewChatExplained: '开始聊天(浮动操作)',
fabNewChatExplained: '打开操作菜单',
fabScanReceiptExplained: '扫描收据(浮动操作)',
chatPinned: '聊天已置顶',
draftedMessage: '已起草的消息',
Expand Down
1 change: 1 addition & 0 deletions src/pages/settings/Security/SecuritySettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ function SecuritySettingsPage() {
<TextLink
style={[styles.link]}
href={CONST.COPILOT_HELP_URL}
accessibilityLabel={translate('delegate.copilotDelegatedAccess')}
>
{translate('common.learnMore')}
</TextLink>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/workspace/categories/WorkspaceCategoriesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
<Switch
isOn={value.enabled}
disabled={isDisabled}
accessibilityLabel={translate('workspace.categories.enableCategory')}
accessibilityLabel={`${translate('workspace.categories.enableCategory')}: ${getDecodedCategoryName(value.name)}`}
onToggle={(newValue: boolean) => {
if (isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])) {
setIsCannotDeleteOrDisableLastCategoryModalVisible(true);
Expand All @@ -222,7 +222,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
<Switch
isOn={value.enabled}
disabled={isDisabled}
accessibilityLabel={translate('workspace.categories.enableCategory')}
accessibilityLabel={`${translate('workspace.categories.enableCategory')}: ${getDecodedCategoryName(value.name)}`}
onToggle={(newValue: boolean) => {
if (isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])) {
setIsCannotDeleteOrDisableLastCategoryModalVisible(true);
Expand Down
11 changes: 9 additions & 2 deletions src/pages/workspace/reports/WorkspaceReportsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {FlashList} from '@shopify/flash-list';
import type {ListRenderItemInfo} from '@shopify/flash-list';
import {Str} from 'expensify-common';
import React, {useEffect, useState} from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import ActivityIndicator from '@components/ActivityIndicator';
import ConfirmModal from '@components/ConfirmModal';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import {Plus} from '@components/Icon/Expensicons';

Check warning on line 9 in src/pages/workspace/reports/WorkspaceReportsPage.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'@components/Icon/Expensicons' import is restricted from being used by a pattern. Direct imports from Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details

Check warning on line 9 in src/pages/workspace/reports/WorkspaceReportsPage.tsx

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

'@components/Icon/Expensicons' import is restricted from being used. Direct imports from @components/Icon/Expensicons are deprecated. Please use lazy loading hooks instead. Use `useMemoizedLazyExpensifyIcons` from @hooks/useLazyAsset. See docs/LAZY_ICONS_AND_ILLUSTRATIONS.md for details
import ImportedFromAccountingSoftware from '@components/ImportedFromAccountingSoftware';
import MenuItem from '@components/MenuItem';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
Expand Down Expand Up @@ -162,6 +162,13 @@
</OfflineWithFeedback>
);

const reportFieldsAccessibilityLabel = useMemo(() => {
if (!hasSyncError && isConnectionVerified && currentConnectionName) {
return `${translate('workspace.common.reportFields')}, ${translate('workspace.reportFields.importedFromAccountingSoftware')} ${currentConnectionName} ${translate('workspace.accounting.settings')}`;
}
return `${translate('workspace.common.reportFields')}, ${translate('workspace.reportFields.subtitle')}`;
}, [hasSyncError, isConnectionVerified, currentConnectionName, translate]);

return (
<AccessOrNotFoundWrapper
policyID={policyID}
Expand Down Expand Up @@ -241,7 +248,7 @@
<ToggleSettingOptionRow
pendingAction={policy?.pendingFields?.areReportFieldsEnabled}
title={translate('workspace.common.reportFields')}
switchAccessibilityLabel={translate('workspace.common.reportFields')}
switchAccessibilityLabel={reportFieldsAccessibilityLabel}
subtitle={getHeaderText()}
titleStyle={[styles.textHeadline, styles.cardSectionTitle, styles.accountSettingsSectionTitle, styles.mb1]}
isActive={!!policy?.areReportFieldsEnabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ function ToggleSettingOptionRow({
</PressableWithoutFeedback>
<Switch
disabledAction={disabledAction}
accessibilityLabel={switchAccessibilityLabel}
accessibilityLabel={typeof subtitle === 'string' && subtitle ? `${switchAccessibilityLabel}, ${subtitle}` : switchAccessibilityLabel}
onToggle={(isOn) => {
shouldAnimateAccordionSection.set(true);
onToggle(isOn);
Expand Down
Loading