Multi Select
The Multi Select component allows users to select multiple options from a select list. It is useful for scenarios where users need to choose more than one item from a predefined set of options.
Basic Usage
V-Model: []
<template>
<spr-select-multiple
id="sample-select"
v-model="selectBasic"
label="Multi-Select Label"
placeholder="Select an option"
:options="options"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectBasic = ref([]); // Use an array for multi-select
const options = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
{ text: 'Date', value: 'date' },
{ text: 'Elderberry', value: 'elderberry' },
{ text: 'Fig', value: 'fig' },
{ text: 'Grape', value: 'grape' },
{ text: 'Nectarine', value: 'nectarine' },
{ text: 'Orange', value: 'orange' },
{ text: 'Papaya', value: 'papaya' },
{ text: '89 Quince', value: '50' },
]);
</script>
Grouped Items By
You can group items by default
, A-Z
or Z-A
order by passing the group-items-by
prop and specifying the desired grouping type.
<template>
<div class="spr-grid spr-gap-4">
<spr-select-multiple
id="sample-select"
v-model="selectGroupedItemsBy"
label="Multi-Select Label"
placeholder="Select an option"
:options="options"
group-items-by="A-Z"
/>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectGroupedItemsBy = ref([]); // Use an array for multi-select
const options = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
{ text: 'Date', value: 'date' },
{ text: 'Elderberry', value: 'elderberry' },
{ text: 'Fig', value: 'fig' },
{ text: 'Grape', value: 'grape' },
{ text: 'Nectarine', value: 'nectarine' },
{ text: 'Orange', value: 'orange' },
{ text: 'Papaya', value: 'papaya' },
{ text: '89 Quince', value: '50' },
]);
</script>
Pre-Selected Items
Pre-selected items are options that are automatically selected when the select is first displayed. For multi-select, the v-model
should be an array of values (strings, numbers, or objects) that match the value
field of your options.
V-Model: [
"100",
"200",
"cherry"
]
<template>
<spr-select-multiple
id="sample-select"
v-model="selectPreSelectedItems"
label="Select Fruits"
placeholder="Select one or more fruits"
:options="options"
group-items-by="A-Z"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
// Pre-select multiple items by passing an array of values
const selectPreSelectedItems = ref(['100', 200, 'cherry']);
const options = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
{ text: 'Date', value: 'date' },
{ text: 'Elderberry', value: 'elderberry' },
{ text: 'Fig', value: 'fig' },
{ text: 'Grape', value: 'grape' },
{ text: 'Honeydew', value: 'honeydew' },
{ text: 'Indian Fig', value: 'indian_fig' },
{ text: 'Jackfruit', value: 'jackfruit' },
{ text: 'Kiwi', value: 'kiwi' },
{ text: 'One Hundred', value: '100' },
{ text: 'Two Hundred', value: 200 },
{ text: 'Lemon', value: 'lemon' },
{ text: 'Mango', value: 'mango' },
{ text: '300', value: '300' },
{ text: 'Nectarine', value: 'nectarine' },
{ text: 'Orange', value: 'orange' },
{ text: 'Papaya', value: 'papaya' },
{ text: '89 Quince', value: '50' },
{ text: 'Raspberry', value: 'raspberry' },
{ text: 'Strawberry', value: 'strawberry' },
{ text: 'Tangerine', value: 'tangerine' },
{ text: 'Uva', value: 'uva' },
{ text: 'Vanilla', value: 'vanilla' },
{ text: 'Watermelon', value: 'watermelon' },
{ text: 'Xigua', value: 'xigua' },
{ text: 'Yunnan Hackberry', value: 'yunnan_hackberry' },
{ text: 'Zucchini', value: 'zucchini' },
{ text: 'Apricot', value: 'apricot' },
{ text: 'Blueberry', value: 'blueberry' },
{ text: 'Cantaloupe', value: 'cantaloupe' },
{ text: 'Dragonfruit', value: 'dragonfruit' },
{ text: 'Pineapple', value: 'pineapple' },
]);
</script>
You can also pre-select items using an array of objects if your options uses objects as values. The component will match by value or by object reference as needed.
Note:
- If you want to start with no selection, use an empty array:
ref([])
.- If you want to pre-select all items, use the full array of values from your options.
- The component will now always treat the model as an array for multi-select, so toggling and pre-selection will work as expected.
Placements
Placement refers to where the select popper will be positioned relative to its trigger element (e.g., button, input field). Pass the placement
props to modify the placement of the select popper.
The available placement options are: auto
, auto-start
, auto-end
, top
, top-start
, top-end
, right
, right-start
, right-end
, bottom
, bottom-start
, bottom-end
, left
, left-start
, and left-end
.
The default placement is bottom
.
Clearable
The clearable feature allows users to easily remove the selected value from the select input. This is particularly useful for forms where users may want to reset their selection without having to open the select.
V-Model: []
Width and Popper Width
You can modify the width of the select component in two ways: by adjusting the width of the select wrapper or by changing the width of the select popper.
Width
- Is the overall width wrapper of both parent element and popper element.
Popper Width
- Width of only popper element
<template>
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Multi-Select Label"
placeholder="Select an option"
:options="options"
width="50%"
popper-width="200px"
/>
</template>
Popper Strategy
The Popper strategy is primarily used when working with elements like modal. It helps control the positioning behavior of popper. The strategy ensures that the popper element is dynamically positioned based on the viewport, the reference element, or other factors such as scrolling or resizing.
By default, the Popper strategy is set to absolute
, which positions the popper element relative to the nearest positioned ancestor (usually the body element). However, you can change the strategy
to fixed
, which positions the popper element relative to the viewport, ensuring that it remains in place even when the page is scrolled.
Pass the prop popper-strategy
to change the behavior position of the popper.
Important to note:
Do not forget to pass prop wrapperPosition
to overwrite relative
position into initial
.
<template>
<spr-button tone="success" @click="modalModel = true">Open Modal</spr-button>
<spr-modal v-model="modalModel" title="Select with Modal">
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Multi-Select Label"
placeholder="Select an option"
:options="options"
wrapper-position="initial"
popper-strategy="fixed"
/>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</spr-modal>
</template>
Active, Disabled, Error States
For guidance on implementing error, active, and disabled states in the select component, you can refer to the documentation for the input text component, as the approach is similar. See the Input Form for detailed instructions.
Active State
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
active
/>
Disabled State
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
disabled
/>
Error State
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
error
/>
Helper Message
A helper message is a text label below the input field that provides additional information about instructions, formatting hints, validation feedback, etc.
To display the helper message, set the display-helper
prop to true
and add the helper-text
prop with the helper message text. You can also insert an icon with the helper-icon
prop. This uses the Iconify icon library.
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
helper-text="This is a helper message"
display-helper
/>
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
helper-text="This is an error message"
helper-icon="ph:warning-circle-fill"
display-helper
error
/>
Alternatively, you can use the helperMessage
slot to display a custom helper message.
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
display-helper
>
<template #helperMessage>This is a helper message</template>
</spr-select-multiple>
<spr-select-multiple
id="sample-select"
v-model="selectModel"
label="Select Label"
placeholder="Select an option"
:options="options"
display-helper
error
>
<template #helperMessage>
<icon icon="ph:warning-circle-fill" width="20px" height="20px" />
<span>This is an error message</span>
</template>
</spr-select-multiple>
Supported Value Types
The spr-select-multiple
component supports multiple value types for selection. For multi-select, always use an array for v-model
, regardless of whether your values are strings, numbers, or objects. The component normalizes single values to an array internally, but it is best practice to use an array from the start.
Multiple String Values
<template>
<spr-select-multiple
id="string-select"
v-model="stringValues"
label="Select Fruits"
placeholder="Select fruits"
:options="stringOptions"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const stringValues = ref(['apple', 'banana']); // Always use an array for multi-select
const stringOptions = ref([
{ text: 'Apple', value: 'apple' },
{ text: 'Banana', value: 'banana' },
{ text: 'Cherry', value: 'cherry' },
]);
</script>
Multiple Number Values
<template>
<spr-select-multiple
id="number-select"
v-model="numberValues"
label="Select Numbers"
placeholder="Select numbers"
:options="numberOptions"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const numberValues = ref([42, 100]); // Always use an array for multi-select
const numberOptions = ref([
{ text: '42', value: 42 },
{ text: '100', value: 100 },
{ text: '200', value: 200 },
]);
</script>
Multiple Object Values
<template>
<spr-select-multiple
id="object-select"
v-model="selectedUsers"
label="Select Users"
placeholder="Select users"
:options="userList"
text-field="name"
value-field="id"
/>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const selectedUsers = ref([
{ id: 1, name: 'John', role: 'Developer' },
{ id: 2, name: 'Jane', role: 'Designer' },
]); // Always use an array for multi-select
const userList = ref([
{ id: 1, name: 'John', role: 'Developer' },
{ id: 2, name: 'Jane', role: 'Designer' },
{ id: 3, name: 'Bob', role: 'Manager' },
]);
</script>
Note:
- If you want to start with no selection, use an empty array:
ref([])
.- If you want to pre-select all items, use the full array of values from your options.
- The component will always treat the model as an array for multi-select, so toggling and pre-selection will work as expected.
API Reference
Name | Description | Type | Default |
---|---|---|---|
id | Required to bind popper within the select | String | - |
v-model | Value binding for the select. Accepts an array of strings, numbers, or objects. Always use an array for multi-select. | Array | [] |
options | List of options. Can be an array of strings, numbers, or objects with text and value fields. | Array | [] |
group-items-by | Group items by a specific field. Supported: 'A-Z', 'Z-A'. | String | - |
text-field | Field name to use for display text when using object arrays. | String | 'text' |
value-field | Field name to use for value when using object arrays. | String | 'value' |
placeholder | Placeholder text for the input. | String | - |
label | Label for the select input. | String | '' |
placement | Popper placement. See available options in the documentation. | String | 'bottom' |
popper-strategy | Popper positioning strategy. 'absolute' or 'fixed'. | String | 'absolute' |
popper-width | Width of the popper element. | String | '100%' |
width | Width of the select wrapper. | String | '100%' |
wrapper-position | CSS position of the wrapper. Use 'initial' for modal usage. | String | 'relative' |
display-text | Display text for the input (useful for async/infinite scroll). | String | - |
display-helper | Show helper text below the input. | Boolean | false |
helper-icon | Icon to display with the helper text. | String | null |
helper-text | Helper text to display below the input. | String | '' |
disabled | Disable the select input and popper. | Boolean | false |
clearable | Show a clear button to remove all selections. | Boolean | false |
Events
Event | Payload | Description |
---|---|---|
update:modelValue | array | Emitted when the selection changes |
Notes
- Always use an array for
v-model
in multi-select mode. - Supports string, number, and object values. The component normalizes single values to an array internally.
- For object values, use
text-field
andvalue-field
to specify which fields to use. - Use
clearable
to allow users to clear all selections. - Use
helper-text
andhelper-icon
to display additional information below the input. - Use
placement
andpopper-strategy
to control the select position and behavior.