Selection
Chip
MD3 chip — assist, filter, input and suggestion, in one component.
import { Chip } from 'omaris' Examples
Kinds
One component covers all four MD3 chip kinds. What makes it a filter chip is selectable; what makes it an input chip is onremove.
<script lang="ts"> import { Chip } from 'omaris'; let selected = $state(true);</script><Chip>Assist</Chip><Chip selectable bind:selected>Filter</Chip><Chip onremove={() => {}} removeLabel="Remove Input">Input</Chip><Chip variant="elevated">Suggestion</Chip> Filter bar
overflow="scroll" keeps a filter bar to one line that swipes sideways, which is what MD3 does above a list. wrap is right in a form.
<script lang="ts"> import { Chip, ChipGroup } from 'omaris'; let picked = $state<string[]>(['Erbil']); function toggle(city: string) { picked = picked.includes(city) ? picked.filter((c) => c !== city) : [...picked, city]; }</script><div class="w-full max-w-md px-4"> <ChipGroup label="Cities" multiple overflow="scroll"> <Chip selectable selected={picked.includes('Baghdad')} onclick={() => toggle('Baghdad')}> Baghdad </Chip> <Chip selectable selected={picked.includes('Erbil')} onclick={() => toggle('Erbil')}>Erbil</Chip > <Chip selectable selected={picked.includes('Basra')} onclick={() => toggle('Basra')}>Basra</Chip > <Chip selectable selected={picked.includes('Mosul')} onclick={() => toggle('Mosul')}>Mosul</Chip > <Chip selectable selected={picked.includes('Duhok')} onclick={() => toggle('Duhok')}>Duhok</Chip > <Chip selectable selected={picked.includes('Najaf')} onclick={() => toggle('Najaf')}>Najaf</Chip > <Chip selectable selected={picked.includes('Karbala')} onclick={() => toggle('Karbala')}> Karbala </Chip> </ChipGroup></div> Icons and tones
check={false} keeps the icon when it is the meaning — a pin, a swatch; tone with tonal for a chip that reads as a state.
<script lang="ts"> import { Chip } from 'omaris';</script>{#snippet pin()} ...{/snippet}<Chip> {#snippet start()}{@render pin()}{/snippet} Pinned</Chip><Chip selectable selected check={false}> {#snippet start()}{@render pin()}{/snippet} Keeps its icon</Chip><Chip tone="success" variant="tonal">Paid</Chip><Chip tone="destructive" variant="tonal">Overdue</Chip><Chip size="sm">Small</Chip><Chip size="lg">Large</Chip> When to use it
Use it for
- A filter bar above a list or a Table.
selectablechips in aChipGroupwithmultiple, andoverflow="scroll"so it stays one line on a phone. - Things the person entered, like tags, recipients or attached files. Input chips with
onremoveand aremoveLabel("Remove React"). - A contextual assist beside content: "Add to calendar", "Open in Maps". A plain chip with an icon in
startand anonclickorhref. - Suggestions and quick replies under a composer.
variant="elevated"when they float over content. - A person. Put an Avatar in
start.
Not for
- The primary or a secondary action of a screen → Button. A chip is small, optional and about the content next to it.
- One choice from a fixed two to five → Segmented Button. Chips are for sets that vary, wrap and can all be off.
- A read-only status nobody presses, like "Paid" or "Overdue" → Badge. A chip looks pressable.
- A boolean submitted with a form → Checkbox.
- One on/off → Switch.
Do
- Put chips that belong together in a
ChipGroupwith alabel. It gives the set an accessible name. - Pick
overflowon purpose:scrollfor a filter bar above a list,wrapinside a form. - Keep the label to a couple of words.
labeltruncates, and a chip that wraps is a button. - Leave
checkon for filter chips. The tick tells a selected chip from atonalone. Usecheck={false}only when the leading icon is the meaning, like a colour swatch.
Don't
- Use
variant="tonal"for unselected filter chips. Selected and unselected then look the same. - Let the × do anything but remove.
- Grow a chip with
size="lg"to make it act as a button. If it needs to be big, it is a Button.
Quick reference
tone primary(default)secondarytertiarydestructivesuccesswarninginfo
variant outlined(default)tonalelevated
size smmd(default)lg
shape round(default)square
Pill instead of MD3's rounded rectangle.
API
Chip
MD3 chip — assist, filter, input and suggestion, in one component.
The four MD3 chip types differ only in behaviour, so they're expressed as props rather than four components: selectable gives you a filter chip (with the tick that slides in), onremove gives you an input chip (with the trailing ×), and neither gives you assist/suggestion.
A removable chip nests a real button inside, so the × is reachable by keyboard on its own rather than being a click target painted on top.
import { Chip } from 'omaris' Parts
Every element this renders is reachable from outside. Pass Tailwind for one part as classes={{ part: '…' }}; class covers the root and is merged last, so it always wins.
root- No description in the source yet.
label- No description in the source yet.
check- The leading tick on a filter chip: zero-width until selected.
remove- The trailing × on an input chip.
Props
variant Defaults to 'outlined'
ChipVariant outlined- MD3's default chip: a hairline outline on the surface.
tonal- Filled, for chips that need to read as a solid object.
elevated- Elevated — a chip floating over content.
tone Defaults to 'primary'
ChipTone primarysecondarytertiarydestructivesuccesswarninginfo
size Defaults to 'md'
ChipSize smmdlg
shape Defaults to 'round'
ChipShape roundsquare
selectable Defaults to false
boolean Turns the chip into a filter chip: clicking toggles selected.
selected bindableDefaults to false
boolean Selected state of a filter chip. Bindable.
check Defaults to true
boolean Hide the leading tick on a selected filter chip.
onremove () => void Adds the trailing ×. Called when it's pressed.
removeLabel string Accessible name for the × — "Remove React".
ripple Defaults to true
boolean class string classes ChipClasses Per-part Tailwind overrides. class still covers the root.
start Snippet Leading icon or avatar.
end Snippet Trailing icon, before the × if there is one.
children Snippet icon boolean Square, label-less button. Requires an aria-label.
confetti boolean | ConfettiOptions Confetti on press. true for the default burst, or any ConfettiOptions — confetti={{ preset: 'fireworks' }}.
loading boolean Grows a spinner in at the start of the button and blocks interaction. The label stays put; only an icon button swaps its icon out.
toggle boolean Turns the button into a two-state toggle driven by pressed. Ignored when href is set — a link has no pressed state.
pressed bindableboolean Selected state of a toggle button. Bindable.
ChipGroup
A set of chips that belong together, with the accessible name that implies.
overflow is the real decision: wrap flows onto more lines and is right in a form, scroll keeps one line that swipes sideways and is what MD3 does for a filter bar above a list.
import { ChipGroup } from 'omaris' Props
overflow Defaults to 'wrap'
'wrap' | 'scroll' wrap lets the set flow onto more lines — the right choice in a form. scroll keeps it to one line that swipes sideways, which is what MD3 does for a filter bar above a list.
scroll bleeds 16px past its container on each side and restores the inset inside itself, so the strip runs to the screen edge while the first chip still lines up with the text above it. It therefore wants a container with at least px-4; in one with none, those 16px are 16px of horizontal page scroll.
label string Accessible name for the set.
multiple Defaults to false
boolean A set where chips are chosen, rather than one where they act.
class string children Snippet