Tabs
A view that switches between panels using interactive tabs.
Usage
Basic
Loading demo...
Indicator
indicatorVariant sets how the indicator is drawn and indicatorMotion how it travels. With showIndicator off, the active item paints its own fill.
Loading demo...
Dynamic Content Size
animation.size keeps the tabs' size in step as panel content grows or shrinks.
Loading demo...
Placement and Header
placement takes four directions. TxTabHeader renders a sticky header above the panel, and the nav-right slot holds actions at the end of the nav bar.
Loading demo...
Height Follows Content
Loading demo...
Disabling Animations
Loading demo...
Dashboard Navigation
Tabs hold the top-level sections; light actions go in TxDropdownMenu, short notes in TxPopover, and dense settings in TxDrawer.
Loading demo...
Best Practices
- Keep each
TxTabItemnamestable, unique, and equal to the values inmodelValue/defaultValue. - Prefer
placement="left"for settings and admin pages; top and bottom tabs suit short secondary switches. - Inactive panels unmount, so keep state that must survive outside them.
- When a panel's height changes after loading, enable direct measurement (
contentScrollable=falseorautoHeight) and callrefresh()once content settles. - Keep
nav-rightcompact; move dense actions into a dropdown menu or drawer.
API Reference
TxTabs
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | - | Name of the active tab (controlled). |
defaultValue | string | - | Initial tab when uncontrolled; selects nothing if no tab matches. |
placement | 'left' | 'right' | 'top' | 'bottom' | 'left' | Where the navigation sits. |
offset | number | 0 | Shift (px) of the line indicator along the nav axis. |
navMinWidth | number | 220 | Minimum nav width for vertical placements. |
navMaxWidth | number | 320 | Maximum nav width for vertical placements. |
contentPadding | number | 12 | Padding of the content panel. |
contentScrollable | boolean | true | Wraps content in a scroll container; removed automatically when size animation is on. |
borderless | boolean | false | Removes the outer border and background. |
autoHeight | boolean | false | Animates height changes. |
autoWidth | boolean | false | Animates width changes. |
showIndicator | boolean | true | Shows the indicator; when off, the active item paints its own fill. |
indicatorVariant | 'line' | 'pill' | 'block' | 'dot' | 'outline' | 'line' | How the indicator is drawn: a line, a raised surface, a tint, a dot, or an inset ring. |
indicatorMotion | 'stretch' | 'warp' | 'glide' | 'snap' | 'spring' | 'stretch' | How it travels: stretch lengthens slightly, warp lengthens further, glide slides rigidly, snap settles fastest, spring passes the target once and returns. |
indicatorMotionStrength | number | 1 | How far the indicator lengthens on the way; 0 slides rigidly. |
animation | TabsAnimation | - | Configures the size, nav, indicator, and content animations. |
animation.size | boolean | { enabled?; durationMs?; easing? } | derived from autoHeight / autoWidth | Size animation. |
animation.nav | boolean | { enabled?; durationMs?; easing? } | on, 220ms ease | Nav width transition. |
animation.indicator | boolean | { enabled?; durationMs?; easing? } | on, 350ms | Indicator travel; durationMs time-scales the springs, false lands in place. |
animation.content | boolean | { enabled?; type?; durationMs?; durationRatio?; easing? } | on, zoom, 180ms ease | Panel entrance; type is fade, slide, zoom, blur, scale, or none. |
autoHeightDurationMs | number | 250 | Default size-animation duration. |
autoHeightEasing | string | ease | Default size-animation easing. |
Events
| Event | Params | Description |
|---|---|---|
update:modelValue | value: string | Fires when the active tab changes. |
change | value: string | Fires after a user activates a tab; not on parent-driven modelValue changes. |
Slots
| Slot | Props | Description |
|---|---|---|
default | - | TxTabItem, TxTabItemGroup, and TxTabHeader nodes; anything else is ignored. |
nav-right | - | Actions at the end of the nav bar. |
Exposed Methods
| Name | Type | Description |
|---|---|---|
refresh | () => void | Re-measures the size. |
flip | (action: () => void | Promise<void>) => Promise<void> | Runs a change inside a FLIP transition. |
action | (fn: (el: HTMLElement | undefined) => void | Promise<void>, optionsOrDetect?: any) => Promise<{ changedKeys: string[] } | any> | Forwards to the internal AutoSizer action. |
size | () => { width: number; height: number } | undefined | The last measured size. |
TxTabItem
Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | required | Unique name, also the active value. |
iconClass | string | '' | Icon class shown before the label. |
disabled | boolean | false | Prevents activation. |
activation | boolean | false | Default tab when neither modelValue nor defaultValue selects one. |
active | boolean | false | Whether it is active; injected by TxTabs, set it only when used standalone. |
Events
| Event | Params | Description |
|---|---|---|
click | - | Fires when used standalone and not disabled. |
Slots
| Slot | Props | Description |
|---|---|---|
default | - | Panel content; not mounted while inactive. |
icon | - | Custom icon, replacing iconClass. |
name | - | Custom label; defaults to name. |
TxTabHeader
Props
| Prop | Type | Default | Description |
|---|---|---|---|
node | unknown | - | The active TxTabItem VNode, passed by TxTabs. |
Slots
| Slot | Props | Description |
|---|---|---|
default | { props: { node?: unknown } } | Sticky header above the panel. |
TxTabItemGroup
Props
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | - | Group label in the navigation. |
Slots
| Slot | Props | Description |
|---|---|---|
default | - | Child TxTabItem nodes. |
Overview
- When controlled,
modelValuewins; otherwisedefaultValue, thenactivation. - Only direct
TxTabItem,TxTabItemGroup, andTxTabHeaderchildren count (fragments included); custom wrappers are ignored. - Inactive panels are not mounted.
- The indicator is the only selection highlight. It glides to the target with each end on its own spring and never scales.
- The indicator lands in place on first measure, on size changes, with
animation.indicator: false, and under reduced motion. - Size animation removes the inner scroll container so the panel can be measured directly.
Technologies
- The indicator runs on the glide material of
useJellyIndicator; itsrequestAnimationFrameloop runs only while moving and writes styles directly, without re-rendering. TxTabItemGrouprenders no DOM; TxTabs reads its children and builds the group.- Source:
packages/tuffex/packages/components/src/tabs/.
Customization
| CSS variable | Used for |
|---|---|
--tx-border-color | Outer border and nav divider. |
--tx-bg-color | Container background. |
--tx-fill-color / --tx-fill-color-light | Active fill (without indicator) / hover fill. |
--tx-color-primary | The line, dot, block, and outline indicators and the active icon. |
--tx-surface-raised / --tx-elevation-1 / --tx-border-color-lighter | The pill surface, its shadow, and its inset ring. |
--tx-text-color-primary / --tx-text-color-regular / --tx-text-color-secondary | Active text, resting text, icons and group labels. |
--tx-tab-item-ink / --tx-tab-item-icon-ink | Text and icon color of .tx-tab-item. |
--tx-tabs-indicator-duration / --tx-tabs-indicator-easing / --tx-tabs-indicator-strength | Generated from the indicator props, for hosts to read. |
--tx-tabs-content-duration / --tx-tabs-content-easing | Generated from the content animation props. |
--tx-tabs-nav-duration / --tx-tabs-nav-easing | Generated from the nav animation props. |
查看源码
packages/tuffex/packages/components/src/tabs/index.ts