Skip to main content
Urbicon UI
source

Segment Group

Segment control with an animated sliding indicator for single selection; collapses to a vertical stack when its row can't fit.

Playground

Variant Style variant (tailwind-variants)
Size Style variant (tailwind-variants)
Tier Style variant (tailwind-variants)
<SegmentGroup>
  <SegmentItem value="list">List</SegmentItem>
  <SegmentItem value="grid">Grid</SegmentItem>
  <SegmentItem value="board">Board</SegmentItem>
</SegmentGroup>

01 Examples

Time-Range Selector

Compact range picker for charts and dashboards. Works well with 2 to 5 options — beyond that, consider a Menu or Tab.
<SegmentGroup value="1h" ariaLabel="Time range">
  <SegmentItem value="1h">1H</SegmentItem>
  <SegmentItem value="6h">6H</SegmentItem>
  <SegmentItem value="1d">1D</SegmentItem>
  <SegmentItem value="1w">1W</SegmentItem>
  <SegmentItem value="1m">1M</SegmentItem>
</SegmentGroup>

Per-Item Disabled

Disable individual segments while the rest of the group stays interactive. Keyboard navigation skips disabled items.
<SegmentGroup value="a" ariaLabel="Partial disabled example">
  <SegmentItem value="a">Available</SegmentItem>
  <SegmentItem value="b" disabled>Unavailable</SegmentItem>
  <SegmentItem value="c">Available</SegmentItem>
</SegmentGroup>

Theme Switcher

Embedded in a settings panel with two-way binding.
Appearance
<div
  class="border-border-subtle bg-surface-elevated flex w-full max-w-sm items-center justify-between rounded-2xl border p-4"
>
  <span class="text-text-primary text-sm font-medium">Appearance</span>
  <SegmentGroup bind:value={theme} size="sm" mint="scale" ariaLabel="Theme preference">
    <SegmentItem value="light">Light</SegmentItem>
    <SegmentItem value="dark">Dark</SegmentItem>
    <SegmentItem value="system">System</SegmentItem>
  </SegmentGroup>
</div>

02 Micro-Interactions

Configured Mint

The Playground toggles single mints — for richer effects, combine multiple mints in an array, or use the object form to fine-tune intensity and duration.
<SegmentGroup
  value="pro"
  mint={[{ name: 'scale', config: { intensity: 1.03, duration: 200 } }, 'glow']}
  ariaLabel="Configured mint"
>
  <SegmentItem value="free">Free</SegmentItem>
  <SegmentItem value="pro">Pro</SegmentItem>
  <SegmentItem value="enterprise">Enterprise</SegmentItem>
</SegmentGroup>

03 Choosing the Right Component

SegmentGroup

Compact mode/view switcher with animated sliding indicator. Best for 2-5 mutually exclusive options that don't control content panels. Minimal API, single neutral style.

ButtonGroup selection="single"

Toolbar-style toggle with full button styling (variants, intents, connected borders). Choose this when you need visual customization, multi-select, or connected button layouts.

RadioGroup

Form input with labels, descriptions, helper/error text, and native <input type="radio">. Choose this when collecting data in forms or when options need descriptions.

Tab

Content panel navigation where each option reveals a different panel. Uses role="tablist" semantics. Choose this when switching between content sections, not selecting a value.

04 Customization

Gradient Pricing Toggle

slotClasses transforms the neutral control into a branded pricing switcher.
<SegmentGroup
  bind:value={pricing}
  mint={['scale', 'glow']}
  slotClasses={{
    base: 'bg-linear-to-r from-violet-500/15 to-fuchsia-500/15 border border-violet-500/20',
    indicator: 'bg-linear-to-r from-violet-600 to-fuchsia-500 shadow-lg shadow-violet-500/30',
    item: 'text-violet-300 data-[state=active]:text-white'
  }}
  ariaLabel="Pricing tier"
>
  <SegmentItem value="free">Free</SegmentItem>
  <SegmentItem value="pro">Pro</SegmentItem>
  <SegmentItem value="enterprise">Enterprise</SegmentItem>
</SegmentGroup>

Neon Chart Switcher

Dark-themed control with neon glow – all via slotClasses, no unstyled needed.
<SegmentGroup
  bind:value={chartType}
  mint="scale"
  slotClasses={{
    base: 'bg-neutral-900 border border-emerald-500/20',
    indicator:
      'bg-emerald-500/20 shadow-[0_0_15px_rgba(52,211,153,0.25)] border border-emerald-400/40',
    item: 'text-neutral-500 data-[state=active]:text-emerald-400'
  }}
  ariaLabel="Chart type"
>
  <SegmentItem value="line">Line</SegmentItem>
  <SegmentItem value="bar">Bar</SegmentItem>
  <SegmentItem value="area">Area</SegmentItem>
</SegmentGroup>

Glassmorphism

Frosted glass effect with backdrop-blur on a vibrant background.
<SegmentGroup
  value="overview"
  mint="scale"
  slotClasses={{
    base: 'bg-white/10 backdrop-blur-md border border-white/20 shadow-lg',
    indicator: 'bg-white/25 backdrop-blur-sm shadow-lg',
    item: 'text-white/60 data-[state=active]:text-white'
  }}
  ariaLabel="Glass navigation"
>
  <SegmentItem value="overview">Overview</SegmentItem>
  <SegmentItem value="details">Details</SegmentItem>
  <SegmentItem value="history">History</SegmentItem>
</SegmentGroup>

Fully Custom (unstyled)

Drop all default styles. The sliding indicator, keyboard nav, and mint still work.
<SegmentGroup
  value="bold"
  unstyled
  mint="scale"
  class="inline-flex gap-1 rounded-2xl bg-linear-to-br from-amber-200 to-orange-400 p-1.5 shadow-xl"
  slotClasses={{
    indicator: 'rounded-xl bg-white/80 shadow-md',
    item: 'relative z-[var(--z-docked)] rounded-xl px-5 py-2 text-sm font-bold text-orange-950/80 transition-colors data-[state=active]:text-orange-900'
  }}
  ariaLabel="Unstyled warm"
>
  <SegmentItem value="bold">Bold</SegmentItem>
  <SegmentItem value="vibrant">Vibrant</SegmentItem>
  <SegmentItem value="muted">Muted</SegmentItem>
</SegmentGroup>
<SegmentGroup
  value="deploy"
  unstyled
  class="inline-flex gap-0 border-2 border-current p-0 font-mono text-sm"
  slotClasses={{
    indicator: 'bg-text-primary',
    item: 'text-text-primary relative z-[var(--z-docked)] border-r border-current px-5 py-2.5 font-bold tracking-widest uppercase transition-colors last:border-r-0 data-[state=active]:text-surface-base'
  }}
  ariaLabel="Unstyled brutalist"
>
  <SegmentItem value="staging">Staging</SegmentItem>
  <SegmentItem value="deploy">Deploy</SegmentItem>
  <SegmentItem value="rollback">Rollback</SegmentItem>
</SegmentGroup>

A switcher chrome reused across settings panels belongs in BlocksProvider presets (presets.SegmentGroup, item styling under presets.SegmentItem) — apply with preset instead of repeating slotClasses. See Customization.

05 Accessibility

ARIA

The container uses role="radiogroup" with each item as role="radio" + aria-checked. Provide ariaLabel to describe the group's purpose.

Keyboard

Arrow keys move between options and select immediately. Home / End jump to first/last option. Only the active item is in the tab order (roving tabindex).

Visual States

Active items expose data-state="active" for CSS-only styling in unstyled mode. The sliding indicator uses aria-hidden="true" since it is purely decorative. Focus rings use focus-visible: for keyboard-only visibility.

06 API Reference

17 props
17 props
Prop
Type
Default
Description

07 Types

Local type definitions used by this component.

10 types
Name
Kind
Category
Used by
Description

08 Installation

Import

import { SegmentGroup, SegmentItem } from '@urbicon-ui/blocks';