From c06d8d01ca774ad55b4bb9982093a6ce3fac524f Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Thu, 1 Jul 2021 14:33:45 -0700 Subject: [PATCH] Support 3 levels of navigation Summary: Changelog: [Internal] RNTester to support 3 levels of navigation Reviewed By: kacieb Differential Revision: D29481463 fbshipit-source-id: e48281cce7fccd7096446c5f0f5583f2588b5028 --- packages/rn-tester/js/RNTesterAppShared.js | 28 +++++++++++++- .../js/components/RNTPressableRow.js | 2 +- .../js/components/RNTesterModuleContainer.js | 37 ++++++++++++++----- .../SectionList/SectionList-onEndReached.js | 1 + .../SectionList-stickyHeadersEnabled.js | 1 + .../SectionList/SectionListBaseExample.js | 2 +- .../examples/SectionList/SectionListIndex.js | 1 + packages/rn-tester/js/types/RNTesterTypes.js | 1 + .../rn-tester/js/utils/RNTesterReducer.js | 12 +++++- .../rn-tester/js/utils/testerStateUtils.js | 2 + 10 files changed, 73 insertions(+), 14 deletions(-) diff --git a/packages/rn-tester/js/RNTesterAppShared.js b/packages/rn-tester/js/RNTesterAppShared.js index de690b0856..a4ee14027c 100644 --- a/packages/rn-tester/js/RNTesterAppShared.js +++ b/packages/rn-tester/js/RNTesterAppShared.js @@ -111,7 +111,13 @@ const RNTesterApp = (): React.Node => { ); const colorScheme = useColorScheme(); - const {activeModuleKey, screen, bookmarks, recentlyUsed} = state; + const { + activeModuleKey, + activeModuleExampleKey, + screen, + bookmarks, + recentlyUsed, + } = state; React.useEffect(() => { getInitialStateFromAsyncStorage(APP_STATE_KEY).then( @@ -166,6 +172,16 @@ const RNTesterApp = (): React.Node => { [dispatch], ); + const handleModuleExampleCardPress = React.useCallback( + exampleName => { + dispatch({ + type: RNTesterActionsType.EXAMPLE_CARD_PRESS, + data: {key: exampleName}, + }); + }, + [dispatch], + ); + const toggleBookmark = React.useCallback( ({exampleType, key}) => { dispatch({ @@ -194,6 +210,10 @@ const RNTesterApp = (): React.Node => { const activeModule = activeModuleKey != null ? RNTesterList.Modules[activeModuleKey] : null; + const activeModuleExample = + activeModuleExampleKey != null + ? activeModule?.examples.find(e => e.name === activeModuleExampleKey) + : null; const title = Screens.COMPONENTS ? 'Components' : Screens.APIS @@ -210,7 +230,11 @@ const RNTesterApp = (): React.Node => { theme={theme} documentationURL={activeModule.documentationURL} /> - + ) : ( { // Filter platform-specific es const {description, platform} = e; @@ -38,7 +41,18 @@ export default function RNTesterModuleContainer(props: Props): React.Node { if (platform != null && Platform.OS !== platform) { return null; } - return ( + return module.showIndividualExamples === true ? ( + onExampleCardPress(e.name)} + title={e.title} + description={description} + accessibilityLabel={e.name + ' ' + description} + style={StyleSheet.compose(styles.separator, { + borderBottomColor: theme.SeparatorColor, + })} + /> + ) : ( {module.showIndividualExamples === true && example != null ? ( - - {example.render()} - + example.render() ) : ( ); } + +const styles = StyleSheet.create({ + separator: { + borderBottomWidth: Platform.select({ + ios: StyleSheet.hairlineWidth, + android: 0, + }), + marginHorizontal: Platform.select({ios: 15, android: 0}), + }, +}); diff --git a/packages/rn-tester/js/examples/SectionList/SectionList-onEndReached.js b/packages/rn-tester/js/examples/SectionList/SectionList-onEndReached.js index a8ba954947..79e3f0218a 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionList-onEndReached.js +++ b/packages/rn-tester/js/examples/SectionList/SectionList-onEndReached.js @@ -39,6 +39,7 @@ export function SectionList_onEndReached(): React.Node { export default { title: 'SectionList Inverted', name: 'SectionList-onEndReached', + description: 'Test onEndReached behavior', render: function(): React.Element { return ; }, diff --git a/packages/rn-tester/js/examples/SectionList/SectionList-stickyHeadersEnabled.js b/packages/rn-tester/js/examples/SectionList/SectionList-stickyHeadersEnabled.js index a7e602b555..6335382004 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionList-stickyHeadersEnabled.js +++ b/packages/rn-tester/js/examples/SectionList/SectionList-stickyHeadersEnabled.js @@ -44,6 +44,7 @@ export function SectionList_stickySectionHeadersEnabled(): React.Node { export default { title: 'SectionList Sticky Headers Enabled', name: 'SectionList-stickyHeadersEnabled', + description: 'Toggle sticky headers on/off', render: function(): React.Element< typeof SectionList_stickySectionHeadersEnabled, > { diff --git a/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js b/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js index 4f50a5393e..9989483b1d 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js +++ b/packages/rn-tester/js/examples/SectionList/SectionListBaseExample.js @@ -129,7 +129,7 @@ const styles = StyleSheet.create({ height: 40, }, output: { - width: '80%', + flex: 1, fontSize: 12, }, list: { diff --git a/packages/rn-tester/js/examples/SectionList/SectionListIndex.js b/packages/rn-tester/js/examples/SectionList/SectionListIndex.js index f8fad29e1f..b5a4231bd3 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionListIndex.js +++ b/packages/rn-tester/js/examples/SectionList/SectionListIndex.js @@ -22,6 +22,7 @@ exports.title = 'SectionList'; exports.category = 'ListView'; exports.documentationURL = 'https://reactnative.dev/docs/sectionlist'; exports.description = 'Performant, scrollable list of data.'; +exports.showIndividualExamples = true; exports.examples = [ ContentInset, onEndReached, diff --git a/packages/rn-tester/js/types/RNTesterTypes.js b/packages/rn-tester/js/types/RNTesterTypes.js index 8f09b55883..af46c2554e 100644 --- a/packages/rn-tester/js/types/RNTesterTypes.js +++ b/packages/rn-tester/js/types/RNTesterTypes.js @@ -61,6 +61,7 @@ export type ComponentList = null | {components: string[], apis: string[]}; export type RNTesterState = { activeModuleKey: null | string, + activeModuleExampleKey: null | string, screen: ScreenTypes, bookmarks: ComponentList, recentlyUsed: ComponentList, diff --git a/packages/rn-tester/js/utils/RNTesterReducer.js b/packages/rn-tester/js/utils/RNTesterReducer.js index cd32905baf..b4edec7946 100644 --- a/packages/rn-tester/js/utils/RNTesterReducer.js +++ b/packages/rn-tester/js/utils/RNTesterReducer.js @@ -16,6 +16,7 @@ export const RNTesterActionsType = { BOOKMARK_PRESS: 'BOOKMARK_PRESS', BACK_BUTTON_PRESS: 'BACK_BUTTON_PRESS', MODULE_CARD_PRESS: 'MODULE_CARD_PRESS', + EXAMPLE_CARD_PRESS: 'EXAMPLE_CARD_PRESS', }; const getUpdatedBookmarks = ({ @@ -77,18 +78,25 @@ export const RNTesterReducer = ( return { ...state, activeModuleKey: null, + activeModuleExampleKey: null, screen: action.data.screen, }; case RNTesterActionsType.MODULE_CARD_PRESS: return { ...state, activeModuleKey: action.data.key, + activeModuleExampleKey: null, recentlyUsed: getUpdatedRecentlyUsed({ exampleType: action.data.exampleType, key: action.data.key, recentlyUsed: state.recentlyUsed, }), }; + case RNTesterActionsType.EXAMPLE_CARD_PRESS: + return { + ...state, + activeModuleExampleKey: action.data.key, + }; case RNTesterActionsType.BOOKMARK_PRESS: return { ...state, @@ -102,7 +110,9 @@ export const RNTesterReducer = ( // Go back to module or list return { ...state, - activeModuleKey: null, + activeModuleExampleKey: null, + activeModuleKey: + state.activeModuleExampleKey != null ? state.activeModuleKey : null, }; default: throw new Error(`Invalid action type ${action.type}`); diff --git a/packages/rn-tester/js/utils/testerStateUtils.js b/packages/rn-tester/js/utils/testerStateUtils.js index fe5b5d6940..fba305784b 100644 --- a/packages/rn-tester/js/utils/testerStateUtils.js +++ b/packages/rn-tester/js/utils/testerStateUtils.js @@ -26,6 +26,7 @@ export const Screens = { export const initialState: RNTesterState = { activeModuleKey: null, + activeModuleExampleKey: null, screen: null, bookmarks: null, recentlyUsed: null, @@ -134,6 +135,7 @@ export const getInitialStateFromAsyncStorage = async ( if (!initialStateString) { return { activeModuleKey: null, + activeModuleExampleKey: null, screen: Screens.COMPONENTS, bookmarks: {components: [], apis: []}, recentlyUsed: {components: [], apis: []},