Skip to content

Dropdown menu ​

Opens a short list of commands from a button: the actions on a table row, or a record's secondary actions.

vue
<script setup lang="ts">
import { FsButton, FsDropdownMenu, type DropdownMenuGroup } from '@fivespark/ui'

const actions: DropdownMenuGroup[] = [
  [
    { label: 'Bewerken', icon: 'pencil', onSelect() {} },
    { label: 'Dupliceren', icon: 'copy', onSelect() {} },
  ],
  [{ label: 'Verwijderen', icon: 'trash', danger: true, onSelect() {} }],
]
</script>

<template>
  <div class="min-h-72">
    <FsDropdownMenu :items="actions">
      <FsButton label="Acties" trailing-icon="chevron-down" />
    </FsDropdownMenu>
  </div>
</template>

Usage ​

vue
<script setup lang="ts">
import { FsButton, FsDropdownMenu } from '@fivespark/ui'
</script>

<template>
  <FsDropdownMenu :items="[[{ label: 'Bewerken', icon: 'pencil', onSelect: edit }]]">
    <FsButton label="Acties" trailing-icon="chevron-down" />
  </FsDropdownMenu>
</template>

items is a list of groups, each an array of items; a line separates the groups. Choosing an item runs its onSelect and closes the menu. To pick a value for a form, use a Select; for navigation between pages, a Navigation menu.

Examples ​

Icon-only trigger ​

Name the button after what it acts on, so each row's menu is told apart.

vue
<script setup lang="ts">
import { FsButton, FsDropdownMenu, type DropdownMenuGroup } from '@fivespark/ui'

const actions: DropdownMenuGroup[] = [
  [
    { label: 'Bewerken', icon: 'pencil', onSelect() {} },
    { label: 'Dupliceren', icon: 'copy', onSelect() {} },
  ],
  [{ label: 'Verwijderen', icon: 'trash', danger: true, onSelect() {} }],
]
</script>

<template>
  <div class="min-h-72">
    <FsDropdownMenu :items="actions">
      <FsButton icon="ellipsis" label="Acties voor offerte 2026-041" variant="ghost" size="dense" />
    </FsDropdownMenu>
  </div>
</template>

Labelled groups and disabled items ​

Give a group a label to name it. A disabled item is still reached with the keyboard and announced; choosing it does nothing. Leave out an action that is never allowed.

vue
<script setup lang="ts">
import { FsButton, FsDropdownMenu, type DropdownMenuGroup } from '@fivespark/ui'

const actions: DropdownMenuGroup[] = [
  { label: 'Offerte', items: [
    { label: 'Bewerken', onSelect() {} },
    { label: 'Dupliceren', onSelect() {} },
  ] },
  { label: 'Klant', items: [
    { label: 'Herinnering sturen', disabled: true, onSelect() {} },
    { label: 'Contact opnemen', onSelect() {} },
  ] },
]
</script>

<template>
  <div class="min-h-72">
    <FsDropdownMenu :items="actions">
      <FsButton label="Acties" trailing-icon="chevron-down" />
    </FsDropdownMenu>
  </div>
</template>

An item with to or href is a link. newTab adds an icon that says so, and download offers the file. A link cannot be disabled.

vue
<script setup lang="ts">
import { FsButton, FsDropdownMenu, type DropdownMenuGroup } from '@fivespark/ui'

const actions: DropdownMenuGroup[] = [
  [
    { label: 'Offerte openen', to: '/offertes/2026-041' },
    { label: 'PDF downloaden', href: '/offerte-2026-041.pdf', download: 'offerte-2026-041.pdf' },
    { label: 'Openen in het klantportaal', href: 'https://portaal.example.nl/offertes/2026-041', newTab: true },
  ],
]
</script>

<template>
  <div class="min-h-72">
    <FsDropdownMenu :items="actions">
      <FsButton label="Openen" trailing-icon="chevron-down" />
    </FsDropdownMenu>
  </div>
</template>

Put an icon on every item of a group, or on none. Put a danger item last, in a group of its own, as in the first example.

Keyboard ​

KeyDoes
Enter, Space, ↓On the trigger, opens the menu and focuses the first item
↓, ↑Moves between the items, wrapping at the ends
Home, EndGoes to the first or the last item
LettersJumps to the next item that starts with them
Enter, SpaceChooses the item and closes the menu
EscCloses the menu and returns focus to the trigger
TabCloses the menu and moves on

API Reference ​

FsDropdownMenu ​

PropTypeDefaultDescription
itemsDropdownMenuGroup[]requiredThe menu's groups, in order, divided by lines: each an array of items, or `{ label, items }` for a group with a name.
SlotPropsDescription
defaultanyThe button that opens it: one `FsButton`, with a trailing `chevron-down`, or icon-only `ellipsis` named after what it acts on.