diff --git a/.storybook/main.ts b/.storybook/main.ts
index 3afea997a31..1069dd6073e 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -1,4 +1,4 @@
-import type {StorybookConfig} from 'storybook/internal/types';
+import type {StorybookConfig} from '@storybook/react-webpack5';
 
 const main: StorybookConfig = {
     stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
@@ -15,6 +15,9 @@ const main: StorybookConfig = {
         options: {},
     },
     docs: {},
+    typescript: {
+        reactDocgen: false,
+    },
 };
 
 export default main;
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 19a350b23af..cb051e4ed72 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -5,7 +5,9 @@ import {SafeAreaProvider} from 'react-native-safe-area-context';
 import type {Parameters} from 'storybook/internal/types';
 import EnvironmentProvider from '@components/EnvironmentContextProvider';
 import OnyxListItemProvider from '@components/OnyxListItemProvider';
+import ScreenWrapperStatusContext from '@components/ScreenWrapper/ScreenWrapperStatusContext';
 import {SearchContextProvider} from '@components/Search/SearchContext';
+import colors from '@styles/theme/colors';
 import ComposeProviders from '@src/components/ComposeProviders';
 import HTMLEngineProvider from '@src/components/HTMLEngineProvider';
 import {LocaleContextProvider} from '@src/components/LocaleContextProvider';
@@ -35,7 +37,9 @@ const decorators = [
                 SearchContextProvider,
             ]}
         >
-            <Story />
+            <ScreenWrapperStatusContext.Provider value={{didScreenTransitionEnd: true, isSafeAreaTopPaddingApplied: false, isSafeAreaBottomPaddingApplied: false}}>
+                <Story />
+            </ScreenWrapperStatusContext.Provider>
         </ComposeProviders>
     ),
 ];
@@ -46,6 +50,16 @@ const parameters: Parameters = {
             color: /(background|color)$/i,
         },
     },
+    backgrounds: {
+        options: {
+            dark: {name: 'Dark', value: colors.productDark100},
+            light: {name: 'Light', value: colors.productLight100},
+        },
+    },
+};
+
+const initialGlobals = {
+    backgrounds: {value: 'dark'},
 };
 
-export {decorators, parameters};
+export {decorators, parameters, initialGlobals};
diff --git a/__mocks__/@react-navigation/native/index.ts b/__mocks__/@react-navigation/native/index.ts
index 5c3d3e6007e..6c9cc76055a 100644
--- a/__mocks__/@react-navigation/native/index.ts
+++ b/__mocks__/@react-navigation/native/index.ts
@@ -1,4 +1,5 @@
 import type * as ReactNavigation from '@react-navigation/native';
+import {useEffect} from 'react';
 import createAddListenerMock from '../../../tests/utils/createAddListenerMock';
 
 const isJestEnv = process.env.NODE_ENV === 'test';
@@ -16,15 +17,14 @@ const {triggerTransitionEnd, addListener} = isJestEnv
           addListener: () => {},
       };
 
-const useNavigation = isJestEnv
-    ? realReactNavigation.useNavigation
-    : {
-          navigate: isJestEnv ? jest.fn() : () => {},
-          getState: () => ({
-              routes: [],
-          }),
-          addListener,
-      };
+const navigationMock = {
+    navigate: () => {},
+    getState: () => ({routes: []}),
+    isFocused: () => true,
+    addListener,
+};
+
+const useNavigation = isJestEnv ? realReactNavigation.useNavigation : () => navigationMock;
 
 type NativeNavigationMock = typeof ReactNavigation & {
     triggerTransitionEnd: () => void;
@@ -42,7 +42,12 @@ const useLinkProps = isJestEnv ? realReactNavigation.useLinkProps : () => null;
 const useLinkTo = isJestEnv ? realReactNavigation.useLinkTo : () => null;
 const useScrollToTop = isJestEnv ? realReactNavigation.useScrollToTop : () => null;
 const useRoute = isJestEnv ? realReactNavigation.useRoute : () => ({params: {}});
-const useFocusEffect = isJestEnv ? realReactNavigation.useFocusEffect : (callback: () => void) => callback();
+// Run callback in useEffect (like real useFocusEffect), not synchronously during render
+const useFocusEffect = isJestEnv
+    ? realReactNavigation.useFocusEffect
+    : (callback: () => (() => void) | void) => {
+          useEffect(() => callback(), [callback]);
+      };
 const usePreventRemove = isJestEnv ? jest.fn() : () => {};
 const useNavigationState = isJestEnv ? realReactNavigation.useNavigationState : () => {};
 
diff --git a/src/components/Search/SearchContext.tsx b/src/components/Search/SearchContext.tsx
index 6b366d6adaa..c3cb96349aa 100644
--- a/src/components/Search/SearchContext.tsx
+++ b/src/components/Search/SearchContext.tsx
@@ -1,4 +1,4 @@
-import {useNavigation} from '@react-navigation/core';
+import {useNavigation} from '@react-navigation/native';
 import type {NavigationState} from '@react-navigation/routers';
 import React, {useContext, useEffect, useRef, useState} from 'react';
 // We need direct access to useOnyx from react-native-onyx to avoid circular dependencies in SearchContext
diff --git a/src/stories/AddressSearch.stories.tsx b/src/stories/AddressSearch.stories.tsx
old mode 100644
new mode 100755
index af9fa41f2db..49a29db16c4
--- a/src/stories/AddressSearch.stories.tsx
+++ b/src/stories/AddressSearch.stories.tsx
@@ -25,6 +25,7 @@ function Template(props: AddressSearchProps) {
     const [value, setValue] = useState<string | number | Address | StreetValue>('');
     return (
         <AddressSearch
+            inputID="addressLine1"
             value={value as string}
             onInputChange={(inputValue) => setValue(inputValue)}
             {...props}
diff --git a/src/stories/Button.stories.tsx b/src/stories/Button.stories.tsx
old mode 100644
new mode 100755
index 68bff3c85d9..aa43a1d30a5
--- a/src/stories/Button.stories.tsx
+++ b/src/stories/Button.stories.tsx
@@ -1,5 +1,5 @@
 import type {Meta, StoryFn} from '@storybook/react-webpack5';
-import React, {useCallback, useState} from 'react';
+import React, {useState} from 'react';
 import {View} from 'react-native';
 import type {ButtonProps} from '@components/Button';
 import Button from '@components/Button';
@@ -26,11 +26,11 @@ function Template(props: ButtonProps) {
 const Default: ButtonStory = Template.bind({});
 const Loading: ButtonStory = Template.bind({});
 function PressOnEnter(props: ButtonProps) {
-    const [text, setText] = useState('');
-    const onPress = useCallback(() => {
+    const [text, setText] = useState(props.text);
+    const onPress = () => {
         setText('Button Pressed!');
-        setTimeout(() => setText(''), 500);
-    }, []);
+        setTimeout(() => setText(props.text), 500);
+    };
     return (
         <Button
             {...props}
diff --git a/src/stories/EReceipt.stories.tsx b/src/stories/EReceipt.stories.tsx
old mode 100644
new mode 100755
index fbe7272ac4a..06cf3bc063b
--- a/src/stories/EReceipt.stories.tsx
+++ b/src/stories/EReceipt.stories.tsx
@@ -35,6 +35,7 @@ const transactionData = {
         amount: 1000,
         currency: 'USD',
         cardID: 5,
+        cardName: 'Expensify Test Card',
         merchant: 'United Airlines',
         mccGroup: 'Commuter',
         created: '2023-07-24 13:46:20',
@@ -155,8 +156,8 @@ const transactionData = {
 
 Onyx.mergeCollection(ONYXKEYS.COLLECTION.TRANSACTION, transactionData);
 Onyx.merge('cardList', {
-    4: {bank: 'Expensify Card', lastFourPAN: '1000'},
-    5: {bank: 'Expensify Card', lastFourPAN: '4444'},
+    4: {cardName: 'Test Card', lastFourPAN: '1000', fundID: '123'},
+    5: {bank: 'Expensify Card', lastFourPAN: '4444', fundID: '456'},
 });
 
 /**
diff --git a/src/stories/Form.stories.tsx b/src/stories/Form.stories.tsx
index a008a87761a..5e4cd5cb4e3 100644
--- a/src/stories/Form.stories.tsx
+++ b/src/stories/Form.stories.tsx
@@ -13,6 +13,7 @@ import Picker from '@components/Picker';
 import StateSelector from '@components/StateSelector';
 import Text from '@components/Text';
 import TextInput from '@components/TextInput';
+import useLocalize from '@hooks/useLocalize';
 import {isRequiredFulfilled} from '@libs/ValidationUtils';
 import {clearErrors, setDraftValues, setErrors, setIsLoading} from '@userActions/FormActions';
 import CONST from '@src/CONST';
@@ -63,6 +64,8 @@ const story: Meta<typeof FormProvider> = {
 };
 
 function Template(props: FormProviderProps & FormProviderOnyxProps) {
+    const {translate} = useLocalize();
+
     // Form consumes data from Onyx, so we initialize Onyx with the necessary data here
     setIsLoading(props.formID, !!props.formState?.isLoading);
     setDraftValues(props.formID, props.draftValues);
@@ -98,7 +101,7 @@ function Template(props: FormProviderProps & FormProviderOnyxProps) {
                 label="Street"
                 inputID="street"
                 containerStyles={defaultStyles.mt4}
-                hint="common.noPO"
+                hint={translate('common.noPO')}
             />
             <InputWrapper
                 InputComponent={DatePicker}
diff --git a/src/stories/MoneyRequestReportPreview.stories.tsx b/src/stories/MoneyRequestReportPreview.stories.tsx
old mode 100644
new mode 100755
index 4536122d9bb..ebde5a80120
--- a/src/stories/MoneyRequestReportPreview.stories.tsx
+++ b/src/stories/MoneyRequestReportPreview.stories.tsx
@@ -1,16 +1,15 @@
+import type {ListRenderItem} from '@shopify/flash-list';
 import type {StoryFn} from '@storybook/react-webpack5';
-import React from 'react';
-import type {ListRenderItem} from 'react-native';
+import React, {useRef, useState} from 'react';
+import type {LayoutChangeEvent} from 'react-native';
 import {View} from 'react-native';
 import MoneyRequestReportPreviewContent from '@components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent';
 import type {MoneyRequestReportPreviewContentProps} from '@components/ReportActionItem/MoneyRequestReportPreview/types';
 import TransactionPreviewContent from '@components/ReportActionItem/TransactionPreview/TransactionPreviewContent';
 import ThemeProvider from '@components/ThemeProvider';
 import ThemeStylesProvider from '@components/ThemeStylesContextProvider';
-// eslint-disable-next-line no-restricted-imports
-import getMoneyRequestReportPreviewStyle from '@styles/utils/getMoneyRequestReportPreviewStyle';
-// eslint-disable-next-line no-restricted-imports
-import sizing from '@styles/utils/sizing';
+import useStyleUtils from '@hooks/useStyleUtils';
+import useThemeStyles from '@hooks/useThemeStyles';
 import CONST from '@src/CONST';
 import SCREENS from '@src/SCREENS';
 import type {Transaction} from '@src/types/onyx';
@@ -34,30 +33,6 @@ const mockTransactionsBig = Array.from({length: 12}).map((item, index) => {
     return {...transactionR14932, transactionID: `${transactionR14932.transactionID}${index}`};
 });
 
-const mockRenderItem: ListRenderItem<Transaction> = ({item}) => (
-    <TransactionPreviewContent
-        action={actionR14932}
-        isWhisper={false}
-        isHovered={false}
-        chatReport={chatReportR14932}
-        personalDetails={personalDetails}
-        report={iouReportR14932}
-        transaction={item}
-        transactionRawAmount={item.amount}
-        violations={item.errors ? violationsR14932 : []}
-        offlineWithFeedbackOnClose={() => undefined}
-        navigateToReviewFields={() => undefined}
-        isBillSplit={false}
-        areThereDuplicates={false}
-        sessionAccountID={11111111}
-        walletTermsErrors={undefined}
-        routeName={SCREENS.TRANSACTION_DUPLICATE.REVIEW}
-        shouldHideOnDelete={false}
-        transactionPreviewWidth={303}
-        containerStyles={[sizing.h100]}
-    />
-);
-
 type MoneyRequestReportPreviewStory = StoryFn<typeof MoneyRequestReportPreviewContent>;
 
 export default {
@@ -123,7 +98,6 @@ export default {
         violations: violationsR14932,
         invoiceReceiverPersonalDetail: undefined,
         invoiceReceiverPolicy: undefined,
-        renderTransactionItem: mockRenderItem,
     },
     parameters: {
         useLightTheme: true,
@@ -133,7 +107,62 @@ export default {
 function Template(props: MoneyRequestReportPreviewContentProps, {parameters}: {parameters: {useLightTheme?: boolean; transactionsBig?: boolean}}) {
     const theme = parameters.useLightTheme ? CONST.THEME.LIGHT : CONST.THEME.DARK;
     const transactions = parameters.transactionsBig ? mockTransactionsBig : props.transactions;
-    const reportPreviewStyle = getMoneyRequestReportPreviewStyle(false, transactions.length, 400, 400);
+
+    const widthsRef = useRef<{currentWidth: number | null; currentWrapperWidth: number | null}>({currentWidth: null, currentWrapperWidth: null});
+    const [widths, setWidths] = useState({currentWidth: 0, currentWrapperWidth: 0});
+
+    const updateWidths = () => {
+        const {currentWidth, currentWrapperWidth} = widthsRef.current;
+
+        if (currentWidth && currentWrapperWidth) {
+            setWidths({currentWidth, currentWrapperWidth});
+        }
+    };
+
+    const onCarouselLayout = (e: LayoutChangeEvent) => {
+        const newWidth = e.nativeEvent.layout.width;
+        if (widthsRef.current.currentWidth !== newWidth) {
+            widthsRef.current.currentWidth = newWidth;
+            updateWidths();
+        }
+    };
+
+    const onWrapperLayout = (e: LayoutChangeEvent) => {
+        const newWrapperWidth = e.nativeEvent.layout.width;
+        if (widthsRef.current.currentWrapperWidth !== newWrapperWidth) {
+            widthsRef.current.currentWrapperWidth = newWrapperWidth;
+            updateWidths();
+        }
+    };
+
+    const StyleUtils = useStyleUtils();
+    const styles = useThemeStyles();
+    const reportPreviewStyles = StyleUtils.getMoneyRequestReportPreviewStyle(false, transactions.length, widths.currentWidth, widths.currentWrapperWidth);
+    const transactionPreviewContainerStyles = [styles.h100, reportPreviewStyles.transactionPreviewCarouselStyle];
+
+    const renderItem: ListRenderItem<Transaction> = ({item}) => (
+        <TransactionPreviewContent
+            action={actionR14932}
+            isWhisper={false}
+            isHovered={false}
+            chatReport={chatReportR14932}
+            personalDetails={personalDetails}
+            report={iouReportR14932}
+            transaction={item}
+            transactionRawAmount={item.amount}
+            violations={item.errors ? violationsR14932 : []}
+            offlineWithFeedbackOnClose={() => undefined}
+            navigateToReviewFields={() => undefined}
+            isBillSplit={false}
+            areThereDuplicates={false}
+            sessionAccountID={11111111}
+            walletTermsErrors={undefined}
+            routeName={SCREENS.TRANSACTION_DUPLICATE.REVIEW}
+            shouldHideOnDelete={false}
+            transactionPreviewWidth={reportPreviewStyles.transactionPreviewCarouselStyle.width}
+            containerStyles={transactionPreviewContainerStyles}
+        />
+    );
 
     return (
         <ThemeProvider theme={theme}>
@@ -141,9 +170,13 @@ function Template(props: MoneyRequestReportPreviewContentProps, {parameters}: {p
                 <View style={{maxWidth: '100%'}}>
                     <MoneyRequestReportPreviewContent
                         {...props}
-                        reportPreviewStyles={reportPreviewStyle}
-                        containerStyles={[reportPreviewStyle.componentStyle, props.containerStyles]}
+                        reportPreviewStyles={reportPreviewStyles}
+                        containerStyles={[reportPreviewStyles.componentStyle, props.containerStyles]}
                         transactions={transactions}
+                        onCarouselLayout={onCarouselLayout}
+                        onWrapperLayout={onWrapperLayout}
+                        currentWidth={widths.currentWidth}
+                        renderTransactionItem={renderItem}
                     />
                 </View>
             </ThemeStylesProvider>
diff --git a/src/stories/PromotedActionBar.stories.tsx b/src/stories/PromotedActionBar.stories.tsx
index f666d0f30f9..edb38b5e3d0 100644
--- a/src/stories/PromotedActionBar.stories.tsx
+++ b/src/stories/PromotedActionBar.stories.tsx
@@ -14,8 +14,7 @@ const story = {
     component: PromotedActionsBar,
 };
 
-type PromotedActionWithText = Omit<PromotedAction, 'translationKey'> & {text: string};
-type PromotedActionsBarPropsWithText = Omit<PromotedActionsBarProps, 'promotedActions'> & {promotedActions: PromotedActionWithText[]};
+type PromotedActionsBarPropsWithText = Omit<PromotedActionsBarProps, 'promotedActions'> & {promotedActions: PromotedAction[]};
 type StoryType = typeof Template & {args?: Partial<PromotedActionsBarPropsWithText>};
 
 function Template(args: PromotedActionsBarProps) {
@@ -30,29 +29,29 @@ const promotedActions = [
     {
         key: 'join',
         icon: 'CommentBubbles',
-        text: 'Join',
+        translationKey: 'common.message',
         onSelected: () => {},
     },
     {
         key: 'pin',
         icon: 'Pin',
-        text: 'Pin',
+        translationKey: 'common.pin',
         onSelected: () => {},
     },
     {
         key: 'share',
         icon: 'QrCode',
-        text: 'Share',
+        translationKey: 'common.share',
         onSelected: () => {},
     },
-] satisfies PromotedActionWithText[];
+] satisfies PromotedAction[];
 
 const defaultPromotedAction = {
     key: '',
     icon: 'ChatBubbles',
-    text: '',
+    translationKey: 'common.join',
     onSelected: () => {},
-} satisfies PromotedActionWithText;
+} satisfies PromotedAction;
 
 // Arguments can be passed to the component by binding
 // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
diff --git a/src/stories/TransactionItemRow.stories.tsx b/src/stories/TransactionItemRow.stories.tsx
old mode 100644
new mode 100755
index df870181890..c2f034710dc
--- a/src/stories/TransactionItemRow.stories.tsx
+++ b/src/stories/TransactionItemRow.stories.tsx
@@ -82,8 +82,8 @@ function Template(
 
     return (
         <ThemeProvider theme={theme}>
-            <ScreenWrapper testID="testID">
-                <ThemeStylesProvider>
+            <ThemeStylesProvider>
+                <ScreenWrapper testID="testID">
                     <TransactionItemRow
                         transactionItem={transactionItem}
                         shouldUseNarrowLayout={shouldUseNarrowLayout}
@@ -97,8 +97,8 @@ function Template(
                         columns={columns}
                         onButtonPress={() => {}}
                     />
-                </ThemeStylesProvider>
-            </ScreenWrapper>
+                </ScreenWrapper>
+            </ThemeStylesProvider>
         </ThemeProvider>
     );
 }
diff --git a/tests/unit/TransactionGroupListItemTest.tsx b/tests/unit/TransactionGroupListItemTest.tsx
index 448fdcae82b..2d725911a41 100644
--- a/tests/unit/TransactionGroupListItemTest.tsx
+++ b/tests/unit/TransactionGroupListItemTest.tsx
@@ -33,6 +33,7 @@ jest.mock('@react-navigation/native', () => ({
     useNavigation: () => ({
         navigate: jest.fn(),
         addListener: jest.fn(),
+        getState: jest.fn(() => undefined),
     }),
     useFocusEffect: jest.fn((callback: () => void) => callback()),
     useRoute: () => ({
