Introducing PrimeReact v11-alpha 🎉Discover Now

useTabs

Hook that manages tab selection state, keyboard navigation, and scrollable overflow.

Account Info

Update your personal information such as name, email address, and profile picture.

Payment

Manage your subscription plan, view invoices, and update your payment method.

Preferences

Customize how the application looks and behaves to match your personal preferences.

basic-demo

Usage#

import { useTabs } from '@primereact/headless/tabs';
const { getTabProps, getIndicatorProps, isItemActive, state, contentRef, contentProps } = useTabs({ defaultValue: 'tab1' });
 
<div role="tablist" ref={contentRef} {...contentProps}>
    <button {...getTabProps('tab1')}>Tab 1</button>
    <button {...getTabProps('tab2')}>Tab 2</button>
    <button {...getTabProps('tab3', true)}>Tab 3 (disabled)</button>
    <span {...getIndicatorProps()} />
</div>;

useTabs manages active tab state, keyboard focus cycling, scroll navigation, and active indicator positioning — see Primitive for a component-based API.

Features#

  • Per-tab prop getter — getTabProps(value, disabled?) returns ARIA roles, keyboard handlers, and focus bookkeeping for any tab you render
  • Animated active indicator — getIndicatorProps() wires a ref and CSS variables that track the active tab's size and position
  • Scrollable tab lists — scrollPrev/scrollNext plus canScrollPrev/canScrollNext flags power overflow buttons with zero measurement code
  • Configurable scroll strategy — pick 'nearest', 'center', disable, or plug in a custom function to scroll the active tab into view
  • Controlled or uncontrolled — manage the active value externally or let the hook track it internally
  • Imperative selection — updateValue() changes tabs programmatically and isItemActive() queries the current selection

Working with callbacks#

Controlled active tab#

Drive the active tab from parent state by pairing value with onValueChange.

const [activeTab, setActiveTab] = React.useState('tab1');
 
const tabs = useTabs({
    value: activeTab,
    onValueChange: (e) => setActiveTab(e.value)
});

Activate on focus#

Set selectOnFocus so arrow-key navigation activates tabs instantly rather than waiting for Enter or Space — the pattern used by automatic tablists.

const tabs = useTabs({ defaultValue: 'tab1', selectOnFocus: true });

Scrollable overflow with prev/next buttons#

Wire contentRef, prevButtonRef, and nextButtonRef into your layout, then use the scroll helpers to drive visibility and clicks.

const tabs = useTabs({ defaultValue: '0' });

Animated active indicator#

Spread getIndicatorProps() on a bar element — the hook sets a ref plus CSS custom properties so you can animate position and size entirely in CSS.

VariableDescription
--active-bar-widthWidth of the active tab element
--active-bar-heightHeight of the active tab element
--active-bar-leftLeft offset of the active tab element
--active-bar-topTop offset of the active tab element
<span
    {...getIndicatorProps()}
    style={{
        width: 'var(--px-active-bar-width)',
        left: 'var(--px-active-bar-left)',
        transition: 'all 200ms ease'
    }}
/>

Styling with data attributes#

The scrollStateAttrs bundle spreads data-can-scroll-prev and data-can-scroll-next onto any element so scroll button visibility can be controlled in CSS.

[data-can-scroll-prev] .scroll-prev {
    display: flex;
}
[data-can-scroll-next] .scroll-next {
    display: flex;
}

API#

useTabs#

NameTypeDefault
valuestring | numberundefined
Value of the active tab. Use for controlled mode.
defaultValuestring | numberundefined
Default value of the active tab. Use for uncontrolled mode.
selectOnFocusbooleanfalse
When enabled, the focused tab is activated.
scrollStrategyfalse | "center" | "nearest" | ((content: HTMLElement, tab: HTMLElement) => void)'nearest'
Defines how the active tab is scrolled into view when it changes. - `'nearest'` : scrolls only if the tab is clipped or too close to an edge, with padding. - `'center'` : always centers the active tab in the viewport. - `false` : disables auto-scrolling. - `function` : a custom scroll function receiving the content element and active tab element.
tabIndexnumber0
The tabIndex of the active tab.
onValueChange(event: useTabsChangeEvent) => void—
Callback fired when the tabs's value changes.

Accessibility#

Arrow keys move between tabs, Home/End jump to first/last, and Enter activates the focused tab. See Primitive for full WAI-ARIA compliance details.