Skip to content

Commit ef6463c

Browse files
huntiemeta-codesync[bot]
authored andcommitted
Align nullable types across Appearance API (#56687)
Summary: Pull Request resolved: #56687 Simplify and align nullable values in the `Appearance` API. | API | Flow / Strict TS API | Manual `.d.ts` | |---|---|---| | `getColorScheme()` | `ColorSchemeName | null` (narrowed) | `ColorSchemeName | null` | | `useColorScheme()` | `ColorSchemeName | null` (narrowed) | `ColorSchemeName | null` (fixed) | At the native spec level, nullability is removed entirely — the module always returns a valid color scheme, and the module-level `?Spec` already covers the "module absent" case. Changelog: [General][Breaking] - Fix return type of `useColorScheme()` hook (now `ColorSchemeName | null`) - Release Crew note: This is a net fix/extension of D102527387 Reviewed By: cipolleschi Differential Revision: D103865622 fbshipit-source-id: a6391cfd86a634ea660734735614169d0601a830
1 parent 8ac88f4 commit ef6463c

8 files changed

Lines changed: 32 additions & 24 deletions

File tree

packages/react-native/Libraries/Utilities/Appearance.d.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type ColorSchemeOverride = ColorSchemeName | 'unspecified';
1515

1616
export namespace Appearance {
1717
type AppearancePreferences = {
18-
colorScheme: ColorSchemeName;
18+
colorScheme: ColorSchemeName | null;
1919
};
2020

2121
type AppearanceListener = (preferences: AppearancePreferences) => void;
@@ -32,7 +32,7 @@ export namespace Appearance {
3232
* - `null` will only be returned if the native Appearance module is
3333
* unavailable (out of tree platforms).
3434
*/
35-
export function getColorScheme(): ColorSchemeName | null | undefined;
35+
export function getColorScheme(): ColorSchemeName | null;
3636

3737
/**
3838
* Force the application to always adopt a light or dark interface style. Pass
@@ -54,5 +54,9 @@ export namespace Appearance {
5454
/**
5555
* Returns the active color scheme (`'light'` or `'dark'`). Automatically
5656
* re-renders the component when the color scheme changes.
57+
*
58+
* Notes:
59+
* - `null` will only be returned if the native Appearance module is unavailable
60+
* (out of tree platforms).
5761
*/
58-
export function useColorScheme(): ColorSchemeName;
62+
export function useColorScheme(): ColorSchemeName | null;

packages/react-native/Libraries/Utilities/Appearance.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import type {EventSubscription} from '../vendor/emitter/EventEmitter';
1212
import type {
13-
AppearancePreferences,
13+
AppearancePreferences as NativeAppearancePreferences,
1414
ColorSchemeName,
1515
ColorSchemeOverride,
1616
} from './NativeAppearance';
@@ -19,10 +19,14 @@ import typeof INativeAppearance from './NativeAppearance';
1919
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
2020
import EventEmitter from '../vendor/emitter/EventEmitter';
2121

22-
export type {AppearancePreferences, ColorSchemeName, ColorSchemeOverride};
22+
export type {ColorSchemeName, ColorSchemeOverride};
23+
24+
export type AppearancePreferences = {
25+
colorScheme: ColorSchemeName | null,
26+
};
2327

2428
type Appearance = {
25-
colorScheme: ?ColorSchemeName,
29+
colorScheme: ColorSchemeName | null,
2630
};
2731

2832
let lazyState: ?{
@@ -60,7 +64,7 @@ function getState(): NonNullable<typeof lazyState> {
6064
eventEmitter,
6165
};
6266
new NativeEventEmitter<{
63-
appearanceChanged: [AppearancePreferences],
67+
appearanceChanged: [NativeAppearancePreferences],
6468
}>(NativeAppearance).addListener('appearanceChanged', newAppearance => {
6569
state.appearance = {
6670
colorScheme: newAppearance.colorScheme,
@@ -84,7 +88,7 @@ function getState(): NonNullable<typeof lazyState> {
8488
* - `null` will only be returned if the native Appearance module is unavailable
8589
* (out of tree platforms).
8690
*/
87-
export function getColorScheme(): ?ColorSchemeName {
91+
export function getColorScheme(): ColorSchemeName | null {
8892
let colorScheme = null;
8993
const state = getState();
9094
const {NativeAppearance} = state;
@@ -114,7 +118,7 @@ export function setColorScheme(colorScheme: ColorSchemeOverride): void {
114118
state.appearance = {
115119
colorScheme:
116120
colorScheme === 'unspecified'
117-
? (NativeAppearance.getColorScheme() ?? null)
121+
? NativeAppearance.getColorScheme()
118122
: colorScheme,
119123
};
120124
}
@@ -126,7 +130,7 @@ export function setColorScheme(colorScheme: ColorSchemeOverride): void {
126130
* or a call to `setColorScheme()`.
127131
*/
128132
export function addChangeListener(
129-
listener: ({colorScheme: ?ColorSchemeName}) => void,
133+
listener: (preferences: AppearancePreferences) => void,
130134
): EventSubscription {
131135
const {eventEmitter} = getState();
132136
return eventEmitter.addListener('change', listener);

packages/react-native/Libraries/Utilities/useColorScheme.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ const subscribe = (onStoreChange: () => void) => {
2828
* - `null` will only be returned if the native Appearance module is unavailable
2929
* (out of tree platforms).
3030
*/
31-
export default function useColorScheme(): ?ColorSchemeName {
31+
export default function useColorScheme(): ColorSchemeName | null {
3232
return useSyncExternalStore(subscribe, getColorScheme);
3333
}

packages/react-native/ReactNativeApi.d.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<4950f1efd16fed02b526f83325c8351d>>
7+
* @generated SignedSource<<04955f1605996352fa3f3a3fc86ba937>>
88
*
99
* This file was generated by scripts/js-api/build-types/index.js.
1010
*/
@@ -1218,7 +1218,7 @@ declare type ActivityIndicatorProps = Readonly<
12181218
>
12191219
declare type add = typeof add
12201220
declare function addChangeListener(
1221-
listener: ($$PARAM_0$$: { colorScheme: ColorSchemeName | undefined }) => void,
1221+
listener: (preferences: AppearancePreferences) => void,
12221222
): EventSubscription
12231223
declare class Alert {
12241224
static alert(
@@ -1629,13 +1629,13 @@ declare namespace Appearance {
16291629
getColorScheme,
16301630
setColorScheme,
16311631
addChangeListener,
1632-
AppearancePreferences,
16331632
ColorSchemeName,
16341633
ColorSchemeOverride,
1634+
AppearancePreferences,
16351635
}
16361636
}
16371637
declare type AppearancePreferences = {
1638-
colorScheme?: ColorSchemeName
1638+
colorScheme: ColorSchemeName | null
16391639
}
16401640
declare type AppParameters = {
16411641
initialProps: {
@@ -2468,7 +2468,7 @@ declare function get_2<T extends TurboModule>(
24682468
name: string,
24692469
): null | T | undefined
24702470
declare function getAppKeys(): ReadonlyArray<string>
2471-
declare function getColorScheme(): ColorSchemeName | null | undefined
2471+
declare function getColorScheme(): ColorSchemeName | null
24722472
declare function getEnforcing<T extends TurboModule>(name: string): T
24732473
declare function getRegistry(): Registry
24742474
declare function getRunnable(appKey: string): null | Runnable | undefined
@@ -5738,7 +5738,7 @@ declare function useAnimatedValueXY(
57385738
},
57395739
config?: Animated.AnimatedConfig | null | undefined,
57405740
): Animated.ValueXY
5741-
declare function useColorScheme(): ColorSchemeName | null | undefined
5741+
declare function useColorScheme(): ColorSchemeName | null
57425742
declare function usePressability(
57435743
config: null | PressabilityConfig | undefined,
57445744
): null | PressabilityEventHandlers
@@ -6073,7 +6073,7 @@ export {
60736073
AppState, // 12012be5
60746074
AppStateEvent, // 80f034c3
60756075
AppStateStatus, // 447e5ef2
6076-
Appearance, // df9545f9
6076+
Appearance, // 0e9bf4fe
60776077
AutoCapitalize, // c0e857a0
60786078
BackHandler, // f139fc69
60796079
BackPressEventName, // 4620fb76
@@ -6339,7 +6339,7 @@ export {
63396339
useAnimatedColor, // e3511f81
63406340
useAnimatedValue, // b18adb63
63416341
useAnimatedValueXY, // c7ee2332
6342-
useColorScheme, // 29a517d5
6342+
useColorScheme, // d585efdb
63436343
usePressability, // b4e21b46
63446344
useWindowDimensions, // bb4b683f
63456345
}

packages/react-native/src/private/specs_DEPRECATED/modules/NativeAppearance.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export type ColorSchemeName = 'light' | 'dark';
1717
export type ColorSchemeOverride = 'light' | 'dark' | 'unspecified';
1818

1919
export type AppearancePreferences = {
20-
colorScheme?: ?ColorSchemeName,
20+
colorScheme: ColorSchemeName,
2121
};
2222

2323
export interface Spec extends TurboModule {
24-
+getColorScheme: () => ?ColorSchemeName;
24+
+getColorScheme: () => ColorSchemeName;
2525
+setColorScheme: (colorScheme: ColorSchemeOverride) => void;
2626

2727
// RCTEventEmitter

packages/rn-tester/js/examples/Appearance/AppearanceExample.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function ColorSchemeSubscription() {
2424

2525
useEffect(() => {
2626
const subscription = Appearance.addChangeListener(
27-
({colorScheme: newColorScheme}: {colorScheme: ?ColorSchemeName}) => {
27+
({colorScheme: newColorScheme}) => {
2828
setColorScheme(newColorScheme);
2929
},
3030
);

scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2653,7 +2653,7 @@ protocol NativeAppStateSpec : public NSObjectRCTBridgeModule, public RCTTurboMod
26532653
}
26542654

26552655
protocol NativeAppearanceSpec : public NSObjectRCTBridgeModule, public RCTTurboModule {
2656-
public virtual NSString* _Nullable getColorScheme();
2656+
public virtual NSString* getColorScheme();
26572657
public virtual void addListener:(NSString* eventName);
26582658
public virtual void removeListeners:(double count);
26592659
public virtual void setColorScheme:(NSString* colorScheme);

scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2653,7 +2653,7 @@ protocol NativeAppStateSpec : public NSObjectRCTBridgeModule, public RCTTurboMod
26532653
}
26542654

26552655
protocol NativeAppearanceSpec : public NSObjectRCTBridgeModule, public RCTTurboModule {
2656-
public virtual NSString* _Nullable getColorScheme();
2656+
public virtual NSString* getColorScheme();
26572657
public virtual void addListener:(NSString* eventName);
26582658
public virtual void removeListeners:(double count);
26592659
public virtual void setColorScheme:(NSString* colorScheme);

0 commit comments

Comments
 (0)