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
This commit is contained in:
Luna Wei 2021-07-01 14:33:45 -07:00 коммит произвёл Facebook GitHub Bot
Родитель 8765b93bae
Коммит c06d8d01ca
10 изменённых файлов: 73 добавлений и 14 удалений

Просмотреть файл

@ -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}
/>
<RNTesterModuleContainer module={activeModule} />
<RNTesterModuleContainer
module={activeModule}
example={activeModuleExample}
onExampleCardPress={handleModuleExampleCardPress}
/>
</View>
) : (
<ModuleListsContainer

Просмотреть файл

@ -37,8 +37,8 @@ export default function RNTPressableRow({
rightAddOn,
bottomAddOn,
onPress,
accessibilityLabel,
style,
accessibilityLabel,
}: Props): React.Node {
const theme = React.useContext(RNTesterThemeContext);
const label = accessibilityLabel ?? `${title} ${description ?? ''}`;

Просмотреть файл

@ -8,9 +8,11 @@
*/
const React = require('react');
const {Platform} = require('react-native');
const RNTesterBlock = require('./RNTesterBlock');
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
import RNTPressableRow from './RNTPressableRow';
import {RNTesterThemeContext} from './RNTesterTheme';
import {StyleSheet, Platform} from 'react-native';
const invariant = require('invariant');
import ExamplePage from './ExamplePage';
@ -30,7 +32,8 @@ function getExampleTitle(title, platform) {
}
export default function RNTesterModuleContainer(props: Props): React.Node {
const {module, example} = props;
const {module, example, onExampleCardPress} = props;
const theme = React.useContext(RNTesterThemeContext);
const renderExample = (e, i) => {
// 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 ? (
<RNTPressableRow
key={e.name}
onPress={() => onExampleCardPress(e.name)}
title={e.title}
description={description}
accessibilityLabel={e.name + ' ' + description}
style={StyleSheet.compose(styles.separator, {
borderBottomColor: theme.SeparatorColor,
})}
/>
) : (
<RNTesterBlock
key={i}
title={getExampleTitle(title, platform)}
@ -99,12 +113,7 @@ export default function RNTesterModuleContainer(props: Props): React.Node {
documentationURL={module.documentationURL}
category={module.category}>
{module.showIndividualExamples === true && example != null ? (
<RNTesterBlock
key={example.name}
title={getExampleTitle(example.title, example.platform)}
description={example.description}>
{example.render()}
</RNTesterBlock>
example.render()
) : (
<RNTesterExampleFilter
testID="example_search"
@ -120,3 +129,13 @@ export default function RNTesterModuleContainer(props: Props): React.Node {
</ExamplePage>
);
}
const styles = StyleSheet.create({
separator: {
borderBottomWidth: Platform.select({
ios: StyleSheet.hairlineWidth,
android: 0,
}),
marginHorizontal: Platform.select({ios: 15, android: 0}),
},
});

Просмотреть файл

@ -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<typeof SectionList_onEndReached> {
return <SectionList_onEndReached />;
},

Просмотреть файл

@ -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,
> {

Просмотреть файл

@ -129,7 +129,7 @@ const styles = StyleSheet.create({
height: 40,
},
output: {
width: '80%',
flex: 1,
fontSize: 12,
},
list: {

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -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}`);

Просмотреть файл

@ -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: []},