Dropdown
The Dropdown component provides a flexible way to display a menu of options when a user interacts with a trigger element. Dropdowns are commonly used for navigation menus, action lists, and other UI interactions where you want to conserve space while providing multiple options. They are distinct from form selection controls and are not intended for form field selection.
Basic Usage
The Dropdown component can be used with various trigger elements, such as buttons, chips, or lozenges. The content inside the dropdown slot becomes the trigger element that opens the dropdown menu when clicked.
<template>
<div class="spr-flex spr-items-center spr-gap-4">
<!-- Button trigger dropdown -->
<spr-dropdown
id="sample-dropdownBasic1"
v-model="dropdownModel.dropdownBasic1"
:menu-list="menuList"
width="100px"
popper-width="200px"
dropdown
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Button</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
<!-- Chips trigger dropdown -->
<spr-dropdown
id="sample-dropdownBasic2"
v-model="dropdownModel.dropdownBasic2"
:menu-list="menuList"
width="100px"
popper-width="200px"
dropdown
>
<spr-chips class="spr-w-full" label="Chips" />
</spr-dropdown>
<!-- Lozenge trigger dropdown -->
<spr-dropdown
id="sample-dropdownBasic3"
v-model="dropdownModel.dropdownBasic3"
:menu-list="menuList"
width="100px"
popper-width="200px"
dropdown
>
<spr-lozenge class="spr-w-full" label="Lozange" />
</spr-dropdown>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { Icon } from '@iconify/vue';
const dropdownModel = ref({
dropdownBasic1: '',
dropdownBasic2: '',
dropdownBasic3: '',
});
const menuList = ref([
{ text: 'Google', value: 'https://www.google.com' },
{ text: 'GitHub', value: 'https://github.com' },
{ text: 'Gmail', value: 'https://mail.google.com' },
// Additional items...
]);
// Optional: Handle selections to open URLs in new tabs
const handleDropdownLink = (newValue, key) => {
if (newValue) {
window.open(newValue, '_blank', 'noopener,noreferrer');
dropdownModel.value[key] = null;
}
};
watch(
() => dropdownModel.value.dropdownBasic1,
(newValue) => handleDropdownLink(newValue, 'dropdownBasic1'),
);
// Similar watchers for other dropdown models...
</script>
Important Properties
id
: A unique identifier required for proper functioning of the dropdownv-model
: Binds the selected value(s) from the dropdownmenu-list
: An array of options to display in the dropdown menudropdown
: Set totrue
to enable dropdown behavior (as opposed to select behavior)
Grouped Items By
The Dropdown component supports organizing menu items into groups based on alphabetical order. You can group items by A-Z
(alphabetical) or Z-A
(reverse alphabetical) by using the group-items-by
prop.
<template>
<div class="spr-grid spr-gap-4">
<spr-dropdown
id="sample-dropdownGroupedItemsBy"
v-model="dropdownModel.dropdownGroupedItemsBy"
:menu-list="menuList"
width="100px"
popper-width="200px"
group-items-by="A-Z" <!-- Options: 'A-Z' or 'Z-A' -->
dropdown
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Button</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
</div>
</template>
<script setup>
import { ref } from 'vue';
const dropdownModel = ref({
dropdownGroupedItemsBy: ''
});
const menuList = ref([
{ text: 'Google', value: 'https://www.google.com' },
{ text: 'GitHub', value: 'https://github.com' },
// Additional items...
]);
</script>
Grouping Benefits
Grouping items alphabetically helps users find options more easily when you have a large number of menu items. This is especially useful for navigation menus or application switching dropdowns.
Pre-Selected Items
You can set a default selected value in the dropdown by initializing the v-model
with a value that matches one of the options in your menu-list
. This is useful when you want to show a pre-selected option or restore a previously selected value.
V-Model: https://www.yahoo.com
<template>
<div class="spr-grid spr-gap-4">
<spr-dropdown
id="sample-dropdownPreSelectedItems"
v-model="dropdownPreSelectedItems"
:menu-list="menuList"
width="100px"
popper-width="200px"
dropdown
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Button</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
<!-- Display the current selected value -->
<code class="spr-font-medium">
V-Model: {{ dropdownPreSelectedItems ? dropdownPreSelectedItems : `""` }}
</code>
</div>
</template>
<script setup>
import { ref } from 'vue';
// Pre-select Yahoo by setting its value
const dropdownPreSelectedItems = ref('https://www.yahoo.com');
const menuList = ref([
{ text: 'Google', value: 'https://www.google.com' },
{ text: 'Yahoo', value: 'https://www.yahoo.com' },
// Additional items...
]);
</script>
Value Types
The v-model
for the dropdown component supports various value types including:
- Single primitive values (strings, numbers)
- Objects
- Arrays (for multi-select dropdowns)
Placements
The dropdown menu can be positioned in various ways relative to the trigger element. The placement
prop controls where the dropdown menu appears.
Available placement options:
auto
,auto-start
,auto-end
- Automatically determine the best placementtop
,top-start
,top-end
- Position above the triggerright
,right-start
,right-end
- Position to the right of the triggerbottom
,bottom-start
,bottom-end
- Position below the trigger (default)left
,left-start
,left-end
- Position to the left of the trigger
<template>
<!-- Auto placement -->
<spr-dropdown
id="dropdown-auto"
v-model="selectedValue"
:menu-list="menuList"
placement="auto"
popper-width="200px"
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Auto</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
<!-- Top placement -->
<spr-dropdown
id="dropdown-top"
v-model="selectedValue"
:menu-list="menuList"
placement="top"
popper-width="200px"
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Top</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
</template>
Responsive Placement
The auto
placement options are particularly useful for responsive designs as they will automatically adjust based on available space, preventing dropdowns from being cut off at screen edges.
Width and Popper Width
The Dropdown component provides two ways to control the sizing:
width
: Controls the overall width of the dropdown wrapper (including the trigger element)popper-width
: Controls the width of just the dropdown menu that appears when clicked
<template>
<spr-dropdown
id="sample-dropdownWidth"
v-model="dropdownWidth"
placeholder="Select an option"
:menu-list="menuList"
width="50%" <!-- Width of the trigger wrapper -->
popper-width="500px" <!-- Width of the dropdown menu -->
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Button</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
</template>
Size Units
Both width properties accept any valid CSS unit:
- Pixels:
"200px"
- Percentage:
"50%"
- Viewport units:
"50vw"
"auto"
or"100%"
for full width
Popper Strategy
When using dropdowns inside positioned elements like modals or fixed panels, you may need to change the positioning strategy. The popper-strategy
prop controls how the dropdown menu is positioned:
absolute
(default): Positions the dropdown relative to its nearest positioned ancestorfixed
: Positions the dropdown relative to the viewport, ignoring parent element positioning
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel" title="Dropdown with Modal">
<spr-dropdown
id="sample-dropdownStrategy"
v-model="dropdownStrategy"
:menu-list="menuList"
wrapper-position="initial" <!-- Important when using with modals -->
popper-strategy="fixed" <!-- Use fixed strategy in modals -->
width="100px"
>
<spr-button class="spr-w-full" tone="success" has-icon>
<span>Button</span>
<Icon icon="ph:caret-down" />
</spr-button>
</spr-dropdown>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit...
</p>
</spr-modal>
</template>
<script setup>
import { ref } from 'vue';
const modalModel = ref(false);
const dropdownStrategy = ref('');
</script>
Important Note
When using the fixed
popper strategy, you should also set wrapper-position="initial"
to override the default relative
positioning. This prevents positioning conflicts within complex layouts like modals.
Menu List Data Formats
The Dropdown component is flexible and supports various data formats for the menu-list
prop:
Array of Objects with text/value Properties
const menuList = [
{ text: 'Google', value: 'https://www.google.com' },
{ text: 'GitHub', value: 'https://github.com' },
];
Array of Strings
const menuList = ['Google', 'GitHub', 'Gmail'];
// Automatically converted to { text: 'Google', value: 'Google' }, etc.
Array of Custom Objects
const menuList = [
{ name: 'John Doe', id: 1, department: 'Engineering' },
{ name: 'Jane Smith', id: 2, department: 'Marketing' },
];
// Use textField and valueField props to specify which properties to use
<spr-dropdown
:menu-list="menuList"
text-field="name" // Display name property as text
value-field="id" // Use id property as the value
/>
Multi-Select Dropdown
To create a dropdown that allows selecting multiple items, set the multi-select
prop to true
. The v-model
will be an array containing all selected values.
<template>
<spr-dropdown
id="multi-select-dropdown"
v-model="selectedValues"
:menu-list="menuList"
:multi-select="true"
dropdown
>
<spr-button class="spr-w-full" tone="success">
Select Multiple Items
</spr-button>
</spr-dropdown>
</template>
<script setup>
import { ref } from 'vue';
// Initialize with pre-selected values
const selectedValues = ref(['https://www.google.com', 'https://github.com']);
const menuList = ref([
{ text: 'Google', value: 'https://www.google.com' },
{ text: 'GitHub', value: 'https://github.com' },
// Additional items...
]);
</script>
API Reference
Props
Name | Description | Type | Default |
---|---|---|---|
id | Required. Unique identifier for the dropdown, used to bind the popper to the correct element | string | - |
modelValue | The selected value(s) in the dropdown. Bound with v-model | string | number | object | Array | [] |
menuList | List of options to display in the dropdown menu. Can be formatted as: - Array of objects with text and value properties- Array of strings - Array of custom objects (use with textField and valueField ) | array | [] |
textField | When using custom objects in menuList , specifies which property to use for display text | string | 'text' |
valueField | When using custom objects in menuList , specifies which property to use for the value | string | 'value' |
searchString | Search term to filter the dropdown options | string | '' |
multiSelect | When true, allows selecting multiple options from the dropdown | boolean | false |
groupItemsBy | Groups the dropdown items alphabetically | 'A-Z' | 'Z-A' | - |
placement | Controls the position of the dropdown menu relative to the trigger | 'auto' | 'auto-start' | 'auto-end' | 'top' | 'top-start' | 'top-end' | 'right' | 'right-start' | 'right-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'left-start' | 'left-end' | 'bottom' |
wrapperPosition | CSS position value for the dropdown wrapper | string | 'relative' |
width | Width of the dropdown wrapper (including the trigger element) | string | '100%' |
popperWidth | Width of the dropdown menu that appears when triggered | string | '100%' |
popperInnerWidth | Width of the inner content area of the dropdown menu | string | 'unset' |
popperStrategy | Positioning strategy for the dropdown menu, especially important in modals | 'absolute' | 'fixed' | 'absolute' |
disabled | When true, disables the dropdown from being opened | boolean | false |
ladderized | When true, enables hierarchical dropdown options (nested menus) | boolean | false |
removeCurrentLevelInBackLabel | For ladderized dropdowns, controls the back label behavior | boolean | false |
noCheckInList | When true, hides the checkmark icons in the dropdown list | boolean | false |
dropdown | When true, enables dropdown-specific behavior (as opposed to select behavior) | boolean | false |
lozenge | When true, enables lozenge list display. | boolean | false |
Events
Name | Description | Parameters |
---|---|---|
update:modelValue | Emitted when the selected value(s) change | The new selected value(s) |
infinite-scroll-trigger | Emitted when the user scrolls to the bottom of the dropdown list, useful for implementing lazy loading | Boolean |
Slots
Name | Description |
---|---|
default | The trigger element that opens the dropdown when clicked (typically a button, chips, or lozenge) |
Product Uses
These Sprout products use the Dropdown component: