<c-button-group>
A button group is a segmented control: a compact group of choices rendered as plain `c-button` children, where activating a button takes effect immediately (switching a view, picking a billing period). Selection is exclusive by default; set `multiple` to let several buttons be active at once. Give the group a `label` when it acts as a form field so the choice it represents is named for every user.
Usage
When to use
- A small set (2–5) of short options selected in place.
- The selection applies immediately — no separate submit step is implied.
When not to use
- Long or dynamic option lists — use
c-select. - Options that need explanation per choice — use
c-radio-group(orc-checkboxes instead ofmultiple). - Switching between content panels — use
c-tabswithc-tab-buttons, which drives this component internally.
Single vs multiple
Without multiple the group holds one value — the active button's value
(or its index when no button declares one). Clicking the active button
toggles it off (value null) unless mandatory is set.
With multiple the value is an array of the active buttons' values in DOM
order. Arrays have no attribute form — bind value as a DOM property
(:value.prop in Vue; the React wrapper and property assignment do this
naturally).
In both modes every active button paints its own fill. The sliding
indicator that glides between choices is a tab-strip affordance — it
belongs to c-tab-buttons, not to this component.
Required vs mandatory
The two props answer different questions and vary independently:
requiredis a form-level demand: this field must be answered before the form is submitted. It renders the required marker on the label; your form logic enforces it.mandatoryis a selection-behavior rule: the selection can never become empty. The active button — or, withmultiple, the last active button — cannot be toggled off. It says nothing about whether the form demands an answer.
A group can be mandatory without being required (a view switcher that
always has a selection) or required without being mandatory (the user
must answer, but may retract while deciding).
Accessibility
Setting label names the group for assistive technology (role="group" +
aria-labelledby) as well as visually. Each button carries aria-pressed
for its active state. Buttons are reachable with the arrow keys once the
group has focus.
Examples
<template>
<div class="example-row">
<c-button-group v-model="view">
<c-button value="day">Day</c-button>
<c-button value="week">Week</c-button>
<c-button value="month">Month</c-button>
</c-button-group>
<p>Selected: {{ view ?? 'none' }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const view = ref<string | null>('week');
</script>
<template>
<c-button-group label="Billing period" required value="monthly" mandatory>
<c-button value="monthly">Monthly</c-button>
<c-button value="yearly">Yearly</c-button>
</c-button-group>
</template>
<template>
<div class="example-row">
<c-button-group v-model="align" label="Alignment" mandatory>
<c-button value="left">Left</c-button>
<c-button value="center">Center</c-button>
<c-button value="right">Right</c-button>
</c-button-group>
<p>Selected: {{ align }} — the active button cannot be toggled off</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const align = ref('left');
</script>
<template>
<div class="example-row">
<c-button-group v-model="toppings" label="Toppings" multiple>
<c-button value="cheese">Cheese</c-button>
<c-button value="pepperoni">Pepperoni</c-button>
<c-button value="mushroom">Mushroom</c-button>
</c-button-group>
<p>Selected: {{ toppings.length ? toppings.join(', ') : 'none' }}</p>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const toppings = ref<string[]>(['cheese']);
</script>
<template>
<div class="example-row">
<c-button-group value="list" mandatory>
<c-button value="list">List</c-button>
<c-button value="grid">Grid</c-button>
</c-button-group>
<c-button-group size="small" value="list" mandatory>
<c-button value="list">List</c-button>
<c-button value="grid">Grid</c-button>
</c-button-group>
</div>
</template>
API reference
<c-button-group>
A button group is a segmented control: a compact group of choices rendered as plain `c-button` children, where activating a button takes effect immediately (switching a view, picking a billing period). Selection is exclusive by default; set `multiple` to let several buttons be active at once. Give the group a `label` when it acts as a form field so the choice it represents is named for every user.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
disabled | disabled | boolean | false | Disable the whole group — every slotted c-button is disabled and the selection can no longer be changed. |
label | label | string | '' | Label of the button group, shown above the buttons |
mandatory | mandatory | boolean | false | The selection can never become empty: the active button (or, with `multiple`, the last active button) cannot be toggled off. Distinct from `required`: mandatory is a selection-behavior rule on the control, not a form-level demand for an answer. |
multiple | multiple | boolean | false | Allow several buttons to be active at once. The value becomes an array of the active buttons' values (in DOM order). Arrays have no attribute form — bind `value` as a DOM property (`:value.prop` in Vue). |
required | required | boolean | false | Set as required — shows the required marker on the label |
size | size | CButtonGroupSize | 'default' | Size of the buttons |
value | — | | null | Value of the group: the active button's `value` (or its index when no button declares one). `null` when nothing is selected. With `multiple`, an array of the active buttons' values. |
Events
| Event | Detail | Description |
|---|---|---|
change | CButtonGroupValue | Fired when the user changes the selection, carrying the new value: the activated button's value (or index), `null` when the active button is toggled off, or the array of active values in `multiple` mode. |
input | void | Native bubbling input event dispatched for plain `v-model` support; carries no detail. |
update:value | CButtonGroupValue | Fired alongside `change` with the new selection; fulfills the `v-model` contract. |
Slots
| Slot | Description |
|---|---|
default | Default slot for the c-button elements |
CSS parts
Style from outside with c-button-group::part(name) — parts are the library's only styling customization API.
| Part | Description |
|---|---|
root | The segmented-control box that frames the buttons |
label | The group label rendered above the buttons |
Types
Importable from the package root: import type { … } from '@cscfi/csc-ui'
CButtonGroupProps
export interface CButtonGroupProps {
/** Disable the whole group — every slotted c-button is disabled and the selection can no longer be changed. */
disabled?: boolean;
/**
* Label of the button group, shown above the buttons
*
* @freeform
*/
label?: string;
/**
* The selection can never become empty: the active button (or, with
* `multiple`, the last active button) cannot be toggled off. Distinct from
* `required`: mandatory is a selection-behavior rule on the control, not a
* form-level demand for an answer.
*/
mandatory?: boolean;
/**
* Allow several buttons to be active at once. The value becomes an array
* of the active buttons' values (in DOM order). Arrays have no attribute
* form — bind `value` as a DOM property (`:value.prop` in Vue).
*/
multiple?: boolean;
/**
* Set as required — shows the required marker on the label
*/
required?: boolean;
/**
* Size of the buttons
*/
size?: CButtonGroupSize;
/**
* Value of the group: the active button's `value` (or its index when no
* button declares one). `null` when nothing is selected. With `multiple`,
* an array of the active buttons' values.
*/
value?: CButtonGroupValue;
}CButtonGroupSize
Size of the button group. `small` renders a more compact control; the size is also propagated to every slotted `<c-button>`. Omitting the attribute renders the default size.
export type CButtonGroupSize = 'default' | 'small';CButtonGroupValue
Selection value of the group: a single button value (or index) — `null` when nothing is selected — or, in `multiple` mode, an array of them.
export type CButtonGroupValue = (number | string)[] | null | number | string;