motif svelteArc

Chip Group ported

Toggleable filter chips that stay visible in the row.

A group of selectable filter chips for facets people toggle often, such as topics or statuses. Picking morphs the chip around a check, neighbours re-flow, and long sets fold behind a "+N more" chip. This port keeps the behaviour with static end-states.

Live specimen

Loading demo…

Guidance

When to use

  • Facets people toggle often, such as topics, statuses, or tags.
  • Filters where every choice should stay visible instead of hiding in a menu.
  • Single- or multi-pick groups with full arrow-key and Home/End navigation.

When not to use

  • Use multi-select when the choices should collapse into a compact field.
  • Use checkbox lists when each option needs its own description.
  • Use segmented-control for two to four exclusive choices with a sliding indicator.

Installation

pnpm add sveltearc

Usage

<script lang="ts">
  import { ChipGroup } from '$lib/components/chip-group';

  let topics = $state(['svelte']);

  const options = [
    { value: 'svelte', label: 'Svelte' },
    { value: 'react', label: 'React' },
    { value: 'vue', label: 'Vue' }
  ];
</script>

<ChipGroup
  label="Topics"
  bind:value={topics}
  {options}
/>

Variants & Examples

Multiple (default)

Several chips can be selected at once; clicking a selected chip removes it.

<ChipGroup
  label="Topics"
  bind:value={topics}
  options={many}
/>

Single

Only one chip at a time; the selected chip can still be cleared.

<ChipGroup
  label="Framework"
  bind:value={framework}
  options={frameworks}
  multiple={false}
/>

Overflow

Chips beyond maxVisible fold behind a "+N more" chip; selections never hide.

<ChipGroup
  label="Topics"
  bind:value={topics}
  options={many}
  maxVisible={4}
/>

API Reference

PropTypeDefaultDescription
optionsChipOption[]–Chips in the group, as { value: string; label: string }, in reading order.
valuestring[]–Controlled selection of chip values; supports two-way bind:value.
onValueChange(value: string[]) => void–Callback fired whenever the selection changes.
labelstring–Accessible name of the group, such as "Topics".
multiplebooleantrueAllow several chips at once. In single mode the selected chip can still be cleared.
maxVisiblenumberInfinityChips shown before the rest fold behind a "+N more" chip. Chips selected when it folds stay in view.
classstring–Additional CSS class applied to the group element.

Keyboard Interactions

KeyAction
ArrowRight / ArrowDownMoves focus to the next chip, wrapping at the end.
ArrowLeft / ArrowUpMoves focus to the previous chip, wrapping at the start.
Home / EndJumps focus to the first or last chip.
Space / EnterToggles the focused chip.

Accessibility

  • The row carries role="group" with the accessible name from label.
  • Each chip is a button with aria-pressed reflecting selection.
  • Roving tabindex keeps one tab stop: the last focused chip, else the first selected, else the first.
  • The overflow chip announces its state through aria-expanded.

Motion

Phase 1 still-state: chips render at their resting end-state (check in, label over, surface tinted) with no layout-spring travel; the overflow folds instantly with no height morph; the "+N" text swaps without the roll. Phase 2 wires the shared-layout springs, width-lag edge follow, height morph, text roll, stagger, and check draw. Reduced motion keeps the same end-states with instant transitions.

Notes for AI

  • Pick for visible toggle filters, not for collapsed fields.
  • value stays purely controlled: every toggle flows out through onValueChange (bind:value is the shorthand).
  • Chips selected when the overflow folds stay in view, so selections never hide.

Source of truth: registry/components/chip-group/chip-group.tsx