Buttons
ButtonGroup
The ButtonGroup joins related buttons into a single unit: a plain action toolbar, or a single-select or multi-select group of toggle buttons. The whole group is one tab stop that the arrow, Home, and End keys navigate, and it follows the WAI-ARIA pattern matching its selection mode.
Notes
1. The BitButtonGroupItem class
2. A Custom Generic class
3. The BitButtonGroupOption component
The SelectionMode decides what the group is: None renders plain action buttons in a toolbar, Single renders a radiogroup whose buttons report aria-checked, and Multiple renders a toolbar of toggle buttons that report aria-pressed. In every mode the group holds a single tab stop (a roving tabindex) unless Navigable is disabled.
Two behaviors follow the selection mode rather than a parameter, and both can be turned around:
1. In the Single mode the selection follows the focus, as the WAI-ARIA radiogroup pattern expects, so an arrow key both moves and selects. Set SelectOnFocus="false" on a group whose selection does real work, and the user then commits with Space or Enter.
2. While the MaxToggles cap is reached, the items that are not toggled report themselves as aria-disabled and run nothing at all - neither OnItemClick nor the item's own OnClick - until one of the toggled items is un-toggled.
Usage
Every example is live. Open its code to see exactly what produced the component running underneath.
Basic
Variant
Icon
IconOnly
ReversedIcon
Toggle
Vertical
Events
FullWidth
Multiple
aria-disabled and stop responding, so the
cap is visible instead of being a click that does nothing; they stay focusable and come back as soon as
one of the toggled buttons is un-toggled.
Justified
Detached
Rounded
Overflow
SelectionIndicator
Loading & Badge
Links
rel="noopener" automatically, and Rel sets the relationship itself
(nofollow, external, ...). A disabled or loading link drops its href and
keeps its link role. In a toggle group a link reports its selection through
aria-current, since aria-pressed belongs to a button.
In the Single mode a link also carries the radio role, so Space selects it while
Enter still follows it.
Templates
Tooltips
Accessibility
Cascading parameters
Color
External Icons
Size
Style & Class
:root or on the Style of a single group.
RTL
CSS variables
The public custom properties this component reads off its root, for what no parameter covers.
Every variable is read with a fallback and never declared by the component, so it inherits like any other custom property:
set one on :root (or in a [bit-theme] block) to restyle every instance, on any ancestor to restyle the ones inside it,
or on the Style of one instance to restyle that one alone. Leave a variable unset and the component falls back to the theme token beside it.
BitButtonGroup CSS variables
| Name | Default value | Description |
|---|---|---|
| --bit-ButtonGroup-color | Per Variant: the Color role's on color (Fill) or its main color (Outline, Text) | Text and icon color of a button at rest. |
| --bit-ButtonGroup-background | Per Variant: the Color role's main color (Fill), transparent (Outline, Text) | Background of a button at rest. |
| --bit-ButtonGroup-border-color | The Color role's main color (the group) and dark color (the separators) | Color of the group's outer border and of the separators between its buttons. It wins over the hover and pressed states, which otherwise repaint the border along with the buttons. |
| --bit-ButtonGroup-separator-color | --bit-ButtonGroup-border-color | Color of the separators between the buttons alone, leaving the group's outer border to the variable above - which is what a segmented control whose dividers are lighter than its outline needs. In the Detached and Wrap layouts every button draws the whole outline itself, so there are no separators of their own there and the border color paints all of it. |
| --bit-ButtonGroup-hover-color | The Color role's on color | Text and icon color while hovered (pointer devices only). |
| --bit-ButtonGroup-hover-background | The Color role's hover color | Background while hovered, and the fallback of the pressed background below. |
| --bit-ButtonGroup-active-background | --bit-ButtonGroup-hover-background | Background while pressed. |
| --bit-ButtonGroup-selected-color | The Color role's on color | Text and icon color of a toggled button, which the check mark of ShowSelectionIndicator follows. |
| --bit-ButtonGroup-selected-background | The Color role's dark color | Background and border of a toggled button - the whole of what marks a button as selected, so a group that has to read differently when selected is re-skinned here. |
| --bit-ButtonGroup-selected-hover-background | The Color role's dark-hover color | Background and border of a toggled button while hovered or pressed. |
| --bit-ButtonGroup-selected-border-color | --bit-ButtonGroup-selected-background | Border of a toggled button, for a selection whose outline is not its background: the two are one declaration otherwise, so tinting the background takes the outline down with it. A color set here is kept while the button is hovered and pressed. |
| --bit-ButtonGroup-disabled-color | The Color role's disabled text color | Text and icon color of a disabled button, and of a group disabled as a whole. |
| --bit-ButtonGroup-disabled-background | Per Variant: the Color role's disabled color (Fill), transparent (Outline, Text) | Background of a disabled button. |
| --bit-ButtonGroup-disabled-border-color | The Color role's disabled color | Border and separators of a disabled group. |
| --bit-ButtonGroup-focus-color | Per Variant: the Color role's on color (Fill) or its main color (Outline, Text) | Color of the keyboard focus indicator, which is drawn inside the focused button so the group's rounded corners never clip it - or as the library's outset focus ring when Detached, where nothing is clipped. |
| --bit-ButtonGroup-radius | --bit-shp-radius-button, or --bit-shp-radius-full when Rounded | Outer corner radius of the group, or of every button when Detached. |
| --bit-ButtonGroup-border-width | --bit-shp-brd-width | Width of the group's outer border and of the separators between its buttons. Set it to 0 for a group whose buttons are told apart by their background alone. |
| --bit-ButtonGroup-min-height | Per Size: --bit-siz-ctrl-sm / -md / -lg | Smallest height of a button, which is what lines a group up with the other controls of its size and keeps the smallest one above the 24px minimum pointer target of WCAG 2.2. It is a floor, not a height: a wrapped label still grows the button. |
| --bit-ButtonGroup-padding | Per Size: --bit-siz-ctrl-pad-y-* and --bit-siz-ctrl-pad-x-* | Padding of a button. |
| --bit-ButtonGroup-font-size | Per Size: --bit-tpg-fs-xs / -sm / -md | Text size of a button. |
| --bit-ButtonGroup-font-weight | --bit-tpg-font-weight | Text weight of a button. |
| --bit-ButtonGroup-icon-size | Per Size: --bit-siz-icon-sm / -md / -lg | Size of the icon, the loading spinner and the selection indicator, which share one slot so a spinner replacing an icon moves nothing around it. |
| --bit-ButtonGroup-content-gap | spacing(1) | Room between the icon, the text and the badge inside a button. |
| --bit-ButtonGroup-gap | spacing(1) | Room between the buttons in the Detached mode. The Gap parameter sets this same variable on one instance. |
| --bit-ButtonGroup-badge-color | The button's own text color | Text color of a button's badge. |
| --bit-ButtonGroup-badge-font-size | Per Size: --bit-tpg-fs-2xs / -xs / -sm | Text size of a button's badge, one ramp step below the button's own text. |
| --bit-ButtonGroup-badge-background | A 20% tint of the button's own text color | Background of a button's badge, tinted out of the text color by default so it stays legible on every variant. |
API
Every parameter, public member, sub-class and enum this component exposes.
BitButtonGroup parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AutoFocus | bool | false | Gives the keyboard focus to the ButtonGroup when the page first renders. The focus lands on the button that owns the group's single tab stop, which is the same button a Tab into the group reaches. |
| ChildContent | RenderFragment? | null | The content of the BitButtonGroup, that are BitButtonGroupOption components. |
| IconOnly | bool | false | Determines that only the icon should be rendered, which also squares the buttons the way every icon button in the library is shaped. The hidden text stays the accessible name of the button, so an icon-only group is still readable without an AriaLabel being set on every item. |
| Classes | BitButtonGroupClassStyles? | null | Custom CSS classes for different parts of the ButtonGroup. |
| Color | BitColor? | null | The general color of the button group. |
| DefaultToggleKey | string? | null | The default key that will be initially used to set toggled item in toggle mode if the ToggleKey parameter is not set. |
| DefaultToggleKeys | IEnumerable<string>? | null | The default keys that will be initially used to set the toggled items in the Multiple selection mode if the ToggleKeys parameter is not set. |
| Detached | bool | false | Detaches the buttons from each other, so each button is rendered as a separate rounded button. |
| DisabledInteractive | bool | false | Keeps the disabled buttons focusable by rendering them with the aria-disabled attribute instead of the disabled attribute, so that assistive technologies can still discover them. |
| FixedToggle | bool | false | Enables the fixed-toggle mode that ensures one item to be always toggled. In the Multiple selection mode it prevents un-toggling the last toggled item. It is what makes a Single-mode group a mandatory choice: without it, activating the toggled item takes the selection back and leaves the radiogroup with nothing checked. |
| FullWidth | bool | false | Expand the ButtonGroup width to 100% of the available width. |
| Gap | string? | null | The gap between the buttons of the ButtonGroup in the detached mode, as any CSS length. It sets the public --bit-ButtonGroup-gap custom property on this group, which can also be set on :root to space every detached group out at once. |
| Justified | bool | false | Gives every button an equal width so that the buttons evenly fill the width of the ButtonGroup. |
| Items | IEnumerable<TItem> | new List<TItem>() | List of Item, each of which can be a Button with different action in the ButtonGroup. |
| ItemTemplate | RenderFragment<TItem>? | null | The content inside the item can be customized. |
| MaxToggles | int? | null | The maximum number of items that can be toggled at the same time in the Multiple selection mode. While the cap is reached, the items that are not toggled are rendered with the aria-disabled attribute and stop responding, so that the cap is visible rather than a click that silently does nothing; they stay focusable and come back as soon as one of the toggled items is un-toggled. |
| NameSelectors | BitButtonGroupNameSelectors<TItem>? | null | Names and selectors of the custom input type properties. |
| Navigable | bool | true | Enables the roving tabindex behavior, which turns the whole ButtonGroup into a single tab stop that is navigable using the arrow, Home, and End keys. |
| OnItemClick | EventCallback<TItem> | The callback that is called when a button is clicked. | |
| OnToggleChange | EventCallback<TItem> | The callback that called when toggled item change. | |
| Options | RenderFragment? | null | Alias of ChildContent. |
| Overflow | BitButtonGroupOverflow? | null | Determines how the ButtonGroup behaves when its buttons do not fit in the available space. |
| Rounded | bool | false | Renders the ButtonGroup with fully rounded (pill shaped) corners. |
| SelectionMode | BitSelectionMode? | null | Determines how many items can be toggled at the same time. When not set, it falls back to Single if the Toggle parameter is enabled, otherwise None. |
| SelectOnFocus | bool? | null | Toggles the focused item while navigating the ButtonGroup using the keyboard, so that the selection follows the focus. Unset, it follows the SelectionMode: on in the Single mode, whose arrow keys the WAI-ARIA radiogroup pattern expects to check the radio they land on, and off in the Multiple and None modes. Set it to false on a Single-mode group whose selection does work - a filter, a fetch - so that arrowing across it does not fire that work on every keystroke. The navigation only ever selects: a key landing on an item that is already toggled leaves it toggled, and un-toggling stays with Space, Enter and a click. |
| ShowSelectionIndicator | bool | false | Renders a check mark at the start of the toggled buttons. |
| Toggle | bool | false | Display ButtonGroup with toggle mode enabled for each button. It is a shorthand of setting the SelectionMode parameter to Single. |
| ToggleKey | string? | null | The key of the toggled item in the Single selection mode. (two-way bound) |
| ToggleKeys | IEnumerable<string>? | null | The keys of the toggled items in the Multiple selection mode. (two-way bound) |
| Size | BitSize? | null | The size of ButtonGroup, Possible values: Small | Medium | Large. |
| Styles | BitButtonGroupClassStyles? | null | Custom CSS styles for different parts of the ButtonGroup. |
| Variant | BitVariant? | null | The visual variant of the button group. |
| Vertical | bool | false | Defines whether to render ButtonGroup children vertically. |
BitButtonGroup public members
| Name | Type | Default value | Description |
|---|---|---|---|
| FocusAsync | ValueTask | Gives the keyboard focus to the button that owns the ButtonGroup's tab stop - the toggled one, otherwise the first focusable one - which is the same button a Tab into the group reaches. It does nothing while the group holds no focusable button at all. |
BitComponentBase parameters
| Name | Type | Default value | Description |
|---|---|---|---|
| AriaLabel | string? | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | string? | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | BitDir? | null | Gets or sets the text directionality for the component's content. |
| Disabled | bool | false | Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction. |
| ForceAnimation | bool | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | Dictionary<string, object> | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. |
| Id | string? | null | Gets or sets the unique identifier for the component's root element. |
| Style | string? | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | string? | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | BitVisibility | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
BitComponentBase public members
| Name | Type | Default value | Description |
|---|---|---|---|
| UniqueId | Guid | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | ElementReference | Gets the reference to the root HTML element associated with this component. |
BitButtonGroupClassStyles properties
| Name | Type | Default value | Description |
|---|---|---|---|
| Root | string? | null | Custom CSS classes/styles for the root element of the BitButtonGroup. |
| Button | string? | null | Custom CSS classes/styles for the internal button of the BitButtonGroup. |
| Badge | string? | null | Custom CSS classes/styles for the badge of the buttons of the BitButtonGroup. |
| Icon | string? | null | Custom CSS classes/styles for the icon of the BitButtonGroup. |
| SelectionIndicator | string? | null | Custom CSS classes/styles for the selection indicator (check mark) of the toggled buttons of the BitButtonGroup. |
| Spinner | string? | null | Custom CSS classes/styles for the loading spinner of the buttons of the BitButtonGroup. |
| Text | string? | null | Custom CSS classes/styles for the text of the BitButtonGroup. |
| ToggledButton | string? | null | Custom CSS classes/styles for the button when in toggle mode of the BitButtonGroup. |
BitButtonGroupNameSelectors properties
| Name | Type | Default value | Description |
|---|---|---|---|
| AriaLabel | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.AriaLabel)) | AriaLabel field name and selector of the custom input class. |
| Badge | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Badge)) | Badge field name and selector of the custom input class. |
| Class | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Class)) | The CSS Class field name and selector of the custom input class. |
| Href | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Href)) | Href field name and selector of the custom input class. |
| Icon | BitNameSelectorPair<TItem, BitIconInfo?> | new(nameof(BitButtonGroupItem.Icon)) | Icon field name and selector of the custom input class. |
| IconName | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.IconName)) | IconName field name and selector of the custom input class. |
| IsDisabled | BitNameSelectorPair<TItem, bool> | new(nameof(BitButtonGroupItem.IsDisabled)) | IsDisabled field name and selector of the custom input class. |
| IsLoading | BitNameSelectorPair<TItem, bool> | new(nameof(BitButtonGroupItem.IsLoading)) | IsLoading field name and selector of the custom input class. |
| Key | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Key)) | Key field name and selector of the custom input class. |
| OffIcon | BitNameSelectorPair<TItem, BitIconInfo?> | new(nameof(BitButtonGroupItem.OffIcon)) | OffIcon field name and selector of the custom input class. |
| OffIconName | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.OffIconName)) | OffIconName field name and selector of the custom input class. |
| OffText | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.OffText)) | OffText field name and selector of the custom input class. |
| OffTitle | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.OffTitle)) | OffTitle field name and selector of the custom input class. |
| OnIcon | BitNameSelectorPair<TItem, BitIconInfo?> | new(nameof(BitButtonGroupItem.OnIcon)) | OnIcon field name and selector of the custom input class. |
| OnIconName | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.OnIconName)) | OnIconName field name and selector of the custom input class. |
| OnText | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.OnText)) | OnText field name and selector of the custom input class. |
| OnTitle | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.OnTitle)) | OnTitle field name and selector of the custom input class. |
| OnClick | BitNameSelectorPair<TItem, Action<TItem>?> | new(nameof(BitButtonGroupItem.OnClick)) | OnClick field name and selector of the custom input class. |
| ReversedIcon | BitNameSelectorPair<TItem, bool> | new(nameof(BitButtonGroupItem.ReversedIcon)) | ReversedIcon field name and selector of the custom input class. |
| Rel | BitNameSelectorPair<TItem, BitLinkRels?> | new(nameof(BitButtonGroupItem.Rel)) | Rel field name and selector of the custom input class. |
| Style | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Style)) | Style field name and selector of the custom input class. |
| Target | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Target)) | Target field name and selector of the custom input class. |
| Template | BitNameSelectorPair<TItem, RenderFragment?> | new(nameof(BitButtonGroupItem.Template)) | Template field name and selector of the custom input class. |
| Text | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Text)) | Text field name and selector of the custom input class. |
| Title | BitNameSelectorPair<TItem, string?> | new(nameof(BitButtonGroupItem.Title)) | Title field name and selector of the custom input class. |
| IsToggled | BitNameSelectorPair<TItem, bool> | new(nameof(BitButtonGroupItem.IsToggled)) | IsToggled field name and selector of the custom input class. This property's value is assigned by the component. |
BitNameSelectorPair properties
| Name | Type | Default value | Description |
|---|---|---|---|
| Name | string | Custom class property name. | |
| Selector | Func<TItem, TProp?>? | Custom class property selector. |
BitIconInfo properties
| Name | Type | Default value | Description |
|---|---|---|---|
| Name | string? | null | Gets or sets the name of the icon. |
| BaseClass | string? | null | Gets or sets the base CSS class for the icon. For built-in Fluent UI icons, this defaults to "bit-icon". For external icon libraries like FontAwesome, you might set this to "fa" or leave empty. |
| Prefix | string? | null | Gets or sets the CSS class prefix used before the icon name. For built-in Fluent UI icons, this defaults to "bit-icon--". For external icon libraries, you might set this to "fa-" or leave empty. |
BitVariant enum
| Name | Value | Description |
|---|---|---|
| Fill | 0 | Fill styled variant. |
| Outline | 1 | Outline styled variant. |
| Text | 2 | Text styled variant. |
BitSelectionMode enum
| Name | Value | Description |
|---|---|---|
| None | 0 | Nothing can be selected: the items act as plain content or as plain action buttons. |
| Single | 1 | At most one item can be selected at a time. |
| Multiple | 2 | Any number of items can be selected at the same time. |
BitButtonGroupOverflow enum
| Name | Value | Description |
|---|---|---|
| Clip | 0 | The items are kept on a single line and the overflowing part is clipped. A detached group lets it spill out instead, since it clips nothing at all - which is what keeps the focus ring of its buttons whole. |
| Wrap | 1 | The items wrap onto multiple lines. |
| Scroll | 2 | The items are kept on a single line and the group becomes scrollable along the axis it is laid out on - sideways, or down a vertical group - without rendering a scrollbar. It can still be scrolled by swiping, by the wheel - ordinary wheel input down a vertical group, shift+wheel across a horizontal one - and through the arrow keys, which bring the button they focus into view. |
| Scrollbar | 3 | The same, with a visible scrollbar. The scrollbar is laid out inside the border of the group, so the group grows by the room it takes on the edge it sits on. |
BitColor enum
| Name | Value | Description |
|---|---|---|
| Primary | 0 | Primary general color. |
| Secondary | 1 | Secondary general color. |
| Tertiary | 2 | Tertiary general color. |
| Info | 3 | Info general color. |
| Success | 4 | Success general color. |
| Warning | 5 | Warning general color. |
| SevereWarning | 6 | Severe Warning general color. |
| Error | 7 | Error general color. |
| PrimaryBackground | 8 | Primary background color. |
| SecondaryBackground | 9 | Secondary background color. |
| TertiaryBackground | 10 | Tertiary background color. |
| PrimaryForeground | 11 | Primary foreground color. |
| SecondaryForeground | 12 | Secondary foreground color. |
| TertiaryForeground | 13 | Tertiary foreground color. |
| PrimaryBorder | 14 | Primary border color. |
| SecondaryBorder | 15 | Secondary border color. |
| TertiaryBorder | 16 | Tertiary border color. |
BitVisibility enum
| Name | Value | Description |
|---|---|---|
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
BitDir enum
| Name | Value | Description |
|---|---|---|
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.