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,
]}
>
-
+
+
+
),
];
@@ -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('');
return (
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 (