@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.
Files changed (172) hide show
  1. package/README.md +4 -1
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +21 -6
  4. package/dist/runtime/components/AlertDialog.d.vue.ts +5 -3
  5. package/dist/runtime/components/AlertDialog.vue +17 -9
  6. package/dist/runtime/components/AlertDialog.vue.d.ts +5 -3
  7. package/dist/runtime/components/App.vue +2 -0
  8. package/dist/runtime/components/Autocomplete.d.vue.ts +2 -2
  9. package/dist/runtime/components/Autocomplete.vue +4 -2
  10. package/dist/runtime/components/Autocomplete.vue.d.ts +2 -2
  11. package/dist/runtime/components/Button.d.vue.ts +7 -5
  12. package/dist/runtime/components/Button.vue +14 -3
  13. package/dist/runtime/components/Button.vue.d.ts +7 -5
  14. package/dist/runtime/components/Calendar.d.vue.ts +69 -0
  15. package/dist/runtime/components/Calendar.vue +163 -0
  16. package/dist/runtime/components/Calendar.vue.d.ts +69 -0
  17. package/dist/runtime/components/Callout.vue +12 -1
  18. package/dist/runtime/components/CodeGroup.vue +13 -3
  19. package/dist/runtime/components/CodeTree.d.vue.ts +2 -0
  20. package/dist/runtime/components/CodeTree.vue +52 -1
  21. package/dist/runtime/components/CodeTree.vue.d.ts +2 -0
  22. package/dist/runtime/components/ColorModeSwitch.d.vue.ts +18 -0
  23. package/dist/runtime/components/ColorModeSwitch.vue +59 -0
  24. package/dist/runtime/components/ColorModeSwitch.vue.d.ts +18 -0
  25. package/dist/runtime/components/ColorPicker.d.vue.ts +8 -0
  26. package/dist/runtime/components/ColorPicker.vue +66 -45
  27. package/dist/runtime/components/ColorPicker.vue.d.ts +8 -0
  28. package/dist/runtime/components/Column.js +1 -1
  29. package/dist/runtime/components/CommandPalette.d.vue.ts +3 -1
  30. package/dist/runtime/components/CommandPalette.vue +5 -0
  31. package/dist/runtime/components/CommandPalette.vue.d.ts +3 -1
  32. package/dist/runtime/components/ConfirmRenderer.d.vue.ts +3 -0
  33. package/dist/runtime/components/ConfirmRenderer.vue +39 -0
  34. package/dist/runtime/components/ConfirmRenderer.vue.d.ts +3 -0
  35. package/dist/runtime/components/ContentNavigation.d.vue.ts +8 -1
  36. package/dist/runtime/components/ContentNavigation.vue +9 -2
  37. package/dist/runtime/components/ContentNavigation.vue.d.ts +8 -1
  38. package/dist/runtime/components/ContextMenu.d.vue.ts +8 -1
  39. package/dist/runtime/components/ContextMenu.vue +20 -6
  40. package/dist/runtime/components/ContextMenu.vue.d.ts +8 -1
  41. package/dist/runtime/components/DatePicker.d.vue.ts +10 -3
  42. package/dist/runtime/components/DatePicker.vue +24 -16
  43. package/dist/runtime/components/DatePicker.vue.d.ts +10 -3
  44. package/dist/runtime/components/Drawer.vue +3 -2
  45. package/dist/runtime/components/Dropdown.d.vue.ts +33 -6
  46. package/dist/runtime/components/Dropdown.vue +146 -12
  47. package/dist/runtime/components/Dropdown.vue.d.ts +33 -6
  48. package/dist/runtime/components/FileTree.d.vue.ts +2 -0
  49. package/dist/runtime/components/FileTree.vue +8 -4
  50. package/dist/runtime/components/FileTree.vue.d.ts +2 -0
  51. package/dist/runtime/components/FormField.d.vue.ts +4 -0
  52. package/dist/runtime/components/FormField.vue +19 -4
  53. package/dist/runtime/components/FormField.vue.d.ts +4 -0
  54. package/dist/runtime/components/Input.vue +3 -2
  55. package/dist/runtime/components/Kbd.vue +12 -2
  56. package/dist/runtime/components/Modal.vue +3 -2
  57. package/dist/runtime/components/NavigationMenu.d.vue.ts +10 -10
  58. package/dist/runtime/components/NavigationMenu.vue +13 -9
  59. package/dist/runtime/components/NavigationMenu.vue.d.ts +10 -10
  60. package/dist/runtime/components/NavigationMenuAccordionItem.vue +5 -1
  61. package/dist/runtime/components/NavigationMenuFlyoutList.vue +7 -4
  62. package/dist/runtime/components/Popover.d.vue.ts +8 -2
  63. package/dist/runtime/components/Popover.vue +13 -6
  64. package/dist/runtime/components/Popover.vue.d.ts +8 -2
  65. package/dist/runtime/components/ProsePre.d.vue.ts +2 -0
  66. package/dist/runtime/components/ProsePre.vue +2 -1
  67. package/dist/runtime/components/ProsePre.vue.d.ts +2 -0
  68. package/dist/runtime/components/Select.d.vue.ts +8 -4
  69. package/dist/runtime/components/Select.vue +4 -2
  70. package/dist/runtime/components/Select.vue.d.ts +8 -4
  71. package/dist/runtime/components/Slideover.vue +3 -2
  72. package/dist/runtime/components/SplitterPanel.d.vue.ts +2 -2
  73. package/dist/runtime/components/SplitterPanel.vue.d.ts +2 -2
  74. package/dist/runtime/components/Table.vue +95 -26
  75. package/dist/runtime/components/Tabs.d.vue.ts +44 -4
  76. package/dist/runtime/components/Tabs.vue +171 -18
  77. package/dist/runtime/components/Tabs.vue.d.ts +44 -4
  78. package/dist/runtime/components/Textarea.vue +3 -2
  79. package/dist/runtime/components/Timeline.d.vue.ts +19 -0
  80. package/dist/runtime/components/Timeline.vue +99 -0
  81. package/dist/runtime/components/Timeline.vue.d.ts +19 -0
  82. package/dist/runtime/components/Toast.d.vue.ts +10 -1
  83. package/dist/runtime/components/Toast.vue +94 -8
  84. package/dist/runtime/components/Toast.vue.d.ts +10 -1
  85. package/dist/runtime/components/Tooltip.d.vue.ts +8 -2
  86. package/dist/runtime/components/Tooltip.vue +13 -6
  87. package/dist/runtime/components/Tooltip.vue.d.ts +8 -2
  88. package/dist/runtime/composables/use-confirm.d.ts +14 -0
  89. package/dist/runtime/composables/use-confirm.js +28 -0
  90. package/dist/runtime/composables/use-form-field.d.ts +1 -0
  91. package/dist/runtime/composables/use-table.d.ts +3 -0
  92. package/dist/runtime/composables/use-table.js +10 -4
  93. package/dist/runtime/composables/use-toast.js +5 -1
  94. package/dist/runtime/directives/hotkey.d.ts +13 -0
  95. package/dist/runtime/directives/hotkey.js +107 -0
  96. package/dist/runtime/directives/index.d.ts +2 -0
  97. package/dist/runtime/directives/index.js +2 -0
  98. package/dist/runtime/directives/mask.d.ts +30 -0
  99. package/dist/runtime/directives/mask.js +165 -0
  100. package/dist/runtime/internal/ComboboxSelectBase.d.vue.ts +41 -36
  101. package/dist/runtime/internal/ComboboxSelectBase.vue +119 -26
  102. package/dist/runtime/internal/ComboboxSelectBase.vue.d.ts +41 -36
  103. package/dist/runtime/internal/ComboboxSelectBody.d.vue.ts +23 -17
  104. package/dist/runtime/internal/ComboboxSelectBody.vue +50 -11
  105. package/dist/runtime/internal/ComboboxSelectBody.vue.d.ts +23 -17
  106. package/dist/runtime/internal/DatePickerCalendarBody.vue +1 -1
  107. package/dist/runtime/internal/DatePickerRangeCalendarBody.vue +1 -1
  108. package/dist/runtime/internal/ShortcutHint.d.vue.ts +6 -0
  109. package/dist/runtime/internal/ShortcutHint.vue +13 -0
  110. package/dist/runtime/internal/ShortcutHint.vue.d.ts +6 -0
  111. package/dist/runtime/internal/ToastItemRenderer.d.vue.ts +9 -1
  112. package/dist/runtime/internal/ToastItemRenderer.vue +55 -8
  113. package/dist/runtime/internal/ToastItemRenderer.vue.d.ts +9 -1
  114. package/dist/runtime/internal/combobox-select.d.ts +19 -18
  115. package/dist/runtime/internal/combobox-select.js +38 -15
  116. package/dist/runtime/internal/programmatic-services.d.ts +13 -0
  117. package/dist/runtime/internal/programmatic-services.js +9 -0
  118. package/dist/runtime/internal/toast-stack.d.ts +36 -0
  119. package/dist/runtime/internal/toast-stack.js +36 -0
  120. package/dist/runtime/structural.css +1 -1
  121. package/dist/runtime/table.d.ts +1 -1
  122. package/dist/runtime/theme/alert-dialog.js +1 -1
  123. package/dist/runtime/theme/badge.d.ts +9 -0
  124. package/dist/runtime/theme/badge.js +2 -1
  125. package/dist/runtime/theme/button.d.ts +18 -0
  126. package/dist/runtime/theme/button.js +4 -1
  127. package/dist/runtime/theme/calendar.d.ts +86 -0
  128. package/dist/runtime/theme/calendar.js +19 -0
  129. package/dist/runtime/theme/callout.d.ts +0 -12
  130. package/dist/runtime/theme/callout.js +8 -8
  131. package/dist/runtime/theme/code-tree.js +1 -1
  132. package/dist/runtime/theme/command-palette.js +1 -1
  133. package/dist/runtime/theme/content-navigation.d.ts +3 -0
  134. package/dist/runtime/theme/content-navigation.js +1 -0
  135. package/dist/runtime/theme/drawer.js +1 -1
  136. package/dist/runtime/theme/dropdown.d.ts +21 -0
  137. package/dist/runtime/theme/dropdown.js +15 -2
  138. package/dist/runtime/theme/file-tree.js +1 -1
  139. package/dist/runtime/theme/form-field.d.ts +18 -0
  140. package/dist/runtime/theme/form-field.js +6 -1
  141. package/dist/runtime/theme/modal.js +1 -1
  142. package/dist/runtime/theme/slideover.js +1 -1
  143. package/dist/runtime/theme/table.d.ts +27 -0
  144. package/dist/runtime/theme/table.js +11 -2
  145. package/dist/runtime/theme/tabs.d.ts +87 -3
  146. package/dist/runtime/theme/tabs.js +46 -22
  147. package/dist/runtime/theme/timeline.d.ts +251 -0
  148. package/dist/runtime/theme/timeline.js +84 -0
  149. package/dist/runtime/theme/toast.d.ts +92 -0
  150. package/dist/runtime/theme/toast.js +29 -7
  151. package/dist/runtime/theme-config.d.ts +13 -2
  152. package/dist/runtime/types/index.d.ts +10 -2
  153. package/dist/runtime/utils/arrow.d.ts +21 -0
  154. package/dist/runtime/utils/arrow.js +10 -0
  155. package/dist/runtime/utils/autocomplete-contracts.d.ts +4 -4
  156. package/dist/runtime/utils/file-icons.js +3 -0
  157. package/dist/runtime/utils/icons.d.ts +2 -0
  158. package/dist/runtime/utils/icons.js +2 -0
  159. package/dist/runtime/utils/messages.d.ts +7 -0
  160. package/dist/runtime/utils/messages.js +7 -0
  161. package/dist/runtime/utils/navigation-menu.d.ts +7 -0
  162. package/dist/runtime/utils/navigation-menu.js +3 -0
  163. package/dist/runtime/utils/overlay.d.ts +17 -0
  164. package/dist/runtime/utils/overlay.js +7 -0
  165. package/dist/runtime/utils/select-contracts.d.ts +25 -11
  166. package/dist/runtime/utils/table-columns.js +1 -1
  167. package/dist/runtime/utils/table-contracts.d.ts +9 -1
  168. package/dist/runtime/utils/timeline-contracts.d.ts +42 -0
  169. package/dist/runtime/utils/timeline-contracts.js +0 -0
  170. package/dist/runtime/utils/ui.d.ts +11 -0
  171. package/dist/runtime/utils/ui.js +54 -1
  172. 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: {}, __VLS_37: {}, __VLS_57: {
34
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
35
- }, __VLS_82: {
36
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
37
- }, __VLS_90: {
38
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
39
- }, __VLS_109: {
40
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
41
- }, __VLS_122: {};
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 __VLS_37) => any;
55
+ 'empty-filter'?: (props: typeof __VLS_31) => any;
52
56
  } & {
53
- item?: (props: typeof __VLS_57) => any;
57
+ 'empty-filter'?: (props: typeof __VLS_39) => any;
54
58
  } & {
55
- group?: (props: typeof __VLS_82) => any;
59
+ item?: (props: typeof __VLS_61) => any;
56
60
  } & {
57
- item?: (props: typeof __VLS_90) => any;
61
+ group?: (props: typeof __VLS_92) => any;
58
62
  } & {
59
- item?: (props: typeof __VLS_109) => any;
63
+ item?: (props: typeof __VLS_102) => any;
60
64
  } & {
61
- footer?: (props: typeof __VLS_122) => any;
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 virtualOptions = computed(() => props.listbox ? visibleOptions.value : props.virtualizedOptions);
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
- <ComboboxEmpty v-else-if="!listbox" v-bind="emptyProps">
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
- <slot name="item" :item="option.raw">
156
+ <template v-if="option.raw === void 0">
128
157
  {{ option.label }}
129
- </slot>
130
- <component :is="primitives.indicator" v-bind="itemIndicatorProps">
131
- <Icon :name="icons.check" class="size-4" />
132
- </component>
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.value"
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: {}, __VLS_37: {}, __VLS_57: {
34
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
35
- }, __VLS_82: {
36
- group: import("./combobox-select.js").SelectOptionGroup<import("../utils/select-contracts.js").SelectValue>;
37
- }, __VLS_90: {
38
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
39
- }, __VLS_109: {
40
- item: SelectOption<import("../utils/select-contracts.js").SelectValue>;
41
- }, __VLS_122: {};
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 __VLS_37) => any;
55
+ 'empty-filter'?: (props: typeof __VLS_31) => any;
52
56
  } & {
53
- item?: (props: typeof __VLS_57) => any;
57
+ 'empty-filter'?: (props: typeof __VLS_39) => any;
54
58
  } & {
55
- group?: (props: typeof __VLS_82) => any;
59
+ item?: (props: typeof __VLS_61) => any;
56
60
  } & {
57
- item?: (props: typeof __VLS_90) => any;
61
+ group?: (props: typeof __VLS_92) => any;
58
62
  } & {
59
- item?: (props: typeof __VLS_109) => any;
63
+ item?: (props: typeof __VLS_102) => any;
60
64
  } & {
61
- footer?: (props: typeof __VLS_122) => any;
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="day" v-bind="headCellProps">
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="day" v-bind="headCellProps">
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({ color: effectiveColor.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
- :duration="toast.duration ?? 5e3"
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
- :style="themeBindings.style"
38
- v-bind="rootProps"
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 { SelectValue } from '../utils/select-contracts.js';
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 SelectValue = SelectValue> {
4
+ export interface SelectOption<Value extends SelectModelValue = SelectModelValue> {
5
5
  [key: string]: unknown;
6
- /** The default option key. Custom `valueKey` fields use the same primitive contract. */
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 SelectValue = SelectValue> {
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 SelectValue = SelectValue> = readonly (SelectOption<Value> | SelectOptionGroup<Value>)[];
15
- export declare function isOptionGroup<Value extends SelectValue = SelectValue>(entry: SelectOption<Value> | SelectOptionGroup<Value>): entry is SelectOptionGroup<Value>;
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<Value extends SelectValue = SelectValue>(items: SelectItems<Value>): SelectOption<Value>[];
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?: SelectValue | SelectValue[];
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: SelectValue;
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: SelectValue | SelectValue[] | undefined) => void, { creatable }?: {
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<SelectValue[]>;
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: SelectValue) => ResolvedOption;
46
- toOption: (raw: SelectOption) => ResolvedItemOption;
47
- setValue: (value: SelectValue | SelectValue[] | undefined) => void;
48
- removeValue: (value: SelectValue) => void;
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
- throw new TypeError("[selaras] Select option values must be strings or finite numbers.");
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 ?? "value");
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
- const value = optionValue(raw[valueKey.value]);
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 ${valueKey.value}: ${typeof value} ${JSON.stringify(value)}.`);
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
- label: String(raw[labelKey.value] ?? value),
27
- disabled: !!raw.disabled,
28
- raw
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
- return flatOptions.value.find((o) => o.value === value) ?? { value, label: String(value), disabled: false, raw: void 0 };
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: optionValue(raw[valueKey.value]),
44
- label: String(raw[labelKey.value] ?? raw[valueKey.value] ?? ""),
45
- disabled: !!raw.disabled,
46
- raw
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
- if (!creatable || !text || hasMatchingOption(text))
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()))