CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-tab-view

Cross-platform Tab View component for React Native applications with swipeable, scrollable tab interfaces and smooth animations

Pending
Overview
Eval results
Files

tab-bar.mddocs/

Tab Bar Component

The TabBar component is the default tab bar implementation that provides scrollable tabs with an animated indicator. It handles tab press events, supports customization of colors and styling, and provides accessibility features.

Capabilities

TabBar Component

Default tab bar component with scrollable tabs, animated indicator, and comprehensive customization options.

/**
 * Default TabBar component for rendering tab navigation
 * @param props - TabBar configuration and styling options
 * @returns JSX element containing the tab bar interface
 */
function TabBar<T extends Route>(props: Props<T>): JSX.Element;

interface Props<T extends Route> extends SceneRendererProps {
  /** Required navigation state */
  navigationState: NavigationState<T>;
  /** Enable horizontal scrolling when tabs exceed container width */
  scrollEnabled?: boolean;
  /** Enable bouncing effect on scroll (iOS) */
  bounces?: boolean;
  /** Active tab text color */
  activeColor?: string;
  /** Inactive tab text color */
  inactiveColor?: string;
  /** Tab press ripple color (Android) */
  pressColor?: string;
  /** Tab press opacity effect */
  pressOpacity?: number;
  /** Per-route tab configuration options */
  options?: Record<string, TabDescriptor<T>>;
  /** Custom indicator renderer */
  renderIndicator?: (props: IndicatorProps<T>) => React.ReactNode;
  /** Custom tab item renderer */
  renderTabBarItem?: (props: TabBarItemProps<T> & { key: string }) => React.ReactElement;
  /** Tab press event handler */
  onTabPress?: (scene: Scene<T> & Event) => void;
  /** Tab long press event handler */
  onTabLongPress?: (scene: Scene<T>) => void;
  /** Individual tab styling */
  tabStyle?: StyleProp<ViewStyle>;
  /** Indicator styling */
  indicatorStyle?: StyleProp<ViewStyle>;
  /** Indicator container styling */
  indicatorContainerStyle?: StyleProp<ViewStyle>;
  /** Content container styling */
  contentContainerStyle?: StyleProp<ViewStyle>;
  /** Tab bar container styling */
  style?: StyleProp<ViewStyle>;
  /** Text direction - 'ltr' or 'rtl' */
  direction?: LocaleDirection;
  /** Space between tabs in pixels */
  gap?: number;
  /** Test identifier */
  testID?: string;
  /** Android ripple configuration */
  android_ripple?: PressableAndroidRippleConfig;
}

Usage Examples:

import React, { useState } from 'react';
import { TabView, TabBar, NavigationState, Route } from 'react-native-tab-view';

// Basic custom TabBar
const BasicTabBarExample = () => {
  const [index, setIndex] = useState(0);
  const [routes] = useState([
    { key: 'home', title: 'Home' },
    { key: 'profile', title: 'Profile' },
  ]);

  const renderTabBar = (props) => (
    <TabBar
      {...props}
      activeColor="#ffffff"
      inactiveColor="#cccccc"
      style={{ backgroundColor: '#2196f3' }}
      indicatorStyle={{ backgroundColor: '#ffeb3b' }}
    />
  );

  return (
    <TabView
      navigationState={{ index, routes }}
      renderScene={renderScene}
      renderTabBar={renderTabBar}
      onIndexChange={setIndex}
    />
  );
};

// Advanced TabBar with custom styling and events
const AdvancedTabBarExample = () => {
  const [index, setIndex] = useState(0);
  const [routes] = useState([
    { key: 'feed', title: 'Feed' },
    { key: 'search', title: 'Search' },
    { key: 'notifications', title: 'Notifications' },
    { key: 'profile', title: 'Profile' },
  ]);

  const handleTabPress = (scene) => {
    console.log('Tab pressed:', scene.route.key);
    // Can prevent default navigation by calling scene.preventDefault()
  };

  const renderTabBar = (props) => (
    <TabBar
      {...props}
      scrollEnabled
      activeColor="#1976d2"
      inactiveColor="#757575"
      pressColor="#e3f2fd"
      pressOpacity={0.8}
      onTabPress={handleTabPress}
      gap={16}
      style={{
        backgroundColor: '#ffffff',
        elevation: 4,
        shadowOpacity: 0.1,
      }}
      tabStyle={{
        minWidth: 120,
      }}
      indicatorStyle={{
        backgroundColor: '#2196f3',
        height: 3,
      }}
      contentContainerStyle={{
        paddingHorizontal: 16,
      }}
    />
  );

  return (
    <TabView
      navigationState={{ index, routes }}
      renderScene={renderScene}
      renderTabBar={renderTabBar}
      onIndexChange={setIndex}
    />
  );
};

Tab Bar Indicator

The TabBar includes an animated indicator that shows the active tab position.

/**
 * Props for the TabBarIndicator component
 */
interface IndicatorProps<T extends Route> extends SceneRendererProps {
  /** Navigation state */
  navigationState: NavigationState<T>;
  /** Indicator width configuration */
  width: 'auto' | `${number}%` | number;
  /** Function to get tab width by index */
  getTabWidth: (index: number) => number;
  /** Text direction */
  direction: LocaleDirection;
  /** Indicator styling */
  style?: StyleProp<ViewStyle>;
  /** Space between tabs */
  gap?: number;
  /** Child components */
  children?: React.ReactNode;
}

Tab Bar Items

Individual tab rendering with support for labels, icons, and badges.

/**
 * Props for individual TabBarItem components
 */
interface TabBarItemProps<T extends Route> extends TabDescriptor<T> {
  /** Animated position value */
  position: Animated.AnimatedInterpolation<number>;
  /** Route object */
  route: T;
  /** Navigation state */
  navigationState: NavigationState<T>;
  /** Active tab color */
  activeColor?: string;
  /** Inactive tab color */
  inactiveColor?: string;
  /** Press ripple color */
  pressColor?: string;
  /** Press opacity effect */
  pressOpacity?: number;
  /** Layout event handler */
  onLayout?: (event: LayoutChangeEvent) => void;
  /** Press event handler */
  onPress: () => void;
  /** Long press event handler */
  onLongPress: () => void;
  /** Default tab width */
  defaultTabWidth?: number;
  /** Tab styling */
  style: StyleProp<ViewStyle>;
  /** Android ripple configuration */
  android_ripple?: PressableAndroidRippleConfig;
}

Customization Options

TabBar supports extensive customization through styling and render functions.

/**
 * TabDescriptor interface for tab configuration
 */
interface TabDescriptor<T extends Route> {
  /** Override accessibility label */
  accessibilityLabel?: string;
  /** Override accessibility enabled flag */
  accessible?: boolean;
  /** Test identifier */
  testID?: string;
  /** Override tab label text */
  labelText?: string;
  /** Allow font scaling */
  labelAllowFontScaling?: boolean;
  /** Web navigation href */
  href?: string;
  /** Custom label renderer */
  label?: (props: {
    route: T;
    labelText?: string;
    focused: boolean;
    color: string;
    allowFontScaling?: boolean;
    style?: StyleProp<TextStyle>;
  }) => React.ReactNode;
  /** Label text styling */
  labelStyle?: StyleProp<TextStyle>;
  /** Custom icon renderer */
  icon?: (props: {
    route: T;
    focused: boolean;
    color: string;
    size: number;
  }) => React.ReactNode;
  /** Custom badge renderer */
  badge?: (props: { route: T }) => React.ReactElement;
  /** Scene container styling */
  sceneStyle?: StyleProp<ViewStyle>;
}

Custom Rendering Examples:

// Custom tab with icon and badge
const renderTabBar = (props) => (
  <TabBar
    {...props}
    renderTabBarItem={({ route, ...itemProps }) => (
      <TabBarItem
        {...itemProps}
        route={route}
        icon={({ focused, color }) => (
          <Icon 
            name={getIconName(route.key)} 
            color={color} 
            size={24} 
          />
        )}
        badge={({ route }) => 
          getBadgeCount(route.key) > 0 ? (
            <Badge count={getBadgeCount(route.key)} />
          ) : null
        }
      />
    )}
  />
);

// Custom indicator
const renderTabBar = (props) => (
  <TabBar
    {...props}
    renderIndicator={(indicatorProps) => (
      <TabBarIndicator
        {...indicatorProps}
        style={{ backgroundColor: 'red', height: 4 }}
      />
    )}
  />
);

Event Handling

Handle tab interactions with custom logic and event prevention.

/**
 * Event object for tab press interactions
 */
interface Event {
  /** Whether default navigation has been prevented */
  defaultPrevented: boolean;
  /** Function to prevent default navigation */
  preventDefault(): void;
}

/**
 * Scene context for event handlers
 */
interface Scene<T extends Route> {
  /** The route being interacted with */
  route: T;
}

Event Handling Examples:

const handleTabPress = (scene: Scene<Route> & Event) => {
  // Custom logic before navigation
  if (scene.route.key === 'protected' && !isAuthenticated) {
    scene.preventDefault();
    showLoginModal();
    return;
  }
  
  // Allow default navigation
  console.log('Navigating to:', scene.route.key);
};

const renderTabBar = (props) => (
  <TabBar
    {...props}
    onTabPress={handleTabPress}
    onTabLongPress={(scene) => {
      showTabContextMenu(scene.route);
    }}
  />
);

Accessibility

TabBar provides comprehensive accessibility support.

/**
 * Accessibility configuration through TabDescriptor
 */
interface AccessibilityProps {
  /** Whether the tab is accessible */
  accessible?: boolean;
  /** Accessibility label for screen readers */
  accessibilityLabel?: string;
  /** Test identifier for automated testing */
  testID?: string;
  /** Allow font scaling for better accessibility */
  labelAllowFontScaling?: boolean;
}

Styling and Layout

Control TabBar appearance through comprehensive styling options.

/**
 * Layout and styling interfaces
 */
interface StyleProps {
  /** Main tab bar container style */
  style?: StyleProp<ViewStyle>;
  /** Individual tab styling */
  tabStyle?: StyleProp<ViewStyle>;
  /** Content container styling */
  contentContainerStyle?: StyleProp<ViewStyle>;
  /** Indicator styling */
  indicatorStyle?: StyleProp<ViewStyle>;
  /** Indicator container styling */
  indicatorContainerStyle?: StyleProp<ViewStyle>;
}

/**
 * Android-specific ripple configuration
 */
interface PressableAndroidRippleConfig {
  /** Ripple color */
  color?: string;
  /** Whether ripple extends beyond bounds */
  borderless?: boolean;
  /** Ripple radius */
  radius?: number;
}

Install with Tessl CLI

npx tessl i tessl/npm-react-native-tab-view

docs

index.md

scene-map.md

tab-bar-indicator.md

tab-bar-item.md

tab-bar.md

tab-view.md

tile.json