@cocoar/vue-ui 3.1.0 → 3.2.0-beta.6

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 (179) hide show
  1. package/dist/components/checkbox/CoarCheckbox.vue.d.ts +1 -1
  2. package/dist/components/checkbox/CoarCheckbox.vue.d.ts.map +1 -1
  3. package/dist/components/code-block/CoarCodeBlock.vue.d.ts +1 -1
  4. package/dist/components/code-block/CoarCodeBlock.vue.d.ts.map +1 -1
  5. package/dist/components/data-list/CoarDataList.vue.d.ts +158 -0
  6. package/dist/components/data-list/CoarDataList.vue.d.ts.map +1 -0
  7. package/dist/components/data-list/CoarDataListToolbar.vue.d.ts +30 -0
  8. package/dist/components/data-list/CoarDataListToolbar.vue.d.ts.map +1 -0
  9. package/dist/components/data-list/data-list-builder.d.ts +288 -0
  10. package/dist/components/data-list/data-list-builder.d.ts.map +1 -0
  11. package/dist/components/data-list/index.d.ts +12 -0
  12. package/dist/components/data-list/index.d.ts.map +1 -0
  13. package/dist/components/data-list/internal/compare.d.ts +14 -0
  14. package/dist/components/data-list/internal/compare.d.ts.map +1 -0
  15. package/dist/components/data-list/internal/reorder-core.d.ts +46 -0
  16. package/dist/components/data-list/internal/reorder-core.d.ts.map +1 -0
  17. package/dist/components/data-list/internal/search.d.ts +16 -0
  18. package/dist/components/data-list/internal/search.d.ts.map +1 -0
  19. package/dist/components/data-list/internal/useDataListLines.d.ts +92 -0
  20. package/dist/components/data-list/internal/useDataListLines.d.ts.map +1 -0
  21. package/dist/components/data-list/internal/useDataListReorder.d.ts +68 -0
  22. package/dist/components/data-list/internal/useDataListReorder.d.ts.map +1 -0
  23. package/dist/components/data-list/internal/useSearchHighlight.d.ts +19 -0
  24. package/dist/components/data-list/internal/useSearchHighlight.d.ts.map +1 -0
  25. package/dist/components/data-list/types.d.ts +185 -0
  26. package/dist/components/data-list/types.d.ts.map +1 -0
  27. package/dist/components/data-list/useDataListModel.d.ts +79 -0
  28. package/dist/components/data-list/useDataListModel.d.ts.map +1 -0
  29. package/dist/components/date-time/_shared/maskito-config.d.ts +7 -2
  30. package/dist/components/date-time/_shared/maskito-config.d.ts.map +1 -1
  31. package/dist/components/date-time/_shared/time-helpers.d.ts +11 -4
  32. package/dist/components/date-time/_shared/time-helpers.d.ts.map +1 -1
  33. package/dist/components/date-time/_shared/use-date-picker-base.d.ts +1 -1
  34. package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts +1 -1
  35. package/dist/components/date-time/plain-date-picker/CoarPlainDatePicker.vue.d.ts.map +1 -1
  36. package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts +1 -1
  37. package/dist/components/date-time/plain-date-time-picker/CoarPlainDateTimePicker.vue.d.ts.map +1 -1
  38. package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts +1 -1
  39. package/dist/components/date-time/zoned-date-time-picker/CoarZonedDateTimePicker.vue.d.ts.map +1 -1
  40. package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts +3 -0
  41. package/dist/components/dual-listbox/CoarDualListbox.vue.d.ts.map +1 -1
  42. package/dist/components/form-field/CoarFormField.vue.d.ts +1 -1
  43. package/dist/components/form-field/CoarFormField.vue.d.ts.map +1 -1
  44. package/dist/components/icon/CoarIcon.vue.d.ts +2 -2
  45. package/dist/components/icon/CoarIcon.vue.d.ts.map +1 -1
  46. package/dist/components/listbox/CoarListbox.vue.d.ts +7 -0
  47. package/dist/components/listbox/CoarListbox.vue.d.ts.map +1 -1
  48. package/dist/components/number-input/CoarNumberInput.vue.d.ts +1 -1
  49. package/dist/components/number-input/CoarNumberInput.vue.d.ts.map +1 -1
  50. package/dist/components/otp-input/CoarOtpInput.vue.d.ts +1 -1
  51. package/dist/components/otp-input/CoarOtpInput.vue.d.ts.map +1 -1
  52. package/dist/components/password-input/CoarPasswordInput.vue.d.ts +1 -1
  53. package/dist/components/password-input/CoarPasswordInput.vue.d.ts.map +1 -1
  54. package/dist/components/switch/CoarSwitch.vue.d.ts +1 -1
  55. package/dist/components/switch/CoarSwitch.vue.d.ts.map +1 -1
  56. package/dist/components/text-input/CoarTextInput.vue.d.ts +1 -1
  57. package/dist/components/text-input/CoarTextInput.vue.d.ts.map +1 -1
  58. package/dist/composables/dragRegistry.d.ts +12 -0
  59. package/dist/composables/dragRegistry.d.ts.map +1 -1
  60. package/dist/composables/index.d.ts +2 -2
  61. package/dist/composables/index.d.ts.map +1 -1
  62. package/dist/composables/useDragDrop.d.ts +62 -6
  63. package/dist/composables/useDragDrop.d.ts.map +1 -1
  64. package/dist/composables/useVirtualList.d.ts +21 -1
  65. package/dist/composables/useVirtualList.d.ts.map +1 -1
  66. package/dist/index.css +1 -1
  67. package/dist/index.d.ts +4 -2
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +4508 -2039
  70. package/package.json +5 -3
  71. package/skills/cocoar-vue-ui/SKILL.md +244 -0
  72. package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
  73. package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
  74. package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
  75. package/skills/cocoar-vue-ui/references/components/button.md +252 -0
  76. package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
  77. package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
  78. package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
  79. package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
  80. package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
  81. package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
  82. package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
  83. package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
  84. package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
  85. package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
  86. package/skills/cocoar-vue-ui/references/components/card.md +151 -0
  87. package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
  88. package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
  89. package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
  90. package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
  91. package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
  92. package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
  93. package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
  94. package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
  95. package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
  96. package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
  97. package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
  98. package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
  99. package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
  100. package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
  101. package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
  102. package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
  103. package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
  104. package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
  105. package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
  106. package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
  107. package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
  108. package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
  109. package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
  110. package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
  111. package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
  112. package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
  113. package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
  114. package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
  115. package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
  116. package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
  117. package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
  118. package/skills/cocoar-vue-ui/references/components/link.md +235 -0
  119. package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
  120. package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
  121. package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
  122. package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
  123. package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
  124. package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
  125. package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
  126. package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
  127. package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
  128. package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
  129. package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
  130. package/skills/cocoar-vue-ui/references/components/note.md +96 -0
  131. package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
  132. package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
  133. package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
  134. package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
  135. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
  136. package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
  137. package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
  138. package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
  139. package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
  140. package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
  141. package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
  142. package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
  143. package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
  144. package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
  145. package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
  146. package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
  147. package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
  148. package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
  149. package/skills/cocoar-vue-ui/references/components/select.md +463 -0
  150. package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
  151. package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
  152. package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
  153. package/skills/cocoar-vue-ui/references/components/table.md +170 -0
  154. package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
  155. package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
  156. package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
  157. package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
  158. package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
  159. package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
  160. package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
  161. package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
  162. package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
  163. package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
  164. package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
  165. package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
  166. package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
  167. package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
  168. package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
  169. package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
  170. package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
  171. package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
  172. package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
  173. package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
  174. package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
  175. package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
  176. package/skills/cocoar-vue-ui/references/guide/getting-started.md +119 -0
  177. package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
  178. package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
  179. package/skills/cocoar-vue-ui/references/guide/theming.md +98 -0
@@ -0,0 +1,463 @@
1
+ <!-- Generated from apps/docs/components/select.md by apps/docs/scripts/sync-skill.mjs. Do not edit; edit the docs page. -->
2
+
3
+ # Select
4
+
5
+ Select components for single and multiple value selection. Choose between Single Select, Multi Select, or Tag Select variants.
6
+
7
+ ```ts
8
+ import { CoarSelect, CoarMultiSelect, CoarTagSelect } from '@cocoar/vue-ui';
9
+ import type { CoarSelectOption } from '@cocoar/vue-ui';
10
+ ```
11
+
12
+ ## Single Select
13
+
14
+ Select a single option from a dropdown list. Toggle props to explore all options.
15
+
16
+ **Demo — `select/demos/SelectPlayground.vue`**
17
+
18
+ ```vue
19
+ <template>
20
+ <div style="display: flex; flex-direction: column; gap: 16px;">
21
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
22
+ <CoarCheckbox v-model="grouped" label="grouped" />
23
+ <CoarCheckbox v-model="searchable" label="searchable" />
24
+ <CoarCheckbox v-model="clearable" label="clearable" />
25
+ <CoarCheckbox v-model="disabled" label="disabled" />
26
+ <CoarCheckbox v-model="readonly" label="readonly" />
27
+ <CoarCheckbox v-model="error" label="error" />
28
+ <CoarSelect v-model="size" :options="sizeOptions" :searchable="false" size="s" style="width: 90px;" />
29
+ <CoarSelect v-model="appearance" :options="appearanceOptions" :searchable="false" size="s" style="width: 120px;" />
30
+ <CoarSelect v-model="position" :options="positionOptions" :searchable="false" size="s" style="width: 110px;" />
31
+ <CoarSelect v-model="sortGroups" :options="sortPresetOptions" :searchable="false" size="s" style="width: 160px;" placeholder="sortGroups" />
32
+ <CoarSelect v-model="sortOptions" :options="sortPresetOptions" :searchable="false" size="s" style="width: 160px;" placeholder="sortOptions" />
33
+ </div>
34
+
35
+ <div style="max-width: 320px;">
36
+ <CoarFormField label="Country">
37
+ <CoarSelect
38
+ v-model="value"
39
+ :options="activeOptions"
40
+ :searchable="searchable"
41
+ :clearable="clearable"
42
+ :disabled="disabled"
43
+ :readonly="readonly"
44
+ :error="error"
45
+ :size="size"
46
+ :appearance="appearance"
47
+ :dropdown-position="position"
48
+ :sort-groups="sortGroups"
49
+ :sort-options="sortOptions"
50
+ placeholder="Select a country..."
51
+ />
52
+ </CoarFormField>
53
+ <p style="margin-top: 8px; font-size: 13px; color: #64748b;">
54
+ Selected: {{ value || 'none' }}
55
+ </p>
56
+ </div>
57
+ </div>
58
+ </template>
59
+
60
+ <script setup lang="ts">
61
+ import { ref, computed } from 'vue';
62
+ import { CoarSelect, CoarCheckbox, CoarFormField } from '@cocoar/vue-ui';
63
+ import type { CoarSelectOption, CoarSelectSortGroups, CoarSelectSortOptions } from '@cocoar/vue-ui';
64
+
65
+ const value = ref<string | null>(null);
66
+ const grouped = ref(true);
67
+ const searchable = ref(false);
68
+ const clearable = ref(false);
69
+ const disabled = ref(false);
70
+ const readonly = ref(false);
71
+ const error = ref(false);
72
+ const size = ref<'xs' | 's' | 'm' | 'l'>('m');
73
+ const appearance = ref<'outline' | 'inline'>('outline');
74
+ const position = ref<'auto' | 'top' | 'bottom'>('auto');
75
+ const sortGroups = ref<CoarSelectSortGroups>('asc');
76
+ const sortOptions = ref<CoarSelectSortOptions>('none');
77
+
78
+ const groupedOptions: CoarSelectOption<string>[] = [
79
+ { value: 'at', label: 'Austria', group: 'Central Europe' },
80
+ { value: 'de', label: 'Germany', group: 'Central Europe' },
81
+ { value: 'ch', label: 'Switzerland', group: 'Central Europe' },
82
+ { value: 'fr', label: 'France', group: 'Western Europe' },
83
+ { value: 'nl', label: 'Netherlands', group: 'Western Europe' },
84
+ { value: 'be', label: 'Belgium', group: 'Western Europe' },
85
+ { value: 'es', label: 'Spain', group: 'Southern Europe' },
86
+ { value: 'it', label: 'Italy', group: 'Southern Europe' },
87
+ { value: 'pt', label: 'Portugal', group: 'Southern Europe' },
88
+ { value: 'se', label: 'Sweden', group: 'Northern Europe' },
89
+ { value: 'no', label: 'Norway', group: 'Northern Europe' },
90
+ { value: 'dk', label: 'Denmark', group: 'Northern Europe' },
91
+ ];
92
+
93
+ const flatOptions: CoarSelectOption<string>[] = groupedOptions.map(({ group, ...rest }) => rest);
94
+
95
+ const activeOptions = computed(() => grouped.value ? groupedOptions : flatOptions);
96
+
97
+ const sizeOptions: CoarSelectOption<string>[] = [
98
+ { value: 'xs', label: 'xs' },
99
+ { value: 's', label: 's' },
100
+ { value: 'm', label: 'm' },
101
+ { value: 'l', label: 'l' },
102
+ ];
103
+
104
+ const appearanceOptions: CoarSelectOption<string>[] = [
105
+ { value: 'outline', label: 'outline' },
106
+ { value: 'inline', label: 'inline' },
107
+ ];
108
+
109
+ const positionOptions: CoarSelectOption<string>[] = [
110
+ { value: 'auto', label: 'auto' },
111
+ { value: 'top', label: 'top' },
112
+ { value: 'bottom', label: 'bottom' },
113
+ ];
114
+
115
+ const sortPresetOptions: CoarSelectOption<string>[] = [
116
+ { value: 'asc', label: 'asc' },
117
+ { value: 'desc', label: 'desc' },
118
+ { value: 'none', label: 'none' },
119
+ ];
120
+ </script>
121
+ ```
122
+
123
+ ## Multi Select
124
+
125
+ Select multiple values with checkmarks. Toggle props to explore options.
126
+
127
+ **Demo — `select/demos/MultiSelectPlayground.vue`**
128
+
129
+ ```vue
130
+ <template>
131
+ <div style="display: flex; flex-direction: column; gap: 16px;">
132
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
133
+ <CoarCheckbox v-model="grouped" label="grouped" />
134
+ <CoarCheckbox v-model="searchable" label="searchable" />
135
+ <CoarCheckbox v-model="clearable" label="clearable" />
136
+ <CoarCheckbox v-model="showSelectAll" label="showSelectAll" />
137
+ <CoarCheckbox v-model="disabled" label="disabled" />
138
+ <CoarCheckbox v-model="readonly" label="readonly" />
139
+ <CoarCheckbox v-model="error" label="error" />
140
+ <CoarSelect v-model="size" :options="sizeOptions" :searchable="false" size="s" style="width: 90px;" />
141
+ <CoarSelect v-model="appearance" :options="appearanceOptions" :searchable="false" size="s" style="width: 120px;" />
142
+ <CoarSelect v-model="sortGroups" :options="sortPresetOptions" :searchable="false" size="s" style="width: 160px;" placeholder="sortGroups" />
143
+ <CoarSelect v-model="sortOptions" :options="sortPresetOptions" :searchable="false" size="s" style="width: 160px;" placeholder="sortOptions" />
144
+ </div>
145
+
146
+ <div style="max-width: 320px;">
147
+ <CoarFormField label="Countries">
148
+ <CoarMultiSelect
149
+ v-model="value"
150
+ :options="activeOptions"
151
+ :searchable="searchable"
152
+ :clearable="clearable"
153
+ :show-select-all="showSelectAll"
154
+ :disabled="disabled"
155
+ :readonly="readonly"
156
+ :error="error"
157
+ :size="size"
158
+ :appearance="appearance"
159
+ :sort-groups="sortGroups"
160
+ :sort-options="sortOptions"
161
+ placeholder="Select countries..."
162
+ />
163
+ </CoarFormField>
164
+ <p style="margin-top: 8px; font-size: 13px; color: #64748b;">
165
+ Selected: {{ value.join(', ') || 'none' }}
166
+ </p>
167
+ </div>
168
+ </div>
169
+ </template>
170
+
171
+ <script setup lang="ts">
172
+ import { ref, computed } from 'vue';
173
+ import { CoarMultiSelect, CoarSelect, CoarCheckbox, CoarFormField } from '@cocoar/vue-ui';
174
+ import type { CoarSelectOption, CoarSelectSortGroups, CoarSelectSortOptions } from '@cocoar/vue-ui';
175
+
176
+ const value = ref<string[]>([]);
177
+ const grouped = ref(true);
178
+ const searchable = ref(false);
179
+ const clearable = ref(false);
180
+ const showSelectAll = ref(false);
181
+ const disabled = ref(false);
182
+ const readonly = ref(false);
183
+ const error = ref(false);
184
+ const size = ref<'xs' | 's' | 'm' | 'l'>('m');
185
+ const appearance = ref<'outline' | 'inline'>('outline');
186
+ const sortGroups = ref<CoarSelectSortGroups>('asc');
187
+ const sortOptions = ref<CoarSelectSortOptions>('none');
188
+
189
+ const groupedOptions: CoarSelectOption<string>[] = [
190
+ { value: 'at', label: 'Austria', group: 'Central Europe' },
191
+ { value: 'de', label: 'Germany', group: 'Central Europe' },
192
+ { value: 'ch', label: 'Switzerland', group: 'Central Europe' },
193
+ { value: 'fr', label: 'France', group: 'Western Europe' },
194
+ { value: 'nl', label: 'Netherlands', group: 'Western Europe' },
195
+ { value: 'be', label: 'Belgium', group: 'Western Europe' },
196
+ { value: 'es', label: 'Spain', group: 'Southern Europe' },
197
+ { value: 'it', label: 'Italy', group: 'Southern Europe' },
198
+ { value: 'pt', label: 'Portugal', group: 'Southern Europe' },
199
+ { value: 'se', label: 'Sweden', group: 'Northern Europe' },
200
+ { value: 'no', label: 'Norway', group: 'Northern Europe' },
201
+ { value: 'dk', label: 'Denmark', group: 'Northern Europe' },
202
+ ];
203
+
204
+ const flatOptions: CoarSelectOption<string>[] = groupedOptions.map(({ group, ...rest }) => rest);
205
+
206
+ const activeOptions = computed(() => grouped.value ? groupedOptions : flatOptions);
207
+
208
+ const sizeOptions: CoarSelectOption<string>[] = [
209
+ { value: 'xs', label: 'xs' },
210
+ { value: 's', label: 's' },
211
+ { value: 'm', label: 'm' },
212
+ { value: 'l', label: 'l' },
213
+ ];
214
+
215
+ const appearanceOptions: CoarSelectOption<string>[] = [
216
+ { value: 'outline', label: 'outline' },
217
+ { value: 'inline', label: 'inline' },
218
+ ];
219
+
220
+ const sortPresetOptions: CoarSelectOption<string>[] = [
221
+ { value: 'asc', label: 'asc' },
222
+ { value: 'desc', label: 'desc' },
223
+ { value: 'none', label: 'none' },
224
+ ];
225
+ </script>
226
+ ```
227
+
228
+ ## Tag Select
229
+
230
+ Select multiple values as removable tags. Search is always active — type to filter or create new tags.
231
+
232
+ **Demo — `select/demos/TagSelectPlayground.vue`**
233
+
234
+ ```vue
235
+ <template>
236
+ <div style="display: flex; flex-direction: column; gap: 16px;">
237
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
238
+ <CoarCheckbox v-model="grouped" label="grouped" />
239
+ <CoarCheckbox v-model="allowCreate" label="allowCreate" />
240
+ <CoarCheckbox v-model="disabled" label="disabled" />
241
+ <CoarCheckbox v-model="readonly" label="readonly" />
242
+ <CoarCheckbox v-model="error" label="error" />
243
+ <CoarSelect v-model="size" :options="sizeOptions" :searchable="false" size="s" style="width: 90px;" />
244
+ <CoarSelect v-model="appearance" :options="appearanceOptions" :searchable="false" size="s" style="width: 120px;" />
245
+ <CoarSelect v-model="sortGroups" :options="sortPresetOptions" :searchable="false" size="s" style="width: 160px;" placeholder="sortGroups" />
246
+ <CoarSelect v-model="sortOptions" :options="sortPresetOptions" :searchable="false" size="s" style="width: 160px;" placeholder="sortOptions" />
247
+ </div>
248
+
249
+ <div style="max-width: 320px;">
250
+ <CoarFormField label="Countries">
251
+ <CoarTagSelect
252
+ v-model="value"
253
+ :options="activeOptions"
254
+ :allow-create="allowCreate"
255
+ :disabled="disabled"
256
+ :readonly="readonly"
257
+ :error="error"
258
+ :size="size"
259
+ :appearance="appearance"
260
+ :sort-groups="sortGroups"
261
+ :sort-options="sortOptions"
262
+ placeholder="Type to search..."
263
+ />
264
+ </CoarFormField>
265
+ <p style="margin-top: 8px; font-size: 13px; color: #64748b;">
266
+ Selected: {{ value.join(', ') || 'none' }}
267
+ </p>
268
+ </div>
269
+ </div>
270
+ </template>
271
+
272
+ <script setup lang="ts">
273
+ import { ref, computed } from 'vue';
274
+ import { CoarTagSelect, CoarSelect, CoarCheckbox, CoarFormField } from '@cocoar/vue-ui';
275
+ import type { CoarSelectOption, CoarSelectSortGroups, CoarSelectSortOptions } from '@cocoar/vue-ui';
276
+
277
+ const value = ref<string[]>([]);
278
+ const grouped = ref(true);
279
+ const allowCreate = ref(false);
280
+ const disabled = ref(false);
281
+ const readonly = ref(false);
282
+ const error = ref(false);
283
+ const size = ref<'xs' | 's' | 'm' | 'l'>('m');
284
+ const appearance = ref<'outline' | 'inline'>('outline');
285
+ const sortGroups = ref<CoarSelectSortGroups>('asc');
286
+ const sortOptions = ref<CoarSelectSortOptions>('none');
287
+
288
+ const groupedOptions: CoarSelectOption<string>[] = [
289
+ { value: 'at', label: 'Austria', group: 'Central Europe' },
290
+ { value: 'de', label: 'Germany', group: 'Central Europe' },
291
+ { value: 'ch', label: 'Switzerland', group: 'Central Europe' },
292
+ { value: 'fr', label: 'France', group: 'Western Europe' },
293
+ { value: 'nl', label: 'Netherlands', group: 'Western Europe' },
294
+ { value: 'be', label: 'Belgium', group: 'Western Europe' },
295
+ { value: 'es', label: 'Spain', group: 'Southern Europe' },
296
+ { value: 'it', label: 'Italy', group: 'Southern Europe' },
297
+ { value: 'pt', label: 'Portugal', group: 'Southern Europe' },
298
+ { value: 'se', label: 'Sweden', group: 'Northern Europe' },
299
+ { value: 'no', label: 'Norway', group: 'Northern Europe' },
300
+ { value: 'dk', label: 'Denmark', group: 'Northern Europe' },
301
+ ];
302
+
303
+ const flatOptions: CoarSelectOption<string>[] = groupedOptions.map(({ group, ...rest }) => rest);
304
+
305
+ const activeOptions = computed(() => grouped.value ? groupedOptions : flatOptions);
306
+
307
+ const sizeOptions: CoarSelectOption<string>[] = [
308
+ { value: 'xs', label: 'xs' },
309
+ { value: 's', label: 's' },
310
+ { value: 'm', label: 'm' },
311
+ { value: 'l', label: 'l' },
312
+ ];
313
+
314
+ const appearanceOptions: CoarSelectOption<string>[] = [
315
+ { value: 'outline', label: 'outline' },
316
+ { value: 'inline', label: 'inline' },
317
+ ];
318
+
319
+ const sortPresetOptions: CoarSelectOption<string>[] = [
320
+ { value: 'asc', label: 'asc' },
321
+ { value: 'desc', label: 'desc' },
322
+ { value: 'none', label: 'none' },
323
+ ];
324
+ </script>
325
+ ```
326
+
327
+ ## Options Format
328
+
329
+ Options must follow the `CoarSelectOption<T>` interface:
330
+
331
+ ```ts
332
+ interface CoarSelectOption<T> {
333
+ value: T;
334
+ label: string;
335
+ disabled?: boolean;
336
+ group?: string;
337
+ icon?: string;
338
+ }
339
+
340
+ const options: CoarSelectOption<string>[] = [
341
+ { value: 'apple', label: 'Apple', group: 'Fruits' },
342
+ { value: 'banana', label: 'Banana', group: 'Fruits', disabled: true },
343
+ { value: 'carrot', label: 'Carrot', group: 'Vegetables' },
344
+ ];
345
+ ```
346
+
347
+ ## Sorting
348
+
349
+ Control the order of groups and options via `sortGroups` and `sortOptions`. Both accept preset strings or a custom comparator function.
350
+
351
+ **Demo — `select/demos/SortingDemo.vue`**
352
+
353
+ ```vue
354
+ <template>
355
+ <div style="display: flex; flex-direction: column; gap: 16px;">
356
+ <div style="display: flex; flex-wrap: wrap; gap: 12px; align-items: center;">
357
+ <CoarSelect v-model="sortGroups" :options="sortPresetOptions" :searchable="false" size="s" style="width: 150px;" placeholder="sortGroups" />
358
+ <CoarSelect v-model="sortOptions" :options="sortPresetOptions" :searchable="false" size="s" style="width: 150px;" placeholder="sortOptions" />
359
+ </div>
360
+
361
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px; max-width: 640px;">
362
+ <CoarFormField label="With groups">
363
+ <CoarSelect
364
+ v-model="value1"
365
+ :options="groupedOptions"
366
+ :sort-groups="sortGroups"
367
+ :sort-options="sortOptions"
368
+ clearable
369
+ searchable
370
+ placeholder="Select..."
371
+ />
372
+ </CoarFormField>
373
+
374
+ <CoarFormField label="Without groups">
375
+ <CoarSelect
376
+ v-model="value2"
377
+ :options="flatOptions"
378
+ :sort-options="sortOptions"
379
+ clearable
380
+ searchable
381
+ placeholder="Select..."
382
+ />
383
+ </CoarFormField>
384
+ </div>
385
+ </div>
386
+ </template>
387
+
388
+ <script setup lang="ts">
389
+ import { ref } from 'vue';
390
+ import { CoarSelect, CoarFormField } from '@cocoar/vue-ui';
391
+ import type { CoarSelectOption, CoarSelectSortGroups, CoarSelectSortOptions } from '@cocoar/vue-ui';
392
+
393
+ const value1 = ref<string | null>(null);
394
+ const value2 = ref<string | null>(null);
395
+ const sortGroups = ref<CoarSelectSortGroups>('asc');
396
+ const sortOptions = ref<CoarSelectSortOptions>('none');
397
+
398
+ const sortPresetOptions: CoarSelectOption<string>[] = [
399
+ { value: 'asc', label: 'asc' },
400
+ { value: 'desc', label: 'desc' },
401
+ { value: 'none', label: 'none' },
402
+ ];
403
+
404
+ const groupedOptions: CoarSelectOption<string>[] = [
405
+ { value: 'carrot', label: 'Carrot', group: 'Vegetables' },
406
+ { value: 'broccoli', label: 'Broccoli', group: 'Vegetables' },
407
+ { value: 'spinach', label: 'Spinach', group: 'Vegetables' },
408
+ { value: 'banana', label: 'Banana', group: 'Fruits' },
409
+ { value: 'apple', label: 'Apple', group: 'Fruits' },
410
+ { value: 'cherry', label: 'Cherry', group: 'Fruits' },
411
+ { value: 'salmon', label: 'Salmon', group: 'Protein' },
412
+ { value: 'chicken', label: 'Chicken', group: 'Protein' },
413
+ { value: 'tofu', label: 'Tofu', group: 'Protein' },
414
+ ];
415
+
416
+ const flatOptions: CoarSelectOption<string>[] = groupedOptions.map(({ group, ...rest }) => rest);
417
+ </script>
418
+ ```
419
+
420
+ - `sortOptions` works **with and without groups** — it sorts all options, or within each group respectively
421
+ - `sortGroups` only applies when options have a `group` property
422
+ - `'none'` preserves the order as passed — giving you full control from the consumer side
423
+ - Pass a custom comparator `(a, b) => number` for special sorting (e.g. by priority, numeric values)
424
+
425
+ ```ts
426
+ import type { CoarSelectSortGroups, CoarSelectSortOptions } from '@cocoar/vue-ui';
427
+ ```
428
+
429
+ ## API
430
+
431
+ ### Props
432
+
433
+ | Prop | Type | Default | Description |
434
+ |------|------|---------|-------------|
435
+ | `v-model` | `T \| null` | `null` | Selected value (the option's `value` field) |
436
+ | `options` | `CoarSelectOption<T>[]` | `[]` | Array of `{ value, label }` option objects |
437
+ | `placeholder` | `string` | `''` | Placeholder when empty |
438
+ | `size` | `'xs' \| 's' \| 'm' \| 'l'` | `'m'` | Input size |
439
+ | `searchable` | `boolean` | `false` | Enable inline search to filter options by typing |
440
+ | `clearable` | `boolean` | `false` | Show a clear button when a value is selected |
441
+ | `disabled` | `boolean` | `false` | Disable the select |
442
+ | `readonly` | `boolean` | `false` | Read-only state |
443
+ | `error` | `boolean` | `false` | Error state (auto-injected from `CoarFormField`) |
444
+ | `appearance` | `'outline' \| 'inline'` | `'outline'` | Visual appearance variant |
445
+ | `compareWith` | `(a: T, b: T) => boolean` | `===` | Custom comparison function for matching values |
446
+ | `dropdownPosition` | `'auto' \| 'top' \| 'bottom'` | `'auto'` | Dropdown position preference |
447
+ | `sortGroups` | `'asc' \| 'desc' \| 'none' \| (a, b) => number` | `'asc'` | Sort order for groups |
448
+ | `sortOptions` | `'asc' \| 'desc' \| 'none' \| (a, b) => number` | `'none'` | Sort order for options (within each group, or all if ungrouped) |
449
+
450
+ ## i18n Keys
451
+
452
+ These keys can be translated via [`@cocoar/vue-localization`](../foundations/localization/translations.md).
453
+
454
+ These keys apply to `CoarSelect`, `CoarMultiSelect`, and `CoarTagSelect`.
455
+
456
+ | Key | Default (English) | Used as |
457
+ |-----|-------------------|---------|
458
+ | `coar.ui.select.clearSelection` | `'Clear selection'` | Clear button `aria-label` |
459
+ | `coar.ui.select.options` | `'Options'` | Options listbox `aria-label` |
460
+ | `coar.ui.select.noResults` | `'No results found'` | Empty state text when search returns no matches |
461
+ | `coar.ui.select.noOptions` | `'No options available'` | Empty state text when options list is empty |
462
+ | `coar.ui.tagSelect.remove` | `'Remove'` | Tag remove button `aria-label` |
463
+ | `coar.ui.tagSelect.options` | `'Options'` | Tag select listbox `aria-label` |