Actions
Button
MD3 buttons, the Expressive way.
import { Button } from 'omaris' Examples
Variants
The five MD3 fill styles, in the spec's own order of emphasis, plus link.
<script lang="ts"> import { Button } from 'omaris';</script><Button variant="elevated">Elevated</Button><Button variant="filled">Filled</Button><Button variant="tonal">Tonal</Button><Button variant="outlined">Outlined</Button><Button variant="text">Text</Button><Button variant="link">Link</Button> Tones
tone is the colour role. Every tone works with every fill style.
<script lang="ts"> import { Button } from 'omaris';</script><div class="flex flex-col gap-3"> <div class="flex flex-wrap items-center gap-2"> <Button variant="filled" tone="primary" size="xs">primary</Button> <Button variant="filled" tone="secondary" size="xs">secondary</Button> <Button variant="filled" tone="tertiary" size="xs">tertiary</Button> <Button variant="filled" tone="destructive" size="xs">destructive</Button> <Button variant="filled" tone="success" size="xs">success</Button> <Button variant="filled" tone="warning" size="xs">warning</Button> <Button variant="filled" tone="info" size="xs">info</Button> </div> <div class="flex flex-wrap items-center gap-2"> <Button variant="tonal" tone="primary" size="xs">primary</Button> <Button variant="tonal" tone="secondary" size="xs">secondary</Button> <Button variant="tonal" tone="tertiary" size="xs">tertiary</Button> <Button variant="tonal" tone="destructive" size="xs">destructive</Button> <Button variant="tonal" tone="success" size="xs">success</Button> <Button variant="tonal" tone="warning" size="xs">warning</Button> <Button variant="tonal" tone="info" size="xs">info</Button> </div> <div class="flex flex-wrap items-center gap-2"> <Button variant="outlined" tone="primary" size="xs">primary</Button> <Button variant="outlined" tone="secondary" size="xs">secondary</Button> <Button variant="outlined" tone="tertiary" size="xs">tertiary</Button> <Button variant="outlined" tone="destructive" size="xs">destructive</Button> <Button variant="outlined" tone="success" size="xs">success</Button> <Button variant="outlined" tone="warning" size="xs">warning</Button> <Button variant="outlined" tone="info" size="xs">info</Button> </div></div> Sizes
MD3 Expressive's five heights: 32 / 40 / 56 / 96 / 136dp.
<script lang="ts"> import { Button } from 'omaris';</script><Button size="xs">Extra small</Button><Button size="sm">Small</Button><Button size="md">Medium</Button> With icons
Hand it an <svg>; the button sets the size and the colour.
<script lang="ts"> import { Button, IconButton } from 'omaris';</script>{#snippet plus()} ...{/snippet}<Button>{@render plus()}New invoice</Button><Button variant="tonal" size="md">{@render plus()}Bigger</Button><IconButton aria-label="New invoice">{@render plus()}</IconButton> Loading
The spinner grows in from zero width with a negative margin that cancels the gap, so an idle button measures as if it had no spinner and nothing jumps when one appears.
<script lang="ts"> import { Button } from 'omaris'; let busy = $state(false); function save() { busy = true; setTimeout(() => (busy = false), 2000); }</script><Button loading={busy} onclick={save}>Save changes</Button><Button variant="tonal" loading>Always loading</Button> Toggle
A toggle drops to a neutral surface when off and takes its tone when on.
<script lang="ts"> import { Button } from 'omaris'; let starred = $state(false); let muted = $state(true);</script><Button toggle bind:pressed={starred}>{starred ? 'Starred' : 'Star'}</Button><Button toggle bind:pressed={muted} variant="outlined" tone="tertiary"> {muted ? 'Muted' : 'Mute'}</Button> As a link
Give it href and it renders an <a>, keeping every anchor attribute.
<script lang="ts"> import { Button } from 'omaris';</script><Button href="https://svelte.dev" target="_blank" rel="noreferrer">Open Svelte</Button><Button href="/docs/components/icon-button" variant="text">Icon Button</Button> Overridden
class is merged last, so a utility beats the component's own — including the height and the pill radius that size and shape set.
<script lang="ts"> import { Button } from 'omaris';</script><Button class="h-12 rounded-none px-8">Squared and taller</Button><Button variant="tonal" class="w-full max-w-56 justify-between"> Full width<span aria-hidden="true">→</span></Button> When to use it
Use it for
- The main action on a screen or dialog. Use
filled, once per view. - The actions next to it.
tonalfor the second most important,outlinedortextfor the rest. - An action that takes a moment. Pass
loading; the label stays and a spinner appears.
Not for
- A link that only changes the URL → give it
hrefand it renders an<a>.variant="link"is for a link inside a sentence. - An icon with no label → Icon Button.
- The floating main action on a phone → FAB.
- One action plus a menu of alternatives → Split Button.
- Picking between options → Segmented Button or filter Chips.
Do
- Keep one
filledbutton per view. Everything else istonal,outlinedortext. - Write labels in sentence case, verb first: "Save changes", not "SAVE" or "OK".
- Give destructive actions
tone="destructive"and confirm them in a Dialog.
Don't
- Wrap a label onto two lines, or put two icons in one button.
- Disable a button to explain why it cannot be pressed. Keep it enabled and say why in the supporting text or a toast.
- Use
size="lg"orxlin a dashboard. They are for landing screens.
Quick reference
tone primary(default)secondarytertiarydestructivesuccesswarninginfo
variant filled(default)tonalelevatedoutlinedtextlink
size xssm(default)mdlgxl
MD3 Expressive's five heights: 32 / 40 / 56 / 96 / 136dp. sm is the classic Material button and stays the default.
shape round(default)square
A pill, or MD3's rounded-rectangle. Fixed — it never morphs.
API
Button
MD3 buttons, the Expressive way.
Two axes instead of one long variant list: variant is the fill style (elevated / filled / tonal / outlined / text) and tone is the color role (primary / secondary / … / destructive), which resolves to the --btn-* custom properties in tones.ts. Every fill style works with every tone, with no combinatorial explosion of classes.
import { Button } from 'omaris' Props
variant Defaults to 'filled'
ButtonVariant Fill style. MD3's five, plus link for inline navigation.
filledtonalelevatedoutlinedtextlink
tone Defaults to 'primary'
ButtonTone Color role the fill style paints with.
primarysecondarytertiarydestructivesuccesswarninginfo
size Defaults to 'sm'
ButtonSize MD3 Expressive heights: 32 / 40 / 56 / 96 / 136dp.
xssmmdlgxl
shape Defaults to 'round'
ButtonShape Pill (round) or MD3 rounded rectangle (square).
roundsquare
icon Defaults to false
boolean Square, label-less button. Requires an aria-label.
ripple Defaults to true
boolean Material ripple on press. Set false for a flat, instant button.
confetti Defaults to false
boolean | ConfettiOptions Confetti on press. true for the default burst, or any ConfettiOptions — confetti={{ preset: 'fireworks' }}.
loading Defaults to false
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 Defaults to false
boolean Turns the button into a two-state toggle driven by pressed. Ignored when href is set — a link has no pressed state.
pressed bindableDefaults to false
boolean Selected state of a toggle button. Bindable.
class string children Snippet