bitboss-ui 2.1.113 → 2.1.115

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 (423) hide show
  1. package/dist/ai/BaseButton.md +448 -0
  2. package/dist/ai/BaseCheckbox.md +494 -0
  3. package/dist/ai/BaseCheckboxGroup.md +597 -0
  4. package/dist/ai/BaseColorInput.md +461 -0
  5. package/dist/ai/BaseDatePicker.md +739 -0
  6. package/dist/ai/BaseDatePickerInput.md +1517 -0
  7. package/dist/ai/BaseDialog.md +610 -0
  8. package/dist/ai/BaseInputContainer.md +570 -0
  9. package/dist/ai/BaseNumberInput.md +509 -0
  10. package/dist/ai/BaseRadio.md +405 -0
  11. package/dist/ai/BaseRadioGroup.md +535 -0
  12. package/dist/ai/BaseRating.md +489 -0
  13. package/dist/ai/BaseSelect.md +1720 -0
  14. package/dist/ai/BaseSlider.md +871 -0
  15. package/dist/ai/BaseSwitch.md +322 -0
  16. package/dist/ai/BaseSwitchGroup.md +298 -0
  17. package/dist/ai/BaseTag.md +624 -0
  18. package/dist/ai/BaseTextInput.md +392 -0
  19. package/dist/ai/BaseTextarea.md +398 -0
  20. package/dist/ai/BbAccordion.md +135 -0
  21. package/dist/ai/BbAlert.md +226 -0
  22. package/dist/ai/BbAvatar.md +200 -0
  23. package/dist/ai/BbBadge.md +185 -0
  24. package/dist/ai/BbBreadcrumbs.md +536 -0
  25. package/dist/ai/BbButton.md +687 -0
  26. package/dist/ai/BbCheckbox.md +280 -0
  27. package/dist/ai/BbCheckboxGroup.md +387 -0
  28. package/dist/ai/BbChip.md +148 -0
  29. package/dist/ai/BbCollapsible.md +119 -0
  30. package/dist/ai/BbColorInput.md +345 -0
  31. package/dist/ai/BbColorPalette.md +360 -0
  32. package/dist/ai/BbConfirm.md +160 -0
  33. package/dist/ai/BbDatePickerInput.md +414 -0
  34. package/dist/ai/BbDialog.md +135 -0
  35. package/dist/ai/BbDropdown.md +765 -0
  36. package/dist/ai/BbDropdownButton.md +629 -0
  37. package/dist/ai/BbDropzone.md +504 -0
  38. package/dist/ai/BbIcon.md +238 -0
  39. package/dist/ai/BbIntersection.md +121 -0
  40. package/dist/ai/BbNumberInput.md +372 -0
  41. package/dist/ai/BbOffCanvas.md +549 -0
  42. package/dist/ai/BbPagination.md +562 -0
  43. package/dist/ai/BbPopover.md +580 -0
  44. package/dist/ai/BbProgress.md +97 -0
  45. package/dist/ai/BbRadio.md +256 -0
  46. package/dist/ai/BbRadioGroup.md +373 -0
  47. package/dist/ai/BbRating.md +245 -0
  48. package/dist/ai/BbRatio.md +62 -0
  49. package/dist/ai/BbRows.md +307 -0
  50. package/dist/ai/BbSelect.md +562 -0
  51. package/dist/ai/BbSelectPopover.md +2010 -0
  52. package/dist/ai/BbSlider.md +274 -0
  53. package/dist/ai/BbSmoothHeight.md +167 -0
  54. package/dist/ai/BbSpinner.md +154 -0
  55. package/dist/ai/BbSwitch.md +151 -0
  56. package/dist/ai/BbSwitchGroup.md +237 -0
  57. package/dist/ai/BbTab.md +954 -0
  58. package/dist/ai/BbTable.md +1624 -0
  59. package/dist/ai/BbTag.md +315 -0
  60. package/dist/ai/BbTextInput.md +357 -0
  61. package/dist/ai/BbTextarea.md +277 -0
  62. package/dist/ai/BbToast.md +219 -0
  63. package/dist/ai/BbTooltip.md +353 -0
  64. package/dist/ai/BbTree.md +271 -0
  65. package/dist/ai/ChipsBox.md +211 -0
  66. package/dist/ai/ClearableButton.md +67 -0
  67. package/dist/ai/CommaBox.md +212 -0
  68. package/dist/ai/CommonInputInnerContainer.md +419 -0
  69. package/dist/ai/CommonInputOuterContainer.md +56 -0
  70. package/dist/ai/CommonPopover.md +446 -0
  71. package/dist/ai/ErrorIcon.md +61 -0
  72. package/dist/ai/FlatListBox.md +382 -0
  73. package/dist/ai/GroupedListBox.md +538 -0
  74. package/dist/ai/ListBox.md +234 -0
  75. package/dist/ai/OptionsContainer.md +257 -0
  76. package/dist/ai/index.md +124 -0
  77. package/dist/components/BaseButton/BaseButton.vue.d.ts +2 -163
  78. package/dist/components/BaseButton/types.d.ts +158 -0
  79. package/dist/components/BaseCheckbox/BaseCheckbox.vue.d.ts +4 -4
  80. package/dist/components/BaseCheckboxGroup/BaseCheckboxGroup.vue.d.ts +2 -2
  81. package/dist/components/BaseCheckboxGroup/types.d.ts +16 -9
  82. package/dist/components/BaseColorInput/BaseColorInput.vue.d.ts +12 -52
  83. package/dist/components/BaseDatePicker/BaseDatePicker.vue.d.ts +4 -76
  84. package/dist/components/BaseDatePicker/types.d.ts +100 -0
  85. package/dist/components/BaseDatePickerInput/BaseDatePickerInput.vue.d.ts +18 -315
  86. package/dist/components/BaseDatePickerInput/types.d.ts +206 -0
  87. package/dist/components/BaseDialog/BaseDialog.vue.d.ts +6 -156
  88. package/dist/components/BaseDialog/types.d.ts +180 -0
  89. package/dist/components/BaseInputContainer/BaseInputContainer.vue.d.ts +1 -107
  90. package/dist/components/BaseInputContainer/types.d.ts +126 -0
  91. package/dist/components/BaseNumberInput/BaseNumberInput.vue.d.ts +7 -170
  92. package/dist/components/BaseNumberInput/types.d.ts +191 -0
  93. package/dist/components/BaseRadio/BaseRadio.vue.d.ts +6 -119
  94. package/dist/components/BaseRadio/types.d.ts +173 -0
  95. package/dist/components/BaseRadioGroup/BaseRadioGroup.vue.d.ts +4 -274
  96. package/dist/components/BaseRadioGroup/types.d.ts +240 -0
  97. package/dist/components/BaseRating/BaseRating.vue.d.ts +5 -106
  98. package/dist/components/BaseRating/types.d.ts +144 -0
  99. package/dist/components/BaseSelect/BaseSelect.vue.d.ts +2 -363
  100. package/dist/components/BaseSelect/types.d.ts +457 -0
  101. package/dist/components/BaseSlider/BaseSlider.vue.d.ts +6 -178
  102. package/dist/components/BaseSlider/types.d.ts +201 -0
  103. package/dist/components/BaseSwitch/BaseSwitch.vue.d.ts +7 -35
  104. package/dist/components/BaseSwitch/types.d.ts +25 -0
  105. package/dist/components/BaseSwitchGroup/BaseSwitchGroup.vue.d.ts +5 -11
  106. package/dist/components/BaseSwitchGroup/types.d.ts +8 -0
  107. package/dist/components/BaseTag/BaseTag.vue.d.ts +27 -222
  108. package/dist/components/BaseTag/types.d.ts +136 -0
  109. package/dist/components/BaseTextInput/BaseTextInput.vue.d.ts +5 -141
  110. package/dist/components/BaseTextInput/types.d.ts +166 -0
  111. package/dist/components/BaseTextarea/BaseTextarea.vue.d.ts +5 -131
  112. package/dist/components/BaseTextarea/types.d.ts +151 -0
  113. package/dist/components/BbAccordion/BbAccordion.vue.d.ts +3 -51
  114. package/dist/components/BbAccordion/types.d.ts +32 -0
  115. package/dist/components/BbAlert/BbAlert.vue.d.ts +3 -50
  116. package/dist/components/BbAlert/types.d.ts +42 -0
  117. package/dist/components/BbAvatar/BbAvatar.vue.d.ts +3 -23
  118. package/dist/components/BbAvatar/types.d.ts +34 -0
  119. package/dist/components/BbBadge/BbBadge.vue.d.ts +3 -40
  120. package/dist/components/BbBadge/types.d.ts +30 -0
  121. package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue.d.ts +14 -178
  122. package/dist/components/BbBreadcrumbs/types.d.ts +109 -0
  123. package/dist/components/BbButton/BbButton.vue.d.ts +4 -163
  124. package/dist/components/BbButton/types.d.ts +159 -0
  125. package/dist/components/BbCheckbox/BbCheckbox.vue.d.ts +7 -165
  126. package/dist/components/BbCheckbox/types.d.ts +130 -0
  127. package/dist/components/BbCheckboxGroup/BbCheckboxGroup.vue.d.ts +7 -324
  128. package/dist/components/BbCheckboxGroup/types.d.ts +189 -0
  129. package/dist/components/BbChip/BbChip.vue.d.ts +6 -28
  130. package/dist/components/BbChip/types.d.ts +23 -0
  131. package/dist/components/BbCollapsible/BbCollapsible.vue.d.ts +3 -24
  132. package/dist/components/BbCollapsible/types.d.ts +20 -0
  133. package/dist/components/BbColorInput/BbColorInput.vue.d.ts +10 -151
  134. package/dist/components/BbColorInput/types.d.ts +131 -0
  135. package/dist/components/BbColorPalette/BbColorPalette.vue.d.ts +2 -112
  136. package/dist/components/BbColorPalette/types.d.ts +127 -0
  137. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue.d.ts +6 -212
  138. package/dist/components/BbDatePickerInput/types.d.ts +180 -0
  139. package/dist/components/BbDialog/BbDialog.vue.d.ts +2 -2
  140. package/dist/components/BbDialog/types.d.ts +1 -0
  141. package/dist/components/BbDropdown/BbDropdown.vue.d.ts +21 -247
  142. package/dist/components/BbDropdown/types.d.ts +147 -0
  143. package/dist/components/BbDropdownButton/BbDropdownButton.vue.d.ts +16 -209
  144. package/dist/components/BbDropdownButton/types.d.ts +114 -0
  145. package/dist/components/BbDropzone/BbDropzone.vue.d.ts +7 -86
  146. package/dist/components/BbDropzone/types.d.ts +67 -0
  147. package/dist/components/BbIcon/BbIcon.vue.d.ts +2 -26
  148. package/dist/components/BbIcon/types.d.ts +28 -0
  149. package/dist/components/BbIntersection/BbIntersection.vue.d.ts +3 -41
  150. package/dist/components/BbIntersection/types.d.ts +36 -0
  151. package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +44 -175
  152. package/dist/components/BbNumberInput/types.d.ts +130 -0
  153. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +5 -93
  154. package/dist/components/BbOffCanvas/types.d.ts +97 -0
  155. package/dist/components/BbPagination/BbPagination.vue.d.ts +4 -87
  156. package/dist/components/BbPagination/types.d.ts +80 -0
  157. package/dist/components/BbPopover/BbPopover.vue.d.ts +9 -135
  158. package/dist/components/BbPopover/types.d.ts +99 -0
  159. package/dist/components/BbProgress/BbProgress.vue.d.ts +2 -14
  160. package/dist/components/BbProgress/types.d.ts +20 -0
  161. package/dist/components/BbRadio/BbRadio.vue.d.ts +7 -150
  162. package/dist/components/BbRadio/types.d.ts +117 -0
  163. package/dist/components/BbRadioGroup/BbRadioGroup.vue.d.ts +7 -322
  164. package/dist/components/BbRadioGroup/types.d.ts +182 -0
  165. package/dist/components/BbRating/BbRating.vue.d.ts +10 -113
  166. package/dist/components/BbRating/types.d.ts +105 -0
  167. package/dist/components/BbRatio/BbRatio.vue.d.ts +3 -18
  168. package/dist/components/BbRatio/types.d.ts +15 -0
  169. package/dist/components/BbSelect/BbSelect.vue.d.ts +7 -375
  170. package/dist/components/BbSelect/types.d.ts +351 -0
  171. package/dist/components/BbSelectPopover/BbSelectPopover.vue.d.ts +1 -1
  172. package/dist/components/BbSelectPopover/types.d.ts +351 -0
  173. package/dist/components/BbSlider/BbSlider.vue.d.ts +10 -129
  174. package/dist/components/BbSlider/types.d.ts +123 -0
  175. package/dist/components/BbSmoothHeight/BbSmoothHeight.vue.d.ts +2 -23
  176. package/dist/components/BbSmoothHeight/types.d.ts +24 -0
  177. package/dist/components/BbSpinner/BbSpinner.vue.d.ts +3 -5
  178. package/dist/components/BbSpinner/types.d.ts +8 -0
  179. package/dist/components/BbSwitch/BbSwitch.vue.d.ts +9 -65
  180. package/dist/components/BbSwitch/types.d.ts +29 -0
  181. package/dist/components/BbSwitchGroup/BbSwitchGroup.vue.d.ts +7 -190
  182. package/dist/components/BbSwitchGroup/types.d.ts +81 -0
  183. package/dist/components/BbTab/BbTab.vue.d.ts +9 -247
  184. package/dist/components/BbTab/types.d.ts +186 -0
  185. package/dist/components/BbTag/BbTag.vue.d.ts +6 -156
  186. package/dist/components/BbTag/types.d.ts +158 -0
  187. package/dist/components/BbTextInput/BbTextInput.vue.d.ts +10 -152
  188. package/dist/components/BbTextInput/types.d.ts +137 -0
  189. package/dist/components/BbTextarea/BbTextarea.vue.d.ts +10 -142
  190. package/dist/components/BbTextarea/types.d.ts +123 -0
  191. package/dist/components/BbToast/BbToast.vue.d.ts +2 -6
  192. package/dist/components/BbToast/types.d.ts +8 -0
  193. package/dist/components/BbTooltip/BbTooltip.vue.d.ts +8 -65
  194. package/dist/components/BbTooltip/types.d.ts +55 -0
  195. package/dist/components/BbTree/BbTree.vue.d.ts +2 -65
  196. package/dist/components/BbTree/types.d.ts +69 -0
  197. package/dist/components/{ChipsBox.vue.d.ts → ChipsBox/ChipsBox.vue.d.ts} +5 -6
  198. package/dist/components/ChipsBox/types.d.ts +14 -0
  199. package/dist/components/{ClearableButton.vue.d.ts → ClearableButton/ClearableButton.vue.d.ts} +2 -0
  200. package/dist/components/ClearableButton/types.d.ts +3 -0
  201. package/dist/components/{CommaBox.vue.d.ts → CommaBox/CommaBox.vue.d.ts} +5 -6
  202. package/dist/components/CommaBox/types.d.ts +14 -0
  203. package/dist/components/CommonInputInnerContainer/CommonInputInnerContainer.vue.d.ts +25 -0
  204. package/dist/components/CommonInputInnerContainer/types.d.ts +47 -0
  205. package/dist/components/CommonInputOuterContainer/CommonInputOuterContainer.vue.d.ts +17 -0
  206. package/dist/components/CommonInputOuterContainer/types.d.ts +16 -0
  207. package/dist/components/{CommonPopover.vue.d.ts → CommonPopover/CommonPopover.vue.d.ts} +5 -30
  208. package/dist/components/CommonPopover/types.d.ts +43 -0
  209. package/dist/components/{ErrorIcon.vue.d.ts → ErrorIcon/ErrorIcon.vue.d.ts} +2 -0
  210. package/dist/components/ErrorIcon/types.d.ts +3 -0
  211. package/dist/components/FlatListBox/types.d.ts +97 -0
  212. package/dist/components/GroupedListBox/types.d.ts +118 -0
  213. package/dist/components/ListBox/ListBox.vue.d.ts +30 -0
  214. package/dist/components/ListBox/types.d.ts +133 -0
  215. package/dist/components/OptionsContainer/OptionsContainer.vue.d.ts +13 -0
  216. package/dist/components/OptionsContainer/types.d.ts +96 -0
  217. package/dist/composables/useBbConfig.d.ts +1 -1
  218. package/dist/composables/useConfirm.d.ts +1 -1
  219. package/dist/index.css +1 -1
  220. package/dist/index.d.ts +18 -18
  221. package/dist/index109.js +9 -9
  222. package/dist/index110.js +50 -49
  223. package/dist/index114.js +1 -1
  224. package/dist/index118.js +1 -1
  225. package/dist/index122.js +1 -0
  226. package/dist/index124.js +4 -4
  227. package/dist/index126.js +13 -13
  228. package/dist/index132.js +22 -19
  229. package/dist/index134.js +1 -1
  230. package/dist/index136.js +5 -5
  231. package/dist/index138.js +1 -1
  232. package/dist/index14.js +1 -1
  233. package/dist/index140.js +18 -17
  234. package/dist/index144.js +1 -1
  235. package/dist/index146.js +2 -2
  236. package/dist/index149.js +2 -2
  237. package/dist/index16.js +3 -3
  238. package/dist/index18.js +3 -3
  239. package/dist/index20.js +70 -59
  240. package/dist/index22.js +14 -14
  241. package/dist/index221.js +138 -2
  242. package/dist/index222.js +2 -138
  243. package/dist/index224.js +5 -34
  244. package/dist/index225.js +7 -32
  245. package/dist/index226.js +32 -26
  246. package/dist/index227.js +7 -0
  247. package/dist/index228.js +5 -5
  248. package/dist/index229.js +5 -8
  249. package/dist/index230.js +5 -7
  250. package/dist/index231.js +3 -2
  251. package/dist/index232.js +2 -9
  252. package/dist/index233.js +6 -13
  253. package/dist/index234.js +8 -3
  254. package/dist/index235.js +268 -2
  255. package/dist/index236.js +52 -11
  256. package/dist/index237.js +50 -6
  257. package/dist/index238.js +32 -3
  258. package/dist/index239.js +60 -3
  259. package/dist/index24.js +10 -10
  260. package/dist/index240.js +13 -2
  261. package/dist/index241.js +187 -17
  262. package/dist/index242.js +3 -12
  263. package/dist/index243.js +2 -51
  264. package/dist/index244.js +2 -18
  265. package/dist/index245.js +2 -12
  266. package/dist/index246.js +12 -16
  267. package/dist/index247.js +11 -28
  268. package/dist/index248.js +48 -15
  269. package/dist/index249.js +17 -4
  270. package/dist/index250.js +2 -2
  271. package/dist/index252.js +2 -2
  272. package/dist/index254.js +3 -135
  273. package/dist/index255.js +4 -0
  274. package/dist/index256.js +4 -107
  275. package/dist/index257.js +19 -12
  276. package/dist/index258.js +6 -2
  277. package/dist/index259.js +16 -7
  278. package/dist/index26.js +3 -3
  279. package/dist/index260.js +86 -7
  280. package/dist/index262.js +32 -0
  281. package/dist/index263.js +18 -5
  282. package/dist/index264.js +12 -5
  283. package/dist/index265.js +18 -5
  284. package/dist/index266.js +2 -5
  285. package/dist/index267.js +7 -5
  286. package/dist/index268.js +7 -5
  287. package/dist/index269.js +3 -67
  288. package/dist/index270.js +4 -33
  289. package/dist/index271.js +5 -2
  290. package/dist/index272.js +5 -2
  291. package/dist/index273.js +5 -3
  292. package/dist/index274.js +135 -4
  293. package/dist/index276.js +9 -6
  294. package/dist/index277.js +7 -11
  295. package/dist/index278.js +23 -5
  296. package/dist/index279.js +3 -5
  297. package/dist/index28.js +57 -55
  298. package/dist/index280.js +21 -266
  299. package/dist/index281.js +364 -43
  300. package/dist/index283.js +32 -31
  301. package/dist/index284.js +3 -60
  302. package/dist/index285.js +25 -4
  303. package/dist/index286.js +3 -20
  304. package/dist/index287.js +18 -5
  305. package/dist/index288.js +12 -373
  306. package/dist/index289.js +109 -0
  307. package/dist/index290.js +11 -6
  308. package/dist/index291.js +66 -15
  309. package/dist/index292.js +32 -10
  310. package/dist/index294.js +5 -8
  311. package/dist/index295.js +9 -20
  312. package/dist/index296.js +2 -8
  313. package/dist/index297.js +9 -23
  314. package/dist/index298.js +52 -24
  315. package/dist/index299.js +5 -188
  316. package/dist/index30.js +3 -3
  317. package/dist/index300.js +21 -3
  318. package/dist/index301.js +28 -3
  319. package/dist/index303.js +9 -0
  320. package/dist/index304.js +2 -7
  321. package/dist/index305.js +280 -3
  322. package/dist/index306.js +2 -2
  323. package/dist/index307.js +16 -5
  324. package/dist/index308.js +2 -7
  325. package/dist/index309.js +16 -3
  326. package/dist/index310.js +2 -3
  327. package/dist/index311.js +27 -3
  328. package/dist/index312.js +2 -2
  329. package/dist/index313.js +2 -28
  330. package/dist/index314.js +2 -17
  331. package/dist/index315.js +2 -4
  332. package/dist/index316.js +1 -1
  333. package/dist/index317.js +28 -3
  334. package/dist/index318.js +2 -280
  335. package/dist/index319.js +7 -2
  336. package/dist/index32.js +2 -2
  337. package/dist/index320.js +719 -125
  338. package/dist/index321.js +366 -2
  339. package/dist/index322.js +56 -14
  340. package/dist/index323.js +4 -2
  341. package/dist/index324.js +3 -16
  342. package/dist/index325.js +17 -2
  343. package/dist/index326.js +3 -16
  344. package/dist/index327.js +3 -2
  345. package/dist/index328.js +3 -19
  346. package/dist/index329.js +3 -2
  347. package/dist/index330.js +120 -22
  348. package/dist/index331.js +2 -2
  349. package/dist/index332.js +15 -2
  350. package/dist/index333.js +2 -2
  351. package/dist/index334.js +19 -2
  352. package/dist/index335.js +2 -2
  353. package/dist/index336.js +5 -2
  354. package/dist/index337.js +5 -3
  355. package/dist/index338.js +2 -4
  356. package/dist/index339.js +4 -719
  357. package/dist/index34.js +8 -8
  358. package/dist/index340.js +2 -366
  359. package/dist/index341.js +3 -57
  360. package/dist/index342.js +3 -6
  361. package/dist/index343.js +6 -5
  362. package/dist/index344.js +6 -34
  363. package/dist/index345.js +17 -127
  364. package/dist/index346.js +7 -396
  365. package/dist/index347.js +14 -199
  366. package/dist/index348.js +5 -259
  367. package/dist/index349.js +6 -227
  368. package/dist/index352.js +35 -2
  369. package/dist/index353.js +129 -2
  370. package/dist/index354.js +378 -114
  371. package/dist/index355.js +92 -6
  372. package/dist/index356.js +226 -17
  373. package/dist/index357.js +22 -9
  374. package/dist/index359.js +7 -5
  375. package/dist/index36.js +4 -4
  376. package/dist/index360.js +200 -7
  377. package/dist/index361.js +255 -18
  378. package/dist/index362.js +136 -0
  379. package/dist/index363.js +2 -93
  380. package/dist/index364.js +2 -441
  381. package/dist/index365.js +427 -114
  382. package/dist/index366.js +127 -46
  383. package/dist/index367.js +44 -67
  384. package/dist/index368.js +66 -516
  385. package/dist/index369.js +515 -45
  386. package/dist/index370.js +52 -0
  387. package/dist/index38.js +133 -131
  388. package/dist/index40.js +8 -8
  389. package/dist/index42.js +2 -2
  390. package/dist/index44.js +16 -15
  391. package/dist/index46.js +4 -4
  392. package/dist/index50.js +28 -25
  393. package/dist/index54.js +1 -1
  394. package/dist/index56.js +1 -1
  395. package/dist/index58.js +2 -2
  396. package/dist/index60.js +2 -2
  397. package/dist/index62.js +5 -5
  398. package/dist/index66.js +3 -1
  399. package/dist/index68.js +1 -1
  400. package/dist/index74.js +4 -4
  401. package/dist/index82.js +6 -6
  402. package/dist/index84.js +1 -1
  403. package/dist/index86.js +2 -2
  404. package/dist/index88.js +3 -3
  405. package/dist/index90.js +1 -1
  406. package/dist/index93.js +3 -3
  407. package/dist/index95.js +2 -2
  408. package/dist/index97.js +5 -5
  409. package/dist/index99.js +1 -1
  410. package/dist/utilities/functions/parseSize.d.ts +1 -1
  411. package/package.json +5 -3
  412. package/dist/components/CommonInputInnerContainer.vue.d.ts +0 -81
  413. package/dist/components/CommonInputOuterContainer.vue.d.ts +0 -41
  414. package/dist/components/FlatListBox.vue.d.ts +0 -119
  415. package/dist/components/GroupedListBox.vue.d.ts +0 -153
  416. package/dist/components/ListBox.vue.d.ts +0 -170
  417. package/dist/components/OptionsContainer.vue.d.ts +0 -172
  418. package/dist/index261.js +0 -88
  419. package/dist/index275.js +0 -25
  420. package/dist/index282.js +0 -54
  421. package/dist/index293.js +0 -5
  422. package/dist/index302.js +0 -55
  423. package/dist/index358.js +0 -17
@@ -0,0 +1,1624 @@
1
+ # BbTable
2
+
3
+ ## Template & Script
4
+
5
+ ```vue
6
+ <template>
7
+ <component
8
+ :is="containerTag"
9
+ :aria-busy="loading"
10
+ :aria-rowcount="hasProvidedAccessibilityData ? props.totalItems : undefined"
11
+ :class="containerClass"
12
+ :inert="disabled"
13
+ >
14
+ <legend v-if="selectable" class="sr-only">{{ legend }}</legend>
15
+ <table ref="tableRef">
16
+ <caption
17
+ v-if="caption"
18
+ :class="{
19
+ 'bb-table-caption': true,
20
+ 'sr-only': !displayCaption,
21
+ }"
22
+ >
23
+ {{
24
+ caption
25
+ }}
26
+ </caption>
27
+ <thead>
28
+ <!-- @vue-ignore -->
29
+ <slot name="thead">
30
+ <tr
31
+ :aria-rowindex="hasProvidedAccessibilityData ? 1 : undefined"
32
+ class="bb-table-header-row"
33
+ >
34
+ <th
35
+ v-if="selectable"
36
+ class="bb-table-header bb-table-header--select"
37
+ :class="thClass"
38
+ scope="col"
39
+ >
40
+ <!-- @vue-ignore -->
41
+ <slot
42
+ :multiple="multiple"
43
+ :name="'header:select'"
44
+ :select-all="!!selectAll"
45
+ :text="selectText || t('table.selectText').value"
46
+ >
47
+ <span class="bb-table-header__content">
48
+ <label
49
+ v-if="allowSelectAll && multiple"
50
+ class="bb-table-check__label"
51
+ :class="{
52
+ 'bb-table-check__label--disabled': disabled,
53
+ }"
54
+ >
55
+ <BaseCheckbox
56
+ :key="indeterminate.toString()"
57
+ v-model="selectAll"
58
+ class="bb-table-check"
59
+ :disabled="disabled"
60
+ :indeterminate="indeterminate"
61
+ :name="`select_all_${name || ''}`"
62
+ :readonly="readonly"
63
+ />
64
+ <span class="bb-table-check__label-text sr-only"
65
+ >{{ selectAllLabel || t('table.selectAllLabel').value }}
66
+ </span>
67
+ </label>
68
+ <span
69
+ v-else-if="!multiple"
70
+ class="bb-table-radio__label-text sr-only"
71
+ >{{ selectText || t('table.selectText').value }}</span
72
+ >
73
+ </span>
74
+ </slot>
75
+ </th>
76
+ <th
77
+ v-for="header in mappedHeaders"
78
+ :key="header.key"
79
+ :aria-sort="header.sortDirection"
80
+ class="bb-table-header"
81
+ :class="header.classes"
82
+ scope="col"
83
+ >
84
+ <!-- @vue-ignore -->
85
+ <slot
86
+ :classes="header.classes"
87
+ :items="internalItems"
88
+ :label="header.label"
89
+ :name="header.slotName"
90
+ ><span class="bb-table-header__content">{{
91
+ header.label
92
+ }}</span></slot
93
+ >
94
+ </th>
95
+ <th
96
+ v-if="actions"
97
+ class="bb-table-header bb-table-header--actions"
98
+ :class="thClass"
99
+ scope="col"
100
+ >
101
+ <!-- @vue-ignore -->
102
+ <slot name="header:actions" :text="actionsText">
103
+ <span class="bb-table-header__content sr-only">
104
+ {{ actionsText }}
105
+ </span>
106
+ </slot>
107
+ </th>
108
+ </tr>
109
+ </slot>
110
+ </thead>
111
+ <tbody>
112
+ <slot v-if="loading" :items="internalItems" name="loading">
113
+ <template v-for="(_, rowIndex) in skeletonLength" :key="rowIndex">
114
+ <tr
115
+ :aria-rowindex="
116
+ hasProvidedAccessibilityData ? rowIndex + 2 : undefined
117
+ "
118
+ class="bb-table-skeleton__row"
119
+ >
120
+ <td
121
+ v-if="selectable"
122
+ class="bb-table-skeleton__cell bb-table-skeleton__cell--select"
123
+ >
124
+ <div class="bb-table-skeleton__placeholder" />
125
+ </td>
126
+ <td
127
+ v-for="(col, colIndex) in props.columns"
128
+ :key="col.key"
129
+ :class="[
130
+ 'bb-table-skeleton__cell',
131
+ `bb-table-skeleton__cell--${col.skeleton ?? 'text'}`,
132
+ ]"
133
+ >
134
+ <!-- text: 2 lines with dynamic widths -->
135
+ <template v-if="!col.skeleton || col.skeleton === 'text'">
136
+ <div class="bb-table-skeleton__cell-content">
137
+ <div
138
+ class="bb-table-skeleton__line"
139
+ :style="{
140
+ width: `${skeletonLineWidths[(rowIndex + colIndex) % 4]}%`,
141
+ }"
142
+ />
143
+ <div
144
+ class="bb-table-skeleton__line"
145
+ :style="{
146
+ width: `${skeletonLineWidths[(rowIndex + colIndex + 2) % 4]}%`,
147
+ }"
148
+ />
149
+ </div>
150
+ </template>
151
+ <!-- avatar: circle only -->
152
+ <div
153
+ v-else-if="col.skeleton === 'avatar'"
154
+ class="bb-table-skeleton__avatar"
155
+ />
156
+ <!-- avatar-text: avatar + 2 lines -->
157
+ <div
158
+ v-else-if="col.skeleton === 'avatar-text'"
159
+ class="bb-table-skeleton__avatar-text"
160
+ >
161
+ <div class="bb-table-skeleton__avatar" />
162
+ <div class="bb-table-skeleton__cell-content">
163
+ <div
164
+ class="bb-table-skeleton__line"
165
+ :style="{
166
+ width: `${skeletonLineWidths[(rowIndex + colIndex) % 4]}%`,
167
+ }"
168
+ />
169
+ <div
170
+ class="bb-table-skeleton__line"
171
+ :style="{
172
+ width: `${skeletonLineWidths[(rowIndex + colIndex + 2) % 4]}%`,
173
+ }"
174
+ />
175
+ </div>
176
+ </div>
177
+ <!-- image: rounded rect -->
178
+ <div
179
+ v-else-if="col.skeleton === 'image'"
180
+ class="bb-table-skeleton__image"
181
+ />
182
+ <!-- badge: small pill -->
183
+ <div
184
+ v-else-if="col.skeleton === 'badge'"
185
+ class="bb-table-skeleton__badge"
186
+ />
187
+ </td>
188
+ <td
189
+ v-if="actions"
190
+ class="bb-table-skeleton__cell bb-table-skeleton__cell--actions"
191
+ >
192
+ <div class="bb-table-skeleton__placeholder" />
193
+ </td>
194
+ </tr>
195
+ </template>
196
+ <tr
197
+ :aria-rowindex="
198
+ hasProvidedAccessibilityData ? skeletonLength + 2 : undefined
199
+ "
200
+ class="bb-table-loading__row bb-table-loading__row--sr-only"
201
+ >
202
+ <td
203
+ :colspan="replacementContentSpan"
204
+ class="bb-table-loading__cell"
205
+ aria-live="polite"
206
+ role="status"
207
+ >
208
+ <span class="bb-table-loading__text sr-only">{{
209
+ loadingText
210
+ }}</span>
211
+ </td>
212
+ </tr>
213
+ </slot>
214
+ <slot v-else-if="!options.length" :name="'no-data'">
215
+ <tr
216
+ :aria-rowindex="hasProvidedAccessibilityData ? 2 : undefined"
217
+ class="bb-table-no-data__row"
218
+ >
219
+ <td
220
+ class="bb-table-no-data__cell"
221
+ :colspan="replacementContentSpan"
222
+ >
223
+ <span class="bb-table-no-data__text">{{
224
+ noDataText || t('table.noDataText').value
225
+ }}</span>
226
+ </td>
227
+ </tr>
228
+ </slot>
229
+ <slot v-else name="tbody">
230
+ <template v-for="item in mappedItems" :key="item.valueHash">
231
+ <tr
232
+ :aria-rowindex="
233
+ hasProvidedAccessibilityData && item.rowIndex
234
+ ? item.rowIndex
235
+ : undefined
236
+ "
237
+ class="bb-table-data__row"
238
+ @click="item.onRowClick"
239
+ @contextmenu="item.onRowContextMenu"
240
+ @dblclick="item.onRowDblClick"
241
+ >
242
+ <td
243
+ v-if="selectable"
244
+ class="bb-table-data__cell bb-table-data__cell--select"
245
+ :class="tdClass"
246
+ >
247
+ <!-- @vue-ignore -->
248
+ <slot
249
+ :checked="isSelected(item)"
250
+ :disabled="!!item.disabled"
251
+ :input-name="randomName"
252
+ :item="item.item"
253
+ :name="'select'"
254
+ :readonly="!!readonly"
255
+ :value="item.value"
256
+ >
257
+ <!-- We use temp names for these inputs because we don't submit them -->
258
+ <label
259
+ v-if="multiple"
260
+ class="bb-table-check__label"
261
+ :class="{
262
+ 'bb-table-check__label--disabled': item.disabled,
263
+ }"
264
+ >
265
+ <BaseCheckbox
266
+ :checked="isSelected(item)"
267
+ class="bb-table-check"
268
+ :disabled="item.disabled"
269
+ :readonly="readonly"
270
+ @change="() => onInputChange(item)"
271
+ />
272
+ <span class="bb-table-check__label-text sr-only">{{
273
+ item.accessibleLabel
274
+ }}</span>
275
+ </label>
276
+
277
+ <label
278
+ v-else
279
+ class="bb-table-radio__label"
280
+ :class="{
281
+ 'bb-table-radio__label--disabled': item.disabled,
282
+ }"
283
+ >
284
+ <BaseRadio
285
+ :checked="item.selected"
286
+ class="bb-table-radio"
287
+ :disabled="item.disabled"
288
+ :name="randomName"
289
+ :readonly="readonly"
290
+ :value="item.value"
291
+ @change="() => onInputChange(item)"
292
+ />
293
+ <span class="bb-table-radio__label-text sr-only">{{
294
+ item.accessibleLabel
295
+ }}</span>
296
+ </label>
297
+ </slot>
298
+ </td>
299
+ <td
300
+ v-for="col in item.cols"
301
+ :key="col.key"
302
+ class="bb-table-data__cell"
303
+ :class="col.classes"
304
+ >
305
+ <!-- @vue-ignore -->
306
+ <slot
307
+ :classes="col.classes"
308
+ :content="col.content"
309
+ :expanded="item.expanded"
310
+ :item="item.item"
311
+ :name="col.slotName"
312
+ :expand-props="getExpandControllerProps(item)"
313
+ :toggle-expanded="() => toggleExpandedFor(item.valueHash)"
314
+ :value="item.value"
315
+ >{{ col.content }}</slot
316
+ >
317
+ </td>
318
+ <td
319
+ v-if="actions"
320
+ class="bb-table__cell bb-table__cell--actions"
321
+ :class="tdClass"
322
+ >
323
+ <!-- @vue-ignore -->
324
+ <slot
325
+ :expanded="item.expanded"
326
+ :item="item.item"
327
+ :name="'actions'"
328
+ :expand-props="getExpandControllerProps(item)"
329
+ :toggle-expanded="() => toggleExpandedFor(item.valueHash)"
330
+ :value="item.value"
331
+ ></slot>
332
+ </td>
333
+ </tr>
334
+ <tr
335
+ v-if="item.expanded"
336
+ :aria-rowindex="
337
+ hasProvidedAccessibilityData && item.rowIndex
338
+ ? item.rowIndex + 1
339
+ : undefined
340
+ "
341
+ :id="`expanded_${item.valueHash}`"
342
+ class="bb-table-expand__row"
343
+ >
344
+ <td
345
+ :colspan="replacementContentSpan"
346
+ class="bb-table-expand__cell"
347
+ >
348
+ <!-- @vue-ignore -->
349
+ <slot
350
+ :expanded="item.expanded"
351
+ :item="item.item"
352
+ :name="'expand'"
353
+ :expand-props="getExpandControllerProps(item)"
354
+ :toggle-expanded="() => toggleExpandedFor(item.valueHash)"
355
+ :value="item.value"
356
+ ></slot>
357
+ </td>
358
+ </tr>
359
+ </template>
360
+ </slot>
361
+ </tbody>
362
+ <tfoot>
363
+ <!-- @vue-ignore -->
364
+ <slot name="tfoot"></slot>
365
+ </tfoot>
366
+ </table>
367
+ <input v-for="input in hiddenInputs" :key="input.value" v-bind="input" />
368
+ </component>
369
+ </template>
370
+
371
+ <script
372
+ setup
373
+ lang="ts"
374
+ generic="Item = any, T extends ItemKey<Item> = string & {}"
375
+ >
376
+ import { computed, reactive, ref, toRef, watch } from 'vue';
377
+ import { clamp } from '@/utilities/functions/clamp';
378
+ import { hash } from '@/utilities/functions/hash';
379
+ import { isNil } from '@/utilities/functions/isNil';
380
+ import { when } from '@/utilities/functions/when';
381
+ import { useId } from '@/composables/useId';
382
+ import { useItemValue } from '@/composables/useItemValue';
383
+ import { useItemsGetter } from '@/composables/useItemsGetter';
384
+ import { usePrefill } from '@/composables/usePrefill';
385
+ import { useIndexById } from '@/composables/useIndexById';
386
+ import { useBaseOptions } from '@/composables/useBaseOptions';
387
+ import { useHashedWatcher } from '@/composables/useHashedWatcher';
388
+ import { useLocale } from '@/composables/useLocale';
389
+ import BaseCheckbox from '../BaseCheckbox/BaseCheckbox.vue';
390
+ import BaseRadio from '../BaseRadio/BaseRadio.vue';
391
+ import type { Option as BaseOption } from '@/types/Option';
392
+ import type { Classes } from '@/types/Classes';
393
+ import type { ColumnName } from '@/types/ColumnName';
394
+ import type { PrefixWith } from '@/types/PrefixWith';
395
+ import type {
396
+ BbTableColumn,
397
+ BbTableEvents,
398
+ BbTableProps,
399
+ BbTableSlots,
400
+ ExpandControllerProps,
401
+ ItemKey,
402
+ MappedCell,
403
+ MappedHeader,
404
+ MappedItem,
405
+ } from './types';
406
+ import {
407
+ applyFixedTableColumns,
408
+ columnKeyToSlotName,
409
+ mergeCellClasses,
410
+ mergeHeaderClasses,
411
+ } from './utils';
412
+ import { useLogger } from '@/composables/useLogger';
413
+ import { isEmpty } from '@/utilities/functions/empty';
414
+
415
+ const { getItemValue } = useItemValue();
416
+
417
+ /** Temporary name for selection inputs; hidden inputs handle real submission. */
418
+ const randomName = useId().id.value;
419
+
420
+ type InternalColumn<K extends string> = Omit<BbTableColumn<Item>, 'key'> & {
421
+ key: K;
422
+ };
423
+
424
+ type InternalProps<K extends string> = Omit<BbTableProps<Item>, 'columns'> & {
425
+ columns: InternalColumn<K>[];
426
+ };
427
+
428
+ const props = withDefaults(defineProps<InternalProps<T>>(), {
429
+ align: 'left',
430
+ actionsText: 'Azioni',
431
+ allowSelectAll: true,
432
+ columns: () => [],
433
+ dependencies: () => [],
434
+ depsDebounceTime: 0,
435
+ fixedColumns: () => [],
436
+ items: () => [],
437
+ max: Infinity,
438
+ multiple: true,
439
+ modelValue: () => [],
440
+ unselectedItems: () => [],
441
+ });
442
+
443
+ const emit = defineEmits<BbTableEvents>();
444
+
445
+ type InferredBodySlots = ColumnName<T>;
446
+ type InferredHeaderSlots = PrefixWith<ColumnName<T>, 'header:'>;
447
+
448
+ defineSlots<
449
+ BbTableSlots<Item> & {
450
+ [K in InferredBodySlots]?: (props: {
451
+ classes?: Classes;
452
+ content?: any;
453
+ expanded?: boolean;
454
+ expandProps?: ExpandControllerProps;
455
+ toggleExpanded?: () => void;
456
+ item: Item;
457
+ value?: any;
458
+ }) => any;
459
+ } & {
460
+ [K in InferredHeaderSlots]?: (props: {
461
+ classes?: Classes;
462
+ content?: any;
463
+ items?: Item[];
464
+ label?: string;
465
+ }) => any;
466
+ }
467
+ >();
468
+
469
+ if (props.multiple && !Array.isArray(props.modelValue)) {
470
+ const logger = useLogger();
471
+ logger.throw(
472
+ 'BbTable is set for multiple selection but modelValue is not an array.'
473
+ );
474
+ }
475
+
476
+ const { t } = useLocale();
477
+
478
+ const tableRef = ref<HTMLTableElement>();
479
+
480
+ /** Builds accessible label for selection controls from row content. */
481
+ const getAccessibleLabel = (columns: MappedCell[]) =>
482
+ [t('table.select').value, ...columns.map((col) => col.content)].join(' ');
483
+
484
+ const containerTag = computed(() => (props.selectable ? 'fieldset' : 'div'));
485
+
486
+ const loading = computed(() => props.loading || innerLoading.value);
487
+
488
+ const hasProvidedAccessibilityData = computed(
489
+ () => !isNil(props.page) && !isNil(props.perPage) && !isNil(props.totalItems)
490
+ );
491
+
492
+ const containerClass = computed(() => ({
493
+ 'bb-table': true,
494
+ [`bb-table--align-${props.align}`]: true,
495
+ 'bb-table--compact': props.compact,
496
+ 'bb-table--fixed': props.fixed,
497
+ 'bb-table--fixed-header': props.fixedHeaders,
498
+ 'bb-table--loading': loading.value,
499
+ 'bb-table--empty': !options.value.length,
500
+ 'bb-table--selectable': !!props.selectable,
501
+ }));
502
+
503
+ const replacementContentSpan = computed(
504
+ () =>
505
+ props.columns.length + Number(!!props.selectable) + Number(!!props.actions)
506
+ );
507
+
508
+ const slotNamesByKey = computed(() =>
509
+ Object.fromEntries(
510
+ props.columns.map((col) => [col.key, columnKeyToSlotName(col.key)])
511
+ )
512
+ );
513
+ const {
514
+ getter,
515
+ items: internalItems,
516
+ loading: innerLoading,
517
+ } = useItemsGetter({
518
+ items: toRef(props, 'items'),
519
+ });
520
+
521
+ const { hasPrefilled } = usePrefill({
522
+ trigger: true,
523
+ fn: async (isPrefill) => {
524
+ await getter(isPrefill, props.modelValue);
525
+ },
526
+ });
527
+
528
+ const { data: modelValueIndexedByHash } = useIndexById({
529
+ items: toRef(props, 'modelValue'),
530
+ });
531
+
532
+ const { options } = useBaseOptions({
533
+ disabled: toRef(props, 'disabled'),
534
+ items: internalItems,
535
+ itemText: undefined,
536
+ itemValue: props.itemValue,
537
+ max: props.max,
538
+ selectable: true,
539
+ selectedIndexedByHash: modelValueIndexedByHash,
540
+ });
541
+
542
+ const onOptionSelected = async (option: BaseOption) => {
543
+ if (props.multiple) {
544
+ emit('update:modelValue', props.modelValue.concat(option.value));
545
+ } else {
546
+ emit('update:modelValue', option.value);
547
+ }
548
+ };
549
+
550
+ const onOptionUnselected = async (option: BaseOption) => {
551
+ if (props.multiple) {
552
+ const copy = { ...modelValueIndexedByHash.value };
553
+ delete copy[option.valueHash];
554
+ emit('update:modelValue', Object.values(copy));
555
+ } else {
556
+ emit('update:modelValue', null);
557
+ }
558
+ };
559
+
560
+ useHashedWatcher(
561
+ () => [props.dependencies, props.items],
562
+ async () => {
563
+ if (!hasPrefilled.value) {
564
+ return;
565
+ }
566
+ await getter(false, props.modelValue);
567
+ },
568
+ {
569
+ debounce: props.depsDebounceTime,
570
+ }
571
+ );
572
+
573
+ const mapColumnToCell = (
574
+ column: BbTableColumn<Item>,
575
+ item: BaseOption
576
+ ): MappedCell => {
577
+ const slotName = slotNamesByKey.value[column.key];
578
+ const align = column.align ?? 'left';
579
+ let content = getItemValue(item.item, column.key);
580
+
581
+ if (column.formatter && (!isNil(content) || column.formatOnNull !== false)) {
582
+ content = column.formatter(content, column.key, item.item);
583
+ }
584
+ if (column.placeholder && isNil(content)) {
585
+ content = column.placeholder;
586
+ }
587
+
588
+ return {
589
+ align,
590
+ classes: mergeCellClasses(
591
+ [`bb-table-data__cell--${align}`],
592
+ props.tdClass,
593
+ column.tdClass,
594
+ content,
595
+ column.key,
596
+ item.item
597
+ ),
598
+ content,
599
+ key: column.key,
600
+ label: column.label,
601
+ slotName,
602
+ };
603
+ };
604
+
605
+ const mappedHeaders = computed(() =>
606
+ props.columns.map((column: BbTableColumn<Item>): MappedHeader => {
607
+ const align = column.align ?? 'left';
608
+ const slotName = `header:${slotNamesByKey.value[column.key]}`;
609
+ const sortDirection = column.sorted
610
+ ? column.sorted === 'asc'
611
+ ? 'ascending'
612
+ : 'descending'
613
+ : undefined;
614
+ return {
615
+ align,
616
+ key: column.key,
617
+ label: column.label,
618
+ slotName,
619
+ classes: mergeHeaderClasses(
620
+ [`bb-table-header--${align}`],
621
+ props.thClass,
622
+ column.thClass
623
+ ),
624
+ sortDirection,
625
+ };
626
+ })
627
+ );
628
+
629
+ const mappedItems = computed<MappedItem[]>(() => {
630
+ let expandedRows = 0;
631
+ return options.value.map((item: BaseOption, index: number): MappedItem => {
632
+ const disabled =
633
+ !props.selectable ||
634
+ (typeof props.selectable === 'function' &&
635
+ !props.selectable(item.item)) ||
636
+ !!item.disabled;
637
+
638
+ // How many rows have passed
639
+ const indexPageOffset = (props.page ?? 0 - 1) * (props.perPage ?? 0);
640
+ const headRowOffset = 1;
641
+ const increment = index + 1;
642
+ const rowIndex = indexPageOffset + headRowOffset + increment + expandedRows;
643
+
644
+ // Create a projection of the columns and run all formatter logic so
645
+ // we just display content in the template
646
+ const cols: MappedCell[] = props.columns.map((column) =>
647
+ mapColumnToCell(column, item)
648
+ );
649
+ const expanded = expandedItemsIndexedByHash.value[item.valueHash] ?? false;
650
+ if (expanded) {
651
+ expandedRows++;
652
+ }
653
+ const res = {
654
+ accessibleLabel: getAccessibleLabel(cols),
655
+ cols,
656
+ expanded,
657
+ onRowClick: (event: MouseEvent) =>
658
+ emit('click:row', event, item, !!item.selected),
659
+ onRowContextMenu: (event: MouseEvent) =>
660
+ emit('contextmenu:row', event, item, !!item.selected),
661
+ onRowDblClick: (event: MouseEvent) =>
662
+ emit('dblclick:row', event, item, !!item.selected),
663
+ item: item.item,
664
+ text: item.text,
665
+ rowIndex,
666
+ valueHash: item.valueHash,
667
+ value: item.value,
668
+ selected: item.selected,
669
+ disabled,
670
+ };
671
+ return res;
672
+ });
673
+ });
674
+
675
+ const selectAll = defineModel<boolean>('selectAll', {
676
+ required: false,
677
+ default: false,
678
+ });
679
+
680
+ const expandedItems = defineModel<any[]>('expandedItems', {
681
+ required: false,
682
+ default: () => [],
683
+ });
684
+
685
+ const { data: expandedItemsIndexedByHash } = useIndexById({
686
+ items: expandedItems,
687
+ });
688
+
689
+ const onExpandControllerKeydown = (event: KeyboardEvent, valueHash: string) => {
690
+ if (!(event.target instanceof HTMLElement)) return;
691
+ if (event.target instanceof HTMLButtonElement) return;
692
+ if (event.key !== 'Enter' && event.key !== ' ') return;
693
+ event.preventDefault();
694
+ toggleExpandedFor(valueHash);
695
+ };
696
+
697
+ const getExpandControllerProps = (item: MappedItem) => ({
698
+ 'aria-controls': isNil(expandedItemsIndexedByHash.value[item.valueHash])
699
+ ? undefined
700
+ : `expanded_${item.valueHash}`,
701
+ 'aria-expanded': item.expanded ? 'true' : 'false',
702
+ onClick: (event: MouseEvent) => {
703
+ event.stopPropagation();
704
+ toggleExpandedFor(item.valueHash);
705
+ },
706
+ onKeydown: (event: KeyboardEvent) =>
707
+ onExpandControllerKeydown(event, item.valueHash),
708
+ });
709
+
710
+ const toggleExpandedFor = (valueHash: string) => {
711
+ const linkedOption = options.value.find((o) => o.valueHash === valueHash);
712
+ if (!linkedOption) return;
713
+ if (valueHash in expandedItemsIndexedByHash.value) {
714
+ expandedItems.value = expandedItems.value.filter(
715
+ (o) => hash(o) !== valueHash
716
+ );
717
+ } else {
718
+ expandedItems.value = [...expandedItems.value, linkedOption.value];
719
+ }
720
+ };
721
+
722
+ watch(selectAll, () => {
723
+ unselectedItems.clear();
724
+ emit('update:unselectedItems', []);
725
+ emit('update:modelValue', []);
726
+ });
727
+
728
+ const indeterminate = computed(() => {
729
+ if (props.multiple && props.modelValue.length > 0 && !props.selectAll) {
730
+ return true;
731
+ }
732
+ if (selectAll.value && unselectedItems.size > 0) {
733
+ return true;
734
+ }
735
+ return false;
736
+ });
737
+
738
+ const unselectedItems = reactive(new Set<string>());
739
+ watch(
740
+ () => props.unselectedItems,
741
+ () => {
742
+ unselectedItems.clear();
743
+ props.unselectedItems.forEach((i) => {
744
+ unselectedItems.add(hash(i));
745
+ });
746
+ }
747
+ );
748
+
749
+ const onInputChange = (item: BaseOption) => {
750
+ if (isSelected(item)) {
751
+ onOptionUnselected(item);
752
+ emit('item:unselected', item.value);
753
+ unselectedItems.add(item.valueHash);
754
+ emit('update:unselectedItems', [...props.unselectedItems, item.value]);
755
+ return;
756
+ }
757
+ if (!selectAll.value) {
758
+ onOptionSelected(item);
759
+ }
760
+ emit('item:selected', item.value);
761
+ unselectedItems.delete(item.valueHash);
762
+ emit(
763
+ 'update:unselectedItems',
764
+ props.unselectedItems.filter((i) => hash(i) !== hash(item.value))
765
+ );
766
+ };
767
+
768
+ const isSelected = (item: BaseOption): boolean => {
769
+ if (unselectedItems.has(item.valueHash)) return false;
770
+ return item.selected || selectAll.value;
771
+ };
772
+
773
+ /**
774
+ * When using this component for submission we add a bunch of hidden inputs
775
+ * so the submitted inputs is on par with v-model
776
+ */
777
+
778
+ /**
779
+ * This is used to keep the value compatible to common html expected values.
780
+ * Convert to string everything that's not but do not double encode strings
781
+ */
782
+ const makeInputValue = when(
783
+ (item: unknown) => typeof item !== 'string',
784
+ JSON.stringify
785
+ );
786
+ const hiddenInputs = computed(() =>
787
+ [].concat(props.modelValue ?? []).map((current: unknown) => ({
788
+ disabled: props.disabled,
789
+ name: props.name,
790
+ type: 'hidden' as const,
791
+ value: makeInputValue(current),
792
+ }))
793
+ );
794
+
795
+ /** Varied line widths for skeleton (percent) to avoid a mechanical look */
796
+ const skeletonLineWidths = [70, 45, 85, 55];
797
+
798
+ const skeletonLength = computed(() =>
799
+ clamp(options.value.length || props.columns.length || 1, 4, 10)
800
+ );
801
+
802
+ watch(
803
+ () => [mappedItems.value, props.fixedColumns],
804
+ () => {
805
+ if (tableRef.value && props.fixedColumns?.length) {
806
+ applyFixedTableColumns(tableRef.value, props.fixedColumns);
807
+ }
808
+ },
809
+ { flush: 'post' }
810
+ );
811
+ </script>
812
+
813
+ <style lang="postcss">
814
+ @import './index.css';
815
+ </style>
816
+ ```
817
+
818
+ ## Types
819
+
820
+ ```ts
821
+ import type { Classes } from '@/types/Classes';
822
+ import type { Option } from '@/types/Option';
823
+ import type { InputHTMLAttributes } from 'vue';
824
+
825
+ /**
826
+ * Recursively builds dot-notation paths from a type's keys.
827
+ * Depth-limited to 3 levels to avoid compiler performance issues.
828
+ */
829
+ type NestedPaths<T, Depth extends unknown[] = []> = Depth['length'] extends 3
830
+ ? never
831
+ : 0 extends 1 & T
832
+ ? string
833
+ : T extends object
834
+ ? T extends any[] | Date | Function | RegExp | Map<any, any> | Set<any>
835
+ ? never
836
+ : {
837
+ [K in Extract<keyof T, string>]:
838
+ | K
839
+ | `${K}.${NestedPaths<NonNullable<T[K]>, [...Depth, unknown]>}`;
840
+ }[Extract<keyof T, string>]
841
+ : never;
842
+
843
+ /**
844
+ * Suggested keys for a column derived from an Item type.
845
+ * Provides autocomplete for nested dot-notation paths (up to 3 levels)
846
+ * while still allowing arbitrary string keys for virtual columns.
847
+ */
848
+ export type ItemKey<Item = any> = NestedPaths<Item> | (string & {});
849
+
850
+ /**
851
+ * Skeleton placeholder style for the loading state.
852
+ * Matches the expected content type for a better loading experience.
853
+ */
854
+ export type SkeletonType =
855
+ | 'text'
856
+ | 'avatar'
857
+ | 'avatar-text'
858
+ | 'image'
859
+ | 'badge';
860
+
861
+ export type BaseColumn<Item = any> = {
862
+ /**
863
+ * When set to false the formatter will not run on nullish values.
864
+ * By default is true so you can create virtual columns with keys that do not
865
+ * reference a prop in the `item` and still extract data from the other
866
+ * arguments in the formatting function.
867
+ */
868
+ formatOnNull?: boolean;
869
+
870
+ /**
871
+ * Formatting function used to generate enhanced content.
872
+ * @param content The content generated by the extraction of `Item[key]`
873
+ * @param key Key of the column taken from the column definition.
874
+ * @param item Item of the row.
875
+ */
876
+ formatter?: (content: any, key: string, item: Item) => any;
877
+
878
+ /**
879
+ * Key identifying the column.
880
+ */
881
+ key: ItemKey<Item>;
882
+
883
+ /**
884
+ * Text used in the header for this column.
885
+ */
886
+ label: string;
887
+
888
+ /**
889
+ * Placeholder used when the pipeline returns null content.
890
+ */
891
+ placeholder?: string;
892
+ };
893
+
894
+ /**
895
+ * Column definition for BbTable. Controls data extraction, formatting, alignment, and styling.
896
+ */
897
+ export type BbTableColumn<Item = any> = BaseColumn<Item> & {
898
+ /**
899
+ * Text alignment of the column.
900
+ */
901
+ align?: 'left' | 'right' | 'center';
902
+
903
+ /**
904
+ * Skeleton placeholder style shown during loading. Defaults to `'text'`.
905
+ */
906
+ skeleton?: SkeletonType;
907
+
908
+ /**
909
+ * Defines the sorting direction of the column.
910
+ */
911
+ sorted?: 'asc' | 'desc';
912
+
913
+ /**
914
+ * Defines the classes to be passed to the `<td>` elements. Can also be a function for dynamic values.
915
+ */
916
+ tdClass?: ColumnClasses<Item>;
917
+
918
+ /**
919
+ * Defines the classes to be passed to the `<th>`.
920
+ */
921
+ thClass?: Classes;
922
+ };
923
+
924
+ export type BbTableProps<Item = any> = {
925
+ /**
926
+ * Function that accepts the columns and the current item as
927
+ * arguments and returns a label to be used for accessibility purposes.
928
+ */
929
+ accessibleLabel?: (columns: MappedCell[], item: any) => string;
930
+
931
+ /**
932
+ * Displays the actions column.
933
+ */
934
+ actions?: boolean;
935
+
936
+ /**
937
+ * Label used in the header of the actions column.
938
+ */
939
+ actionsText?: string;
940
+
941
+ /**
942
+ * Text alignment of the columns.
943
+ */
944
+ align?: 'left' | 'center' | 'right';
945
+
946
+ /**
947
+ * Boolean that defines whether to display a "Select all" checkbox.
948
+ */
949
+ allowSelectAll?: boolean;
950
+
951
+ /**
952
+ * Caption that describes the content of the table. Used for accessibility purposes.
953
+ */
954
+ caption?: string;
955
+
956
+ /**
957
+ * Array of definitions of how the columns should be rendered.
958
+ *
959
+ */
960
+ columns: BbTableColumn<Item>[];
961
+
962
+ /**
963
+ * Adds a CSS class that applies a compact style to the component.
964
+ */
965
+ compact?: boolean;
966
+
967
+ /**
968
+ * Defines an array of dependencies that will trigger actions in the component upon change.
969
+ */
970
+ dependencies?: any[];
971
+
972
+ /**
973
+ * Timeout used to debounce response to changes to dependencies.
974
+ */
975
+ depsDebounceTime?: number;
976
+
977
+ /**
978
+ * Disables the component
979
+ */
980
+ disabled?: boolean;
981
+
982
+ /**
983
+ * Boolean that defines whether to display or hide the caption.
984
+ * By default is true and the caption is hidden.
985
+ */
986
+ displayCaption?: boolean;
987
+
988
+ /**
989
+ * Defines the table layout as fixed
990
+ * making each column take up the same amount of space.
991
+ */
992
+ fixed?: boolean;
993
+
994
+ /**
995
+ * Definition for which column should be fixed.
996
+ * It can be an array of index of the column to fix on the left side of the table or
997
+ * an array of objects indicating the index and the position `left` or `right` where to affix the columns.
998
+ */
999
+ fixedColumns?: (number | { index: number; position: 'left' | 'right' })[];
1000
+
1001
+ /**
1002
+ * Boolean that sets the headers as sticky to the top of the table.
1003
+ */
1004
+ fixedHeaders?: boolean;
1005
+
1006
+ items:
1007
+ | Item[]
1008
+ | ((prefill: boolean, modelValue?: any[]) => Promise<Item[]>)
1009
+ | ((prefill: boolean, modelValue?: any[]) => Item[]);
1010
+
1011
+ itemValue?: string | ((item: Item) => any);
1012
+
1013
+ /**
1014
+ * Text content of the legend.
1015
+ */
1016
+ legend?: string;
1017
+
1018
+ /**
1019
+ * Sets the component in a loading state, usually triggering some visual styles.
1020
+ */
1021
+ loading?: boolean;
1022
+
1023
+ /**
1024
+ * String displayed while items are being loaded.
1025
+ */
1026
+ loadingText?: string;
1027
+
1028
+ /**
1029
+ * Maximum number of items that can be selected.
1030
+ */
1031
+ max?: number;
1032
+
1033
+ /**
1034
+ * Used by v-model. Can be any serializable type.
1035
+ */
1036
+ modelValue?: any;
1037
+
1038
+ /**
1039
+ * Allows the selection of multiple items.
1040
+ */
1041
+ multiple?: boolean;
1042
+
1043
+ /**
1044
+ * Defines the name of the input.
1045
+ */
1046
+ name?: InputHTMLAttributes['name'];
1047
+
1048
+ /**
1049
+ * String displayed when there are no items to display.
1050
+ */
1051
+ noDataText?: string;
1052
+
1053
+ /**
1054
+ * Current page number starting from 1, used for accessibility purposes.
1055
+ */
1056
+ page?: number;
1057
+
1058
+ /**
1059
+ * Number of items per page, used for accessibility purposes.
1060
+ */
1061
+ perPage?: number;
1062
+
1063
+ /**
1064
+ * Sets the input in a readonly state.
1065
+ */
1066
+ readonly?: boolean;
1067
+
1068
+ /**
1069
+ * Defines whether the "Select all" checkbox is checked.
1070
+ */
1071
+ selectAll?: boolean;
1072
+
1073
+ /**
1074
+ * Defines whether the table is selectable.
1075
+ * Can be a global boolean that affects all rows or a function
1076
+ * that accepts an item and returns a boolean that only affects that item.
1077
+ */
1078
+ selectable?: boolean | ((item: Item) => boolean);
1079
+
1080
+ /**
1081
+ * Text of the label used by the "Select all" boolean.
1082
+ */
1083
+ selectAllLabel?: string;
1084
+
1085
+ /**
1086
+ * Text of the header used for the radio inputs when the table is not `multiple`.
1087
+ */
1088
+ selectText?: string;
1089
+
1090
+ /**
1091
+ * Defines the classes to be passed to the `<td>` elements. Can also be a function for dynamic values.
1092
+ */
1093
+ tdClass?: ColumnClasses<Item>;
1094
+
1095
+ /**
1096
+ * Defines the classes to be passed to the `<th>`.
1097
+ */
1098
+ thClass?: Classes;
1099
+
1100
+ /**
1101
+ * Total number of items there is.
1102
+ */
1103
+ totalItems?: number;
1104
+
1105
+ /**
1106
+ * Items that are not selected.
1107
+ */
1108
+ unselectedItems?: any[];
1109
+ };
1110
+
1111
+ /**
1112
+ * We allow table data classes to be a function so it can depend on the item
1113
+ */
1114
+ export type ColumnClasses<Item = any> =
1115
+ | Classes
1116
+ | ((content: any, key: string, item: Item) => Classes);
1117
+
1118
+ /**
1119
+ * Projection that represents a row of cells with flags
1120
+ * linked to the state of the item
1121
+ */
1122
+ export type MappedItem = Option & {
1123
+ accessibleLabel: string;
1124
+ cols: MappedCell[];
1125
+ expanded: boolean;
1126
+ onRowClick: (event: MouseEvent) => void;
1127
+ onRowContextMenu: (event: MouseEvent) => void;
1128
+ onRowDblClick: (event: MouseEvent) => void;
1129
+ rowIndex: number | undefined;
1130
+ };
1131
+
1132
+ /**
1133
+ * Projection that represents a header
1134
+ */
1135
+ export type MappedHeader = {
1136
+ align: HTMLTableCellElement['align'];
1137
+ classes?: Classes;
1138
+ key: string;
1139
+ label: string;
1140
+ slotName: string;
1141
+ sortDirection?: 'ascending' | 'descending';
1142
+ };
1143
+
1144
+ /**
1145
+ * Projection that represents a cell of data for display.
1146
+ */
1147
+ export type MappedCell = {
1148
+ align: string;
1149
+ classes: Classes;
1150
+ content: any;
1151
+ key: string;
1152
+ label: string;
1153
+ slotName: string;
1154
+ };
1155
+
1156
+ export type ExpandControllerProps = {
1157
+ 'aria-controls'?: string;
1158
+ 'aria-expanded': 'true' | 'false';
1159
+ onClick: () => void;
1160
+ onKeydown: (event: KeyboardEvent) => void;
1161
+ };
1162
+
1163
+ export type BbTableEvents = {
1164
+ (e: 'click:row', event: MouseEvent, item: any, selected: boolean): void;
1165
+ (e: 'contextmenu:row', event: MouseEvent, item: any, selected: boolean): void;
1166
+ (e: 'dblclick:row', event: MouseEvent, item: any, selected: boolean): void;
1167
+ (e: 'update:modelValue', value: any): void;
1168
+ (e: 'update:selectAll', value: boolean): void;
1169
+ (e: 'update:expandedItems', value: any[]): void;
1170
+ (e: 'update:unselectedItems', value: any[]): void;
1171
+ (e: 'item:selected', value: any): void;
1172
+ (e: 'item:unselected', value: any): void;
1173
+ };
1174
+
1175
+ export type BbTableSlots<Item = any> = {
1176
+ /**
1177
+ * Replaces the entire `<thead>` element. Use when you need full control over the header markup.
1178
+ */
1179
+ thead?: (props: object) => any;
1180
+ /**
1181
+ * Replaces the entire `<tbody>` element. Use when you need full control over the body markup.
1182
+ */
1183
+ tbody?: (props: object) => any;
1184
+ /**
1185
+ * Replaces the entire `<tfoot>` element. Use when you need full control over the footer markup.
1186
+ */
1187
+ tfoot?: (props: object) => any;
1188
+ /**
1189
+ * Replaces the default selection header cell content (checkbox or radio label).
1190
+ * @param multiple - Whether the table allows multiple selection.
1191
+ * @param selectAll - Whether the "select all" checkbox is currently checked.
1192
+ * @param text - The accessible label text for the select-all control.
1193
+ */
1194
+ 'header:select'?: (props: {
1195
+ multiple: boolean;
1196
+ selectAll: boolean;
1197
+ text: string;
1198
+ }) => any;
1199
+ /**
1200
+ * Replaces the default actions header cell content.
1201
+ * @param text - The accessible label text for the actions column header.
1202
+ */
1203
+ 'header:actions'?: (props: { text: string }) => any;
1204
+ /**
1205
+ * Content shown while table rows are loading (replaces the skeleton rows).
1206
+ * @param items - The current (possibly stale) list of items, useful to match the previous row count.
1207
+ */
1208
+ loading?: (props: { items: Item[] }) => any;
1209
+ /**
1210
+ * Content shown when the items list is empty and not loading.
1211
+ */
1212
+ 'no-data'?: (props: object) => any;
1213
+ /**
1214
+ * Content rendered in the actions cell for each row.
1215
+ * @param expanded - Whether this row is currently expanded.
1216
+ * @param expandProps - Bind these onto an expand-toggle button to wire up aria attributes and keyboard handling.
1217
+ * @param toggleExpanded - Toggles the expanded state for this row.
1218
+ * @param item - The raw item for this row.
1219
+ * @param value - The resolved value for this row.
1220
+ */
1221
+ actions?: (props: {
1222
+ expanded?: boolean;
1223
+ expandProps?: ExpandControllerProps;
1224
+ toggleExpanded?: () => void;
1225
+ item: Item;
1226
+ value: any;
1227
+ }) => any;
1228
+ /**
1229
+ * Full-width expandable content row rendered below each main row when expanded.
1230
+ * @param expanded - Whether this row is currently expanded.
1231
+ * @param expandProps - Bind these onto an expand-toggle button to wire up aria attributes and keyboard handling.
1232
+ * @param toggleExpanded - Toggles the expanded state for this row.
1233
+ * @param item - The raw item for this row.
1234
+ * @param value - The resolved value for this row.
1235
+ */
1236
+ expand?: (props: {
1237
+ expanded: boolean;
1238
+ expandProps?: ExpandControllerProps;
1239
+ toggleExpanded: () => void;
1240
+ item: Item;
1241
+ value: any;
1242
+ }) => any;
1243
+ /**
1244
+ * Replaces the default checkbox/radio in the selection cell for each row.
1245
+ * @param item - The raw item for this row.
1246
+ * @param value - The resolved value for this row.
1247
+ * @param checked - Whether this row is currently selected.
1248
+ * @param disabled - Whether this row's selection control is disabled.
1249
+ * @param inputName - The `name` attribute for the selection input.
1250
+ * @param readonly - Whether the selection control is read-only.
1251
+ */
1252
+ select?: (props: {
1253
+ item: Item;
1254
+ value: any;
1255
+ checked: boolean;
1256
+ disabled: boolean;
1257
+ inputName: string;
1258
+ readonly: boolean;
1259
+ }) => any;
1260
+ } & {
1261
+ /**
1262
+ * Named slot for a specific column cell (`col-key`) or column header (`header:col-key`).
1263
+ * @param classes - CSS classes computed for the cell.
1264
+ * @param content - The formatted cell content.
1265
+ * @param expanded - Whether this row is currently expanded (body slots only).
1266
+ * @param expandProps - Bind these onto an expand-toggle button (body slots only).
1267
+ * @param toggleExpanded - Toggles the expanded state for this row (body slots only).
1268
+ * @param item - The raw item for this row (body slots only).
1269
+ * @param value - The resolved row value (body slots only).
1270
+ * @param items - The full items list (header slots only).
1271
+ * @param label - The column label (header slots only).
1272
+ */
1273
+ [key: string]: (props: {
1274
+ classes?: Classes[];
1275
+ content?: any;
1276
+ expanded?: boolean;
1277
+ expandProps?: ExpandControllerProps;
1278
+ toggleExpanded?: () => void;
1279
+ item: Item;
1280
+ value?: any;
1281
+ items?: Item[];
1282
+ label?: string;
1283
+ }) => any;
1284
+ };
1285
+ ```
1286
+
1287
+ ## Styles
1288
+
1289
+ ```css
1290
+ .bb-table {
1291
+ --padding-x: 16px;
1292
+ --padding-y: 8px;
1293
+ --actions-spacing: 8px;
1294
+ border-collapse: separate;
1295
+ border-spacing: 0;
1296
+ display: grid;
1297
+ overflow-x: auto;
1298
+
1299
+ position: relative;
1300
+
1301
+ &--align {
1302
+ &-left {
1303
+ text-align: left;
1304
+ }
1305
+ &-center {
1306
+ text-align: center;
1307
+ }
1308
+ &-right {
1309
+ text-align: right;
1310
+ }
1311
+ }
1312
+
1313
+ &--compact {
1314
+ --padding-x: 8px;
1315
+ --padding-y: 4px;
1316
+ }
1317
+
1318
+ &--fixed {
1319
+ table {
1320
+ table-layout: fixed;
1321
+ width: 100%;
1322
+
1323
+ thead {
1324
+ .bb-table-header--actions {
1325
+ width: auto;
1326
+ }
1327
+ }
1328
+ }
1329
+ }
1330
+
1331
+ &--fixed-header {
1332
+ table {
1333
+ thead {
1334
+ th {
1335
+ position: sticky;
1336
+ top: 0;
1337
+ z-index: 1;
1338
+ }
1339
+ th[style*='sticky'] {
1340
+ position: sticky;
1341
+ top: 0;
1342
+ z-index: 2;
1343
+ }
1344
+ }
1345
+ }
1346
+ }
1347
+
1348
+ &--loading {
1349
+ }
1350
+
1351
+ &--empty {
1352
+ }
1353
+
1354
+ &--selectable {
1355
+ tr {
1356
+ > .bb-table-data__cell--select {
1357
+ text-align: center;
1358
+ width: 0px;
1359
+ }
1360
+ }
1361
+ }
1362
+
1363
+ legend {
1364
+ }
1365
+
1366
+ table {
1367
+ min-width: 100%;
1368
+ }
1369
+
1370
+ .bb-table-caption {
1371
+ }
1372
+
1373
+ &-header-row {
1374
+ }
1375
+
1376
+ &-header {
1377
+ border-bottom: 1px solid var(--bb-border);
1378
+ color: color-mix(in srgb, var(--bb-text), transparent 40%);
1379
+ font-size: 14px;
1380
+ font-weight: 500;
1381
+ padding: var(--padding-y) var(--padding-x);
1382
+
1383
+ &--center {
1384
+ text-align: center;
1385
+ }
1386
+
1387
+ &--right {
1388
+ text-align: right;
1389
+ }
1390
+
1391
+ &--select {
1392
+ }
1393
+
1394
+ &--actions {
1395
+ width: 0;
1396
+
1397
+ .bb-table-header__content {
1398
+ }
1399
+ }
1400
+
1401
+ &__content {
1402
+ }
1403
+ }
1404
+
1405
+ tbody {
1406
+ tr {
1407
+ &:not(:last-child) {
1408
+ border-bottom: 1px solid var(--bb-border);
1409
+ }
1410
+ td {
1411
+ color: var(--bb-text);
1412
+ font-size: 14px;
1413
+ font-weight: 400;
1414
+ height: var(--bb-table-cell-h);
1415
+ padding: var(--padding-y) var(--padding-x);
1416
+ }
1417
+
1418
+ td.bb-table-expand__cell {
1419
+ padding: 0;
1420
+ }
1421
+ }
1422
+ }
1423
+
1424
+ &.bb-table--loading {
1425
+ .bb-table-loading__row {
1426
+ .bb-table-loading__cell {
1427
+ padding: 0 var(--padding-x) !important;
1428
+ vertical-align: top;
1429
+ }
1430
+ }
1431
+
1432
+ .bb-table-loading__row--sr-only {
1433
+ .bb-table-loading__cell {
1434
+ padding: 0 !important;
1435
+ border: none;
1436
+ height: 0;
1437
+ overflow: hidden;
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ &-skeleton {
1443
+ &__row {
1444
+ }
1445
+
1446
+ &__cell {
1447
+ height: var(--bb-table-cell-h);
1448
+ overflow: hidden;
1449
+ padding: var(--padding-y) var(--padding-x);
1450
+ vertical-align: middle;
1451
+
1452
+ &--select,
1453
+ &--actions {
1454
+ text-align: center;
1455
+ width: 0;
1456
+ }
1457
+ }
1458
+
1459
+ &__cell-content {
1460
+ display: flex;
1461
+ flex-direction: column;
1462
+ gap: 6px;
1463
+ justify-content: center;
1464
+ max-height: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1465
+ min-width: 96px;
1466
+ }
1467
+
1468
+ &__line {
1469
+ background: linear-gradient(
1470
+ 90deg,
1471
+ var(--bb-border) 0%,
1472
+ var(--bb-border) 35%,
1473
+ color-mix(in srgb, var(--bb-border) 60%, white) 50%,
1474
+ var(--bb-border) 65%,
1475
+ var(--bb-border) 100%
1476
+ );
1477
+ background-size: 200% 100%;
1478
+ border-radius: 6px;
1479
+ flex-shrink: 0;
1480
+ height: 10px;
1481
+ animation: bb-table-skeleton-shimmer 1.8s ease-in-out infinite;
1482
+ }
1483
+
1484
+ @media (prefers-reduced-motion: reduce) {
1485
+ &__line {
1486
+ animation: none;
1487
+ background: var(--bb-border);
1488
+ }
1489
+ }
1490
+
1491
+ &__placeholder {
1492
+ background-color: var(--bb-border);
1493
+ border-radius: 6px;
1494
+ flex-shrink: 0;
1495
+ height: 22px;
1496
+ margin: 0 auto;
1497
+ min-width: 22px;
1498
+ width: 22px;
1499
+ }
1500
+
1501
+ &__avatar {
1502
+ aspect-ratio: 1;
1503
+ background-color: var(--bb-border);
1504
+ border-radius: 50%;
1505
+ flex-shrink: 0;
1506
+ height: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1507
+ min-width: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1508
+ width: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1509
+ }
1510
+
1511
+ &__avatar-text {
1512
+ align-items: center;
1513
+ display: flex;
1514
+ gap: 12px;
1515
+ max-height: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1516
+ min-width: 140px;
1517
+ }
1518
+
1519
+ &__avatar-text .bb-table-skeleton__avatar {
1520
+ width: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1521
+ }
1522
+
1523
+ &__avatar-text .bb-table-skeleton__cell-content {
1524
+ flex: 1;
1525
+ min-width: 0;
1526
+ }
1527
+
1528
+ &__image {
1529
+ aspect-ratio: 4 / 3;
1530
+ background-color: var(--bb-border);
1531
+ border-radius: 8px;
1532
+ height: calc(var(--bb-table-cell-h) - var(--padding-y) * 2);
1533
+ min-width: 64px;
1534
+ width: auto;
1535
+ }
1536
+
1537
+ &__badge {
1538
+ background-color: var(--bb-border);
1539
+ border-radius: 999px;
1540
+ flex-shrink: 0;
1541
+ height: 26px;
1542
+ min-width: 72px;
1543
+ width: 88px;
1544
+ }
1545
+ }
1546
+
1547
+ @keyframes bb-table-skeleton-shimmer {
1548
+ 0% {
1549
+ background-position: 200% 0;
1550
+ }
1551
+ 100% {
1552
+ background-position: -200% 0;
1553
+ }
1554
+ }
1555
+
1556
+ &-no-data {
1557
+ &__row {
1558
+ }
1559
+ &__cell {
1560
+ }
1561
+ &__text {
1562
+ }
1563
+ }
1564
+
1565
+ &-data {
1566
+ &__row {
1567
+ }
1568
+ &__cell {
1569
+ &--center {
1570
+ text-align: center;
1571
+ }
1572
+
1573
+ &--right {
1574
+ text-align: right;
1575
+ }
1576
+
1577
+ &--select {
1578
+ }
1579
+ }
1580
+ }
1581
+
1582
+ &-data-row {
1583
+ }
1584
+
1585
+ &__cell {
1586
+ &--select {
1587
+ }
1588
+
1589
+ &--actions {
1590
+ white-space: nowrap;
1591
+ > *:not(:first-child) {
1592
+ margin-left: var(--actions-spacing);
1593
+ }
1594
+ }
1595
+ }
1596
+
1597
+ &-check,
1598
+ &-radio {
1599
+ &__label {
1600
+ cursor: pointer;
1601
+ display: inline-block;
1602
+ transform: translateY(2px);
1603
+ user-select: none;
1604
+
1605
+ &.bb-table {
1606
+ &-check,
1607
+ &-radio {
1608
+ &__label--disabled {
1609
+ cursor: default;
1610
+ visibility: hidden;
1611
+ }
1612
+ }
1613
+ }
1614
+
1615
+ &.bb-table-radio__label--disabled {
1616
+ cursor: default;
1617
+ }
1618
+
1619
+ &-text {
1620
+ }
1621
+ }
1622
+ }
1623
+ }
1624
+ ```