CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rc-tabs

React tabs UI component providing comprehensive, accessible, and customizable tabbed interfaces

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

advanced-features.mddocs/

Advanced Features

Extended functionality including extra content, dropdown overflow, custom rendering, and responsive behavior. These features enable sophisticated tab interfaces for complex applications and unique use cases.

Capabilities

Extra Content in Tab Bar

Additional content areas within the tab bar for actions, information, or custom controls.

/**
 * Extra content configuration for tab bar areas
 * Content can be placed on left or right side of tabs
 */
type TabBarExtraContent = React.ReactNode | TabBarExtraMap;

/**
 * Map defining content for specific positions in tab bar
 */
type TabBarExtraMap = Partial<Record<TabBarExtraPosition, React.ReactNode>>;

/**
 * Available positions for extra content
 */
type TabBarExtraPosition = 'left' | 'right';

/**
 * Tab bar styling and layout options
 */
interface TabBarConfig {
  /** Extra content in the tab bar */
  tabBarExtraContent?: TabBarExtraContent;
  /** Gap between individual tabs in pixels */
  tabBarGutter?: number;
  /** Styles for the tab bar container */
  tabBarStyle?: React.CSSProperties;
}

Usage Examples:

import Tabs from "rc-tabs";
import { Button, Badge, Avatar } from "antd";

// Simple extra content
function TabsWithExtraContent() {
  return (
    <Tabs
      items={tabItems}
      tabBarExtraContent={
        <Button type="primary" size="small">
          Action
        </Button>
      }
    />
  );
}

// Positioned extra content
function TabsWithPositionedContent() {
  return (
    <Tabs
      items={tabItems}
      tabBarExtraContent={{
        left: (
          <div style={{ marginRight: 16 }}>
            <Badge count={5}>
              <Avatar icon="user" />
            </Badge>
          </div>
        ),
        right: (
          <div>
            <Button size="small" style={{ marginRight: 8 }}>
              Save
            </Button>
            <Button size="small" type="primary">
              Publish
            </Button>
          </div>
        ),
      }}
    />
  );
}

// Dynamic extra content
function DynamicExtraContent() {
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
  
  return (
    <Tabs
      items={tabItems}
      tabBarExtraContent={
        hasUnsavedChanges ? (
          <Badge status="warning" text="Unsaved changes" />
        ) : (
          <Badge status="success" text="All saved" />
        )
      }
    />
  );
}

Overflow Handling and More Dropdown

Automatic handling of tab overflow with customizable dropdown for collapsed tabs.

/**
 * Configuration for overflow tabs dropdown
 */
interface MoreProps extends Omit<DropdownProps, 'children'> {
  /** Custom icon for the more dropdown trigger */
  icon?: React.ReactNode;
}

/**
 * Dropdown properties from rc-dropdown
 * Controls behavior of overflow tabs menu
 */
interface DropdownProps {
  /** Dropdown trigger type */
  trigger?: Array<'click' | 'hover' | 'contextMenu'>;
  /** Dropdown placement */
  placement?: 'topLeft' | 'topCenter' | 'topRight' | 'bottomLeft' | 'bottomCenter' | 'bottomRight';
  /** Whether dropdown is visible */
  visible?: boolean;
  /** Custom dropdown container */
  getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
  /** Dropdown overlay class name */
  overlayClassName?: string;
  /** Dropdown overlay style */
  overlayStyle?: React.CSSProperties;
}

Overflow Examples:

import { MoreOutlined, EllipsisOutlined } from "@ant-design/icons";

// Basic overflow handling
function TabsWithOverflow() {
  const manyTabs = Array.from({ length: 20 }, (_, i) => ({
    key: `tab-${i + 1}`,
    label: `Tab ${i + 1}`,
    children: <div>Content for tab {i + 1}</div>,
  }));
  
  return (
    <Tabs
      items={manyTabs}
      more={{
        icon: <MoreOutlined />,
        trigger: ['click'],
      }}
    />
  );
}

// Custom overflow dropdown
function CustomOverflowTabs() {
  return (
    <Tabs
      items={manyTabs}
      more={{
        icon: <EllipsisOutlined />,
        trigger: ['hover'],
        placement: 'bottomRight',
        overlayClassName: 'custom-tabs-dropdown',
      }}
      getPopupContainer={(node) => node.parentElement || document.body}
    />
  );
}

// Responsive overflow behavior
function ResponsiveOverflowTabs() {
  const [containerWidth, setContainerWidth] = useState(800);
  
  return (
    <div style={{ width: containerWidth }}>
      <input
        type="range"
        min="300"
        max="1200"
        value={containerWidth}
        onChange={(e) => setContainerWidth(Number(e.target.value))}
      />
      <Tabs
        items={manyTabs}
        more={{
          icon: <span>···</span>,
        }}
      />
    </div>
  );
}

Custom Tab Bar Rendering

Complete customization of tab bar appearance and behavior through render functions.

/**
 * Custom tab bar render function
 * Provides complete control over tab bar rendering
 */
type RenderTabBar = (
  props: RenderTabBarProps,
  DefaultTabBar: React.ComponentType<TabNavListProps>
) => React.ReactElement;

/**
 * Properties passed to custom tab bar render function
 */
interface RenderTabBarProps {
  id: string;
  activeKey: string;
  animated: AnimatedConfig;
  tabPosition: TabPosition;
  rtl: boolean;
  mobile: boolean;
  editable: EditableConfig;
  locale: TabsLocale;
  more: MoreProps;
  tabBarGutter: number;
  onTabClick: (key: string, e: React.MouseEvent | React.KeyboardEvent) => void;
  onTabScroll: OnTabScroll;
  extra: TabBarExtraContent;
  style: React.CSSProperties;
}

/**
 * Default tab bar component props
 */
interface TabNavListProps {
  id: string;
  tabPosition: TabPosition;
  activeKey: string;
  rtl: boolean;
  animated?: AnimatedConfig;
  extra?: TabBarExtraContent;
  editable?: EditableConfig;
  more?: MoreProps;
  mobile: boolean;
  tabBarGutter?: number;
  className?: string;
  style?: React.CSSProperties;
  locale?: TabsLocale;
  onTabClick: (activeKey: string, e: React.MouseEvent | React.KeyboardEvent) => void;
  onTabScroll?: OnTabScroll;
}

Custom Rendering Examples:

// Wrapped tab bar with additional controls
function TabsWithCustomBar() {
  const renderTabBar = (props: RenderTabBarProps, DefaultTabBar: any) => (
    <div className="custom-tab-bar-wrapper">
      <div className="tab-bar-header">
        <h3>Document Tabs</h3>
        <Button size="small">Settings</Button>
      </div>
      <DefaultTabBar {...props} />
    </div>
  );
  
  return (
    <Tabs
      items={tabItems}
      renderTabBar={renderTabBar}
    />
  );
}

// Completely custom tab bar
function TabsWithFullCustomBar() {
  const [activeKey, setActiveKey] = useState('1');
  
  const renderTabBar = (props: RenderTabBarProps) => (
    <div className="custom-tabs-nav">
      {tabItems.map(item => (
        <button
          key={item.key}
          className={`custom-tab ${activeKey === item.key ? 'active' : ''}`}
          onClick={(e) => {
            setActiveKey(item.key);
            props.onTabClick(item.key, e);
          }}
        >
          {item.label}
          {activeKey === item.key && <span className="active-indicator" />}
        </button>
      ))}
    </div>
  );
  
  return (
    <Tabs
      activeKey={activeKey}
      items={tabItems}
      renderTabBar={renderTabBar}
    />
  );
}

// Conditional tab bar rendering
function ConditionalTabBar() {
  const [isCompact, setIsCompact] = useState(false);
  
  const renderTabBar = (props: RenderTabBarProps, DefaultTabBar: any) => {
    if (isCompact) {
      return (
        <select 
          value={props.activeKey}
          onChange={(e) => props.onTabClick(e.target.value, e as any)}
        >
          {tabItems.map(item => (
            <option key={item.key} value={item.key}>
              {item.label}
            </option>
          ))}
        </select>
      );
    }
    
    return <DefaultTabBar {...props} />;
  };
  
  return (
    <Tabs
      items={tabItems}
      renderTabBar={renderTabBar}
    />
  );
}

Tab Scrolling and Navigation

Control and respond to tab scrolling behavior in overflow scenarios.

/**
 * Tab scroll event handler
 * Fired when tab bar is scrolled horizontally or vertically
 */
type OnTabScroll = (info: { direction: 'left' | 'right' | 'top' | 'bottom' }) => void;

/**
 * Scroll behavior configuration
 */
interface TabScrollConfig {
  /** Callback for tab scroll events */
  onTabScroll?: OnTabScroll;
  /** Whether to show scroll buttons in overflow */
  showScrollArrows?: boolean;
  /** Scroll speed and behavior settings */
  scrollAnimated?: boolean;
}

Scroll Examples:

// Tab scroll monitoring
function ScrollMonitoredTabs() {
  const [scrollInfo, setScrollInfo] = useState('');
  
  const handleTabScroll = (info: { direction: string }) => {
    setScrollInfo(`Scrolled ${info.direction} at ${new Date().toLocaleTimeString()}`);
  };
  
  return (
    <div>
      <div>Scroll Status: {scrollInfo}</div>
      <Tabs
        items={manyTabs}
        onTabScroll={handleTabScroll}
      />
    </div>
  );
}

// Programmatic tab scrolling
function ProgrammaticScrollTabs() {
  const tabsRef = useRef<HTMLDivElement>(null);
  
  const scrollToTab = (direction: 'left' | 'right') => {
    const tabsElement = tabsRef.current?.querySelector('.rc-tabs-nav-wrap');
    if (tabsElement) {
      const scrollAmount = 200;
      tabsElement.scrollBy({
        left: direction === 'left' ? -scrollAmount : scrollAmount,
        behavior: 'smooth',
      });
    }
  };
  
  return (
    <div>
      <div>
        <Button onClick={() => scrollToTab('left')}>← Scroll Left</Button>
        <Button onClick={() => scrollToTab('right')}>Scroll Right →</Button>
      </div>
      <Tabs
        ref={tabsRef}
        items={manyTabs}
      />
    </div>
  );
}

Indicator Customization

Customization of the tab indicator (ink bar) appearance and behavior.

/**
 * Tab indicator configuration
 * Controls the visual indicator showing active tab
 */
interface IndicatorConfig {
  /** Function to calculate indicator size */
  size?: GetIndicatorSize;
  /** Alignment of indicator relative to tab */
  align?: 'start' | 'center' | 'end';
}

/**
 * Type for calculating indicator size
 * Can be a number or function that takes origin size and returns new size
 */
type GetIndicatorSize = number | ((origin: number) => number);

Indicator Examples:

// Fixed size indicator
function FixedSizeIndicatorTabs() {
  return (
    <Tabs
      items={tabItems}
      indicator={{
        size: 3, // Fixed 3px indicator height/width
        align: 'center',
      }}
    />
  );
}

// Dynamic indicator sizing
function DynamicIndicatorTabs() {
  const calculateSize: GetIndicatorSize = (originalSize) => {
    // Make indicator 80% of original size
    return Math.floor(originalSize * 0.8);
  };
  
  return (
    <Tabs
      items={tabItems}
      indicator={{
        size: calculateSize,
        align: 'center',
      }}
    />
  );
}

// Responsive indicator based on screen size
function ResponsiveIndicatorTabs() {
  const [indicatorSize, setIndicatorSize] = useState<GetIndicatorSize>(2);
  
  useEffect(() => {
    const updateSize = () => {
      setIndicatorSize(window.innerWidth < 768 ? 2 : 4);
    };
    
    updateSize();
    window.addEventListener('resize', updateSize);
    return () => window.removeEventListener('resize', updateSize);
  }, []);
  
  return (
    <Tabs
      items={tabItems}
      indicator={{
        size: indicatorSize,
        align: 'start',
      }}
    />
  );
}

Popup Container Control

Control where popups and dropdowns are rendered for proper z-index and positioning.

/**
 * Popup container configuration
 * Controls where dropdown and popup elements are rendered
 */
interface PopupConfig {
  /** Function to get container element for popups */
  getPopupContainer?: (node: HTMLElement) => HTMLElement;
  /** CSS class name for popup elements */
  popupClassName?: string;
}

Popup Container Examples:

// Custom popup container
function CustomPopupTabs() {
  return (
    <div className="tabs-container">
      <Tabs
        items={manyTabs}
        getPopupContainer={(node) => {
          // Render popups in specific container
          return document.querySelector('.popup-container') || document.body;
        }}
        popupClassName="custom-tabs-popup"
        more={{
          icon: <MoreOutlined />,
        }}
      />
      <div className="popup-container" />
    </div>
  );
}

// Modal-safe popup rendering
function ModalSafeTabs({ inModal }: { inModal: boolean }) {
  return (
    <Tabs
      items={manyTabs}
      getPopupContainer={inModal ? 
        (node) => node.closest('.ant-modal-content') || document.body :
        undefined
      }
      more={{
        icon: <MoreOutlined />,
      }}
    />
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-rc-tabs

docs

advanced-features.md

animation-transitions.md

core-interface.md

editable-tabs.md

index.md

tab-configuration.md

tile.json