Segmented control
In reviewLive · web
com.dizyx.nockerl.design.components.NockerlSegmented
View mode: the pill slides; the preview below swaps (Tab in, Arrow keys)
Text only: 2 · 3 · 5 segments
NockerlIcon + label · icon only, sm and md
A disabled segment: skipped by arrow keys, still legible
Full-width: equal-share segments fill the row
Disabled control: dimmed but readable, not interactive
Viewing list · range week · diff unified. The pill slides to the active segment. The island is live.
// Web: React, consuming @dizyx/nockerl-tokens. (Web is the laggard platform;// this is the canonical API the published @dizyx/nockerl-react package exposes.)import { NockerlSegmentedControl } from '@dizyx/nockerl-react';
export function TaskViewSwitch() { const [view, setView] = useState('list'); return ( <> <NockerlSegmentedControl label="Task view" value={view} onChange={setView} segments={[ { value: 'list', label: 'List', icon: 'list' }, { value: 'grid', label: 'Grid', icon: 'grid' }, { value: 'board', label: 'Board', icon: 'board' }, ]} /> {view === 'list' ? <TaskList /> : view === 'grid' ? <TaskGrid /> : <TaskBoard />} </> );}
// NockerlIcon-only, compact: pass `icon` + `title` (the accessible name) and no `label`.<NockerlSegmentedControl label="Appearance" size="sm" value={theme} onChange={setTheme} segments={[ { value: 'light', icon: 'sun', title: 'Light' }, { value: 'dark', icon: 'moon', title: 'Dark' }, { value: 'auto', icon: 'auto', title: 'Auto' }, ]} />// (com.dizyx.nockerl.design on GitHub Packages Maven). One muted track; the ACTIVE// segment is filled with SOFT cyan + a cyan medium label; the rest stay transparent +// muted. Pass Modifier.fillMaxWidth() for a full-width control.import com.dizyx.nockerl.design.components.NockerlSegmented
enum class TaskView(val display: String) { LIST("List"), GRID("Grid"), BOARD("Board") }
var view by remember { mutableStateOf(TaskView.LIST) }
NockerlSegmented( options = TaskView.entries.toList(), selected = view, onSelect = { view = it }, label = { it.display }, modifier = Modifier.fillMaxWidth(),)// macOS SwiftUI (canonical). NockerlVoice/UI/SettingsComponents.swift// The active option is a cyan OUTLINE (the 1pt @0.45 selection weight), not a fill;// equal-width segments// on an inset `canvasAlt` track.SegmentedSelector( options: TaskView.allCases, selection: $view) { $0.label }
// System stand-in (more segments / native feel), the platform segmented picker:Picker("Task view", selection: $view) { ForEach(TaskView.allCases) { view in Text(view.label).tag(view) }}.pickerStyle(.segmented)Parameters
Section titled “Parameters”| Prop | Type | Default | Description |
|---|---|---|---|
segments * | Segment[] | The segments, left-to-right. 2-5 mutually-exclusive peers. | |
value * | string | The currently-active value (controlled). Exactly one is selected. | |
onChange | (next: string) => void | Fired with the next value. Ignored for a disabled segment. | |
label * | string | Accessible name for the group (wired via aria-label). | |
size | SegmentSize | 'md' | Control height + padding + type role. |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Track axis. horizontal (default) = segments in a row, pill slides X. vertical = segments stacked, pill slides Y (e.g. an AM/PM meridiem in a narrow slot). Additive: omitting it is a no-op for existing (horizontal) consumers. |
fullWidth | boolean | false | Stretch to fill the row (equal-width segments) vs. hug its content. |
disabled | boolean | false | Dim + disable the whole control. |
Also accepts the native <div> attributes (e.g. onClick, disabled, id, aria-*, data-*), forwarded straight through, plus a forwarded ref.
| Parameter | Type | Default | Description |
|---|---|---|---|
options * | List<T> | The segments, in order (typically an enum). Each gets an equal-weight share of the track. | |
selected * | T | The currently-active option. Its segment gets the soft-cyan fill + cyan medium-weight label. | |
onSelect * | (T) -> Unit | Invoked with the tapped option. No-op while enabled = false. | |
label * | (T) -> String | Maps an option to its display string (e.g. { it.display }). | |
modifier | Modifier | Modifier | Outer modifier. Pass Modifier.fillMaxWidth() for a full-width control. |
enabled | Boolean | true | When false, the whole control is dimmed (alpha) and non-interactive. |
SwiftUI exposes the control as the custom SegmentedSelector (cyan outline) or a
system Picker(.segmented). State is two-way bound; there are no per-segment
state parameters.
| Style | Type | Default | Description |
|---|---|---|---|
options | [Option] | The segments (Hashable & Identifiable), rendered left-to-right as equal-width segments. | |
selection | Binding<Option> | Two-way bound active option. The active segment gets a cyan outline at the selection weight (border.width.selection @ border.opacity.selection), not a fill. | |
label | (Option) -> String | Maps an option to its visible text (e.g. { $0.label }). | |
.pickerStyle | PickerStyle | System stand-in: .segmented for the native segmented look on a standard Picker. |