生态产品多个设计器现已发布候选版本

查看生态总览
Skip to content

Tabs ​

Navigation component. This page is the API reference, generated from the source code. Usage guidance and live examples are on the Chinese page.

Anatomy ​

Parts in bold are required.

data-scope="tabs": root · list · trigger · close-trigger · indicator · separator · prev-trigger · next-trigger · overflow-trigger · content · tab-drag-trigger · live-region

API reference ​

Descriptions of individual props, events and slots are written in Chinese and appear on the Chinese page.

Artifacts ​

LayerValue
Custom element<xh-tabs>
Vue componentsXhTabsCloseTrigger XhTabsContent XhTabsIndicator XhTabsList XhTabsLiveRegion XhTabsNextTrigger XhTabsOverflowTrigger XhTabsPrevTrigger XhTabsRoot XhTabsSeparator XhTabsTabDragTrigger XhTabsTrigger
ComposableuseTabs
State machinetabsMachine
Skin@xihan-ui/styles/tabs.css

Props ​

PropTypeRequired
collectionTabsNode[]
valuestring | null
defaultValuestring | null
orientationOrientation
dirDirection
activationModeTabsActivationMode
loopboolean
variantTabsVariant
toneTone
sizeSize
reorderableboolean
onTabMove(details: TabsMoveDetails) => void
closableboolean
onTabClose(details: TabsCloseDetails) => void
lazyMountboolean
unmountOnExitboolean
translationsPartial<TabsTranslations>
onValueChange(details: TabsValueChangeDetails) => void

TabsNode ​

Elements of collection.

FieldTypeRequired
valuestringYes
labelstring
disabledboolean

Events ​

Custom elements put the payload in detail; Vue emits an event of the same name.

EventPayload
value-changeTabsValueChangeDetails
tab-moveTabsMoveDetails
tab-closeTabsCloseDetails

React adapter props ​

Only the props each component declares itself: DOM attributes inherited from ComponentPropsWithRef are left out, and root props already listed in the Props table are not repeated. The Vue counterpart is the slot table above.

React componentPropTypeRequired
XhTabsCloseTriggervaluestringYes
XhTabsCloseTriggerdisabledboolean
XhTabsContentvaluestringYes
XhTabsRootrenderPanel(node: TabsNodeMeta) => ReactNode
XhTabsRootchildrenReactNode
XhTabsTabDragTriggervaluestringYes
XhTabsTriggervaluestringYes
XhTabsTriggerdisabledboolean

State ​

Public state is written to data-state.

PartValues
trigger'active' | 'inactive'
content'active' | 'inactive'

The following names are internal to the state machine.

States: idle

Events: VALUE.SET · TRIGGER.SELECT · TRIGGER.FOCUS · TRIGGER.NAVIGATE · LIST.BLUR · TAB_DRAG.START · TAB_DRAG.MOVE · TAB_DRAG.END · TAB_DRAG.CANCEL · TAB.MOVE_BY · TAB.CLOSE · PRESS.START · PRESS.END · SCROLL.PREV · SCROLL.NEXT · SCROLL.BY · SCROLL.FRAME · PAN.START · PAN.MOVE · PAN.END · PAN.CANCEL · OVERFLOW.SELECT

Guards: isAutomatic · canPress

connect API ​

getXxxProps() returns the host attributes of the matching part.

MemberType
valuestring | null
collectionreadonly TabsNodeMeta[]
focusedValuestring | null
dropTargetDropTarget | null
announcementstring
overflowTabsOverflow | null
overflowItemsreadonly TabsOverflowItem[]
setValue(next: string | null) => void
getRootProps() => T['element']
getListProps() => T['element']
getTriggerProps(props: TabsTriggerProps) => T['button']
getCloseTriggerProps(props: TabsTriggerProps) => T['button']
isContentMounted(value: string) => boolean
getIndicatorProps() => T['element']
getSeparatorProps() => T['element']
getPrevTriggerProps() => T['button']
getNextTriggerProps() => T['button']
getOverflowTriggerProps() => T['button']
getContentProps(props: TabsContentProps) => T['element']
getTabDragTriggerProps(props: TabsTriggerProps) => T['element']
getLiveRegionProps() => T['element']

Accessibility ​

Keyboard ​

Specification: W3C APG. Each row is a stable behavior id that the conformance tests cover; the conditions and effects are described on the Chinese page.

KeysBehavior
ArrowRight / ArrowDowntabs.kbd.next
ArrowLeft / ArrowUptabs.kbd.prev
Hometabs.kbd.first
Endtabs.kbd.last
Enter / Spacetabs.kbd.activate
Enter / Spacetabs.kbd.press
Delete / Backspacetabs.kbd.close
Tab / Shift+Tabtabs.kbd.tab
Tab / Shift+Tabtabs.kbd.overflow-stop
Enter / Space / ArrowDown / ArrowUptabs.kbd.overflow-open
Escapetabs.kbd.overflow-close
Alt+ArrowLeft / Alt+ArrowRight / Alt+ArrowUp / Alt+ArrowDowntabs.kbd.tab-move

ARIA ​

These attributes are produced by connect.

PartAttributeValue
listaria-orientationprops.orientation
listrole'tablist'
triggeraria-controlsid of the content part
triggeraria-disabled'true' | 'false'
triggeraria-selected'true' | 'false'
triggerrole'tab'
close-triggeraria-hidden'true'
indicatoraria-hidden'true'
separatoraria-hidden'true'
prev-triggeraria-hidden'true'
next-triggeraria-hidden'true'
overflow-triggeraria-labeltranslations.overflowTrigger
contentaria-labelledbyid of the trigger part
contentrole'tabpanel'
tab-drag-triggeraria-hidden'true'
live-regionaria-atomic'true'
live-regionaria-live'polite'
live-regionrole'status'

Style reference ​

Skin ​

@xihan-ui/styles/tabs.css is written against [data-scope="tabs"][data-part="root"] part selectors; the published build uses the mount class .xh-scope-tabs in place of data-scope (same specificity) and sits in the xihan.components layer. Put overrides in xihan.overrides; the part selectors work as usual.

Data attributes ​

Produced by connect; valueless attributes are omitted while their condition does not hold.

PartAttributeValue
rootdata-orientationprops.orientation
rootdata-sizeprops.size
rootdata-toneprops.tone
rootdata-variantprops.variant
triggerdata-closable'' (present only while the condition holds)
triggerdata-current'' (present only while the condition holds)
triggerdata-disabled'' (present only while the condition holds)
triggerdata-draggable'' (present only while the condition holds)
triggerdata-dragging'' (present only while the condition holds)
triggerdata-drop'before' | 'after'
triggerdata-pressed'' (present only while the condition holds)
triggerdata-state'active' | 'inactive'
triggerdata-xh-collection-context'nav' | undefined
triggerdata-xh-collection-item'' (present only while the condition holds)
triggerdata-xh-collection-sizeprops.size | undefined
close-triggerdata-disabled'' (present only while the condition holds)
close-triggerdata-xh-action-control''
close-triggerdata-xh-action-display'always'
close-triggerdata-xh-action-profile'icon'
close-triggerdata-xh-action-size'xs'
close-triggerdata-xh-action-variant'ghost'
indicatordata-instant'' (present only while the condition holds)
indicatordata-orientationprops.orientation
indicatordata-valueitem.value
indicatordata-variantprops.variant
separatordata-orientationprops.orientation
prev-triggerdata-disabled'' (present only while the condition holds)
prev-triggerdata-orientationprops.orientation
prev-triggerdata-xh-action-control''
prev-triggerdata-xh-action-display'always'
prev-triggerdata-xh-action-profile'icon'
prev-triggerdata-xh-action-sizeprops.size
prev-triggerdata-xh-action-variant'ghost'
next-triggerdata-disabled'' (present only while the condition holds)
next-triggerdata-orientationprops.orientation
next-triggerdata-xh-action-control''
next-triggerdata-xh-action-display'always'
next-triggerdata-xh-action-profile'icon'
next-triggerdata-xh-action-sizeprops.size
next-triggerdata-xh-action-variant'ghost'
overflow-triggerdata-orientationprops.orientation
overflow-triggerdata-xh-action-control''
overflow-triggerdata-xh-action-display'always'
overflow-triggerdata-xh-action-profile'icon'
overflow-triggerdata-xh-action-sizeprops.size
overflow-triggerdata-xh-action-variant'ghost'
contentdata-state'active' | 'inactive'
tab-drag-triggerdata-disabled'' (present only while the condition holds)
tab-drag-triggerdata-dragging'' (present only while the condition holds)

CSS variables ​

The public override slots, generated from what the standalone skin actually consumes.

VariablePartCSS propertyStateDefault from
--xh-tabs-content-fgcontentcolordefault--xh-fg-default
--xh-tabs-content-pycontentpadding-blockdefault--xh-stack-gap-md
--xh-tabs-drag-fgtab-drag-triggercolordefault--xh-fg-subtle
--xh-tabs-drag-fg-activetab-drag-triggercolordisabled
dragging
hover
not([data-disabled])
--xh-fg-default
--xh-tabs-drag-fg-disabledtab-drag-triggercolordisabled--xh-fg-disabled
--xh-tabs-drag-grip-longroot
tab-drag-trigger
block-size
inline-size
empty
orientation=vertical
--xh-space-2
--xh-tabs-drag-grip-shortroot
tab-drag-trigger
block-size
inline-size
empty
orientation=vertical
--xh-space-1
--xh-tabs-drag-radiustab-drag-triggerborder-radiusdefault--xh-shape-control
--xh-tabs-drag-sizetab-drag-triggerblock-size
inline-size
default--xh-control-indicator-size
--xh-tabs-dragging-opacitytriggeropacitydragging--xh-state-dragging-opacity
--xh-tabs-drop-fgtriggerbackgrounddrop=after
drop=before
is([data-drop='before'], [data-drop='after'])
--xh-bg-brand
--xh-tabs-drop-lineroot
trigger
block-size
inline-size
drop=after
drop=before
is([data-drop='before'], [data-drop='after'])
orientation=horizontal
orientation=vertical
--xh-stroke-thick
--xh-tabs-gaprootcolumn-gap
gap
row-gap
default
has(> [data-scope='tabs'][data-part='overflow-trigger'])
orientation=vertical
--xh-stack-gap-md
--xh-tabs-indicator-colorindicator
root
trigger
backgroundcurrent
default
drop
not([data-drop])
variant=line
--xh-_tabs-accent
--xh-tabs-indicator-radiusindicator
root
trigger
border-radiuscurrent
default
drop
not([data-drop])
variant=line
--xh-shape-pill
--xh-tabs-indicator-thicknessindicator
root
trigger
block-size
inline-size
current
default
drop
not([data-drop])
not([data-variant='segment'])
orientation=horizontal
orientation=vertical
variant=line
variant=segment
--xh-stroke-thick
--xh-tabs-list-bglistbackgrounddefault--xh-_tabs-list-bg
--xh-tabs-list-borderlist
root
border
border-block-end
border-inline-end
default
variant=segment
--xh-border-default
transparent
--xh-tabs-list-gapclose-trigger
list
root
gap
margin-block-start
margin-inline-start
default
orientation=vertical
--xh-_tabs-list-gap
--xh-tabs-list-plist
next-trigger
prev-trigger
inset-block-end
inset-block-start
inset-inline
inset-inline-end
inset-inline-start
padding
default
orientation=vertical
--xh-_tabs-list-p
--xh-tabs-list-radiuslistborder-radiusdefault--xh-_tabs-list-radius
--xh-tabs-scroll-icon-sizenext-trigger
prev-trigger
--xh-icon-sizedefault--xh-_action-profile-glyph-size
--xh-tabs-scroll-trigger-bgnext-trigger
prev-trigger
--xh-ink-surface
background-color
default
disabled
focus-visible
xh-ink-surface
--xh-_tabs-scroll-trigger-bg
--xh-tabs-scroll-trigger-fgnext-trigger
prev-trigger
colordefault--xh-fg-muted
--xh-tabs-separator-colorseparatorbackgrounddefault--xh-border-default
--xh-tabs-separator-radiusseparatorborder-radiusdefault--xh-shape-pill
--xh-tabs-separator-sizeseparatorblock-sizedefault--xh-space-4
--xh-tabs-separator-thicknessseparatorblock-size
inline-size
default
orientation=vertical
--xh-stroke-thin
--xh-tabs-trigger-bgroot
trigger
background
background-color
is([data-variant='card'], [data-variant='segment'])
variant=card
variant=line
variant=segment
xh-collection-context=nav
transparent
--xh-tabs-trigger-bg-activeindicator
root
trigger
background
background-color
current
disabled
error
is([data-variant='card'], [data-variant='segment'])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
state=active
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-_tabs-trigger-bg-active
--xh-_tone-subtle
transparent
--xh-tabs-trigger-bg-active-hoverroot
trigger
background
background-color
current
disabled
error
hover
is([data-variant='card'], [data-variant='segment'])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
not([data-disabled])
state=active
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-_tabs-trigger-bg-active-hover
--xh-bg-subtle
--xh-tabs-trigger-bg-hoverroot
trigger
background
background-color
disabled
error
hover
is([data-variant='card'], [data-variant='segment'])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
not([data-disabled])
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-_tabs-trigger-bg-hover
--xh-bg-subtle
--xh-tabs-trigger-bg-pressedroot
trigger
background
background-color
disabled
error
is(:active, [data-pressed])
is([data-variant='card'], [data-variant='segment'])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
not([data-disabled])
not([data-state='active'])
pressed
state=active
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-_tabs-trigger-bg-pressed
--xh-bg-subtle-hover
--xh-tabs-trigger-bordertriggerborderdefault--xh-_tabs-trigger-border
--xh-tabs-trigger-border-activeindicator
root
trigger
border
border-color
is([data-variant='card'], [data-variant='segment'])
state=active
variant=card
variant=segment
--xh-_tabs-trigger-border-active
--xh-_tone-border
--xh-tabs-trigger-fgroot
trigger
coloris([data-variant='card'], [data-variant='segment'])
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-fg-muted
--xh-tabs-trigger-fg-activeroot
trigger
colorcurrent
disabled
error
highlighted
hover
is(:active, [data-pressed])
is(:focus-visible, [data-highlighted])
is([data-variant='card'], [data-variant='segment'])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
pressed
state=active
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-_tabs-accent-text
--xh-_tabs-accent-text-strong
--xh-tabs-trigger-fg-hoverroot
trigger
colordisabled
error
hover
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
variant=line
xh-collection-context=nav
--xh-fg-default
--xh-tabs-trigger-fg-pressedroot
trigger
colordisabled
error
is(:active, [data-pressed])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
pressed
variant=line
xh-collection-context=nav
--xh-fg-default
--xh-tabs-trigger-font-sizetriggerfont-sizedefault--xh-_tabs-trigger-font-size
--xh-tabs-trigger-font-weightroot
trigger
font-weightis([data-variant='card'], [data-variant='segment'])
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-font-weight-regular
--xh-text-label-weight
--xh-tabs-trigger-font-weight-activeroot
trigger
font-weightcurrent
disabled
error
is([data-variant='card'], [data-variant='segment'])
not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])
state=active
variant=card
variant=line
variant=segment
xh-collection-context=nav
--xh-font-weight-medium
--xh-tabs-trigger-gaptriggergapdefault--xh-control-gap-md
--xh-tabs-trigger-hclose-trigger
next-trigger
overflow-trigger
prev-trigger
root
trigger
block-size
inline-size
margin-block-end
margin-block-start
margin-inline-end
margin-inline-start
padding-inline-end
default
has(+ [data-scope='tabs'][data-part='close-trigger']:not([hidden])
orientation=vertical
xh-action-profile=icon
--xh-_tabs-trigger-h
--xh-tabs-trigger-pxtriggerpadding-inlinedefault--xh-_tabs-trigger-px
--xh-tabs-trigger-radiusindicator
trigger
border-radiusdefault
variant=segment
--xh-_tabs-trigger-radius
--xh-shape-inset
--xh-tabs-trigger-shadow-activeindicator
root
trigger
box-shadowis([data-variant='card'], [data-variant='segment'])
state=active
variant=card
variant=segment
--xh-_tabs-trigger-shadow-active
--xh-elevation-raised

Released under The MIT License