Skip to content

ButtonGroup

ButtonGroup displays multiple related actions in a row to help with arrangement and spacing.

Group related buttons with default spacing.

Minimal space between buttons for compact layouts.

<script>
import { ButtonGroup, Button } from 'svelte-polaris';
</script>
<ButtonGroup gap="extraTight">
<Button>Previous</Button>
<Button>1</Button>
<Button>2</Button>
<Button>3</Button>
<Button>Next</Button>
</ButtonGroup>

Reduced space between buttons.

<script>
import { ButtonGroup, Button } from 'svelte-polaris';
</script>
<ButtonGroup gap="tight">
<Button>Bold</Button>
<Button>Italic</Button>
<Button>Underline</Button>
</ButtonGroup>

Increased space between buttons for better separation.

<script>
import { ButtonGroup, Button } from 'svelte-polaris';
</script>
<ButtonGroup gap="loose">
<Button>Create</Button>
<Button>Import</Button>
<Button>Export</Button>
</ButtonGroup>

Create a segmented control appearance where buttons are visually connected.

Use icons in segmented button groups for visual clarity.

<script>
import { ButtonGroup, Button, Icon } from 'svelte-polaris';
import { ViewListIcon, ViewGridIcon, ViewCardIcon } from 'svelte-polaris/icons';
let activeView = 'list';
</script>
<ButtonGroup variant="segmented">
<Button
pressed={activeView === 'list'}
onclick={() => activeView = 'list'}
accessibilityLabel="List view"
>
<Icon source={ViewListIcon} />
</Button>
<Button
pressed={activeView === 'grid'}
onclick={() => activeView = 'grid'}
accessibilityLabel="Grid view"
>
<Icon source={ViewGridIcon} />
</Button>
<Button
pressed={activeView === 'card'}
onclick={() => activeView = 'card'}
accessibilityLabel="Card view"
>
<Icon source={ViewCardIcon} />
</Button>
</ButtonGroup>

Buttons stretch to fill the available width.

<script>
import { ButtonGroup, Button } from 'svelte-polaris';
</script>
<ButtonGroup fullWidth>
<Button>Option A</Button>
<Button>Option B</Button>
<Button>Option C</Button>
</ButtonGroup>

Prevent buttons from wrapping to the next line.

<script>
import { ButtonGroup, Button } from 'svelte-polaris';
</script>
<ButtonGroup noWrap>
<Button>Very Long Button Text</Button>
<Button>Another Long Button</Button>
<Button>Third Long Button</Button>
<Button>Fourth Button</Button>
</ButtonGroup>

Remove top border radius for buttons connected to elements above.

<script>
import { ButtonGroup, Button, Card, Text } from 'svelte-polaris';
</script>
<Card>
<Text variant="headingMd" as="h2">
Product Actions
</Text>
<ButtonGroup connectedTop>
<Button>Edit</Button>
<Button>Duplicate</Button>
<Button>Archive</Button>
</ButtonGroup>
</Card>

Group form submission and cancellation buttons.

<script>
import { ButtonGroup, Button, TextField, FormLayout, Card } from 'svelte-polaris';
let productName = '';
let productDescription = '';
function handleSave() {
console.log('Saving product:', { productName, productDescription });
}
function handleCancel() {
console.log('Canceling form');
productName = '';
productDescription = '';
}
</script>
<Card title="Add Product">
<FormLayout>
<TextField
label="Product name"
bind:value={productName}
placeholder="Enter product name"
/>
<TextField
label="Description"
multiline={4}
bind:value={productDescription}
placeholder="Describe your product"
/>
<ButtonGroup>
<Button onclick={handleCancel}>Cancel</Button>
<Button variant="primary" onclick={handleSave}>Save product</Button>
</ButtonGroup>
</FormLayout>
</Card>

Create pagination navigation with button groups.

<script>
import { ButtonGroup, Button } from 'svelte-polaris';
let currentPage = 1;
const totalPages = 10;
function goToPage(page) {
if (page >= 1 && page <= totalPages) {
currentPage = page;
}
}
function previousPage() {
goToPage(currentPage - 1);
}
function nextPage() {
goToPage(currentPage + 1);
}
</script>
<ButtonGroup gap="tight">
<Button
disabled={currentPage === 1}
onclick={previousPage}
>
Previous
</Button>
{#each Array.from({length: Math.min(5, totalPages)}, (_, i) => i + Math.max(1, currentPage - 2)) as page}
<Button
pressed={page === currentPage}
onclick={() => goToPage(page)}
>
{page}
</Button>
{/each}
<Button
disabled={currentPage === totalPages}
onclick={nextPage}
>
Next
</Button>
</ButtonGroup>

Group toolbar actions with different spacing and variants.

<script>
import { ButtonGroup, Button, Icon } from 'svelte-polaris';
import {
BoldIcon,
ItalicIcon,
UnderlineIcon,
AlignLeftIcon,
AlignCenterIcon,
AlignRightIcon
} from 'svelte-polaris/icons';
let formatting = {
bold: false,
italic: false,
underline: false,
align: 'left'
};
function toggleFormat(format) {
formatting[format] = !formatting[format];
}
function setAlignment(align) {
formatting.align = align;
}
</script>
<div style="display: flex; gap: 1rem; align-items: center;">
<!-- Text formatting -->
<ButtonGroup variant="segmented" gap="extraTight">
<Button
pressed={formatting.bold}
onclick={() => toggleFormat('bold')}
accessibilityLabel="Bold"
>
<Icon source={BoldIcon} />
</Button>
<Button
pressed={formatting.italic}
onclick={() => toggleFormat('italic')}
accessibilityLabel="Italic"
>
<Icon source={ItalicIcon} />
</Button>
<Button
pressed={formatting.underline}
onclick={() => toggleFormat('underline')}
accessibilityLabel="Underline"
>
<Icon source={UnderlineIcon} />
</Button>
</ButtonGroup>
<!-- Text alignment -->
<ButtonGroup variant="segmented" gap="extraTight">
<Button
pressed={formatting.align === 'left'}
onclick={() => setAlignment('left')}
accessibilityLabel="Align left"
>
<Icon source={AlignLeftIcon} />
</Button>
<Button
pressed={formatting.align === 'center'}
onclick={() => setAlignment('center')}
accessibilityLabel="Align center"
>
<Icon source={AlignCenterIcon} />
</Button>
<Button
pressed={formatting.align === 'right'}
onclick={() => setAlignment('right')}
accessibilityLabel="Align right"
>
<Icon source={AlignRightIcon} />
</Button>
</ButtonGroup>
</div>

Use button groups in modal dialogs for consistent action placement.

<script>
import { ButtonGroup, Button, Modal, Text } from 'svelte-polaris';
let showModal = false;
function openModal() {
showModal = true;
}
function closeModal() {
showModal = false;
}
function confirmDelete() {
console.log('Item deleted');
closeModal();
}
</script>
<Button onclick={openModal}>Delete Item</Button>
<Modal
open={showModal}
onClose={closeModal}
title="Delete Item"
primaryAction={{
content: 'Delete',
onAction: confirmDelete,
destructive: true
}}
secondaryActions={[
{
content: 'Cancel',
onAction: closeModal
}
]}
>
<Text variant="bodyMd" as="p">
Are you sure you want to delete this item? This action cannot be undone.
</Text>
</Modal>
PropTypeDefaultDescription
gap'extraTight' | 'tight' | 'loose'-Space between button group items
variant'segmented'-Styling variant for the group
fullWidthbooleanfalseButtons stretch to occupy full width
connectedTopbooleanfalseRemove top left and right border radius
noWrapbooleanfalsePrevent buttons from wrapping to next line
  • Use descriptive button labels or accessibilityLabel for icon-only buttons
  • Implement proper keyboard navigation between buttons
  • Use pressed state for toggle buttons in segmented groups
  • Ensure sufficient color contrast for button states
  • Group related actions logically for screen readers

Group related actions

Only group buttons that are related in function or context to avoid confusion.

Use consistent button variants

Maintain visual hierarchy by using appropriate button variants within groups.

Consider spacing

Choose appropriate gap values based on the relationship between actions.

Limit group size

Keep button groups small (2-5 buttons) for better usability and visual clarity.