Segmented control <l-segmented-control>
A single-select switch between a few mutually-exclusive options, with a sliding pill behind the selected segment.
<l-segmented-control><l-segmented-control
label="View"
value="list"
>
<button value="list">List</button>
<button value="board">Board</button>
<button value="calendar">Calendar</button>
</l-segmented-control>Each segment is a native <button>. Set value on the control to the value of the initially-selected segment; the control emits a change event with the new value when the selection changes.
Options
Label
Add label to give the control an accessible name announced by screen readers.
Code
<l-segmented-control
label="View"
value="list"
>
<button value="list">List</button>
<button value="board">Board</button>
<button value="calendar">Calendar</button>
</l-segmented-control>Sizes
Add size (sm, lg, xl) to align the control with buttons and form controls of the same size. Defaults to md.
Code
<div class="flex flex-col items-start gap-3">
<l-segmented-control
label="Size sm"
size="sm"
>
<button value="day">Day</button>
<button value="week">Week</button>
<button value="month">Month</button>
</l-segmented-control>
<l-segmented-control label="Size md">
<button value="day">Day</button>
<button value="week">Week</button>
<button value="month">Month</button>
</l-segmented-control>
<l-segmented-control
label="Size lg"
size="lg"
>
<button value="day">Day</button>
<button value="week">Week</button>
<button value="month">Month</button>
</l-segmented-control>
</div>Full width
Add full-width to stretch the segments to fill the container.
Code
<l-segmented-control
label="Billing period"
value="yearly"
full-width
class="w-full"
>
<button value="monthly">Monthly</button>
<button value="yearly">Yearly</button>
</l-segmented-control>Form field
It is form-associated: add name and the selected value is submitted with the form, like a native radio group. Reset restores the initial selection, and disabled opts the control out of submission.
Code
<form class="flex flex-col items-start gap-3">
<l-segmented-control
name="billing"
label="Billing period"
value="yearly"
>
<button value="monthly">Monthly</button>
<button value="yearly">Yearly</button>
</l-segmented-control>
<button
class="l-button"
type="reset"
>
Reset
</button>
</form>Examples
With icons
Place an <l-icon> before the label inside a segment.
Code
<l-segmented-control label="Source">
<button value="github">
<l-icon name="lucide:github"></l-icon>
GitHub
</button>
<button value="dribbble">
<l-icon name="lucide:dribbble"></l-icon>
Dribbble
</button>
<button value="youtube">
<l-icon name="lucide:youtube"></l-icon>
YouTube
</button>
</l-segmented-control>Icon-only
A segment with no text is squared automatically. Give each one an aria-label.
Code
<l-segmented-control label="Text alignment">
<button
value="left"
aria-label="Align left"
>
<l-icon name="lucide:align-left"></l-icon>
</button>
<button
value="center"
aria-label="Align center"
>
<l-icon name="lucide:align-center"></l-icon>
</button>
<button
value="right"
aria-label="Align right"
>
<l-icon name="lucide:align-right"></l-icon>
</button>
</l-segmented-control>Filter toolbar
Segmented controls line up with .l-button triggers and l-select at the same size, so a filter bar stays visually consistent. Here the dropdowns take a quiet neutral fill (bg-fill-neutral-subtle) so the chrome recedes and the active selections carry the emphasis.
Code
<div class="flex flex-wrap items-center gap-2">
<button class="l-button bg-fill-neutral-subtle">
<l-icon name="lucide:layout-list"></l-icon>
List view
<l-icon name="lucide:chevron-down"></l-icon>
</button>
<button class="l-button bg-fill-neutral-subtle">
<l-icon name="lucide:arrow-down-narrow-wide"></l-icon>
Sort
<l-icon name="lucide:chevron-down"></l-icon>
</button>
<l-segmented-control
label="Metric"
value="cost"
>
<button value="volume">Volume</button>
<button value="cost">Cost</button>
</l-segmented-control>
<l-segmented-control
label="Color"
value="all"
>
<button value="all">All</button>
<button value="color">
<span class="size-2.5 rounded-[3px] bg-[#ef4444]"></span>
Color
</button>
<button value="black">
<span class="size-2.5 rounded-[3px] bg-[#64748b]"></span>
Black
</button>
</l-segmented-control>
</div>Accessibility
Criteria
Keyboard interactions
API reference
Importing
import 'luxen-ui/segmented-control';@import 'luxen-ui/css/segmented-control';Attributes & Properties
valuestringProperty- Value of the selected segment (its
valueattribute, else its index). sizeSegmentedControlSizedefault:'md'Property- Control height, aligned with buttons and form controls at the same size.
labelstring | undefinedProperty- Accessible label announced for the group. Not displayed on screen.
full-widthbooleandefault:falseProperty- Stretch segments to fill the container width.
Events
changeEvent- Fired when the selected segment changes. Not cancelable. Bubbles. Properties:
value: string,index: number.
CSS custom properties
--indicator-colordefault:var(--l-color-surface)Custom property- Background of the sliding pill behind the selected segment.
--border-radiusdefault:var(--l-radius-lg)Custom property- Corner radius of the track.