Skip to content

Button Group

<loomi-button-group> and <loomi-button-group-item> — a horizontal row of segmented toggle buttons with shared sizing, radius, icons, colors, outline mode, and disabled states.

Terminal window
npm install @loomidev/button-group lit
import "@loomidev/button-group";

Place <loomi-button-group-item> elements inside a group. One item can be marked selected for the initial state.

<loomi-button-group>
<loomi-button-group-item label="Day" value="day" selected></loomi-button-group-item>
<loomi-button-group-item label="Week" value="week"></loomi-button-group-item>
<loomi-button-group-item label="Month" value="month"></loomi-button-group-item>
</loomi-button-group>

Listen for selection changes on the group:

<loomi-button-group id="range">
<loomi-button-group-item label="Day" value="day" selected></loomi-button-group-item>
<loomi-button-group-item label="Week" value="week"></loomi-button-group-item>
</loomi-button-group>
<script type="module">
document.querySelector("#range").addEventListener("loomi-button-group-change", (event) => {
console.log(event.detail.value);
});
</script>

Use the same built-in icon names as <loomi-button>. Set icon-right to place the icon after the label.

<loomi-button-group>
<loomi-button-group-item label="List" value="list" icon="list" selected></loomi-button-group-item>
<loomi-button-group-item label="Grid" value="grid" icon="grid-2x2"></loomi-button-group-item>
</loomi-button-group>

Icon-only items work too. Set icon-only on the group when every item should be compact, or on one item when only that button should hide its label.

<loomi-button-group color="primary" icon-only aria-label="Text formatting">
<loomi-button-group-item label="Bold" value="bold" icon="bold" selected></loomi-button-group-item>
<loomi-button-group-item label="Italic" value="italic" icon="italic"></loomi-button-group-item>
</loomi-button-group>

size accepts tiny, small, regular (default), medium, and big. radius accepts the same values as <loomi-button>: none, small, medium (default), and full. The segmented bar is shrink-wrapped, so it ends with the last button instead of filling the parent width.

The selected item uses the same surface fill, accent text, and subtle shadow as <loomi-tabs tab-style="system">. color accepts any Loomi color name and tints the selected text plus focus ring. Add outline for a transparent, outline-only variant.

<loomi-button-group size="small" radius="full" color="success">
<loomi-button-group-item label="Left" value="left" selected></loomi-button-group-item>
<loomi-button-group-item label="Right" value="right"></loomi-button-group-item>
</loomi-button-group>
<loomi-button-group outline radius="small" color="error">
<loomi-button-group-item label="Open" value="open" selected></loomi-button-group-item>
<loomi-button-group-item label="Closed" value="closed"></loomi-button-group-item>
</loomi-button-group>

Disable a single item with disabled on <loomi-button-group-item>, or disable the entire group with disabled on <loomi-button-group>.

<loomi-button-group disabled>
<loomi-button-group-item label="Day" value="day" selected></loomi-button-group-item>
<loomi-button-group-item label="Week" value="week"></loomi-button-group-item>
</loomi-button-group>
  • Supports keyboard focus with visible :focus-visible styling on each button.
  • Icon-only items should provide label or aria-label so the button still has an accessible name.

For the library-wide baseline, see Foundations — Accessibility.

For dense layouts, let the component keep its natural shrink-wrapped width and give the surrounding layout room to scroll or wrap. For long labels or user-provided content, prefer concise text instead of fixed pixel assumptions.

For the shared container and viewport rules, see Foundations — Responsive behavior.

For theme activation, token overrides, and contrast guidance, see Foundations — Dark mode.

AttributeDefaultDescription
colorprimaryAccent color for the selected item text and focus ring. Accepts any Loomi color name.
sizeregularButton size. tiny | small | regular | medium | big.
radiusmediumBar corner radius. none | small | medium | full.
outlinefalseOutline-only treatment: transparent track and selected item outline. (boolean)
icon-onlyfalseHide every item label visually and render square icon buttons. (boolean)
aria-label(blank)Accessible label for the internal role="group" wrapper.
disabledfalseDisable every item in the group. (boolean)
AttributeDefaultDescription
label(blank)Visible label text. Also used as the accessible name when icon-only is set.
value(blank)Value emitted in loomi-button-group-change; falls back to the label or text content.
icon(blank)Built-in icon name from @loomidev/icons.
icon-rightfalsePlace the icon after the label. (boolean)
icon-onlyfalseHide this item’s label visually and render a square icon button. (boolean)
aria-label(blank)Accessible label for icon-only items when label is not enough.
selectedfalseMark this item as active. (boolean)
disabledfalseDisable only this item. (boolean)
SlotDescription
(default)Content placed inside the component.
EventDetail
loomi-bg-click{ value } from the activated group item
loomi-button-group-change{ value, label, index } when the selected item changes
  • @loomidev/core
  • @loomidev/icons
  • @loomidev/theme