feat(touchable-ripple): MD3 state-layer opacity via android_ripple alpha#4997
Draft
adrcotfas wants to merge 3 commits into
Draft
feat(touchable-ripple): MD3 state-layer opacity via android_ripple alpha#4997adrcotfas wants to merge 3 commits into
adrcotfas wants to merge 3 commits into
Conversation
stateLayerPressed pre-baked onSurface at the pressed opacity because PlatformColor can't be alpha-manipulated in JS. RN 0.86's android_ripple alpha makes that workaround unnecessary, so the field is dropped from the theme. TouchableRipple now defaults its ripple to onSurface and applies the opacity separately.
Replace the rippleAlpha prop with the MD3 pressed opacity applied automatically, so the public API is just an opaque rippleColor plus the raw background escape hatch. - Extract a shared TouchableRippleCommonProps type so web and native expose one API, and type background as PressableAndroidRippleConfig instead of Object. - Multiply the opacity into the color's own alpha (matching Android's android_ripple.alpha) so a transparent rippleColor stays invisible on web; fill the pressed opacity into a custom background only when it doesn't set its own alpha.
Add a stateLayer role to each FAB variant (the container's on-color) and resolve it following the container, ignoring a contentColor override. Shell passes it as rippleColor so the pressed and hover state layers match the variant instead of always using onSurface.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
MD3 interaction state layers are an opaque color drawn at a fixed opacity (0.1 pressed, 0.08 hover). Previously the theme shipped a pre-baked
stateLayerPressedcolor (onSurfaceat 0.1 alpha) becausePlatformColorcan't be alpha-manipulated in JS, so the opacity had to be baked into the token ahead of time.React Native 0.86's
android_ripple.alpha(react/react-native#56395) removes that limitation: the alpha can now be applied at draw time, even over aPlatformColor. This lets us drop the pre-baked theme color and giveTouchableRippleownership of the state-layer opacity, so any component can pass its own opaque state-layer color and get the correct pressed/hover opacity for free.This PR does that in three steps:
stateLayerPressedfrom the theme.TouchableRipplenow defaults its ripple toonSurfaceand applies the pressed opacity itself, so the workaround color is no longer needed.TouchableRippleAPI. The ripple color is treated as opaque and the MD3 pressed opacity is applied automatically (multiplied into the color's own alpha, matchingandroid_ripple.alpha), so atransparentripple color stays invisible on web too. The public surface is justrippleColorplus the rawbackgroundescape hatch. Web and native now share oneTouchableRippleCommonPropstype, andbackgroundis typed asPressableAndroidRippleConfiginstead ofObject.stateLayerrole (the container's on-color), resolved following the container and ignoring acontentColoroverride, and passed toTouchableRippleasrippleColor. The pressed/hover state layer now matches the variant (e.g. primary → onPrimary, tonalPrimary → onPrimaryContainer) instead of always usingonSurface.Test plan
lint, typescript and tests pass
Postponed until #4996 is merged