JavaScript Button Group
@lemonadejs/buttongroup · ✓ 20 contract checks · framework-agnostic · zero dependencies
<ButtonGroup /> — a fused row (or column) of buttons (LemonadeJS v6 block)
One block covering both plain action groups and toggle selection: selectable=” plain action buttons — onclick(value, event) selectable=‘single’ exclusive selection — click selects, click again deselects (value | null) selectable=‘multiple’ toggle set — the value is always an array
The selection follows the dropdown model, divisor-free: bind=”${state}” the live two-way selection (single value or array) external writes land silently; user toggles fire onchange (.set)
Example
import { html } from 'lemonadejs';
import ButtonGroup from '@lemonadejs/buttongroup';
const App = (props, { state }) => {
const period = state('month');
const channels = state(['email']);
return html`<div>
<p>Report period</p>
<${ButtonGroup} selectable="single" variant="outlined" bind="${period}"
options="${[
{ value: 'week', label: 'Week' },
{ value: 'month', label: 'Month' },
{ value: 'quarter', label: 'Quarter' },
{ value: 'year', label: 'Year' },
]}" />
<p>Notify me by</p>
<${ButtonGroup} selectable="multiple" bind="${channels}"
options="${[
{ value: 'email', label: 'Email' },
{ value: 'sms', label: 'SMS' },
{ value: 'slack', label: 'Slack' },
]}" />
<p>Sending the <b>${period}</b> report via <b>${() => channels.value.join(', ') || 'nothing'}</b></p>
</div>`;
};Installation
npm install @lemonadejs/buttongroup
import Buttongroup from '@lemonadejs/buttongroup';
import '@lemonadejs/buttongroup/style.css';
The icons come from Google Material Symbols. Load the font once per page:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined">
Three deployment forms, one component:
html`<${Buttongroup} />` // by value (no registration)
setComponents({ Buttongroup }); // then <Buttongroup /> by name anywhere
createWebComponent(Buttongroup); // <lm-buttongroup> in plain HTML/any framework
Props
Every declared prop arrives as a live state — pass a value for a snapshot or a state for a two-way live wire. Attribute strings are coerced to the declared type.
| Prop | Type | Default | Description |
|---|---|---|---|
bind | any | — | Two-way bound value. .set() fires onchange; plain assignment is silent. selection: single value, array when multiple (any) |
options | array | — | { value, label, icon, disabled } or strings |
selectable | string | '' | ” action buttons |
variant | string | '' | ” contained |
color | string | '' | green |
size | string | '' | small |
orientation | string | '' | ” horizontal |
disabled | boolean | false | blocks the whole group (native) |
aria-label | string | '' |
Events
All event names are lowercase (the platform convention — LJS-305 warns otherwise).
onchange— (selection) on user togglesonclick— (value, event) in plain mode
Styling
All classes follow the lm-buttongroup-* convention; visual variants are data-*
attributes on the root. Override freely — there is no styling engine to fight.
Contract
The machine-readable schema ships with the package:
import contract from '@lemonadejs/buttongroup/contract.json';
verify.json carries the conformance proof produced by verify(Buttongroup).
Looking for the v5 plugin? See the archived v5 documentation.