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 (