11import * as React from 'react' ;
2- import {
3- AccessibilityInfo ,
4- Appearance ,
5- ColorSchemeName ,
6- NativeEventSubscription ,
7- } from 'react-native' ;
2+ import { Appearance , ColorSchemeName } from 'react-native' ;
83
94import SafeAreaProviderCompat from './SafeAreaProviderCompat' ;
105import { Provider as SettingsProvider , Settings } from './settings' ;
116import { defaultThemes , ThemeProvider } from './theming' ;
127import MaterialCommunityIcon from '../components/MaterialCommunityIcon' ;
138import PortalHost from '../components/Portal/PortalHost' ;
14- import type { ThemeProp } from '../types ' ;
15- import { addEventListener } from '../utils/addEventListener ' ;
9+ import { useAccessibleTheme } from '../theme/accessibility ' ;
10+ import type { Theme , ThemeProp } from '../types ' ;
1611
1712export type Props = {
1813 children : React . ReactNode ;
1914 theme ?: ThemeProp ;
2015 settings ?: Settings ;
16+ /**
17+ * Whether OS-level accessibility preferences (reduce motion) are automatically
18+ * reflected in the theme. Defaults to `true`. Set to `false` to handle
19+ * accessibility in your own code.
20+ */
21+ accessibilityAdapters ?: boolean ;
2122} ;
2223
2324const PaperProvider = ( props : Props ) => {
25+ const { accessibilityAdapters = true } = props ;
26+
2427 const colorSchemeName =
2528 ( ! props . theme && Appearance ?. getColorScheme ( ) ) || 'light' ;
2629
27- const [ reduceMotionEnabled , setReduceMotionEnabled ] =
28- React . useState < boolean > ( false ) ;
2930 const [ colorScheme , setColorScheme ] =
3031 React . useState < ColorSchemeName > ( colorSchemeName ) ;
3132
@@ -37,28 +38,13 @@ const PaperProvider = (props: Props) => {
3738 } ;
3839
3940 React . useEffect ( ( ) => {
40- let subscription : NativeEventSubscription | undefined ;
41-
42- if ( ! props . theme ) {
43- subscription = addEventListener (
44- AccessibilityInfo ,
45- 'reduceMotionChanged' ,
46- setReduceMotionEnabled
47- ) ;
48- }
49- return ( ) => {
50- if ( ! props . theme ) {
51- subscription ?. remove ( ) ;
52- }
53- } ;
54- } , [ props . theme ] ) ;
55-
56- React . useEffect ( ( ) => {
57- let appearanceSubscription : NativeEventSubscription | undefined ;
41+ let appearanceSubscription :
42+ | ReturnType < typeof Appearance . addChangeListener >
43+ | undefined ;
5844 if ( ! props . theme ) {
5945 appearanceSubscription = Appearance ?. addChangeListener (
6046 handleAppearanceChange
61- ) as NativeEventSubscription | undefined ;
47+ ) as typeof appearanceSubscription ;
6248 }
6349 return ( ) => {
6450 if ( ! props . theme ) {
@@ -72,19 +58,20 @@ const PaperProvider = (props: Props) => {
7258 } ;
7359 } , [ props . theme ] ) ;
7460
75- const theme = React . useMemo ( ( ) => {
61+ const rawTheme = React . useMemo ( ( ) => {
7662 const scheme = colorScheme === 'dark' ? 'dark' : 'light' ;
77- const defaultThemeBase = defaultThemes [ scheme ] ;
78-
63+ const base = defaultThemes [ scheme ] ;
7964 return {
80- ...defaultThemeBase ,
65+ ...base ,
8166 ...props . theme ,
8267 animation : {
8368 ...props . theme ?. animation ,
84- scale : reduceMotionEnabled ? 0 : 1 ,
69+ scale : props . theme ?. animation ?. scale ?? 1 ,
8570 } ,
86- } ;
87- } , [ colorScheme , props . theme , reduceMotionEnabled ] ) ;
71+ } as Theme ;
72+ } , [ colorScheme , props . theme ] ) ;
73+
74+ const theme = useAccessibleTheme ( rawTheme , accessibilityAdapters !== false ) ;
8875
8976 const { children, settings } = props ;
9077
0 commit comments