GithubHelp home page GithubHelp logo

ariesbrylle-bms / react-native-collapsible-tab-view Goto Github PK

View Code? Open in Web Editor NEW

This project forked from pedrobern/react-native-collapsible-tab-view

0.0 0.0 0.0 10.59 MB

A cross-platform Collapsible Tab View component for React Native

License: MIT License

JavaScript 3.45% TypeScript 96.55%

react-native-collapsible-tab-view's Introduction

react-native-collapsible-tab-view

Build Status Version MIT License

Expo app

A simple wrapper for react-native-tab-view that helps to build a collapsible tab view.

Demo

Features

  • Smooth animations and gestures
  • Scrollable tabs
  • Supports both top and bottom tab bars
  • Follows Material Design spec
  • Highly customizable
  • Fully typed with TypeScript

From this package

Installation

Open a Terminal in the project root and run:

yarn add react-native-collapsible-tab-view

Now add react-native-tab-view and all it's peer dependencies:

yarn add react-native-tab-view

For the peer dependencies, if using expo:

expo install react-native-gesture-handler react-native-reanimated

If not using expo, follow these instructions.

React Navigation Integration

To integrate with react-navigation:

yarn add @react-navigation/native @react-navigation/material-top-tabs

Quick Start

import * as React from 'react';
import { StyleSheet, View, Text, Animated } from 'react-native';
import {
  CollapsibleTabView,
  useCollapsibleScene,
  createMaterialCollapsibleTopTabNavigator,
} from 'react-native-collapsible-tab-view';
import { SceneMap } from 'react-native-tab-view';
import { NavigationContainer } from '@react-navigation/native';

type Route = {
  key: string;
  title: string;
};

const SomeRoute: React.FC<{ routeKey: string; color: string }> = ({
  routeKey,
  color,
}) => {
  const scrollPropsAndRef = useCollapsibleScene(routeKey);

  return (
    <Animated.ScrollView
      style={{ backgroundColor: color }}
      {...scrollPropsAndRef}
    >
      {new Array(20).fill(null).map((_, index) => {
        return (
          // eslint-disable-next-line react/no-array-index-key
          <Text key={index} style={{ padding: 20, color: 'red' }}>
            {index}
          </Text>
        );
      })}
    </Animated.ScrollView>
  );
};

const FirstScene = () => <SomeRoute routeKey="first" color="white" />;
const SecondScene = () => <SomeRoute routeKey="second" color="black" />;

const HEADER_HEIGHT = 250;

// set pointerEvents="none" to allow scroll on header
// see the docs for more information
const renderHeader = () => (
  <View pointerEvents="none" style={styles.header}>
    <Text style={styles.headerText}>COLLAPSIBLE</Text>
  </View>
);

// example with react navigation

const Tab = createMaterialCollapsibleTopTabNavigator();

export const WithReactNavigation: React.FC<object> = () => {
  return (
    <NavigationContainer>
      <Tab.Navigator
        collapsibleOptions={{
          headerHeight: HEADER_HEIGHT,
          renderHeader,
          disableSnap: true,
        }}
      >
        <Tab.Screen name="first" component={FirstScene} />
        <Tab.Screen name="second" component={SecondScene} />
      </Tab.Navigator>
    </NavigationContainer>
  );
};

// example without react navigation

const renderScene = SceneMap({
  first: FirstScene,
  second: SecondScene,
});

export const WithoutReactNavigation: React.FC<object> = () => {
  const [index, setIndex] = React.useState(0);
  const [routes] = React.useState<Route[]>([
    { key: 'first', title: 'First' },
    { key: 'second', title: 'Second' },
  ]);

  const handleIndexChange = (index: number) => {
    setIndex(index);
  };

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

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

export default WithReactNavigation;

Scroll on header

If you want to allow scrolling from the header:

  • If renderHeader doesn't contain touchables set pointerEvents='none'
  • If renderHeader does contain touchables set pointerEvents='box-none' for them to work. Note: With this setting any child component that should not respond to touches (e.g. <Image />) needs to have pointerEvents set to 'none'. Otherwise it can become the target of a touch gesture on iOS devices and thereby preventing scrolling.

API reference

The package has 3 main exports:

export description
CollapsibleTabView Component which is the one you'd use to render the collapsible tab view.
useCollapsibleScene Hook which you use to get props and ref for ScrollView or FlatList.
createMaterialCollapsibleTopTabNavigator Function to create the Navigator, if you are integrating with react-navigation

CollapsibleTabView

Simple wrapper of the original TabView.

Basic usage looks like this:

<CollapsibleTabView
  navigationState={{ index, routes }}
  onIndexChange={setIndex}
  renderScene={SceneMap({
    first: FirstRoute,
    second: SecondRoute,
  })}
  renderHeader={() => <MyHeader />} // optional
  headerHeight={HEADER_HEIGHT} // optional
/>

Props

All props are optional, but if you are not rendering a header, you'd be probably better with the original TabView.

prop description default
animatedValue? Optionally controlled animated value. new Animated.Value(0)
headerHeight? Header component height. It is computed on layout. Providing it is just an optimization. 0
tabBarHeight? Tab bar height. 49
tabBarProps? Props passed to the tab bar component. undefined
renderHeader? Header rendered on top of the tab bar. () => null
headerContainerStyle? Styles applied to header and tabbar container. undefined
preventTabPressOnGliding? Prevent tab press if screen is gliding. Ignored if renderTabBar is provided. true
disableSnap? Disable the snap animation. false
renderTabBar? Same as renderTabBar of the original TabView, but with the additional isGliding and preventTabPressOnGliding properties. undefined
snapThreshold? Percentage of header height to make the snap effect. A number between 0 and 1. 0.5
snapTimeout? How long to wait before initiating the snap effect, in milliseconds. 250
onHeaderHeightChange? Callback fired when the headerHeight state value inside CollapsibleTabView will be updated in the onLayout event from the tab/header container.

Useful to call layout animations. Example:

() => {LayoutAnimation.configureNext(preset)};
undefined
routeKeyProp? The property from the routes map to use for the active route key. key

useCollapsibleScene

A hook to get all props and ref for the animated component in order to make the collapsible tabs work.

Works with:

  • Animated.ScrollView
  • Animated.FlatList
const FirstScene: React.FC<object> = ({ children }) => {
  const scrollPropsAndRef = useCollapsibleScene('firstScene');

  return (
    <Animated.ScrollView {...scrollPropsAndRef}>{children}</Animated.ScrollView>
  );
};

It includes de following values:

value description
ref Function to get ref from scrollable components inside the scene, and track in the Collapsible Tab View.
onScroll Scroll event, enabled only for the focused route.
scrollEnabled Disable scroll for unfocused routes is optional, but prevents weird/delayed animations if the user changes tabs and quickly start scrolling the new tab, before the animated value starting to track the new focused route.
contentContainerStyle Content container style with paddingTop and minHeight.
progressViewOffset Needed for the loading indicator to show correctly on android.
onMomentumScrollBegin Callback to set isGliding to true.
onScrollEndDrag Callback to sync the scroll of unfocused routes.
onMomentumScrollEnd Callback to sync the scroll of unfocused routes.

createMaterialCollapsibleTopTabNavigator

Same API as the createMaterialTopTabNavigator (not-collapsible), with aditional collapsibleOptions prop, extending all props of CollapsibleTabView.

Contributing

While developing, you can run the example app to test your changes.

Please follow the angular commit message format.

Make sure your code passes TypeScript and ESLint. Run the following to verify:

yarn typescript
yarn lint

To fix formatting errors, run the following:

yarn lint -- --fix

Remember to add tests for your change if possible.

react-native-collapsible-tab-view's People

Contributors

pedrobern avatar andreialecu avatar ariesbrylle-bms avatar dependabot[bot] avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.