import { Component } from '@angular/core';
import { WrSegmented } from 'ngwr/segmented';
@Component({ imports: [WrSegmented] })
export class MyComponent {}Segmented
Pick one option from a row of buttons.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Basic usage
Bind the picked value with [(value)] or any Angular form.
<wr-segmented [options]="options" [(value)]="range" />With icons
Give an option an icon; an icon-only one needs an ariaLabel.
<wr-segmented
[options]="[
{ value: 'light', label: 'Light', icon: 'sun' },
{ value: 'dark', label: 'Dark', icon: 'moon' },
]"
[(value)]="mode"
/>Signal Forms
Inside <wr-form-field>, [formField] binds the value and the field labels the strip and shows its errors.
import { Component, signal } from '@angular/core';
import { FormField, form, required } from '@angular/forms/signals';
import { WrFormField } from 'ngwr/form';
import { WrSegmented, type WrSegmentedOption } from 'ngwr/segmented';
@Component({
selector: 'app-schedule',
imports: [FormField, WrFormField, WrSegmented],
template: `
<wr-form-field label="Range">
<wr-segmented [options]="ranges" [formField]="schedule.range" />
</wr-form-field>
`,
})
export class ScheduleComponent {
protected readonly ranges: readonly WrSegmentedOption<string>[] = [
{ value: 'day', label: 'Day' },
{ value: 'week', label: 'Week' },
{ value: 'month', label: 'Month' },
];
private readonly model = signal({ range: '' });
protected readonly schedule = form(this.model, path => {
required(path.range, { message: 'Pick a range.' });
});
}Keyboard
Tab moves between segments; Enter / Space picks one.
Types
interface WrSegmentedOption<T = unknown> {
value: T;
label?: string;
icon?: WrIconName;
disabled?: boolean;
/** Accessible name for an icon-only segment, which has no text to read. */
ariaLabel?: string;
}| Name | Description | Type | Default |
|---|---|---|---|
ariaLabel | Accessible name for an icon-only option. Falls back to value. | string | — |
WrSegmentedOption | One entry in the track. | interface | — |
valuerequired | Model value when this segment is picked. | T | — |
label | Visible text; omit for icon-only segments. | string | — |
icon | Leading icon. | WrIconName | — |
disabled | Disable this segment. | boolean | false |
API
| Name | Description | Type | Default |
|---|---|---|---|
optionsrequired | The segments to render. | readonly WrSegmentedOption<T>[] | — |
value | The picked segment's value, null when nothing is selected. Bound by [formField], or two-way via [(value)]. | T | null | null |
(touch) | Emitted when focus leaves the strip, so a bound field can mark itself touched. | void | — |
disabled | Disable the whole control. Bound automatically from the field's disabled state when used with [formField]. | boolean | false |
readonly | Refuse changes while every segment stays focusable and the value still submits. Bound automatically from the field's readonly state when used with [formField]. NOTHING is mirrored into ARIA here, deliberately: the strip is a role="group" of aria-pressed buttons, and ARIA defines aria-readonly for neither role — it is a state of checkbox / radiogroup / textbox and their kin, and it is not global. aria-disabled is the only attribute that would apply to a button, and it says the wrong thing: these segments are still focusable and the value still submits. So the state is honest in the DOM (wr-segmented--readonly) and silent in the accessibility tree rather than announced with a word that means something else. | boolean | false |
size | Control size — shares the --wr-control-* contract. | WrSegmentedSize | 'md' |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/segmented's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-segmented-bg | var(--wr-color-fill) | .wr-segmented |
--wr-segmented-color | var(--wr-color-on-surface) | .wr-segmented |
--wr-segmented-font-family | var(--wr-font-family-base) | .wr-segmented |
--wr-segmented-font-size | var(--wr-text-sm) | .wr-segmented +2 variant overrides |
--wr-segmented-line-height | var(--wr-control-line-height-md) | .wr-segmented +2 variant overrides |
--wr-segmented-option-gap | var(--wr-space-sm) | .wr-segmented |
--wr-segmented-option-px | var(--wr-control-padding-x-md) | .wr-segmented |
--wr-segmented-option-py | 0.125rem | .wr-segmented +2 variant overrides |
--wr-segmented-padding | 0.1875rem | .wr-segmented +2 variant overrides |
--wr-segmented-radius | 0.5rem | .wr-segmented +2 variant overrides |
--wr-segmented-selected-bg | var(--wr-color-surface) | .wr-segmented |
--wr-segmented-selected-color | var(--wr-color-on-surface) | .wr-segmented |
--wr-segmented-thumb-count | 1 | .wr-segmented |
--wr-segmented-thumb-index | 0 | .wr-segmented |
--wr-segmented-thumb-radius | calc(var(--wr-segmented-radius) - var(--wr-segmented-padding)) | .wr-segmented |
Dependencies
| Built on | Form, Icon |
|---|---|
| Used by | Color Picker |
See also
Component RadioPick one option from a short list.Component TabsSwitch between panels, or between routes.Component Button GroupJoins buttons into one control with shared borders.Component Form FieldWraps a form control with a label, a hint and its error messages.Guide FormsBind ngwr controls to any Angular form and show their errors.Component FormA plain layout wrapper for a label, a control and its error.Component IconRenders an SVG icon you register by name; ngwr ships none of its own.