Skip to content

Commit f855ba5

Browse files
authored
Merge pull request #87670 from Expensify/claude-screenReaderDisabledButtonAnnouncement
fix: Re-apply screen reader disabled button announcement with crash fix
2 parents 8069766 + fa0a8f9 commit f855ba5

5 files changed

Lines changed: 26 additions & 7 deletions

File tree

src/components/Pressable/GenericPressable/implementation/BaseGenericPressable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ function GenericPressable({
177177
hitSlop={shouldUseAutoHitSlop ? hitSlop : undefined}
178178
onLayout={shouldUseAutoHitSlop ? onLayout : undefined}
179179
ref={ref as ForwardedRef<View>}
180-
disabled={fullDisabled}
180+
disabled={fullDisabled || undefined}
181181
onPress={!isDisabled ? singleExecution(onPressHandler) : undefined}
182182
onLongPress={!isDisabled && onLongPress ? onLongPressHandler : undefined}
183183
onKeyDown={!isDisabled ? handleKeyDown : undefined}

src/components/Pressable/GenericPressable/implementation/index.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,35 @@
1-
import React from 'react';
2-
import type {Role} from 'react-native';
1+
import React, {useLayoutEffect, useRef} from 'react';
2+
import type {Role, View} from 'react-native';
33
import type PressableProps from '@components/Pressable/GenericPressable/types';
4+
import mergeRefs from '@libs/mergeRefs';
45
import GenericPressable from './BaseGenericPressable';
56

67
function WebGenericPressable({focusable = true, ref, sentryLabel, ...props}: PressableProps) {
78
const accessible = (props.accessible ?? props.accessible === undefined) ? true : props.accessible;
89

10+
// react-native-web's Pressable always sets aria-disabled from its own `disabled` prop,
11+
// overriding any explicit aria-disabled we pass. We pass fullDisabled (not isDisabled) to
12+
// preserve interaction/focus behavior, so we must set aria-disabled imperatively instead.
13+
const internalRef = useRef<View>(null);
14+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- `||` is intentional so that falsy values like empty string or 0 are treated as not-disabled
15+
const isAriaDisabled = props.fullDisabled || props.disabled || props.accessibilityState?.disabled;
16+
useLayoutEffect(() => {
17+
const el = internalRef.current as unknown as HTMLElement | null;
18+
if (!el) {
19+
return;
20+
}
21+
if (isAriaDisabled) {
22+
el.setAttribute('aria-disabled', 'true');
23+
} else {
24+
el.removeAttribute('aria-disabled');
25+
}
26+
}, [isAriaDisabled]);
27+
928
return (
1029
<GenericPressable
1130
// eslint-disable-next-line react/jsx-props-no-spreading
1231
{...props}
13-
ref={ref}
32+
ref={mergeRefs(internalRef, ref)}
1433
// change native accessibility props to web accessibility props
1534
focusable={focusable}
1635
tabIndex={(props.tabIndex ?? (!accessible || !focusable)) ? -1 : 0}

src/pages/domain/Saml/SamlLoginSectionContent.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ function SamlLoginSectionContent({accountID, domainName, isSamlEnabled, isSamlRe
7676
<Switch
7777
accessibilityLabel={translate('domain.samlLogin.enableSamlLogin')}
7878
isOn={isSamlEnabled}
79-
disabled={domainSettings?.twoFactorAuthRequired}
79+
disabled={!!domainSettings?.twoFactorAuthRequired}
8080
onToggle={() => setSamlEnabled({enabled: !isSamlEnabled, accountID, domainName})}
8181
/>
8282
</View>

src/pages/settings/Profile/TimezoneInitialPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function TimezoneInitialPage({currentUserPersonalDetails}: TimezoneInitialPagePr
6464
title={timezone.selected}
6565
description={translate('timezonePage.timezone')}
6666
shouldShowRightIcon
67-
disabled={timezone.automatic}
67+
disabled={!!timezone.automatic}
6868
onPress={() => Navigation.navigate(ROUTES.SETTINGS_TIMEZONE_SELECT)}
6969
/>
7070
</View>

src/pages/settings/Profile/TimezoneSelectPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ function TimezoneSelectPage({currentUserPersonalDetails}: TimezoneSelectPageProp
8585
onSelectRow={saveSelectedTimezone}
8686
textInputOptions={textInputOptions}
8787
initiallyFocusedItemKey={timezoneOptions.find((tz) => tz.text === timezone.selected)?.keyForList}
88-
isDisabled={timezone.automatic}
88+
isDisabled={!!timezone.automatic}
8989
shouldShowTooltips={false}
9090
shouldSingleExecuteRowSelect
9191
showScrollIndicator

0 commit comments

Comments
 (0)