showtime tab view logo

Showtime Tab View

A react native component, support collapse header and custom refresh control, power by Reanimated v2 & GestureHandler V2.

showtime-profile.mp4

What

This is a react native tab view component, it wraps gestures and animations on top of react-native-tab-view, source code in here before.

you can see this context on Twitter.

Features

  • Collapse header.
  • Support FlashList. *(see this)
  • Custom fresh control.
  • Support bounces effect on iOS.
  • Support iOS & Android & Web.
  • Zoom header when pull refresh. *(see this thread)

Installation

First things you should follow installation instructions of:

and then

yarn add showtime-tab-view

Example

Usage

mostly API is same with react-native-tab-view, I just added some props on top of it, basic:

import React, { useCallback, useState } from "react";
import { StatusBar, Text, View } from "react-native";
import { useSharedValue } from "react-native-reanimated";
import { Route, TabView } from "showtime-tab-view";
import { TabFlashList } from "./tab-flash-list";
const StatusBarHeight = StatusBar.currentHeight ?? 0;
const TabScene = ({ route }: any) => {
  return (
    <TabFlashList
      index={route.index}
      data={new Array(20).fill(0)}
      estimatedItemSize={60}
      renderItem={({ index }) => {
        return (
          <View
            style={{
              height: 60,
              backgroundColor: "#fff",
              marginBottom: 8,
              justifyContent: "center",
              alignItems: "center",
            }}
          >
            <Text>{`${route.title}-Item-${index}`}</Text>
          </View>
        );
      }}
    />
  );
};

export function Example() {
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [routes] = useState<Route[]>([
    { key: "like", title: "Like", index: 0 },
    { key: "owner", title: "Owner", index: 1 },
    { key: "created", title: "Created", index: 2 },
  ]);
  const [index, setIndex] = useState(0);
  const animationHeaderPosition = useSharedValue(0);
  const animationHeaderHeight = useSharedValue(0);

  const renderScene = useCallback(({ route }: any) => {
    switch (route.key) {
      case "like":
        return <TabScene route={route} index={0} />;
      case "owner":
        return <TabScene route={route} index={1} />;
      case "created":
        return <TabScene route={route} index={2} />;
      default:
        return null;
    }
  }, []);

  const onStartRefresh = async () => {
    setIsRefreshing(true);
    setTimeout(() => {
      console.log("onStartRefresh");
      setIsRefreshing(false);
    }, 300);
  };
  const renderHeader = () => (
    <View style={{ height: 300, backgroundColor: "#000" }}></View>
  );
  return (
    <TabView
      onStartRefresh={onStartRefresh}
      isRefreshing={isRefreshing}
      navigationState={{ index, routes }}
      renderScene={renderScene}
      onIndexChange={setIndex}
      lazy
      renderScrollHeader={renderHeader}
      minHeaderHeight={44 + StatusBarHeight}
      animationHeaderPosition={animationHeaderPosition}
      animationHeaderHeight={animationHeaderHeight}
    />
  );
}

API

Will come soon! 🔜

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

Special thanks @Daavidaviid to try zoom header effect when pull to refresh.

License

MIT


GitHub

View Github