React tabs UI component providing comprehensive, accessible, and customizable tabbed interfaces
npx @tessl/cli install tessl/npm-rc-tabs@15.7.0RC Tabs is a comprehensive React tabs UI component library that provides accessible, customizable, and feature-rich tabbed interfaces. It offers keyboard navigation, animations, editable tabs, multiple positioning options, and extensive styling capabilities, making it suitable for both simple tabbed content and complex interactive applications.
npm install rc-tabsimport Tabs from "rc-tabs";
import type {
TabsProps,
Tab,
TabPosition,
AnimatedConfig,
EditableConfig,
TabsLocale,
TabContextProps
} from "rc-tabs";For accessing utility functions:
import Tabs, { stringify, genDataNodeKey, getRemovable } from "rc-tabs";For CommonJS:
const Tabs = require("rc-tabs");
const { stringify, genDataNodeKey, getRemovable } = require("rc-tabs");import Tabs from "rc-tabs";
const items = [
{
key: '1',
label: 'Tab 1',
children: <div>Content of Tab 1</div>,
},
{
key: '2',
label: 'Tab 2',
children: <div>Content of Tab 2</div>,
},
{
key: '3',
label: 'Tab 3',
children: <div>Content of Tab 3</div>,
disabled: true,
},
];
function App() {
return (
<Tabs
defaultActiveKey="1"
items={items}
onChange={(key) => console.log('Active tab:', key)}
/>
);
}RC Tabs is built around several key components:
<Tabs> component that orchestrates the entire tabbed interfaceMain tabs component providing comprehensive tabbed interface functionality with full accessibility support.
interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange' | 'children'> {
prefixCls?: string;
className?: string;
style?: React.CSSProperties;
id?: string;
items?: Tab[];
activeKey?: string;
defaultActiveKey?: string;
direction?: 'ltr' | 'rtl';
animated?: boolean | AnimatedConfig;
renderTabBar?: RenderTabBar;
tabBarExtraContent?: TabBarExtraContent;
tabBarGutter?: number;
tabBarStyle?: React.CSSProperties;
tabPosition?: TabPosition;
destroyInactiveTabPane?: boolean;
onChange?: (activeKey: string) => void;
onTabClick?: (activeKey: string, e: React.KeyboardEvent | React.MouseEvent) => void;
onTabScroll?: OnTabScroll;
editable?: EditableConfig;
getPopupContainer?: (node: HTMLElement) => HTMLElement;
locale?: TabsLocale;
more?: MoreProps;
popupClassName?: string;
indicator?: {
size?: GetIndicatorSize;
align?: 'start' | 'center' | 'end';
};
}Individual tab item configuration with support for content, styling, and interactive features.
interface Tab {
key: string;
label: React.ReactNode;
className?: string;
style?: React.CSSProperties;
disabled?: boolean;
children?: React.ReactNode;
forceRender?: boolean;
closable?: boolean;
closeIcon?: React.ReactNode;
icon?: React.ReactNode;
}Animation system with configurable ink bar and tab pane transitions for smooth user experiences.
interface AnimatedConfig {
inkBar?: boolean;
tabPane?: boolean;
tabPaneMotion?: CSSMotionProps;
}Interactive tab management with add/remove functionality and customizable controls.
interface EditableConfig {
onEdit: (
type: 'add' | 'remove',
info: { key?: string; event: React.MouseEvent | React.KeyboardEvent }
) => void;
showAdd?: boolean;
removeIcon?: React.ReactNode;
addIcon?: React.ReactNode;
}Extended functionality including extra content, dropdown overflow, custom rendering, and responsive behavior.
type TabPosition = 'left' | 'right' | 'top' | 'bottom';
type TabBarExtraContent = React.ReactNode | TabBarExtraMap;
type OnTabScroll = (info: { direction: 'left' | 'right' | 'top' | 'bottom' }) => void;Helper functions exported for advanced use cases and internal operations.
/**
* Converts Map or Record to JSON string for dependency comparison
* Used internally for optimizing re-renders with Map dependencies
*/
function stringify<K extends PropertyKey, V>(obj: Record<K, V> | Map<K, V>): string;
/**
* Generates a safe data node key by escaping double quotes
* Used internally for DOM element key generation
*/
function genDataNodeKey(key: React.Key): string;
/**
* Determines if a tab can be removed based on various conditions
* Used internally for editable tab validation
*/
function getRemovable(
closable?: boolean,
closeIcon?: React.ReactNode,
editable?: EditableConfig,
disabled?: boolean
): boolean;type TabPosition = 'left' | 'right' | 'top' | 'bottom';
interface TabsLocale {
dropdownAriaLabel?: string;
removeAriaLabel?: string;
addAriaLabel?: string;
}
type TabBarExtraMap = Partial<Record<'left' | 'right', React.ReactNode>>;
type TabBarExtraContent = React.ReactNode | TabBarExtraMap;
type GetIndicatorSize = number | ((origin: number) => number);
interface MoreProps {
icon?: React.ReactNode;
trigger?: 'hover' | 'click';
}
type RenderTabBar = (
props: RenderTabBarProps,
DefaultTabBar: React.ComponentType
) => React.ReactElement;
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;
panes: React.ReactNode;
}
interface CSSMotionProps {
motionName?: string;
motionAppear?: boolean;
motionEnter?: boolean;
motionLeave?: boolean;
motionAppearDuration?: number;
motionEnterDuration?: number;
motionLeaveDuration?: number;
onAppearStart?: (node: HTMLElement, done: () => void) => CSSMotionEvent;
onEnterStart?: (node: HTMLElement, done: () => void) => CSSMotionEvent;
onLeaveStart?: (node: HTMLElement, done: () => void) => CSSMotionEvent;
onAppearActive?: (node: HTMLElement, done: () => void) => CSSMotionEvent;
onEnterActive?: (node: HTMLElement, done: () => void) => CSSMotionEvent;
onLeaveActive?: (node: HTMLElement, done: () => void) => CSSMotionEvent;
onAppearEnd?: (node: HTMLElement, done: () => void) => boolean | void;
onEnterEnd?: (node: HTMLElement, done: () => void) => boolean | void;
onLeaveEnd?: (node: HTMLElement, done: () => void) => boolean | void;
}
interface CSSMotionEvent {
deadline?: boolean;
target?: HTMLElement;
}
interface TabContextProps {
tabs: Tab[];
prefixCls: string;
}
type SizeInfo = [width: number, height: number];
type TabSizeMap = Map<React.Key, { width: number; height: number; left: number; top: number }>;
interface TabOffset {
width: number;
height: number;
left: number;
right: number;
top: number;
}
type TabOffsetMap = Map<React.Key, TabOffset>;