diff --git a/src/lib/a11y/focus.js b/src/lib/a11y/focus.js index afc4f27..d33c548 100644 --- a/src/lib/a11y/focus.js +++ b/src/lib/a11y/focus.js @@ -5,10 +5,21 @@ import { } from "react-native"; export function setA11yFocus(refOrNode) { - const node = findNodeHandle(refOrNode?.current ?? refOrNode); - if (!node) return; - - AccessibilityInfo.setAccessibilityFocus(node); + // RN's `setAccessibilityFocus` expects a native host node handle. + // In practice, callers may pass: + // - a ref object ({ current }) + // - a host component + // - a composite component instance (invalid) + // - null/undefined + // We must never throw here, otherwise we can crash the whole app. + try { + const candidate = refOrNode?.current ?? refOrNode; + const node = findNodeHandle(candidate); + if (typeof node !== "number") return; + AccessibilityInfo.setAccessibilityFocus(node); + } catch (_e) { + // noop + } } export function setA11yFocusAfterInteractions(refOrNode) { diff --git a/src/scenes/AlertCurMap/index.js b/src/scenes/AlertCurMap/index.js index 40232bb..9436b5a 100644 --- a/src/scenes/AlertCurMap/index.js +++ b/src/scenes/AlertCurMap/index.js @@ -505,7 +505,9 @@ function AlertCurMap() { const closeStepper = useCallback(() => { setStepperIsOpened(false); - setA11yFocusAfterInteractions(lastStepsTriggerRef.current); + // Pass the ref object (not `.current`) so `findNodeHandle` can safely + // resolve the native host view. + setA11yFocusAfterInteractions(lastStepsTriggerRef); }, [setStepperIsOpened]); const stepperOnOpen = useCallback(() => { @@ -521,7 +523,7 @@ function AlertCurMap() { setStepperIsOpened(false); } announceForA11yIfScreenReaderEnabled("Liste des étapes fermée"); - setA11yFocusAfterInteractions(lastStepsTriggerRef.current); + setA11yFocusAfterInteractions(lastStepsTriggerRef); }, [stepperIsOpened, setStepperIsOpened]); const [externalGeoIsVisible, setExternalGeoIsVisible] = useState(false);