Skip to content

Select

🌏 Translated with the assistance of DeepSeek and ChatGPT

A common selector that presents and selects content via a drop-down menu.

Basic Usage

Pass modelValue to enter controlled mode.
Omit it or pass undefined for uncontrolled mode, in which you can supply a defaultValue prop as the initial value.

Vue
Vue
<template>
	<px-space direction="vertical">
		<px-select v-model="value" :options="options" placeholder="Please Select"></px-select>
		<px-select :defaultValue="'vue'" :options="options" placeholder="Please Select"></px-select>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref('vue')
const options = [
	{ label: 'Vue', value: 'vue' },
	{ label: 'React', value: 'react' },
	{ label: 'Angular', value: 'angular' }
]
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Disabled Options

Inside options, set an option's disabled field to true to disable that option.

Vue
Vanilla
<template>
	<px-space direction="vertical">
		<px-select v-model="value" :options="options" placeholder="Please Select"></px-select>
		<px-select
			:defaultValue="'vanilla'"
			:options="options"
			placeholder="Please Select"
		></px-select>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref('vue')
const options = [
	{ label: 'Vanilla', value: 'vanilla', disabled: true },
	{ label: 'Vue', value: 'vue' },
	{ label: 'React', value: 'react' },
	{ label: 'Angular', value: 'angular' }
]
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Groups

The options array also supports option groups.

Vue
<template>
	<px-space>
		<px-select v-model="value" :options="options" placeholder="Please Select"></px-select>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref('vue')
const options = [
	{
		label: 'JS Framework',
		key: 'JS Framework',
		type: 'group',
		children: [
			{ label: 'Vanilla', value: 'vanilla', disabled: true },
			{ label: 'Vue', value: 'vue' },
			{ label: 'React', value: 'react' },
			{ label: 'Angular', value: 'angular' }
		]
	},
	{
		label: 'CSS Preprocessor',
		key: 'CSS Preprocessor',
		type: 'group',
		children: [
			{ label: 'Less', value: 'less' },
			{ label: 'Sass', value: 'sass' }
		]
	}
]
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Remote Loading

Set the loading prop and listen to the focus event to reflect UI changes while data is being fetched or searched.

Please Select
<template>
	<px-select
		v-model="value"
		:options="options"
		placeholder="Please Select"
		@focus="focusHandler"
		:loading="loading"
	></px-select>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref(null)

const options = ref<string[]>([])
const loading = ref(false)

const list = ['Ready to work', 'Work, work', 'Work completed']

const focusHandler = () => {
	options.value = []
	loading.value = true
	setTimeout(() => {
		options.value = list
		loading.value = false
	}, 5000)
}
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Multiple Selection

Add the multiple prop to enable multi-select mode.

Please Select
<template>
	<px-select
		v-model="value"
		:options="options"
		placeholder="Please Select"
		multiple
	></px-select>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref<string[]>([])

const options = ref<string[]>(['Ready for action', 'Locked and loaded', 'I await your command'])
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Collapsed Tags

In multi-select mode, set collapseTags to true (default false) to collapse selected tags.
maxDisplayTags controls how many tags remain visible, and collapseTagsPopover (default true) decides whether collapsed tags are shown in a popover.

Please select
Please select
<template>
	<px-space direction="vertical">
		<px-select
			placeholder="Please select"
			v-model="value"
			collapse-tags
			:max-display-tags="3"
			multiple
			:options="options"
		></px-select>
		<px-select
			placeholder="Please select"
			v-model="value"
			collapse-tags
			:max-display-tags="3"
			:collapse-tags-popover="false"
			multiple
			:options="options"
		></px-select>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const value = ref<string[]>([])
const options = [
	{ label: 'Vue', value: 'vue' },
	{ label: 'React', value: 'react' },
	{ label: 'Angular', value: 'angular' },
	{ label: 'Svelte', value: 'svelte' },
	{ label: 'Preact', value: 'Preact' },
	{ label: 'Next', value: 'next' },
	{ label: 'Nuxt', value: 'nuxt' },
	{ label: 'Astro', value: 'astro' }
]
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Searchable Options

Set filterable to make the drop-down searchable.
For the search input itself, pass inputValue for controlled mode; otherwise supply defaultInputValue for uncontrolled mode.

inputValue:
Please select
Please select
<template>
	<px-space direction="vertical">
		<div>inputValue: {{ inputValue }}</div>
		<px-select
			placeholder="Please select"
			v-model="value"
			:options="options"
			v-model:input-value="inputValue"
			filterable
		></px-select>
		<px-select
			placeholder="Please select"
			v-model="multiValue"
			default-input-value="Nest"
			multiple
			:options="options"
			filterable
		></px-select>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const multiValue = ref<string[]>([])
const value = ref<string | null>(null)
const inputValue = ref<string>()
const options = [
	{ label: 'Express', value: 'express' },
	{ label: 'Koa', value: 'koa' },
	{ label: 'Nest', value: 'nest' },
	{ label: 'Fastify', value: 'fastify' }
]
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

Adding Options

Set creatable to allow new options to be added (type string). filterable must also be enabled.

Please select
Please select
<template>
	<px-space direction="vertical">
		<px-select
			placeholder="Please select"
			v-model="value"
			:options="options"
			filterable
			creatable
		></px-select>
		<px-select
			placeholder="Please select"
			v-model="multiValue"
			multiple
			:options="options"
			filterable
			creatable
		></px-select>
	</px-space>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const multiValue = ref<string[]>([])
const value = ref<string | null>(null)
const options = [
	{ label: 'Morning Mood', value: 'music1' },
	{ label: 'The Death of Åse', value: 'music2' },
	{ label: "Anitra's Dance", value: 'music3' },
	{ label: 'In the Hall of the Mountain King', value: 'music4' }
]
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

More Options

The Select component also inherits parts of Input, InputTag, and AutoComplete functionalities.

Disabled, Readonly, Loading & Clearable

Please input
Please input
Please input
Please input

Shape

Please input
Please input

Size

Please input
Please input
Please input

Slot

prefix
Please input
suffix
Please input
Please input

Composite

Please input

Status

Please input
Please input
Please input
Please input

Expose

Please input

Tag Render

Please input

Option Render

Please input
<template>
	<px-space direction="vertical">
		<h4>Disabled, Readonly, Loading & Clearable</h4>
		<px-space>
			<px-select placeholder="Please input" disabled :options="options"></px-select>
			<px-select placeholder="Please input" readonly :options="options"></px-select>
			<px-select placeholder="Please input" loading :options="options"></px-select>
			<px-select placeholder="Please input" clearable :options="options"></px-select>
		</px-space>
		<h4>Shape</h4>
		<px-space>
			<px-select placeholder="Please input" shape="round" :options="options"></px-select>
			<px-select placeholder="Please input" :options="options"></px-select>
		</px-space>
		<h4>Size</h4>
		<px-space>
			<px-select placeholder="Please input" size="small" :options="options"></px-select>
			<px-select placeholder="Please input" :options="options"></px-select>
			<px-select placeholder="Please input" size="large" :options="options"></px-select>
		</px-space>
		<h4>Slot</h4>
		<px-space>
			<px-select placeholder="Please input" :options="options">
				<template #prefix>prefix</template>
				<template #suffix>suffix</template>
			</px-select>
			<px-select placeholder="Please input" :options="options">
				<template #prepend>
					<IconBolt></IconBolt>
				</template>
			</px-select>
			<px-select placeholder="Please input" :options="options">
				<template #append>
					<IconBolt></IconBolt>
				</template>
			</px-select>
		</px-space>
		<h4>Composite</h4>
		<px-space>
			<px-input-group>
				<px-input-group-label>
					<IconBolt></IconBolt>
				</px-input-group-label>
				<px-select placeholder="Please input" :options="options"> </px-select>
				<px-button>Confirm</px-button>
			</px-input-group>
		</px-space>
		<h4>Status</h4>
		<px-space>
			<px-select placeholder="Please input" :options="options"> </px-select>
			<px-select placeholder="Please input" :options="options" status="success"> </px-select>
			<px-select placeholder="Please input" :options="options" status="warning"> </px-select>
			<px-select placeholder="Please input" :options="options" status="error"> </px-select>
		</px-space>
		<h4>Expose</h4>
		<px-space direction="vertical">
			<px-space>
				<px-button theme="info" @click="focusHandler">Focus & Blur after 5s</px-button>
				<px-button theme="warning" @click="clearHandler">Clear</px-button>
			</px-space>
			<px-select placeholder="Please input" :options="options" ref="selectRef"></px-select>
		</px-space>
		<h4>Tag Render</h4>
		<px-select placeholder="Please input" multiple :options="options">
			<template #tag="{ label }">
				<div style="display: flex; align-items: center">
					<IconBolt style="margin-right: 4px"></IconBolt> {{ label }}
				</div>
			</template>
		</px-select>
		<h4>Option Render</h4>
		<px-select placeholder="Please input" v-model="input" :options="options">
			<template #group-label="{ option }">
				{{ option.label }}
				<div
					style="margin-left: 12px; color: red; font-size: 16px"
					v-if="option.label === 'citrus fruits'"
				>
					HOT!
				</div>
			</template>
			<template #option="{ option }">
				{{ option.label }}
				<px-tag style="margin-left: 12px" v-if="option.value === 'orange'">NEW!</px-tag>
			</template>
		</px-select>
	</px-space>
</template>

<script setup lang="ts">
import { IconBolt } from '@pixelium/web-vue/icon-hn/es'
import { ref } from 'vue'
import { Select } from '@pixelium/web-vue'

// If on-demand import
// import { Select } from '@pixelium/web-vue/es'

const selectRef = ref<InstanceType<typeof Select>>(null)

const focusHandler = () => {
	setTimeout(() => {
		selectRef.value?.focus()
		setTimeout(() => {
			selectRef.value?.blur()
		}, 5000)
	}, 50)
}
const clearHandler = () => {
	selectRef.value?.clear()
}

const options = ref([
	{
		type: 'group',
		label: 'citrus fruits',
		children: [
			{ label: 'orange', value: 'orange' },
			{ label: 'lemon', value: 'lemon' },
			{ label: 'lime', value: 'lime' },
			{ label: 'grapefruit', value: 'grapefruit' },
			{ label: 'tangerine', value: 'tangerine' }
		]
	},
	{
		type: 'group',
		label: 'tropical fruits',
		children: [
			{ label: 'mango', value: 'mango' },
			{ label: 'pineapple', value: 'pineapple' },
			{ label: 'papaya', value: 'papaya' },
			{ label: 'dragon fruit', value: 'dragon fruit' },
			{ label: 'durian', value: 'durian' },
			{ label: 'lychee', value: 'lychee' },
			{ label: 'longan', value: 'longan' }
		]
	}
])
</script>

<style lang="css" scoped>
.px-select {
	width: 320px;
}
</style>

API

SelectProps

AttributeTypeOptionalDefaultDescriptionVersion
modelValueanyTrueCurrent value (controlled), supports v-model.0.0.2
defaultValueanyTrueDefault value when uncontrolled.0.0.2
optionsstringTrueArray of options.0.0.2
placeholderstringTruePlaceholder text.0.0.2
disabledbooleanTruefalseDisable the whole selector.0.0.2
readonlybooleanTruefalseMake the selector read-only.0.0.2
clearablebooleanTruefalseShow a clear button.0.0.2
multiplebooleanTruefalse0.0.2
loadingbooleanTruefalseShow loading state.0.0.2
inputValuestring | nullTrueSearch input text (controlled), supports v-model.0.0.2
defaultInputValuestring | nullTrueDefault search input text when uncontrolled.0.0.2
filterablebooleanTruefalseEnable search within options.0.0.2
shouldShowPopover(value: string, optionsFiltered: (string | SelectOption | SelectGroupOption)[]) => booleanTrueFunction to determine whether to show the popover.0.0.2
filter(keyword: string, options: (string | SelectOption | SelectGroupOption)[]) => (string | SelectOption | SelectGroupOption)[]TrueFunction to filter options.0.0.2
creatablebooleanTruefalseAllow creating new options; requires filterable.0.0.2
collapseTagsbooleanTruefalseCollapse selected tags in multi-select mode.0.0.2
collapseTagsnumberTrueCollapse selected tags in multi-select mode.0.0.2
collapseTagsPopoverbooleanTruetrueShow collapsed tags in a popover when collapseTags is on.0.0.2
tagTheme'primary' | 'sakura' | 'success' | 'warning' | 'danger' | 'info'True'info'theme prop for tags (color theme).0.0.2
tagVariant'primary' | 'plain' | 'outline'True'plain'variant prop for tags (style variant).0.0.2
tagColorstringTruecolor prop for tags (custom color).0.0.2
size'medium' | 'large' | 'small'True'medium'Size of the selector.0.0.2
shape'default' | 'round'True'default'Shape of the selector.0.0.2
borderRadiusNumberOrPercentage | NumberOrPercentage[]TrueBorder-radius value; higher priority than shape. Single value or 1-item array → all corners; 2-item array → [top-left & bottom-right, top-right & bottom-left]; 3-item array → [top-left, top-right & bottom-left, bottom-right]; 4-item array → clockwise order for all four corners.0.0.2
status'success' | 'warning' | 'error' | 'normal'True'normal'Form validation status.0.0.2

SelectEvents

EventParameterDescriptionVersion
inputvalue: string, e: EventFired on search input.0.0.2
update:modelValuevalue: anyFired when modelValue changes.0.0.2
update:inputValuevalue: stringFired when inputValue changes.0.0.2
changevalue: anyFired when selection changes.0.0.2
changevalue: string, e: Event | undefinedFired when selection changes.0.0.2
clearvalue: anyFired when the clear button is clicked.0.0.2
blurFired when the selector loses focus.0.0.2
focusFired when the selector gains focus.0.0.2
selectvalue: any, e: MouseEventFired when an option is selected.0.0.2
tagClosevalue: any, e: MouseEventFired when a tag is closed.0.0.2

SelectSlots

SlotParameterDescriptionVersion
prefixPrefix content.0.0.2
suffixSuffix content.0.0.2
optionoption: string | SelectOptionCustom option content.0.0.2
group-labeloption: SelectGroupOptionCustom group-label content.0.0.2
tagvalue: any, label: string, index: numberCustom tag content.0.0.2

SelectExpose

AttributeTypeOptionalDefaultDescriptionVersion
focus() => voidFalseFocus the selector.0.0.2
blur() => voidFalseBlur the selector.0.0.2
clear() => voidFalseClear the current input.0.0.2