Skip to content

Tabs

  • Layer: Component
  • Base: @ark-ui/solid Tabs + Park UI tabs recipe

Horizontal tab bar with a sliding underline indicator. The line variant is the default — minimal, most common. The recipe provides slot class names; triggers require inline horizontal padding because the recipe’s CSS classes may not be emitted in the bundle (see Inline Style Requirements below).

A — UNDERLINE (minimal, most common)

Content for First tab

4-tab layout (used in Settings page)

Backup targets and schedule
import { Tabs } from '@ark-ui/solid/tabs'
import { tabs } from '@risingswamp/design-system/styled-system/recipes'
const slots = tabs({ variant: 'line', size: 'sm' })
<Tabs.Root defaultValue="first" class={slots.root}>
<Tabs.List class={slots.list} style={{
'border-bottom': '1px solid var(--colors-border)',
gap: '8px',
}}>
<Tabs.Trigger value="first" class={slots.trigger} style={{
'font-size': '12px',
'font-family': 'var(--fonts-sans)',
'letter-spacing': '0.05em',
'text-transform': 'uppercase',
background: 'transparent',
border: 'none',
cursor: 'pointer',
padding: '0 10px 8px 0', // first tab: no left pad
}}>First</Tabs.Trigger>
<Tabs.Trigger value="second" class={slots.trigger} style={{
/* same base styles */
padding: '0 10px 8px 10px', // middle tabs: full horizontal pad
}}>Second</Tabs.Trigger>
<Tabs.Trigger value="last" class={slots.trigger} style={{
/* same base styles */
padding: '0 0 8px 10px', // last tab: no right pad
}}>Last</Tabs.Trigger>
<Tabs.Indicator class={slots.indicator} />
</Tabs.List>
<Tabs.Content value="first" class={slots.content}>…</Tabs.Content>
<Tabs.Content value="second" class={slots.content}>…</Tabs.Content>
<Tabs.Content value="last" class={slots.content}>…</Tabs.Content>
</Tabs.Root>
VariantDescription
lineUnderline indicator only — minimal, default
enclosedBordered tabs with contained panel
outlineOutlined triggers, no filled panel
SizeTrigger heightFont size
sm32px12px
md40px14px (default)
lg48px16px

The Park UI tabs recipe defines px: '2.5' (10px) horizontal padding on triggers via compound variants, but these CSS classes may not be emitted in the generated stylesheet bundle. Always supplement with inline horizontal padding on triggers:

PositionPadding value
First triggerpadding: '0 10px 8px 0' (no left pad)
Middle triggerspadding: '0 10px 8px 10px'
Last triggerpadding: '0 0 8px 10px' (no right pad)

The gap: '8px' on Tabs.List also needs to be set inline.

  • Each Tabs.Trigger gets role="tab" and aria-selected via Ark UI
  • Tabs.Content gets role="tabpanel" and aria-labelledby automatically
  • Arrow keys navigate between tabs; Enter/Space activates
  • Tabs.Indicator is aria-hidden and purely visual
TokenUsage
--colors-borderList bottom border, list gap colour
--colors-fgActive trigger text
--colors-text-mutedInactive trigger text
--colors-accentIndicator bar colour
--fonts-sansTrigger label font