@cocoar/vue-ui 3.2.0-beta.5 → 3.2.0-beta.7
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.
- package/bin/cli.mjs +53 -0
- package/package.json +9 -3
- package/skills/cocoar-vue-ui/SKILL.md +244 -0
- package/skills/cocoar-vue-ui/references/components/avatar.md +178 -0
- package/skills/cocoar-vue-ui/references/components/badge.md +290 -0
- package/skills/cocoar-vue-ui/references/components/breadcrumb.md +238 -0
- package/skills/cocoar-vue-ui/references/components/button.md +252 -0
- package/skills/cocoar-vue-ui/references/components/calendar/agenda-view.md +353 -0
- package/skills/cocoar-vue-ui/references/components/calendar/coar-calendar.md +1645 -0
- package/skills/cocoar-vue-ui/references/components/calendar/day-view.md +361 -0
- package/skills/cocoar-vue-ui/references/components/calendar/index.md +312 -0
- package/skills/cocoar-vue-ui/references/components/calendar/month-view.md +475 -0
- package/skills/cocoar-vue-ui/references/components/calendar/performance.md +186 -0
- package/skills/cocoar-vue-ui/references/components/calendar/timeline-view.md +301 -0
- package/skills/cocoar-vue-ui/references/components/calendar/week-view.md +382 -0
- package/skills/cocoar-vue-ui/references/components/calendar/work-week-view.md +145 -0
- package/skills/cocoar-vue-ui/references/components/calendar/year-view.md +63 -0
- package/skills/cocoar-vue-ui/references/components/card.md +151 -0
- package/skills/cocoar-vue-ui/references/components/checkbox-group.md +103 -0
- package/skills/cocoar-vue-ui/references/components/checkbox.md +279 -0
- package/skills/cocoar-vue-ui/references/components/code-block.md +241 -0
- package/skills/cocoar-vue-ui/references/components/context-menu.md +355 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/checkbox.md +213 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/date-columns.md +272 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/editing.md +236 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/multi-select.md +193 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/number.md +147 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/select.md +202 -0
- package/skills/cocoar-vue-ui/references/components/data-grid/text.md +127 -0
- package/skills/cocoar-vue-ui/references/components/data-grid.md +1225 -0
- package/skills/cocoar-vue-ui/references/components/data-list.md +2121 -0
- package/skills/cocoar-vue-ui/references/components/date-or-time-picker.md +200 -0
- package/skills/cocoar-vue-ui/references/components/date-picker.md +203 -0
- package/skills/cocoar-vue-ui/references/components/date-time-picker.md +154 -0
- package/skills/cocoar-vue-ui/references/components/date-views.md +212 -0
- package/skills/cocoar-vue-ui/references/components/dialog.md +148 -0
- package/skills/cocoar-vue-ui/references/components/divider.md +157 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/annotations.md +400 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/coar-document-viewer.md +327 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/index.md +234 -0
- package/skills/cocoar-vue-ui/references/components/document-viewer/toolbar.md +221 -0
- package/skills/cocoar-vue-ui/references/components/drag-drop.md +267 -0
- package/skills/cocoar-vue-ui/references/components/dual-listbox.md +449 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/asset-store.md +327 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/in-memory-store.md +176 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/index.md +311 -0
- package/skills/cocoar-vue-ui/references/components/file-explorer/use-file-explorer.md +300 -0
- package/skills/cocoar-vue-ui/references/components/form-field.md +1025 -0
- package/skills/cocoar-vue-ui/references/components/fragment-parser.md +298 -0
- package/skills/cocoar-vue-ui/references/components/link.md +235 -0
- package/skills/cocoar-vue-ui/references/components/listbox.md +575 -0
- package/skills/cocoar-vue-ui/references/components/map/editor.md +448 -0
- package/skills/cocoar-vue-ui/references/components/map/index.md +351 -0
- package/skills/cocoar-vue-ui/references/components/markdown-diagrams.md +210 -0
- package/skills/cocoar-vue-ui/references/components/markdown-editor.md +1478 -0
- package/skills/cocoar-vue-ui/references/components/markdown-embeds.md +387 -0
- package/skills/cocoar-vue-ui/references/components/markdown-form.md +447 -0
- package/skills/cocoar-vue-ui/references/components/markdown.md +276 -0
- package/skills/cocoar-vue-ui/references/components/menu.md +380 -0
- package/skills/cocoar-vue-ui/references/components/mermaid.md +172 -0
- package/skills/cocoar-vue-ui/references/components/navbar.md +147 -0
- package/skills/cocoar-vue-ui/references/components/note.md +96 -0
- package/skills/cocoar-vue-ui/references/components/notice.md +131 -0
- package/skills/cocoar-vue-ui/references/components/number-input.md +215 -0
- package/skills/cocoar-vue-ui/references/components/otp-input.md +324 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/authoring-contract.md +271 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-builder.md +476 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/coar-page-renderer.md +677 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/custom-elements.md +441 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/idp-integration.md +122 -0
- package/skills/cocoar-vue-ui/references/components/page-builder/index.md +573 -0
- package/skills/cocoar-vue-ui/references/components/pagination.md +150 -0
- package/skills/cocoar-vue-ui/references/components/panel-layout.md +372 -0
- package/skills/cocoar-vue-ui/references/components/password-input.md +175 -0
- package/skills/cocoar-vue-ui/references/components/popconfirm.md +186 -0
- package/skills/cocoar-vue-ui/references/components/popover.md +173 -0
- package/skills/cocoar-vue-ui/references/components/progress-bar.md +178 -0
- package/skills/cocoar-vue-ui/references/components/radio-group.md +225 -0
- package/skills/cocoar-vue-ui/references/components/script-editor.md +1271 -0
- package/skills/cocoar-vue-ui/references/components/segmented-control.md +238 -0
- package/skills/cocoar-vue-ui/references/components/select.md +463 -0
- package/skills/cocoar-vue-ui/references/components/sidebar.md +421 -0
- package/skills/cocoar-vue-ui/references/components/spinner.md +132 -0
- package/skills/cocoar-vue-ui/references/components/switch.md +195 -0
- package/skills/cocoar-vue-ui/references/components/table.md +170 -0
- package/skills/cocoar-vue-ui/references/components/tabs.md +382 -0
- package/skills/cocoar-vue-ui/references/components/tag.md +178 -0
- package/skills/cocoar-vue-ui/references/components/text-input.md +256 -0
- package/skills/cocoar-vue-ui/references/components/toast.md +160 -0
- package/skills/cocoar-vue-ui/references/components/tooltip.md +121 -0
- package/skills/cocoar-vue-ui/references/components/transitions.md +193 -0
- package/skills/cocoar-vue-ui/references/components/tree.md +2388 -0
- package/skills/cocoar-vue-ui/references/components/virtual-list.md +212 -0
- package/skills/cocoar-vue-ui/references/components/wizard.md +251 -0
- package/skills/cocoar-vue-ui/references/components/zoned-date-time-picker.md +177 -0
- package/skills/cocoar-vue-ui/references/foundations/colors.md +708 -0
- package/skills/cocoar-vue-ui/references/foundations/design-principles.md +115 -0
- package/skills/cocoar-vue-ui/references/foundations/icons.md +381 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/formatting.md +530 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/setup.md +86 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/timezones.md +182 -0
- package/skills/cocoar-vue-ui/references/foundations/localization/translations.md +305 -0
- package/skills/cocoar-vue-ui/references/foundations/motion.md +549 -0
- package/skills/cocoar-vue-ui/references/foundations/spacing.md +330 -0
- package/skills/cocoar-vue-ui/references/foundations/theming.md +140 -0
- package/skills/cocoar-vue-ui/references/foundations/typography.md +206 -0
- package/skills/cocoar-vue-ui/references/guide/error-handling.md +162 -0
- package/skills/cocoar-vue-ui/references/guide/getting-started.md +116 -0
- package/skills/cocoar-vue-ui/references/guide/migration-page-builder-3.md +207 -0
- package/skills/cocoar-vue-ui/references/guide/migration.md +140 -0
- 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` |
|