Skip to content

Add 'auto' to ColorSchemeOverride, deprecate 'unspecified'#56696

Open
huntie wants to merge 3 commits intofacebook:mainfrom
huntie:export-D103841988
Open

Add 'auto' to ColorSchemeOverride, deprecate 'unspecified'#56696
huntie wants to merge 3 commits intofacebook:mainfrom
huntie:export-D103841988

Conversation

@huntie
Copy link
Copy Markdown
Member

@huntie huntie commented May 6, 2026

Summary:
NOTE: 👋🏻 This is an RFC, additional and separate to the previous 2 diffs. Looking for feedback :)

Proposes an API tweak to Appearance.setColorScheme() to make it more idiomatic/understandable.

  • Aligns with the CSS color-scheme property vocabulary, where auto means "defer to the system preference".
  • Replaces the ambiguous unspecified (now deprecated), which gave no indication of the resulting behaviour.

See also:

Alternative names considered

  • 'reset' - Implies reversing a change, not deferring to system
  • 'inherit' - Weak — CSS inherit is element→parent, not app→OS

Changelog:
[General][Deprecated] - Appearance.setColorScheme('unspecified') is deprecated, use 'auto' instead.

Differential Revision: D103841988

huntie added 3 commits May 6, 2026 03:09
Summary:

Removes `'unspecified'` from the return type of `Appearance.getColorScheme()` and `useColorScheme()`, splitting the setter input into a separate `ColorSchemeOverride` type. This resolves a longstanding misalignment between what native returns and what the types promise.

**Motivation**

`'unspecified'` is only meaningful as an input to `setColorScheme()` — neither iOS nor Android ever returns it from `getColorScheme()`. When `setColorScheme('unspecified')` is called, the JS layer re-queries the native module and caches the resolved system value.

After this change:

- `Appearance.getColorScheme()` returns `'light' | 'dark'` (no longer `'unspecified'`)
- `Appearance.setColorScheme()` receives `'light' | 'dark' | 'unspecified'`

Paired with docs updates:
- facebook/react-native-website#5060
- facebook/react-native-website#5069

**History of this API**

- The TurboModule spec originally typed these methods as plain `string` because codegen didn't support union types (T52919652).
- When support landed, D63681874 upgraded to `ColorSchemeName = 'light' | 'dark' | 'unspecified'` — a type-level cleanup that inadvertently widened return types to include `'unspecified'`, a value native never returns. This caused `$FlowFixMe` suppressions across downstream callers.
- D80705652 later aligned the `.d.ts` and fixed a bug where `setColorScheme('unspecified')` threw an incorrect invariant.

Changelog:
[General][Breaking] - `useColorScheme()` no longer returns `'unspecified'` (this was always the case, but is a breaking type change)

Reviewed By: cipolleschi

Differential Revision: D102527387
Summary:

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: [Internal] - This is a net fix/extension of D102527387

Differential Revision: D103865622
Summary:
NOTE: 👋🏻 **This is an RFC**, additional and separate to the previous 2 diffs. Looking for feedback :)

Proposes an API tweak to `Appearance.setColorScheme()` to make it more idiomatic/understandable.

- Aligns with the CSS `color-scheme` property vocabulary, where `auto` means "defer to the system preference". Replaces the ambiguous `unspecified` (now deprecated), which gave no indication of the resulting behaviour.

See also:
- History of this API + return type narrowing in D102527387.
- Extended docs + diagram in facebook/react-native-website#5060.

**Alternative names considered**

- `'reset'` - Implies reversing a change, not deferring to system
- `'inherit'` -  Weak — CSS inherit is element→parent, not app→OS

Changelog:
[General][Deprecated] - `Appearance.setColorScheme('unspecified')` is deprecated, use `'auto'` instead.

Differential Revision: D103841988
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 6, 2026
@facebook-github-tools facebook-github-tools Bot added p: Facebook Partner: Facebook Partner labels May 6, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 6, 2026

@huntie has exported this pull request. If you are a Meta employee, you can view the originating Diff in D103841988.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Warning

JavaScript API change detected

This PR commits an update to ReactNativeApi.d.ts, indicating a change to React Native's public JavaScript API.

  • Please include a clear changelog message.
  • This change will be subject to additional review.

This change was flagged as: POTENTIALLY_BREAKING

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant