@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
@@ -26,6 +26,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.skeleto
26
26
  aria-label="loading"
27
27
  aria-live="polite"
28
28
  role="alert"
29
+ data-slot="base"
29
30
  :class="b24ui.base({ class: [props.b24ui?.base, props.class] })"
30
31
  >
31
32
  <slot />
@@ -67,10 +67,11 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.slideov
67
67
  </DialogTrigger>
68
68
 
69
69
  <DialogPortal v-bind="portalProps">
70
- <DialogOverlay v-if="overlay" :class="b24ui.overlay({ class: props.b24ui?.overlay })" />
70
+ <DialogOverlay v-if="overlay" data-slot="overlay" :class="b24ui.overlay({ class: props.b24ui?.overlay })" />
71
71
 
72
72
  <DialogContent
73
73
  :data-side="side"
74
+ data-slot="content"
74
75
  :class="b24ui.content({ class: [!slots.default && props.class, props.b24ui?.content] })"
75
76
  v-bind="contentProps"
76
77
  @after-enter="emits('after:enter')"
@@ -112,6 +113,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.slideov
112
113
  label: 'hidden sm:flex'
113
114
  }"
114
115
  v-bind="typeof props.close === 'object' ? props.close : {}"
116
+ data-slot="close"
115
117
  :class="b24ui.close({ class: props.b24ui?.close })"
116
118
  />
117
119
  </slot>
@@ -139,16 +141,16 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.slideov
139
141
  </template>
140
142
 
141
143
  <template v-if="!!slots.header || (title || !!slots.title) || (description || !!slots.description) || ['top'].includes(props?.side) && (props.close || !!slots.close)" #content-top>
142
- <div :class="b24ui.header({ class: props.b24ui?.header })">
144
+ <div data-slot="header" :class="b24ui.header({ class: props.b24ui?.header })">
143
145
  <slot name="header" :close="close">
144
- <div :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
145
- <DialogTitle v-if="title || !!slots.title" :class="b24ui.title({ class: props.b24ui?.title })">
146
+ <div data-slot="wrapper" :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
147
+ <DialogTitle v-if="title || !!slots.title" data-slot="title" :class="b24ui.title({ class: props.b24ui?.title })">
146
148
  <slot name="title">
147
149
  {{ title }}
148
150
  </slot>
149
151
  </DialogTitle>
150
152
 
151
- <DialogDescription v-if="description || !!slots.description" :class="b24ui.description({ class: props.b24ui?.description })">
153
+ <DialogDescription v-if="description || !!slots.description" data-slot="description" :class="b24ui.description({ class: props.b24ui?.description })">
152
154
  <slot name="description">
153
155
  {{ description }}
154
156
  </slot>
@@ -165,6 +167,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.slideov
165
167
  :aria-label="t('slideover.close')"
166
168
  size="lg"
167
169
  v-bind="typeof props.close === 'object' ? props.close : {}"
170
+ data-slot="close"
168
171
  :class="b24ui.close({ class: props.b24ui?.close })"
169
172
  />
170
173
  </slot>
@@ -179,13 +182,13 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.slideov
179
182
  </template>
180
183
 
181
184
  <template v-if="!!slots['body']" #default>
182
- <div :class="b24ui.body({ class: props.b24ui?.body })">
185
+ <div data-slot="body" :class="b24ui.body({ class: props.b24ui?.body })">
183
186
  <slot name="body" :close="close" />
184
187
  </div>
185
188
  </template>
186
189
 
187
190
  <template v-if="!!slots.footer" #content-bottom>
188
- <div :class="b24ui.footer({ class: props.b24ui?.footer })">
191
+ <div data-slot="footer" :class="b24ui.footer({ class: props.b24ui?.footer })">
189
192
  <slot name="footer" :close="close" />
190
193
  </div>
191
194
  </template>
@@ -61,22 +61,24 @@ defineExpose({
61
61
  </script>
62
62
 
63
63
  <template>
64
- <StepperRoot v-bind="rootProps" v-model="currentStepIndex" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
65
- <div :class="b24ui.header({ class: props.b24ui?.header })">
64
+ <StepperRoot v-bind="rootProps" v-model="currentStepIndex" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
65
+ <div data-slot="header" :class="b24ui.header({ class: props.b24ui?.header })">
66
66
  <StepperItem
67
67
  v-for="(item, count) in items"
68
68
  :key="item.value ?? count"
69
69
  :step="count"
70
70
  :disabled="item.disabled || props.disabled"
71
+ data-slot="item"
71
72
  :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class] })"
72
73
  >
73
- <div :class="b24ui.container({ class: [props.b24ui?.container, item.b24ui?.container] })">
74
- <StepperTrigger :class="b24ui.trigger({ class: [props.b24ui?.trigger, item.b24ui?.trigger] })">
75
- <StepperIndicator :class="b24ui.indicator({ class: [props.b24ui?.indicator, item.b24ui?.indicator] })">
74
+ <div data-slot="container" :class="b24ui.container({ class: [props.b24ui?.container, item.b24ui?.container] })">
75
+ <StepperTrigger data-slot="trigger" :class="b24ui.trigger({ class: [props.b24ui?.trigger, item.b24ui?.trigger] })">
76
+ <StepperIndicator data-slot="indicator" :class="b24ui.indicator({ class: [props.b24ui?.indicator, item.b24ui?.indicator] })">
76
77
  <slot name="indicator" :item="item" :b24ui="b24ui">
77
78
  <Component
78
79
  :is="item.icon"
79
80
  v-if="item.icon"
81
+ data-slot="icon"
80
82
  :class="b24ui.icon({ class: [props.b24ui?.icon, item.b24ui?.icon] })"
81
83
  />
82
84
  <template v-else>
@@ -88,17 +90,18 @@ defineExpose({
88
90
 
89
91
  <StepperSeparator
90
92
  v-if="count < items.length - 1"
93
+ data-slot="separator"
91
94
  :class="b24ui.separator({ class: [props.b24ui?.separator, item.b24ui?.separator] })"
92
95
  />
93
96
  </div>
94
97
 
95
- <div :class="b24ui.wrapper({ class: [props.b24ui?.wrapper, item.b24ui?.wrapper] })">
96
- <StepperTitle as="div" :class="b24ui.title({ class: [props.b24ui?.title, item.b24ui?.title] })">
98
+ <div data-slot="wrapper" :class="b24ui.wrapper({ class: [props.b24ui?.wrapper, item.b24ui?.wrapper] })">
99
+ <StepperTitle as="div" data-slot="title" :class="b24ui.title({ class: [props.b24ui?.title, item.b24ui?.title] })">
97
100
  <slot name="title" :item="item">
98
101
  {{ item.title }}
99
102
  </slot>
100
103
  </StepperTitle>
101
- <StepperDescription as="div" :class="b24ui.description({ class: [props.b24ui?.description, item.b24ui?.description] })">
104
+ <StepperDescription as="div" data-slot="description" :class="b24ui.description({ class: [props.b24ui?.description, item.b24ui?.description] })">
102
105
  <slot name="description" :item="item">
103
106
  {{ item.description }}
104
107
  </slot>
@@ -107,7 +110,7 @@ defineExpose({
107
110
  </StepperItem>
108
111
  </div>
109
112
 
110
- <div v-if="currentStep?.content || !!slots.content || currentStep?.slot" :class="b24ui.content({ class: props.b24ui?.content })">
113
+ <div v-if="currentStep?.content || !!slots.content || currentStep?.slot" data-slot="content" :class="b24ui.content({ class: props.b24ui?.content })">
111
114
  <slot
112
115
  :name="currentStep?.slot || 'content'"
113
116
  :item="currentStep"
@@ -54,45 +54,49 @@ function onUpdate(value) {
54
54
  </script>
55
55
 
56
56
  <template>
57
- <Primitive :as="as" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
58
- <div :class="b24ui.container({ class: props.b24ui?.container })">
57
+ <Primitive :as="as" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
58
+ <div data-slot="container" :class="b24ui.container({ class: props.b24ui?.container })">
59
59
  <SwitchRoot
60
60
  :id="id"
61
61
  v-bind="{ ...rootProps, ...omit({ ...$attrs }, ['data-state']), ...ariaAttrs }"
62
62
  v-model="modelValue"
63
63
  :name="name"
64
64
  :disabled="disabled || loading"
65
+ data-slot="base"
65
66
  :class="b24ui.base({ class: props.b24ui?.base })"
66
67
  @update:model-value="onUpdate"
67
68
  >
68
- <SwitchThumb :class="b24ui.thumb({ class: props.b24ui?.thumb })">
69
+ <SwitchThumb data-slot="thumb" :class="b24ui.thumb({ class: props.b24ui?.thumb })">
69
70
  <Component
70
71
  :is="loadingIcon || icons.refresh"
71
72
  v-if="loading"
73
+ data-slot="icon"
72
74
  :class="b24ui.icon({ class: props.b24ui?.icon, checked: true, unchecked: true })"
73
75
  />
74
76
  <template v-else>
75
77
  <Component
76
78
  :is="checkedIcon"
77
79
  v-if="checkedIcon"
80
+ data-slot="icon"
78
81
  :class="b24ui.icon({ class: props.b24ui?.icon, checked: true })"
79
82
  />
80
83
  <Component
81
84
  :is="uncheckedIcon"
82
85
  v-if="uncheckedIcon"
86
+ data-slot="icon"
83
87
  :class="b24ui.icon({ class: props.b24ui?.icon, unchecked: true })"
84
88
  />
85
89
  </template>
86
90
  </SwitchThumb>
87
91
  </SwitchRoot>
88
92
  </div>
89
- <div v-if="label || !!slots.label || (description || !!slots.description)" :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
90
- <Label v-if="label || !!slots.label" :for="id" :class="b24ui.label({ class: props.b24ui?.label })">
93
+ <div v-if="label || !!slots.label || (description || !!slots.description)" data-slot="wrapper" :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
94
+ <Label v-if="label || !!slots.label" :for="id" data-slot="label" :class="b24ui.label({ class: props.b24ui?.label })">
91
95
  <slot name="label" :label="label">
92
96
  {{ label }}
93
97
  </slot>
94
98
  </Label>
95
- <p v-if="description || !!slots.description" :class="b24ui.description({ class: props.b24ui?.description })">
99
+ <p v-if="description || !!slots.description" data-slot="description" :class="b24ui.description({ class: props.b24ui?.description })">
96
100
  <slot name="description" :description="description">
97
101
  {{ description }}
98
102
  </slot>
@@ -63,10 +63,10 @@ export interface TableProps<T extends TableData = TableData> extends TableOption
63
63
  */
64
64
  overscan?: number;
65
65
  /**
66
- * Estimated size (in px) of each item
66
+ * Estimated size (in px) of each item, or a function that returns the size for a given index
67
67
  * @defaultValue 65
68
68
  */
69
- estimateSize?: number;
69
+ estimateSize?: number | ((index: number) => number);
70
70
  });
71
71
  /**
72
72
  * The text to display when the table is empty.
@@ -225,7 +225,20 @@ const virtualizer = !!props.virtualize && useVirtualizer({
225
225
  return rows.value.length;
226
226
  },
227
227
  getScrollElement: () => rootRef.value?.$el,
228
- estimateSize: () => virtualizerProps.value.estimateSize
228
+ estimateSize: (index) => {
229
+ const estimate = virtualizerProps.value.estimateSize;
230
+ return typeof estimate === "function" ? estimate(index) : estimate;
231
+ }
232
+ });
233
+ const renderedSize = computed(() => {
234
+ if (!virtualizer) {
235
+ return 0;
236
+ }
237
+ const virtualItems = virtualizer.value.getVirtualItems();
238
+ if (!virtualItems?.length) {
239
+ return 0;
240
+ }
241
+ return virtualItems.reduce((sum, item) => sum + item.size, 0);
229
242
  });
230
243
  function valueUpdater(updaterOrValue, ref2) {
231
244
  ref2.value = typeof updaterOrValue === "function" ? updaterOrValue(ref2.value) : updaterOrValue;
@@ -285,6 +298,7 @@ defineExpose({
285
298
  :data-expanded="row.getIsExpanded()"
286
299
  :role="props.onSelect ? 'button' : void 0"
287
300
  :tabindex="props.onSelect ? 0 : void 0"
301
+ data-slot="tr"
288
302
  :class="b24ui.tr({
289
303
  class: [
290
304
  props.b24ui?.tr,
@@ -303,6 +317,7 @@ defineExpose({
303
317
  :data-pinned="cell.column.getIsPinned()"
304
318
  :colspan="resolveValue(cell.column.columnDef.meta?.colspan?.td, cell)"
305
319
  :rowspan="resolveValue(cell.column.columnDef.meta?.rowspan?.td, cell)"
320
+ data-slot="td"
306
321
  :class="b24ui.td({
307
322
  class: [
308
323
  props.b24ui?.td,
@@ -318,23 +333,23 @@ defineExpose({
318
333
  </td>
319
334
  </tr>
320
335
 
321
- <tr v-if="row.getIsExpanded()" :class="b24ui.tr({ class: [props.b24ui?.tr] })">
322
- <td :colspan="row.getAllCells().length" :class="b24ui.td({ class: [props.b24ui?.td] })">
336
+ <tr v-if="row.getIsExpanded()" data-slot="tr" :class="b24ui.tr({ class: [props.b24ui?.tr] })">
337
+ <td :colspan="row.getAllCells().length" data-slot="td" :class="b24ui.td({ class: [props.b24ui?.td] })">
323
338
  <slot name="expanded" :row="row" />
324
339
  </td>
325
340
  </tr>
326
341
  </DefineRowTemplate>
327
342
 
328
343
  <DefineTableTemplate>
329
- <table ref="tableRef" :class="b24ui.base({ class: [props.b24ui?.base] })">
330
- <caption v-if="caption || !!slots.caption" :class="b24ui.caption({ class: [props.b24ui?.caption] })">
344
+ <table ref="tableRef" data-slot="base" :class="b24ui.base({ class: [props.b24ui?.base] })">
345
+ <caption v-if="caption || !!slots.caption" data-slot="caption" :class="b24ui.caption({ class: [props.b24ui?.caption] })">
331
346
  <slot name="caption">
332
347
  {{ caption }}
333
348
  </slot>
334
349
  </caption>
335
350
 
336
- <thead :class="b24ui.thead({ class: [props.b24ui?.thead] })">
337
- <tr v-for="headerGroup in tableApi.getHeaderGroups()" :key="headerGroup.id" :class="b24ui.tr({ class: [props.b24ui?.tr] })">
351
+ <thead data-slot="thead" :class="b24ui.thead({ class: [props.b24ui?.thead] })">
352
+ <tr v-for="headerGroup in tableApi.getHeaderGroups()" :key="headerGroup.id" data-slot="tr" :class="b24ui.tr({ class: [props.b24ui?.tr] })">
338
353
  <th
339
354
  v-for="header in headerGroup.headers"
340
355
  :key="header.id"
@@ -342,6 +357,7 @@ defineExpose({
342
357
  :scope="header.colSpan > 1 ? 'colgroup' : 'col'"
343
358
  :colspan="header.colSpan > 1 ? header.colSpan : void 0"
344
359
  :rowspan="header.rowSpan > 1 ? header.rowSpan : void 0"
360
+ data-slot="th"
345
361
  :class="b24ui.th({
346
362
  class: [
347
363
  props.b24ui?.th,
@@ -357,10 +373,10 @@ defineExpose({
357
373
  </th>
358
374
  </tr>
359
375
 
360
- <tr :class="b24ui.separator({ class: [props.b24ui?.separator] })" />
376
+ <tr data-slot="separator" :class="b24ui.separator({ class: [props.b24ui?.separator] })" />
361
377
  </thead>
362
378
 
363
- <tbody :class="b24ui.tbody({ class: [props.b24ui?.tbody] })">
379
+ <tbody data-slot="tbody" :class="b24ui.tbody({ class: [props.b24ui?.tbody] })">
364
380
  <slot name="body-top" />
365
381
 
366
382
  <template v-if="rows.length">
@@ -382,13 +398,13 @@ defineExpose({
382
398
  </template>
383
399
 
384
400
  <tr v-else-if="loading && !!slots['loading']">
385
- <td :colspan="tableApi.getAllLeafColumns().length" :class="b24ui.loading({ class: props.b24ui?.loading })">
401
+ <td :colspan="tableApi.getAllLeafColumns().length" data-slot="loading" :class="b24ui.loading({ class: props.b24ui?.loading })">
386
402
  <slot name="loading" />
387
403
  </td>
388
404
  </tr>
389
405
 
390
406
  <tr v-else>
391
- <td :colspan="tableApi.getAllLeafColumns().length" :class="b24ui.empty({ class: props.b24ui?.empty })">
407
+ <td :colspan="tableApi.getAllLeafColumns().length" data-slot="empty" :class="b24ui.empty({ class: props.b24ui?.empty })">
392
408
  <slot name="empty">
393
409
  {{ empty || t("table.noData") }}
394
410
  </slot>
@@ -400,20 +416,22 @@ defineExpose({
400
416
 
401
417
  <tfoot
402
418
  v-if="hasFooter"
419
+ data-slot="tfoot"
403
420
  :class="b24ui.tfoot({ class: [props.b24ui?.tfoot] })"
404
421
  :style="virtualizer ? {
405
- transform: `translateY(${virtualizer.getTotalSize() - virtualizer.getVirtualItems().length * virtualizerProps.estimateSize}px)`
422
+ transform: `translateY(${virtualizer.getTotalSize() - renderedSize}px)`
406
423
  } : void 0"
407
424
  >
408
- <tr :class="b24ui.separator({ class: [props.b24ui?.separator] })" />
425
+ <tr data-slot="separator" :class="b24ui.separator({ class: [props.b24ui?.separator] })" />
409
426
 
410
- <tr v-for="footerGroup in tableApi.getFooterGroups()" :key="footerGroup.id" :class="b24ui.tr({ class: [props.b24ui?.tr] })">
427
+ <tr v-for="footerGroup in tableApi.getFooterGroups()" :key="footerGroup.id" data-slot="tr" :class="b24ui.tr({ class: [props.b24ui?.tr] })">
411
428
  <th
412
429
  v-for="header in footerGroup.headers"
413
430
  :key="header.id"
414
431
  :data-pinned="header.column.getIsPinned()"
415
432
  :colspan="header.colSpan > 1 ? header.colSpan : void 0"
416
433
  :rowspan="header.rowSpan > 1 ? header.rowSpan : void 0"
434
+ data-slot="th"
417
435
  :class="b24ui.th({
418
436
  class: [
419
437
  props.b24ui?.th,
@@ -432,7 +450,7 @@ defineExpose({
432
450
  </table>
433
451
  </DefineTableTemplate>
434
452
 
435
- <Primitive ref="rootRef" :as="as" v-bind="$attrs" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
453
+ <Primitive ref="rootRef" :as="as" v-bind="$attrs" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
436
454
  <div
437
455
  v-if="virtualizer"
438
456
  :style="{
@@ -63,10 +63,10 @@ export interface TableProps<T extends TableData = TableData> extends TableOption
63
63
  */
64
64
  overscan?: number;
65
65
  /**
66
- * Estimated size (in px) of each item
66
+ * Estimated size (in px) of each item, or a function that returns the size for a given index
67
67
  * @defaultValue 65
68
68
  */
69
- estimateSize?: number;
69
+ estimateSize?: number | ((index: number) => number);
70
70
  });
71
71
  /**
72
72
  * The text to display when the table is empty.
@@ -37,6 +37,7 @@ const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.tableWr
37
37
  <template>
38
38
  <Primitive
39
39
  :as="as"
40
+ data-slot="base"
40
41
  :class="b24ui.base({ class: [props.b24ui?.base, props.class] })"
41
42
  >
42
43
  <slot />
@@ -3,7 +3,7 @@ import type { TabsRootProps, TabsRootEmits } from 'reka-ui';
3
3
  import type { AppConfig } from '@nuxt/schema';
4
4
  import theme from '#build/b24ui/tabs';
5
5
  import type { AvatarProps, BadgeProps, IconComponent } from '../types';
6
- import type { DynamicSlots } from '../types/utils';
6
+ import type { DynamicSlots, GetItemKeys } from '../types/utils';
7
7
  import type { ComponentConfig } from '../types/tv';
8
8
  type Tabs = ComponentConfig<typeof theme, AppConfig, 'tabs'>;
9
9
  export interface TabsItem {
@@ -15,7 +15,7 @@ export interface TabsItem {
15
15
  avatar?: AvatarProps;
16
16
  /**
17
17
  * Display a badge on the item.
18
- * `{ size: 'sm', color: 'air-primary' }`{lang="ts"}
18
+ * `{ size: 'sm', color: 'air-primary' }`{lang="ts-type"}
19
19
  */
20
20
  badge?: string | number | BadgeProps;
21
21
  slot?: string;
@@ -56,7 +56,7 @@ export interface TabsProps<T extends TabsItem = TabsItem> extends Pick<TabsRootP
56
56
  * The key used to get the label from the item.
57
57
  * @defaultValue 'label'
58
58
  */
59
- labelKey?: string;
59
+ labelKey?: GetItemKeys<T>;
60
60
  class?: any;
61
61
  b24ui?: Tabs['slots'];
62
62
  }
@@ -18,7 +18,7 @@ const props = defineProps({
18
18
  size: { type: null, required: false },
19
19
  orientation: { type: null, required: false, default: "horizontal" },
20
20
  content: { type: Boolean, required: false, default: true },
21
- labelKey: { type: String, required: false, default: "label" },
21
+ labelKey: { type: null, required: false, default: "label" },
22
22
  class: { type: null, required: false },
23
23
  b24ui: { type: null, required: false },
24
24
  defaultValue: { type: null, required: false, default: "0" },
@@ -29,10 +29,7 @@ const props = defineProps({
29
29
  const emits = defineEmits(["update:modelValue"]);
30
30
  const slots = defineSlots();
31
31
  const appConfig = useAppConfig();
32
- const rootProps = useForwardPropsEmits(reactivePick(props, "as", "modelValue", "defaultValue", "orientation", "activationMode", "unmountOnHide"), emits);
33
- const getLabel = (item) => {
34
- return get(item, props.labelKey);
35
- };
32
+ const rootProps = useForwardPropsEmits(reactivePick(props, "as", "unmountOnHide"), emits);
36
33
  const b24ui = computed(() => tv({ extend: tv(theme), ...appConfig.b24ui?.tabs || {} })({
37
34
  variant: props.variant,
38
35
  size: props.size,
@@ -45,45 +42,56 @@ defineExpose({
45
42
  </script>
46
43
 
47
44
  <template>
48
- <TabsRoot v-bind="rootProps" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
49
- <TabsList :class="b24ui.list({ class: props.b24ui?.list })">
50
- <TabsIndicator :class="b24ui.indicator({ class: props.b24ui?.indicator })" />
45
+ <TabsRoot
46
+ v-bind="rootProps"
47
+ :model-value="modelValue"
48
+ :default-value="defaultValue"
49
+ :orientation="orientation"
50
+ :activation-mode="activationMode"
51
+ data-slot="root"
52
+ :class="b24ui.root({ class: [props.b24ui?.root, props.class] })"
53
+ >
54
+ <TabsList data-slot="list" :class="b24ui.list({ class: props.b24ui?.list })">
55
+ <TabsIndicator data-slot="indicator" :class="b24ui.indicator({ class: props.b24ui?.indicator })" />
51
56
 
52
57
  <slot name="list-leading" />
53
58
 
54
59
  <TabsTrigger
55
- v-for="(item, index) in items"
60
+ v-for="(item, index) of items"
56
61
  :key="index"
57
62
  :ref="(el) => triggersRef[index] = el"
58
- :value="item.value || String(index)"
63
+ :value="item.value ?? String(index)"
59
64
  :disabled="item.disabled"
65
+ data-slot="trigger"
60
66
  :class="b24ui.trigger({ class: [props.b24ui?.trigger, item.b24ui?.trigger] })"
61
67
  >
62
68
  <slot name="leading" :item="item" :index="index" :b24ui="b24ui">
63
69
  <Component
64
70
  :is="item.icon"
65
71
  v-if="item.icon"
72
+ data-slot="leadingIcon"
66
73
  :class="b24ui.leadingIcon({ class: [props.b24ui?.leadingIcon, item.b24ui?.leadingIcon] })"
67
74
  />
68
75
  <B24Avatar
69
76
  v-else-if="item.avatar"
70
77
  :size="item.b24ui?.leadingAvatarSize || props.b24ui?.leadingAvatarSize || b24ui.leadingAvatarSize()"
71
78
  v-bind="item.avatar"
79
+ data-slot="leadingAvatar"
72
80
  :class="b24ui.leadingAvatar({ class: [props.b24ui?.leadingAvatar, item.b24ui?.leadingAvatar] })"
73
81
  />
74
82
  </slot>
75
83
 
76
- <span v-if="getLabel(item) || !!slots.default" :class="b24ui.label({ class: [props.b24ui?.label, item.b24ui?.label] })">
77
- <slot :item="item" :index="index">{{ getLabel(item) }}</slot>
84
+ <span v-if="get(item, props.labelKey) || !!slots.default" data-slot="label" :class="b24ui.label({ class: [props.b24ui?.label, item.b24ui?.label] })">
85
+ <slot :item="item" :index="index">{{ get(item, props.labelKey) }}</slot>
78
86
  </span>
79
87
 
80
88
  <slot name="trailing" :item="item" :index="index" :b24ui="b24ui">
81
89
  <B24Badge
82
90
  v-if="item.badge || item.badge === 0"
83
91
  color="air-primary"
84
- variant="outline"
85
92
  :size="item.b24ui?.trailingBadgeSize || props.b24ui?.trailingBadgeSize || b24ui.trailingBadgeSize()"
86
93
  v-bind="typeof item.badge === 'string' || typeof item.badge === 'number' ? { label: item.badge } : item.badge"
94
+ data-slot="trailingBadge"
87
95
  :class="b24ui.trailingBadge({ class: [props.b24ui?.trailingBadge, item.b24ui?.trailingBadge] })"
88
96
  />
89
97
  </slot>
@@ -94,9 +102,10 @@ defineExpose({
94
102
 
95
103
  <template v-if="!!content">
96
104
  <TabsContent
97
- v-for="(item, index) in items"
105
+ v-for="(item, index) of items"
98
106
  :key="index"
99
- :value="item.value || String(index)"
107
+ :value="item.value ?? String(index)"
108
+ data-slot="content"
100
109
  :class="b24ui.content({ class: [props.b24ui?.content, item.b24ui?.content, item.class] })"
101
110
  >
102
111
  <slot
@@ -3,7 +3,7 @@ import type { TabsRootProps, TabsRootEmits } from 'reka-ui';
3
3
  import type { AppConfig } from '@nuxt/schema';
4
4
  import theme from '#build/b24ui/tabs';
5
5
  import type { AvatarProps, BadgeProps, IconComponent } from '../types';
6
- import type { DynamicSlots } from '../types/utils';
6
+ import type { DynamicSlots, GetItemKeys } from '../types/utils';
7
7
  import type { ComponentConfig } from '../types/tv';
8
8
  type Tabs = ComponentConfig<typeof theme, AppConfig, 'tabs'>;
9
9
  export interface TabsItem {
@@ -15,7 +15,7 @@ export interface TabsItem {
15
15
  avatar?: AvatarProps;
16
16
  /**
17
17
  * Display a badge on the item.
18
- * `{ size: 'sm', color: 'air-primary' }`{lang="ts"}
18
+ * `{ size: 'sm', color: 'air-primary' }`{lang="ts-type"}
19
19
  */
20
20
  badge?: string | number | BadgeProps;
21
21
  slot?: string;
@@ -56,7 +56,7 @@ export interface TabsProps<T extends TabsItem = TabsItem> extends Pick<TabsRootP
56
56
  * The key used to get the label from the item.
57
57
  * @defaultValue 'label'
58
58
  */
59
- labelKey?: string;
59
+ labelKey?: GetItemKeys<T>;
60
60
  class?: any;
61
61
  b24ui?: Tabs['slots'];
62
62
  }
@@ -146,9 +146,10 @@ defineExpose({
146
146
  </script>
147
147
 
148
148
  <template>
149
- <Primitive :as="as" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
149
+ <Primitive :as="as" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
150
150
  <B24Badge
151
151
  v-if="isTag"
152
+ data-slot="tag"
152
153
  :class="b24ui.tag({ class: props.b24ui?.tag })"
153
154
  :color="props.tagColor"
154
155
  :label="props.tag"
@@ -162,6 +163,7 @@ defineExpose({
162
163
  :name="name"
163
164
  :rows="rows"
164
165
  :placeholder="placeholder"
166
+ data-slot="base"
165
167
  :class="b24ui.base({ class: props.b24ui?.base })"
166
168
  :disabled="disabled"
167
169
  :required="required"
@@ -174,27 +176,30 @@ defineExpose({
174
176
 
175
177
  <slot :b24ui="b24ui" />
176
178
 
177
- <span v-if="isLeading || !!avatar || !!slots.leading" :class="b24ui.leading({ class: props.b24ui?.leading })">
179
+ <span v-if="isLeading || !!avatar || !!slots.leading" data-slot="leading" :class="b24ui.leading({ class: props.b24ui?.leading })">
178
180
  <slot name="leading" :b24ui="b24ui">
179
181
  <Component
180
182
  :is="leadingIconName"
181
183
  v-if="isLeading && leadingIconName"
184
+ data-slot="leadingIcon"
182
185
  :class="b24ui.leadingIcon({ class: props.b24ui?.leadingIcon })"
183
186
  />
184
187
  <B24Avatar
185
188
  v-else-if="!!avatar"
186
189
  :size="props.b24ui?.leadingAvatarSize || b24ui.leadingAvatarSize()"
187
190
  v-bind="avatar"
191
+ data-slot="leadingAvatar"
188
192
  :class="b24ui.leadingAvatar({ class: props.b24ui?.leadingAvatar })"
189
193
  />
190
194
  </slot>
191
195
  </span>
192
196
 
193
- <span v-if="isTrailing || !!slots.trailing" :class="b24ui.trailing({ class: props.b24ui?.trailing })">
197
+ <span v-if="isTrailing || !!slots.trailing" data-slot="trailing" :class="b24ui.trailing({ class: props.b24ui?.trailing })">
194
198
  <slot name="trailing" :b24ui="b24ui">
195
199
  <Component
196
200
  :is="trailingIconName"
197
201
  v-if="trailingIconName"
202
+ data-slot="trailingIcon"
198
203
  :class="b24ui.trailingIcon({ class: props.b24ui?.trailingIcon })"
199
204
  />
200
205
  </slot>
@@ -51,18 +51,20 @@ function getItemState(index) {
51
51
  </script>
52
52
 
53
53
  <template>
54
- <Primitive :as="as" :data-orientation="orientation" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
54
+ <Primitive :as="as" :data-orientation="orientation" data-slot="root" :class="b24ui.root({ class: [props.b24ui?.root, props.class] })">
55
55
  <div
56
56
  v-for="(item, index) in items"
57
57
  :key="item.value ?? index"
58
+ data-slot="item"
58
59
  :class="b24ui.item({ class: [props.b24ui?.item, item.b24ui?.item, item.class] })"
59
60
  :data-state="getItemState(index)"
60
61
  >
61
- <div :class="b24ui.container({ class: [props.b24ui?.container, item.b24ui?.container] })">
62
+ <div data-slot="container" :class="b24ui.container({ class: [props.b24ui?.container, item.b24ui?.container] })">
62
63
  <B24Avatar
63
64
  :size="size"
64
65
  :icon="item.icon"
65
66
  v-bind="typeof item.avatar === 'object' ? item.avatar : {}"
67
+ data-slot="indicator"
66
68
  :class="b24ui.indicator({ class: [props.b24ui?.indicator, item.b24ui?.indicator] })"
67
69
  :b24ui="{ icon: 'text-inherit', fallback: 'text-inherit' }"
68
70
  >
@@ -71,23 +73,24 @@ function getItemState(index) {
71
73
 
72
74
  <Separator
73
75
  v-if="index < items.length - 1"
76
+ data-slot="separator"
74
77
  :class="b24ui.separator({ class: [props.b24ui?.separator, item.b24ui?.separator] })"
75
78
  :orientation="props.orientation"
76
79
  />
77
80
  </div>
78
81
 
79
- <div :class="b24ui.wrapper({ class: [props.b24ui?.wrapper, item.b24ui?.wrapper] })">
80
- <div v-if="item.date" :class="b24ui.date({ class: [props.b24ui?.date, item.b24ui?.date] })">
82
+ <div data-slot="wrapper" :class="b24ui.wrapper({ class: [props.b24ui?.wrapper, item.b24ui?.wrapper] })">
83
+ <div v-if="item.date" data-slot="date" :class="b24ui.date({ class: [props.b24ui?.date, item.b24ui?.date] })">
81
84
  <slot :name="item.slot ? `${item.slot}-date` : 'date'" :item="item">
82
85
  {{ item.date }}
83
86
  </slot>
84
87
  </div>
85
- <div v-if="item.title || !!slots.title" :class="b24ui.title({ class: [props.b24ui?.title, item.b24ui?.title] })">
88
+ <div v-if="item.title || !!slots.title" data-slot="title" :class="b24ui.title({ class: [props.b24ui?.title, item.b24ui?.title] })">
86
89
  <slot :name="item.slot ? `${item.slot}-title` : 'title'" :item="item">
87
90
  {{ item.title }}
88
91
  </slot>
89
92
  </div>
90
- <div v-if="item.description || !!slots.description" :class="b24ui.description({ class: [props.b24ui?.description, item.b24ui?.description] })">
93
+ <div v-if="item.description || !!slots.description" data-slot="description" :class="b24ui.description({ class: [props.b24ui?.description, item.b24ui?.description] })">
91
94
  <slot :name="item.slot ? `${item.slot}-description` : 'description'" :item="item">
92
95
  {{ item.description }}
93
96
  </slot>