@sewadah/selaras 0.3.0 → 0.3.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.
- package/README.md +4 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +21 -6
- package/dist/runtime/components/AlertDialog.d.vue.ts +5 -3
- package/dist/runtime/components/AlertDialog.vue +17 -9
- package/dist/runtime/components/AlertDialog.vue.d.ts +5 -3
- package/dist/runtime/components/App.vue +2 -0
- package/dist/runtime/components/Autocomplete.d.vue.ts +2 -2
- package/dist/runtime/components/Autocomplete.vue +4 -2
- package/dist/runtime/components/Autocomplete.vue.d.ts +2 -2
- package/dist/runtime/components/Button.d.vue.ts +7 -5
- package/dist/runtime/components/Button.vue +14 -3
- package/dist/runtime/components/Button.vue.d.ts +7 -5
- package/dist/runtime/components/Calendar.d.vue.ts +69 -0
- package/dist/runtime/components/Calendar.vue +163 -0
- package/dist/runtime/components/Calendar.vue.d.ts +69 -0
- package/dist/runtime/components/Callout.vue +12 -1
- package/dist/runtime/components/CodeGroup.vue +13 -3
- package/dist/runtime/components/CodeTree.d.vue.ts +2 -0
- package/dist/runtime/components/CodeTree.vue +52 -1
- package/dist/runtime/components/CodeTree.vue.d.ts +2 -0
- package/dist/runtime/components/ColorModeSwitch.d.vue.ts +18 -0
- package/dist/runtime/components/ColorModeSwitch.vue +59 -0
- package/dist/runtime/components/ColorModeSwitch.vue.d.ts +18 -0
- package/dist/runtime/components/ColorPicker.d.vue.ts +8 -0
- package/dist/runtime/components/ColorPicker.vue +66 -45
- package/dist/runtime/components/ColorPicker.vue.d.ts +8 -0
- package/dist/runtime/components/Column.js +1 -1
- package/dist/runtime/components/CommandPalette.d.vue.ts +3 -1
- package/dist/runtime/components/CommandPalette.vue +5 -0
- package/dist/runtime/components/CommandPalette.vue.d.ts +3 -1
- package/dist/runtime/components/ConfirmRenderer.d.vue.ts +3 -0
- package/dist/runtime/components/ConfirmRenderer.vue +39 -0
- package/dist/runtime/components/ConfirmRenderer.vue.d.ts +3 -0
- package/dist/runtime/components/ContentNavigation.d.vue.ts +8 -1
- package/dist/runtime/components/ContentNavigation.vue +9 -2
- package/dist/runtime/components/ContentNavigation.vue.d.ts +8 -1
- package/dist/runtime/components/ContextMenu.d.vue.ts +8 -1
- package/dist/runtime/components/ContextMenu.vue +20 -6
- package/dist/runtime/components/ContextMenu.vue.d.ts +8 -1
- package/dist/runtime/components/DatePicker.d.vue.ts +10 -3
- package/dist/runtime/components/DatePicker.vue +24 -16
- package/dist/runtime/components/DatePicker.vue.d.ts +10 -3
- package/dist/runtime/components/Drawer.vue +3 -2
- package/dist/runtime/components/Dropdown.d.vue.ts +33 -6
- package/dist/runtime/components/Dropdown.vue +146 -12
- package/dist/runtime/components/Dropdown.vue.d.ts +33 -6
- package/dist/runtime/components/FileTree.d.vue.ts +2 -0
- package/dist/runtime/components/FileTree.vue +8 -4
- package/dist/runtime/components/FileTree.vue.d.ts +2 -0
- package/dist/runtime/components/FormField.d.vue.ts +4 -0
- package/dist/runtime/components/FormField.vue +19 -4
- package/dist/runtime/components/FormField.vue.d.ts +4 -0
- package/dist/runtime/components/Input.vue +3 -2
- package/dist/runtime/components/Kbd.vue +12 -2
- package/dist/runtime/components/Modal.vue +3 -2
- package/dist/runtime/components/NavigationMenu.d.vue.ts +10 -10
- package/dist/runtime/components/NavigationMenu.vue +13 -9
- package/dist/runtime/components/NavigationMenu.vue.d.ts +10 -10
- package/dist/runtime/components/NavigationMenuAccordionItem.vue +5 -1
- package/dist/runtime/components/NavigationMenuFlyoutList.vue +7 -4
- package/dist/runtime/components/Popover.d.vue.ts +8 -2
- package/dist/runtime/components/Popover.vue +13 -6
- package/dist/runtime/components/Popover.vue.d.ts +8 -2
- package/dist/runtime/components/ProsePre.d.vue.ts +2 -0
- package/dist/runtime/components/ProsePre.vue +2 -1
- package/dist/runtime/components/ProsePre.vue.d.ts +2 -0
- package/dist/runtime/components/Select.d.vue.ts +8 -4
- package/dist/runtime/components/Select.vue +4 -2
- package/dist/runtime/components/Select.vue.d.ts +8 -4
- package/dist/runtime/components/Slideover.vue +3 -2
- package/dist/runtime/components/SplitterPanel.d.vue.ts +2 -2
- package/dist/runtime/components/SplitterPanel.vue.d.ts +2 -2
- package/dist/runtime/components/Table.vue +95 -26
- package/dist/runtime/components/Tabs.d.vue.ts +44 -4
- package/dist/runtime/components/Tabs.vue +171 -18
- package/dist/runtime/components/Tabs.vue.d.ts +44 -4
- package/dist/runtime/components/Textarea.vue +3 -2
- package/dist/runtime/components/Timeline.d.vue.ts +19 -0
- package/dist/runtime/components/Timeline.vue +99 -0
- package/dist/runtime/components/Timeline.vue.d.ts +19 -0
- package/dist/runtime/components/Toast.d.vue.ts +10 -1
- package/dist/runtime/components/Toast.vue +94 -8
- package/dist/runtime/components/Toast.vue.d.ts +10 -1
- package/dist/runtime/components/Tooltip.d.vue.ts +8 -2
- package/dist/runtime/components/Tooltip.vue +13 -6
- package/dist/runtime/components/Tooltip.vue.d.ts +8 -2
- package/dist/runtime/composables/use-confirm.d.ts +14 -0
- package/dist/runtime/composables/use-confirm.js +28 -0
- package/dist/runtime/composables/use-form-field.d.ts +1 -0
- package/dist/runtime/composables/use-table.d.ts +3 -0
- package/dist/runtime/composables/use-table.js +10 -4
- package/dist/runtime/composables/use-toast.js +5 -1
- package/dist/runtime/directives/hotkey.d.ts +13 -0
- package/dist/runtime/directives/hotkey.js +107 -0
- package/dist/runtime/directives/index.d.ts +2 -0
- package/dist/runtime/directives/index.js +2 -0
- package/dist/runtime/directives/mask.d.ts +30 -0
- package/dist/runtime/directives/mask.js +165 -0
- package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +41 -36
- package/dist/runtime/internal/ComboboxSelectBase.vue +119 -26
- package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +41 -36
- package/dist/runtime/internal/ComboboxSelectBody.d.vue.ts +23 -17
- package/dist/runtime/internal/ComboboxSelectBody.vue +50 -11
- package/dist/runtime/internal/ComboboxSelectBody.vue.d.ts +23 -17
- package/dist/runtime/internal/DatePickerCalendarBody.vue +1 -1
- package/dist/runtime/internal/DatePickerRangeCalendarBody.vue +1 -1
- package/dist/runtime/internal/ShortcutHint.d.vue.ts +6 -0
- package/dist/runtime/internal/ShortcutHint.vue +13 -0
- package/dist/runtime/internal/ShortcutHint.vue.d.ts +6 -0
- package/dist/runtime/internal/ToastItemRenderer.d.vue.ts +9 -1
- package/dist/runtime/internal/ToastItemRenderer.vue +55 -8
- package/dist/runtime/internal/ToastItemRenderer.vue.d.ts +9 -1
- package/dist/runtime/internal/combobox-select.d.ts +19 -18
- package/dist/runtime/internal/combobox-select.js +38 -15
- package/dist/runtime/internal/programmatic-services.d.ts +13 -0
- package/dist/runtime/internal/programmatic-services.js +9 -0
- package/dist/runtime/internal/toast-stack.d.ts +36 -0
- package/dist/runtime/internal/toast-stack.js +36 -0
- package/dist/runtime/structural.css +1 -1
- package/dist/runtime/table.d.ts +1 -1
- package/dist/runtime/theme/alert-dialog.js +1 -1
- package/dist/runtime/theme/badge.d.ts +9 -0
- package/dist/runtime/theme/badge.js +2 -1
- package/dist/runtime/theme/button.d.ts +18 -0
- package/dist/runtime/theme/button.js +4 -1
- package/dist/runtime/theme/calendar.d.ts +86 -0
- package/dist/runtime/theme/calendar.js +19 -0
- package/dist/runtime/theme/callout.d.ts +0 -12
- package/dist/runtime/theme/callout.js +8 -8
- package/dist/runtime/theme/code-tree.js +1 -1
- package/dist/runtime/theme/command-palette.js +1 -1
- package/dist/runtime/theme/content-navigation.d.ts +3 -0
- package/dist/runtime/theme/content-navigation.js +1 -0
- package/dist/runtime/theme/drawer.js +1 -1
- package/dist/runtime/theme/dropdown.d.ts +21 -0
- package/dist/runtime/theme/dropdown.js +15 -2
- package/dist/runtime/theme/file-tree.js +1 -1
- package/dist/runtime/theme/form-field.d.ts +18 -0
- package/dist/runtime/theme/form-field.js +6 -1
- package/dist/runtime/theme/modal.js +1 -1
- package/dist/runtime/theme/slideover.js +1 -1
- package/dist/runtime/theme/table.d.ts +27 -0
- package/dist/runtime/theme/table.js +11 -2
- package/dist/runtime/theme/tabs.d.ts +87 -3
- package/dist/runtime/theme/tabs.js +46 -22
- package/dist/runtime/theme/timeline.d.ts +251 -0
- package/dist/runtime/theme/timeline.js +84 -0
- package/dist/runtime/theme/toast.d.ts +92 -0
- package/dist/runtime/theme/toast.js +29 -7
- package/dist/runtime/theme-config.d.ts +13 -2
- package/dist/runtime/types/index.d.ts +10 -2
- package/dist/runtime/utils/arrow.d.ts +21 -0
- package/dist/runtime/utils/arrow.js +10 -0
- package/dist/runtime/utils/autocomplete-contracts.d.ts +4 -4
- package/dist/runtime/utils/file-icons.js +3 -0
- package/dist/runtime/utils/icons.d.ts +2 -0
- package/dist/runtime/utils/icons.js +2 -0
- package/dist/runtime/utils/messages.d.ts +7 -0
- package/dist/runtime/utils/messages.js +7 -0
- package/dist/runtime/utils/navigation-menu.d.ts +7 -0
- package/dist/runtime/utils/navigation-menu.js +3 -0
- package/dist/runtime/utils/overlay.d.ts +17 -0
- package/dist/runtime/utils/overlay.js +7 -0
- package/dist/runtime/utils/select-contracts.d.ts +25 -11
- package/dist/runtime/utils/table-columns.js +1 -1
- package/dist/runtime/utils/table-contracts.d.ts +9 -1
- package/dist/runtime/utils/timeline-contracts.d.ts +42 -0
- package/dist/runtime/utils/timeline-contracts.js +0 -0
- package/dist/runtime/utils/ui.d.ts +11 -0
- package/dist/runtime/utils/ui.js +54 -1
- package/package.json +6 -5
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { SelectModelValue } from '../utils/select-contracts.js';
|
|
1
2
|
import type { ResolvedItemOption, SelectItems, SelectOption } from './combobox-select.js';
|
|
2
3
|
export interface ComboboxSelectBodyProps {
|
|
3
4
|
listbox?: boolean;
|
|
4
5
|
searchable?: boolean;
|
|
5
6
|
creatable?: boolean;
|
|
7
|
+
multiple?: boolean;
|
|
8
|
+
forceSelection?: boolean;
|
|
9
|
+
selectedValues?: SelectModelValue[];
|
|
6
10
|
searchText: string;
|
|
7
11
|
displayValue: (value: unknown) => string;
|
|
8
12
|
items: SelectItems;
|
|
@@ -12,9 +16,9 @@ export interface ComboboxSelectBodyProps {
|
|
|
12
16
|
overscan: number;
|
|
13
17
|
} | null;
|
|
14
18
|
virtualizedOptions: ResolvedItemOption[];
|
|
15
|
-
toOption: (entry: SelectOption) => ResolvedItemOption;
|
|
19
|
+
toOption: (entry: SelectOption | SelectModelValue) => ResolvedItemOption;
|
|
16
20
|
groupOptions: (group: {
|
|
17
|
-
items: readonly SelectOption[];
|
|
21
|
+
items: readonly (SelectOption | SelectModelValue)[];
|
|
18
22
|
}) => ResolvedItemOption[];
|
|
19
23
|
onSearchKeydown: (event: KeyboardEvent) => void;
|
|
20
24
|
onSearchBlur: () => void;
|
|
@@ -30,15 +34,15 @@ export interface ComboboxSelectBodyEmits {
|
|
|
30
34
|
'update:searchText': [value: string];
|
|
31
35
|
}
|
|
32
36
|
declare function focusSearch(): boolean;
|
|
33
|
-
declare var __VLS_1: {}, __VLS_3: {}, __VLS_21: {}, __VLS_29: {},
|
|
34
|
-
item: SelectOption<
|
|
35
|
-
},
|
|
36
|
-
group: import("./combobox-select.js").SelectOptionGroup<
|
|
37
|
-
},
|
|
38
|
-
item: SelectOption<
|
|
39
|
-
},
|
|
40
|
-
item: SelectOption<
|
|
41
|
-
},
|
|
37
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_21: {}, __VLS_29: {}, __VLS_31: {}, __VLS_39: {}, __VLS_61: {
|
|
38
|
+
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
39
|
+
}, __VLS_92: {
|
|
40
|
+
group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
|
|
41
|
+
}, __VLS_102: {
|
|
42
|
+
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
43
|
+
}, __VLS_123: {
|
|
44
|
+
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
45
|
+
}, __VLS_136: {};
|
|
42
46
|
type __VLS_Slots = {} & {
|
|
43
47
|
header?: (props: typeof __VLS_1) => any;
|
|
44
48
|
} & {
|
|
@@ -48,17 +52,19 @@ type __VLS_Slots = {} & {
|
|
|
48
52
|
} & {
|
|
49
53
|
'empty-filter'?: (props: typeof __VLS_29) => any;
|
|
50
54
|
} & {
|
|
51
|
-
'empty-filter'?: (props: typeof
|
|
55
|
+
'empty-filter'?: (props: typeof __VLS_31) => any;
|
|
52
56
|
} & {
|
|
53
|
-
|
|
57
|
+
'empty-filter'?: (props: typeof __VLS_39) => any;
|
|
54
58
|
} & {
|
|
55
|
-
|
|
59
|
+
item?: (props: typeof __VLS_61) => any;
|
|
56
60
|
} & {
|
|
57
|
-
|
|
61
|
+
group?: (props: typeof __VLS_92) => any;
|
|
58
62
|
} & {
|
|
59
|
-
item?: (props: typeof
|
|
63
|
+
item?: (props: typeof __VLS_102) => any;
|
|
60
64
|
} & {
|
|
61
|
-
|
|
65
|
+
item?: (props: typeof __VLS_123) => any;
|
|
66
|
+
} & {
|
|
67
|
+
footer?: (props: typeof __VLS_136) => any;
|
|
62
68
|
};
|
|
63
69
|
declare const __VLS_base: import("vue").DefineComponent<ComboboxSelectBodyProps, {
|
|
64
70
|
focusSearch: typeof focusSearch;
|
|
@@ -27,6 +27,9 @@ const props = defineProps({
|
|
|
27
27
|
listbox: { type: Boolean, required: false },
|
|
28
28
|
searchable: { type: Boolean, required: false },
|
|
29
29
|
creatable: { type: Boolean, required: false },
|
|
30
|
+
multiple: { type: Boolean, required: false },
|
|
31
|
+
forceSelection: { type: Boolean, required: false },
|
|
32
|
+
selectedValues: { type: Array, required: false },
|
|
30
33
|
searchText: { type: String, required: true },
|
|
31
34
|
displayValue: { type: Function, required: true },
|
|
32
35
|
items: { type: null, required: true },
|
|
@@ -53,10 +56,29 @@ const searchInput = ref();
|
|
|
53
56
|
const { contains } = useFilter({ sensitivity: "base" });
|
|
54
57
|
const primitives = computed(() => props.listbox ? { input: ListboxFilter, viewport: ListboxContent, group: ListboxGroup, label: ListboxGroupLabel, item: ListboxItem, indicator: ListboxItemIndicator, virtualizer: ListboxVirtualizer } : { input: ComboboxInput, viewport: ComboboxViewport, group: ComboboxGroup, label: ComboboxLabel, item: ComboboxItem, indicator: ComboboxItemIndicator, virtualizer: ComboboxVirtualizer });
|
|
55
58
|
function matches(option) {
|
|
56
|
-
return !props.listbox || !props.searchable || contains(option.label, props.searchText);
|
|
59
|
+
return !(props.listbox || props.creatable && props.multiple) || !props.searchable || contains(option.label, props.searchText);
|
|
57
60
|
}
|
|
58
61
|
const visibleOptions = computed(() => props.flatOptions.filter(matches));
|
|
59
|
-
const
|
|
62
|
+
const createText = computed(() => {
|
|
63
|
+
if (!props.creatable || !props.multiple || props.forceSelection)
|
|
64
|
+
return "";
|
|
65
|
+
const text = props.searchText.trim();
|
|
66
|
+
const lower = text.toLowerCase();
|
|
67
|
+
if (!text || props.flatOptions.some((option) => String(option.value).toLowerCase() === lower || option.label.toLowerCase() === lower) || props.selectedValues?.some((value) => typeof value === "string" && value.toLowerCase() === lower)) {
|
|
68
|
+
return "";
|
|
69
|
+
}
|
|
70
|
+
return text;
|
|
71
|
+
});
|
|
72
|
+
const virtualOptions = computed(() => {
|
|
73
|
+
const options = props.listbox ? visibleOptions.value : props.virtualizedOptions;
|
|
74
|
+
return createText.value ? [{ value: createText.value, key: `create:${createText.value}`, label: messages.value.createOption(createText.value), disabled: false, raw: void 0 }, ...options] : options;
|
|
75
|
+
});
|
|
76
|
+
function onItemSelect(event, value) {
|
|
77
|
+
if (!props.creatable || !props.multiple || !props.selectedValues?.includes(value))
|
|
78
|
+
return;
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
emit("update:searchText", "");
|
|
81
|
+
}
|
|
60
82
|
const filterInputProps = computed(() => mergeProps(
|
|
61
83
|
props.listbox ? { "role": "combobox", "aria-autocomplete": "list", "aria-expanded": true, "aria-controls": listboxId, "aria-label": messages.value.search } : { displayValue: props.displayValue },
|
|
62
84
|
props.searchInputProps ?? {}
|
|
@@ -90,18 +112,23 @@ defineExpose({ focusSearch });
|
|
|
90
112
|
/>
|
|
91
113
|
</div>
|
|
92
114
|
|
|
93
|
-
<div v-if="flatOptions.length === 0" v-bind="emptyProps">
|
|
115
|
+
<div v-if="flatOptions.length === 0 && !createText" v-bind="emptyProps">
|
|
94
116
|
<slot name="empty">
|
|
95
117
|
{{ messages.noOptions }}
|
|
96
118
|
</slot>
|
|
97
119
|
</div>
|
|
98
120
|
<component :is="primitives.viewport" v-else :id="listbox ? listboxId : void 0" v-bind="viewportProps">
|
|
99
|
-
<div v-if="listbox && visibleOptions.length === 0" v-bind="emptyProps">
|
|
121
|
+
<div v-if="listbox && visibleOptions.length === 0 && !createText" v-bind="emptyProps">
|
|
100
122
|
<slot name="empty-filter">
|
|
101
123
|
{{ messages.noResultsFound }}
|
|
102
124
|
</slot>
|
|
103
125
|
</div>
|
|
104
|
-
<
|
|
126
|
+
<div v-else-if="creatable && multiple && visibleOptions.length === 0 && !createText" v-bind="emptyProps">
|
|
127
|
+
<slot name="empty-filter">
|
|
128
|
+
{{ messages.noResultsFound }}
|
|
129
|
+
</slot>
|
|
130
|
+
</div>
|
|
131
|
+
<ComboboxEmpty v-else-if="!listbox && !(creatable && multiple)" v-bind="emptyProps">
|
|
105
132
|
<slot name="empty-filter">
|
|
106
133
|
{{ messages.noResultsFound }}
|
|
107
134
|
</slot>
|
|
@@ -121,20 +148,30 @@ defineExpose({ focusSearch });
|
|
|
121
148
|
:key="String(virtualItem.key)"
|
|
122
149
|
:value="option.value"
|
|
123
150
|
:disabled="option.disabled"
|
|
151
|
+
:data-selaras-create-option="option.raw === void 0 || void 0"
|
|
124
152
|
:style="{ position: 'absolute', top: 0, left: 0, right: 0, transform: `translateY(${virtualItem.start}px)`, height: `${virtualItem.size}px` }"
|
|
125
153
|
v-bind="itemProps"
|
|
154
|
+
@select="onItemSelect($event, option.value)"
|
|
126
155
|
>
|
|
127
|
-
<
|
|
156
|
+
<template v-if="option.raw === void 0">
|
|
128
157
|
{{ option.label }}
|
|
129
|
-
</
|
|
130
|
-
<
|
|
131
|
-
<
|
|
132
|
-
|
|
158
|
+
</template>
|
|
159
|
+
<template v-else>
|
|
160
|
+
<slot name="item" :item="option.raw">
|
|
161
|
+
{{ option.label }}
|
|
162
|
+
</slot>
|
|
163
|
+
<component :is="primitives.indicator" v-bind="itemIndicatorProps">
|
|
164
|
+
<Icon :name="icons.check" class="size-4" />
|
|
165
|
+
</component>
|
|
166
|
+
</template>
|
|
133
167
|
</component>
|
|
134
168
|
</component>
|
|
135
169
|
</ClientOnly>
|
|
136
170
|
|
|
137
171
|
<template v-else>
|
|
172
|
+
<component :is="primitives.item" v-if="createText" :value="createText" data-selaras-create-option v-bind="itemProps">
|
|
173
|
+
{{ messages.createOption(createText) }}
|
|
174
|
+
</component>
|
|
138
175
|
<template v-for="(entry, index) in items" :key="index">
|
|
139
176
|
<component :is="primitives.group" v-if="isOptionGroup(entry) && groupOptions(entry).some(matches)">
|
|
140
177
|
<component :is="primitives.label" v-bind="groupProps">
|
|
@@ -145,10 +182,11 @@ defineExpose({ focusSearch });
|
|
|
145
182
|
<component
|
|
146
183
|
:is="primitives.item"
|
|
147
184
|
v-for="option in groupOptions(entry).filter(matches)"
|
|
148
|
-
:key="option.
|
|
185
|
+
:key="option.key"
|
|
149
186
|
:value="option.value"
|
|
150
187
|
:disabled="option.disabled"
|
|
151
188
|
v-bind="itemProps"
|
|
189
|
+
@select="onItemSelect($event, option.value)"
|
|
152
190
|
>
|
|
153
191
|
<slot name="item" :item="option.raw">
|
|
154
192
|
{{ option.label }}
|
|
@@ -164,6 +202,7 @@ defineExpose({ focusSearch });
|
|
|
164
202
|
:value="toOption(entry).value"
|
|
165
203
|
:disabled="toOption(entry).disabled"
|
|
166
204
|
v-bind="itemProps"
|
|
205
|
+
@select="onItemSelect($event, toOption(entry).value)"
|
|
167
206
|
>
|
|
168
207
|
<slot name="item" :item="entry">
|
|
169
208
|
{{ toOption(entry).label }}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { SelectModelValue } from '../utils/select-contracts.js';
|
|
1
2
|
import type { ResolvedItemOption, SelectItems, SelectOption } from './combobox-select.js';
|
|
2
3
|
export interface ComboboxSelectBodyProps {
|
|
3
4
|
listbox?: boolean;
|
|
4
5
|
searchable?: boolean;
|
|
5
6
|
creatable?: boolean;
|
|
7
|
+
multiple?: boolean;
|
|
8
|
+
forceSelection?: boolean;
|
|
9
|
+
selectedValues?: SelectModelValue[];
|
|
6
10
|
searchText: string;
|
|
7
11
|
displayValue: (value: unknown) => string;
|
|
8
12
|
items: SelectItems;
|
|
@@ -12,9 +16,9 @@ export interface ComboboxSelectBodyProps {
|
|
|
12
16
|
overscan: number;
|
|
13
17
|
} | null;
|
|
14
18
|
virtualizedOptions: ResolvedItemOption[];
|
|
15
|
-
toOption: (entry: SelectOption) => ResolvedItemOption;
|
|
19
|
+
toOption: (entry: SelectOption | SelectModelValue) => ResolvedItemOption;
|
|
16
20
|
groupOptions: (group: {
|
|
17
|
-
items: readonly SelectOption[];
|
|
21
|
+
items: readonly (SelectOption | SelectModelValue)[];
|
|
18
22
|
}) => ResolvedItemOption[];
|
|
19
23
|
onSearchKeydown: (event: KeyboardEvent) => void;
|
|
20
24
|
onSearchBlur: () => void;
|
|
@@ -30,15 +34,15 @@ export interface ComboboxSelectBodyEmits {
|
|
|
30
34
|
'update:searchText': [value: string];
|
|
31
35
|
}
|
|
32
36
|
declare function focusSearch(): boolean;
|
|
33
|
-
declare var __VLS_1: {}, __VLS_3: {}, __VLS_21: {}, __VLS_29: {},
|
|
34
|
-
item: SelectOption<
|
|
35
|
-
},
|
|
36
|
-
group: import("./combobox-select.js").SelectOptionGroup<
|
|
37
|
-
},
|
|
38
|
-
item: SelectOption<
|
|
39
|
-
},
|
|
40
|
-
item: SelectOption<
|
|
41
|
-
},
|
|
37
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_21: {}, __VLS_29: {}, __VLS_31: {}, __VLS_39: {}, __VLS_61: {
|
|
38
|
+
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
39
|
+
}, __VLS_92: {
|
|
40
|
+
group: import("./combobox-select.js").SelectOptionGroup<SelectModelValue>;
|
|
41
|
+
}, __VLS_102: {
|
|
42
|
+
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
43
|
+
}, __VLS_123: {
|
|
44
|
+
item: SelectModelValue | SelectOption<SelectModelValue>;
|
|
45
|
+
}, __VLS_136: {};
|
|
42
46
|
type __VLS_Slots = {} & {
|
|
43
47
|
header?: (props: typeof __VLS_1) => any;
|
|
44
48
|
} & {
|
|
@@ -48,17 +52,19 @@ type __VLS_Slots = {} & {
|
|
|
48
52
|
} & {
|
|
49
53
|
'empty-filter'?: (props: typeof __VLS_29) => any;
|
|
50
54
|
} & {
|
|
51
|
-
'empty-filter'?: (props: typeof
|
|
55
|
+
'empty-filter'?: (props: typeof __VLS_31) => any;
|
|
52
56
|
} & {
|
|
53
|
-
|
|
57
|
+
'empty-filter'?: (props: typeof __VLS_39) => any;
|
|
54
58
|
} & {
|
|
55
|
-
|
|
59
|
+
item?: (props: typeof __VLS_61) => any;
|
|
56
60
|
} & {
|
|
57
|
-
|
|
61
|
+
group?: (props: typeof __VLS_92) => any;
|
|
58
62
|
} & {
|
|
59
|
-
item?: (props: typeof
|
|
63
|
+
item?: (props: typeof __VLS_102) => any;
|
|
60
64
|
} & {
|
|
61
|
-
|
|
65
|
+
item?: (props: typeof __VLS_123) => any;
|
|
66
|
+
} & {
|
|
67
|
+
footer?: (props: typeof __VLS_136) => any;
|
|
62
68
|
};
|
|
63
69
|
declare const __VLS_base: import("vue").DefineComponent<ComboboxSelectBodyProps, {
|
|
64
70
|
focusSearch: typeof focusSearch;
|
|
@@ -120,7 +120,7 @@ const cellTriggerUi = {
|
|
|
120
120
|
<DatePickerGrid v-for="month in grid" :key="month.value.toString()" v-bind="gridProps">
|
|
121
121
|
<DatePickerGridHead v-bind="gridHeadProps">
|
|
122
122
|
<DatePickerGridRow>
|
|
123
|
-
<DatePickerHeadCell v-for="day in weekDays" :key="
|
|
123
|
+
<DatePickerHeadCell v-for="(day, index) in weekDays" :key="index" v-bind="headCellProps">
|
|
124
124
|
{{ day }}
|
|
125
125
|
</DatePickerHeadCell>
|
|
126
126
|
</DatePickerGridRow>
|
|
@@ -51,7 +51,7 @@ const rangeCellTriggerUi = {
|
|
|
51
51
|
<DateRangePickerGrid v-for="month in grid" :key="month.value.toString()" v-bind="gridProps">
|
|
52
52
|
<DateRangePickerGridHead v-bind="gridHeadProps">
|
|
53
53
|
<DateRangePickerGridRow>
|
|
54
|
-
<DateRangePickerHeadCell v-for="day in weekDays" :key="
|
|
54
|
+
<DateRangePickerHeadCell v-for="(day, index) in weekDays" :key="index" v-bind="headCellProps">
|
|
55
55
|
{{ day }}
|
|
56
56
|
</DateRangePickerHeadCell>
|
|
57
57
|
</DateRangePickerGridRow>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
shortcut?: string;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import Kbd from "../components/Kbd.vue";
|
|
3
|
+
import { applyClassPrefix } from "../utils/ui";
|
|
4
|
+
defineProps({
|
|
5
|
+
shortcut: { type: String, required: false }
|
|
6
|
+
});
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<template>
|
|
10
|
+
<span v-if="shortcut" :class="applyClassPrefix('ms-auto inline-flex items-center gap-1')" aria-hidden="true">
|
|
11
|
+
<Kbd v-for="key in shortcut.split('+')" :key="key" :value="key.trim()" size="sm" />
|
|
12
|
+
</span>
|
|
13
|
+
</template>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
shortcut?: string;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
5
|
+
declare const _default: typeof __VLS_export;
|
|
6
|
+
export default _default;
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type { ToastThemeSlots } from '../theme/toast.js';
|
|
1
|
+
import type { ToastPosition, ToastThemeSlots } from '../theme/toast.js';
|
|
2
2
|
import type { UiProp } from '../utils/ui.js';
|
|
3
3
|
import type { ToastItem } from './programmatic-services.js';
|
|
4
|
+
import type { ToastStackItem } from './toast-stack.js';
|
|
4
5
|
type __VLS_Props = {
|
|
5
6
|
toast: ToastItem;
|
|
6
7
|
ui?: UiProp<ToastThemeSlots>;
|
|
8
|
+
duration: number;
|
|
9
|
+
expand: boolean;
|
|
10
|
+
position: ToastPosition;
|
|
11
|
+
placement: ToastStackItem | undefined;
|
|
12
|
+
leaving: boolean;
|
|
7
13
|
};
|
|
8
14
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
15
|
remove: (id: number) => any;
|
|
16
|
+
resize: (height: number) => any;
|
|
10
17
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
18
|
onRemove?: ((id: number) => any) | undefined;
|
|
19
|
+
onResize?: ((height: number) => any) | undefined;
|
|
12
20
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
21
|
declare const _default: typeof __VLS_export;
|
|
14
22
|
export default _default;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { ToastClose, ToastDescription, ToastRoot, ToastTitle } from "reka-ui";
|
|
3
|
-
import { computed } from "vue";
|
|
3
|
+
import { computed, ref, watch } from "vue";
|
|
4
4
|
import Button from "../components/Button.vue";
|
|
5
5
|
import Icon from "../components/Icon.vue";
|
|
6
6
|
import { useIcons } from "../composables/use-icons";
|
|
@@ -11,16 +11,62 @@ import { resolveRegisteredColorRole } from "../utils/registered-colors";
|
|
|
11
11
|
import { resolveSlot, useComponentTheme, useThemeBindings } from "../utils/ui";
|
|
12
12
|
const props = defineProps({
|
|
13
13
|
toast: { type: Object, required: true },
|
|
14
|
-
ui: { type: Object, required: false }
|
|
14
|
+
ui: { type: Object, required: false },
|
|
15
|
+
duration: { type: Number, required: true },
|
|
16
|
+
expand: { type: Boolean, required: true },
|
|
17
|
+
position: { type: null, required: true },
|
|
18
|
+
placement: { type: null, required: true },
|
|
19
|
+
leaving: { type: Boolean, required: true }
|
|
15
20
|
});
|
|
16
|
-
const emit = defineEmits(["remove"]);
|
|
21
|
+
const emit = defineEmits(["remove", "resize"]);
|
|
22
|
+
const rootElement = ref(null);
|
|
23
|
+
function setRootElement(instance) {
|
|
24
|
+
if (typeof HTMLElement === "undefined")
|
|
25
|
+
return;
|
|
26
|
+
const element = instance instanceof HTMLElement ? instance : instance?.$el;
|
|
27
|
+
if (element instanceof HTMLElement)
|
|
28
|
+
rootElement.value = element;
|
|
29
|
+
}
|
|
30
|
+
const placement = ref(props.placement);
|
|
31
|
+
watch(() => [props.placement, props.leaving], ([next, leaving]) => {
|
|
32
|
+
if (!leaving && next)
|
|
33
|
+
placement.value = next;
|
|
34
|
+
});
|
|
35
|
+
const clamped = computed(() => placement.value?.height !== void 0);
|
|
36
|
+
watch(rootElement, (element, _previous, onCleanup) => {
|
|
37
|
+
if (!element)
|
|
38
|
+
return;
|
|
39
|
+
const updateHeight = () => {
|
|
40
|
+
if (!clamped.value && !props.leaving)
|
|
41
|
+
emit("resize", element.offsetHeight);
|
|
42
|
+
};
|
|
43
|
+
updateHeight();
|
|
44
|
+
if (typeof ResizeObserver === "undefined")
|
|
45
|
+
return;
|
|
46
|
+
const observer = new ResizeObserver(updateHeight);
|
|
47
|
+
observer.observe(element);
|
|
48
|
+
onCleanup(() => observer.disconnect());
|
|
49
|
+
}, { flush: "post" });
|
|
17
50
|
const icons = useIcons();
|
|
18
51
|
const messages = useMessages();
|
|
19
52
|
const theme = useComponentTheme("toast", toastTheme);
|
|
20
53
|
const themeBindings = useThemeBindings();
|
|
21
54
|
const effectiveColor = computed(() => props.toast.color ? resolveRegisteredColorRole(props.toast.color, "info") : void 0);
|
|
22
|
-
const itemUi = computed(() => theme.value({
|
|
55
|
+
const itemUi = computed(() => theme.value({
|
|
56
|
+
color: effectiveColor.value,
|
|
57
|
+
expand: props.expand,
|
|
58
|
+
position: props.position
|
|
59
|
+
}));
|
|
23
60
|
const rootProps = computed(() => resolveSlot(itemUi.value.root, props.ui?.root));
|
|
61
|
+
const rootBindings = computed(() => ({
|
|
62
|
+
...rootProps.value,
|
|
63
|
+
"data-stack": placement.value?.state,
|
|
64
|
+
"style": [
|
|
65
|
+
themeBindings.value.style,
|
|
66
|
+
placement.value && { transform: placement.value.transform, height: placement.value.height, zIndex: placement.value.zIndex },
|
|
67
|
+
rootProps.value.style
|
|
68
|
+
]
|
|
69
|
+
}));
|
|
24
70
|
const iconProps = computed(() => resolveSlot(itemUi.value.icon, props.ui?.icon));
|
|
25
71
|
const titleProps = computed(() => resolveSlot(itemUi.value.title, props.ui?.title));
|
|
26
72
|
const descriptionProps = computed(() => resolveSlot(itemUi.value.description, props.ui?.description));
|
|
@@ -30,12 +76,13 @@ const iconName = computed(() => props.toast.icon ?? (effectiveColor.value && isF
|
|
|
30
76
|
|
|
31
77
|
<template>
|
|
32
78
|
<ToastRoot
|
|
33
|
-
:
|
|
79
|
+
:ref="setRootElement"
|
|
80
|
+
:duration="toast.duration ?? duration"
|
|
34
81
|
:data-selaras-theme="themeBindings['data-selaras-theme']"
|
|
35
82
|
:data-selaras-mode="themeBindings['data-selaras-mode']"
|
|
36
83
|
:data-selaras-color="effectiveColor"
|
|
37
|
-
:
|
|
38
|
-
v-bind="
|
|
84
|
+
:open="!leaving"
|
|
85
|
+
v-bind="rootBindings"
|
|
39
86
|
@update:open="(open) => !open && emit('remove', toast.id)"
|
|
40
87
|
>
|
|
41
88
|
<Icon v-if="iconName" :name="iconName" v-bind="iconProps" />
|
|
@@ -48,7 +95,7 @@ const iconName = computed(() => props.toast.icon ?? (effectiveColor.value && isF
|
|
|
48
95
|
</ToastDescription>
|
|
49
96
|
</div>
|
|
50
97
|
<ToastClose as-child>
|
|
51
|
-
<Button size="sm" variant="ghost" color="neutral" :icon="icons.close" :aria-label="messages.close" v-bind="closeProps" />
|
|
98
|
+
<Button size="sm" variant="ghost" :color="effectiveColor ?? 'neutral'" :icon="icons.close" :aria-label="messages.close" v-bind="closeProps" />
|
|
52
99
|
</ToastClose>
|
|
53
100
|
</ToastRoot>
|
|
54
101
|
</template>
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type { ToastThemeSlots } from '../theme/toast.js';
|
|
1
|
+
import type { ToastPosition, ToastThemeSlots } from '../theme/toast.js';
|
|
2
2
|
import type { UiProp } from '../utils/ui.js';
|
|
3
3
|
import type { ToastItem } from './programmatic-services.js';
|
|
4
|
+
import type { ToastStackItem } from './toast-stack.js';
|
|
4
5
|
type __VLS_Props = {
|
|
5
6
|
toast: ToastItem;
|
|
6
7
|
ui?: UiProp<ToastThemeSlots>;
|
|
8
|
+
duration: number;
|
|
9
|
+
expand: boolean;
|
|
10
|
+
position: ToastPosition;
|
|
11
|
+
placement: ToastStackItem | undefined;
|
|
12
|
+
leaving: boolean;
|
|
7
13
|
};
|
|
8
14
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
15
|
remove: (id: number) => any;
|
|
16
|
+
resize: (height: number) => any;
|
|
10
17
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
18
|
onRemove?: ((id: number) => any) | undefined;
|
|
19
|
+
onResize?: ((height: number) => any) | undefined;
|
|
12
20
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
21
|
declare const _default: typeof __VLS_export;
|
|
14
22
|
export default _default;
|
|
@@ -1,51 +1,52 @@
|
|
|
1
1
|
import type { ComputedRef } from 'vue';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SelectModelValue } from '../utils/select-contracts.js';
|
|
3
3
|
/** Erased runtime records for the shared implementation, not authoring types. */
|
|
4
|
-
export interface SelectOption<Value extends
|
|
4
|
+
export interface SelectOption<Value extends SelectModelValue = SelectModelValue> {
|
|
5
5
|
[key: string]: unknown;
|
|
6
|
-
/** The default option key. Custom `valueKey` fields use the same
|
|
6
|
+
/** The default option key. Custom `valueKey` fields use the same identity contract. */
|
|
7
7
|
value?: Value;
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
}
|
|
10
|
-
export interface SelectOptionGroup<Value extends
|
|
10
|
+
export interface SelectOptionGroup<Value extends SelectModelValue = SelectModelValue> {
|
|
11
11
|
label: string;
|
|
12
|
-
items: readonly SelectOption<Value>[];
|
|
12
|
+
items: readonly (Value | SelectOption<Value>)[];
|
|
13
13
|
}
|
|
14
|
-
export type SelectItems<Value extends
|
|
15
|
-
export declare function isOptionGroup
|
|
14
|
+
export type SelectItems<Value extends SelectModelValue = SelectModelValue> = readonly (Value | SelectOption<Value> | SelectOptionGroup<Value>)[];
|
|
15
|
+
export declare function isOptionGroup(entry: unknown): entry is SelectOptionGroup;
|
|
16
16
|
/** Flattens groups into a plain option list - groups lose their header when virtualized. */
|
|
17
|
-
export declare function flattenItems
|
|
17
|
+
export declare function flattenItems(items: SelectItems): (SelectModelValue | SelectOption)[];
|
|
18
18
|
interface SelectLikeProps {
|
|
19
19
|
items: SelectItems;
|
|
20
20
|
valueKey?: string;
|
|
21
21
|
labelKey?: string;
|
|
22
|
-
modelValue?:
|
|
22
|
+
modelValue?: SelectModelValue | SelectModelValue[];
|
|
23
23
|
multiple?: boolean;
|
|
24
24
|
displayMode?: 'comma' | 'chip';
|
|
25
25
|
maxChips?: number;
|
|
26
26
|
}
|
|
27
27
|
export interface ResolvedOption {
|
|
28
|
-
value:
|
|
28
|
+
value: SelectModelValue;
|
|
29
|
+
key: string | number;
|
|
29
30
|
label: string;
|
|
30
31
|
disabled: boolean;
|
|
31
|
-
raw: SelectOption | undefined;
|
|
32
|
+
raw: SelectOption | SelectModelValue | undefined;
|
|
32
33
|
}
|
|
33
34
|
export interface ResolvedItemOption extends ResolvedOption {
|
|
34
|
-
raw: SelectOption;
|
|
35
|
+
raw: SelectOption | SelectModelValue;
|
|
35
36
|
}
|
|
36
|
-
export declare function useComboboxSelect(props: SelectLikeProps, emit: (event: 'update:modelValue', value:
|
|
37
|
+
export declare function useComboboxSelect(props: SelectLikeProps, emit: (event: 'update:modelValue', value: SelectModelValue | SelectModelValue[] | undefined) => void, { creatable }?: {
|
|
37
38
|
creatable?: boolean;
|
|
38
39
|
}): {
|
|
39
40
|
flatOptions: ComputedRef<ResolvedItemOption[]>;
|
|
40
|
-
selectedValues: ComputedRef<
|
|
41
|
+
selectedValues: ComputedRef<SelectModelValue[]>;
|
|
41
42
|
selectedOptions: ComputedRef<ResolvedOption[]>;
|
|
42
43
|
visibleOptions: ComputedRef<ResolvedOption[]>;
|
|
43
44
|
overflowOptions: ComputedRef<ResolvedOption[]>;
|
|
44
45
|
commaText: ComputedRef<string>;
|
|
45
|
-
resolveOption: (value:
|
|
46
|
-
toOption: (raw: SelectOption) => ResolvedItemOption;
|
|
47
|
-
setValue: (value:
|
|
48
|
-
removeValue: (value:
|
|
46
|
+
resolveOption: (value: SelectModelValue) => ResolvedOption;
|
|
47
|
+
toOption: (raw: SelectOption | SelectModelValue) => ResolvedItemOption;
|
|
48
|
+
setValue: (value: SelectModelValue | SelectModelValue[] | undefined) => void;
|
|
49
|
+
removeValue: (value: SelectModelValue) => void;
|
|
49
50
|
hasMatchingOption: (text: string) => boolean;
|
|
50
51
|
commitCreatableText: (rawText: string) => boolean;
|
|
51
52
|
};
|
|
@@ -2,30 +2,42 @@ import { computed } from "vue";
|
|
|
2
2
|
function optionValue(value) {
|
|
3
3
|
if (typeof value === "string" || typeof value === "number" && Number.isFinite(value))
|
|
4
4
|
return value;
|
|
5
|
-
|
|
5
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value))
|
|
6
|
+
return value;
|
|
7
|
+
throw new TypeError("[selaras] Select option values must be strings, finite numbers, or objects.");
|
|
6
8
|
}
|
|
7
9
|
export function isOptionGroup(entry) {
|
|
8
|
-
return typeof entry.label === "string" && "items" in entry && Array.isArray(entry.items);
|
|
10
|
+
return typeof entry === "object" && entry !== null && !Array.isArray(entry) && "label" in entry && typeof entry.label === "string" && "items" in entry && Array.isArray(entry.items);
|
|
9
11
|
}
|
|
10
12
|
export function flattenItems(items) {
|
|
11
13
|
return items.flatMap((entry) => isOptionGroup(entry) ? entry.items : [entry]);
|
|
12
14
|
}
|
|
13
15
|
export function useComboboxSelect(props, emit, { creatable = false } = {}) {
|
|
14
|
-
const valueKey = computed(() => props.valueKey
|
|
16
|
+
const valueKey = computed(() => props.valueKey);
|
|
15
17
|
const labelKey = computed(() => props.labelKey ?? "label");
|
|
16
18
|
const flatOptions = computed(() => {
|
|
17
19
|
const identities = /* @__PURE__ */ new Set();
|
|
18
|
-
return flattenItems(props.items).map((raw) => {
|
|
19
|
-
|
|
20
|
+
return flattenItems(props.items).map((raw, index) => {
|
|
21
|
+
if (typeof raw === "string" || typeof raw === "number") {
|
|
22
|
+
const value2 = optionValue(raw);
|
|
23
|
+
if (identities.has(value2))
|
|
24
|
+
throw new TypeError(`[selaras] Select option identities must be unique across all groups. Duplicate value: ${typeof value2} ${JSON.stringify(value2)}.`);
|
|
25
|
+
identities.add(value2);
|
|
26
|
+
return { value: value2, key: `${typeof value2}:${String(value2)}`, label: String(value2), disabled: false, raw };
|
|
27
|
+
}
|
|
28
|
+
const option = raw;
|
|
29
|
+
const key = valueKey.value ?? (option.value !== void 0 ? "value" : void 0);
|
|
30
|
+
const value = optionValue(key === void 0 ? option : option[key]);
|
|
20
31
|
if (identities.has(value)) {
|
|
21
|
-
throw new TypeError(`[selaras] Select option identities must be unique across all groups. Duplicate ${
|
|
32
|
+
throw new TypeError(`[selaras] Select option identities must be unique across all groups. Duplicate ${key ?? "object identity"}: ${typeof value} ${JSON.stringify(value)}.`);
|
|
22
33
|
}
|
|
23
34
|
identities.add(value);
|
|
24
35
|
return {
|
|
25
36
|
value,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
key: typeof value === "object" ? `object:${index}` : `${typeof value}:${String(value)}`,
|
|
38
|
+
label: String(option[labelKey.value] ?? (typeof value === "object" ? "" : value)),
|
|
39
|
+
disabled: !!option.disabled,
|
|
40
|
+
raw: option
|
|
29
41
|
};
|
|
30
42
|
});
|
|
31
43
|
});
|
|
@@ -36,14 +48,24 @@ export function useComboboxSelect(props, emit, { creatable = false } = {}) {
|
|
|
36
48
|
return Array.isArray(v) ? v : [v];
|
|
37
49
|
});
|
|
38
50
|
function resolveOption(value) {
|
|
39
|
-
|
|
51
|
+
const option = flatOptions.value.find((o) => o.value === value);
|
|
52
|
+
if (option)
|
|
53
|
+
return option;
|
|
54
|
+
const label = typeof value === "object" ? value[labelKey.value] : value;
|
|
55
|
+
return { value, key: typeof value === "object" ? "missing-object" : `${typeof value}:${String(value)}`, label: String(label ?? ""), disabled: false, raw: void 0 };
|
|
40
56
|
}
|
|
41
57
|
function toOption(raw) {
|
|
58
|
+
if (typeof raw === "string" || typeof raw === "number")
|
|
59
|
+
return { value: optionValue(raw), key: `${typeof raw}:${String(raw)}`, label: String(raw), disabled: false, raw };
|
|
60
|
+
const option = raw;
|
|
61
|
+
const key = valueKey.value ?? (option.value !== void 0 ? "value" : void 0);
|
|
62
|
+
const value = optionValue(key === void 0 ? option : option[key]);
|
|
42
63
|
return {
|
|
43
|
-
value
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
value,
|
|
65
|
+
key: typeof value === "object" ? "object:unknown" : `${typeof value}:${String(value)}`,
|
|
66
|
+
label: String(option[labelKey.value] ?? (typeof value === "object" ? "" : value)),
|
|
67
|
+
disabled: !!option.disabled,
|
|
68
|
+
raw: option
|
|
47
69
|
};
|
|
48
70
|
}
|
|
49
71
|
const selectedOptions = computed(() => selectedValues.value.map(resolveOption));
|
|
@@ -67,7 +89,8 @@ export function useComboboxSelect(props, emit, { creatable = false } = {}) {
|
|
|
67
89
|
}
|
|
68
90
|
function commitCreatableText(rawText) {
|
|
69
91
|
const text = rawText.trim();
|
|
70
|
-
|
|
92
|
+
const lower = text.toLowerCase();
|
|
93
|
+
if (!creatable || !text || flatOptions.value.some((o) => String(o.value).toLowerCase() === lower || o.label.toLowerCase() === lower))
|
|
71
94
|
return false;
|
|
72
95
|
if (props.multiple) {
|
|
73
96
|
if (selectedValues.value.some((v) => typeof v === "string" && v.toLowerCase() === text.toLowerCase()))
|