bitboss-ui 2.1.132 → 2.1.133

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 (201) hide show
  1. package/dist/ai/BbDropdown.md +66 -13
  2. package/dist/ai/BbDropdownButton.md +29 -13
  3. package/dist/components/BbDropdown/types.d.ts +14 -2
  4. package/dist/components/BbDropdownButton/types.d.ts +2 -2
  5. package/dist/index.css +1 -1
  6. package/dist/index109.js +9 -9
  7. package/dist/index110.js +16 -16
  8. package/dist/index118.js +1 -1
  9. package/dist/index124.js +3 -3
  10. package/dist/index126.js +14 -14
  11. package/dist/index134.js +1 -1
  12. package/dist/index136.js +4 -4
  13. package/dist/index138.js +1 -1
  14. package/dist/index14.js +1 -1
  15. package/dist/index142.js +2 -2
  16. package/dist/index146.js +1 -1
  17. package/dist/index148.js +2 -2
  18. package/dist/index150.js +1 -1
  19. package/dist/index151.js +2 -2
  20. package/dist/index16.js +3 -3
  21. package/dist/index18.js +3 -3
  22. package/dist/index20.js +9 -9
  23. package/dist/index22.js +14 -14
  24. package/dist/index224.js +2 -138
  25. package/dist/index225.js +138 -2
  26. package/dist/index226.js +2 -2
  27. package/dist/index227.js +86 -4
  28. package/dist/index229.js +29 -19
  29. package/dist/index230.js +17 -5
  30. package/dist/index231.js +51 -5
  31. package/dist/index232.js +18 -5
  32. package/dist/index233.js +3 -5
  33. package/dist/index234.js +12 -3
  34. package/dist/index235.js +18 -2
  35. package/dist/index236.js +8 -6
  36. package/dist/index237.js +5 -8
  37. package/dist/index238.js +8 -268
  38. package/dist/index239.js +2 -52
  39. package/dist/index24.js +10 -10
  40. package/dist/index240.js +2 -52
  41. package/dist/index241.js +3 -32
  42. package/dist/index242.js +4 -60
  43. package/dist/index243.js +187 -4
  44. package/dist/index244.js +3 -8
  45. package/dist/index245.js +13 -10
  46. package/dist/index246.js +34 -3
  47. package/dist/index247.js +2 -4
  48. package/dist/index248.js +10 -3
  49. package/dist/index249.js +3 -373
  50. package/dist/index250.js +6 -0
  51. package/dist/index251.js +4 -160
  52. package/dist/index252.js +22 -0
  53. package/dist/index253.js +5 -7
  54. package/dist/index254.js +5 -2
  55. package/dist/index255.js +4 -4
  56. package/dist/index256.js +5 -5
  57. package/dist/index257.js +2 -5
  58. package/dist/index258.js +6 -3
  59. package/dist/index259.js +268 -6
  60. package/dist/index26.js +3 -3
  61. package/dist/index260.js +50 -14
  62. package/dist/index261.js +52 -2
  63. package/dist/index262.js +32 -11
  64. package/dist/index263.js +54 -80
  65. package/dist/index264.js +7 -0
  66. package/dist/index265.js +5 -30
  67. package/dist/index266.js +5 -17
  68. package/dist/index267.js +3 -51
  69. package/dist/index268.js +160 -18
  70. package/dist/index270.js +3 -18
  71. package/dist/index271.js +7 -9
  72. package/dist/index272.js +2 -2
  73. package/dist/index273.js +2 -2
  74. package/dist/index274.js +7 -34
  75. package/dist/index275.js +6 -32
  76. package/dist/index276.js +25 -28
  77. package/dist/index277.js +11 -0
  78. package/dist/index278.js +3 -4
  79. package/dist/index279.js +13 -25
  80. package/dist/index28.js +1 -1
  81. package/dist/index280.js +13 -106
  82. package/dist/index281.js +375 -0
  83. package/dist/index283.js +25 -0
  84. package/dist/index284.js +65 -7
  85. package/dist/index285.js +9 -44
  86. package/dist/index286.js +43 -52
  87. package/dist/index287.js +51 -11
  88. package/dist/index288.js +11 -13
  89. package/dist/index289.js +17 -22
  90. package/dist/index290.js +11 -17
  91. package/dist/index291.js +32 -11
  92. package/dist/index292.js +2 -2
  93. package/dist/index294.js +105 -20
  94. package/dist/index296.js +100 -3
  95. package/dist/index298.js +5 -23
  96. package/dist/index299.js +9 -3
  97. package/dist/index30.js +3 -3
  98. package/dist/index300.js +23 -2
  99. package/dist/index301.js +7 -6
  100. package/dist/index302.js +6 -7
  101. package/dist/index303.js +16 -3
  102. package/dist/index304.js +28 -5
  103. package/dist/index306.js +21 -7
  104. package/dist/index307.js +3 -280
  105. package/dist/index308.js +17 -2
  106. package/dist/index309.js +27 -15
  107. package/dist/index310.js +7 -2
  108. package/dist/index311.js +2 -16
  109. package/dist/index312.js +4 -2
  110. package/dist/index313.js +5 -27
  111. package/dist/index314.js +280 -2
  112. package/dist/index315.js +2 -2
  113. package/dist/index316.js +16 -2
  114. package/dist/index317.js +2 -2
  115. package/dist/index318.js +16 -2
  116. package/dist/index319.js +2 -28
  117. package/dist/index32.js +2 -2
  118. package/dist/index320.js +27 -2
  119. package/dist/index321.js +2 -3
  120. package/dist/index322.js +2 -17
  121. package/dist/index323.js +2 -3
  122. package/dist/index324.js +2 -3
  123. package/dist/index325.js +1 -1
  124. package/dist/index326.js +2 -4
  125. package/dist/index327.js +127 -0
  126. package/dist/index328.js +2 -7
  127. package/dist/index329.js +15 -3
  128. package/dist/index330.js +2 -125
  129. package/dist/index331.js +19 -2
  130. package/dist/index332.js +2 -15
  131. package/dist/index333.js +3 -2
  132. package/dist/index334.js +5 -19
  133. package/dist/index335.js +2 -2
  134. package/dist/index336.js +3 -719
  135. package/dist/index337.js +4 -366
  136. package/dist/index338.js +5 -56
  137. package/dist/index339.js +1 -1
  138. package/dist/index34.js +8 -8
  139. package/dist/index340.js +1 -1
  140. package/dist/index343.js +7 -6
  141. package/dist/index344.js +719 -2
  142. package/dist/index345.js +366 -5
  143. package/dist/index346.js +56 -66
  144. package/dist/index347.js +3 -67
  145. package/dist/index348.js +5 -4
  146. package/dist/index349.js +7 -5
  147. package/dist/index350.js +34 -6
  148. package/dist/index351.js +128 -17
  149. package/dist/index352.js +397 -7
  150. package/dist/index353.js +6 -14
  151. package/dist/index354.js +17 -5
  152. package/dist/index355.js +8 -34
  153. package/dist/index356.js +12 -127
  154. package/dist/index357.js +83 -389
  155. package/dist/index358.js +226 -198
  156. package/dist/index359.js +65 -257
  157. package/dist/index36.js +4 -4
  158. package/dist/index360.js +66 -21
  159. package/dist/index361.js +24 -0
  160. package/dist/index364.js +200 -2
  161. package/dist/index365.js +259 -2
  162. package/dist/index366.js +2 -228
  163. package/dist/index367.js +2 -482
  164. package/dist/index368.js +468 -114
  165. package/dist/index369.js +127 -46
  166. package/dist/index370.js +44 -67
  167. package/dist/index371.js +66 -516
  168. package/dist/index372.js +515 -45
  169. package/dist/index373.js +52 -0
  170. package/dist/index38.js +20 -20
  171. package/dist/index40.js +7 -7
  172. package/dist/index42.js +2 -2
  173. package/dist/index44.js +8 -8
  174. package/dist/index46.js +6 -6
  175. package/dist/index50.js +2 -2
  176. package/dist/index54.js +1 -1
  177. package/dist/index56.js +1 -1
  178. package/dist/index58.js +2 -2
  179. package/dist/index60.js +2 -2
  180. package/dist/index62.js +5 -5
  181. package/dist/index68.js +1 -1
  182. package/dist/index74.js +4 -4
  183. package/dist/index82.js +194 -179
  184. package/dist/index84.js +49 -47
  185. package/dist/index86.js +2 -2
  186. package/dist/index88.js +3 -3
  187. package/dist/index90.js +1 -1
  188. package/dist/index93.js +3 -3
  189. package/dist/index95.js +2 -2
  190. package/dist/index97.js +5 -5
  191. package/dist/index99.js +1 -1
  192. package/dist/utilities/functions/normalizeItemGroups.d.ts +13 -0
  193. package/package.json +1 -1
  194. package/dist/index228.js +0 -15
  195. package/dist/index269.js +0 -14
  196. package/dist/index282.js +0 -102
  197. package/dist/index295.js +0 -190
  198. package/dist/index297.js +0 -11
  199. package/dist/index305.js +0 -69
  200. package/dist/index342.js +0 -7
  201. package/dist/index362.js +0 -95
@@ -49,13 +49,18 @@
49
49
  :placement="placement"
50
50
  ></slot>
51
51
  <template
52
- v-for="({ original, ...item }, index) in mappedItems"
52
+ v-for="({ original, isGroupStart, ...item }, index) in mappedItems"
53
53
  :key="item.key"
54
54
  >
55
+ <hr
56
+ v-if="isGroupStart && index > 0"
57
+ aria-hidden="true"
58
+ class="bb-dropdown__divider"
59
+ />
55
60
  <slot
56
61
  :disabled="item.disabled"
57
62
  :index="index"
58
- :item="items[index]"
63
+ :item="flatItems[index]"
59
64
  :name="`item:prepend`"
60
65
  :open="open"
61
66
  :placement="placement"
@@ -66,7 +71,7 @@
66
71
  class="bb-dropdown__item"
67
72
  :class="{
68
73
  'bb-dropdown__item--first': index === 0,
69
- 'bb-dropdown__item--last': index === items.length - 1,
74
+ 'bb-dropdown__item--last': index === flatItems.length - 1,
70
75
  }"
71
76
  :data-dropdown-item="true"
72
77
  v-bind="item"
@@ -91,7 +96,7 @@
91
96
  ><slot
92
97
  :disabled="item.disabled"
93
98
  :index="index"
94
- :item="items[index]"
99
+ :item="flatItems[index]"
95
100
  :name="`item:append`"
96
101
  :open="open"
97
102
  :placement="placement"
@@ -122,15 +127,19 @@ import type { ColumnName } from '@/types/ColumnName';
122
127
  import { extractDomContainer } from '@/utilities/functions/extractDomContainer';
123
128
  import { useElementSize, useIntersectionObserver } from '@vueuse/core';
124
129
  import { parseWidthString } from '@/utilities/functions/parseWidthString';
130
+ import { normalizeItemGroups } from '@/utilities/functions/normalizeItemGroups';
125
131
  import type {
126
132
  BbDropdownProps,
127
133
  BbDropdownSlots,
134
+ FlatItem,
128
135
  Item,
129
136
  MappedItem,
130
137
  DropdownTrigger,
131
138
  } from './types';
132
139
 
133
- type InferredBodySlots = ColumnName<BbDropdownProps['items'][number]['key']>;
140
+ type InferredBodySlots = ColumnName<
141
+ FlatItem<BbDropdownProps['items'][number]>['key']
142
+ >;
134
143
  defineSlots<BbDropdownSlots>();
135
144
 
136
145
  const props = withDefaults(defineProps<BbDropdownProps>(), {
@@ -208,14 +217,35 @@ const { resume, pause } = useIntersectionObserver(
208
217
  { threshold: [0, 1], immediate: false }
209
218
  );
210
219
 
220
+ /**
221
+ * Items normalized into divider-separated groups. A flat `items` array yields a
222
+ * single group; nested arrays (or loose items around them) become their own
223
+ * groups. See {@link normalizeItemGroups}.
224
+ */
225
+ const itemGroups = computed(() => normalizeItemGroups(props.items));
226
+ /** Flattened view of {@link itemGroups}; keyboard navigation and indices are flat. */
227
+ const flatItems = computed(() => itemGroups.value.flat());
228
+ /** Flat indices that begin a new group, used to render dividers between groups. */
229
+ const groupStartIndices = computed(() => {
230
+ const set = new Set<number>();
231
+ let offset = 0;
232
+ for (const group of itemGroups.value) {
233
+ set.add(offset);
234
+ offset += group.length;
235
+ }
236
+ return set;
237
+ });
238
+
211
239
  const mappedItems = computed(() => {
212
- let firstFocusableIndex: number = props.items.findIndex((el) => !el.disabled);
240
+ let firstFocusableIndex: number = flatItems.value.findIndex(
241
+ (el) => !el.disabled
242
+ );
213
243
  let lastFocusableIndex: number = findRightIndex(
214
- props.items,
244
+ flatItems.value,
215
245
  (item) => !item.disabled
216
246
  );
217
247
 
218
- return props.items.map((item, index) => {
248
+ return flatItems.value.map((item, index) => {
219
249
  const itemid = `${id}-item-${item.key}`;
220
250
  const { onClick: handler, ...rest } = item;
221
251
 
@@ -261,7 +291,7 @@ const mappedItems = computed(() => {
261
291
  event.preventDefault();
262
292
  if (index !== firstFocusableIndex) {
263
293
  const indexOfPrevious = findRightIndex(
264
- props.items,
294
+ flatItems.value,
265
295
  (item, i) => i < index && !item.disabled
266
296
  );
267
297
  const options = Array.from(
@@ -302,6 +332,7 @@ const mappedItems = computed(() => {
302
332
  key: item.key.split(/\W+/g).join('_').toLowerCase() as InferredBodySlots,
303
333
  disabled: rest.disabled || props.disabled,
304
334
  id: itemid,
335
+ isGroupStart: groupStartIndices.value.has(index),
305
336
  onClick,
306
337
  onKeydown,
307
338
  };
@@ -379,9 +410,9 @@ const onPointerUp = () => {
379
410
 
380
411
  const onKeydown = async (event: KeyboardEvent) => {
381
412
  if (props.disabled) return;
382
- const firstFocusableIndex = props.items.findIndex((el) => !el.disabled);
413
+ const firstFocusableIndex = flatItems.value.findIndex((el) => !el.disabled);
383
414
  const lastFocusableIndex = findRightIndex(
384
- props.items,
415
+ flatItems.value,
385
416
  (item) => !item.disabled
386
417
  );
387
418
 
@@ -592,6 +623,16 @@ export type Item = Omit<BaseButtonProps, 'block' | 'tag' | 'type'> & {
592
623
  'append:icon'?: IconType;
593
624
  };
594
625
 
626
+ /**
627
+ * Items accepted by the dropdown. A flat list renders a single group with no
628
+ * dividers; a nested array introduces a divider before and after the group.
629
+ * The two shapes can be mixed, e.g. `[item, item, [item, item], item]`.
630
+ */
631
+ export type Items = (Item | Item[])[];
632
+
633
+ /** Unwraps the item type out of the (possibly nested) {@link Items} shape. */
634
+ export type FlatItem<T> = T extends (infer U)[] ? U : T;
635
+
595
636
  export type MappedItem = Item & {
596
637
  /**
597
638
  * Identifier of the element among its siblings.
@@ -635,8 +676,12 @@ export type BbDropdownProps = Pick<
635
676
  * Array used to render each dropdown button.
636
677
  * They can act as `button`, as `a`, or as `router-link`
637
678
  * as they are based on the functionality provided by `BaseButton`.
679
+ *
680
+ * Pass a flat array for a single group, or nest arrays to split the items
681
+ * into divider-separated groups. The two shapes can be mixed, e.g.
682
+ * `[item, item, [item, item], item]`.
638
683
  */
639
- items: Item[];
684
+ items: Items;
640
685
  /**
641
686
  * Name of the theme to apply to the component. It creates a CSS class with the name of the theme.
642
687
  *
@@ -696,7 +741,7 @@ export type BbDropdownItemSlotProps = {
696
741
  /** The zero-based index of this item. */
697
742
  index: number;
698
743
  /** The raw item object from the `items` prop. */
699
- item: BbDropdownProps['items'][number];
744
+ item: FlatItem<BbDropdownProps['items'][number]>;
700
745
  /** Whether the dropdown panel is currently open. */
701
746
  open: boolean;
702
747
  /** The current placement of the dropdown panel. */
@@ -745,6 +790,14 @@ export type BbDropdownSlots = {
745
790
  display: inline-grid;
746
791
  grid-template-columns: 1fr;
747
792
  padding: 6px;
793
+ .bb-dropdown__divider {
794
+ /* Negative inline margins cancel the container padding so the rule
795
+ * spans the full width of the dropdown panel, edge to edge. */
796
+ border: none;
797
+ border-top: 1px solid color-mix(in srgb, var(--bb-text) 15%, transparent);
798
+ height: 0;
799
+ margin: 6px -6px;
800
+ }
748
801
  .bb-dropdown__item {
749
802
  border-radius: var(--bb-radius);
750
803
  column-gap: 6px;
@@ -85,7 +85,7 @@
85
85
  <slot name="item:prepend" v-bind="data" />
86
86
  </template>
87
87
  <!-- @vue-ignore - wrong inferred type -->
88
- <template v-for="item in mappedItems" #[item.key]="data">
88
+ <template v-for="item in flatMappedItems" #[item.key]="data">
89
89
  <slot :name="item.key" v-bind="data" />
90
90
  </template>
91
91
  <template #item:append="data">
@@ -103,6 +103,7 @@ import BbDropdown from '../BbDropdown/BbDropdown.vue';
103
103
  import { ref } from 'vue';
104
104
  import { BbIcon, BbSpinner } from '@/index';
105
105
  import { useLocale } from '@/composables/useLocale';
106
+ import type { Item } from '../BbDropdown/types';
106
107
  import type { BbDropdownButtonProps, BbDropdownButtonSlots } from './types';
107
108
 
108
109
  type Sizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
@@ -131,23 +132,34 @@ const wrapClick =
131
132
  internalLoading.value--;
132
133
  };
133
134
 
134
- const mappedItems = computed(() =>
135
- props.items.map((el) => {
136
- if (el.onClick)
137
- return {
138
- ...el,
139
- key: el.key.split(/\W+/g).join('_').toLowerCase(),
140
- onClick: wrapClick(el.onClick),
141
- };
135
+ const transformItem = (el: Item) => {
136
+ if (el.onClick)
142
137
  return {
143
138
  ...el,
144
139
  key: el.key.split(/\W+/g).join('_').toLowerCase(),
140
+ onClick: wrapClick(el.onClick),
145
141
  };
146
- })
142
+ return {
143
+ ...el,
144
+ key: el.key.split(/\W+/g).join('_').toLowerCase(),
145
+ };
146
+ };
147
+
148
+ /**
149
+ * Items with leaf transforms applied while preserving the (possibly nested)
150
+ * group structure, so dividers passed down to `BbDropdown` are kept intact.
151
+ */
152
+ const mappedItems = computed(() =>
153
+ props.items.map((entry) =>
154
+ Array.isArray(entry) ? entry.map(transformItem) : transformItem(entry)
155
+ )
147
156
  );
148
157
 
158
+ /** Flattened view used for the main button and per-item named slots. */
159
+ const flatMappedItems = computed(() => mappedItems.value.flat());
160
+
149
161
  const mainBtn = computed(() => {
150
- const base = { ...mappedItems.value[0] };
162
+ const base = { ...flatMappedItems.value[0] };
151
163
  base.disabled = base.disabled || props.disabled;
152
164
  return base;
153
165
  });
@@ -178,7 +190,11 @@ const sizeAttributes = Object.entries<Sizes>(baseSize).reduce(
178
190
  ## Types
179
191
 
180
192
  ```ts
181
- import type { BbDropdownProps, MappedItem } from '../BbDropdown/types';
193
+ import type {
194
+ BbDropdownProps,
195
+ FlatItem,
196
+ MappedItem,
197
+ } from '../BbDropdown/types';
182
198
  import type { IconType } from '@/types/Icon';
183
199
 
184
200
  type Sizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
@@ -269,7 +285,7 @@ export type BbDropdownButtonItemSlotProps = {
269
285
  /** The zero-based index of this item. */
270
286
  index: number;
271
287
  /** The raw item object from the `items` prop. */
272
- item: BbDropdownProps['items'][number];
288
+ item: FlatItem<BbDropdownProps['items'][number]>;
273
289
  /** Whether the dropdown panel is currently open. */
274
290
  open: boolean;
275
291
  /** The current placement of the dropdown panel. */
@@ -20,6 +20,14 @@ export type Item = Omit<BaseButtonProps, 'block' | 'tag' | 'type'> & {
20
20
  */
21
21
  'append:icon'?: IconType;
22
22
  };
23
+ /**
24
+ * Items accepted by the dropdown. A flat list renders a single group with no
25
+ * dividers; a nested array introduces a divider before and after the group.
26
+ * The two shapes can be mixed, e.g. `[item, item, [item, item], item]`.
27
+ */
28
+ export type Items = (Item | Item[])[];
29
+ /** Unwraps the item type out of the (possibly nested) {@link Items} shape. */
30
+ export type FlatItem<T> = T extends (infer U)[] ? U : T;
23
31
  export type MappedItem = Item & {
24
32
  /**
25
33
  * Identifier of the element among its siblings.
@@ -53,8 +61,12 @@ export type BbDropdownProps = Pick<CommonProps, 'arrowPadding' | 'disabled' | 'e
53
61
  * Array used to render each dropdown button.
54
62
  * They can act as `button`, as `a`, or as `router-link`
55
63
  * as they are based on the functionality provided by `BaseButton`.
64
+ *
65
+ * Pass a flat array for a single group, or nest arrays to split the items
66
+ * into divider-separated groups. The two shapes can be mixed, e.g.
67
+ * `[item, item, [item, item], item]`.
56
68
  */
57
- items: Item[];
69
+ items: Items;
58
70
  /**
59
71
  * Name of the theme to apply to the component. It creates a CSS class with the name of the theme.
60
72
  *
@@ -110,7 +122,7 @@ export type BbDropdownItemSlotProps = {
110
122
  /** The zero-based index of this item. */
111
123
  index: number;
112
124
  /** The raw item object from the `items` prop. */
113
- item: BbDropdownProps['items'][number];
125
+ item: FlatItem<BbDropdownProps['items'][number]>;
114
126
  /** Whether the dropdown panel is currently open. */
115
127
  open: boolean;
116
128
  /** The current placement of the dropdown panel. */
@@ -1,4 +1,4 @@
1
- import { BbDropdownProps, MappedItem } from '../BbDropdown/types';
1
+ import { BbDropdownProps, FlatItem, MappedItem } from '../BbDropdown/types';
2
2
  import { IconType } from '../../types/Icon';
3
3
  type Sizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
4
4
  export type BbDropdownButtonProps = Pick<BbDropdownProps, 'arrowPadding' | 'disabled' | 'eager' | 'id' | 'items' | 'offset' | 'padding' | 'placement' | 'theme' | 'transitionDuration' | 'width'> & {
@@ -63,7 +63,7 @@ export type BbDropdownButtonItemSlotProps = {
63
63
  /** The zero-based index of this item. */
64
64
  index: number;
65
65
  /** The raw item object from the `items` prop. */
66
- item: BbDropdownProps['items'][number];
66
+ item: FlatItem<BbDropdownProps['items'][number]>;
67
67
  /** Whether the dropdown panel is currently open. */
68
68
  open: boolean;
69
69
  /** The current placement of the dropdown panel. */