|
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'; |
3 | 3 | import type PressableProps from '@components/Pressable/GenericPressable/types'; |
| 4 | +import mergeRefs from '@libs/mergeRefs'; |
4 | 5 | import GenericPressable from './BaseGenericPressable'; |
5 | 6 |
|
6 | 7 | function WebGenericPressable({focusable = true, ref, sentryLabel, ...props}: PressableProps) { |
7 | 8 | const accessible = (props.accessible ?? props.accessible === undefined) ? true : props.accessible; |
8 | 9 |
|
| 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 | + |
9 | 28 | return ( |
10 | 29 | <GenericPressable |
11 | 30 | // eslint-disable-next-line react/jsx-props-no-spreading |
12 | 31 | {...props} |
13 | | - ref={ref} |
| 32 | + ref={mergeRefs(internalRef, ref)} |
14 | 33 | // change native accessibility props to web accessibility props |
15 | 34 | focusable={focusable} |
16 | 35 | tabIndex={(props.tabIndex ?? (!accessible || !focusable)) ? -1 : 0} |
|
0 commit comments