Skip to content

Dropdown

Toggleable menu for displaying lists of links and actions.

NameCategoryDescriptionTypeDefault
type? StyleButton typeButtonType
splitButton? StyleWhether to use split buttonbooleanfalse
maxHeight? StyleMax menu height, scrollable when exceedednumber | string
showArrow? StyleWhether to show pixel arrow pointing to triggerbooleanfalse
hoverColor? StyleCustom hover background color for menu itemsstring
DropdownItemdivided? StyleWhether to show dividerbooleanfalse
size? SizeButton size'large' | 'default' | 'small''default'
disabled? StateWhether disabledbooleanfalse
DropdownItemdisabled? StateWhether disabledbooleanfalse
trigger? BehaviorTrigger mode'hover' | 'click' | 'contextmenu''hover'
hideOnClick? BehaviorWhether to hide menu on clickbooleantrue
placement? BehaviorMenu placementPlacement'bottom'
↑ / ↓? BehaviorMove focus between items (skip disabled)
Enter / Space? BehaviorSelect the focused item
Escape? BehaviorClose menu and return focus to trigger
Home / End? BehaviorJump to first/last enabled item
items? ContentMenu itemsDropdownItemProps[]
DropdownItemcommand? ContentCommandstring | number
DropdownItemlabel? ContentDisplay textstring | VNode
DropdownItemicon? ContentMenu item icon namestring
command? EventTriggered when menu item is clicked(command: string | number) => void
visible-change? EventTriggered when menu shows/hides(visible: boolean) => void
click? EventTriggered when split button left side is clicked(event: MouseEvent) => void
default? SlotElement that triggers dropdown
dropdown? SlotDropdown content, usually <px-dropdown-item>
open? ExposeOpen dropdown() => void
close? ExposeClose dropdown() => void

Basic Usage

Hover on the dropdown menu to unfold it for more actions.

<template>
  <px-dropdown :items="items" @command="handleCommand">
    <px-button>
      Dropdown Menu <px-icon icon="chevron-down" style="margin-left: 4px" />
    </px-button>
  </px-dropdown>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Action 1', command: 'a' },
  { label: 'Action 2', command: 'b' },
  { label: 'Action 3', command: 'c' },
  { label: 'Action 4', command: 'd', divided: true },
];

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Trigger

Configure click or hover to trigger.

<template>
  <div class="demo-dropdown">
    <px-dropdown :items="items" trigger="hover">
      <px-button>Hover</px-button>
    </px-dropdown>
    <px-dropdown :items="items" trigger="click">
      <px-button>Click</px-button>
    </px-dropdown>
  </div>
</template>

<script setup lang="ts">
const items = [
  { label: 'Action 1', command: 'a' },
  { label: 'Action 2', command: 'b' },
  { label: 'Action 3', command: 'c' },
];
</script>

<style scoped>
.demo-dropdown {
  display: flex;
  gap: 12px;
}
</style>

Split Button

Use split-button to split the dropdown button.

<template>
  <px-dropdown :items="items" split-button type="primary" trigger="click" @click="handleClick" @command="handleCommand">
    Actions
  </px-dropdown>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Action 1', command: 'a' },
  { label: 'Action 2', command: 'b' },
  { label: 'Action 3', command: 'c' },
];

const handleClick = () => {
  PxMessage.info('Button clicked');
};

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Disabled Items

Use disabled attribute to disable certain items.

<template>
  <px-dropdown :items="items" @command="handleCommand">
    <px-button>
      Dropdown <px-icon icon="chevron-down" style="margin-left: 4px" />
    </px-button>
  </px-dropdown>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Action 1', command: 'a' },
  { label: 'Action 2 (disabled)', command: 'b', disabled: true },
  { label: 'Action 3', command: 'c' },
  { label: 'Action 4 (disabled)', command: 'd', disabled: true },
];

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Icon Items

Use icon property on items to show pixel icons alongside labels.

<template>
  <px-dropdown :items="items" @command="handleCommand">
    <px-button>
      Icon Menu <px-icon icon="chevron-down" style="margin-left: 4px" />
    </px-button>
  </px-dropdown>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Edit', command: 'edit', icon: 'edit' },
  { label: 'Search', command: 'search', icon: 'search' },
  { label: 'Bookmark', command: 'bookmark', icon: 'bookmark' },
  { label: 'Delete', command: 'delete', icon: 'trash', divided: true },
];

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Max Height

Use max-height to limit the menu height when there are many items.

<template>
  <px-dropdown :items="items" :max-height="200" @command="handleCommand">
    <px-button>
      Long Menu <px-icon icon="chevron-down" style="margin-left: 4px" />
    </px-button>
  </px-dropdown>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = Array.from({ length: 20 }, (_, i) => ({
  label: `Action ${i + 1}`,
  command: `action-${i + 1}`,
}));

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Arrow

Use show-arrow to display a pixel-art arrow pointing from the dropdown panel to the trigger.

<template>
  <div style="display: flex; gap: 16px; flex-wrap: wrap">
    <px-dropdown :items="items" show-arrow @command="handleCommand">
      <px-button>
        Bottom (default) <px-icon icon="chevron-down" style="margin-left: 4px" />
      </px-button>
    </px-dropdown>

    <px-dropdown :items="items" show-arrow placement="right" @command="handleCommand">
      <px-button>
        Right <px-icon icon="chevron-down" style="margin-left: 4px" />
      </px-button>
    </px-dropdown>

    <px-dropdown :items="items" show-arrow placement="top" @command="handleCommand">
      <px-button>
        Top <px-icon icon="chevron-down" style="margin-left: 4px" />
      </px-button>
    </px-dropdown>
  </div>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Action 1', command: 'a' },
  { label: 'Action 2', command: 'b' },
  { label: 'Action 3', command: 'c' },
];

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Custom Hover Color

Use hover-color to customize the background color of menu items on hover.

<template>
  <div style="display: flex; gap: 16px; flex-wrap: wrap">
    <px-dropdown :items="items" hover-color="#22c55e" @command="handleCommand">
      <px-button>
        Green <px-icon icon="chevron-down" style="margin-left: 4px" />
      </px-button>
    </px-dropdown>

    <px-dropdown :items="items" hover-color="#ef4444" @command="handleCommand">
      <px-button>
        Red <px-icon icon="chevron-down" style="margin-left: 4px" />
      </px-button>
    </px-dropdown>

    <px-dropdown :items="items" hover-color="#f59e0b" @command="handleCommand">
      <px-button>
        Amber <px-icon icon="chevron-down" style="margin-left: 4px" />
      </px-button>
    </px-dropdown>
  </div>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Action 1', command: 'a' },
  { label: 'Action 2', command: 'b' },
  { label: 'Action 3', command: 'c' },
  { label: 'Action 4', command: 'd', divided: true },
];

const handleCommand = (command: string) => {
  PxMessage.info(`Command: ${command}`);
};
</script>

Keyboard Navigation

The dropdown supports full keyboard navigation. Press Arrow keys to move between items, Enter to select, and Escape to close.

<template>
  <px-dropdown :items="items" trigger="click" @command="handleCommand">
    <px-button>
      Click &amp; Navigate <px-icon icon="chevron-down" style="margin-left: 4px" />
    </px-button>
  </px-dropdown>
</template>

<script setup lang="ts">
import { PxMessage } from 'sakana-element';

const items = [
  { label: 'Home', command: 'home', icon: 'home' },
  { label: 'Edit', command: 'edit', icon: 'edit' },
  { label: 'Disabled', command: 'disabled', disabled: true },
  { label: 'Search', command: 'search', icon: 'search' },
  { label: 'Settings', command: 'settings', icon: 'sliders', divided: true },
];

const handleCommand = (command: string) => {
  PxMessage.info(`Selected: ${command}`);
};
</script>