Button Group
A container for grouping related buttons. Supports a standard stacked layout and a segmented (toolbar) layout where buttons share borders. Follows USWDS button group patterns.
Props
c-button-group
| Prop | Default | Description |
|---|---|---|
segemented |
Set to "true" to render buttons as a connected segmented group |
c-button-group.button-group-item
The c-button-group.button-group-item component is a wrapper <li> item. It accepts no props; place a c-button inside it.
Example Usage
Default Button Group
Buttons are stacked and styled independently.
<c-button-group>
<c-button-group.button-group-item>
<c-button text="Back" variant="outline" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Continue" />
</c-button-group.button-group-item>
</c-button-group>
Segmented Button Group
Buttons share borders and appear as a connected unit, useful for toggle controls.
<c-button-group segemented="true">
<c-button-group.button-group-item>
<c-button text="Map" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Hybrid" variant="outline" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Satellite" variant="outline" />
</c-button-group.button-group-item>
</c-button-group>
Segmented Group with Accent Cool
<c-button-group segemented="true">
<c-button-group.button-group-item>
<c-button text="Map" variant="accent-cool" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Hybrid" variant="accent-cool" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Satellite" variant="accent-cool" />
</c-button-group.button-group-item>
</c-button-group>
Segmented Group with Outline Inverse
Use on dark backgrounds.
<c-button-group segemented="true">
<c-button-group.button-group-item>
<c-button text="Map" variant="outline-inverse" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Hybrid" variant="outline-inverse" />
</c-button-group.button-group-item>
<c-button-group.button-group-item>
<c-button text="Satellite" variant="outline-inverse" />
</c-button-group.button-group-item>
</c-button-group>
Usage Notes
- Note: the
segementedprop name preserves the original USWDS Cotton component spelling - In a segmented group, all buttons should use the same
variantfor visual consistency - Each button must be wrapped in a
c-button-group.button-group-itemelement - The default layout is suitable for form navigation (e.g., Back / Continue); the segmented layout is better for view-toggle controls
{% load cotton %}
<div class="component-variants">
<h1>Button Group Component</h1>
{% for variant in default_variant %}
<div class="component-variant">
<h2 class="variant-title">{{ variant.title }}</h2>
{% cotton button-group %}
{% cotton button-group.button-group-item %}
{% cotton button text="Back" variant="outline" %}{% endcotton %}
{% endcotton %}
{% cotton button-group.button-group-item %}
{% cotton button text="Continue" %}{% endcotton %}
{% endcotton %}
{% endcotton %}
</div>
{% endfor %}
{% for variant in segemented_variant %}
<div class="component-variant">
<h2 class="variant-title">{{ variant.title }}</h2>
{% cotton button-group segemented="{{ variant.segemented }}" %}
{% for options in variant.options %}
{% cotton button-group.button-group-item %}
{% cotton button text="{{ options.text }}" variant="{{ options.variant }}" %}{% endcotton %}
{% endcotton %}
{% endfor %}
{% endcotton %}
</div>
{% endfor %}
{% for variant in segemented_inverse_variant %}
<div class="component-variant">
<h2 class="variant-title">{{ variant.title }}</h2>
<div class="bg-base-darkest padding-1" style="max-width: fit-content">
{% cotton button-group segemented="{{ variant.segemented }}" %}
{% for options in variant.options %}
{% cotton button-group.button-group-item %}
{% cotton button text="{{ options.text }}" variant="{{ options.variant }}" %}{% endcotton %}
{% endcotton %}
{% endfor %}
{% endcotton %}
</div>
</div>
{% endfor %}
</div>
name: Button Group
context:
default_variant:
- title: "Button Group Default"
control_id: "button-group-1"
label_title: "This is a button group"
segemented_variant:
- title: "Button Group Segemented Hybrid"
segemented: "true"
options:
- text: "Map"
state: ""
variant: ""
- text: "Hybrid"
state: ""
variant: "outline"
- text: "Satellite"
state: ""
variant: "outline"
- title: "Button Group Segemented Default"
segemented: "true"
options:
- text: "Map"
state: ""
variant: ""
- text: "Hybrid"
state: ""
variant: ""
- text: "Satellite"
state: ""
variant: ""
- title: "Button Group Segemented Accent Cool"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "accent-cool"
- text: "Hybrid"
state: ""
variant: "accent-cool"
- text: "Satellite"
state: ""
variant: "accent-cool"
- title: "Button Group Segemented Accent Warm"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "accent-warm"
- text: "Hybrid"
state: ""
variant: "accent-warm"
- text: "Satellite"
state: ""
variant: "accent-warm"
- title: "Button Group Segemented Base"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "base"
- text: "Hybrid"
state: ""
variant: "base"
- text: "Satellite"
state: ""
variant: "base"
- title: "Button Group Segemented Big"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "big"
- text: "Hybrid"
state: ""
variant: "big"
- text: "Satellite"
state: ""
variant: "big"
- title: "Button Group Segemented Outline"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "outline"
- text: "Hybrid"
state: ""
variant: "outline"
- text: "Satellite"
state: ""
variant: "outline"
- title: "Button Group Segemented Secondary"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "secondary"
- text: "Hybrid"
state: ""
variant: "secondary"
- text: "Satellite"
state: ""
variant: "secondary"
segemented_inverse_variant:
- title: "Button Group Segemented Hybrid"
segemented: "true"
options:
- text: "Map"
state: ""
variant: "outline-inverse"
- text: "Hybrid"
state: ""
variant: "outline-inverse"
- text: "Satellite"
state: ""
variant: "outline-inverse"