Files
react-native/packages/rn-tester/js/utils/RNTesterNavigationReducer.js
T
Kevin Gozali a47d7c54e8 Improved RNTester deeplink support to go straight to a specific example (#41981)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41981

Improved RNTester URL deeplink support to cover:
*  `rntester://example/<moduleKey>`
*  `rntester://example/<moduleKey>/<exampleKey>`

Extra details:
* For example modules that do not specify `showIndividualExamples: true`, allow deeplink URL with the specific exampleKey to only render the specific example, instead of all of them.
* Added flexibility for moduleKey: search for optional suffixes ("Index", "Example").
* Adjusted Back button action to properly go back to the root after a deeplink.
* Added `example-container` generic testID on the example wrapper component.

Changelog: [Internal]

Reviewed By: yungsters, NickGerleman

Differential Revision: D52227013

fbshipit-source-id: 4ba050592f39d6895f5124fa25c77f2d0199aa3f
2023-12-20 18:33:13 -08:00

130 lines
3.3 KiB
JavaScript

/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
import type {
ComponentList,
RNTesterNavigationState,
} from '../types/RNTesterTypes';
export const RNTesterNavigationActionsType = {
NAVBAR_PRESS: 'NAVBAR_PRESS',
BACK_BUTTON_PRESS: 'BACK_BUTTON_PRESS',
MODULE_CARD_PRESS: 'MODULE_CARD_PRESS',
EXAMPLE_CARD_PRESS: 'EXAMPLE_CARD_PRESS',
EXAMPLE_OPEN_URL_REQUEST: 'EXAMPLE_OPEN_URL_REQUEST',
};
const getUpdatedRecentlyUsed = ({
exampleType,
key,
recentlyUsed,
}: {
exampleType: 'apis' | 'components' | null,
key: string | null,
recentlyUsed: ComponentList,
}) => {
const updatedRecentlyUsed = recentlyUsed
? {...recentlyUsed}
: // $FlowFixMe[missing-empty-array-annot]
{components: [], apis: []};
if (!exampleType || !key) {
return updatedRecentlyUsed;
}
let existingKeys = updatedRecentlyUsed[exampleType];
if (existingKeys.includes(key)) {
existingKeys = existingKeys.filter(k => k !== key);
}
// $FlowFixMe[incompatible-call]
existingKeys.unshift(key);
updatedRecentlyUsed[exampleType] = existingKeys.slice(0, 5);
return updatedRecentlyUsed;
};
export const RNTesterNavigationReducer = (
state: RNTesterNavigationState,
action: {type: $Keys<typeof RNTesterNavigationActionsType>, data?: any},
): RNTesterNavigationState => {
const {
data: {
key = null,
title = null,
exampleKey = null,
exampleType = null,
screen = null,
} = {},
} = action;
switch (action.type) {
case RNTesterNavigationActionsType.NAVBAR_PRESS:
return {
...state,
activeModuleKey: null,
activeModuleTitle: null,
activeModuleExampleKey: null,
screen,
hadDeepLink: false,
};
case RNTesterNavigationActionsType.MODULE_CARD_PRESS:
return {
...state,
activeModuleKey: key,
activeModuleTitle: title,
activeModuleExampleKey: null,
// $FlowFixMe[incompatible-return]
recentlyUsed: getUpdatedRecentlyUsed({
exampleType: exampleType,
key: key,
recentlyUsed: state.recentlyUsed,
}),
};
case RNTesterNavigationActionsType.EXAMPLE_CARD_PRESS:
return {
...state,
activeModuleExampleKey: key,
};
case RNTesterNavigationActionsType.BACK_BUTTON_PRESS:
// Go back to module or list.
// If there was a deeplink navigation, pressing Back should bring us back to the root.
return {
...state,
activeModuleExampleKey: null,
activeModuleKey:
!state.hadDeepLink && state.activeModuleExampleKey != null
? state.activeModuleKey
: null,
activeModuleTitle:
!state.hadDeepLink && state.activeModuleExampleKey != null
? state.activeModuleTitle
: null,
hadDeepLink: false,
};
case RNTesterNavigationActionsType.EXAMPLE_OPEN_URL_REQUEST:
return {
...state,
activeModuleKey: key,
activeModuleTitle: title,
activeModuleExampleKey: exampleKey,
hadDeepLink: true,
};
default:
throw new Error(`Invalid action type ${action.type}`);
}
};