Dropdown
<pa-dropdown> | PaDropdown
A versatile dropdown select component with floating labels, validation support, and icon integration. Built on native HTML select elements for accessibility while providing enhanced styling and functionality.
<template>
<pa-dropdown
v-model="selectedValue"
label="Choose an option"
:items="[
{ value: '', label: 'Select...' },
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
{ value: 'option3', label: 'Option 3' }
]"
/>
</template>
<script setup>
import { ref } from 'vue'
const selectedValue = ref('')
</script>Examples
Basic Usage
The simplest way to use a dropdown with predefined options.
<template>
<pa-dropdown
v-model="country"
label="Select Country"
:items="[
{ value: '', label: 'Choose country...' },
{ value: 'us', label: 'United States' },
{ value: 'ca', label: 'Canada' },
{ value: 'uk', label: 'United Kingdom' },
{ value: 'au', label: 'Australia' }
]"
@update:modelValue="handleCountryChange"
/>
</template>
<script setup>
import { ref } from 'vue'
const country = ref('')
const handleCountryChange = (value) => {
console.log('Selected country:', value)
}
</script>Using Slots for Options
For more complex option content or when working with dynamic templates.
<template>
<pa-dropdown v-model="priority" label="Priority Level">
<option value="" disabled>Select priority...</option>
<option value="low">🟢 Low Priority</option>
<option value="medium">🟡 Medium Priority</option>
<option value="high">🔴 High Priority</option>
<option value="urgent">🚨 Urgent</option>
</pa-dropdown>
</template>
<script setup>
import { ref } from 'vue'
const priority = ref('')
</script>With Icons
Add prepend or append icons to enhance the dropdown interface.
<template>
<div style="display: flex; flex-direction: column; gap: 1rem;">
<pa-dropdown
v-model="accountType"
label="Account Type"
prepend-icon="user-solid"
:items="[
{ value: '', label: 'Select account type...' },
{ value: 'personal', label: 'Personal Account' },
{ value: 'business', label: 'Business Account' },
{ value: 'enterprise', label: 'Enterprise Account' }
]"
/>
<pa-dropdown
v-model="paymentMethod"
label="Payment Method"
append-icon="credit-card-solid"
:items="[
{ value: '', label: 'Choose payment method...' },
{ value: 'card', label: 'Credit Card' },
{ value: 'bank', label: 'Bank Transfer' },
{ value: 'paypal', label: 'PayPal' }
]"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
const accountType = ref('')
const paymentMethod = ref('')
</script>Required Field with Validation
Dropdown with required validation and error handling.
<template>
<pa-dropdown
v-model="requiredValue"
label="Required Selection"
:required="true"
:items="[
{ value: '', label: 'Please select...' },
{ value: 'option1', label: 'Option 1' },
{ value: 'option2', label: 'Option 2' },
{ value: 'option3', label: 'Option 3' }
]"
/>
</form>
</template>Disabled State
Not connected
Dropdown in disabled state for read-only scenarios.
<template>
<pa-dropdown
v-model="status"
label="Status (Read Only)"
:disabled="true"
:items="[
{ value: 'active', label: 'Active' },
{ value: 'inactive', label: 'Inactive' },
{ value: 'pending', label: 'Pending' }
]"
/>
</template>Interactive Example
A complete form example showing dropdown integration with other components.
<template>
<form @submit.prevent="createListing" class="listing-form">
<pa-dropdown
v-model="category"
label="Category"
prepend-icon="tags-solid"
:items="categoryOptions"
:required="true"
/>
<pa-dropdown
v-model="condition"
label="Condition"
:items="conditionOptions"
:required="true"
/>
<pa-button type="submit" variant="primary">
Create Listing
</pa-button>
</form>
</template>Importing
import { PaDropdown } from '@payadvantage/ui-components'Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
modelValue | The selected value (used with v-model). | no | string | null | '' |
label | The floating label text. | no | string | '' |
items | Array of options when not using slots. | no | PaDropdownGroupItem[] | [] |
required | Makes the dropdown required for validation. | no | boolean | false |
disabled | Disables the dropdown. | no | boolean | false |
readonly | Makes the dropdown read-only. | no | boolean | false |
prependIcon | Icon to display on the left side. | no | string | '' |
appendIcon | Icon to display on the right side (overrides default dropdown arrow). | no | string | '' |
iconVariant | Icon color variant. | no | 'light' | 'dark' | 'dark' |
sfSelector | Custom selector for testing frameworks. | no | string | '' |
Learn more about component properties.
Events
| Name | Description | Event Detail |
|---|---|---|
update:modelValue | Emitted when the selected value changes (for v-model). | string - The new selected value |
focus | Emitted when the dropdown gains focus. | Event - The focus event |
blur | Emitted when the dropdown loses focus. | Event - The blur event |
appendClick | Emitted when the append icon is clicked. | PaDropdown - The component instance |
prependClick | Emitted when the prepend icon is clicked. | PaDropdown - The component instance |
Learn more about component events.
Slots
| Name | Description |
|---|---|
default | The option elements. Use when you need custom option content or dynamic templates. |
<template>
<pa-dropdown label="Custom Options">
<option value="">Choose...</option>
<option value="1">Option with 🎯 emoji</option>
<option value="2">Option with custom formatting</option>
</pa-dropdown>
</template>Learn more about using slots.
Methods
| Name | Description | Parameters |
|---|---|---|
focus() | Programmatically focus the dropdown. | None |
<template>
<pa-dropdown ref="dropdownRef" label="Focus me" />
<pa-button @click="focusDropdown">Focus Dropdown</pa-button>
</template>
<script setup>
import { ref } from 'vue'
const dropdownRef = ref()
const focusDropdown = () => {
dropdownRef.value?.focus()
}
</script>Types
interface PaDropdownGroupItem {
value: string
label: string
}Dependencies
- PaIcon: Used for prepend, append, and dropdown arrow icons
- Validation Mixin: Provides built-in validation capabilities with visual feedback
- Bootstrap CSS: Uses Bootstrap's form control and custom select styling
- Design Tokens: CSS custom properties for consistent theming
Design Notes
The dropdown component provides:
- Native accessibility: Built on standard HTML select elements for screen reader compatibility
- Floating labels: Smooth label animations based on focus and selection state
- Flexible options: Support for both prop-based and slot-based option definitions
- Icon integration: Optional prepend and append icons with click handling
- Validation support: Built-in validation with visual error states
- Responsive design: Adapts to container width and screen sizes
Visual Design
- Uses floating label pattern for space efficiency
- Custom dropdown arrow icon that rotates based on open/closed state
- Validation states with clear visual feedback
- Icon positioning that doesn't interfere with text content
- Consistent styling with other form components
Interaction Patterns
- Click to open native dropdown menu
- Keyboard navigation through options
- Automatic validation on blur events
- Icon click events for custom actions
- Focus management for accessibility
This component is ideal for:
- Form field selection inputs
- Filter and sorting controls
- Configuration and settings interfaces
- Multi-step form navigation
- Data entry applications requiring validated selections
Accessibility Notes
- Uses semantic HTML select elements for proper screen reader support
- Maintains native keyboard navigation (arrow keys, Enter, Escape)
- Required fields are properly announced to assistive technologies
- Validation states are communicated both visually and programmatically
- Focus management follows standard form control patterns
- Label association is maintained for screen reader compatibility
- Custom icons don't interfere with accessibility features