Skip to content

Commit 488d5e6

Browse files
committed
revert(MUSD-744): drop floating Add money footer in favour of static placement
The peek-and-hide overlay introduced by MUSD-747 (#29736) is no longer desired on Money home. Restores the simpler pre-MUSD-747 layout where MoneyFooter renders as a plain ScrollView sibling that sits at the bottom of the screen. - MoneyHomeView.tsx: remove Animated/reanimated wiring, footer/stepper layout refs, scroll-driven visibility computation, and the Box onLayout wrapper around MoneyOnboardingCard. ScrollView no longer needs onScroll/onLayout/scrollEventThrottle. - MoneyHomeView.styles.ts: drop footerOverlay; restore scrollContent with paddingBottom 0 for the static layout. - Delete utils/computeStepperVisibility.{ts,test.ts} — no longer used. - MoneyHomeView.test.tsx: remove the 11 peek-and-hide tests; drop now unused act and ReactTestInstance imports.
1 parent 01598d3 commit 488d5e6

5 files changed

Lines changed: 12 additions & 507 deletions

File tree

app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.styles.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@ const styleSheet = (params: { theme: Theme }) =>
77
flex: 1,
88
backgroundColor: params.theme.colors.background.default,
99
},
10-
footerOverlay: {
11-
position: 'absolute',
12-
left: 0,
13-
right: 0,
14-
bottom: 0,
10+
scrollContent: {
11+
paddingBottom: 0,
1512
},
1613
});
1714

app/components/UI/Money/Views/MoneyHomeView/MoneyHomeView.test.tsx

Lines changed: 1 addition & 273 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from 'react';
2-
import { act, fireEvent } from '@testing-library/react-native';
2+
import { fireEvent } from '@testing-library/react-native';
33
import { Linking } from 'react-native';
4-
import type { ReactTestInstance } from 'react-test-renderer';
54
import renderWithProvider from '../../../../../util/test/renderWithProvider';
65
import MoneyHomeView from './MoneyHomeView';
76
import { MoneyHomeViewTestIds } from './MoneyHomeView.testIds';
@@ -848,275 +847,4 @@ describe('MoneyHomeView', () => {
848847
expect(mockNavigate).toHaveBeenCalledWith(Routes.CARD.ROOT);
849848
});
850849
});
851-
852-
describe('Add money footer peek-and-hide', () => {
853-
it('mounts the footer in its hidden initial position', () => {
854-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
855-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
856-
});
857-
858-
it('handleScrollViewLayout updates scroll view height and calls updateStepperVisibility', () => {
859-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
860-
const scrollView = getByTestId(MoneyHomeViewTestIds.SCROLL_VIEW);
861-
862-
act(() => {
863-
fireEvent(scrollView, 'layout', {
864-
nativeEvent: { layout: { height: 700, width: 390, x: 0, y: 0 } },
865-
});
866-
});
867-
868-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
869-
});
870-
871-
it('handleScrollViewLayout is a no-op when height is unchanged', () => {
872-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
873-
const scrollView = getByTestId(MoneyHomeViewTestIds.SCROLL_VIEW);
874-
875-
act(() => {
876-
fireEvent(scrollView, 'layout', {
877-
nativeEvent: { layout: { height: 600, width: 390, x: 0, y: 0 } },
878-
});
879-
});
880-
881-
act(() => {
882-
fireEvent(scrollView, 'layout', {
883-
nativeEvent: { layout: { height: 600, width: 390, x: 0, y: 0 } },
884-
});
885-
});
886-
887-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
888-
});
889-
890-
it('handleScroll records the current scroll offset and calls updateStepperVisibility', () => {
891-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
892-
const scrollView = getByTestId(MoneyHomeViewTestIds.SCROLL_VIEW);
893-
894-
act(() => {
895-
fireEvent.scroll(scrollView, {
896-
nativeEvent: {
897-
contentOffset: { y: 300, x: 0 },
898-
contentSize: { height: 1200, width: 390 },
899-
layoutMeasurement: { height: 700, width: 390 },
900-
},
901-
});
902-
});
903-
904-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
905-
});
906-
907-
it('handleStepperLayout stores new layout and triggers visibility update', () => {
908-
const { UNSAFE_getAllByType, getByTestId } = renderWithProvider(
909-
<MoneyHomeView />,
910-
);
911-
912-
const Box = jest.requireActual(
913-
'@metamask/design-system-react-native',
914-
).Box;
915-
const stepperBox = UNSAFE_getAllByType(Box).find(
916-
(b: { props: { onLayout?: unknown } }) => b.props.onLayout,
917-
);
918-
919-
act(() => {
920-
stepperBox?.props.onLayout({
921-
nativeEvent: { layout: { y: 200, height: 120, x: 0, width: 390 } },
922-
});
923-
});
924-
925-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
926-
});
927-
928-
it('handleStepperLayout is a no-op when layout dimensions are unchanged', () => {
929-
const { UNSAFE_getAllByType, getByTestId } = renderWithProvider(
930-
<MoneyHomeView />,
931-
);
932-
933-
const Box = jest.requireActual(
934-
'@metamask/design-system-react-native',
935-
).Box;
936-
const stepperBox = UNSAFE_getAllByType(Box).find(
937-
(b: { props: { onLayout?: unknown } }) => b.props.onLayout,
938-
);
939-
940-
act(() => {
941-
stepperBox?.props.onLayout({
942-
nativeEvent: { layout: { y: 200, height: 120, x: 0, width: 390 } },
943-
});
944-
});
945-
946-
act(() => {
947-
stepperBox?.props.onLayout({
948-
nativeEvent: { layout: { y: 200, height: 120, x: 0, width: 390 } },
949-
});
950-
});
951-
952-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
953-
});
954-
955-
it('footer peek-in: scrolling past stepper bottom triggers animateFooter(true)', () => {
956-
const { UNSAFE_getAllByType, getByTestId } = renderWithProvider(
957-
<MoneyHomeView />,
958-
);
959-
960-
const scrollView = getByTestId(MoneyHomeViewTestIds.SCROLL_VIEW);
961-
962-
act(() => {
963-
fireEvent(scrollView, 'layout', {
964-
nativeEvent: { layout: { height: 700, width: 390, x: 0, y: 0 } },
965-
});
966-
});
967-
968-
const Box = jest.requireActual(
969-
'@metamask/design-system-react-native',
970-
).Box;
971-
const stepperBox = UNSAFE_getAllByType(Box).find(
972-
(b: { props: { onLayout?: unknown } }) => b.props.onLayout,
973-
);
974-
975-
act(() => {
976-
stepperBox?.props.onLayout({
977-
nativeEvent: { layout: { y: 100, height: 200, x: 0, width: 390 } },
978-
});
979-
});
980-
981-
act(() => {
982-
fireEvent.scroll(scrollView, {
983-
nativeEvent: {
984-
contentOffset: { y: 500, x: 0 },
985-
contentSize: { height: 2000, width: 390 },
986-
layoutMeasurement: { height: 700, width: 390 },
987-
},
988-
});
989-
});
990-
991-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
992-
});
993-
994-
it('footer hide: scrolling back above stepper bottom triggers animateFooter(false)', () => {
995-
const { UNSAFE_getAllByType, getByTestId } = renderWithProvider(
996-
<MoneyHomeView />,
997-
);
998-
999-
const scrollView = getByTestId(MoneyHomeViewTestIds.SCROLL_VIEW);
1000-
1001-
act(() => {
1002-
fireEvent(scrollView, 'layout', {
1003-
nativeEvent: { layout: { height: 700, width: 390, x: 0, y: 0 } },
1004-
});
1005-
});
1006-
1007-
const Box = jest.requireActual(
1008-
'@metamask/design-system-react-native',
1009-
).Box;
1010-
const stepperBox = UNSAFE_getAllByType(Box).find(
1011-
(b: { props: { onLayout?: unknown } }) => b.props.onLayout,
1012-
);
1013-
1014-
act(() => {
1015-
stepperBox?.props.onLayout({
1016-
nativeEvent: { layout: { y: 100, height: 200, x: 0, width: 390 } },
1017-
});
1018-
});
1019-
1020-
act(() => {
1021-
fireEvent.scroll(scrollView, {
1022-
nativeEvent: {
1023-
contentOffset: { y: 500, x: 0 },
1024-
contentSize: { height: 2000, width: 390 },
1025-
layoutMeasurement: { height: 700, width: 390 },
1026-
},
1027-
});
1028-
});
1029-
1030-
act(() => {
1031-
fireEvent.scroll(scrollView, {
1032-
nativeEvent: {
1033-
contentOffset: { y: 50, x: 0 },
1034-
contentSize: { height: 2000, width: 390 },
1035-
layoutMeasurement: { height: 700, width: 390 },
1036-
},
1037-
});
1038-
});
1039-
1040-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
1041-
});
1042-
1043-
it('updateStepperVisibility does not animate when visibility is unchanged', () => {
1044-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
1045-
const scrollView = getByTestId(MoneyHomeViewTestIds.SCROLL_VIEW);
1046-
1047-
act(() => {
1048-
fireEvent.scroll(scrollView, {
1049-
nativeEvent: {
1050-
contentOffset: { y: 0, x: 0 },
1051-
contentSize: { height: 2000, width: 390 },
1052-
layoutMeasurement: { height: 700, width: 390 },
1053-
},
1054-
});
1055-
});
1056-
1057-
act(() => {
1058-
fireEvent.scroll(scrollView, {
1059-
nativeEvent: {
1060-
contentOffset: { y: 10, x: 0 },
1061-
contentSize: { height: 2000, width: 390 },
1062-
layoutMeasurement: { height: 700, width: 390 },
1063-
},
1064-
});
1065-
});
1066-
1067-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
1068-
});
1069-
1070-
it('handleFooterLayout updates footer height on first measurement', () => {
1071-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
1072-
1073-
const footerEl = getByTestId(MoneyFooterTestIds.CONTAINER);
1074-
let footerAnimatedView: ReactTestInstance | null = null;
1075-
let cursor: ReactTestInstance | null = footerEl.parent ?? null;
1076-
while (cursor) {
1077-
if (typeof cursor.props?.onLayout === 'function') {
1078-
footerAnimatedView = cursor;
1079-
break;
1080-
}
1081-
cursor = cursor.parent ?? null;
1082-
}
1083-
1084-
act(() => {
1085-
footerAnimatedView?.props.onLayout?.({
1086-
nativeEvent: { layout: { height: 80, width: 390, x: 0, y: 0 } },
1087-
});
1088-
});
1089-
1090-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
1091-
});
1092-
1093-
it('handleFooterLayout is a no-op when footer height is unchanged', () => {
1094-
const { getByTestId } = renderWithProvider(<MoneyHomeView />);
1095-
1096-
const footerEl = getByTestId(MoneyFooterTestIds.CONTAINER);
1097-
let footerAnimatedView: ReactTestInstance | null = null;
1098-
let cursor: ReactTestInstance | null = footerEl.parent ?? null;
1099-
while (cursor) {
1100-
if (typeof cursor.props?.onLayout === 'function') {
1101-
footerAnimatedView = cursor;
1102-
break;
1103-
}
1104-
cursor = cursor.parent ?? null;
1105-
}
1106-
1107-
act(() => {
1108-
footerAnimatedView?.props.onLayout?.({
1109-
nativeEvent: { layout: { height: 80, width: 390, x: 0, y: 0 } },
1110-
});
1111-
});
1112-
1113-
act(() => {
1114-
footerAnimatedView?.props.onLayout?.({
1115-
nativeEvent: { layout: { height: 80, width: 390, x: 0, y: 0 } },
1116-
});
1117-
});
1118-
1119-
expect(getByTestId(MoneyFooterTestIds.CONTAINER)).toBeOnTheScreen();
1120-
});
1121-
});
1122850
});

0 commit comments

Comments
 (0)