Closed siddharth-kt closed 2 years ago
Deleted old comment - I see you asked for a backport.
The current version (4+) does not have an official binding for react navigation but it works fine with RN6.
Here's how I'm using it, if this helps:
createCollapsibleTabNavigator.tsx
:
import {
createNavigatorFactory,
DefaultNavigatorOptions,
ParamListBase,
TabActionHelpers,
TabNavigationState,
TabRouter,
TabRouterOptions,
useNavigationBuilder,
} from '@react-navigation/native';
import * as React from 'react';
import {useRef} from 'react';
import {StyleSheet, View} from 'react-native';
import {CollapsibleRef, Tabs} from 'react-native-collapsible-tab-view';
import {TabName} from 'react-native-collapsible-tab-view/lib/typescript/types';
// Props accepted by the view
export type TabNavigationConfig = {
collapsibleOptions: Omit<
React.ComponentPropsWithoutRef<typeof Tabs['Container']>,
'children'
>;
};
// Supported screen options
type TabNavigationOptions = {
title?: string;
};
// Map of event name and the type of data (in event.data)
//
// canPreventDefault: true adds the defaultPrevented property to the
// emitted events.
type TabNavigationEventMap = {
tabPress: {
data: {isAlreadyFocused: boolean};
canPreventDefault?: true;
};
};
// The props accepted by the component is a combination of 3 things
type Props = DefaultNavigatorOptions<any, any, any, any> &
TabRouterOptions &
TabNavigationConfig;
function CollapsibleTabNavigator({
initialRouteName,
children,
screenOptions,
collapsibleOptions,
}: Props) {
const {state, navigation, descriptors} = useNavigationBuilder<
TabNavigationState<ParamListBase>,
TabRouterOptions,
TabActionHelpers<ParamListBase>,
TabNavigationOptions,
TabNavigationEventMap
>(TabRouter, {
children,
screenOptions,
initialRouteName,
});
const ref = useRef<CollapsibleRef<TabName>>();
const onTabChange = React.useCallback(
({tabName}) => {
navigation.emit({
type: 'tabPress',
target: tabName.toString(),
data: {
isAlreadyFocused:
tabName.toString() === state.routes[state.index].name,
},
});
},
[navigation, state.index, state.routes],
);
return (
<Tabs.Container
ref={ref}
{...collapsibleOptions}
initialTabName={state.routeNames[state.index]}
onTabChange={onTabChange}
>
{state.routes.map((route) => (
<Tabs.Tab
name={route.name}
key={route.key}
label={descriptors[route.key].options.title}
>
{descriptors[route.key].render()}
</Tabs.Tab>
))}
</Tabs.Container>
);
}
export default createNavigatorFactory<
TabNavigationState<ParamListBase>,
TabNavigationOptions,
TabNavigationEventMap,
typeof CollapsibleTabNavigator
>(CollapsibleTabNavigator);
Used like:
const Tab = createCollapsibleNavigator();
...
<Tab.Navigator collapsibleOptions={collapsibleOptions}>
<Tab.Screen name="screen1" options={{ title: "Screen1 }}>
{() => <Screen props={props} />}
useEffect(() => {
ref.current?.jumpToTab(state.routeNames[state.index]);
}, [state.index]);
@andreialecu you should also add this to make navigation to the tabs work
The current version (4+) does not have an official binding for react navigation but it works fine with RN6.
Here's how I'm using it, if this helps:
createCollapsibleTabNavigator.tsx
:import { createNavigatorFactory, DefaultNavigatorOptions, ParamListBase, TabActionHelpers, TabNavigationState, TabRouter, TabRouterOptions, useNavigationBuilder, } from '@react-navigation/native'; import * as React from 'react'; import {useRef} from 'react'; import {StyleSheet, View} from 'react-native'; import {CollapsibleRef, Tabs} from 'react-native-collapsible-tab-view'; import {TabName} from 'react-native-collapsible-tab-view/lib/typescript/types'; // Props accepted by the view export type TabNavigationConfig = { collapsibleOptions: Omit< React.ComponentPropsWithoutRef<typeof Tabs['Container']>, 'children' >; }; // Supported screen options type TabNavigationOptions = { title?: string; }; // Map of event name and the type of data (in event.data) // // canPreventDefault: true adds the defaultPrevented property to the // emitted events. type TabNavigationEventMap = { tabPress: { data: {isAlreadyFocused: boolean}; canPreventDefault?: true; }; }; // The props accepted by the component is a combination of 3 things type Props = DefaultNavigatorOptions<any, any, any, any> & TabRouterOptions & TabNavigationConfig; function CollapsibleTabNavigator({ initialRouteName, children, screenOptions, collapsibleOptions, }: Props) { const {state, navigation, descriptors} = useNavigationBuilder< TabNavigationState<ParamListBase>, TabRouterOptions, TabActionHelpers<ParamListBase>, TabNavigationOptions, TabNavigationEventMap >(TabRouter, { children, screenOptions, initialRouteName, }); const ref = useRef<CollapsibleRef<TabName>>(); const onTabChange = React.useCallback( ({tabName}) => { navigation.emit({ type: 'tabPress', target: tabName.toString(), data: { isAlreadyFocused: tabName.toString() === state.routes[state.index].name, }, }); }, [navigation, state.index, state.routes], ); return ( <Tabs.Container ref={ref} {...collapsibleOptions} initialTabName={state.routeNames[state.index]} onTabChange={onTabChange} > {state.routes.map((route) => ( <Tabs.Tab name={route.name} key={route.key} label={descriptors[route.key].options.title} > {descriptors[route.key].render()} </Tabs.Tab> ))} </Tabs.Container> ); } export default createNavigatorFactory< TabNavigationState<ParamListBase>, TabNavigationOptions, TabNavigationEventMap, typeof CollapsibleTabNavigator >(CollapsibleTabNavigator);
Used like:
const Tab = createCollapsibleNavigator(); ... <Tab.Navigator collapsibleOptions={collapsibleOptions}> <Tab.Screen name="screen1" options={{ title: "Screen1 }}> {() => <Screen props={props} />}
ok then 👍
Feature request
Hi @andreialecu @PedroBern, Kindly update https://github.com/PedroBern/react-native-collapsible-tab-view/tree/v2 to react-navigation version 6 and also add new updates/features to this (version 2.0.2) (if any) from latest version https://github.com/PedroBern/react-native-collapsible-tab-view. (4.4.0)
Current behavior
Currently it works on react-navigation version 5, but most people already shifted to react-navigation version 6.
Thanks