Skip to content

Feat/dynamic colors#4888

Open
adrcotfas wants to merge 14 commits intocallstack:mainfrom
adrcotfas:feat/dynamic_colors
Open

Feat/dynamic colors#4888
adrcotfas wants to merge 14 commits intocallstack:mainfrom
adrcotfas:feat/dynamic_colors

Conversation

@adrcotfas
Copy link
Copy Markdown

Note

Sorry for the large PR!
Reviewing should be easier by going through the individual commits.

Motivation

This replaces @pchmn/expo-material3-theme with React Native's built-in PlatformColor, so dynamic colors on Android 12+ work without any native module.
The MD3 color schema also had gaps and inaccurate values compared to the https://m3.material.io/styles/color/roles. Several color roles were missing, state layer opacity tokens were off, and some values were stale from the original 2021
release. This fixes all of that along with the removal of MD2 support.

What changed:

  • Dynamic colors via PlatformColor: New DynamicTheme for Android. API 34+ uses named system role resources (system_primary_light, etc.), API 31-33 falls back to tonal accent resources (system_accent*_NNN), and anything below falls back to the static MD3 theme colors. See docs.
  • Updated MD3 color schema to match the current https://m3.material.io/styles/color/roles, including roles that were missing before.
  • State layer opacity tokens: Updated to match the current MD3 spec.
  • Removed disabled FAB state: MD3 guidelines don't have a disabled state for FABs.
  • Removed customRippleColor: Not part of the native Material API. It offered too much customization at the cost of correctness, so it's gone from all components.
  • MD2 theme removal: Cleaned up remaining MD2 theme code.

Known limitation:

PlatformColor can't be combined with alpha in android_ripple, so ripple colors for dynamic-themed components like filled buttons and FABs use a pre-calculated On-Surface color (Neutral 10/90) for now. This is what most MD3 components use anyway and the difference is barely noticeable due to ripple transparency. I'm investigating a change in RN Core for this.

Next steps (out of scope for this PR):

  • Verify all Material components against the latest MD3 guidelines
  • Update the Switch component which is still using the MD2 style
  • Add Material Expressive components
  • Update the documentation

Test plan

  • On Android 12+ (API 31+), use DynamicTheme in the example app and check that colors follow the system wallpaper palette
  • On Android below API 31, confirm the app falls back to the static MD3 theme without errors
  • On iOS, confirm DynamicTheme falls back to the static MD3 theme
  • Check that components that previously had customRippleColor still render correctly
  • Check that FAB no longer has a disabled state

@callstack-bot
Copy link
Copy Markdown

callstack-bot commented Apr 8, 2026

Hey @adrcotfas, thank you for your pull request 🤗. The documentation from this branch can be viewed here.

Copy link
Copy Markdown
Member

@satya164 satya164 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please split the PR into multiple PRs with stacked PRs. This PR is doing too many things. Reviewing individual commits isn't sufficient; the changes will still get merged in a single commit without splitting.

  • MD2 removal
  • Dynamic themes

Updated MD3 color schema
State layer opacity tokens: Updated to match the current MD3 spec.

There was already a task on the bench Notion board about this, and existing PR. Please collaborate with @wonderlul and remove these changes from here #4886

Removed disabled FAB state: MD3 guidelines don't have a disabled state for FABs.
Removed customRippleColor: Not part of the native Material API. It offered too much customization at the cost of correctness, so it's gone from all components.

Removal of features is unrelated to the task. Also, who decides it offers "too much customization"? Please revert them and create issue/separate PR for discussion before removing features.

Next steps
Material Expressive components

Please discuss these first so they can be properly prioritized considered.

Update the documentation

Documentation update should be part of the PR that changes things.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants