Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate issues remain in Avatar background-style precedence and Tooltip ref forwarding and measurement fallback.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Refactors v6 components to remove style flattening and improve Reanimated animated-style support.
Changes:
- Replaces style-derived values with explicit component props.
- Updates Tooltip measurement and ref handling.
- Updates tests, snapshots, examples, linting, and migration documentation.
File summaries
| File | Summary |
|---|---|
src/utils/splitStyles.ts |
Removes obsolete utility. |
src/utils/__tests__/splitStyles.test.ts |
Removes obsolete tests. |
src/components/Tooltip/utils.ts |
Supports direct measurement. |
src/components/Tooltip/Tooltip.tsx |
Adds ref forwarding and measurement. |
src/components/Surface.tsx |
Exports shared visual prop types. |
src/components/DataTable/DataTablePagination.tsx |
Uses trailing icon positioning. |
src/components/Card/utils.tsx |
Removes style-derived radius handling. |
src/components/Card/CardCover.tsx |
Applies clipping radius to the container. |
src/components/Card/Card.tsx |
Uses themed outline color. |
src/components/Button/utils.tsx |
Uses static border-radius keys. |
src/components/Button/Button.tsx |
Adds explicit icon positioning and styling. |
src/components/BottomNavigation/BottomNavigationBar.tsx |
Moves background styling to the outer bar. |
src/components/Avatar/AvatarText.tsx |
Adds an explicit background color prop. |
src/components/Avatar/AvatarImage.tsx |
Adds an explicit background color prop. |
src/components/Avatar/AvatarIcon.tsx |
Adds an explicit background color prop. |
src/components/Appbar/utils.ts |
Removes border extraction. |
src/components/Appbar/AppbarHeader.tsx |
Updates header styling and safe-area handling. |
src/components/Appbar/Appbar.tsx |
Adds visual props and inset-aware sizing. |
src/components/__tests__/Tooltip.test.tsx |
Tests ref forwarding. |
src/components/__tests__/Card/Card.test.tsx |
Updates Card behavior tests. |
src/components/__tests__/Card/__snapshots__/Card.test.tsx.snap |
Updates Card snapshots. |
src/components/__tests__/Button.test.tsx |
Tests icon positioning. |
src/components/__tests__/Avatar.test.tsx |
Uses background color props. |
src/components/__tests__/Appbar/Appbar.test.tsx |
Tests Appbar visual props. |
src/components/__tests__/Appbar/__snapshots__/Appbar.test.tsx.snap |
Updates Appbar snapshots. |
src/components/__tests__/__snapshots__/DataTable.test.tsx.snap |
Updates pagination snapshot. |
src/components/__tests__/__snapshots__/Button.test.tsx.snap |
Updates Button snapshot. |
src/components/__tests__/__snapshots__/BottomNavigation.test.tsx.snap |
Updates navigation snapshots. |
src/components/__tests__/__snapshots__/Avatar.test.tsx.snap |
Updates Avatar snapshots. |
example/src/Examples/ButtonExample.tsx |
Migrates trailing icons. |
example/src/Examples/AvatarExample.tsx |
Migrates background colors. |
example/src/Examples/AppbarExample.tsx |
Migrates Appbar background colors. |
eslint.config.mjs |
Bans source StyleSheet.flatten usage. |
docs/6.x/docs/guides/migration.md |
Documents breaking API changes. |
Review details
Suppressed comments (3)
src/components/Appbar/Appbar.tsx:226
- This changes the Appbar layout contract by adding top and bottom safe-area values to the computed height, but the Appbar tests do not assert the resulting height for either
AppbarorAppbar.Header(including the custom header-height case described in the migration guide). Add a regression case covering the inset calculation so a future refactor cannot drop or double-count these values.
// The safe area insets are applied as padding, so they need to be included in the height
const height =
modeAppbarHeight[mode] +
(safeAreaInsets?.top ?? 0) +
(safeAreaInsets?.bottom ?? 0);
src/components/Tooltip/Tooltip.tsx:201
- The wrapper fallback only runs when the ref is null. A wrapped class or
forwardRefcomponent can yield a non-null custom instance that does not implement React Native'smeasure, so this calls an undefined method and the tooltip crashes instead of falling back as documented. Check that the ref exposesmeasurebefore selecting it; otherwise usechildrenWrapperRef.current.
const target = childRef.current ?? childrenWrapperRef.current;
target?.measure((_x, _y, width, height, pageX, pageY) => {
src/components/Tooltip/Tooltip.tsx:108
- The ref merge only reads
children.props.ref, but React 18 stores an element ref on the element rather than inprops. Since this package declares an unrestricted React peer, wrapping a child with a ref under React 18 will replace the user's ref withsetChildRefand never invoke the original ref, contrary to the forwarding behavior documented by this change. Use a React-version-compatible ref merge and add coverage for the supported React 18 path.
const childOwnRef = isValidChild
? // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
(children.props as TooltipChildProps).ref
: undefined;
// Keep a ref to the wrapped element so it can be measured directly,
// while still forwarding the ref passed by the user (if any)
const setChildRef = React.useCallback(
(node: View | null) => {
childRef.current = node;
if (typeof childOwnRef === 'function') {
childOwnRef(node);
} else if (childOwnRef) {
childOwnRef.current = node;
- Files reviewed: 34/34 changed files
- Comments generated: 4
- Review effort level: Lite (auto)
Note
Copilot is running an experiment and ran this review at Lite.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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
A few components still read values out of the
styleprop withStyleSheet.flatten(andsplitStyleson top of it) to derive other styles: background color, border radius, border color, icon placement and so on. This doesn't work with styles returned fromuseAnimatedStyle, they can't be flattened, so these components couldn't get full Reanimated support.This PR removes
splitStylesand everyStyleSheet.flattencall from the library and moves the values we need into props, following what was done forSurfacein #5078.Appbar/Appbar.Header: newbackgroundColorprop and the same border radius props asSurface.stylenow accepts animated styles.getAppbarBordersis gone.Appbarnow includessafeAreaInsetsin its height, soAppbar.Headerno longer needs to readheightfromstyleto add the status bar inset.Avatar.Icon/Avatar.Image/Avatar.Text: newbackgroundColorprop. Contrast color for the text and icon is still derived from it.Button: newiconPositionprop (leading|trailing) instead of detectingflexDirection: 'row-reverse'incontentStyle. Icon color and size no longer come fromlabelStyle,textColorcovers the color.Card: outline color comes fromtheme.colors.outlineinstead ofstyle.borderColor.Card.Cover: border radius fromstyleis applied to the container only, the image is clipped by it anyway.BottomNavigation.Bar: background color moved to the outer view, sobarStyle={{ backgroundColor }}keeps working without parsing the style.Tooltip: instead of readingposition/top/leftfrom the child's style, it attaches a ref to the wrapped element and measures it directly (falling back to the wrapper). The user's ref is still forwarded.DataTable.Paginationand the example app updated to the new props.StyleSheet.flatteninsrcso it doesn't come back.Breaking changes are listed in the 6.x migration guide.
Related issue
Part of the Reanimated migration for v6. Note that #4943 also adds
iconPositiontoButtonwith the same name, whichever lands second will need a small rebase.Test plan
yarn typecheck,yarn lintandyarn jestpass.Appbarprops and for ref forwarding inTooltip, updated theAvatar,ButtonandCardtests to use the new props.BottomNavigation.Bar, therow-reversecontent style inButtonandDataTable.Pagination, and{}turning intoundefinedwhere the flattened style used to be.