refactor: rework Surface and elevation shadows - #5078
Draft
satya164 wants to merge 1 commit into
Draft
Conversation
There was a problem hiding this comment.
Pull request overview
Reworks Surface around Reanimated-compatible styling and updates dependent components, animations, examples, documentation, and tests.
Changes:
- Replaces layered/style-flattening Surface behavior with explicit visual props and platform shadows.
- Migrates several component animations to Reanimated.
- Updates affected APIs, tests, snapshots, examples, and documentation.
Reviewed changes
Copilot reviewed 61 out of 70 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/utils/animations.ts |
Removes obsolete Animated helper. |
src/theme/tokens/sys/elevation.ts |
Reworks static shadow generation. |
src/components/ToggleButton/ToggleButton.tsx |
Updates animated style typing. |
src/components/Surface.tsx |
Reimplements Surface and visual props. |
src/components/Snackbar.tsx |
Migrates animations to Reanimated. |
src/components/Searchbar.tsx |
Adopts new Surface API. |
src/components/Modal.tsx |
Adds transitions and elevation. |
src/components/Menu/Menu.tsx |
Migrates menu animations and layout. |
src/components/IconButton/IconButton.tsx |
Replaces Surface with Animated View. |
src/components/FAB/useVisibility.ts |
Removes superseded visibility hook. |
src/components/FAB/Shell.tsx |
Integrates Surface and visibility animation. |
src/components/FAB/Extended.tsx |
Updates measurement behavior. |
src/components/Dialog/Dialog.tsx |
Uses Modal elevation. |
src/components/Chip/Chip.tsx |
Adopts numeric elevation transitions. |
src/components/Card/Card.tsx |
Adopts new Surface visual props. |
src/components/Button/Button.tsx |
Adopts new Surface visual props. |
src/components/BottomNavigation/BottomNavigationBar.tsx |
Adds animated wrapper around Surface. |
src/components/Banner.tsx |
Migrates animations to Reanimated. |
src/components/Appbar/utils.ts |
Updates elevation and border helpers. |
src/components/Appbar/AppbarHeader.tsx |
Replaces elevated flag with elevation. |
src/components/Appbar/Appbar.tsx |
Integrates new Surface API. |
src/components/__tests__/ToggleButton.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Surface.test.tsx |
Updates Surface layer assertions. |
src/components/__tests__/Snackbar.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Searchbar.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Modal.test.tsx |
Updates Surface and style assertions. |
src/components/__tests__/Menu.test.tsx |
Updates content-style assertion. |
src/components/__tests__/IconButton.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Chip.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Checkbox/__snapshots__/CheckboxItem.test.tsx.snap |
Refreshes Reanimated snapshots. |
src/components/__tests__/Checkbox/__snapshots__/Checkbox.test.tsx.snap |
Refreshes Reanimated snapshots. |
src/components/__tests__/Card/Card.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Card/__snapshots__/Card.test.tsx.snap |
Reflects new Surface structure. |
src/components/__tests__/Button.test.tsx |
Removes legacy animation test. |
src/components/__tests__/BottomNavigation.test.tsx |
Targets new animated wrapper. |
src/components/__tests__/Banner.test.tsx |
Removes legacy animation test. |
src/components/__tests__/Appbar/Appbar.test.tsx |
Updates Appbar API assertions. |
src/components/__tests__/__snapshots__/ToggleButton.test.tsx.snap |
Reflects IconButton structure. |
src/components/__tests__/__snapshots__/Switch.test.tsx.snap |
Refreshes Reanimated snapshots. |
src/components/__tests__/__snapshots__/ListItem.test.tsx.snap |
Reflects new Chip Surface structure. |
src/components/__tests__/__snapshots__/Badge.test.tsx.snap |
Refreshes Reanimated snapshots. |
jest/testSetup.js |
Adjusts worklets mocking. |
example/src/RootNavigator.tsx |
Updates Appbar usage. |
example/src/Examples/TooltipExample.tsx |
Updates Appbar usage. |
example/src/Examples/TeamDetails.tsx |
Updates Appbar usage. |
example/src/Examples/SurfaceExample.tsx |
Demonstrates new Surface props. |
example/src/Examples/MenuExample.tsx |
Updates Appbar usage. |
example/src/Examples/BottomNavigationExample.tsx |
Updates Appbar usage. |
example/src/Examples/AppbarExample.tsx |
Uses numeric elevation. |
docs/6.x/docs/components/Surface.mdx |
Documents Surface visual props. |
docs/6.x/docs/components/Modal.mdx |
Documents Modal elevation. |
docs/6.x/docs/components/Chip/Chip.mdx |
Documents Chip ref. |
docs/6.x/docs/components/Card/Card.mdx |
Documents Card ref. |
docs/6.x/docs/components/Appbar/AppbarHeader.mdx |
Documents elevation API. |
docs/6.x/docs/components/Appbar/Appbar.mdx |
Documents elevation API. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| height: shadowLayers[layer].height[elevation], | ||
| }, | ||
| shadowRadius: shadowLayers[layer].shadowRadius[elevation], | ||
| export type Props = Omit<ViewProps, 'pointerEvents' | 'style'> & |
| * - `overflow: 'hidden'` is not supported with `elevation` as it can clip the shadow. | ||
| * To achieve the same effect, wrap the content in a child View with the overflow style. | ||
| */ | ||
| style?: StyleProp<AnimatedStyle<Omit<ViewStyle, keyof SurfaceVisualProps>>>; |
| theme={theme} | ||
| style={[{ opacity }, styles.content, contentContainerStyle]} | ||
| container | ||
| backgroundColor="transparent" |
satya164
force-pushed
the
@satya164/rework-surface
branch
2 times, most recently
from
August 27, 2026 16:39
f72f11a to
66bded7
Compare
satya164
marked this pull request as ready for review
August 27, 2026 17:14
satya164
force-pushed
the
@satya164/rework-surface
branch
from
August 27, 2026 17:14
66bded7 to
b61df18
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 59 out of 68 changed files in this pull request and generated 3 comments.
Suppressed comments (3)
src/components/Surface.tsx:258
- Elevation also changes the derived
backgroundColor, but this branch only transitions native elevation. Changing levels on Android makes the surface color jump while the shadow animates; include the background color in the transition as well.
src/components/Surface.tsx:282 - The elevation-derived background changes together with these shadow properties, but it is omitted from the transition. This causes level colors to snap on iOS while the shadow animates; transition
backgroundColortoo.
src/components/Surface.tsx:194 - The central behavior of this refactor—reacting to updates from Reanimated shared/animated styles—is not covered. The new Surface tests only assert static styles, while the prior animation tests in its consumers were removed. Add a test that mutates a shared value and verifies the rendered Surface style updates so metadata-preserving behavior cannot regress.
|
|
||
| transitionStyle = { | ||
| ...transitionStyle, | ||
| transitionProperty: 'boxShadow', |
| elevation={0} | ||
| testID={testID} | ||
| style={{ pointerEvents }} | ||
| onLayout={onLayout} |
Comment on lines
+62
to
+65
| - `Banner` | ||
| - `Button` | ||
| - `Card` | ||
| - `Chip` |
satya164
marked this pull request as draft
August 27, 2026 18:01
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
This reworks the
Surfacecomponent to work with Reanimated + updates components that useSurface.Previously, since the component rendered outer and inner views, it flattened styles and picked where to apply what. Style flattening adds challenges when using Reanimated, as Reanimated relies on metadata from
useAnimatedStylefor UI-thread updates.After trying a couple of approaches, I arrived at this approach:
ViewforSurfaceso it can accept both position and layout related stylesViewfor second shadow layer, but instead of wrappingchildrenin it (which adds more challenges), we absolutely position it behind the contentTest plan
Appbar
Android
Before
After
iOS
Before
After
Web
Before
After
Badge
Android
Before
After
iOS
Before
After
Web
Before
After
Banner
Android
Before
banner-android-before.mp4
After
banner-android-after.mp4
iOS
Before
banner-ios-before.mp4
After
banner-ios-after.mp4
Web
Before
banner-web-before.mp4
After
banner-web-after.mp4
Bottom Navigation
Android
Before
bottom-navigation-android-before.mp4
After
bottom-navigation-android-after.mp4
iOS
Before
bottom-navigation-ios-before.mp4
After
bottom-navigation-ios-after.mp4
Web
Before
bottom-navigation-web-before.mp4
After
bottom-navigation-web-after.mp4
Button
Android
Before
After
iOS
Before
After
Web
Before
After
Card
Android
Before
After
iOS
Before
After
Web
Before
After
Chip
Android
Before
After
iOS
Before
After
Web
Before
After
Dialog
Android
Before
dialog-android-before.mp4
After
dialog-android-after.mp4
iOS
Before
dialog-ios-before.mp4
After
dialog-ios-after.mp4
Web
Before
dialog-web-before.mp4
After
dialog-web-after.mp4
FAB
Android
Before
fab-android-before.mp4
After
fab-android-after.mp4
iOS
Before
fab-ios-before.mp4
After
fab-ios-after.mp4
Web
Before
fab-web-before.mp4
After
fab-web-after.mp4
Icon Button
Android
Before
After
iOS
Before
After
Web
Before
After
Menu
Android
Before
menu-android-before.mp4
After
menu-android-after.mp4
iOS
Before
menu-ios-before.mp4
After
menu-ios-after.mp4
Web
Before
menu-web-before.mp4
After
menu-web-after.mp4
Modal
Android
Before
modal-android-before.mp4
After
modal-android-after.mp4
iOS
Before
modal-ios-before.mp4
After
modal-ios-after.mp4
Web
Before
modal-web-before.mp4
After
modal-web-after.mp4
Searchbar
Android
Before
After
iOS
Before
After
Web
Before
After
Snackbar
Android
Before
snackbar-android-before.mp4
After
snackbar-android-after.mp4
iOS
Before
snackbar-ios-before.mp4
After
snackbar-ios-after.mp4
Web
Before
snackbar-web-before.mp4
After
snackbar-web-after.mp4
Surface
Android
Before
surface-android-before.mp4
After
surface-android-after.mp4
iOS
Before
surface-ios-before.mp4
After
surface-ios-after.mp4
Web
Before
surface-web-before.mp4
After
surface-web-after.mp4
Toggle Button
Android
Before
After
iOS
Before
After
Web
Before
After