0

I have a fairly simple React Native app that I am using to showcase a custom component library. I recently upgraded the app from React Native version 0.67.2 to 0.70.6. React Navigation is still on version 5.x (latest is 6.x). My issue is that when I attempt to open my navigation drawer, I see a shadow over my home screen, but the drawer does not appear. The ellipsis menu also fails to appear.

Here is the home screen on app load:

Home screen on app load

Here is the home screen when I tap the hamburger menu:

Home screen with drawer open

I have narrowed down the problem to my custom header component. When I comment out the Actions in the header, including the children, the drawer works.

Here is the home page:

HomeStack.tsx:

import { CustomHeader } from '@custom-components/Header';
import { createStackNavigator } from '@react-navigation/stack';
import React from 'react';
import { Appbar, Menu, Divider, useTheme } from 'react-native-paper';
import { HomeScreen } from '../screens';

const Stack = createStackNavigator();

const HomeStack = (): JSX.Element => {

  const theme: ReactNativePaper.Theme = useTheme();
  const [isMenuVisible, setMenuVisible] = React.useState(false);
  const openMenu = () => setMenuVisible(true);
  const closeMenu = () => setMenuVisible(false);

  return (
    <Stack.Navigator
      headerMode="float"
      screenOptions={{
        header: () => (
          <CustomHeader title="Home">
            <Menu
              visible={isMenuVisible}
              onDismiss={closeMenu}
              anchor={
                <Appbar.Action
                  icon="dots-vertical"
                  testID="header-action-1"
                  touchSoundDisabled={false}
                  onPress={openMenu}
                  color={theme.colors.text}
                />
              }
            >
              <Menu.Item onPress={() => {}} title="Item 1" />
              <Menu.Item onPress={() => {}} title="Item 2" />
              <Menu.Item onPress={() => {}} title="Item 3" />
            </Menu>
          </CustomHeader>
        ),
      }}
    >
      <Stack.Screen name="Home" component={HomeScreen} />
    </Stack.Navigator>
  );
};

export default HomeStack;

And the header:

CustomHeader.tsx

import { DrawerActions, useNavigation } from '@react-navigation/native';
import React from 'react';
import { Platform, StyleSheet, View } from 'react-native';
import { Appbar, useTheme } from 'react-native-paper';
import { common } from '../theme/colors';

export type CustomHeaderProps = {
  title: string;
  subtitle?: string;
  scaleMenuIcon?: number;
  headerHeight?: number;
  titleSize?: number;
  subtitleSize?: number;
  children?: React.ReactNode;
  backgroundColor?: string;
  color?: string;
};

export const CustomHeader = ({
  title,
  subtitle,
  scaleMenuIcon,
  titleSize = 20,
  subtitleSize = 15,
  headerHeight,
  children,
  backgroundColor = common.offWhite,
  color = common.black,
}: CustomHeaderProps): JSX.Element => {
  const navigation = useNavigation();

  const theme = useTheme();

  const openMenu = () => {
    navigation.dispatch(DrawerActions.openDrawer());
  };

  return (
    <Appbar.Header style={
      backgroundColor: theme.dark ? undefined : backgroundColor,
      height: headerHeight
      }>
      <Appbar.Action
        icon="menu"
        testID="header-button"
        style={styles.menuIcon}
        onPress={openMenu}
        touchSoundDisabled={true}
        size={scaleMenuIcon}
        color={theme.dark ? undefined : color}
      />
      <Appbar.Content
        testID="appbar-content"
        color={theme.dark ? undefined : color}
        style={styles.headerText}
        title={title}
        titleStyle={{ fontSize: titleSize }}
        subtitle={subtitle}
        subtitleStyle={{ fontSize: subtitleSize }}
      />

      // If I comment out this View, the drawer appears.
      <View style={styles.headerImageText}>
        {children && (
          <View testID="appbar-actions" style={styles.children}>
            {children}
          </View>
        )}
      </View>

    </Appbar.Header>
  );
};

const styles = StyleSheet.create({
  children: {
    flexDirection: 'row',
    justifyContent: 'flex-end',
    paddingRight: 30,
    ...Platform.select({
      ios: {
        left: -10,
      },
      android: {
        left: 0,
      },
    }),
  },
  headerImageText: {
    alignItems: 'center',
    flexDirection: 'row',
    justifyContent: 'flex-start',
    paddingLeft: 10,
  },
  headerText: {
    flexGrow: 6,
    flexShrink: 1,
    fontSize: 20,
    fontWeight: 'bold',
    justifyContent: 'center',
    left: -10,
    letterSpacing: 1,
  },
  menuIcon: {
    left: 10,
  },
});
GreatDane
  • 23
  • 5

0 Answers0