Two-state press button: outline when off, navy when on, each state with its own label and optional icon, such as "Voided hidden" and "Voided shown". Use it for a view option the user flips in place. Clicks stay native and the state change is suiChange. Form-associated: posts name=value while on.
import { Component } from "@angular/core";
import { SuiToggleButton } from "@shineui/angular";
@Component({
standalone: true,
imports: [SuiToggleButton],
template: `<sui-toggle-button label-off="Voided hidden" label-on="Voided shown" icon-off="fa-regular fa-eye-slash" icon-on="fa-regular fa-eye" name="show-voided" (suiChange)="onChange($event)"></sui-toggle-button>`,
})
export class Example {
onChange(e: CustomEvent) { console.log(e.detail); }
}
Basic
The control is a real button with aria-pressed, so Space and Enter toggle it and a screen reader announces the pressed state. Each state has its own label and icon.
required means the button must be on for the form to be valid, and the browser names the field from the on-state label. There is no aria-required on it, because the button role does not support that attribute.
<div style="display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:start;max-width:520px">
<sui-toggle-button label-off="Not reviewed" label-on="Reviewed" required help="Mark the reconciliation reviewed before closing."></sui-toggle-button>
<sui-toggle-button label-off="Not reviewed" label-on="Reviewed" required error="Mark the reconciliation reviewed."></sui-toggle-button>
</div>
Read-only
readonly keeps the button named, in the tab order and pressed, a click changes nothing, and it still posts.
Presses or releases it and fires suiChange; aria-pressed follows.
API
<sui-toggle-button>
Properties
Property
Attribute
Type
Default
Description
checked
checked
boolean
false
Pressed state, exposed as aria-pressed. Mutable: the element toggles it on click, then emits suiChange. Reflected, so sui-toggle-button[checked] matches the button as it is now.
disabled
disabled
boolean
false
Disables the button. It keeps its current label, posts nothing and never holds the form.
error
error
stringstring | undefined
Error message under the button; replaces the help line and sets aria-invalid.
help
help
stringstring | undefined
Help text under the button. Replaced by error when set.
iconOff
icon-off
stringstring | undefined
Font Awesome class shown while off, e.g. "fa-regular fa-eye-slash".
iconOn
icon-on
stringstring | undefined
Font Awesome class shown while on, e.g. "fa-regular fa-eye".
invalid
invalid
boolean
false
Danger border without a message (validation handled elsewhere), as on sui-checkbox.
labelOff
label-off
stringstring | undefined
Label shown while off; defaults to Off, or the locale's word for it.
labelOn
label-on
stringstring | undefined
Label shown while on; defaults to On, or the locale's word for it.
name
name
stringstring | undefined
Form control name. Reflected: the form entry is built from the content attribute.
readOnly
readonly
boolean
false
Display only: the button keeps its name, its tab stop and its pressed state but a click changes nothing, and it still posts. Neither a read-only nor a disabled button holds the form on valueMissing.
required
required
boolean
false
The button must be on for the surrounding form to be valid. The browser names the field from labelOn in its message; there is no aria-required, because the button role does not support it.
size
size
"lg" | "md" | "sm"
'md'
Control height: sm 28px, md 34px (default), lg 42px, the same stops the input family uses.
value
value
string
'on'
Value posted with the form while on; defaults to "on".
Events
Event
Detail
React
Vue
Description
suiChange
boolean
onSuiChange
@sui-change
Fires on toggle; detail is the new pressed state.
Methods
Method
Signature
Description
setFocus()
setFocus() => Promise<void>
Moves keyboard focus to the button, as el.focus() does.
Theming
Every design token this element can render with, read from its own stylesheets and the ones it imports. Set a token on :root or on any ancestor and every use below follows it. The values shown are the ones in the theme you are viewing. The list is read per stylesheet, so an element that imports a shared drawing module lists that module's tokens too, whether or not it paints with all of them.