Chips
Compact element representing an entity, attribute, or action — smaller than a button and used in groups. Material parity (`/components/chips`). Covers four canonical variants (assist, filter, input, suggestion) and their behaviors.
Spec — Chips
Facet *isual*of Koder Design. Material parity: https://m3.material.io/components/chips.
4 variants
| Variant | Purpose | Selectable | Removable |
|---|---|---|---|
| *ssist* | Trigger contextual action tied to a noun ("Add to calendar") | No | No |
| *ilter* | Toggle inclusion in a filtered set | Yes (multi-select) | No |
| *nput* | Represent user-entered value (email tag, applied filter) | No | Yes (× button) |
| *uggestion* | Predefined response or query option | One-shot tap | No |
Pick variant by question: "Does this represent a thing I typed?" → input. "Does this filter a list?" → filter. "Does this give me a shortcut to type something?" → suggestion. "Does this trigger an action attached to nearby content?" → assist.
Anatomy
┌──────────────────┐ ┌──────────────────┐
│ ⚙ Settings │ │ ● Important × │
└──────────────────┘ └──────────────────┘
↑ ↑ ↑ ↑ ↑
icon label leading label remove
(optional) (input only)- *eight* 32 px (default)
- *adding* 12 px horizontal (label only) / 8 px (with icon)
- *orner radius* 8 px (Material 3 default, see preset variation)
- *abel*
label-large(14/20, weight 500) - *eading icon* 18 px, optional
- *railing* × icon (input variant) or check (selected filter)
- *it target* minimum 48 × 48 px (extends invisibly around chip)
- *ontainer bg* variant-specific (see R2)
R1 — Group layout
Chips appear in groups. Layout rules:
| Layout | When |
|---|---|
| *orizontal scroll* | Mobile / narrow surface, many chips |
| *rap* | Default — chips wrap to next line when overflow |
| *ingle row* | Few chips (≤ 5) that always fit |
Spacing between chips: * px horizontal, 8 px vertical*
R2 — Visual by variant + state
| Variant | Rest bg | Rest border | Selected bg | Selected border |
|---|---|---|---|---|
| Assist | transparent |
1 px outline |
n/a | n/a |
| Filter (unselected) | transparent |
1 px outline |
secondary-container |
none |
| Filter (selected) | secondary-container |
none | (same) | none |
| Input | surface-container-low |
1 px outline-variant |
n/a | n/a |
| Suggestion | transparent |
1 px outline |
(one-shot tap, no selected state) | n/a |
Elevation: 0 dp at rest; rises to 2 dp on hover (Material 3 "elevated" chip is an opt-in variant — document explicitly if used).
R3 — Filter chip selection
| Action | Result |
|---|---|
| Tap unselected | Becomes selected (add filter) |
| Tap selected | Becomes unselected (remove filter) |
| Long-press (touch) | Show tooltip with full label |
Filter chips are *ulti-select*by default — multiple can be selected simultaneously. If single-select needed (mutually exclusive), use radio buttons or segmented buttons instead.
Selection state shows:
- Leading check icon (✓) replaces optional leading icon
- Background fills with
secondary-container - Border removed (filled state)
R4 — Input chip removal
× icon on right side, 18 px, accessible via:
- Tap × → remove chip + announce "Removed: [label]" to screen reader
- Backspace when chip has keyboard focus → remove
- Backspace in adjacent text field → focus last chip
- Keyboard delete on focused chip → remove + move focus to previous
Animation: chip fadeout (motionfast) + adjacent chips slide to fill.
R5 — States (all variants)
| State | Visual change |
|---|---|
| Rest | Base style |
| Hover | State layer 8% over base |
| Focused | 2 px focus ring outside chip border |
| Pressed | State layer 12% |
| Disabled | 38% opacity, no interaction |
R6 — With icon
Leading icon slot accepts:
- 18 px icon (default — matches text height)
- 24 px avatar (input chip representing a person)
When icon is present:
- Padding-left reduces from 12 px → 8 px
- Icon
tolabel gap: 4 px
Selected filter chip ALWAYS shows check leading; replaces optional icon (don't try to show both — order is check OR icon).
R7 — Accessibility
- Assist:
role="button"+ accessible name from label - Filter:
role="checkbox"(multi) ORrole="radio"(single, rare)with
aria-checkedstate - Input:
role="button"for chip + nestedrole="button"for ×remove; remove button has
aria-label="Remove [label]" - Suggestion:
role="button" - Group container:
role="group"+aria-labeldescribing thecollection
- Keyboard:
- Tab: enters first chip in group, then Tab moves OUT
- Arrow Left/Right: moves between chips within group
- Space / Enter: toggles (filter) or activates (assist /
suggestion)
- Backspace / Delete: removes (input)
R8 — Density
| Density | Height | Padding | Icon size |
|---|---|---|---|
| Compact | 28 px | 10 px | 16 px |
| Default | 32 px | 12 px | 18 px |
| Comfortable | 40 px | 16 px | 20 px |
Inherits from customization.kmd.
R9 — Per-preset variation
| Preset | Corners | Selected style |
|---|---|---|
material3 |
8 px radius | Filled tonal container |
material2 |
16 px pill | Saturated accent, white text |
ios_cupertino |
16 px pill | Filled accent |
gnome |
6 px radius | Solid accent border, tonal bg |
windows_11 |
4 px radius | Accent color filled, subtle outline |
brutalist |
0 px (sharp) | Inverted colors, 2 px border |
terminal_classic |
Bracketed text [Filter] / [X] |
Asterisk prefix *[Filter] |
R10 — Forbidden patterns
- ❌ Chips taller than 48 px (becomes a button; use button instead)
- ❌ Chips with multi-line labels (truncate or use card / list)
- ❌ Mixing variants in a single group (a row of filter chips with
one input chip in the middle is confusing)
- ❌ Filter chip groups acting as single-select (use radio / segmented
buttons)
- ❌ Chip without label (icon-only — use icon button)
- ❌ Long-press as the only way to remove an input chip (no
discoverability)
- ❌ Animating bg color on selection without a state layer (jarring
flash)
- ❌ Hit target < 48 × 48 px
Cross-link
interaction/selection.kmd— multi-select patterninteraction/states.kmd— hover / pressed / focused layersthemes/color-roles.kmd—secondary-containerfor selected filterthemes/typography.kmd—label-largecomponents/buttons.kmd— single primary action siblingcomponents/text-fields.kmd— input chip parent contextfoundations/elements.kmd— Control + Marker families