@bitrix24/b24ui-nuxt 2.1.2 → 2.1.4

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 (144) hide show
  1. package/cli/templates.mjs +2 -2
  2. package/dist/meta.d.mts +1321 -192
  3. package/dist/meta.mjs +1321 -192
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +1 -1
  6. package/dist/runtime/components/Accordion.vue +9 -4
  7. package/dist/runtime/components/Advice.vue +9 -5
  8. package/dist/runtime/components/Alert.vue +9 -7
  9. package/dist/runtime/components/Avatar.vue +4 -2
  10. package/dist/runtime/components/AvatarGroup.vue +3 -3
  11. package/dist/runtime/components/Badge.vue +6 -1
  12. package/dist/runtime/components/Banner.vue +9 -8
  13. package/dist/runtime/components/Breadcrumb.vue +9 -4
  14. package/dist/runtime/components/Button.vue +12 -9
  15. package/dist/runtime/components/Calendar.vue +11 -5
  16. package/dist/runtime/components/Card.vue +4 -4
  17. package/dist/runtime/components/ChatMessage.vue +7 -5
  18. package/dist/runtime/components/ChatMessages.vue +4 -2
  19. package/dist/runtime/components/ChatPalette.vue +3 -3
  20. package/dist/runtime/components/ChatPrompt.vue +4 -3
  21. package/dist/runtime/components/ChatPromptSubmit.vue +1 -0
  22. package/dist/runtime/components/Checkbox.vue +9 -7
  23. package/dist/runtime/components/CheckboxGroup.vue +4 -2
  24. package/dist/runtime/components/Chip.vue +3 -0
  25. package/dist/runtime/components/Collapsible.vue +2 -2
  26. package/dist/runtime/components/ColorPicker.vue +7 -3
  27. package/dist/runtime/components/CommandPalette.vue +68 -23
  28. package/dist/runtime/components/ContextMenu.vue +1 -0
  29. package/dist/runtime/components/ContextMenuContent.vue +19 -6
  30. package/dist/runtime/components/Countdown.vue +8 -1
  31. package/dist/runtime/components/DashboardSearch.vue +1 -0
  32. package/dist/runtime/components/DashboardSearchButton.vue +2 -1
  33. package/dist/runtime/components/DescriptionList.vue +12 -4
  34. package/dist/runtime/components/DropdownMenu.vue +2 -1
  35. package/dist/runtime/components/DropdownMenuContent.vue +21 -7
  36. package/dist/runtime/components/Empty.vue +9 -8
  37. package/dist/runtime/components/Error.vue +5 -5
  38. package/dist/runtime/components/FileUpload.vue +15 -8
  39. package/dist/runtime/components/FormField.vue +11 -11
  40. package/dist/runtime/components/Input.vue +8 -3
  41. package/dist/runtime/components/InputDate.vue +9 -2
  42. package/dist/runtime/components/InputMenu.vue +50 -32
  43. package/dist/runtime/components/InputNumber.vue +5 -2
  44. package/dist/runtime/components/InputTags.vue +12 -3
  45. package/dist/runtime/components/InputTime.vue +8 -2
  46. package/dist/runtime/components/Kbd.vue +1 -1
  47. package/dist/runtime/components/Modal.vue +11 -8
  48. package/dist/runtime/components/Navbar.vue +1 -1
  49. package/dist/runtime/components/NavbarDivider.vue +1 -1
  50. package/dist/runtime/components/NavbarSection.vue +2 -1
  51. package/dist/runtime/components/NavbarSpacer.vue +1 -1
  52. package/dist/runtime/components/NavigationMenu.vue +43 -12
  53. package/dist/runtime/components/PageCard.vue +10 -9
  54. package/dist/runtime/components/PageLinks.vue +9 -7
  55. package/dist/runtime/components/Pagination.vue +8 -8
  56. package/dist/runtime/components/PinInput.vue +2 -0
  57. package/dist/runtime/components/Popover.vue +2 -2
  58. package/dist/runtime/components/Progress.vue +6 -6
  59. package/dist/runtime/components/RadioGroup.d.vue.ts +2 -2
  60. package/dist/runtime/components/RadioGroup.vue +10 -4
  61. package/dist/runtime/components/RadioGroup.vue.d.ts +2 -2
  62. package/dist/runtime/components/Range.vue +5 -4
  63. package/dist/runtime/components/Select.vue +25 -11
  64. package/dist/runtime/components/SelectMenu.vue +47 -25
  65. package/dist/runtime/components/Separator.vue +7 -7
  66. package/dist/runtime/components/Sidebar.vue +1 -1
  67. package/dist/runtime/components/SidebarBody.vue +1 -1
  68. package/dist/runtime/components/SidebarFooter.vue +1 -1
  69. package/dist/runtime/components/SidebarHeader.vue +1 -1
  70. package/dist/runtime/components/SidebarHeading.vue +1 -1
  71. package/dist/runtime/components/SidebarLayout.vue +18 -13
  72. package/dist/runtime/components/SidebarSection.vue +2 -1
  73. package/dist/runtime/components/SidebarSpacer.vue +1 -1
  74. package/dist/runtime/components/Skeleton.vue +1 -0
  75. package/dist/runtime/components/Slideover.vue +10 -7
  76. package/dist/runtime/components/Stepper.vue +12 -9
  77. package/dist/runtime/components/Switch.vue +10 -6
  78. package/dist/runtime/components/Table.d.vue.ts +2 -2
  79. package/dist/runtime/components/Table.vue +33 -15
  80. package/dist/runtime/components/Table.vue.d.ts +2 -2
  81. package/dist/runtime/components/TableWrapper.vue +1 -0
  82. package/dist/runtime/components/Tabs.d.vue.ts +3 -3
  83. package/dist/runtime/components/Tabs.vue +24 -15
  84. package/dist/runtime/components/Tabs.vue.d.ts +3 -3
  85. package/dist/runtime/components/Textarea.vue +8 -3
  86. package/dist/runtime/components/Timeline.vue +9 -6
  87. package/dist/runtime/components/Toast.vue +10 -6
  88. package/dist/runtime/components/Toaster.vue +2 -0
  89. package/dist/runtime/components/Tooltip.vue +4 -4
  90. package/dist/runtime/components/User.vue +13 -6
  91. package/dist/runtime/components/color-mode/ColorModeButton.d.vue.ts +2 -9
  92. package/dist/runtime/components/color-mode/ColorModeButton.vue +8 -13
  93. package/dist/runtime/components/color-mode/ColorModeButton.vue.d.ts +2 -9
  94. package/dist/runtime/components/content/ContentSearch.vue +59 -68
  95. package/dist/runtime/components/content/ContentSearchButton.vue +2 -1
  96. package/dist/runtime/components/content/ContentSurround.vue +6 -4
  97. package/dist/runtime/components/content/ContentToc.vue +13 -10
  98. package/dist/runtime/components/prose/A.vue +1 -1
  99. package/dist/runtime/components/prose/Blockquote.vue +1 -1
  100. package/dist/runtime/components/prose/Callout.vue +4 -1
  101. package/dist/runtime/components/prose/Card.vue +5 -3
  102. package/dist/runtime/components/prose/Code.vue +1 -0
  103. package/dist/runtime/components/prose/CodeCollapse.vue +3 -2
  104. package/dist/runtime/components/prose/CodeGroup.vue +6 -6
  105. package/dist/runtime/components/prose/CodePreview.vue +3 -3
  106. package/dist/runtime/components/prose/Collapsible.vue +3 -2
  107. package/dist/runtime/components/prose/Em.vue +1 -1
  108. package/dist/runtime/components/prose/Field.vue +7 -7
  109. package/dist/runtime/components/prose/H1.vue +1 -0
  110. package/dist/runtime/components/prose/H2.vue +4 -2
  111. package/dist/runtime/components/prose/H3.vue +4 -2
  112. package/dist/runtime/components/prose/H4.vue +4 -2
  113. package/dist/runtime/components/prose/H5.vue +1 -0
  114. package/dist/runtime/components/prose/H6.vue +1 -0
  115. package/dist/runtime/components/prose/Hr.vue +1 -1
  116. package/dist/runtime/components/prose/Img.vue +4 -0
  117. package/dist/runtime/components/prose/Li.vue +1 -1
  118. package/dist/runtime/components/prose/Ol.vue +1 -1
  119. package/dist/runtime/components/prose/P.vue +1 -1
  120. package/dist/runtime/components/prose/Pre.vue +6 -5
  121. package/dist/runtime/components/prose/Strong.vue +1 -1
  122. package/dist/runtime/components/prose/Table.d.vue.ts +0 -3
  123. package/dist/runtime/components/prose/Table.vue +2 -1
  124. package/dist/runtime/components/prose/Table.vue.d.ts +0 -3
  125. package/dist/runtime/components/prose/Tbody.vue +1 -1
  126. package/dist/runtime/components/prose/Td.vue +1 -1
  127. package/dist/runtime/components/prose/Th.vue +1 -1
  128. package/dist/runtime/components/prose/Thead.vue +1 -1
  129. package/dist/runtime/components/prose/Tr.vue +1 -1
  130. package/dist/runtime/components/prose/Ul.vue +1 -1
  131. package/dist/runtime/composables/useContentSearch.d.ts +5 -0
  132. package/dist/runtime/composables/useContentSearch.js +30 -1
  133. package/dist/runtime/inertia/stubs.js +1 -1
  134. package/dist/runtime/types/index.d.ts +3 -0
  135. package/dist/runtime/types/index.js +3 -0
  136. package/dist/runtime/utils/virtualizer.d.ts +6 -0
  137. package/dist/runtime/utils/virtualizer.js +32 -0
  138. package/dist/shared/{b24ui-nuxt.B9uYyQGR.mjs → b24ui-nuxt.Bs0V9FLV.mjs} +25 -19
  139. package/dist/unplugin.mjs +1 -1
  140. package/dist/vite.mjs +1 -1
  141. package/package.json +11 -11
  142. package/dist/runtime/vue/components/color-mode/ColorModeButton.d.vue.ts +0 -12
  143. package/dist/runtime/vue/components/color-mode/ColorModeButton.vue +0 -83
  144. package/dist/runtime/vue/components/color-mode/ColorModeButton.vue.d.ts +0 -12
@@ -57,8 +57,8 @@ defineExpose({
57
57
  </script>
58
58
 
59
59
  <template>
60
- <Primitive :as="as" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })" @submit.prevent="submit">
61
- <div v-if="!!slots.header" :class="b24ui.header({ class: props.b24ui?.header })">
60
+ <Primitive :as="as" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })" @submit.prevent="submit">
61
+ <div v-if="!!slots.header" data-slot="header" :class="b24ui.header({ class: props.b24ui?.header })">
62
62
  <slot name="header" />
63
63
  </div>
64
64
 
@@ -70,6 +70,7 @@ defineExpose({
70
70
  no-border
71
71
  v-bind="{ ...textareaProps, ...$attrs }"
72
72
  :b24ui="transformUI(omit(b24ui, ['root', 'body', 'header', 'footer']), props.b24ui)"
73
+ data-slot="body"
73
74
  :class="b24ui.body({ class: props.b24ui?.body })"
74
75
  @keydown.enter.exact.prevent="submit"
75
76
  @keydown.esc="blur"
@@ -79,7 +80,7 @@ defineExpose({
79
80
  </template>
80
81
  </B24Textarea>
81
82
 
82
- <div :class="b24ui.footer({ class: props.b24ui?.footer })">
83
+ <div data-slot="footer" :class="b24ui.footer({ class: props.b24ui?.footer })">
83
84
  <slot name="footer" />
84
85
  <slot name="default" :b24ui="transformUI(omit(b24ui, ['root', 'body', 'header', 'footer']), props.b24ui)" />
85
86
  </div>
@@ -112,6 +112,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.chatPro
112
112
  ...$attrs
113
113
  }"
114
114
  :aria-label="t('chatPromptSubmit.label')"
115
+ data-slot="base"
115
116
  :class="b24ui.base({ class: [props.b24ui?.base, props.class] })"
116
117
  :b24ui="transformUI(b24ui, props.b24ui)"
117
118
  >
@@ -53,38 +53,40 @@ function onUpdate(value) {
53
53
  </script>
54
54
 
55
55
  <template>
56
- <Primitive :as="!variant || variant === 'list' ? as : Label" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
57
- <div :class="b24ui.container({ class: props.b24ui?.container })">
56
+ <Primitive :as="!variant || variant === 'list' ? as : Label" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
57
+ <div data-slot="container" :class="b24ui.container({ class: props.b24ui?.container })">
58
58
  <CheckboxRoot
59
59
  :id="id"
60
60
  v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
61
61
  v-model="modelValue"
62
62
  :name="name"
63
63
  :disabled="disabled"
64
+ data-slot="base"
64
65
  :class="b24ui.base({ class: props.b24ui?.base })"
65
66
  @update:model-value="onUpdate"
66
67
  >
67
68
  <template #default="{ modelValue }">
68
- <CheckboxIndicator :class="b24ui.indicator({ class: props.b24ui?.indicator })">
69
- <Minus20Icon v-if="modelValue === 'indeterminate'" :class="b24ui.icon({ class: props.b24ui?.icon })" />
70
- <CheckIcon v-else :class="b24ui.icon({ class: props.b24ui?.icon })" />
69
+ <CheckboxIndicator data-slot="indicator" :class="b24ui.indicator({ class: props.b24ui?.indicator })">
70
+ <Minus20Icon v-if="modelValue === 'indeterminate'" data-slot="icon" :class="b24ui.icon({ class: props.b24ui?.icon })" />
71
+ <CheckIcon v-else data-slot="icon" :class="b24ui.icon({ class: props.b24ui?.icon })" />
71
72
  </CheckboxIndicator>
72
73
  </template>
73
74
  </CheckboxRoot>
74
75
  </div>
75
76
 
76
- <div v-if="label || !!slots.label || (description || !!slots.description)" :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
77
+ <div v-if="label || !!slots.label || (description || !!slots.description)" data-slot="wrapper" :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
77
78
  <component
78
79
  :is="!variant || variant === 'list' ? Label : 'p'"
79
80
  v-if="label || !!slots.label"
80
81
  :for="id"
82
+ data-slot="label"
81
83
  :class="b24ui.label({ class: props.b24ui?.label })"
82
84
  >
83
85
  <slot name="label" :label="label">
84
86
  {{ label }}
85
87
  </slot>
86
88
  </component>
87
- <p v-if="description || !!slots.description" :class="b24ui.description({ class: props.b24ui?.description })">
89
+ <p v-if="description || !!slots.description" data-slot="description" :class="b24ui.description({ class: props.b24ui?.description })">
88
90
  <slot name="description" :description="description">
89
91
  {{ description }}
90
92
  </slot>
@@ -93,11 +93,12 @@ function onUpdate(value) {
93
93
  v-bind="rootProps"
94
94
  :name="name"
95
95
  :disabled="disabled"
96
+ data-slot="root"
96
97
  :class="b24ui.root({ class: [props.b24ui?.root, props.class] })"
97
98
  @update:model-value="onUpdate"
98
99
  >
99
- <fieldset :class="b24ui.fieldset({ class: props.b24ui?.fieldset })" v-bind="ariaAttrs">
100
- <legend v-if="legend || !!slots.legend" :class="b24ui.legend({ class: props.b24ui?.legend })">
100
+ <fieldset data-slot="fieldset" :class="b24ui.fieldset({ class: props.b24ui?.fieldset })" v-bind="ariaAttrs">
101
+ <legend v-if="legend || !!slots.legend" data-slot="legend" :class="b24ui.legend({ class: props.b24ui?.legend })">
101
102
  <slot name="legend">
102
103
  {{ legend }}
103
104
  </slot>
@@ -111,6 +112,7 @@ function onUpdate(value) {
111
112
  :name="name"
112
113
  :disabled="item.disabled || disabled"
113
114
  :b24ui="{ ...props.b24ui ? omit(props.b24ui, ['root']) : void 0, ...item.b24ui || {} }"
115
+ data-slot="item"
114
116
  :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class] })"
115
117
  >
116
118
  <template v-for="(_, name) in getProxySlots()" #[name]>
@@ -44,6 +44,7 @@ const value = computed(() => {
44
44
  <template>
45
45
  <Primitive
46
46
  :as="as"
47
+ data-slot="root"
47
48
  :class="b24ui.root({ class: [props.b24ui?.root, props.class] })"
48
49
  >
49
50
  <Slot v-bind="$attrs">
@@ -52,6 +53,7 @@ const value = computed(() => {
52
53
 
53
54
  <span
54
55
  v-if="show"
56
+ data-slot="base"
55
57
  :class="b24ui.base({ class: props.b24ui?.base })"
56
58
  :data-value="value"
57
59
  >
@@ -61,6 +63,7 @@ const value = computed(() => {
61
63
  <slot name="trailing">
62
64
  <Component
63
65
  :is="trailingIcon"
66
+ data-slot="trailingIcon"
64
67
  :class="b24ui.trailingIcon({ class: props.b24ui?.trailingIcon })"
65
68
  />
66
69
  </slot>
@@ -25,12 +25,12 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.collaps
25
25
  </script>
26
26
 
27
27
  <template>
28
- <CollapsibleRoot v-slot="{ open }" v-bind="rootProps" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
28
+ <CollapsibleRoot v-slot="{ open }" v-bind="rootProps" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
29
29
  <CollapsibleTrigger v-if="!!slots.default" as-child>
30
30
  <slot :open="open" />
31
31
  </CollapsibleTrigger>
32
32
 
33
- <CollapsibleContent :class="b24ui.content({ class: props.b24ui?.content })">
33
+ <CollapsibleContent data-slot="content" :class="b24ui.content({ class: props.b24ui?.content })">
34
34
  <slot name="content" />
35
35
  </CollapsibleContent>
36
36
  </CollapsibleRoot>
@@ -178,16 +178,18 @@ const trackThumbStyle = computed(() => ({
178
178
  </script>
179
179
 
180
180
  <template>
181
- <Primitive :as="as" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })" :data-disabled="disabled ? true : void 0">
182
- <div :class="b24ui.picker({ class: props.b24ui?.picker })">
181
+ <Primitive :as="as" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })" :data-disabled="disabled ? true : void 0">
182
+ <div data-slot="picker" :class="b24ui.picker({ class: props.b24ui?.picker })">
183
183
  <div
184
184
  ref="selectorRef"
185
+ data-slot="selector"
185
186
  :class="b24ui.selector({ class: props.b24ui?.selector })"
186
187
  :style="selectorStyle"
187
188
  >
188
- <div :class="b24ui.selectorBackground({ class: props.b24ui?.selectorBackground })" data-color-picker-background>
189
+ <div data-slot="selectorBackground" :class="b24ui.selectorBackground({ class: props.b24ui?.selectorBackground })" data-color-picker-background>
189
190
  <div
190
191
  ref="selectorThumbRef"
192
+ data-slot="selectorThumb"
191
193
  :class="b24ui.selectorThumb({ class: props.b24ui?.selectorThumb })"
192
194
  :style="selectorThumbStyle"
193
195
  :data-disabled="disabled ? true : void 0"
@@ -196,11 +198,13 @@ const trackThumbStyle = computed(() => ({
196
198
  </div>
197
199
  <div
198
200
  ref="trackRef"
201
+ data-slot="track"
199
202
  :class="b24ui.track({ class: props.b24ui?.track })"
200
203
  data-color-picker-track
201
204
  >
202
205
  <div
203
206
  ref="trackThumbRef"
207
+ data-slot="trackThumb"
204
208
  :class="b24ui.trackThumb({ class: props.b24ui?.trackThumb })"
205
209
  :style="trackThumbStyle"
206
210
  :data-disabled="disabled ? true : void 0"
@@ -6,14 +6,15 @@ import theme from "#build/b24ui/command-palette";
6
6
  import { computed, ref, useTemplateRef, toRef } from "vue";
7
7
  import { ListboxRoot, ListboxFilter, ListboxContent, ListboxGroup, ListboxGroupLabel, ListboxVirtualizer, ListboxItem, ListboxItemIndicator, useForwardProps, useForwardPropsEmits } from "reka-ui";
8
8
  import { defu } from "defu";
9
- import { reactivePick, createReusableTemplate } from "@vueuse/core";
9
+ import { reactivePick, createReusableTemplate, refThrottled } from "@vueuse/core";
10
10
  import { useFuse } from "@vueuse/integrations/useFuse";
11
11
  import { useAppConfig } from "#imports";
12
12
  import { useLocale } from "../composables/useLocale";
13
13
  import { omit, get } from "../utils";
14
- import { tv } from "../utils/tv";
15
14
  import { highlight } from "../utils/fuse";
16
15
  import { pickLinkProps } from "../utils/link";
16
+ import { getEstimateSize } from "../utils/virtualizer";
17
+ import { tv } from "../utils/tv";
17
18
  import icons from "../dictionary/icons";
18
19
  import B24Avatar from "./Avatar.vue";
19
20
  import B24Button from "./Button.vue";
@@ -58,7 +59,12 @@ const { t } = useLocale();
58
59
  const appConfig = useAppConfig();
59
60
  const rootProps = useForwardPropsEmits(reactivePick(props, "as", "disabled", "multiple", "modelValue", "defaultValue", "highlightOnHover"), emits);
60
61
  const inputProps = useForwardProps(reactivePick(props, "loading"));
61
- const virtualizerProps = toRef(() => !!props.virtualize && defu(typeof props.virtualize === "boolean" ? {} : props.virtualize, { estimateSize: 32 }));
62
+ const virtualizerProps = toRef(() => {
63
+ if (!props.virtualize) return false;
64
+ return defu(typeof props.virtualize === "boolean" ? {} : props.virtualize, {
65
+ estimateSize: getEstimateSize(filteredItems.value, "md", props.descriptionKey)
66
+ });
67
+ });
62
68
  const [DefineItemTemplate, ReuseItemTemplate] = createReusableTemplate({
63
69
  props: {
64
70
  item: {
@@ -101,13 +107,15 @@ const items = computed(() => groups.value?.filter((group) => {
101
107
  return true;
102
108
  })?.flatMap((group) => group.items?.map((item) => ({ ...item, group: group.id })) || []) || []);
103
109
  const { results: fuseResults } = useFuse(searchTerm, items, fuse);
104
- function getGroupWithItems(group, items2) {
110
+ const throttledFuseResults = refThrottled(fuseResults, 16, true);
111
+ function processGroupItems(group, items2) {
112
+ let processedItems = items2;
105
113
  if (group?.postFilter && typeof group.postFilter === "function") {
106
- items2 = group.postFilter(searchTerm.value, items2);
114
+ processedItems = group.postFilter(searchTerm.value, processedItems);
107
115
  }
108
116
  return {
109
117
  ...group,
110
- items: items2.slice(0, fuse.value.resultLimit).map((item) => {
118
+ items: processedItems.slice(0, fuse.value.resultLimit).map((item) => {
111
119
  return {
112
120
  ...item,
113
121
  labelHtml: highlight(item, searchTerm.value, props.labelKey),
@@ -117,7 +125,8 @@ function getGroupWithItems(group, items2) {
117
125
  };
118
126
  }
119
127
  const filteredGroups = computed(() => {
120
- const groupsById = fuseResults.value.reduce((acc, result) => {
128
+ const currentGroups = groups.value;
129
+ const groupsById = throttledFuseResults.value.reduce((acc, result) => {
121
130
  const { item, matches } = result;
122
131
  if (!item.group) {
123
132
  return acc;
@@ -128,25 +137,33 @@ const filteredGroups = computed(() => {
128
137
  }, {});
129
138
  if (props.preserveGroupOrder) {
130
139
  const processedGroups = [];
131
- for (const group of groups.value || []) {
140
+ for (const group of currentGroups || []) {
132
141
  if (!group.items?.length) {
133
142
  continue;
134
143
  }
135
144
  const items2 = group.ignoreFilter ? group.items : groupsById[group.id];
136
- if (items2?.length) {
137
- processedGroups.push(getGroupWithItems(group, items2));
145
+ if (!items2?.length) {
146
+ continue;
147
+ }
148
+ const processedGroup = processGroupItems(group, items2);
149
+ if (processedGroup.items?.length) {
150
+ processedGroups.push(processedGroup);
138
151
  }
139
152
  }
140
153
  return processedGroups;
141
154
  }
142
155
  const fuseGroups = Object.entries(groupsById).map(([id, items2]) => {
143
- const group = groups.value?.find((group2) => group2.id === id);
156
+ const group = currentGroups?.find((group2) => group2.id === id);
144
157
  if (!group) {
145
158
  return;
146
159
  }
147
- return getGroupWithItems(group, items2);
160
+ const processedGroup = processGroupItems(group, items2);
161
+ return processedGroup.items?.length ? processedGroup : void 0;
148
162
  }).filter((group) => !!group);
149
- const nonFuseGroups = groups.value?.map((group, index) => ({ ...group, index }))?.filter((group) => group.ignoreFilter && group.items?.length)?.map((group) => ({ ...getGroupWithItems(group, group.items || []), index: group.index })) || [];
163
+ const nonFuseGroups = currentGroups?.map((group, index) => ({ ...group, index }))?.filter((group) => group.ignoreFilter && group.items?.length)?.map((group) => {
164
+ const processedGroup = processGroupItems(group, group.items || []);
165
+ return { ...processedGroup, index: group.index };
166
+ })?.filter((group) => group.items?.length) || [];
150
167
  return nonFuseGroups.reduce((acc, group) => {
151
168
  acc.splice(group.index, 0, group);
152
169
  return acc;
@@ -202,6 +219,7 @@ function onSelect(e, item) {
202
219
  <B24Link v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
203
220
  <B24LinkBase
204
221
  v-bind="slotProps"
222
+ data-slot="item"
205
223
  :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class], active: active || item.active })"
206
224
  >
207
225
  <slot
@@ -219,17 +237,20 @@ function onSelect(e, item) {
219
237
  <Component
220
238
  :is="icons.loading"
221
239
  v-if="item.loading"
240
+ data-slot="itemLeadingIcon"
222
241
  :class="b24ui.itemLeadingIcon({ class: [props.b24ui?.itemLeadingIcon, item.b24ui?.itemLeadingIcon], loading: true })"
223
242
  />
224
243
  <Component
225
244
  :is="item.icon"
226
245
  v-else-if="item.icon"
246
+ data-slot="itemLeadingIcon"
227
247
  :class="b24ui.itemLeadingIcon({ class: [props.b24ui?.itemLeadingIcon, item.b24ui?.itemLeadingIcon], active: active || item.active })"
228
248
  />
229
249
  <B24Avatar
230
250
  v-else-if="item.avatar"
231
251
  :size="item.b24ui?.itemLeadingAvatarSize || props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()"
232
252
  v-bind="item.avatar"
253
+ data-slot="itemLeadingAvatar"
233
254
  :class="b24ui.itemLeadingAvatar({ class: [props.b24ui?.itemLeadingAvatar, item.b24ui?.itemLeadingAvatar], active: active || item.active })"
234
255
  />
235
256
  <B24Chip
@@ -238,15 +259,17 @@ function onSelect(e, item) {
238
259
  inset
239
260
  standalone
240
261
  v-bind="item.chip"
262
+ data-slot="itemLeadingChip"
241
263
  :class="b24ui.itemLeadingChip({ class: [props.b24ui?.itemLeadingChip, item.b24ui?.itemLeadingChip], active: active || item.active })"
242
264
  />
243
265
  </slot>
244
266
 
245
267
  <span
246
268
  v-if="item.prefix || (item.labelHtml || get(item, props.labelKey)) || (item.suffixHtml || item.suffix) || !!slots[item.slot ? `${item.slot}-label` : group?.slot ? `${group.slot}-label` : `item-label`] || (get(item, props.descriptionKey) || !!slots[item.slot ? `${item.slot}-description` : group?.slot ? `${group.slot}-description` : `item-description`])"
269
+ data-slot="itemWrapper"
247
270
  :class="b24ui.itemWrapper({ class: [props.b24ui?.itemWrapper, item.b24ui?.itemWrapper] })"
248
271
  >
249
- <span :class="b24ui.itemLabel({ class: [props.b24ui?.itemLabel, item.b24ui?.itemLabel], active: active || item.active })">
272
+ <span data-slot="itemLabel" :class="b24ui.itemLabel({ class: [props.b24ui?.itemLabel, item.b24ui?.itemLabel], active: active || item.active })">
250
273
  <slot
251
274
  :name="item.slot ? `${item.slot}-label` : group?.slot ? `${group.slot}-label` : `item-label`"
252
275
  :item="item"
@@ -255,23 +278,39 @@ function onSelect(e, item) {
255
278
  >
256
279
  <span
257
280
  v-if="item.prefix"
281
+ data-slot="itemLabelPrefix"
258
282
  :class="b24ui.itemLabelPrefix({ class: [props.b24ui?.itemLabelPrefix, item.b24ui?.itemLabelPrefix] })"
259
283
  >{{ item.prefix }}</span>
260
284
 
261
285
  <span
286
+ v-if="item.labelHtml"
287
+ data-slot="itemLabelBase"
262
288
  :class="b24ui.itemLabelBase({ class: [props.b24ui?.itemLabelBase, item.b24ui?.itemLabelBase], active: active || item.active })"
263
289
  v-html="item.labelHtml || get(item, props.labelKey)"
264
290
  />
291
+ <span
292
+ v-else
293
+ data-slot="itemLabelBase"
294
+ :class="b24ui.itemLabelBase({ class: [props.b24ui?.itemLabelBase, item.b24ui?.itemLabelBase], active: active || item.active })"
295
+ >{{ get(item, props.labelKey) }}</span>
265
296
 
266
297
  <span
298
+ v-if="item.suffixHtml"
299
+ data-slot="itemLabelSuffix"
267
300
  :class="b24ui.itemLabelSuffix({ class: [props.b24ui?.itemLabelSuffix, item.b24ui?.itemLabelSuffix], active: active || item.active })"
268
301
  v-html="item.suffixHtml || item.suffix"
269
302
  />
303
+ <span
304
+ v-else-if="item.suffix"
305
+ data-slot="itemLabelSuffix"
306
+ :class="b24ui.itemLabelSuffix({ class: [props.b24ui?.itemLabelSuffix, item.b24ui?.itemLabelSuffix], active: active || item.active })"
307
+ >{{ item.suffix }}</span>
270
308
  </slot>
271
309
  </span>
272
310
 
273
311
  <span
274
312
  v-if="get(item, props.descriptionKey)"
313
+ data-slot="itemDescription"
275
314
  :class="b24ui.itemDescription({ class: [props.b24ui?.itemDescription, item.b24ui?.itemDescription] })"
276
315
  >
277
316
  <slot
@@ -285,7 +324,7 @@ function onSelect(e, item) {
285
324
  </span>
286
325
  </span>
287
326
 
288
- <span :class="b24ui.itemTrailing({ class: [props.b24ui?.itemTrailing, item.b24ui?.itemTrailing] })">
327
+ <span data-slot="itemTrailing" :class="b24ui.itemTrailing({ class: [props.b24ui?.itemTrailing, item.b24ui?.itemTrailing] })">
289
328
  <slot
290
329
  :name="item.slot ? `${item.slot}-trailing` : group?.slot ? `${group.slot}-trailing` : `item-trailing`"
291
330
  :item="item"
@@ -295,10 +334,11 @@ function onSelect(e, item) {
295
334
  <Component
296
335
  :is="childrenIcon || icons.chevronRight"
297
336
  v-if="item.children && item.children.length > 0"
337
+ data-slot="itemTrailingIcon"
298
338
  :class="b24ui.itemTrailingIcon({ class: [props.b24ui?.itemTrailingIcon, item.b24ui?.itemTrailingIcon] })"
299
339
  />
300
340
 
301
- <span v-else-if="item.kbds?.length" :class="b24ui.itemTrailingKbds({ class: [props.b24ui?.itemTrailingKbds, item.b24ui?.itemTrailingKbds] })">
341
+ <span v-else-if="item.kbds?.length" data-slot="itemTrailingKbds" :class="b24ui.itemTrailingKbds({ class: [props.b24ui?.itemTrailingKbds, item.b24ui?.itemTrailingKbds] })">
302
342
  <B24Kbd
303
343
  v-for="(kbd, kbdIndex) in item.kbds"
304
344
  :key="kbdIndex"
@@ -310,6 +350,7 @@ function onSelect(e, item) {
310
350
  <Component
311
351
  :is="group.highlightedIcon"
312
352
  v-else-if="group?.highlightedIcon"
353
+ data-slot="itemTrailingHighlightedIcon"
313
354
  :class="b24ui.itemTrailingHighlightedIcon({ class: [props.b24ui?.itemTrailingHighlightedIcon, item.b24ui?.itemTrailingHighlightedIcon] })"
314
355
  />
315
356
  </slot>
@@ -317,6 +358,7 @@ function onSelect(e, item) {
317
358
  <ListboxItemIndicator v-if="!item.children?.length" as-child>
318
359
  <Component
319
360
  :is="selectedIcon || icons.check"
361
+ data-slot="itemTrailingIcon"
320
362
  :class="b24ui.itemTrailingIcon({ class: [props.b24ui?.itemTrailingIcon, item.b24ui?.itemTrailingIcon] })"
321
363
  />
322
364
  </ListboxItemIndicator>
@@ -327,7 +369,7 @@ function onSelect(e, item) {
327
369
  </ListboxItem>
328
370
  </DefineItemTemplate>
329
371
 
330
- <ListboxRoot v-bind="{ ...rootProps, ...$attrs }" ref="rootRef" :selection-behavior="selectionBehavior" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
372
+ <ListboxRoot v-bind="{ ...rootProps, ...$attrs }" ref="rootRef" :selection-behavior="selectionBehavior" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
331
373
  <ListboxFilter v-model="searchTerm" as-child>
332
374
  <B24Input
333
375
  :placeholder="placeholder"
@@ -338,6 +380,7 @@ function onSelect(e, item) {
338
380
  size="xl"
339
381
  :trailing-icon="trailingIcon"
340
382
  :icon="icon || icons.search"
383
+ data-slot="input"
341
384
  :class="b24ui.input({ class: props.b24ui?.input })"
342
385
  @keydown.backspace="onBackspace"
343
386
  >
@@ -349,6 +392,7 @@ function onSelect(e, item) {
349
392
  color="air-selection"
350
393
  :aria-label="t('commandPalette.back')"
351
394
  v-bind="typeof back === 'object' ? back : {}"
395
+ data-slot="back"
352
396
  :class="b24ui.back({ class: props.b24ui?.back })"
353
397
  @click="navigateBack"
354
398
  />
@@ -364,6 +408,7 @@ function onSelect(e, item) {
364
408
  color="air-tertiary-no-accent"
365
409
  :aria-label="t('commandPalette.close')"
366
410
  v-bind="typeof close === 'object' ? close : {}"
411
+ data-slot="close"
367
412
  :class="b24ui.close({ class: props.b24ui?.close })"
368
413
  @click="emits('update:open', false)"
369
414
  />
@@ -372,8 +417,8 @@ function onSelect(e, item) {
372
417
  </B24Input>
373
418
  </ListboxFilter>
374
419
 
375
- <ListboxContent :class="b24ui.content({ class: props.b24ui?.content })">
376
- <div v-if="filteredGroups?.length" role="presentation" :class="b24ui.viewport({ class: props.b24ui?.viewport })">
420
+ <ListboxContent data-slot="content" :class="b24ui.content({ class: props.b24ui?.content })">
421
+ <div v-if="filteredGroups?.length" role="presentation" data-slot="viewport" :class="b24ui.viewport({ class: props.b24ui?.viewport })">
377
422
  <ListboxVirtualizer
378
423
  v-if="!!virtualize"
379
424
  v-slot="{ option: item, virtualItem }"
@@ -385,8 +430,8 @@ function onSelect(e, item) {
385
430
  </ListboxVirtualizer>
386
431
 
387
432
  <template v-else>
388
- <ListboxGroup v-for="group in filteredGroups" :key="`group-${group.id}`" :class="b24ui.group({ class: props.b24ui?.group })">
389
- <ListboxGroupLabel v-if="get(group, props.labelKey)" :class="b24ui.label({ class: props.b24ui?.label })">
433
+ <ListboxGroup v-for="group in filteredGroups" :key="`group-${group.id}`" data-slot="group" :class="b24ui.group({ class: props.b24ui?.group })">
434
+ <ListboxGroupLabel v-if="get(group, props.labelKey)" data-slot="label" :class="b24ui.label({ class: props.b24ui?.label })">
390
435
  {{ get(group, props.labelKey) }}
391
436
  </ListboxGroupLabel>
392
437
 
@@ -401,14 +446,14 @@ function onSelect(e, item) {
401
446
  </template>
402
447
  </div>
403
448
 
404
- <div v-else :class="b24ui.empty({ class: props.b24ui?.empty })">
449
+ <div v-else data-slot="empty" :class="b24ui.empty({ class: props.b24ui?.empty })">
405
450
  <slot name="empty" :search-term="searchTerm">
406
451
  {{ searchTerm ? t("commandPalette.noMatch", { searchTerm }) : t("commandPalette.noData") }}
407
452
  </slot>
408
453
  </div>
409
454
  </ListboxContent>
410
455
 
411
- <div v-if="!!slots.footer" :class="b24ui.footer({ class: props.b24ui?.footer })">
456
+ <div v-if="!!slots.footer" data-slot="footer" :class="b24ui.footer({ class: props.b24ui?.footer })">
412
457
  <slot name="footer" :b24ui="b24ui" />
413
458
  </div>
414
459
  </ListboxRoot>
@@ -41,6 +41,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.context
41
41
  </ContextMenuTrigger>
42
42
 
43
43
  <B24ContextMenuContent
44
+ data-slot="content"
44
45
  :class="b24ui.content({ class: [!slots.default && props.class, props.b24ui?.content] })"
45
46
  :b24ui="b24ui"
46
47
  :b24ui-override="props.b24ui"
@@ -75,15 +75,17 @@ const groups = computed(
75
75
  v-if="item.avatar"
76
76
  :size="item.b24ui?.itemLeadingAvatarSize || b24uiOverride?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()"
77
77
  v-bind="item.avatar"
78
+ data-slot="itemLeadingAvatar"
78
79
  :class="b24ui.itemLeadingAvatar({ class: [b24uiOverride?.itemLeadingAvatar, item.b24ui?.itemLeadingAvatar], active })"
79
80
  />
80
81
  </slot>
81
82
 
82
83
  <span
83
84
  v-if="get(item, props.labelKey) || !!slots[item.slot ? `${item.slot}-label` : 'item-label'] || (get(item, props.descriptionKey) || !!slots[item.slot ? `${item.slot}-description` : 'item-description'])"
85
+ data-slot="itemWrapper"
84
86
  :class="b24ui.itemWrapper({ class: [b24uiOverride?.itemWrapper, item.b24ui?.itemWrapper] })"
85
87
  >
86
- <span :class="b24ui.itemLabel({ class: [b24uiOverride?.itemLabel, item.b24ui?.itemLabel], active })">
88
+ <span data-slot="itemLabel" :class="b24ui.itemLabel({ class: [b24uiOverride?.itemLabel, item.b24ui?.itemLabel], active })">
87
89
  <slot :name="item.slot ? `${item.slot}-label` : 'item-label'" :item="item" :active="active" :index="index">
88
90
  {{ get(item, props.labelKey) }}
89
91
  </slot>
@@ -91,6 +93,7 @@ const groups = computed(
91
93
 
92
94
  <span
93
95
  v-if="get(item, props.descriptionKey)"
96
+ data-slot="itemDescription"
94
97
  :class="b24ui.itemDescription({ class: [b24uiOverride?.itemDescription, item.b24ui?.itemDescription] })"
95
98
  >
96
99
  <slot
@@ -104,10 +107,11 @@ const groups = computed(
104
107
  </span>
105
108
  </span>
106
109
 
107
- <span :class="b24ui.itemTrailing({ class: [b24uiOverride?.itemTrailing, item.b24ui?.itemTrailing] })">
110
+ <span data-slot="itemTrailing" :class="b24ui.itemTrailing({ class: [b24uiOverride?.itemTrailing, item.b24ui?.itemTrailing] })">
108
111
  <ContextMenu.ItemIndicator as-child>
109
112
  <Component
110
113
  :is="checkedIcon || icons.check"
114
+ data-slot="itemTrailingIcon"
111
115
  :class="b24ui.itemTrailingIcon({ class: [b24uiOverride?.itemTrailingIcon, item.b24ui?.itemTrailingIcon], color: item?.color })"
112
116
  />
113
117
  </ContextMenu.ItemIndicator>
@@ -122,24 +126,28 @@ const groups = computed(
122
126
  <Component
123
127
  :is="loadingIcon || icons.loading"
124
128
  v-if="item.loading"
129
+ data-slot="itemLeadingIcon"
125
130
  :class="b24ui.itemLeadingIcon({ class: [b24uiOverride?.itemLeadingIcon, item.b24ui?.itemLeadingIcon], color: item?.color, loading: true })"
126
131
  />
127
132
  <Component
128
133
  :is="childrenIcon"
129
134
  v-else-if="item.children?.length"
135
+ data-slot="itemTrailingIcon"
130
136
  :class="b24ui.itemTrailingIcon({ class: [b24uiOverride?.itemTrailingIcon, item.b24ui?.itemTrailingIcon], color: item?.color, active })"
131
137
  />
132
138
  <Component
133
139
  :is="typeof externalIcon !== 'boolean' ? externalIcon : icons.external"
134
140
  v-else-if="item.target === '_blank' && externalIcon !== false"
141
+ data-slot="itemLabelExternalIcon"
135
142
  :class="b24ui.itemLabelExternalIcon({ class: [b24uiOverride?.itemLabelExternalIcon, item.b24ui?.itemLabelExternalIcon], color: item?.color, active })"
136
143
  />
137
144
  <Component
138
145
  :is="item.icon"
139
146
  v-else-if="item.icon"
147
+ data-slot="itemLeadingIcon"
140
148
  :class="b24ui.itemLeadingIcon({ class: [b24uiOverride?.itemLeadingIcon, item.b24ui?.itemLeadingIcon], color: item?.color, active })"
141
149
  />
142
- <span v-else-if="item.kbds?.length" :class="b24ui.itemTrailingKbds({ class: [b24uiOverride?.itemTrailingKbds, item.b24ui?.itemTrailingKbds] })">
150
+ <span v-else-if="item.kbds?.length" data-slot="itemTrailingKbds" :class="b24ui.itemTrailingKbds({ class: [b24uiOverride?.itemTrailingKbds, item.b24ui?.itemTrailingKbds] })">
143
151
  <B24Kbd v-for="(kbd, kbdIndex) in item.kbds" :key="kbdIndex" :size="item.b24ui?.itemTrailingKbdsSize || b24uiOverride?.itemTrailingKbdsSize || b24ui.itemTrailingKbdsSize()" v-bind="typeof kbd === 'string' ? { value: kbd } : kbd" />
144
152
  </span>
145
153
  </slot>
@@ -150,22 +158,24 @@ const groups = computed(
150
158
  <ContextMenu.Portal v-bind="portalProps">
151
159
  <component
152
160
  :is="sub ? ContextMenu.SubContent : ContextMenu.Content"
161
+ data-slot="content"
153
162
  :class="b24ui.content({ class: [b24uiOverride?.content, props.class] })"
154
163
  v-bind="contentProps"
155
164
  >
156
165
  <slot name="content-top" />
157
166
 
158
- <div role="presentation" :class="b24ui.viewport({ class: b24uiOverride?.viewport })">
167
+ <div role="presentation" data-slot="viewport" :class="b24ui.viewport({ class: b24uiOverride?.viewport })">
159
168
  <ContextMenu.Group
160
169
  v-for="(group, groupIndex) in groups"
161
170
  :key="`group-${groupIndex}`"
171
+ data-slot="group"
162
172
  :class="b24ui.group({ class: b24uiOverride?.group })"
163
173
  >
164
174
  <template v-for="(item, index) in group" :key="`group-${groupIndex}-${index}`">
165
- <ContextMenu.Label v-if="item.type === 'label'" :class="b24ui.label({ class: [b24uiOverride?.label, item.b24ui?.label, item.class] })">
175
+ <ContextMenu.Label v-if="item.type === 'label'" data-slot="label" :class="b24ui.label({ class: [b24uiOverride?.label, item.b24ui?.label, item.class] })">
166
176
  <ReuseItemTemplate :item="item" :index="index" />
167
177
  </ContextMenu.Label>
168
- <ContextMenu.Separator v-else-if="item.type === 'separator'" :class="b24ui.separator({ class: [b24uiOverride?.separator, item.b24ui?.separator, item.class] })" />
178
+ <ContextMenu.Separator v-else-if="item.type === 'separator'" data-slot="separator" :class="b24ui.separator({ class: [b24uiOverride?.separator, item.b24ui?.separator, item.class] })" />
169
179
  <ContextMenu.Sub
170
180
  v-else-if="item?.children?.length"
171
181
  :open="item.open"
@@ -176,6 +186,7 @@ const groups = computed(
176
186
  type="button"
177
187
  :disabled="item.disabled"
178
188
  :text-value="get(item, props.labelKey)"
189
+ data-slot="item"
179
190
  :class="b24ui.item({ class: [b24uiOverride?.item, item.b24ui?.item, item.class], color: item?.color })"
180
191
  >
181
192
  <ReuseItemTemplate :item="item" :index="index" />
@@ -206,6 +217,7 @@ const groups = computed(
206
217
  :model-value="item.checked"
207
218
  :disabled="item.disabled"
208
219
  :text-value="get(item, props.labelKey)"
220
+ data-slot="item"
209
221
  :class="b24ui.item({ class: [b24uiOverride?.item, item.b24ui?.item, item.class], color: item?.color })"
210
222
  @update:model-value="item.onUpdateChecked"
211
223
  @select="item.onSelect"
@@ -222,6 +234,7 @@ const groups = computed(
222
234
  <B24Link v-slot="{ active, ...slotProps }" v-bind="pickLinkProps(item)" custom>
223
235
  <B24LinkBase
224
236
  v-bind="slotProps"
237
+ data-slot="item"
225
238
  :class="b24ui.item({ class: [b24uiOverride?.item, item.b24ui?.item, item.class], color: item?.color, active })"
226
239
  >
227
240
  <ReuseItemTemplate :item="item" :active="active" :index="index" />