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:
Родитель
8765b93bae
Коммит
c06d8d01ca
|
@ -111,7 +111,13 @@ const RNTesterApp = (): React.Node => {
|
||||||
);
|
);
|
||||||
const colorScheme = useColorScheme();
|
const colorScheme = useColorScheme();
|
||||||
|
|
||||||
const {activeModuleKey, screen, bookmarks, recentlyUsed} = state;
|
const {
|
||||||
|
activeModuleKey,
|
||||||
|
activeModuleExampleKey,
|
||||||
|
screen,
|
||||||
|
bookmarks,
|
||||||
|
recentlyUsed,
|
||||||
|
} = state;
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
getInitialStateFromAsyncStorage(APP_STATE_KEY).then(
|
getInitialStateFromAsyncStorage(APP_STATE_KEY).then(
|
||||||
|
@ -166,6 +172,16 @@ const RNTesterApp = (): React.Node => {
|
||||||
[dispatch],
|
[dispatch],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleModuleExampleCardPress = React.useCallback(
|
||||||
|
exampleName => {
|
||||||
|
dispatch({
|
||||||
|
type: RNTesterActionsType.EXAMPLE_CARD_PRESS,
|
||||||
|
data: {key: exampleName},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
const toggleBookmark = React.useCallback(
|
const toggleBookmark = React.useCallback(
|
||||||
({exampleType, key}) => {
|
({exampleType, key}) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -194,6 +210,10 @@ const RNTesterApp = (): React.Node => {
|
||||||
|
|
||||||
const activeModule =
|
const activeModule =
|
||||||
activeModuleKey != null ? RNTesterList.Modules[activeModuleKey] : null;
|
activeModuleKey != null ? RNTesterList.Modules[activeModuleKey] : null;
|
||||||
|
const activeModuleExample =
|
||||||
|
activeModuleExampleKey != null
|
||||||
|
? activeModule?.examples.find(e => e.name === activeModuleExampleKey)
|
||||||
|
: null;
|
||||||
const title = Screens.COMPONENTS
|
const title = Screens.COMPONENTS
|
||||||
? 'Components'
|
? 'Components'
|
||||||
: Screens.APIS
|
: Screens.APIS
|
||||||
|
@ -210,7 +230,11 @@ const RNTesterApp = (): React.Node => {
|
||||||
theme={theme}
|
theme={theme}
|
||||||
documentationURL={activeModule.documentationURL}
|
documentationURL={activeModule.documentationURL}
|
||||||
/>
|
/>
|
||||||
<RNTesterModuleContainer module={activeModule} />
|
<RNTesterModuleContainer
|
||||||
|
module={activeModule}
|
||||||
|
example={activeModuleExample}
|
||||||
|
onExampleCardPress={handleModuleExampleCardPress}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<ModuleListsContainer
|
<ModuleListsContainer
|
||||||
|
|
|
@ -37,8 +37,8 @@ export default function RNTPressableRow({
|
||||||
rightAddOn,
|
rightAddOn,
|
||||||
bottomAddOn,
|
bottomAddOn,
|
||||||
onPress,
|
onPress,
|
||||||
accessibilityLabel,
|
|
||||||
style,
|
style,
|
||||||
|
accessibilityLabel,
|
||||||
}: Props): React.Node {
|
}: Props): React.Node {
|
||||||
const theme = React.useContext(RNTesterThemeContext);
|
const theme = React.useContext(RNTesterThemeContext);
|
||||||
const label = accessibilityLabel ?? `${title} ${description ?? ''}`;
|
const label = accessibilityLabel ?? `${title} ${description ?? ''}`;
|
||||||
|
|
|
@ -8,9 +8,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const {Platform} = require('react-native');
|
|
||||||
const RNTesterBlock = require('./RNTesterBlock');
|
const RNTesterBlock = require('./RNTesterBlock');
|
||||||
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
|
const RNTesterExampleFilter = require('./RNTesterExampleFilter');
|
||||||
|
import RNTPressableRow from './RNTPressableRow';
|
||||||
|
import {RNTesterThemeContext} from './RNTesterTheme';
|
||||||
|
import {StyleSheet, Platform} from 'react-native';
|
||||||
|
|
||||||
const invariant = require('invariant');
|
const invariant = require('invariant');
|
||||||
import ExamplePage from './ExamplePage';
|
import ExamplePage from './ExamplePage';
|
||||||
|
@ -30,7 +32,8 @@ function getExampleTitle(title, platform) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RNTesterModuleContainer(props: Props): React.Node {
|
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) => {
|
const renderExample = (e, i) => {
|
||||||
// Filter platform-specific es
|
// Filter platform-specific es
|
||||||
const {description, platform} = e;
|
const {description, platform} = e;
|
||||||
|
@ -38,7 +41,18 @@ export default function RNTesterModuleContainer(props: Props): React.Node {
|
||||||
if (platform != null && Platform.OS !== platform) {
|
if (platform != null && Platform.OS !== platform) {
|
||||||
return null;
|
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
|
<RNTesterBlock
|
||||||
key={i}
|
key={i}
|
||||||
title={getExampleTitle(title, platform)}
|
title={getExampleTitle(title, platform)}
|
||||||
|
@ -99,12 +113,7 @@ export default function RNTesterModuleContainer(props: Props): React.Node {
|
||||||
documentationURL={module.documentationURL}
|
documentationURL={module.documentationURL}
|
||||||
category={module.category}>
|
category={module.category}>
|
||||||
{module.showIndividualExamples === true && example != null ? (
|
{module.showIndividualExamples === true && example != null ? (
|
||||||
<RNTesterBlock
|
example.render()
|
||||||
key={example.name}
|
|
||||||
title={getExampleTitle(example.title, example.platform)}
|
|
||||||
description={example.description}>
|
|
||||||
{example.render()}
|
|
||||||
</RNTesterBlock>
|
|
||||||
) : (
|
) : (
|
||||||
<RNTesterExampleFilter
|
<RNTesterExampleFilter
|
||||||
testID="example_search"
|
testID="example_search"
|
||||||
|
@ -120,3 +129,13 @@ export default function RNTesterModuleContainer(props: Props): React.Node {
|
||||||
</ExamplePage>
|
</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 {
|
export default {
|
||||||
title: 'SectionList Inverted',
|
title: 'SectionList Inverted',
|
||||||
name: 'SectionList-onEndReached',
|
name: 'SectionList-onEndReached',
|
||||||
|
description: 'Test onEndReached behavior',
|
||||||
render: function(): React.Element<typeof SectionList_onEndReached> {
|
render: function(): React.Element<typeof SectionList_onEndReached> {
|
||||||
return <SectionList_onEndReached />;
|
return <SectionList_onEndReached />;
|
||||||
},
|
},
|
||||||
|
|
|
@ -44,6 +44,7 @@ export function SectionList_stickySectionHeadersEnabled(): React.Node {
|
||||||
export default {
|
export default {
|
||||||
title: 'SectionList Sticky Headers Enabled',
|
title: 'SectionList Sticky Headers Enabled',
|
||||||
name: 'SectionList-stickyHeadersEnabled',
|
name: 'SectionList-stickyHeadersEnabled',
|
||||||
|
description: 'Toggle sticky headers on/off',
|
||||||
render: function(): React.Element<
|
render: function(): React.Element<
|
||||||
typeof SectionList_stickySectionHeadersEnabled,
|
typeof SectionList_stickySectionHeadersEnabled,
|
||||||
> {
|
> {
|
||||||
|
|
|
@ -129,7 +129,7 @@ const styles = StyleSheet.create({
|
||||||
height: 40,
|
height: 40,
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
width: '80%',
|
flex: 1,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
|
|
|
@ -22,6 +22,7 @@ exports.title = 'SectionList';
|
||||||
exports.category = 'ListView';
|
exports.category = 'ListView';
|
||||||
exports.documentationURL = 'https://reactnative.dev/docs/sectionlist';
|
exports.documentationURL = 'https://reactnative.dev/docs/sectionlist';
|
||||||
exports.description = 'Performant, scrollable list of data.';
|
exports.description = 'Performant, scrollable list of data.';
|
||||||
|
exports.showIndividualExamples = true;
|
||||||
exports.examples = [
|
exports.examples = [
|
||||||
ContentInset,
|
ContentInset,
|
||||||
onEndReached,
|
onEndReached,
|
||||||
|
|
|
@ -61,6 +61,7 @@ export type ComponentList = null | {components: string[], apis: string[]};
|
||||||
|
|
||||||
export type RNTesterState = {
|
export type RNTesterState = {
|
||||||
activeModuleKey: null | string,
|
activeModuleKey: null | string,
|
||||||
|
activeModuleExampleKey: null | string,
|
||||||
screen: ScreenTypes,
|
screen: ScreenTypes,
|
||||||
bookmarks: ComponentList,
|
bookmarks: ComponentList,
|
||||||
recentlyUsed: ComponentList,
|
recentlyUsed: ComponentList,
|
||||||
|
|
|
@ -16,6 +16,7 @@ export const RNTesterActionsType = {
|
||||||
BOOKMARK_PRESS: 'BOOKMARK_PRESS',
|
BOOKMARK_PRESS: 'BOOKMARK_PRESS',
|
||||||
BACK_BUTTON_PRESS: 'BACK_BUTTON_PRESS',
|
BACK_BUTTON_PRESS: 'BACK_BUTTON_PRESS',
|
||||||
MODULE_CARD_PRESS: 'MODULE_CARD_PRESS',
|
MODULE_CARD_PRESS: 'MODULE_CARD_PRESS',
|
||||||
|
EXAMPLE_CARD_PRESS: 'EXAMPLE_CARD_PRESS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const getUpdatedBookmarks = ({
|
const getUpdatedBookmarks = ({
|
||||||
|
@ -77,18 +78,25 @@ export const RNTesterReducer = (
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
activeModuleKey: null,
|
activeModuleKey: null,
|
||||||
|
activeModuleExampleKey: null,
|
||||||
screen: action.data.screen,
|
screen: action.data.screen,
|
||||||
};
|
};
|
||||||
case RNTesterActionsType.MODULE_CARD_PRESS:
|
case RNTesterActionsType.MODULE_CARD_PRESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
activeModuleKey: action.data.key,
|
activeModuleKey: action.data.key,
|
||||||
|
activeModuleExampleKey: null,
|
||||||
recentlyUsed: getUpdatedRecentlyUsed({
|
recentlyUsed: getUpdatedRecentlyUsed({
|
||||||
exampleType: action.data.exampleType,
|
exampleType: action.data.exampleType,
|
||||||
key: action.data.key,
|
key: action.data.key,
|
||||||
recentlyUsed: state.recentlyUsed,
|
recentlyUsed: state.recentlyUsed,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
case RNTesterActionsType.EXAMPLE_CARD_PRESS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
activeModuleExampleKey: action.data.key,
|
||||||
|
};
|
||||||
case RNTesterActionsType.BOOKMARK_PRESS:
|
case RNTesterActionsType.BOOKMARK_PRESS:
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -102,7 +110,9 @@ export const RNTesterReducer = (
|
||||||
// Go back to module or list
|
// Go back to module or list
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
activeModuleKey: null,
|
activeModuleExampleKey: null,
|
||||||
|
activeModuleKey:
|
||||||
|
state.activeModuleExampleKey != null ? state.activeModuleKey : null,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
throw new Error(`Invalid action type ${action.type}`);
|
throw new Error(`Invalid action type ${action.type}`);
|
||||||
|
|
|
@ -26,6 +26,7 @@ export const Screens = {
|
||||||
|
|
||||||
export const initialState: RNTesterState = {
|
export const initialState: RNTesterState = {
|
||||||
activeModuleKey: null,
|
activeModuleKey: null,
|
||||||
|
activeModuleExampleKey: null,
|
||||||
screen: null,
|
screen: null,
|
||||||
bookmarks: null,
|
bookmarks: null,
|
||||||
recentlyUsed: null,
|
recentlyUsed: null,
|
||||||
|
@ -134,6 +135,7 @@ export const getInitialStateFromAsyncStorage = async (
|
||||||
if (!initialStateString) {
|
if (!initialStateString) {
|
||||||
return {
|
return {
|
||||||
activeModuleKey: null,
|
activeModuleKey: null,
|
||||||
|
activeModuleExampleKey: null,
|
||||||
screen: Screens.COMPONENTS,
|
screen: Screens.COMPONENTS,
|
||||||
bookmarks: {components: [], apis: []},
|
bookmarks: {components: [], apis: []},
|
||||||
recentlyUsed: {components: [], apis: []},
|
recentlyUsed: {components: [], apis: []},
|
||||||
|
|
Загрузка…
Ссылка в новой задаче