Split Button
MD3 Expressive split button.
Walkthrough
1. Basic
A wide half that does the obvious thing, and a narrow half that offers the rest — with a hairline gap between them, the same shape language as ButtonGroup's connected ends.
<script lang="ts"> import { MenuItem, SplitButton, toast } from 'omaris';</script><SplitButton label="Save" onclick={() => toast.success('Saved')}> {#snippet menu()} <MenuItem>Save as a copy…</MenuItem> <MenuItem>Save as template</MenuItem> {/snippet}</SplitButton><SplitButton label="Deploy" variant="tonal" tone="tertiary"> {#snippet menu()} <MenuItem>Deploy to staging</MenuItem> <MenuItem tone="destructive">Roll back</MenuItem> {/snippet}</SplitButton> 2. Sizes icons and loading
Both halves share variant, tone and size with Button, so a split button never looks like a guest among them. loading disables the pair and spins the main half; icon is the leading slot on that half.
<script lang="ts"> import { MenuItem, SplitButton, toast } from 'omaris'; let publishing = $state(false); async function publish() { publishing = true; await new Promise((resolve) => setTimeout(resolve, 1400)); publishing = false; toast.success('Published'); }</script>{#snippet uploadIcon()} ...{/snippet}<SplitButton label="Publish" size="xs" loading={publishing} onclick={publish} icon={uploadIcon}> {#snippet menu()} <MenuItem>Schedule…</MenuItem> <MenuItem>Save as draft</MenuItem> {/snippet}</SplitButton><SplitButton label="Export" variant="outlined" size="sm"> {#snippet menu()} <MenuItem>Export as CSV</MenuItem> <MenuItem>Export as JSON</MenuItem> {/snippet}</SplitButton><SplitButton label="Invite" variant="elevated" tone="secondary" size="md" align="end"> {#snippet menu()} <MenuItem>Invite by email</MenuItem> <MenuItem>Copy invite link</MenuItem> {/snippet}</SplitButton>