Button
MD3 buttons, the Expressive way.
Try it
Knobs
tone variant size MD3 Expressive's five heights: 32 / 40 / 56 / 96 / 136dp. sm is the classic Material button and stays the default.
shape A pill, or MD3's rounded-rectangle. Fixed — it never morphs.
<script> import { Button } from 'omaris';</script><Button>Save changes</Button> Walkthrough
1. 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> 2. 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> 3. 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> 4. 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> 5. 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> 6. 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> 7. 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> 8. 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>