Skip to content

chore: Added HeaderStandardAnimated to components temp#26712

Merged
brianacnguyen merged 6 commits into
mainfrom
component/headeranimated
Feb 28, 2026
Merged

chore: Added HeaderStandardAnimated to components temp#26712
brianacnguyen merged 6 commits into
mainfrom
component/headeranimated

Conversation

@brianacnguyen

@brianacnguyen brianacnguyen commented Feb 27, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds HeaderStandardAnimated, a scroll-driven animated header component to app/component-library/components-temp/. The header shows a full title section (e.g. with TitleStandard) when at the top of the scroll, and animates to a compact center title when the user scrolls past that section.

Reason for change: Screens with a large title block (e.g. Perps market detail) need a header that stays visible and collapses to a compact title as the user scrolls. This component provides that pattern with Reanimated-driven animation tied to scroll position.

What changed:

  1. HeaderStandardAnimated (app/component-library/components-temp/HeaderStandardAnimated/)

    • New component that extends the header pattern from HeaderCompactStandard and requires scrollY and titleSectionHeight shared values to drive the center-title animation.
    • Renders a HeaderBase with optional back/close buttons, title, subtitle, or custom children. The center content is wrapped in an Animated.View whose opacity and translateY are derived from scroll (compact title appears when scrollY >= titleSectionHeight).
    • Props: scrollY, titleSectionHeight (required), plus title/subtitle/children, onBack/backButtonProps, onClose/closeButtonProps, startButtonIconProps/endButtonIconProps, testID, twClassName, and other HeaderBase props.
  2. useHeaderStandardAnimated

    • New hook that returns scrollY, titleSectionHeightSv, setTitleSectionHeight, and onScroll for use with HeaderStandardAnimated and a ScrollView. Consumers call setTitleSectionHeight from the title section’s onLayout and pass onScroll to the ScrollView.
  3. Stories

    • HeaderStandardAnimated.stories.tsx: Default (title + back) and WithSubtitle, both with scrollable content and the hook wiring.
  4. Unit tests

    • HeaderStandardAnimated.test.tsx: Rendering (title, subtitle, children, testIDs via child prop objects), back/close button behavior and callbacks, and startButtonIconProps priority. Uses mocked Reanimated and safe area; shared values use a full SharedValue<number>-shaped mock.
    • useHeaderStandardAnimated.test.ts: Return shape, initial values, and that setTitleSectionHeight and onScroll update the shared values.
  5. Storybook

    • HeaderStandardAnimated stories registered in .storybook/storybook.requires.js.

Changelog

This PR is not end-user-facing; it adds a new internal header component for scroll-driven screens.

CHANGELOG entry: null

Related issues

Fixes: https://consensyssoftware.atlassian.net/browse/DSYS-287?atlOrigin=eyJpIjoiZThjYTU4Y2UyODcwNDJlMWJjMWQ0ZTQ1YmI0NjVhMGUiLCJwIjoiaiJ9

Manual testing steps

Feature: HeaderStandardAnimated component

  Scenario: Default header with scroll shows compact title when scrolled
    Given the app is open with Storybook or a screen using HeaderStandardAnimated
    When the user views the header with a scrollable list below a title section
    Then the full title section is visible at the top
    When the user scrolls down past the title section
    Then a compact center title appears in the header and the transition is animated

  Scenario: Back and close buttons work
    Given a HeaderStandardAnimated with onBack and onClose
    When the user taps the back button
    Then onBack is invoked
    When the user taps the close button
    Then onClose is invoked

Screenshots/Recordings

Before

N/A – new component.

After

Simulator.Screen.Recording.-.iPhone.15.Pro.Max.-.2026-02-27.at.13.21.34.mov

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Low Risk
Low risk because this is additive and isolated to the component library (components-temp) plus Storybook registration, with unit tests covering basic rendering and button-callback behavior.

Overview
Adds HeaderStandardAnimated, a new components-temp header wrapper around HeaderCompactStandard that animates the centered title/subtitle in based on scrollY and a measured titleSectionHeight shared value.

Introduces useHeaderStandardAnimated to provide the required Reanimated SharedValues and onScroll handler, along with Storybook stories demonstrating the scroll behavior and unit tests validating rendering and back/close/start-button callback precedence.

Written by Cursor Bugbot for commit e06f5c5. This will update automatically on new commits. Configure here.

@brianacnguyen brianacnguyen self-assigned this Feb 27, 2026
@brianacnguyen brianacnguyen added the No QA Needed Apply this label when your PR does not need any QA effort. label Feb 27, 2026
@brianacnguyen brianacnguyen requested a review from a team as a code owner February 27, 2026 21:32
@brianacnguyen brianacnguyen added team-design-system All issues relating to design system in Mobile no changelog required No changelog entry is required for this change labels Feb 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@brianacnguyen brianacnguyen changed the title update: Added HeaderStandardAnimated to components temp chore: Added HeaderStandardAnimated to components temp Feb 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: None (no tests recommended)
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: low
  • AI Confidence: 95%
click to see 🤖 AI reasoning details

E2E Test Selection:
This PR introduces a new HeaderStandardAnimated component in the component library's components-temp directory. The component is a scroll-linked animated header that shows/hides a compact title based on scroll position.

Key findings:

  1. No current usage in the app: The component is only imported by its own test files, stories, and index file. It's not used anywhere in the actual application code.
  2. Self-contained new component: All changes are within the new HeaderStandardAnimated directory, plus a single line addition to .storybook/storybook.requires.js to register the Storybook story.
  3. Comprehensive unit tests included: The PR includes thorough unit tests for both the component (HeaderStandardAnimated.test.tsx) and the hook (useHeaderStandardAnimated.test.ts).
  4. No breaking changes: Since this is a brand new component with no existing consumers, there's no risk of breaking existing functionality or E2E tests.

Since this component is not yet integrated into any user-facing features or screens, no E2E tests are necessary to validate this change. The unit tests provided adequately cover the component's functionality.

Performance Test Selection:
This PR adds a new component that is not yet used anywhere in the application. The component uses react-native-reanimated for scroll-linked animations, but since it's not integrated into any screens or user flows, there's no performance impact to measure. No performance tests are needed.

View GitHub Actions results

@georgewrmarshall georgewrmarshall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice work! LGTM ✅

  • Left some non blocking comments more for when it's migrated to MMDS

Comment on lines +142 to +168
it('renders back button when onBack provided', () => {
const { getByTestId } = render(
<HeaderStandardAnimated
{...defaultProps}
title="Title"
onBack={jest.fn()}
backButtonProps={{ testID: BACK_BUTTON_TEST_ID }}
/>,
);

expect(getByTestId(BACK_BUTTON_TEST_ID)).toBeOnTheScreen();
});

it('renders back button when backButtonProps provided', () => {
const { getByTestId } = render(
<HeaderStandardAnimated
{...defaultProps}
title="Title"
backButtonProps={{
onPress: jest.fn(),
testID: BACK_BUTTON_TEST_ID,
}}
/>,
);

expect(getByTestId(BACK_BUTTON_TEST_ID)).toBeOnTheScreen();
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking seems like these tests could be consolidated into one if we are using backButtonProps to assert for the back button

scrollY,
titleSectionHeight,
twClassName = '',
...headerStandardProps

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: I think we usually just use ...props for spread props

});

const content = title ? (
<Box alignItems={BoxAlignItems.Center}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: Is this wrapper necessary or can we just apply the styles to the Animated.View to reduce bloat?

@@ -0,0 +1,6 @@
export { default } from './HeaderStandardAnimated';
export { default as useHeaderStandardAnimated } from './useHeaderStandardAnimated';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: Why not just export as a named export from useHeaderStandardAnimated?

* Extends HeaderCompactStandardProps with scroll-driven animation inputs.
* Content is driven by title/subtitle only; children is not supported.
*/
export interface HeaderStandardAnimatedProps

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

non-blocking: I think we want to move away from interface for MDMS components in favor of type

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

@brianacnguyen brianacnguyen added this pull request to the merge queue Feb 27, 2026
Merged via the queue into main with commit 1591e2d Feb 28, 2026
60 checks passed
@brianacnguyen brianacnguyen deleted the component/headeranimated branch February 28, 2026 00:14
@github-actions github-actions Bot locked and limited conversation to collaborators Feb 28, 2026
@metamaskbot metamaskbot added the release-7.69.0 Issue or pull request that will be included in release 7.69.0 label Feb 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

no changelog required No changelog entry is required for this change No QA Needed Apply this label when your PR does not need any QA effort. release-7.69.0 Issue or pull request that will be included in release 7.69.0 size-L team-design-system All issues relating to design system in Mobile

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants