@primevue/mcp 4.5.5 → 5.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/LICENSE.md +45 -21
  2. package/README.md +48 -250
  3. package/data/components.json +47269 -0
  4. package/data/llms/components/accordion.md +629 -0
  5. package/data/llms/components/animateonscroll.md +165 -0
  6. package/data/llms/components/autocomplete.md +995 -0
  7. package/data/llms/components/avatar.md +264 -0
  8. package/data/llms/components/badge.md +200 -0
  9. package/data/llms/components/blockui.md +99 -0
  10. package/data/llms/components/breadcrumb.md +269 -0
  11. package/data/llms/components/button.md +902 -0
  12. package/data/llms/components/card.md +209 -0
  13. package/data/llms/components/carousel.md +506 -0
  14. package/data/llms/components/cascadeselect.md +1207 -0
  15. package/data/llms/components/chart.md +1022 -0
  16. package/data/llms/components/checkbox.md +401 -0
  17. package/data/llms/components/chip.md +206 -0
  18. package/data/llms/components/colorpicker.md +213 -0
  19. package/data/llms/components/commandmenu.md +660 -0
  20. package/data/llms/components/compare.md +407 -0
  21. package/data/llms/components/confirmdialog.md +343 -0
  22. package/data/llms/components/confirmpopup.md +252 -0
  23. package/data/llms/components/contextmenu.md +522 -0
  24. package/data/llms/components/datatable.md +5266 -0
  25. package/data/llms/components/dataview.md +569 -0
  26. package/data/llms/components/datepicker.md +964 -0
  27. package/data/llms/components/deferredcontent.md +96 -0
  28. package/data/llms/components/dialog.md +702 -0
  29. package/data/llms/components/divider.md +152 -0
  30. package/data/llms/components/dock.md +488 -0
  31. package/data/llms/components/drawer.md +469 -0
  32. package/data/llms/components/dynamicdialog.md +214 -0
  33. package/data/llms/components/editor.md +205 -0
  34. package/data/llms/components/fieldset.md +253 -0
  35. package/data/llms/components/fileupload.md +459 -0
  36. package/data/llms/components/floatlabel.md +144 -0
  37. package/data/llms/components/fluid.md +104 -0
  38. package/data/llms/components/focustrap.md +59 -0
  39. package/data/llms/components/forms.md +344 -0
  40. package/data/llms/components/galleria.md +1119 -0
  41. package/data/llms/components/gallery.md +1003 -0
  42. package/data/llms/components/iconfield.md +283 -0
  43. package/data/llms/components/iftalabel.md +96 -0
  44. package/data/llms/components/image.md +179 -0
  45. package/data/llms/components/imagecompare.md +108 -0
  46. package/data/llms/components/inplace.md +183 -0
  47. package/data/llms/components/inputcolor.md +869 -0
  48. package/data/llms/components/inputgroup.md +419 -0
  49. package/data/llms/components/inputmask.md +345 -0
  50. package/data/llms/components/inputnumber.md +551 -0
  51. package/data/llms/components/inputotp.md +345 -0
  52. package/data/llms/components/inputpassword.md +738 -0
  53. package/data/llms/components/inputtags.md +432 -0
  54. package/data/llms/components/inputtext.md +569 -0
  55. package/data/llms/components/installation.md +1 -0
  56. package/data/llms/components/keyfilter.md +116 -0
  57. package/data/llms/components/knob.md +318 -0
  58. package/data/llms/components/label.md +151 -0
  59. package/data/llms/components/laravel.md +53 -0
  60. package/data/llms/components/listbox.md +636 -0
  61. package/data/llms/components/mask.md +203 -0
  62. package/data/llms/components/mcp.md +39 -0
  63. package/data/llms/components/megamenu.md +563 -0
  64. package/data/llms/components/menu.md +651 -0
  65. package/data/llms/components/menubar.md +446 -0
  66. package/data/llms/components/message.md +497 -0
  67. package/data/llms/components/metergroup.md +281 -0
  68. package/data/llms/components/multiselect.md +752 -0
  69. package/data/llms/components/orderlist.md +224 -0
  70. package/data/llms/components/organizationchart.md +418 -0
  71. package/data/llms/components/paginator.md +221 -0
  72. package/data/llms/components/panel.md +321 -0
  73. package/data/llms/components/panelmenu.md +703 -0
  74. package/data/llms/components/password.md +657 -0
  75. package/data/llms/components/picklist.md +286 -0
  76. package/data/llms/components/popover.md +145 -0
  77. package/data/llms/components/progressbar.md +242 -0
  78. package/data/llms/components/progressspinner.md +104 -0
  79. package/data/llms/components/radiobutton.md +427 -0
  80. package/data/llms/components/rating.md +312 -0
  81. package/data/llms/components/ripple.md +91 -0
  82. package/data/llms/components/scrollarea.md +700 -0
  83. package/data/llms/components/scrollpanel.md +131 -0
  84. package/data/llms/components/scrolltop.md +87 -0
  85. package/data/llms/components/select.md +1251 -0
  86. package/data/llms/components/selectbutton.md +268 -0
  87. package/data/llms/components/sidebar.md +2232 -0
  88. package/data/llms/components/skeleton.md +302 -0
  89. package/data/llms/components/slider.md +416 -0
  90. package/data/llms/components/speeddial.md +402 -0
  91. package/data/llms/components/splitbutton.md +840 -0
  92. package/data/llms/components/splitter.md +447 -0
  93. package/data/llms/components/stepper.md +551 -0
  94. package/data/llms/components/styleclass.md +226 -0
  95. package/data/llms/components/tabs.md +609 -0
  96. package/data/llms/components/tag.md +178 -0
  97. package/data/llms/components/terminal.md +123 -0
  98. package/data/llms/components/textarea.md +519 -0
  99. package/data/llms/components/tieredmenu.md +578 -0
  100. package/data/llms/components/timeline.md +494 -0
  101. package/data/llms/components/toast.md +472 -0
  102. package/data/llms/components/togglebutton.md +276 -0
  103. package/data/llms/components/toggleswitch.md +271 -0
  104. package/data/llms/components/toolbar.md +140 -0
  105. package/data/llms/components/tooltip.md +160 -0
  106. package/data/llms/components/tree.md +1076 -0
  107. package/data/llms/components/treeselect.md +660 -0
  108. package/data/llms/components/treetable.md +2493 -0
  109. package/data/llms/components/virtualscroller.md +265 -0
  110. package/data/llms/guides/autoimport.md +28 -0
  111. package/data/llms/guides/cdn.md +72 -0
  112. package/data/llms/guides/configuration.md +158 -0
  113. package/data/llms/guides/customicons.md +67 -0
  114. package/data/llms/guides/guides/accessibility.md +27 -0
  115. package/data/llms/guides/guides/animations.md +119 -0
  116. package/data/llms/guides/guides/rtl.md +7 -0
  117. package/data/llms/guides/icons.md +136 -0
  118. package/data/llms/guides/installation.md +3 -0
  119. package/data/llms/guides/laravel.md +66 -0
  120. package/data/llms/guides/llms.md +15 -0
  121. package/data/llms/guides/mcp.md +104 -0
  122. package/data/llms/guides/migration/v4.md +15 -0
  123. package/data/llms/guides/migration/v5.md +15 -0
  124. package/data/llms/guides/nuxt.md +141 -0
  125. package/data/llms/guides/passthrough.md +137 -0
  126. package/data/llms/guides/primeclt.md +43 -0
  127. package/data/llms/guides/tailwind.md +151 -0
  128. package/data/llms/guides/theming/styled.md +497 -0
  129. package/data/llms/guides/theming/unstyled.md +57 -0
  130. package/data/llms/guides/uikit.md +3 -0
  131. package/data/llms/guides/vite.md +90 -0
  132. package/data/llms/llms-full.txt +54465 -0
  133. package/data/llms/llms.txt +132 -0
  134. package/data/llms/pages/accessibility.md +27 -0
  135. package/data/llms/pages/animations.md +119 -0
  136. package/data/llms/pages/autoimport.md +28 -0
  137. package/data/llms/pages/cdn.md +72 -0
  138. package/data/llms/pages/configuration.md +158 -0
  139. package/data/llms/pages/contribution.md +31 -0
  140. package/data/llms/pages/customicons.md +67 -0
  141. package/data/llms/pages/designer.md +79 -0
  142. package/data/llms/pages/dynamicimports.md +7 -0
  143. package/data/llms/pages/forms.md +63 -0
  144. package/data/llms/pages/guides/accessibility.md +27 -0
  145. package/data/llms/pages/guides/animations.md +119 -0
  146. package/data/llms/pages/guides/rtl.md +7 -0
  147. package/data/llms/pages/icons.md +136 -0
  148. package/data/llms/pages/installation.md +3 -0
  149. package/data/llms/pages/introduction.md +23 -0
  150. package/data/llms/pages/laravel.md +66 -0
  151. package/data/llms/pages/llms.md +15 -0
  152. package/data/llms/pages/mcp.md +104 -0
  153. package/data/llms/pages/migration/v4.md +15 -0
  154. package/data/llms/pages/migration/v5.md +15 -0
  155. package/data/llms/pages/nuxt.md +141 -0
  156. package/data/llms/pages/passthrough.md +137 -0
  157. package/data/llms/pages/primeclt.md +43 -0
  158. package/data/llms/pages/rtl.md +7 -0
  159. package/data/llms/pages/setup.md +3 -0
  160. package/data/llms/pages/styled.md +497 -0
  161. package/data/llms/pages/tailwind.md +151 -0
  162. package/data/llms/pages/theming/styled.md +497 -0
  163. package/data/llms/pages/theming/unstyled.md +57 -0
  164. package/data/llms/pages/uikit.md +3 -0
  165. package/data/llms/pages/unstyled.md +57 -0
  166. package/data/llms/pages/v4.md +15 -0
  167. package/data/llms/pages/v5.md +15 -0
  168. package/data/llms/pages/vite.md +90 -0
  169. package/data/manifest.json +11117 -0
  170. package/data/mcp-data.json +55940 -0
  171. package/dist/index.d.ts +17 -1
  172. package/dist/index.js +66066 -72541
  173. package/package.json +10 -12
@@ -0,0 +1,1251 @@
1
+ # Select
2
+
3
+ Select is used to choose an item from a collection of options.
4
+
5
+ ## Basic
6
+
7
+ Select is used as a controlled component with v-model property along with an options collection. Label and value of an option are defined with the optionLabel and optionValue properties respectively. Note that, when options are simple primitive values such as a string array, no optionLabel and optionValue would be necessary.
8
+
9
+ ```vue
10
+ <template>
11
+ <div class="flex justify-center">
12
+ <Select v-model="selectedLanguage" :options="languages" optionLabel="label" optionValue="value" placeholder="Select a language" class="w-full md:w-56" />
13
+ </div>
14
+ </template>
15
+
16
+ <script setup>
17
+ import { ref } from 'vue';
18
+
19
+ const selectedLanguage = ref(null);
20
+ const languages = ref([
21
+ { label: 'English', value: 'en' },
22
+ { label: 'Deutsch', value: 'de' },
23
+ { label: 'Español', value: 'es' },
24
+ { label: 'Français', value: 'fr' },
25
+ { label: 'Italiano', value: 'it' },
26
+ { label: 'Türkçe', value: 'tr' },
27
+ { label: '日本語', value: 'ja' },
28
+ { label: '中文', value: 'zh' }
29
+ ]);
30
+ <\/script>
31
+ ```
32
+
33
+ ## Multiple
34
+
35
+ When multiple is enabled, multiple items can be selected. Use checkmark to display a check indicator and a custom #value slot for the label.
36
+
37
+ ```vue
38
+ <template>
39
+ <div class="flex justify-center">
40
+ <Select v-model="selected" :options="toppings" multiple checkmark optionLabel="label" optionValue="value" showClear placeholder="Select Toppings" class="w-full md:w-56">
41
+ <template #value="slotProps">
42
+ <span>{{ getLabel() !== '' ? getLabel() : slotProps.placeholder }}</span>
43
+ </template>
44
+ </Select>
45
+ </div>
46
+ </template>
47
+
48
+ <script setup>
49
+ import { ref } from 'vue';
50
+
51
+ const selected = ref([]);
52
+ const toppings = ref([
53
+ { label: 'Pepperoni', value: 'pepperoni' },
54
+ { label: 'Mushrooms', value: 'mushrooms' },
55
+ { label: 'Onions', value: 'onions' },
56
+ { label: 'Black Olives', value: 'olives' },
57
+ { label: 'Green Peppers', value: 'peppers' },
58
+ { label: 'Mozzarella', value: 'mozzarella' },
59
+ { label: 'Basil', value: 'basil' },
60
+ { label: 'Tomatoes', value: 'tomatoes' }
61
+ ]);
62
+
63
+ const getLabel = () => {
64
+ if (selected.value.length === 0) return '';
65
+ const first = toppings.value.find((t) => t.value === selected.value[0])?.label ?? selected.value[0];
66
+ return selected.value.length > 1 ? \`\${first} (+\${selected.value.length - 1} more)\` : first;
67
+ };
68
+ <\/script>
69
+ ```
70
+
71
+ ## Checkmark
72
+
73
+ An alternative way to highlight the selected option is displaying a checkmark instead.
74
+
75
+ ```vue
76
+ <template>
77
+ <div class="flex justify-center">
78
+ <Select v-model="selectedTheme" :options="themes" checkmark optionLabel="label" placeholder="Select a Theme" scrollHeight="auto" class="w-full md:w-64" :pt="{ option: { class: 'flex-row-reverse justify-between' } }">
79
+ <template #value="slotProps">
80
+ <div v-if="slotProps.value" class="flex items-center gap-2">
81
+ <span>{{ slotProps.value.icon }}</span>
82
+ <span>{{ slotProps.value.label }}</span>
83
+ </div>
84
+ <span v-else>{{ slotProps.placeholder }}</span>
85
+ </template>
86
+ <template #option="slotProps">
87
+ <div class="flex items-center gap-3 py-1">
88
+ <span class="text-xl">{{ slotProps.option.icon }}</span>
89
+ <div class="flex flex-col">
90
+ <span class="font-medium">{{ slotProps.option.label }}</span>
91
+ <span class="text-xs text-surface-500">{{ slotProps.option.description }}</span>
92
+ </div>
93
+ </div>
94
+ </template>
95
+ </Select>
96
+ </div>
97
+ </template>
98
+
99
+ <script setup>
100
+ import { ref } from 'vue';
101
+
102
+ const selectedTheme = ref(null);
103
+ const themes = ref([
104
+ { label: 'Light', value: 'light', icon: '☀️', description: 'Clean and bright interface' },
105
+ { label: 'Dark', value: 'dark', icon: '🌙', description: 'Easy on the eyes' },
106
+ { label: 'System', value: 'system', icon: '💻', description: 'Match your device settings' },
107
+ { label: 'High Contrast', value: 'high-contrast', icon: '◐', description: 'Maximum readability' }
108
+ ]);
109
+ <\/script>
110
+ ```
111
+
112
+ ## Checkbox Selection
113
+
114
+ Multiple selection with checkboxes using multiple and custom #option and #header slots.
115
+
116
+ ```vue
117
+ <template>
118
+ <div class="flex justify-center">
119
+ <Select v-model="selectedCities" :options="cities" multiple optionLabel="name" optionValue="code" showClear placeholder="Select Cities" class="w-full md:w-56">
120
+ <template #header>
121
+ <div class="p-2">
122
+ <Checkbox :modelValue="allSelected" binary :indeterminate="indeterminate" @update:modelValue="onToggleAll" label="Select All" class="ml-1.5" />
123
+ </div>
124
+ </template>
125
+ <template #value="slotProps">
126
+ <span>{{ getLabel() !== '' ? getLabel() : slotProps.placeholder }}</span>
127
+ </template>
128
+ <template #option="slotProps">
129
+ <div class="flex items-center gap-2">
130
+ <Checkbox :modelValue="isItemSelected(slotProps.option)" binary :tabindex="-1" readonly />
131
+ <span>{{ slotProps.option.name }}</span>
132
+ </div>
133
+ </template>
134
+ </Select>
135
+ </div>
136
+ </template>
137
+
138
+ <script setup>
139
+ import { ref, computed } from 'vue';
140
+
141
+ const selectedCities = ref([]);
142
+ const cities = ref([
143
+ { name: 'New York', code: 'NY' },
144
+ { name: 'Rome', code: 'RM' },
145
+ { name: 'London', code: 'LDN' },
146
+ { name: 'Istanbul', code: 'IST' },
147
+ { name: 'Paris', code: 'PRS' }
148
+ ]);
149
+
150
+ const allSelected = computed(() => selectedCities.value.length === cities.value.length);
151
+ const indeterminate = computed(() => selectedCities.value.length > 0 && !allSelected.value);
152
+
153
+ const getLabel = () => {
154
+ if (selectedCities.value.length === 0) return '';
155
+ const first = cities.value.find((c) => c.code === selectedCities.value[0])?.name ?? selectedCities.value[0];
156
+ return selectedCities.value.length > 1 ? \`\${first} (+\${selectedCities.value.length - 1} more)\` : first;
157
+ };
158
+
159
+ const isItemSelected = (city) => selectedCities.value.includes(city.code);
160
+
161
+ const onToggleAll = (checked) => {
162
+ selectedCities.value = checked ? cities.value.map((c) => c.code) : [];
163
+ };
164
+ <\/script>
165
+ ```
166
+
167
+ ## Chips
168
+
169
+ Selected items displayed as chips using a custom #value slot in multiple mode.
170
+
171
+ ```vue
172
+ <template>
173
+ <div class="flex justify-center">
174
+ <Select v-model="selected" :options="members" multiple optionLabel="name" optionValue="code" showClear placeholder="Select Members" class="w-full">
175
+ <template #option="slotProps">
176
+ <div class="flex items-center gap-2">
177
+ <img :src="slotProps.option.avatar" :alt="slotProps.option.name" class="w-7 h-7 rounded-full" />
178
+ <span>{{ slotProps.option.name }}</span>
179
+ </div>
180
+ </template>
181
+ <template #value="{ value, placeholder }">
182
+ <div v-if="value && value.length > 0" class="flex flex-wrap gap-1">
183
+ <Chip
184
+ v-for="code of value"
185
+ :key="code"
186
+ :label="getFirstName(code)"
187
+ :image="getAvatar(code)"
188
+ removable
189
+ @remove="removeItem($event, code)"
190
+ :pt="{ root: { class: 'py-0!' }, label: { class: 'text-xs!' }, image: { class: 'w-5! h-5!' } }"
191
+ />
192
+ </div>
193
+ <span v-else>{{ placeholder }}</span>
194
+ </template>
195
+ </Select>
196
+ </div>
197
+ </template>
198
+
199
+ <script setup>
200
+ import { ref } from 'vue';
201
+
202
+ const selected = ref([]);
203
+ const members = ref([
204
+ { name: 'Amy Elsner', code: 'AE', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png' },
205
+ { name: 'Anna Fali', code: 'AF', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/annafali.png' },
206
+ { name: 'Asiya Javayant', code: 'AJ', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/asiyajavayant.png' },
207
+ { name: 'Bernardo Dominic', code: 'BD', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/bernardodominic.png' },
208
+ { name: 'Elwin Sharvill', code: 'ES', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/elwinsharvill.png' },
209
+ { name: 'Ioni Bowcher', code: 'IB', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/ionibowcher.png' },
210
+ { name: 'Ivan Magalhaes', code: 'IM', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/ivanmagalhaes.png' },
211
+ { name: 'Stephen Shaw', code: 'SS', avatar: 'https://primefaces.org/cdn/primevue/images/avatar/stephenshaw.png' }
212
+ ]);
213
+
214
+ const getFirstName = (code) => {
215
+ const member = members.value.find((m) => m.code === code);
216
+ return member ? member.name.split(' ')[0] : code;
217
+ };
218
+
219
+ const getAvatar = (code) => members.value.find((m) => m.code === code)?.avatar ?? '';
220
+
221
+ const removeItem = (event, code) => {
222
+ event.stopPropagation();
223
+ selected.value = selected.value.filter((c) => c !== code);
224
+ };
225
+ <\/script>
226
+ ```
227
+
228
+ ## Clear
229
+
230
+ When showClear is enabled, a clear icon is displayed to clear the value.
231
+
232
+ ```vue
233
+ <template>
234
+ <div class="flex justify-center">
235
+ <Select v-model="selectedCategory" :options="categories" optionLabel="label" placeholder="Category" class="w-full md:w-56" showClear>
236
+ <template #option="slotProps">
237
+ <div class="flex items-center justify-between w-full">
238
+ <span>{{ slotProps.option.label }}</span>
239
+ <Tag :value="'' + slotProps.option.count" severity="secondary" rounded />
240
+ </div>
241
+ </template>
242
+ </Select>
243
+ </div>
244
+ </template>
245
+
246
+ <script setup>
247
+ import { ref } from 'vue';
248
+
249
+ const selectedCategory = ref(null);
250
+ const categories = ref([
251
+ { label: 'Electronics', value: 'electronics', count: 1247 },
252
+ { label: 'Clothing', value: 'clothing', count: 856 },
253
+ { label: 'Garden', value: 'home', count: 634 },
254
+ { label: 'Sports', value: 'sports', count: 421 },
255
+ { label: 'Books', value: 'books', count: 2103 },
256
+ { label: 'Toys', value: 'toys', count: 312 }
257
+ ]);
258
+ <\/script>
259
+ ```
260
+
261
+ ## Filter
262
+
263
+ Select provides built-in filtering that is enabled by adding the filter property.
264
+
265
+ ```vue
266
+ <template>
267
+ <div class="flex justify-center">
268
+ <Select v-model="selectedCountry" :options="countries" optionLabel="name" filter filterBy="name" showClear placeholder="Select a Country" class="w-full md:w-56">
269
+ <template #value="slotProps">
270
+ <div v-if="slotProps.value" class="flex items-center gap-2">
271
+ <img src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${slotProps.value.code.toLowerCase()}\`" style="width: 18px" />
272
+ <div>{{ slotProps.value.name }}</div>
273
+ </div>
274
+ <span v-else>{{ slotProps.placeholder }}</span>
275
+ </template>
276
+ <template #option="slotProps">
277
+ <div class="flex items-center gap-2">
278
+ <img src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${slotProps.option.code.toLowerCase()}\`" style="width: 18px" />
279
+ <div>{{ slotProps.option.name }}</div>
280
+ </div>
281
+ </template>
282
+ </Select>
283
+ </div>
284
+ </template>
285
+
286
+ <script setup>
287
+ import { ref } from 'vue';
288
+
289
+ const selectedCountry = ref(null);
290
+ const countries = ref([
291
+ { name: 'Australia', code: 'AU' },
292
+ { name: 'Brazil', code: 'BR' },
293
+ { name: 'China', code: 'CN' },
294
+ { name: 'Egypt', code: 'EG' },
295
+ { name: 'France', code: 'FR' },
296
+ { name: 'Germany', code: 'DE' },
297
+ { name: 'India', code: 'IN' },
298
+ { name: 'Japan', code: 'JP' },
299
+ { name: 'Spain', code: 'ES' },
300
+ { name: 'United States', code: 'US' }
301
+ ]);
302
+ <\/script>
303
+ ```
304
+
305
+ ## Custom Option
306
+
307
+ Custom content can be placed inside options using the #option slot.
308
+
309
+ ```vue
310
+ <template>
311
+ <div class="flex justify-center">
312
+ <Select v-model="assignee" :options="teamMembers" optionLabel="name" placeholder="Select team member..." class="w-full md:w-56">
313
+ <template #value="slotProps">
314
+ <div v-if="slotProps.value" class="flex items-center gap-2">
315
+ <span :class="\`inline-block w-2 h-2 rounded-full \${slotProps.value.statusClass}\`"></span>
316
+ <span>{{ slotProps.value.name }}</span>
317
+ </div>
318
+ <span v-else>{{ slotProps.placeholder }}</span>
319
+ </template>
320
+ <template #option="slotProps">
321
+ <div class="flex items-center gap-3 py-1">
322
+ <div class="relative">
323
+ <Avatar :label="slotProps.option.avatar" shape="circle" class="w-8 h-8" />
324
+ <span :class="\`absolute -bottom-0.5 -right-0.5 w-3 h-3 rounded-full border-2 border-surface-0 dark:border-surface-900 \${slotProps.option.statusClass}\`"></span>
325
+ </div>
326
+ <div class="flex flex-col">
327
+ <span class="font-medium">{{ slotProps.option.name }}</span>
328
+ <span class="text-xs text-surface-500">{{ slotProps.option.role }}</span>
329
+ </div>
330
+ </div>
331
+ </template>
332
+ </Select>
333
+ </div>
334
+ </template>
335
+
336
+ <script setup>
337
+ import { ref } from 'vue';
338
+
339
+ const assignee = ref(null);
340
+ const teamMembers = ref([
341
+ { id: 1, name: 'Sarah Chen', role: 'Engineering Lead', avatar: 'SC', statusClass: 'bg-amber-400' },
342
+ { id: 2, name: 'Alex Rivera', role: 'Senior Developer', avatar: 'AR', statusClass: 'bg-green-400' },
343
+ { id: 3, name: 'Jordan Kim', role: 'UX Designer', avatar: 'JK', statusClass: 'bg-amber-400' },
344
+ { id: 4, name: 'Taylor Morgan', role: 'Product Manager', avatar: 'TM', statusClass: 'bg-zinc-400' },
345
+ { id: 5, name: 'Morgan Lee', role: 'DevOps Engineer', avatar: 'ML', statusClass: 'bg-green-400' },
346
+ { id: 6, name: 'Casey Jones', role: 'QA Engineer', avatar: 'CJ', statusClass: 'bg-red-400' }
347
+ ]);
348
+ <\/script>
349
+ ```
350
+
351
+ ## Simple
352
+
353
+ Options can be grouped when a nested data structures is provided.
354
+
355
+ ```vue
356
+ <template>
357
+ <div class="flex justify-center">
358
+ <Select
359
+ v-model="selectedPosition"
360
+ :options="jobCategories"
361
+ optionLabel="label"
362
+ optionValue="value"
363
+ optionGroupLabel="label"
364
+ optionGroupChildren="items"
365
+ placeholder="Select a position..."
366
+ class="w-full md:w-56"
367
+ />
368
+ </div>
369
+ </template>
370
+
371
+ <script setup>
372
+ import { ref } from 'vue';
373
+
374
+ const selectedPosition = ref(null);
375
+ const jobCategories = ref([
376
+ {
377
+ label: 'Engineering',
378
+ value: 'eng',
379
+ items: [
380
+ { label: 'Frontend Developer', value: 'frontend' },
381
+ { label: 'Backend Developer', value: 'backend' },
382
+ { label: 'Full Stack Developer', value: 'fullstack' },
383
+ { label: 'DevOps Engineer', value: 'devops' },
384
+ { label: 'QA Engineer', value: 'qa' }
385
+ ]
386
+ },
387
+ {
388
+ label: 'Design',
389
+ value: 'design',
390
+ items: [
391
+ { label: 'UI Designer', value: 'ui' },
392
+ { label: 'UX Designer', value: 'ux' },
393
+ { label: 'Product Designer', value: 'product-design' },
394
+ { label: 'Brand Designer', value: 'brand' }
395
+ ]
396
+ },
397
+ {
398
+ label: 'Product',
399
+ value: 'product',
400
+ items: [
401
+ { label: 'Product Manager', value: 'pm' },
402
+ { label: 'Product Owner', value: 'po' },
403
+ { label: 'Business Analyst', value: 'ba' }
404
+ ]
405
+ },
406
+ {
407
+ label: 'Marketing',
408
+ value: 'marketing',
409
+ items: [
410
+ { label: 'Growth Manager', value: 'growth' },
411
+ { label: 'Content Strategist', value: 'content' },
412
+ { label: 'SEO Specialist', value: 'seo' }
413
+ ]
414
+ }
415
+ ]);
416
+ <\/script>
417
+ ```
418
+
419
+ ## Custom
420
+
421
+ Customize group headers with custom rendering using the #optiongroup slot.
422
+
423
+ ```vue
424
+ <template>
425
+ <div class="flex justify-center">
426
+ <Select
427
+ v-model="selectedCity"
428
+ :options="groupedCities"
429
+ optionLabel="label"
430
+ optionValue="value"
431
+ optionGroupLabel="label"
432
+ optionGroupChildren="items"
433
+ placeholder="Select a City"
434
+ class="w-full md:w-56"
435
+ :pt="{ list: { class: 'p-0!' }, optionGroup: { class: 'border-b border-surface rounded-none' } }"
436
+ >
437
+ <template #optiongroup="slotProps">
438
+ <div class="flex items-center gap-2">
439
+ <span>{{ countryFlags[slotProps.option.value] }}</span>
440
+ <span>{{ slotProps.option.label }}</span>
441
+ </div>
442
+ </template>
443
+ </Select>
444
+ </div>
445
+ </template>
446
+
447
+ <script setup>
448
+ import { ref } from 'vue';
449
+
450
+ const selectedCity = ref(null);
451
+ const groupedCities = ref([
452
+ {
453
+ label: 'Germany',
454
+ value: 'DE',
455
+ items: [
456
+ { label: 'Berlin', value: 'Berlin' },
457
+ { label: 'Frankfurt', value: 'Frankfurt' },
458
+ { label: 'Hamburg', value: 'Hamburg' },
459
+ { label: 'Munich', value: 'Munich' }
460
+ ]
461
+ },
462
+ {
463
+ label: 'USA',
464
+ value: 'US',
465
+ items: [
466
+ { label: 'Chicago', value: 'Chicago' },
467
+ { label: 'Los Angeles', value: 'Los Angeles' },
468
+ { label: 'New York', value: 'New York' },
469
+ { label: 'San Francisco', value: 'San Francisco' }
470
+ ]
471
+ },
472
+ {
473
+ label: 'Japan',
474
+ value: 'JP',
475
+ items: [
476
+ { label: 'Kyoto', value: 'Kyoto' },
477
+ { label: 'Osaka', value: 'Osaka' },
478
+ { label: 'Tokyo', value: 'Tokyo' },
479
+ { label: 'Yokohama', value: 'Yokohama' }
480
+ ]
481
+ }
482
+ ]);
483
+ const countryFlags = ref({
484
+ DE: '🇩🇪',
485
+ US: '🇺🇸',
486
+ JP: '🇯🇵'
487
+ });
488
+ <\/script>
489
+ ```
490
+
491
+ ## Checkbox and Filter
492
+
493
+ Combine grouped options, checkbox selection, and a filter to create a rich multi-select experience.
494
+
495
+ ```vue
496
+ <template>
497
+ <div class="flex justify-center">
498
+ <Select
499
+ v-model="selected"
500
+ :options="labelGroups"
501
+ multiple
502
+ filter
503
+ filterBy="label"
504
+ optionLabel="label"
505
+ optionValue="value"
506
+ optionGroupLabel="label"
507
+ optionGroupChildren="items"
508
+ placeholder="Select labels"
509
+ filterPlaceholder="Search..."
510
+ class="w-full md:w-64 border-0! bg-transparent! shadow-none!"
511
+ :pt="{ dropdown: { class: 'hidden!' } }"
512
+ >
513
+ <template #header>
514
+ <div class="flex items-center gap-1 px-3 pt-2">
515
+ <Button variant="text" size="small" @click="selectAll">Select All</Button>
516
+ <Button variant="text" size="small" severity="secondary" @click="selected = []">Clear</Button>
517
+ </div>
518
+ </template>
519
+ <template #value>
520
+ <span class="inline-flex items-center gap-1 bg-blue-50 dark:bg-blue-950 text-blue-700 dark:text-blue-300 text-xs rounded-full py-1 px-3">
521
+ <TagIcon />
522
+ <span class="font-semibold">{{ getTriggerLabel() }}</span>
523
+ </span>
524
+ </template>
525
+ <template #optiongroup="slotProps">
526
+ <span class="text-xs font-semibold text-surface-500 uppercase tracking-wide">{{ slotProps.option.label }}</span>
527
+ </template>
528
+ <template #option="slotProps">
529
+ <div class="flex items-center gap-2">
530
+ <Checkbox :modelValue="isItemSelected(slotProps.option)" binary :tabindex="-1" readonly />
531
+ <span class="truncate">{{ slotProps.option.label }}</span>
532
+ </div>
533
+ </template>
534
+ </Select>
535
+ </div>
536
+ </template>
537
+
538
+ <script setup>
539
+ import { ref, computed } from 'vue';
540
+ import TagIcon from '@primeicons/vue/tag';
541
+
542
+ const selected = ref(['security']);
543
+ const labelGroups = ref([
544
+ {
545
+ label: 'Critical',
546
+ value: 'critical',
547
+ items: [
548
+ { label: 'Security', value: 'security' },
549
+ { label: 'Performance', value: 'performance' }
550
+ ]
551
+ },
552
+ {
553
+ label: 'Optional',
554
+ value: 'optional',
555
+ items: [
556
+ { label: 'Feature', value: 'feature' },
557
+ { label: 'Other', value: 'other' }
558
+ ]
559
+ }
560
+ ]);
561
+
562
+ const allItems = computed(() => labelGroups.value.flatMap((g) => g.items));
563
+
564
+ const getTriggerLabel = () => {
565
+ if (selected.value.length === 0) return '';
566
+ const first = allItems.value.find((i) => i.value === selected.value[0])?.label ?? selected.value[0];
567
+ return selected.value.length > 1 ? \`\${first} +\${selected.value.length - 1}\` : first;
568
+ };
569
+
570
+ const isItemSelected = (item) => selected.value.includes(item.value);
571
+
572
+ const selectAll = () => {
573
+ selected.value = allItems.value.map((i) => i.value);
574
+ };
575
+ <\/script>
576
+ ```
577
+
578
+ ## Float Label
579
+
580
+ A floating label appears on top of the input field when focused. Visit FloatLabel documentation for more information.
581
+
582
+ ```vue
583
+ <template>
584
+ <div class="flex flex-wrap justify-center items-end gap-4">
585
+ <FloatLabel class="w-full md:w-56">
586
+ <Select v-model="value1" inputId="over_label" :options="cities" optionLabel="name" class="w-full" />
587
+ <label for="over_label">Over Label</label>
588
+ </FloatLabel>
589
+
590
+ <FloatLabel class="w-full md:w-56" variant="in">
591
+ <Select v-model="value2" inputId="in_label" :options="cities" optionLabel="name" class="w-full" variant="filled" />
592
+ <label for="in_label">In Label</label>
593
+ </FloatLabel>
594
+
595
+ <FloatLabel class="w-full md:w-56" variant="on">
596
+ <Select v-model="value3" inputId="on_label" :options="cities" optionLabel="name" class="w-full" />
597
+ <label for="on_label">On Label</label>
598
+ </FloatLabel>
599
+ </div>
600
+ </template>
601
+
602
+ <script setup>
603
+ import { ref } from 'vue';
604
+
605
+ const value1 = ref(null);
606
+ const value2 = ref(null);
607
+ const value3 = ref(null);
608
+ const cities = ref([
609
+ { name: 'New York', code: 'NY' },
610
+ { name: 'Rome', code: 'RM' },
611
+ { name: 'London', code: 'LDN' },
612
+ { name: 'Istanbul', code: 'IST' },
613
+ { name: 'Paris', code: 'PRS' }
614
+ ]);
615
+ <\/script>
616
+ ```
617
+
618
+ ## Ifta Label
619
+
620
+ IftaLabel is used to create infield top aligned labels. Visit IftaLabel documentation for more information.
621
+
622
+ ```vue
623
+ <template>
624
+ <div class="flex justify-center">
625
+ <IftaLabel class="w-full md:w-56">
626
+ <Select v-model="selectedCity" inputId="dd-city" :options="cities" optionLabel="name" class="w-full" />
627
+ <label for="dd-city">City</label>
628
+ </IftaLabel>
629
+ </div>
630
+ </template>
631
+
632
+ <script setup>
633
+ import { ref } from 'vue';
634
+
635
+ const selectedCity = ref(null);
636
+ const cities = ref([
637
+ { name: 'New York', code: 'NY' },
638
+ { name: 'Rome', code: 'RM' },
639
+ { name: 'London', code: 'LDN' },
640
+ { name: 'Istanbul', code: 'IST' },
641
+ { name: 'Paris', code: 'PRS' }
642
+ ]);
643
+ <\/script>
644
+ ```
645
+
646
+ ## Fluid
647
+
648
+ The fluid prop makes the component take up the full width of its container when set to true.
649
+
650
+ ```vue
651
+ <template>
652
+ <Select v-model="selectedCity" :options="cities" optionLabel="name" placeholder="Select a City" fluid />
653
+ </template>
654
+
655
+ <script setup>
656
+ import { ref } from 'vue';
657
+
658
+ const selectedCity = ref(null);
659
+ const cities = ref([
660
+ { name: 'New York', code: 'NY' },
661
+ { name: 'Rome', code: 'RM' },
662
+ { name: 'London', code: 'LDN' },
663
+ { name: 'Istanbul', code: 'IST' },
664
+ { name: 'Paris', code: 'PRS' }
665
+ ]);
666
+ <\/script>
667
+ ```
668
+
669
+ ## Sizes
670
+
671
+ Select provides small and large sizes as alternatives to the base.
672
+
673
+ ```vue
674
+ <template>
675
+ <div class="flex flex-col items-center gap-4">
676
+ <Select v-model="value1" :options="cities" optionLabel="name" size="small" placeholder="Small" class="w-full md:w-56" />
677
+ <Select v-model="value2" :options="cities" optionLabel="name" placeholder="Normal" class="w-full md:w-56" />
678
+ <Select v-model="value3" :options="cities" optionLabel="name" size="large" placeholder="Large" class="w-full md:w-56" />
679
+ </div>
680
+ </template>
681
+
682
+ <script setup>
683
+ import { ref } from 'vue';
684
+
685
+ const value1 = ref(null);
686
+ const value2 = ref(null);
687
+ const value3 = ref(null);
688
+ const cities = ref([
689
+ { name: 'New York', code: 'NY' },
690
+ { name: 'Rome', code: 'RM' },
691
+ { name: 'London', code: 'LDN' },
692
+ { name: 'Istanbul', code: 'IST' },
693
+ { name: 'Paris', code: 'PRS' }
694
+ ]);
695
+ <\/script>
696
+ ```
697
+
698
+ ## Filled
699
+
700
+ Specify the variant property as filled to display the component with a higher visual emphasis than the default outlined style.
701
+
702
+ ```vue
703
+ <template>
704
+ <div class="flex justify-center">
705
+ <Select v-model="selectedCity" variant="filled" :options="cities" optionLabel="name" placeholder="Select a City" class="w-full md:w-56" />
706
+ </div>
707
+ </template>
708
+
709
+ <script setup>
710
+ import { ref } from "vue";
711
+
712
+ const selectedCity = ref();
713
+ const cities = ref([
714
+ { name: 'New York', code: 'NY' },
715
+ { name: 'Rome', code: 'RM' },
716
+ { name: 'London', code: 'LDN' },
717
+ { name: 'Istanbul', code: 'IST' },
718
+ { name: 'Paris', code: 'PRS' }
719
+ ]);
720
+ <\/script>
721
+ ```
722
+
723
+ ## Disabled
724
+
725
+ When disabled is present, the element cannot be edited and focused.
726
+
727
+ ```vue
728
+ <template>
729
+ <div class="flex justify-center">
730
+ <Select v-model="selectedCity" :options="cities" optionLabel="name" placeholder="Select a City" disabled class="w-full md:w-56" />
731
+ </div>
732
+ </template>
733
+
734
+ <script setup>
735
+ import { ref } from 'vue';
736
+
737
+ const selectedCity = ref(null);
738
+ const cities = ref([
739
+ { name: 'New York', code: 'NY' },
740
+ { name: 'Rome', code: 'RM' },
741
+ { name: 'London', code: 'LDN' },
742
+ { name: 'Istanbul', code: 'IST' },
743
+ { name: 'Paris', code: 'PRS' }
744
+ ]);
745
+ <\/script>
746
+ ```
747
+
748
+ ## Invalid
749
+
750
+ The invalid state is applied using the invalid property to indicate failed validation, which can be integrated with form validation libraries.
751
+
752
+ ```vue
753
+ <template>
754
+ <div class="flex justify-center gap-4">
755
+ <Select v-model="selectedCity1" :options="cities" optionLabel="name" showClear :invalid="value1" placeholder="Select a City" class="w-full md:w-56" />
756
+ <Select v-model="selectedCity2" :options="cities" optionLabel="name" showClear :invalid="value2" placeholder="Select a City" class="w-full md:w-56" variant="filled" />
757
+ </div>
758
+ </template>
759
+
760
+ <script setup>
761
+ import { ref } from 'vue';
762
+
763
+ const selectedCity1 = ref(null);
764
+ const selectedCity2 = ref(null);
765
+ const value1 = ref(true);
766
+ const value2 = ref(true);
767
+ const cities = ref([
768
+ { name: 'New York', code: 'NY' },
769
+ { name: 'Rome', code: 'RM' },
770
+ { name: 'London', code: 'LDN' },
771
+ { name: 'Istanbul', code: 'IST' },
772
+ { name: 'Paris', code: 'PRS' }
773
+ ]);
774
+ <\/script>
775
+ ```
776
+
777
+ ## Focus Behavior
778
+
779
+ Customize keyboard and mouse focus behavior with autoOptionFocus , selectOnFocus , and focusOnHover properties.
780
+
781
+ ```vue
782
+ <template>
783
+ <div class="space-y-4">
784
+ <div class="flex flex-wrap gap-2 justify-center">
785
+ <Button @click="autoOptionFocus = !autoOptionFocus" :severity="autoOptionFocus ? 'primary' : 'secondary'" size="small">{{ \`autoOptionFocus: \${autoOptionFocus}\` }}</Button>
786
+ <Button @click="selectOnFocus = !selectOnFocus" :severity="selectOnFocus ? 'primary' : 'secondary'" size="small">{{ \`selectOnFocus: \${selectOnFocus}\` }}</Button>
787
+ <Button @click="focusOnHover = !focusOnHover" :severity="focusOnHover ? 'primary' : 'secondary'" size="small">{{ \`focusOnHover: \${focusOnHover}\` }}</Button>
788
+ </div>
789
+ <div class="flex justify-center">
790
+ <Select
791
+ v-model="selectedCity"
792
+ :options="cities"
793
+ optionLabel="name"
794
+ optionValue="code"
795
+ :autoOptionFocus="autoOptionFocus"
796
+ :selectOnFocus="selectOnFocus"
797
+ :focusOnHover="focusOnHover"
798
+ placeholder="Select a city"
799
+ class="w-full md:w-56"
800
+ />
801
+ </div>
802
+ </div>
803
+ </template>
804
+
805
+ <script setup>
806
+ import { ref } from 'vue';
807
+
808
+ const selectedCity = ref(null);
809
+ const autoOptionFocus = ref(true);
810
+ const selectOnFocus = ref(false);
811
+ const focusOnHover = ref(true);
812
+ const cities = ref([
813
+ { name: 'New York', code: 'NY' },
814
+ { name: 'Rome', code: 'RM' },
815
+ { name: 'London', code: 'LDN' },
816
+ { name: 'Istanbul', code: 'IST' },
817
+ { name: 'Paris', code: 'PRS' }
818
+ ]);
819
+ <\/script>
820
+ ```
821
+
822
+ ## Editable
823
+
824
+ When editable is present, the input can also be entered with typing.
825
+
826
+ ```vue
827
+ <template>
828
+ <div class="flex justify-center">
829
+ <Select v-model="selectedCity" editable :options="cities" optionLabel="name" placeholder="Select a City" class="w-full md:w-56" />
830
+ </div>
831
+ </template>
832
+
833
+ <script setup>
834
+ import { ref } from "vue";
835
+
836
+ const selectedCity = ref();
837
+ const cities = ref([
838
+ { name: 'New York', code: 'NY' },
839
+ { name: 'Rome', code: 'RM' },
840
+ { name: 'London', code: 'LDN' },
841
+ { name: 'Istanbul', code: 'IST' },
842
+ { name: 'Paris', code: 'PRS' }
843
+ ]);
844
+ <\/script>
845
+ ```
846
+
847
+ ## Template
848
+
849
+ Both the selected option and the options list can be templated to provide customizated representation. Use the #value slot to customize the selected label display and the #option slot to change the content of the options in the select panel. In addition when grouping is enabled, the #optiongroup slot is available to customize the option groups. All slots get the option instance as the default slot props.
850
+
851
+ ```vue
852
+ <template>
853
+ <div class="flex justify-center">
854
+ <Select v-model="selectedCountry" :options="countries" optionLabel="name" placeholder="Select a country" class="w-full md:w-56">
855
+ <template #value="slotProps">
856
+ <div v-if="slotProps.value" class="flex items-center gap-2">
857
+ <img src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${slotProps.value.code.toLowerCase()}\`" style="width: 18px" />
858
+ <div>{{ slotProps.value.name }}</div>
859
+ </div>
860
+ <span v-else>{{ slotProps.placeholder }}</span>
861
+ </template>
862
+ <template #option="slotProps">
863
+ <div class="flex items-center gap-2">
864
+ <img src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="\`flag flag-\${slotProps.option.code.toLowerCase()}\`" style="width: 18px" />
865
+ <div>{{ slotProps.option.name }}</div>
866
+ </div>
867
+ </template>
868
+ <template #dropdownicon>
869
+ <Map />
870
+ </template>
871
+ <template #header>
872
+ <div class="font-medium p-3">Available Countries</div>
873
+ </template>
874
+ <template #footer>
875
+ <div class="p-3">
876
+ <Button fluid severity="secondary" variant="text" size="small">
877
+ <Plus />
878
+ Add New
879
+ </Button>
880
+ </div>
881
+ </template>
882
+ </Select>
883
+ </div>
884
+ </template>
885
+
886
+ <script setup>
887
+ import { ref } from 'vue';
888
+ import Map from '@primeicons/vue/map';
889
+ import Plus from '@primeicons/vue/plus';
890
+
891
+ const selectedCountry = ref(null);
892
+ const countries = ref([
893
+ { name: 'Australia', code: 'AU' },
894
+ { name: 'Brazil', code: 'BR' },
895
+ { name: 'China', code: 'CN' },
896
+ { name: 'Egypt', code: 'EG' },
897
+ { name: 'France', code: 'FR' },
898
+ { name: 'Germany', code: 'DE' },
899
+ { name: 'India', code: 'IN' },
900
+ { name: 'Japan', code: 'JP' },
901
+ { name: 'Spain', code: 'ES' },
902
+ { name: 'United States', code: 'US' }
903
+ ]);
904
+ <\/script>
905
+ ```
906
+
907
+ ## Loading State
908
+
909
+ Loading state is enabled with the loading property.
910
+
911
+ ```vue
912
+ <template>
913
+ <div class="flex justify-center">
914
+ <Select v-model="selectedCity" :options="cities" loading optionLabel="name" placeholder="Loading..." class="w-full md:w-56" />
915
+ </div>
916
+ </template>
917
+
918
+ <script setup>
919
+ import { ref } from 'vue';
920
+
921
+ const selectedCity = ref(null);
922
+ const cities = ref([
923
+ { name: 'New York', code: 'NY' },
924
+ { name: 'Rome', code: 'RM' },
925
+ { name: 'London', code: 'LDN' },
926
+ { name: 'Istanbul', code: 'IST' },
927
+ { name: 'Paris', code: 'PRS' }
928
+ ]);
929
+ <\/script>
930
+ ```
931
+
932
+ ## Virtual Scroll
933
+
934
+ VirtualScroller is used to render a long list of options efficiently like 100K records in this demo. The configuration is done with virtualScrollerOptions property, refer to the VirtualScroller for more information about the available options as it is used internally by Select.
935
+
936
+ ```vue
937
+ <template>
938
+ <div class="flex justify-center">
939
+ <Select v-model="selectedItem" :options="items" optionLabel="label" optionValue="value" :virtualScrollerOptions="{ itemSize: 38 }" placeholder="Select Item" class="w-full md:w-56" />
940
+ </div>
941
+ </template>
942
+
943
+ <script setup>
944
+ import { ref } from 'vue';
945
+
946
+ const selectedItem = ref();
947
+ const items = ref(Array.from({ length: 100000 }, (_, i) => ({ label: \`Item #\${i}\`, value: i })));
948
+ <\/script>
949
+ ```
950
+
951
+ ## Lazy Virtual Scroll
952
+
953
+ ```vue
954
+ <template>
955
+ <div class="flex justify-center">
956
+ <Select
957
+ v-model="selectedItem"
958
+ :options="items"
959
+ optionLabel="label"
960
+ optionValue="value"
961
+ :virtualScrollerOptions="{ lazy: true, onLazyLoad: onLazyLoad, itemSize: 38, showLoader: true, loading: loading, delay: 250 }"
962
+ placeholder="Select Item"
963
+ class="w-full md:w-56"
964
+ />
965
+ </div>
966
+ </template>
967
+
968
+ <script setup>
969
+ import { ref } from 'vue';
970
+
971
+ const selectedItem = ref(null);
972
+ const items = ref(Array.from({ length: 100000 }));
973
+ const loading = ref(false);
974
+ const loadLazyTimeout = ref();
975
+
976
+ const onLazyLoad = (event) => {
977
+ loading.value = true;
978
+
979
+ if (loadLazyTimeout.value) {
980
+ clearTimeout(loadLazyTimeout.value);
981
+ }
982
+
983
+ //imitate delay of a backend call
984
+ loadLazyTimeout.value = setTimeout(() => {
985
+ const { first, last } = event;
986
+ const _items = [...items.value];
987
+
988
+ for (let i = first; i < last; i++) {
989
+ _items[i] = { label: \`Item #\${i}\`, value: i };
990
+ }
991
+
992
+ items.value = _items;
993
+ loading.value = false;
994
+ }, Math.random() * 1000 + 250);
995
+ };
996
+ <\/script>
997
+ ```
998
+
999
+ ## Forms
1000
+
1001
+ Select integrates seamlessly with the PrimeVue Forms library.
1002
+
1003
+ ```vue
1004
+ <template>
1005
+ <div class="flex justify-center">
1006
+ <Form v-slot="$form" :resolver="resolver" :initialValues="initialValues" @submit="onFormSubmit" class="flex flex-col gap-4 w-full sm:w-56">
1007
+ <div class="flex flex-col gap-1">
1008
+ <Select name="city" :options="cities" optionLabel="name" placeholder="Select a City" fluid />
1009
+ <Message v-if="$form.city?.invalid" severity="error" size="small" variant="simple">{{ $form.city.error?.message }}</Message>
1010
+ </div>
1011
+ <Button type="submit" severity="secondary">Submit</Button>
1012
+ </Form>
1013
+ </div>
1014
+ </template>
1015
+
1016
+ <script setup>
1017
+ import { ref } from 'vue';
1018
+ import { zodResolver } from '@primevue/forms/resolvers/zod';
1019
+ import { useToast } from "primevue/usetoast";
1020
+ import { z } from 'zod';
1021
+
1022
+ const toast = useToast();
1023
+ const initialValues = ref({
1024
+ city: null
1025
+ });
1026
+ const resolver = ref(zodResolver(
1027
+ z.object({
1028
+ city: z.object({ name: z.string(), code: z.string() }, { message: 'City is required.' })
1029
+ })
1030
+ ));
1031
+ const cities = ref([
1032
+ { name: 'New York', code: 'NY' },
1033
+ { name: 'Rome', code: 'RM' },
1034
+ { name: 'London', code: 'LDN' },
1035
+ { name: 'Istanbul', code: 'IST' },
1036
+ { name: 'Paris', code: 'PRS' }
1037
+ ]);
1038
+
1039
+ const onFormSubmit = ({ valid }) => {
1040
+ if (valid) {
1041
+ toast.add({ severity: 'success', summary: 'Form is submitted.', life: 3000 });
1042
+ }
1043
+ };
1044
+ <\/script>
1045
+ ```
1046
+
1047
+ ## Accessibility
1048
+
1049
+ Screen Reader Value to describe the component can either be provided with aria-labelledby or aria-label props. The select element has a combobox role in addition to aria-haspopup and aria-expanded attributes. If the editable option is enabled aria-autocomplete is also added. The relation between the combobox and the popup is created with aria-controls and aria-activedescendant attribute is used to instruct screen reader which option to read during keyboard navigation within the popup list. The popup list has an id that refers to the aria-controls attribute of the combobox element and uses listbox as the role. Each list item has an option role, an id to match the aria-activedescendant of the input element along with aria-label , aria-selected and aria-disabled attributes. If filtering is enabled, filterInputProps can be defined to give aria-* props to the filter input element. Closed State Keyboard Support Key Function tab Moves focus to the select element. space Opens the popup and moves visual focus to the selected option, if there is none then first option receives the focus. enter Opens the popup and moves visual focus to the selected option, if there is none then first option receives the focus. down arrow Opens the popup and moves visual focus to the selected option, if there is none then first option receives the focus. up arrow Opens the popup and moves visual focus to the selected option, if there is none then last option receives the focus. any printable character Opens the popup and moves focus to the option whose label starts with the characters being typed, if there is none and select is not editable then first option receives the focus. Popup Keyboard Support Key Function tab Moves focus to the next focusable element in the popup. If there is none, the focusable option is selected and the overlay is closed then moves focus to next element in page. shift + tab Moves focus to the previous focusable element in the popup. If there is none, the focusable option is selected and the overlay is closed then moves focus to next element in page. enter Selects the focused option and closes the popup, then moves focus to the select element. space Selects the focused option and closes the popup, then moves focus to the select element. escape Closes the popup, then moves focus to the select element. down arrow Moves focus to the next option, if there is none then visual focus does not change. up arrow Moves focus to the previous option, if there is none then visual focus does not change. alt + up arrow Selects the focused option and closes the popup, then moves focus to the select element. left arrow If the select is editable, removes the visual focus from the current option and moves input cursor to one character left. right arrow If the select is editable, removes the visual focus from the current option and moves input cursor to one character right. home If the select is editable, moves input cursor at the end, if not then moves focus to the first option. end If the select is editable, moves input cursor at the beginning, if not then moves focus to the last option. pageUp Jumps visual focus to first option. pageDown Jumps visual focus to last option. any printable character Moves focus to the option whose label starts with the characters being typed if select is not editable. Filter Input Keyboard Support Key Function down arrow Moves focus to the next option, if there is none then visual focus does not change. up arrow Moves focus to the previous option, if there is none then visual focus does not change. left arrow Removes the visual focus from the current option and moves input cursor to one character left. right arrow Removes the visual focus from the current option and moves input cursor to one character right. home Moves input cursor at the end, if not then moves focus to the first option. end Moves input cursor at the beginning, if not then moves focus to the last option. enter Closes the popup and moves focus to the select element. escape Closes the popup and moves focus to the select element. tab Moves focus to the next focusable element in the popup. If there is none, the focusable option is selected and the overlay is closed then moves focus to next element in page.
1050
+
1051
+ ```vue
1052
+ <span id="dd1">Options</span>
1053
+ <Select aria-labelledby="dd1" />
1054
+
1055
+ <Select aria-label="Options" />
1056
+ ```
1057
+
1058
+ ## Select API
1059
+
1060
+ ### Props
1061
+
1062
+ | Name |Type |Default |Description |
1063
+ | --- | --- | --- | --- |
1064
+ | modelValue | any | - | Value of the component. |
1065
+ | defaultValue | any | - | The default value for the input when not controlled by `modelValue` . |
1066
+ | name | string | - | The name attribute for the element, typically used in form submissions. |
1067
+ | options | any[] | - | An array of select items to display as the available options. |
1068
+ | optionLabel | string \| Function | - | Property name or getter function to use as the label of an option. |
1069
+ | optionValue | string \| Function | - | Property name or getter function to use as the value of an option, defaults to the option itself when not defined. |
1070
+ | optionDisabled | string \| Function | - | Property name or getter function to use as the disabled flag of an option, defaults to false when not defined. |
1071
+ | optionGroupLabel | string \| Function | - | Property name or getter function to use as the label of an option group. |
1072
+ | optionGroupChildren | string \| Function | - | Property name or getter function that refers to the children options of option group. |
1073
+ | scrollHeight | string | 14rem | Height of the viewport, a scrollbar is defined if height of list exceeds this value. |
1074
+ | filter | boolean | false | When specified, displays a filter input at header. |
1075
+ | filterPlaceholder | string | - | Placeholder text to show when filter input is empty. |
1076
+ | filterLocale | string | - | Locale to use in filtering. The default locale is the host environment's current locale. |
1077
+ | filterMatchMode | HintedString<"startsWith" \| "contains" \| "endsWith"> | contains | Defines the filtering algorithm to use when searching the options. |
1078
+ | filterFields | string[] | - | Fields used when filtering the options, defaults to optionLabel. |
1079
+ | editable | boolean | false | When present, custom value instead of predefined options can be entered using the editable input field. |
1080
+ | placeholder | string | - | Default text to display when no option is selected. |
1081
+ | size | HintedString<"small" \| "large"> | - | Defines the size of the component. |
1082
+ | invalid | boolean | false | When present, it specifies that the component should have invalid state style. |
1083
+ | disabled | boolean | false | When present, it specifies that the component should be disabled. |
1084
+ | variant | null \| HintedString<"outlined" \| "filled"> | null | Specifies the input variant of the component. |
1085
+ | dataKey | string | - | A property to uniquely identify an option. |
1086
+ | showClear | boolean | false | When enabled, a clear icon is displayed to clear the value. |
1087
+ | fluid | boolean | null | Spans 100% width of the container when enabled. |
1088
+ | inputId | string | - | |
1089
+ | inputStyle | object | - | |
1090
+ | inputClass | string \| object | - | |
1091
+ | labelId | string | - | Identifier of the underlying label element. |
1092
+ | labelStyle | object | - | Inline style of the label field. |
1093
+ | labelClass | string \| object | - | Style class of the label field. |
1094
+ | overlayStyle | object | - | Inline style of the overlay. |
1095
+ | overlayClass | string \| object | - | Style class of the overlay. |
1096
+ | appendTo | HTMLElement \| HintedString<"body" \| "self"> | body | A valid query selector or an HTMLElement to specify where the overlay gets attached. |
1097
+ | loading | boolean | false | Whether the select is in loading state. |
1098
+ | clearIcon | string | - | Icon to display in clear button. |
1099
+ | dropdownIcon | string | - | Icon to display in the select. |
1100
+ | filterIcon | string | - | Icon to display in filter input. |
1101
+ | loadingIcon | string | - | Icon to display in loading state. |
1102
+ | resetFilterOnHide | boolean | false | Clears the filter value when hiding the select. |
1103
+ | resetFilterOnClear | boolean | false | Clears the filter value when clicking on the clear icon. |
1104
+ | virtualScrollerOptions | any | - | Whether to use the virtualScroller feature. The properties of VirtualScroller component can be used like an object in it. |
1105
+ | autoOptionFocus | boolean | false | Whether to focus on the first visible or selected element when the overlay panel is shown. |
1106
+ | autoFilterFocus | boolean | false | Whether to focus on the filter element when the overlay panel is shown. |
1107
+ | selectOnFocus | boolean | false | When enabled, the focused option is selected. |
1108
+ | focusOnHover | boolean | true | When enabled, the focus is placed on the hovered option. |
1109
+ | highlightOnSelect | boolean | true | Whether the selected option will be add highlight class. |
1110
+ | checkmark | boolean | false | Whether the selected option will be shown with a check mark. |
1111
+ | multiple | boolean | false | When specified, allows selecting multiple values. |
1112
+ | filterMessage | string | '{0} results are available' | Text to be displayed in hidden accessible field when filtering returns any results. Defaults to value from PrimeVue locale configuration. |
1113
+ | selectionMessage | string | '{0} items selected' | Text to be displayed in hidden accessible field when options are selected. Defaults to value from PrimeVue locale configuration. |
1114
+ | emptySelectionMessage | string | No selected item | Text to be displayed in hidden accessible field when any option is not selected. Defaults to value from PrimeVue locale configuration. |
1115
+ | emptyFilterMessage | string | No results found | Text to display when filtering does not return any results. Defaults to value from PrimeVue locale configuration. |
1116
+ | emptyMessage | string | No available options | Text to display when there are no options available. Defaults to value from PrimeVue locale configuration. |
1117
+ | tabindex | string \| number | - | Index of the element in tabbing order. |
1118
+ | ariaLabel | string | - | Defines a string value that labels an interactive element. |
1119
+ | ariaLabelledby | string | - | Identifier of the underlying input element. |
1120
+ | formControl | Record<string, any> | - | Form control object, typically used for handling validation and form state. |
1121
+ | dt | any | - | It generates scoped CSS variables using design tokens for the component. |
1122
+ | pt | PassThrough<SelectPassThroughOptions<any>> | - | Used to pass attributes to DOM elements inside the component. |
1123
+ | ptOptions | any | - | Used to configure passthrough(pt) options of the component. |
1124
+ | unstyled | boolean | false | When enabled, it removes component related styles in the core. |
1125
+
1126
+ ### Pass Through Options
1127
+
1128
+ | Name |Type |Description |
1129
+ | --- | --- | --- |
1130
+ | root | SelectPassThroughOptionType<T> | Used to pass attributes to the root's DOM element. |
1131
+ | label | SelectPassThroughOptionType<T> | Used to pass attributes to the label's DOM element. |
1132
+ | clearIcon | SelectPassThroughOptionType<T> | Used to pass attributes to the clear icon's DOM element. |
1133
+ | dropdown | SelectPassThroughOptionType<T> | Used to pass attributes to the dropdown's DOM element. |
1134
+ | dropdownIcon | SelectPassThroughOptionType<T> | Used to pass attributes to the dropdown icon's DOM element. |
1135
+ | loadingIcon | SelectPassThroughOptionType<T> | Used to pass attributes to the loading icon's DOM element. |
1136
+ | overlay | SelectPassThroughOptionType<T> | Used to pass attributes to the overlay's DOM element. |
1137
+ | header | SelectPassThroughOptionType<T> | Used to pass attributes to the header's DOM element. |
1138
+ | pcFilterContainer | any | Used to pass attributes to the IconField component. |
1139
+ | pcFilter | any | Used to pass attributes to the InputText component. |
1140
+ | pcFilterIconContainer | any | Used to pass attributes to the InputIcon component. |
1141
+ | filterIcon | SelectPassThroughOptionType<T> | Used to pass attributes to the filter icon's DOM element. |
1142
+ | listContainer | SelectPassThroughOptionType<T> | Used to pass attributes to the list container's DOM element. |
1143
+ | virtualScroller | any | Used to pass attributes to the VirtualScroller component. |
1144
+ | list | SelectPassThroughOptionType<T> | Used to pass attributes to the list's DOM element. |
1145
+ | optionGroup | SelectPassThroughOptionType<T> | Used to pass attributes to the option group's DOM element. |
1146
+ | optionGroupLabel | SelectPassThroughOptionType<T> | Used to pass attributes to the option group label's DOM element. |
1147
+ | option | SelectPassThroughOptionType<T> | Used to pass attributes to the option's DOM element. |
1148
+ | optionLabel | SelectPassThroughOptionType<T> | Used to pass attributes to the option label's DOM element. |
1149
+ | optionCheckIcon | SelectPassThroughOptionType<T> | Used to pass attributes to the option check icon's DOM element. |
1150
+ | optionBlankIcon | SelectPassThroughOptionType<T> | Used to pass attributes to the option blank icon's DOM element. |
1151
+ | emptyMessage | SelectPassThroughOptionType<T> | Used to pass attributes to the empty message's DOM element. |
1152
+ | hiddenFirstFocusableEl | SelectPassThroughOptionType<T> | Used to pass attributes to the hidden first focusable element's DOM element. |
1153
+ | hiddenFilterResult | SelectPassThroughOptionType<T> | Used to pass attributes to the hidden filter result's DOM element. |
1154
+ | hiddenEmptyMessage | SelectPassThroughOptionType<T> | Used to pass attributes to the hidden empty message's DOM element. |
1155
+ | hiddenSelectedMessage | SelectPassThroughOptionType<T> | Used to pass attributes to the hidden selected message's DOM element. |
1156
+ | hiddenLastFocusableEl | SelectPassThroughOptionType<T> | Used to pass attributes to the hidden last focusable element's DOM element. |
1157
+ | hooks | any | Used to manage all lifecycle hooks. |
1158
+ | transition | SelectPassThroughTransitionType<any> | Used to control Vue Transition API. |
1159
+
1160
+ ### Theming
1161
+
1162
+ ### CSS Classes
1163
+
1164
+ | Class |Description |
1165
+ | --- | --- |
1166
+ | p-select | Class name of the root element |
1167
+ | p-select-label | Class name of the label element |
1168
+ | p-select-clear-icon | Class name of the clear icon element |
1169
+ | p-select-dropdown | Class name of the dropdown element |
1170
+ | p-select-loading-icon | Class name of the loadingicon element |
1171
+ | p-select-dropdown-icon | Class name of the dropdown icon element |
1172
+ | p-select-overlay | Class name of the overlay element |
1173
+ | p-select-header | Class name of the header element |
1174
+ | p-select-filter | Class name of the filter element |
1175
+ | p-select-list-container | Class name of the list container element |
1176
+ | p-select-list | Class name of the list element |
1177
+ | p-select-option-group | Class name of the option group element |
1178
+ | p-select-option-group-label | Class name of the option group label element |
1179
+ | p-select-option | Class name of the option element |
1180
+ | p-select-option-label | Class name of the option label element |
1181
+ | p-select-option-check-icon | Class name of the option check icon element |
1182
+ | p-select-option-blank-icon | Class name of the option blank icon element |
1183
+ | p-select-empty-message | Class name of the empty message element |
1184
+
1185
+ ### Design Tokens
1186
+
1187
+ | Token |CSS Variable |Description |
1188
+ | --- | --- | --- |
1189
+ | select.background | --p-select-background | Background of root |
1190
+ | select.disabled.background | --p-select-disabled-background | Disabled background of root |
1191
+ | select.filled.background | --p-select-filled-background | Filled background of root |
1192
+ | select.filled.hover.background | --p-select-filled-hover-background | Filled hover background of root |
1193
+ | select.filled.focus.background | --p-select-filled-focus-background | Filled focus background of root |
1194
+ | select.border.color | --p-select-border-color | Border color of root |
1195
+ | select.hover.border.color | --p-select-hover-border-color | Hover border color of root |
1196
+ | select.focus.border.color | --p-select-focus-border-color | Focus border color of root |
1197
+ | select.invalid.border.color | --p-select-invalid-border-color | Invalid border color of root |
1198
+ | select.color | --p-select-color | Color of root |
1199
+ | select.disabled.color | --p-select-disabled-color | Disabled color of root |
1200
+ | select.placeholder.color | --p-select-placeholder-color | Placeholder color of root |
1201
+ | select.invalid.placeholder.color | --p-select-invalid-placeholder-color | Invalid placeholder color of root |
1202
+ | select.shadow | --p-select-shadow | Shadow of root |
1203
+ | select.padding.x | --p-select-padding-x | Padding x of root |
1204
+ | select.padding.y | --p-select-padding-y | Padding y of root |
1205
+ | select.border.radius | --p-select-border-radius | Border radius of root |
1206
+ | select.focus.ring.width | --p-select-focus-ring-width | Focus ring width of root |
1207
+ | select.focus.ring.style | --p-select-focus-ring-style | Focus ring style of root |
1208
+ | select.focus.ring.color | --p-select-focus-ring-color | Focus ring color of root |
1209
+ | select.focus.ring.offset | --p-select-focus-ring-offset | Focus ring offset of root |
1210
+ | select.focus.ring.shadow | --p-select-focus-ring-shadow | Focus ring shadow of root |
1211
+ | select.transition.duration | --p-select-transition-duration | Transition duration of root |
1212
+ | select.sm.font.size | --p-select-sm-font-size | Sm font size of root |
1213
+ | select.sm.padding.x | --p-select-sm-padding-x | Sm padding x of root |
1214
+ | select.sm.padding.y | --p-select-sm-padding-y | Sm padding y of root |
1215
+ | select.lg.font.size | --p-select-lg-font-size | Lg font size of root |
1216
+ | select.lg.padding.x | --p-select-lg-padding-x | Lg padding x of root |
1217
+ | select.lg.padding.y | --p-select-lg-padding-y | Lg padding y of root |
1218
+ | select.font.weight | --p-select-font-weight | Font weight of root |
1219
+ | select.font.size | --p-select-font-size | Font size of root |
1220
+ | select.dropdown.width | --p-select-dropdown-width | Width of dropdown |
1221
+ | select.dropdown.color | --p-select-dropdown-color | Color of dropdown |
1222
+ | select.overlay.background | --p-select-overlay-background | Background of overlay |
1223
+ | select.overlay.border.color | --p-select-overlay-border-color | Border color of overlay |
1224
+ | select.overlay.border.radius | --p-select-overlay-border-radius | Border radius of overlay |
1225
+ | select.overlay.color | --p-select-overlay-color | Color of overlay |
1226
+ | select.overlay.shadow | --p-select-overlay-shadow | Shadow of overlay |
1227
+ | select.list.padding | --p-select-list-padding | Padding of list |
1228
+ | select.list.gap | --p-select-list-gap | Gap of list |
1229
+ | select.list.header.padding | --p-select-list-header-padding | Header padding of list |
1230
+ | select.option.focus.background | --p-select-option-focus-background | Focus background of option |
1231
+ | select.option.selected.background | --p-select-option-selected-background | Selected background of option |
1232
+ | select.option.selected.focus.background | --p-select-option-selected-focus-background | Selected focus background of option |
1233
+ | select.option.color | --p-select-option-color | Color of option |
1234
+ | select.option.focus.color | --p-select-option-focus-color | Focus color of option |
1235
+ | select.option.selected.color | --p-select-option-selected-color | Selected color of option |
1236
+ | select.option.selected.focus.color | --p-select-option-selected-focus-color | Selected focus color of option |
1237
+ | select.option.selected.font.weight | --p-select-option-selected-font-weight | Font weight of a selected option |
1238
+ | select.option.padding | --p-select-option-padding | Padding of option |
1239
+ | select.option.border.radius | --p-select-option-border-radius | Border radius of option |
1240
+ | select.option.font.weight | --p-select-option-font-weight | Font weight of option |
1241
+ | select.option.font.size | --p-select-option-font-size | Font size of option |
1242
+ | select.option.group.background | --p-select-option-group-background | Background of option group |
1243
+ | select.option.group.color | --p-select-option-group-color | Color of option group |
1244
+ | select.option.group.font.weight | --p-select-option-group-font-weight | Font weight of option group |
1245
+ | select.option.group.font.size | --p-select-option-group-font-size | Font size of option group |
1246
+ | select.option.group.padding | --p-select-option-group-padding | Padding of option group |
1247
+ | select.clear.icon.color | --p-select-clear-icon-color | Color of clear icon |
1248
+ | select.checkmark.color | --p-select-checkmark-color | Color of checkmark |
1249
+ | select.checkmark.gutter.start | --p-select-checkmark-gutter-start | Gutter start of checkmark |
1250
+ | select.checkmark.gutter.end | --p-select-checkmark-gutter-end | Gutter end of checkmark |
1251
+ | select.empty.message.padding | --p-select-empty-message-padding | Padding of empty message |