[Feature Request] Add `VSplitButton` Component
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 41k
- Forks
- 7.1k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 11
Description
Problem to solve
Description
Currently, Vuetify does not provide a built-in SplitButton component. A SplitButton combines:
- A primary action button (executes the most common/primary action).
- A secondary dropdown toggle (reveals additional related actions).
This pattern is widely used in enterprise apps, admin panels, and productivity tools to reduce button clutter while still offering quick access to multiple related commands.
Proposed API / Usage Example
<v-split-btn
label="Save"
:items="[
{ label: 'Save As Draft', value: 'draft' },
{ label: 'Save & Publish', value: 'publish' }
]"
color="primary"
variant="flat"
size="large"
@click="onSave"
@click:item="onSplitAction"
/>
-
Props:
label→ primary action textitems→ array of dropdown items (or allow slot for full flexibility)color,variant,size→ inherited fromv-btnfor consistency
-
Events:
primary-click→ when the main button is clickeditem-click→ when a dropdown item is selected
Why this belongs in Vuetify
- Material Design Adjacent: Many modern design systems (Material Design, Fluent UI, Bootstrap, Ant Design) include split buttons because they solve a common UX problem: offering a default action with secondary options nearby.
- Developer Experience: Today, developers must manually compose
v-btn+v-menu+v-list. This is repetitive boilerplate and inconsistent across projects. - Consistency: A canonical Vuetify implementation would ensure accessibility (keyboard navigation, focus trapping, aria roles), consistent sizing/alignment, and theme support.
Alternatives Today
- Manually compose a
v-btnand av-menuwithv-list(works, but verbose and error-prone). - Use
v-btn-toggle(not semantically the same, doesn’t support a primary action + dropdown).
References
- Material Design: Split Button
- Fluent UI:
SplitButton - Bootstrap: Split Button Dropdowns
- Ant Design: Dropdown Button
Additional Context
This component would be especially valuable in enterprise dashboards, admin panels, and data-heavy applications, where contextual actions need to be accessible but not overwhelming.
Proposed solution
<template>
<div class="d-inline-flex">
<!-- Primary Action Button -->
<v-btn
:color="props.color"
:variant="props.variant"
:size="props.size"
@click="emit('click')"
>
<slot>{{ props.label }}</slot>
</v-btn>
<!-- Dropdown Menu -->
<v-menu>
<template #activator="{ props: menuProps }">
<v-btn
v-bind="menuProps"
:color="props.color"
:variant="props.variant"
:size="props.size"
icon
>
<!-- Or let this icon be a prop/slot -->
<v-icon>mdi-chevron-down</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in props.items"
:key="index"
@click="emit('click:item', item)"
>
<v-list-item-title>{{ item.label }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</template>
<script setup lang="ts">
// Or use a similar existing type
type SplitButtonItem = {
label: string;
value?: string | number | boolean | object;
};
// Or use a similar existing type
type SplitButtonVariant =
| "text"
| "flat"
| "outlined"
| "tonal"
| "elevated"
| "plain";
// Or use a similar existing type
type SplitButtonSize =
| "x-small"
| "small"
| "default"
| "large"
| "x-large";
// Or use a similar existing type
type SplitButtonProps = {
label?: string;
items?: SplitButtonItem[];
color?: string;
variant?: SplitButtonVariant;
size?: SplitButtonSize;
};
// Or use a similar existing type
type SplitButtonEmits = {
(e: "click"): void;
(e: "click:item", item: SplitButtonItem): void;
};
const props = withDefaults(defineProps<SplitButtonProps>(), {
label: "Action",
items: () => [],
color: "primary",
variant: "flat",
size: "default",
});
const emit = defineEmits<SplitButtonEmits>();
</script>
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the existing v-btn, v-menu, and v-list components referenced in the proposed composition, along with their APIs and interaction patterns. Define the component's final props, events, accessibility behavior, and item handling; done means a documented VSplitButton implementation with coverage for primary and dropdown actions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100