From 9395a0144f0cf8e254c967e2415298ca483be061 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:32:58 +0300 Subject: [PATCH 01/30] Fix #76903: Include category name in switch label --- src/pages/workspace/categories/WorkspaceCategoriesPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx index a547794e1dd53..19502f19eabce 100644 --- a/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx +++ b/src/pages/workspace/categories/WorkspaceCategoriesPage.tsx @@ -212,7 +212,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { { if (isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])) { setIsCannotDeleteOrDisableLastCategoryModalVisible(true); @@ -228,7 +228,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) { { if (isDisablingOrDeletingLastEnabledCategory(policy, policyCategories, [value])) { setIsCannotDeleteOrDisableLastCategoryModalVisible(true); From 0c08105c96cc3ed805f3dbd30354b7302ac21f1e Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:32:58 +0300 Subject: [PATCH 02/30] Fix #76907: Include subtitle in toggle switch label --- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 70d9a48332a80..4c92cc114611e 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -201,7 +201,7 @@ function ToggleSettingOptionRow({ { shouldAnimateAccordionSection.set(true); onToggle(isOn); From c073d9c9eece90087dc2c750a200ba357bcf4269 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:32:59 +0300 Subject: [PATCH 03/30] Fix #76908: Fix disabled state announcement order in pressables --- .../implementation/BaseGenericPressable.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx b/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx index 8cac1a9551089..501f649295320 100644 --- a/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx +++ b/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx @@ -171,10 +171,13 @@ function GenericPressable({ isDisabled && [StyleUtils.parseStyleFromFunction(disabledStyle, state), styles.noSelect], isRoleButton && styles.userSelectNone, ]} - // accessibility props + fsClass={forwardedFSClass} + // eslint-disable-next-line react/jsx-props-no-spreading + {...rest} + // accessibility props - must come after {...rest} to ensure proper disabled state announcement accessibilityState={{ - disabled: isDisabled, ...rest.accessibilityState, + disabled: isDisabled, }} aria-disabled={isDisabled} aria-keyshortcuts={keyboardShortcut && `${keyboardShortcut.modifiers.join('')}+${keyboardShortcut.shortcutKey}`} @@ -182,9 +185,6 @@ function GenericPressable({ onMagicTap={!isDisabled ? voidOnPressHandler : undefined} onAccessibilityTap={!isDisabled ? voidOnPressHandler : undefined} accessible={accessible} - fsClass={forwardedFSClass} - // eslint-disable-next-line react/jsx-props-no-spreading - {...rest} onHoverOut={(event) => { if (event?.type === 'pointerenter' || event?.type === 'mouseenter') { return; From a2e84b5da0640cc9ac8221d9c64d8df99c40b1d3 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:32:59 +0300 Subject: [PATCH 04/30] Fix #76910: Always return button role instead of presentation --- src/components/Button/utils/index.web.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Button/utils/index.web.ts b/src/components/Button/utils/index.web.ts index 3235b10e35bd8..16aee4cb19cb6 100644 --- a/src/components/Button/utils/index.web.ts +++ b/src/components/Button/utils/index.web.ts @@ -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}; From e40af8672dcda777aa7a767817d55b36023cd6e3 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:12 +0300 Subject: [PATCH 05/30] Fix #76911: Include alternate text in list item labels --- src/components/SelectionListWithSections/BaseListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SelectionListWithSections/BaseListItem.tsx b/src/components/SelectionListWithSections/BaseListItem.tsx index ea490d7e6c3e1..976cf04e8a356 100644 --- a/src/components/SelectionListWithSections/BaseListItem.tsx +++ b/src/components/SelectionListWithSections/BaseListItem.tsx @@ -107,7 +107,7 @@ function BaseListItem({ }} disabled={isDisabled && !item.isSelected} interactive={item.isInteractive} - accessibilityLabel={item.text ?? ''} + accessibilityLabel={[item.text, item.alternateText].filter(Boolean).join(', ')} role={getButtonRole(true)} isNested hoverDimmingValue={1} From 2dfbcae8afaac2720b697d9f7ff2d32ed8510a31 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:12 +0300 Subject: [PATCH 06/30] Fix #76947: Remove redundant floating action text from labels --- src/languages/en.ts | 4 ++-- src/languages/es.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index a0c754e62dbbc..7fa9cf0314696 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -957,8 +957,8 @@ const translations = { buttonFind: 'Find something...', buttonMySettings: 'My settings', fabNewChat: 'Start chat', - fabNewChatExplained: 'Start chat (Floating action)', - fabScanReceiptExplained: 'Scan receipt (Floating action)', + fabNewChatExplained: 'Start chat', + fabScanReceiptExplained: 'Scan receipt', chatPinned: 'Chat pinned', draftedMessage: 'Drafted message', listOfChatMessages: 'List of chat messages', diff --git a/src/languages/es.ts b/src/languages/es.ts index 2ed90a809ac4d..7e4eb03a211a5 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -666,8 +666,8 @@ const translations: TranslationDeepObject = { buttonFind: 'Encuentre algo...', buttonMySettings: 'Mi configuración', fabNewChat: 'Iniciar chat', - fabNewChatExplained: 'Iniciar chat (Acción flotante)', - fabScanReceiptExplained: 'Escanear recibo (Acción flotante)', + fabNewChatExplained: 'Iniciar chat', + fabScanReceiptExplained: 'Escanear recibo', chatPinned: 'Chat fijado', draftedMessage: 'Mensaje borrador', listOfChatMessages: 'Lista de mensajes del chat', From 72e3a030e0457a8a302003abe68f56612f1d532c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:13 +0300 Subject: [PATCH 07/30] Fix #76949: Add descriptive label to copilot learn more link --- src/pages/settings/Security/SecuritySettingsPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index d1c77959961cd..909ca8962a505 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -385,6 +385,7 @@ function SecuritySettingsPage() { {translate('common.learnMore')} From abf2c59148f58723f2b910824c5ea4a17e4b60df Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:25 +0300 Subject: [PATCH 08/30] Fix #76952: Add context to banner close button label --- src/components/Banner.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Banner.tsx b/src/components/Banner.tsx index 8348d0f5323c8..b5ba853f3b98a 100644 --- a/src/components/Banner.tsx +++ b/src/components/Banner.tsx @@ -131,7 +131,7 @@ function Banner({ Date: Thu, 8 Jan 2026 17:33:26 +0300 Subject: [PATCH 09/30] Fix #76959: Add context to popover menu back button --- src/components/PopoverMenu.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/PopoverMenu.tsx b/src/components/PopoverMenu.tsx index 742cfa872acbe..ab23bde899237 100644 --- a/src/components/PopoverMenu.tsx +++ b/src/components/PopoverMenu.tsx @@ -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'; @@ -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(); @@ -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 ( (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} From 2d3cdbd3e65cabc8599bbe80533ba55cf3178ea1 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:26 +0300 Subject: [PATCH 10/30] Fix #76961: Add custom accessibility label for select all checkbox --- .../BaseSelectionListWithSections.tsx | 7 +++++-- src/components/SelectionListWithSections/types.ts | 3 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx b/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx index 7eb2b96aaaa91..c0999af094075 100644 --- a/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx +++ b/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx @@ -45,6 +45,7 @@ function BaseSelectionListWithSections({ shouldSingleExecuteRowSelect = false, onCheckboxPress, onSelectAll, + selectAllAccessibilityLabel, onDismissError, getItemHeight = getDefaultItemHeight, textInputLabel = '', @@ -608,6 +609,8 @@ function BaseSelectionListWithSections({ ); }; + const selectAllLabel = selectAllAccessibilityLabel ?? translate('workspace.people.selectAll'); + const header = () => ( <> {!headerMessage && canSelectMultiple && shouldShowSelectAll && ( @@ -615,7 +618,7 @@ function BaseSelectionListWithSections({ ({ = Partial & { /** Callback to fire when "Select All" checkbox is pressed. Only use along with `canSelectMultiple` */ onSelectAll?: () => void; + /** Custom accessibility label for the "Select All" checkbox. Defaults to 'Select all' */ + selectAllAccessibilityLabel?: string; + /** * Callback that should return height of the specific item * Only use this if we're handling some non-standard items, most of the time the default value is correct From 4f326fc40c7a47567e22bd6e0fb9f648aafe59c9 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:37 +0300 Subject: [PATCH 11/30] Fix #77534, #77541, #77546: Add combobox role and accessibility state to picker --- src/components/Picker/BasePicker.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/Picker/BasePicker.tsx b/src/components/Picker/BasePicker.tsx index c78b8cbbe85cb..8edeb91d23563 100644 --- a/src/components/Picker/BasePicker.tsx +++ b/src/components/Picker/BasePicker.tsx @@ -204,6 +204,16 @@ function BasePicker({ onClose={disableHighlight} textInputProps={{ allowFontScaling: false, + accessibilityRole: 'combobox', + accessibilityLabel: label ? `${label}, ${value}` : String(value), + accessibilityState: {disabled: isDisabled, expanded: isHighlighted}, + }} + touchableDoneProps={{ + accessibilityRole: 'button', + }} + touchableWrapperProps={{ + accessibilityRole: 'button', + accessibilityLabel: 'Dismiss', }} pickerProps={{ ref: picker, From 79fa700198a19b7c783a4643f7b6447c7327885a Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 8 Jan 2026 17:33:38 +0300 Subject: [PATCH 12/30] Fix #77561: Add button role to calendar picker controls --- src/components/DatePicker/CalendarPicker/index.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/DatePicker/CalendarPicker/index.tsx b/src/components/DatePicker/CalendarPicker/index.tsx index b46720c88c829..e0e0faea170a0 100644 --- a/src/components/DatePicker/CalendarPicker/index.tsx +++ b/src/components/DatePicker/CalendarPicker/index.tsx @@ -194,6 +194,7 @@ function CalendarPicker({ disabled={years.length <= 1} testID="currentYearButton" accessibilityLabel={translate('common.currentYear')} + role={CONST.ROLE.BUTTON} > @@ -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}) => ( Date: Thu, 8 Jan 2026 17:33:38 +0300 Subject: [PATCH 13/30] Fix #77570: Remove presentation role from amount input --- src/components/AmountTextInput.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/AmountTextInput.tsx b/src/components/AmountTextInput.tsx index 58a9d0fcd5517..96395a6fa134b 100644 --- a/src/components/AmountTextInput.tsx +++ b/src/components/AmountTextInput.tsx @@ -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. From 28ed4b92a759669e40c9b4f6f1cfe262c4e04e7b Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Fri, 9 Jan 2026 00:34:50 +0300 Subject: [PATCH 14/30] Add accessibilityLabel prop to MenuItem Allow passing custom accessibility labels to MenuItem component --- src/components/MenuItem.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index f11abee49c161..960f7d4c6fb74 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -209,6 +209,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; @@ -461,6 +464,7 @@ function MenuItem({ focused = false, disabled = false, title, + accessibilityLabel, titleComponent, titleContainerStyle, subtitle, @@ -724,7 +728,7 @@ function MenuItem({ disabled={disabled || isExecuting} ref={mergeRefs(ref, popoverAnchor)} role={CONST.ROLE.MENUITEM} - accessibilityLabel={title ? title.toString() : ''} + accessibilityLabel={accessibilityLabel ?? (title ? title.toString() : '')} accessible onFocus={onFocus} sentryLabel={sentryLabel} From daf55cd89d63c7ad86f01faea220699ae9058be6 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Fri, 9 Jan 2026 00:55:55 +0300 Subject: [PATCH 15/30] Fix #77498: Update FAB button label to "Open actions menu" Co-Authored-By: Claude Opus 4.5 --- src/languages/de.ts | 2 +- src/languages/en.ts | 2 +- src/languages/es.ts | 2 +- src/languages/fr.ts | 2 +- src/languages/it.ts | 2 +- src/languages/ja.ts | 2 +- src/languages/nl.ts | 2 +- src/languages/pl.ts | 2 +- src/languages/pt-BR.ts | 2 +- src/languages/zh-hans.ts | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/languages/de.ts b/src/languages/de.ts index 736eab6999d3e..0beb6840ac3f1 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -974,7 +974,7 @@ const translations: TranslationDeepObject = { 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', diff --git a/src/languages/en.ts b/src/languages/en.ts index 7fa9cf0314696..b75f8aded087b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -957,7 +957,7 @@ const translations = { buttonFind: 'Find something...', buttonMySettings: 'My settings', fabNewChat: 'Start chat', - fabNewChatExplained: 'Start chat', + fabNewChatExplained: 'Open actions menu', fabScanReceiptExplained: 'Scan receipt', chatPinned: 'Chat pinned', draftedMessage: 'Drafted message', diff --git a/src/languages/es.ts b/src/languages/es.ts index 7e4eb03a211a5..ed30f4b13a95b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -666,7 +666,7 @@ const translations: TranslationDeepObject = { buttonFind: 'Encuentre algo...', buttonMySettings: 'Mi configuración', fabNewChat: 'Iniciar chat', - fabNewChatExplained: 'Iniciar chat', + fabNewChatExplained: 'Abrir menú de acciones', fabScanReceiptExplained: 'Escanear recibo', chatPinned: 'Chat fijado', draftedMessage: 'Mensaje borrador', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 6974bab3986c7..bda254765ac66 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -976,7 +976,7 @@ const translations: TranslationDeepObject = { 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é', diff --git a/src/languages/it.ts b/src/languages/it.ts index 0c6a41bf918b6..a97f04ec13cc2 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -973,7 +973,7 @@ const translations: TranslationDeepObject = { 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', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 385fc00e960be..d82e6f5d05689 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -972,7 +972,7 @@ const translations: TranslationDeepObject = { buttonFind: '何かを検索…', buttonMySettings: 'マイ設定', fabNewChat: 'チャットを開始', - fabNewChatExplained: 'チャットを開始 (フローティングアクション)', + fabNewChatExplained: 'アクションメニューを開く', fabScanReceiptExplained: '領収書をスキャン', chatPinned: 'ピン留めされたチャット', draftedMessage: '下書きメッセージ', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index d405ca615944b..6f8f17b247b1a 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -973,7 +973,7 @@ const translations: TranslationDeepObject = { 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', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index a60e02d7c5023..fbe4a98204da4 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -973,7 +973,7 @@ const translations: TranslationDeepObject = { 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', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 5c6d81a4e554b..8c9440da4b1dc 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -972,7 +972,7 @@ const translations: TranslationDeepObject = { 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', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 1783d8af0106e..19c7e8200c4f8 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -961,7 +961,7 @@ const translations: TranslationDeepObject = { buttonFind: '查找内容…', buttonMySettings: '我的设置', fabNewChat: '开始聊天', - fabNewChatExplained: '开始聊天(浮动操作)', + fabNewChatExplained: '打开操作菜单', fabScanReceiptExplained: '扫描收据(浮动操作)', chatPinned: '聊天已置顶', draftedMessage: '已起草的消息', From 5f4c11e08bfec684144654a2e5df744fe8541924 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 07:44:27 +0100 Subject: [PATCH 16/30] run pretty --- src/languages/fr.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/fr.ts b/src/languages/fr.ts index 979068c07f3ca..98c70593171dd 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -1001,7 +1001,7 @@ const translations: TranslationDeepObject = { buttonFind: 'Rechercher quelque chose...', buttonMySettings: 'Mes paramètres', fabNewChat: 'Démarrer le chat', - fabNewChatExplained: 'Ouvrir le menu d\'actions', + fabNewChatExplained: "Ouvrir le menu d'actions", fabScanReceiptExplained: 'Scanner un reçu (Action flottante)', chatPinned: 'Discussion épinglée', draftedMessage: 'Message rédigé', From 188227ef199944443fa517574b5c6d3305b056df Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 07:46:33 +0100 Subject: [PATCH 17/30] Revert "Fix #77534, #77541, #77546: Add combobox role and accessibility state to picker" This reverts commit 4f326fc40c7a47567e22bd6e0fb9f648aafe59c9. --- src/components/Picker/BasePicker.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/components/Picker/BasePicker.tsx b/src/components/Picker/BasePicker.tsx index edd204cab1517..462646b49123b 100644 --- a/src/components/Picker/BasePicker.tsx +++ b/src/components/Picker/BasePicker.tsx @@ -204,16 +204,6 @@ function BasePicker({ onClose={disableHighlight} textInputProps={{ allowFontScaling: false, - accessibilityRole: 'combobox', - accessibilityLabel: label ? `${label}, ${value}` : String(value), - accessibilityState: {disabled: isDisabled, expanded: isHighlighted}, - }} - touchableDoneProps={{ - accessibilityRole: 'button', - }} - touchableWrapperProps={{ - accessibilityRole: 'button', - accessibilityLabel: 'Dismiss', }} pickerProps={{ ref: picker, From b9aefb8088e7bbdadfc98b85ac0aa2e6408e07dd Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 08:23:56 +0100 Subject: [PATCH 18/30] Revert "Fix #76908: Fix disabled state announcement order in pressables" This reverts commit c073d9c9eece90087dc2c750a200ba357bcf4269. --- .../implementation/BaseGenericPressable.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx b/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx index e75c31ec4fb60..513e3df69bb04 100644 --- a/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx +++ b/src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx @@ -170,13 +170,10 @@ function GenericPressable({ isDisabled && [StyleUtils.parseStyleFromFunction(disabledStyle, state), styles.noSelect], isRoleButton && styles.userSelectNone, ]} - fsClass={forwardedFSClass} - // eslint-disable-next-line react/jsx-props-no-spreading - {...rest} - // accessibility props - must come after {...rest} to ensure proper disabled state announcement + // accessibility props accessibilityState={{ - ...rest.accessibilityState, disabled: isDisabled, + ...rest.accessibilityState, }} aria-disabled={isDisabled} aria-keyshortcuts={keyboardShortcut && `${keyboardShortcut.modifiers.join('')}+${keyboardShortcut.shortcutKey}`} @@ -184,6 +181,9 @@ function GenericPressable({ onMagicTap={!isDisabled ? voidOnPressHandler : undefined} onAccessibilityTap={!isDisabled ? voidOnPressHandler : undefined} accessible={accessible} + fsClass={forwardedFSClass} + // eslint-disable-next-line react/jsx-props-no-spreading + {...rest} onHoverOut={(event) => { if (event?.type === 'pointerenter' || event?.type === 'mouseenter') { return; From f7ef12d78fd24694936a65a52eda41628040911a Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 08:38:57 +0100 Subject: [PATCH 19/30] rm unused accessibilitylabel --- src/components/MenuItem.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index bf2f2571d5c4a..3300e70842778 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -212,9 +212,6 @@ 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; @@ -482,7 +479,6 @@ function MenuItem({ focused = false, disabled = false, title, - accessibilityLabel, titleComponent, titleContainerStyle, subtitle, From fe4c4ef31d9075e6127b379aa949287138d1062f Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 08:50:49 +0100 Subject: [PATCH 20/30] Revert "rm unused accessibilitylabel" This reverts commit f7ef12d78fd24694936a65a52eda41628040911a. --- src/components/MenuItem.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index 3300e70842778..bf2f2571d5c4a 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -212,6 +212,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; @@ -479,6 +482,7 @@ function MenuItem({ focused = false, disabled = false, title, + accessibilityLabel, titleComponent, titleContainerStyle, subtitle, From b961b29bf34203e911af41ab70f4c6ebe3611511 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 08:52:32 +0100 Subject: [PATCH 21/30] use accessiblity label --- src/components/MenuItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index bf2f2571d5c4a..51e1c25fda841 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -748,7 +748,7 @@ function MenuItem({ disabled={disabled || isExecuting} ref={mergeRefs(ref, popoverAnchor)} role={CONST.ROLE.MENUITEM} - accessibilityLabel={[description, title].filter(Boolean).join(', ')} + accessibilityLabel={accessibilityLabel ?? [description, title].filter(Boolean).join(', ')} accessible={shouldBeAccessible} tabIndex={tabIndex} onFocus={onFocus} From 4e979ca7e79a79b89a41b8bed955a8cdae32cf6d Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 09:06:50 +0100 Subject: [PATCH 22/30] only include alternate text if it differs --- src/components/SelectionListWithSections/BaseListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SelectionListWithSections/BaseListItem.tsx b/src/components/SelectionListWithSections/BaseListItem.tsx index 976cf04e8a356..f02d460e23795 100644 --- a/src/components/SelectionListWithSections/BaseListItem.tsx +++ b/src/components/SelectionListWithSections/BaseListItem.tsx @@ -107,7 +107,7 @@ function BaseListItem({ }} disabled={isDisabled && !item.isSelected} interactive={item.isInteractive} - accessibilityLabel={[item.text, item.alternateText].filter(Boolean).join(', ')} + accessibilityLabel={[item.text, item.text !== item.alternateText ? item.alternateText : undefined].filter(Boolean).join(', ')} role={getButtonRole(true)} isNested hoverDimmingValue={1} From 6a4649110642b9750ec66052e99399dd144cc793 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 19 Jan 2026 10:52:09 +0100 Subject: [PATCH 23/30] swapping when shouldShowDescriptionOnTop --- src/components/MenuItem.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index 51e1c25fda841..180a223204b46 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -564,6 +564,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( [ @@ -748,7 +749,7 @@ function MenuItem({ disabled={disabled || isExecuting} ref={mergeRefs(ref, popoverAnchor)} role={CONST.ROLE.MENUITEM} - accessibilityLabel={accessibilityLabel ?? [description, title].filter(Boolean).join(', ')} + accessibilityLabel={accessibilityLabel ?? defaultAccessibilityLabel} accessible={shouldBeAccessible} tabIndex={tabIndex} onFocus={onFocus} From a3ba3d0abe2bfe9dcadeb7197c917132eef512b7 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jan 2026 03:42:39 +0100 Subject: [PATCH 24/30] Revert "Fix #76961: Add custom accessibility label for select all checkbox" This reverts commit 2d3cdbd3e65cabc8599bbe80533ba55cf3178ea1. --- .../BaseSelectionListWithSections.tsx | 7 ++----- src/components/SelectionListWithSections/types.ts | 3 --- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx b/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx index 97a8a9031959b..cb49ef3ac3f53 100644 --- a/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx +++ b/src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx @@ -45,7 +45,6 @@ function BaseSelectionListWithSections({ shouldSingleExecuteRowSelect = false, onCheckboxPress, onSelectAll, - selectAllAccessibilityLabel, onDismissError, getItemHeight = getDefaultItemHeight, textInputLabel = '', @@ -609,8 +608,6 @@ function BaseSelectionListWithSections({ ); }; - const selectAllLabel = selectAllAccessibilityLabel ?? translate('workspace.people.selectAll'); - const header = () => ( <> {!headerMessage && canSelectMultiple && shouldShowSelectAll && ( @@ -618,7 +615,7 @@ function BaseSelectionListWithSections({ ({ = Partial & { /** Callback to fire when "Select All" checkbox is pressed. Only use along with `canSelectMultiple` */ onSelectAll?: () => void; - /** Custom accessibility label for the "Select All" checkbox. Defaults to 'Select all' */ - selectAllAccessibilityLabel?: string; - /** * Callback that should return height of the specific item * Only use this if we're handling some non-standard items, most of the time the default value is correct From 4ba6543346ee2649723f6feb2f19018cd54ea70e Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jan 2026 03:50:12 +0100 Subject: [PATCH 25/30] fix #76907 --- src/pages/workspace/reports/WorkspaceReportsPage.tsx | 2 +- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx index 3273496a9fdc8..6e32a3a80636b 100644 --- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx +++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx @@ -267,7 +267,7 @@ function WorkspaceReportFieldsPage({ { shouldAnimateAccordionSection.set(true); onToggle(isOn); From 2f405232bb24e603e0f094954c545f44694d0e09 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jan 2026 04:04:10 +0100 Subject: [PATCH 26/30] fix #76911 - pass subtitle to selection list --- src/components/SelectionList/ListItem/BaseListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/SelectionList/ListItem/BaseListItem.tsx b/src/components/SelectionList/ListItem/BaseListItem.tsx index a3b812ee1ae7d..cac76d4928114 100644 --- a/src/components/SelectionList/ListItem/BaseListItem.tsx +++ b/src/components/SelectionList/ListItem/BaseListItem.tsx @@ -112,7 +112,7 @@ function BaseListItem({ }} disabled={isDisabled && !item.isSelected} interactive={item.isInteractive} - accessibilityLabel={item.text ?? ''} + accessibilityLabel={[item.text, item.text !== item.alternateText ? item.alternateText : undefined].filter(Boolean).join(', ')} role={getButtonRole(true)} isNested hoverDimmingValue={1} From 53f10a910e0163643687be5d9d8ec8eae4b1d8c0 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jan 2026 04:16:07 +0100 Subject: [PATCH 27/30] fix string case --- src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 70d9a48332a80..4c92cc114611e 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -201,7 +201,7 @@ function ToggleSettingOptionRow({ { shouldAnimateAccordionSection.set(true); onToggle(isOn); From 4c6a214d1581439eddf3837526b2de98fea11565 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jan 2026 18:36:43 +0100 Subject: [PATCH 28/30] add memoized accessibility label for report fields --- src/pages/workspace/reports/WorkspaceReportsPage.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx index 6e32a3a80636b..444eda09e70fa 100644 --- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx +++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx @@ -168,6 +168,13 @@ function WorkspaceReportFieldsPage({ const toggleTitleStyle = useMemo(() => [styles.pv2, styles.pr3], [styles.pv2, styles.pr3]); + 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]); + const renderReportTitle = useCallback( () => ( From 933a6a2e9ae1b53a7a6155fe50cc96eeae07131e Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 21 Jan 2026 18:36:43 +0100 Subject: [PATCH 29/30] use reportFieldsAccessibilityLabel for switch --- src/pages/workspace/reports/WorkspaceReportsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx index 444eda09e70fa..00c19386cf423 100644 --- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx +++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx @@ -274,7 +274,7 @@ function WorkspaceReportFieldsPage({ Date: Wed, 21 Jan 2026 19:19:55 +0100 Subject: [PATCH 30/30] fix merge --- .../reports/WorkspaceReportsPage.tsx | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/pages/workspace/reports/WorkspaceReportsPage.tsx b/src/pages/workspace/reports/WorkspaceReportsPage.tsx index 5435cd74a9a08..a4a2a3d7bacff 100644 --- a/src/pages/workspace/reports/WorkspaceReportsPage.tsx +++ b/src/pages/workspace/reports/WorkspaceReportsPage.tsx @@ -1,7 +1,7 @@ import {FlashList} from '@shopify/flash-list'; import type {ListRenderItemInfo} from '@shopify/flash-list'; import {Str} from 'expensify-common'; -import React, {useCallback, useEffect, useMemo, 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'; @@ -148,20 +148,10 @@ function WorkspaceReportFieldsPage({ const toggleTitleStyle = [styles.pv2, styles.pr3]; - 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]); - - const renderReportTitle = useCallback( - () => ( - - {translate('workspace.common.reportTitle')} - - ), - [policy?.pendingAction, styles.textHeadline, styles.cardSectionTitle, styles.accountSettingsSectionTitle, styles.mb1, translate], + const renderReportTitle = () => ( + + {translate('workspace.common.reportTitle')} + ); const renderReportSubtitle = () => ( @@ -172,6 +162,13 @@ function WorkspaceReportFieldsPage({ ); + 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 (