Split button

One button in two halves: a default action, and a caret that opens related actions. Use it when one choice is the obvious one but a few alternatives should stay within reach.

Usage

The action half runs onclick. The trailing half opens the menu and never triggers the action. Give it a menuLabel, because it shows only a caret. While the menu is open the caret turns over and its half rounds out into a circle.

<script lang="ts">
	import { MenuItem, Snackbar, SplitButton } from 'noph-ui'

	let snackbar: ReturnType<typeof Snackbar> | undefined = $state()
	const say = () => snackbar?.show()
</script>

<SplitButton label="Save" onclick={say}>
	{#snippet menu()}
		<MenuItem onclick={say}>Save as draft</MenuItem>
		<MenuItem onclick={say}>Save a copy</MenuItem>
	{/snippet}
</SplitButton>
<Snackbar bind:this={snackbar} label="Action clicked" />

Variants

Both halves take the same variant, four of the ones a Button takes.

<script lang="ts">
	import { MenuItem, Snackbar, SplitButton } from 'noph-ui'

	let snackbar: ReturnType<typeof Snackbar> | undefined = $state()
	const say = () => snackbar?.show()
</script>

{#each ['filled', 'tonal', 'outlined', 'elevated'] as const as variant (variant)}
	<SplitButton {variant} label={variant} onclick={say}>
		{#snippet menu()}
			<MenuItem onclick={say}>First</MenuItem>
			<MenuItem onclick={say}>Second</MenuItem>
		{/snippet}
	</SplitButton>
{/each}
<Snackbar bind:this={snackbar} label="Action clicked" />

With an icon

<script lang="ts">
	import { MenuItem, Snackbar, SplitButton } from 'noph-ui'
	import { Icon } from 'noph-ui/icons'

	let snackbar: ReturnType<typeof Snackbar> | undefined = $state()
	const say = () => snackbar?.show()
</script>

<SplitButton label="Send" onclick={say}>
	{#snippet icon()}<Icon>send</Icon>{/snippet}
	{#snippet menu()}
		<MenuItem onclick={say}>Schedule send</MenuItem>
	{/snippet}
</SplitButton>
<Snackbar bind:this={snackbar} label="Action clicked" />

API

Renders a connected ButtonGroup holding the two halves and the menu. bind:element gives you the group.

AttributeTypeDefaultDescription
labelstring''Text of the action half.
iconSnippet | undefinedundefinedLeading icon on the action half.
menuSnippet | undefinedundefinedMenu items, rendered inside a Menu.
onclickMouseEventHandler | undefinedundefinedThe action half's handler. The trailing half opens the menu instead.
variant'filled' | 'tonal' | 'outlined' | 'elevated''filled'Applied to both halves.
size'xs' | 's' | 'm' | 'l' | 'xl''s'Applied to both halves.
openbooleanfalseBindable. Whether the menu is open.
menuLabelstring'More options'Accessible name for the trailing half.