DropdownButton
A button that allows selecting from a list of items.
Usage
Use DropdownButton to let the user select a single value from a set of options.
DropdownButton VariantsExpanded & CustomSelected Value: Selected Multi: []Smart Positioning (Resize window or scroll to test auto-flip)
iOS Style (Default)Selected:
Select Item
Material Selected: Option 1
Option 1
Select User
Select Multiple Items
Left Align
Center Align
Right Align
Code Example
vue
<template>
<Container :padding="EdgeInsets.all(20)">
<Column :crossAxisAlignment="'start'" :mainAxisSize="'min'">
<Text :style="headerStyle">DropdownButton Variants</Text>
<SizedBox :height="20" />
<Row :mainAxisAlignment="'spaceEvenly'" :crossAxisAlignment="'start'">
<!-- iOS Variant -->
<Column :mainAxisSize="'min'" :crossAxisAlignment="'center'">
<Text :style="labelStyle">iOS Style (Default)</Text>
<SizedBox :height="10" />
<DropdownButton
v-model="selectedIos"
:items="items"
placeholder="Select Item"
variant="ios"
color="white"
/>
<SizedBox :height="10" />
<Text>Selected: {{ selectedIos }}</Text>
</Column>
<!-- Material Variant -->
<Column :mainAxisSize="'min'" :crossAxisAlignment="'center'">
<Text :style="labelStyle">Material </Text>
<SizedBox :height="10" />
<DropdownButton
v-model="selectedMaterial"
:items="items"
placeholder="Choose an option"
variant="material"
/>
<SizedBox :height="10" />
<Text>Selected: {{ selectedMaterial }}</Text>
</Column>
</Row>
<SizedBox :height="40" />
<Text :style="headerStyle">Expanded & Custom</Text>
<SizedBox :height="20" />
<Row :mainAxisAlignment="'start'" :gap="40">
<Container
:width="300"
:decoration="
BoxDecoration({
border: Border.all({ width: 1, color: Colors.grey300 }),
borderRadius: BorderRadius.circular(8),
})
"
:padding="EdgeInsets.all(10)"
>
<DropdownButton
v-model="selectedCustom"
:items="complexItems"
placeholder="Select User"
expanded
:color="Colors.grey50"
/>
</Container>
<!-- Multi-select -->
<Container
:width="300"
:decoration="
BoxDecoration({
border: Border.all({ width: 1, color: Colors.grey300 }),
borderRadius: BorderRadius.circular(8),
})
"
:padding="EdgeInsets.all(10)"
>
<DropdownButton
v-model="selectedMulti"
:items="items"
placeholder="Select Multiple Items"
expanded
multiple
:color="Colors.grey50"
/>
</Container>
</Row>
<SizedBox :height="10" />
<Text>Selected Value: {{ selectedCustom }}</Text>
<Text>Selected Multi: {{ selectedMulti }}</Text>
<SizedBox :height="40" />
<Text :style="headerStyle">Smart Positioning</Text>
<SizedBox :height="5" />
<Text :style="subHeaderStyle"> (Resize window or scroll to test auto-flip) </Text>
<SizedBox :height="20" />
<Row mainAxisAlignment="spaceBetween" :gap="20">
<DropdownButton
v-model="posLeft"
:items="longItems"
placeholder="Left Align"
variant="ios"
/>
<DropdownButton
v-model="posCenter"
:items="longItems"
placeholder="Center Align"
variant="ios"
/>
<DropdownButton
v-model="posRight"
:items="longItems"
placeholder="Right Align"
variant="ios"
/>
</Row>
<SizedBox :height="100" />
<!-- Extra space for bottom positioning test -->
</Column>
</Container>
</template>
<script setup lang="ts">
import { ref, computed } from "vue";
import {
Container,
Column,
Row,
Text,
SizedBox,
DropdownButton,
EdgeInsets,
Colors,
TextStyle,
FontWeight,
FontStyle,
BoxDecoration,
BorderRadius,
Border,
} from "fluekit";
const items = ["Option 1", "Option 2", "Option 3", "Option 4"];
const longItems = Array.from({ length: 8 }, (_, i) => `Option ${i + 1} (Long List)`);
const complexItems = [
{ label: "Alice Smith", value: 1 },
{ label: "Bob Johnson", value: 2 },
{ label: "Charlie Brown", value: 3 },
];
const selectedMaterial = ref(items[0]);
const selectedIos = ref(null);
const selectedCustom = ref(null);
const selectedMulti = ref([]);
const posLeft = ref(null);
const posCenter = ref(null);
const posRight = ref(null);
const headerStyle = computed(() =>
TextStyle({
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.black87,
}),
);
const subHeaderStyle = computed(() =>
TextStyle({
fontSize: 14,
color: Colors.grey600,
fontStyle: FontStyle.italic,
}),
);
const labelStyle = computed(() =>
TextStyle({
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.grey700,
}),
);
</script>Props
| Prop | Type | Default | Description |
|---|---|---|---|
| modelValue | any | - | The currently selected value. |
| items | Array<string | {label, value}> | [] | The list of items to display. |
| variant | 'material' | 'ios' | 'ios' | The visual style of the dropdown. |
| placeholder | string | 'Select' | Text to display when no item is selected. |
| expanded | boolean | false | Whether the button should fill the available width. |
| multiple | boolean | false | Whether multiple items can be selected. |
| color | string | Color | 'transparent' | Background color of the button. |
| menuColor | string | Color | Colors.white | Background color of the menu. |
| textColor | string | Color | Colors.black87 | Color of the text. |
| icon | any | ArrowDropDown | Custom icon for the dropdown. |
| iconColor | string | Color | - | Color of the icon. |
| elevation | number | 8 | Elevation of the menu (shadow). |
| offset | {x: number, y: number} | {x: 0, y: 4} | Offset of the menu relative to the button. |
Events
| Name | Payload | Description |
|---|---|---|
| update:modelValue | value | Emitted when the selection changes. |
| change | value | Emitted when the selection changes. |
Smart Positioning
The menu automatically adjusts its position based on the available screen space:
- Vertical Alignment: Opens downwards by default. If there isn't enough space below, it automatically flips to open upwards.
- Horizontal Alignment:
- Left Alignment: If the button is close to the left screen edge, the menu aligns to the left side of the button.
- Right Alignment: If the button is close to the right screen edge, the menu aligns to the right side of the button.
- Center Alignment: In standard conditions, the menu is centered relative to the button.