expo-linear-like-bottom-tabs

repository·main·Indexed 42 days ago

https://github.com/rit3zh/expo-linear-like-bottom-tabs

A React Native component library providing a smooth, minimal, floating bottom tab bar inspired by the Linear app interface. Built with react-native-reanimated, expo, and react-native-gesture-handler, it offers a gesture-driven interface for @react-navigation/bottom-tabs including the LinearTabBar component and support for expanded menu items.

Tokens
1.6K
Snippets
8
Records
9
Agent score
53%

What's inside expo-linear-like-bottom-tabs

  1. Overview of expo-linear-like-bottom-tabs

    main
    A sleek, Linear-inspired floating bottom tab bar designed for React Native. It provides a minimal UI with smooth transitions and is built using react-native-reanimated, expo, and react-native-gesture-handler. It is cross-platform, supporting both iOS and Android, and is fully typed with TypeScript.
  2. Install expo-linear-like-bottom-tabs

    main

    To use this project, clone the repository, install dependencies using bun, and run the platform-specific commands to start the development server for iOS or Android.

    git clone https://github.com/rit3zh/expo-linear-like-bottom-tabs
    cd expo-linear-like-bottom-tabs
    bun install
    bun ios
    bun android
  3. Use the LinearTabBar component

    main

    The LinearTabBar component is a custom tab bar designed for use with @react-navigation/bottom-tabs. It provides a highly animated, gesture-driven interface that can expand into a menu.

    To use it, pass it to the tabBar prop of your BottomTabNavigator.

    Props

    PropTypeDescription
    stateBottomTabNavigationStateRequired. The navigation state provided by the navigator.
    descriptorsBottomTabDescriptorMapRequired. Descriptors for each route.
    navigationBottomTabNavigationPropRequired. The navigation object.
    onLinearTabPress (optional)() => void | anyCallback triggered when the special 'Linear' tab (the dummy tab) is pressed.
    onMenuItemPress (optional)(index: number) => void | anyCallback triggered when an item in the expanded menu is pressed.
    import { LinearTabBar } from '@/components/linear-tab-bar';
    import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
    
    const Tab = createBottomTabNavigator();
    
    function MyTabs() {
      return (
        <Tab.Navigator
          tabBar={(props) => (
            <LinearTabBar
              {...props}
              onLinearTabPress={() => console.log('Linear tab pressed!')}
              onMenuItemPress={(index) => console.log('Menu item pressed:', index)}
            />
          )}
        >
          {/* Your Tab.Screen components here */}
        </Tab.Navigator>
      );
    }
  4. Reference FavoriteItem and TeamItem data structures

    main

    The library provides specific interfaces for data items that might be displayed within the tab interface:

    • FavoriteItem: Represents a favorite entry with id, title, checked status, and an optional icon (which can be "loading", "clock", or null).
    • TeamItem: Represents a team entry with id, name, and an optional icon string.
    interface FavoriteItem {
      id: string;
      title: string;
      checked: boolean;
      icon?: "loading" | "clock" | null;
    }
    
    interface TeamItem {
      id: string;
      name: string;
      icon?: string;
    }
  5. Configure ExpandedMenuItemProps for expanded menu items

    main

    The ExpandedMenuItemProps interface is used to pass state and handlers to individual items within the expanded menu view, including the current animationProgress and the totalItems count for layout calculations.

    import type { SharedValue } from "react-native-reanimated";
    import { ExpandedMenuItem } from "./typings";
    
    interface ExpandedMenuItemProps {
      item: ExpandedMenuItem;
      index: number;
      animationProgress: SharedValue<number>;
      totalItems: number;
      isSelected: boolean;
      onPress: () => void;
    }
  6. Define an ExpandedMenuItem for custom tab items

    main

    When building custom menu items for the expanded state of the bottom tabs, use the ExpandedMenuItem interface. It requires an iconName that must be a valid key from @expo/vector-icons's Ionicons.glyphMap, a label string, and a route string representing the navigation path.

    import { Ionicons } from "@expo/vector-icons";
    
    interface ExpandedMenuItem {
      iconName: keyof typeof Ionicons.glyphMap;
      label: string;
      route: string;
    }
  7. Configure AnimatedTabProps for tab animations

    main

    The AnimatedTabProps interface defines the properties required for an animated tab component. It uses react-native-reanimated's SharedValue<number> to drive the animationProgress.

    import type { SharedValue } from "react-native-reanimated";
    
    interface AnimatedTabProps {
      isFocused: boolean;
      options: any;
      colors: {
        primary: string;
        text: string;
      };
      onPress: () => void;
      onLongPress: () => void;
      animationProgress: SharedValue<number>;
      index: number;
    }