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' });
 
return (
    <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. Returns spread-ready prop objects via getTabProps(value, disabled?) and getIndicatorProps(), along with state, refs, and scroll helpers.

Features#

  • getTabProps(value) returns spread-ready props for each tab including ARIA attributes, keyboard handlers, and active state tracking
  • getIndicatorProps() returns ref and CSS custom properties for animated active bar positioning
  • isItemActive() to check active state per tab and updateValue() to set it programmatically
  • Scroll navigation with scrollPrev/scrollNext methods and canScrollPrev/canScrollNext state
  • Configurable scrollStrategy: 'nearest', 'center', false, or a custom function

Behavior#

Default Value#

Set defaultValue for uncontrolled tab selection.

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

Controlled#

Pass value and onValueChange for controlled usage.

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

Select on Focus#

Set selectOnFocus to activate tabs when they receive focus instead of requiring Enter/Space.

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

Scroll Navigation#

Use contentRef, prevButtonRef, and nextButtonRef for scrollable tab lists. The hook provides scrollPrev/scrollNext methods and state.canScrollPrev/state.canScrollNext for button visibility.

const tabs = useTabs({ defaultValue: '0' });
 
<div ref={tabs.contentRef} {...tabs.contentProps}>
    {/* tabs */}
</div>
<button ref={tabs.prevButtonRef} onClick={tabs.scrollPrev} disabled={!tabs.state.canScrollPrev}>Prev</button>
<button ref={tabs.nextButtonRef} onClick={tabs.scrollNext} disabled={!tabs.state.canScrollNext}>Next</button>

Active Indicator#

Spread getIndicatorProps() on a bar element. The hook assigns a ref and sets the following CSS custom properties on it.

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(--active-bar-width)', left: 'var(--active-bar-left)' }} />

Custom Styling with Data Attributes#

Use scrollStateAttrs to spread data-can-scroll-prev and data-can-scroll-next onto elements for CSS-based scroll button styling.

[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#

See Tabs Primitive for WAI-ARIA compliance details and keyboard support.