Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Header not showing #16

Closed
alexpchin opened this issue Dec 3, 2020 · 17 comments
Closed

Header not showing #16

alexpchin opened this issue Dec 3, 2020 · 17 comments
Labels
bug Something isn't working

Comments

@alexpchin
Copy link
Contributor

I've just tried to implement the basic example but the header isn't displaying? I'm on:

"react-native": "0.63.3"

Using:

  const [index, setIndex] = useState(0);

  const [routes] = useState([
    { key: 'first', title: 'First' },
    { key: 'second', title: 'Second' },
  ]);

  const _renderHeader = () => (
    <View style={styles.header}>
      <Text style={styles.headerText}>COLLAPSIBLE</Text>
    </View>
  );

  const _onTabPress = (tabProps) => {
    tabProps.jumpTo(tabProps.route.key);
  };

  const _renderTabBar = (props) => {
    return <TabBar {...props} onTabPress={_onTabPress} />;
  };

  return (
    <CollapsibleTabView
      navigationState={{ index, routes }}
      onIndexChange={setIndex}
      renderHeader={_renderHeader}
      renderScene={SceneMap({
        first: () => null,
        second: () => null,
      })}
      renderTabBar={_renderTabBar}
    />
  );

Any ideas?

@alexpchin alexpchin added the bug Something isn't working label Dec 3, 2020
@alexpchin
Copy link
Contributor Author

It seems like you should include the header in renderTabBar?

const [index, setIndex] = useState(0);

  const [routes] = useState([
    {
      icon: (
        <FontAwesomeIcon
          color={C.COLOR_BLACK}
          icon={['fab', 'apple']}
          size={20}
          style={styles.iconStyle}
        />
      ),
      key: 'first',
      title: 'First',
    },
    { key: 'second', title: 'Second' },
  ]);

  const _renderHeader = (props) => (
    <>
      <View style={styles.header}>
        <Text style={styles.headerText}>COLLAPSIBLE</Text>
      </View>
      <TabBar {...props} onTabPress={_onTabPress} />
    </>
  );

  const _onTabPress = (tabProps) => {
    tabProps.jumpTo(tabProps.route.key);
  };

  return (
    <CollapsibleTabView
      navigationState={{ index, routes }}
      onIndexChange={setIndex}
      renderScene={SceneMap({
        first: () => <SomeRoute color="white" routeKey="first" />,
        second: () => <SomeRoute color="black" routeKey="second" />,
      })}
      renderTabBar={_renderHeader}
    />
  );

@PedroBern
Copy link
Owner

Hi @alexpchin no, the header shouldn't be included in the tab bar.

Did you forget to add the styles? Assuming you are copying from the quick start example in the readme.

const styles = StyleSheet.create({
  header: {
    height: HEADER_HEIGHT,
    backgroundColor: '#2196f3',
    justifyContent: 'center',
    alignItems: 'center',
    elevation: 4,
  },
  headerText: {
    color: 'white',
    fontSize: 24,
  },
  content: {
    height: 1500,
  },
});

@PedroBern PedroBern added invalid This doesn't seem right and removed bug Something isn't working labels Dec 3, 2020
@alexpchin
Copy link
Contributor Author

alexpchin commented Dec 4, 2020

Hi @PedroBern I do appreciate that this issue seems like I haven't followed the installation instructions... I promise I'm not simple ;) I am adding to an existing react-native application.

Firstly, to get up and running I had to install @react-navigation/material-top-tabs. Whilst I do have react-navigation running in the project, it seemed from the README that you only had to do this if you were integrating with react-navigation rather than just using the component on a screen.

I will investigate further and perhaps create a demo to share on CodeSandbox or something.

Question - If the content of one of the tabs is shorter than the other, are the tabs meant to stick at the top?

Thanks,
Alex

@alexpchin
Copy link
Contributor Author

FYI, a small update. The issue is when you omit the headerHeight which the docs say is optional. I checked the code in your example. If you comment out CollapsibleTabViewDemoExample, you will see the issue I was facing.

return (
    <CollapsibleTabView
      // headerHeight={HEADER_HEIGHT} // optional, will be computed.
      navigationState={{ index, routes }}
      onIndexChange={handleIndexChange}
      renderHeader={renderHeader}
      renderScene={renderScene} 
    />
  );

Thanks!

@PedroBern
Copy link
Owner

FYI, a small update. The issue is when you omit the headerHeight which the docs say is optional. I checked the code in your example. If you comment out CollapsibleTabViewDemoExample, you will see the issue I was facing.

That's weird, it does not happen here. I've just commented out, I get the same behavior as before.

Question - If the content of one of the tabs is shorter than the other, are the tabs meant to stick at the top?

Do you mean the tab or the screen of the tab? If you have a tab screen smaller than the window, you can see small content example.

I will investigate further and perhaps create a demo to share on CodeSandbox or something.

Perfect, if can do that I appreciate :)

@alexpchin
Copy link
Contributor Author

alexpchin commented Dec 4, 2020

Thank you for the heads up on the small content example.

So far my steps:

  • I forked the repo.
  • Loaded the packages in example with yarn.
  • Ran the example using ios simulator. (Everything worked ok).
  • Commented out the line about headerHeight which causes the header not to appear.

Interestingly, the header works fine if the value is:

headerHeight={1}

The line in CollapsibleTabView:

{headerHeight > 0 && renderHeader()}

If the default headerHeight is 0 and there is no headerHeight provided by props, if renderHeader has been provided then a header will render, if not then you'll render null... So can you not just omit this check?

{renderHeader()}

This will display the header, but it seems like the scrollY then stops working.

Please let me know if you follow the same steps and you do not replicate what I am seeing on CollapsibleabViewDemoExample.tsx.

UPDATE

When logging out the header, it seemed like the header was initially -1. Checking:

{!!headerHeight && renderHeader()}

Seems to resolve. Looking into why it's initially -1.

UPDATE2

Could this be because in TabBarItem in react-native-tab-view the styling for item is:

item: {
  flex: 1,
  alignItems: 'center',
  justifyContent: 'center',
  padding: 10,
  minHeight: 48,
},

TabBar height in this package is 49, which would give -1 (48-49) ?

@PedroBern PedroBern added triage and removed invalid This doesn't seem right labels Dec 4, 2020
@PedroBern
Copy link
Owner

PedroBern commented Dec 4, 2020

Thank you for the heads up on the small content example.

It will be handled inside the package in the next release with #17. EDIT: shipped in v1.3.0

Regardings the header height, I will check it today and come back here.

@PedroBern
Copy link
Owner

PedroBern commented Dec 4, 2020

UPDATE2 ...

The 48 is the minHeight. You can check the real tabBarHeight with the following code in your fork. We need to chose between computing the real tabBarHeight or headerHeight onLayout, we can't guess both, only if one of then is provided, in this case, I choose to always have tabBarHeight, allowing to render a header without up front height.

Add this to your fork, in the CollapsibleTabView.tsx.

const getHeaderHeight = React.useCallback(
    (event: LayoutChangeEvent) => {
      const value = event.nativeEvent.layout.height - tabBarHeight;
      // 250 is the header height from the example. It will log the real tabBarHeight, around 49.xx
      console.log(event.nativeEvent.layout.height - 250)
      ....

@alexpchin
Copy link
Contributor Author

@PedroBern Thanks for replying so quickly.

If I do pass in the headerHeight={HEADER_HEIGHT} in the example, where headerHeight is 250 and then use the code:

console.log(event.nativeEvent.layout.height - 250)

This logs out 48. What do you get?

Have you managed to replicate my initial problem, where not providing a headerHeight means that the header does not render?

PedroBern added a commit that referenced this issue Dec 4, 2020
@PedroBern
Copy link
Owner

PedroBern commented Dec 4, 2020

I get 49.428558349609375.

Check out #18, at any moment the preview will be ready. Or see the code and try to implement by yourself to see if works. I don't have access to iOS simulator right now, so I couldn't tell.

EDIT: see the no upfront height example

EDIT: I will wait your response to merge and release it.

@alexpchin
Copy link
Contributor Author

Hi @PedroBern Thanks! I've just fetched #18 and the problem still occurs. I will look at a possible solution now.

@PedroBern
Copy link
Owner

@alexpchin thanks, please if you solve share it here or open a PR :)

@alexpchin
Copy link
Contributor Author

Hello @PedroBern From what I can tell, I think this is working:

const getHeaderHeight = React.useCallback(
    (event: LayoutChangeEvent) => {
      const value = event.nativeEvent.layout.height - tabBarHeight;
      if (Math.round(value * 10) / 10 !== Math.round(headerHeight * 10) / 10) {
        onHeaderHeightChange?.();
        setHeaderHeight(Math.max(value, 0));
        setTranslateY(
          scrollY.interpolate({
            inputRange: [0, Math.max(value, 0)],
            outputRange: [0, -value],
            extrapolateRight: 'clamp',
          })
        );
      }
    },
    [headerHeight, onHeaderHeightChange, scrollY, tabBarHeight]
  );

Accompanied by:

{renderHeader()}

@PedroBern
Copy link
Owner

Of course! Already pushed to #18

@PedroBern
Copy link
Owner

Solved in v1.3.1, with #18

@PedroBern PedroBern added bug Something isn't working and removed triage labels Dec 4, 2020
@alexpchin
Copy link
Contributor Author

👍🏻 Kudos on the library by the way. Nice work!

@PedroBern
Copy link
Owner

Thanks :) please let me know if you find more problems

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants