Home / Docs / PixelSegmented PixelSegmented Single-select segmented control for toggling between a small set of mutually exclusive options inline.
Controlled — value + onChange (React), v-model (Vue), [(value)] or forms (Angular) — over a list of options. Compact horizontal layout for 2-5 options that share visual real estate. Seven tones and pixel/linear surfaces share the kit-wide design tokens. Optional name emits a hidden input so it serializes inside native forms. disabled cascades to every option button (not just visually). Status stable Category forms Since v1.0.0 API React Vue Angular
import { PixelSegmented } from '@pxlkit/ui-kit';Prop Type Default Description labelstring— Caption rendered above the segmented control. Omitted when empty. value* (required) string— Active option value. options* (required) Option[]— Segment items. onChange* (required) (next: string) => void— Fires with the new value when a segment is clicked. disabledbooleanfalseDisables every segment. tone'green' | 'cyan' | 'gold' | 'red' | 'purple' | 'pink' | 'neutral''green'Visual tone for the active segment. Default: 'green'. surface'pixel' | 'linear'— Surface variant. Inherits from PxlKitSurfaceProvider when omitted. namestring— Form-serialization name. requiredboolean— Marks the field as required for native form validation. aria-labelstring— Accessible name for the group; use it when no visible label is rendered.
ref points to <div>.
Accessibility WCAG target: 2.1 AA
Each option renders as a <button> with aria-pressed reflecting the active selection, and aria-disabled mirroring the disabled prop. When name is set a hidden <input> mirrors the current value so the control participates in native <form> submissions. The implementation uses aria-pressed (toggle-button semantics) rather than role="radio" on each button.
Keyboard Key Action When Tab Moves focus to the next option button in the segmented control. — Space Activates the focused option (native <button> behavior). — Enter Activates the focused option (native <button> behavior). —
Usage React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Default() {
const [value, setValue] = useState('grid');
return (
<PixelSegmented
label="View"
value={value}
options={VIEWS}
onChange={setValue}
/>
);
}Examples Default React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Default() {
const [value, setValue] = useState('grid');
return (
<PixelSegmented
label="View"
value={value}
options={VIEWS}
onChange={setValue}
/>
);
}Controlled React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Controlled() {
const [value, setValue] = useState('list');
return (
<div className="space-y-2">
<PixelSegmented
label="Active view"
value={value}
options={VIEWS}
onChange={setValue}
tone="cyan"
/>
<p className="text-xs text-retro-muted">Picked: {value}</p>
</div>
);
}Tones React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Tones() {
const [value, setValue] = useState('grid');
return (
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
<PixelSegmented label="Neutral" tone="neutral" value={value} options={VIEWS} onChange={setValue} />
<PixelSegmented label="Green" tone="green" value={value} options={VIEWS} onChange={setValue} />
<PixelSegmented label="Cyan" tone="cyan" value={value} options={VIEWS} onChange={setValue} />
<PixelSegmented label="Gold" tone="gold" value={value} options={VIEWS} onChange={setValue} />
<PixelSegmented label="Red" tone="red" value={value} options={VIEWS} onChange={setValue} />
<PixelSegmented label="Purple" tone="purple" value={value} options={VIEWS} onChange={setValue} />
<PixelSegmented label="Pink" tone="pink" value={value} options={VIEWS} onChange={setValue} />
</div>
);
}Surfaces React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Surfaces() {
const [pixel, setPixel] = useState('grid');
const [linear, setLinear] = useState('grid');
return (
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
<PixelSegmented
label="Pixel surface"
surface="pixel"
value={pixel}
options={VIEWS}
onChange={setPixel}
/>
<PixelSegmented
label="Linear surface"
surface="linear"
value={linear}
options={VIEWS}
onChange={setLinear}
/>
</div>
);
}Disabled React Vue Angular
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Disabled() {
return (
<PixelSegmented
label="View (locked)"
value="grid"
options={VIEWS}
onChange={() => {}}
disabled
/>
);
}Required React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function Required() {
const [value, setValue] = useState('grid');
return (
<PixelSegmented
label="Choose a view"
value={value}
options={VIEWS}
onChange={setValue}
required
/>
);
}With form name React Vue Angular
import { useState } from 'react';
import { PixelSegmented } from '@pxlkit/ui-kit';
const VIEWS = [
{ value: 'grid', label: 'Grid' },
{ value: 'list', label: 'List' },
{ value: 'kanban', label: 'Kanban' },
];
export function WithFormName() {
const [value, setValue] = useState('grid');
return (
<form>
<PixelSegmented
label="View"
name="view"
value={value}
options={VIEWS}
onChange={setValue}
required
/>
</form>
);
}