bitboss-ui 3.0.0-beta.2 → 3.0.0-beta.21

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 (350) hide show
  1. package/README.md +72 -33
  2. package/dist/ai/BbAccordion.md +3 -3
  3. package/dist/ai/BbAlert.md +9 -5
  4. package/dist/ai/BbAsterisk.md +17 -0
  5. package/dist/ai/BbAvatar.md +12 -3
  6. package/dist/ai/BbBadge.md +15 -10
  7. package/dist/ai/BbBadgeButton.md +16 -16
  8. package/dist/ai/BbBaseButton.md +16 -16
  9. package/dist/ai/BbBaseCheckbox.md +8 -8
  10. package/dist/ai/BbBaseCheckboxGroup.md +13 -13
  11. package/dist/ai/BbBaseCheckboxIcon.md +26 -9
  12. package/dist/ai/BbBaseColorInput.md +11 -11
  13. package/dist/ai/BbBaseDatePicker.md +6 -6
  14. package/dist/ai/BbBaseDatePickerInput.md +15 -15
  15. package/dist/ai/BbBaseInputContainer.md +12 -12
  16. package/dist/ai/BbBaseNumberInput.md +8 -8
  17. package/dist/ai/BbBaseRadio.md +5 -5
  18. package/dist/ai/BbBaseRadioGroup.md +7 -7
  19. package/dist/ai/BbBaseRadioIcon.md +25 -9
  20. package/dist/ai/BbBaseRating.md +5 -5
  21. package/dist/ai/BbBaseSelect.md +22 -21
  22. package/dist/ai/BbBaseSlider.md +9 -9
  23. package/dist/ai/BbBaseSwitch.md +8 -8
  24. package/dist/ai/BbBaseSwitchGroup.md +13 -13
  25. package/dist/ai/BbBaseSwitchIcon.md +28 -10
  26. package/dist/ai/BbBaseTag.md +10 -10
  27. package/dist/ai/BbBaseTextInput.md +9 -9
  28. package/dist/ai/BbBaseTextarea.md +9 -9
  29. package/dist/ai/BbBaseTimePickerInput.md +13 -13
  30. package/dist/ai/BbBreadcrumbs.md +2 -2
  31. package/dist/ai/BbButton.md +15 -15
  32. package/dist/ai/BbCheckbox.md +18 -17
  33. package/dist/ai/BbCheckboxGroup.md +15 -14
  34. package/dist/ai/BbCollapsible.md +11 -9
  35. package/dist/ai/BbColorInput.md +15 -15
  36. package/dist/ai/BbColorPalette.md +12 -6
  37. package/dist/ai/BbConfirm.md +12 -5
  38. package/dist/ai/BbDatePicker.md +13 -13
  39. package/dist/ai/BbDatePickerInput.md +20 -20
  40. package/dist/ai/BbDialog.md +78 -12
  41. package/dist/ai/BbDropdown.md +132 -22
  42. package/dist/ai/BbDropdownButton.md +12 -12
  43. package/dist/ai/BbDropdownGroup.md +1 -1
  44. package/dist/ai/BbDropzone.md +4 -4
  45. package/dist/ai/BbForm.md +49 -14
  46. package/dist/ai/BbIcon.md +6 -0
  47. package/dist/ai/BbIndicator.md +5 -5
  48. package/dist/ai/BbNumberInput.md +11 -11
  49. package/dist/ai/BbOffCanvas.md +90 -20
  50. package/dist/ai/BbPagination.md +3 -3
  51. package/dist/ai/BbPopover.md +32 -17
  52. package/dist/ai/BbProgress.md +7 -4
  53. package/dist/ai/BbRadio.md +16 -15
  54. package/dist/ai/BbRadioGroup.md +20 -17
  55. package/dist/ai/BbRating.md +11 -11
  56. package/dist/ai/BbSelect.md +138 -37
  57. package/dist/ai/BbSelectPopover.md +40 -41
  58. package/dist/ai/BbSlider.md +37 -22
  59. package/dist/ai/BbSmoothHeight.md +1 -1
  60. package/dist/ai/BbSwitch.md +25 -10
  61. package/dist/ai/BbSwitchGroup.md +17 -14
  62. package/dist/ai/BbTable.md +920 -109
  63. package/dist/ai/BbTabs.md +28 -14
  64. package/dist/ai/BbTabsList.md +1 -1
  65. package/dist/ai/BbTabsPanes.md +1 -1
  66. package/dist/ai/BbTabsRoot.md +10 -10
  67. package/dist/ai/BbTag.md +14 -14
  68. package/dist/ai/BbTextInput.md +16 -15
  69. package/dist/ai/BbTextarea.md +13 -13
  70. package/dist/ai/BbTimePicker.md +10 -10
  71. package/dist/ai/BbTimePickerInput.md +17 -17
  72. package/dist/ai/BbToast.md +1 -1
  73. package/dist/ai/BbToastPortal.md +1 -1
  74. package/dist/ai/BbTooltip.md +12 -10
  75. package/dist/ai/BbTree.md +1 -1
  76. package/dist/ai/ChipsBox.md +1 -1
  77. package/dist/ai/CommonInputWrapper.md +10 -10
  78. package/dist/ai/CommonPopover.md +6 -6
  79. package/dist/ai/FlatListBox.md +5 -5
  80. package/dist/ai/GroupedListBox.md +5 -5
  81. package/dist/ai/ListBox.md +4 -4
  82. package/dist/ai/OptionsContainer.md +4 -4
  83. package/dist/ai/changelog.json +128 -2
  84. package/dist/ai/components.json +917 -100
  85. package/dist/ai/composables/useBbConfig.md +72 -11
  86. package/dist/ai/composables/useConfirm.md +5 -3
  87. package/dist/ai/guides/ai-router.md +9 -4
  88. package/dist/ai/guides/component-picker.md +18 -18
  89. package/dist/ai/guides/design-language.md +14 -14
  90. package/dist/ai/guides/design-tokens.md +25 -18
  91. package/dist/ai/guides/fetch-items-playbook.md +1 -1
  92. package/dist/ai/guides/icons-policy.md +11 -5
  93. package/dist/ai/guides/installation-and-plugin-setup.md +85 -23
  94. package/dist/ai/guides/migration/components/bb-checkbox-group.md +30 -0
  95. package/dist/ai/guides/migration/components/bb-checkbox.md +37 -3
  96. package/dist/ai/guides/migration/components/bb-collapsible.md +5 -5
  97. package/dist/ai/guides/migration/components/bb-dialog.md +62 -34
  98. package/dist/ai/guides/migration/components/bb-offcanvas.md +29 -13
  99. package/dist/ai/guides/migration/components/bb-rating.md +8 -2
  100. package/dist/ai/guides/migration/components/bb-select.md +5 -2
  101. package/dist/ai/guides/migration/components/bb-table.md +560 -28
  102. package/dist/ai/guides/migration/components/bb-text-input.md +6 -6
  103. package/dist/ai/guides/migration/v2-to-v3.md +260 -89
  104. package/dist/ai/guides/ssr-prefill.md +120 -0
  105. package/dist/ai/index.md +10 -9
  106. package/dist/ai/recipes/inertia/approvals-inbox.md +0 -1
  107. package/dist/ai/recipes/inertia/inline-edit-workspace.md +0 -1
  108. package/dist/ai/recipes/inertia/layout-scaffold.md +5 -1
  109. package/dist/ai/recipes/inertia/ownership-atlas.md +49 -29
  110. package/dist/ai/recipes/inertia/record-form.md +0 -1
  111. package/dist/ai/recipes/inertia/records-workspace.md +26 -8
  112. package/dist/ai/recipes/inertia/upload-center.md +0 -1
  113. package/dist/ai/recipes/nuxt/approvals-inbox.md +0 -1
  114. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +0 -1
  115. package/dist/ai/recipes/nuxt/layout-scaffold.md +5 -1
  116. package/dist/ai/recipes/nuxt/record-form.md +0 -1
  117. package/dist/ai/recipes/nuxt/records-workspace.md +26 -8
  118. package/dist/ai/recipes/nuxt/upload-center.md +0 -1
  119. package/dist/ai/recipes/vue/approvals-inbox.md +0 -1
  120. package/dist/ai/recipes/vue/inline-edit-workspace.md +0 -1
  121. package/dist/ai/recipes/vue/layout-scaffold.md +5 -1
  122. package/dist/ai/recipes/vue/records-workspace.md +26 -8
  123. package/dist/ai/recipes/vue/upload-center.md +0 -1
  124. package/dist/ai/source/BbAlert.md +60 -2
  125. package/dist/ai/source/BbAvatar.md +3 -3
  126. package/dist/ai/source/BbBadge.md +60 -15
  127. package/dist/ai/source/BbBadgeButton.md +8 -2
  128. package/dist/ai/source/BbBaseButton.md +3 -1
  129. package/dist/ai/source/BbBaseCheckboxGroup.md +6 -2
  130. package/dist/ai/source/BbBaseDatePicker.md +3 -1
  131. package/dist/ai/source/BbBaseDatePickerInput.md +5 -1
  132. package/dist/ai/source/BbBaseInputContainer.md +52 -1
  133. package/dist/ai/source/BbBaseRadioGroup.md +4 -0
  134. package/dist/ai/source/BbBaseRating.md +3 -1
  135. package/dist/ai/source/BbBaseSelect.md +71 -16
  136. package/dist/ai/source/BbBaseSwitchGroup.md +4 -0
  137. package/dist/ai/source/BbBaseTimePickerInput.md +5 -1
  138. package/dist/ai/source/BbBreadcrumbs.md +31 -0
  139. package/dist/ai/source/BbButton.md +51 -24
  140. package/dist/ai/source/BbCheckbox.md +15 -1
  141. package/dist/ai/source/BbCheckboxGroup.md +2 -1
  142. package/dist/ai/source/BbCollapsible.md +7 -1
  143. package/dist/ai/source/BbColorInput.md +3 -4
  144. package/dist/ai/source/BbColorPalette.md +3 -4
  145. package/dist/ai/source/BbDatePicker.md +5 -1
  146. package/dist/ai/source/BbDatePickerInput.md +5 -1
  147. package/dist/ai/source/BbDialog.md +175 -19
  148. package/dist/ai/source/BbDropdown.md +376 -69
  149. package/dist/ai/source/BbDropdownGroup.md +330 -59
  150. package/dist/ai/source/BbForm.md +93 -5
  151. package/dist/ai/source/BbIcon.md +46 -36
  152. package/dist/ai/source/BbNumberInput.md +3 -4
  153. package/dist/ai/source/BbOffCanvas.md +474 -194
  154. package/dist/ai/source/BbPopover.md +24 -17
  155. package/dist/ai/source/BbProgress.md +2 -2
  156. package/dist/ai/source/BbRadio.md +15 -1
  157. package/dist/ai/source/BbRadioGroup.md +3 -1
  158. package/dist/ai/source/BbSelect.md +50 -2
  159. package/dist/ai/source/BbSelectPopover.md +171 -23
  160. package/dist/ai/source/BbSlider.md +3 -4
  161. package/dist/ai/source/BbSwitch.md +15 -1
  162. package/dist/ai/source/BbSwitchGroup.md +8 -5
  163. package/dist/ai/source/BbTable.md +5092 -1446
  164. package/dist/ai/source/BbTabs.md +6 -7
  165. package/dist/ai/source/BbTabsList.md +6 -7
  166. package/dist/ai/source/BbTabsPanes.md +6 -7
  167. package/dist/ai/source/BbTabsRoot.md +6 -7
  168. package/dist/ai/source/BbTag.md +3 -4
  169. package/dist/ai/source/BbTextInput.md +3 -4
  170. package/dist/ai/source/BbTextarea.md +3 -4
  171. package/dist/ai/source/BbTimePicker.md +4 -1
  172. package/dist/ai/source/BbTimePickerInput.md +5 -1
  173. package/dist/ai/source/BbToast.md +3 -1
  174. package/dist/ai/source/BbTooltip.md +5 -1
  175. package/dist/ai/source/CommonInputWrapper.md +4 -0
  176. package/dist/ai/source/CommonPopover.md +6 -0
  177. package/dist/ai/source/FlatListBox.md +11 -5
  178. package/dist/ai/source/GroupedListBox.md +7 -5
  179. package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +4 -4
  180. package/dist/components/BbAlert/types.d.ts +10 -1
  181. package/dist/components/BbAvatar/BbAvatar.vue.d.ts +1 -1
  182. package/dist/components/BbAvatar/BbAvatar.vue_vue_type_script_setup_true_lang.js +33 -33
  183. package/dist/components/BbBadge/BadgeBodyContent.vue_vue_type_script_setup_true_lang.js +22 -16
  184. package/dist/components/BbBadge/BbBadge.vue_vue_type_script_setup_true_lang.js +36 -15
  185. package/dist/components/BbBadge/badgeButtonContext.d.ts +21 -8
  186. package/dist/components/BbBadge/types.d.ts +8 -2
  187. package/dist/components/BbBaseButton/BbBaseButton.vue_vue_type_script_setup_true_lang.js +47 -47
  188. package/dist/components/BbBaseButton/RouterComponent.vue_vue_type_script_setup_true_lang.js +14 -14
  189. package/dist/components/BbBaseCheckboxGroup/BbBaseCheckboxGroup.vue_vue_type_script_setup_true_lang.js +30 -28
  190. package/dist/components/BbBaseCheckboxGroup/types.d.ts +2 -2
  191. package/dist/components/BbBaseDatePicker/BbBaseDatePicker.vue_vue_type_script_setup_true_lang.js +167 -167
  192. package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue.d.ts +9 -9
  193. package/dist/components/BbBaseDatePicker/BbBaseDatePickerInputDaySelector.vue_vue_type_script_setup_true_lang.js +78 -78
  194. package/dist/components/BbBaseDatePicker/BbBaseDatePickerMonthSelector.vue_vue_type_script_setup_true_lang.js +64 -64
  195. package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue.d.ts +1 -1
  196. package/dist/components/BbBaseDatePickerInput/BbBaseDatePickerInput.vue_vue_type_script_setup_true_lang.js +138 -138
  197. package/dist/components/BbBaseInputContainer/BbBaseInputContainer.vue_vue_type_script_setup_true_lang.js +2 -2
  198. package/dist/components/BbBaseRadioGroup/BbBaseRadioGroup.vue_vue_type_script_setup_true_lang.js +24 -22
  199. package/dist/components/BbBaseRating/BbBaseRating.vue_vue_type_script_setup_true_lang.js +40 -40
  200. package/dist/components/BbBaseSelect/BbBaseSelect.vue_vue_type_script_setup_true_lang.js +74 -65
  201. package/dist/components/BbBaseSelect/types.d.ts +22 -0
  202. package/dist/components/BbBaseSlider/BbBaseSlider.vue_vue_type_script_setup_true_lang.js +5 -5
  203. package/dist/components/BbBaseSwitchGroup/BbBaseSwitchGroup.vue_vue_type_script_setup_true_lang.js +30 -28
  204. package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue.d.ts +1 -1
  205. package/dist/components/BbBaseTimePickerInput/BbBaseTimePickerInput.vue_vue_type_script_setup_true_lang.js +104 -104
  206. package/dist/components/BbBreadcrumbs/BbBreadcrumbs.vue_vue_type_script_setup_true_lang.js +35 -35
  207. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +85 -81
  208. package/dist/components/BbCheckboxGroup/types.d.ts +2 -1
  209. package/dist/components/BbCollapsible/types.d.ts +7 -1
  210. package/dist/components/BbColorInput/BbColorInput.vue.d.ts +1 -1
  211. package/dist/components/BbColorInput/BbColorInput.vue_vue_type_script_setup_true_lang.js +18 -18
  212. package/dist/components/BbColorPalette/BbColorPalette.vue.d.ts +2 -2
  213. package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +50 -50
  214. package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +17 -17
  215. package/dist/components/BbDatePicker/BbDatePicker.vue.d.ts +1 -1
  216. package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +100 -100
  217. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +21 -21
  218. package/dist/components/BbDialog/BbDialog.vue.d.ts +1 -1
  219. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +133 -107
  220. package/dist/components/BbDialog/types.d.ts +29 -2
  221. package/dist/components/BbDropdown/AdaptiveDropdown.vue.d.ts +2 -0
  222. package/dist/components/BbDropdown/AdaptiveDropdown.vue_vue_type_script_setup_true_lang.js +99 -100
  223. package/dist/components/BbDropdown/BbDropdown.vue.d.ts +2 -2
  224. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +208 -201
  225. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +225 -208
  226. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +21 -21
  227. package/dist/components/BbDropdown/types.d.ts +20 -5
  228. package/dist/components/BbDropdownButton/BbDropdownButton.vue_vue_type_script_setup_true_lang.js +5 -5
  229. package/dist/components/BbIcon/BbIcon.vue_vue_type_script_setup_true_lang.js +46 -46
  230. package/dist/components/BbIcon/iconCache.d.ts +33 -0
  231. package/dist/components/BbIcon/iconCache.js +17 -0
  232. package/dist/components/BbNumberInput/BbNumberInput.vue.d.ts +1 -1
  233. package/dist/components/BbNumberInput/BbNumberInput.vue_vue_type_script_setup_true_lang.js +15 -15
  234. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +1 -1
  235. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +254 -208
  236. package/dist/components/BbOffCanvas/types.d.ts +30 -5
  237. package/dist/components/BbPagination/BbPagination.vue.d.ts +1 -1
  238. package/dist/components/BbPopover/BbPopover.vue.d.ts +2 -2
  239. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +149 -146
  240. package/dist/components/BbPopover/types.d.ts +3 -2
  241. package/dist/components/BbRadioGroup/types.d.ts +3 -1
  242. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +27 -23
  243. package/dist/components/BbSelect/types.d.ts +32 -0
  244. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +221 -213
  245. package/dist/components/BbSlider/BbSlider.vue.d.ts +1 -1
  246. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +20 -20
  247. package/dist/components/BbTable/BbTable.vue.d.ts +10 -4
  248. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +1433 -600
  249. package/dist/components/BbTable/BbTableDataRow.d.ts +162 -0
  250. package/dist/components/BbTable/BbTableDataRow.js +136 -0
  251. package/dist/components/BbTable/BbTableExpandRow.d.ts +73 -0
  252. package/dist/components/BbTable/BbTableExpandRow.js +52 -0
  253. package/dist/components/BbTable/types.d.ts +324 -111
  254. package/dist/components/BbTable/utils.d.ts +92 -4
  255. package/dist/components/BbTable/utils.js +71 -36
  256. package/dist/components/BbTabs/types.d.ts +0 -8
  257. package/dist/components/BbTag/BbTag.vue.d.ts +1 -1
  258. package/dist/components/BbTag/BbTag.vue_vue_type_script_setup_true_lang.js +18 -18
  259. package/dist/components/BbTextInput/BbTextInput.vue.d.ts +1 -1
  260. package/dist/components/BbTextInput/BbTextInput.vue_vue_type_script_setup_true_lang.js +18 -18
  261. package/dist/components/BbTextarea/BbTextarea.vue.d.ts +1 -1
  262. package/dist/components/BbTextarea/BbTextarea.vue_vue_type_script_setup_true_lang.js +54 -54
  263. package/dist/components/BbTimePicker/BbTimePicker.vue.d.ts +1 -1
  264. package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +80 -80
  265. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +61 -61
  266. package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +17 -17
  267. package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +13 -13
  268. package/dist/components/BbTooltip/types.d.ts +5 -1
  269. package/dist/components/ChipsBox/ChipsBox.vue_vue_type_script_setup_true_lang.js +17 -17
  270. package/dist/components/ClearableButton/ClearableButton.vue_vue_type_script_setup_true_lang.js +5 -5
  271. package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +2 -1
  272. package/dist/components/FlatListBox/FlatListBox.vue_vue_type_script_setup_true_lang.js +83 -83
  273. package/dist/components/GroupedListBox/GroupedListBox.vue_vue_type_script_setup_true_lang.js +56 -56
  274. package/dist/composables/useBaseOptions.js +30 -20
  275. package/dist/composables/useBbConfig.d.ts +27 -6
  276. package/dist/composables/useBbConfig.js +8 -2
  277. package/dist/composables/useConfig.d.ts +59 -0
  278. package/dist/composables/useConfig.js +9 -0
  279. package/dist/composables/useItemsGetter.d.ts +11 -0
  280. package/dist/composables/useItemsGetter.js +44 -18
  281. package/dist/composables/useLocale.js +10 -7
  282. package/dist/composables/useMobile.js +5 -5
  283. package/dist/composables/usePrefill.d.ts +21 -2
  284. package/dist/composables/usePrefill.js +25 -19
  285. package/dist/composables/useSsrState.d.ts +20 -0
  286. package/dist/composables/useSsrState.js +13 -0
  287. package/dist/composables/useTableWidthContext.d.ts +24 -4
  288. package/dist/composables/useTableWidthContext.js +31 -28
  289. package/dist/composables/useToast.js +5 -5
  290. package/dist/deprecation/ai-deprecations.json.d.ts +121 -11
  291. package/dist/deprecation/ai-deprecations.json.js +1 -1
  292. package/dist/directives/bbDropdown.d.ts +15 -4
  293. package/dist/directives/bbDropdown.js +31 -9
  294. package/dist/directives/createPopoverDirective.d.ts +62 -0
  295. package/dist/directives/createPopoverDirective.js +63 -23
  296. package/dist/i18n/locales/cs.json +4 -1
  297. package/dist/i18n/locales/da.json +4 -1
  298. package/dist/i18n/locales/de.json +4 -1
  299. package/dist/i18n/locales/el.json +4 -1
  300. package/dist/i18n/locales/en.json +4 -1
  301. package/dist/i18n/locales/es.json +4 -1
  302. package/dist/i18n/locales/fi.json +4 -1
  303. package/dist/i18n/locales/fr.json +4 -1
  304. package/dist/i18n/locales/hu.json +4 -1
  305. package/dist/i18n/locales/it.json +4 -1
  306. package/dist/i18n/locales/ja.json +4 -1
  307. package/dist/i18n/locales/ko.json +4 -1
  308. package/dist/i18n/locales/nb.json +4 -1
  309. package/dist/i18n/locales/nl.json +4 -1
  310. package/dist/i18n/locales/pl.json +4 -1
  311. package/dist/i18n/locales/pt.json +4 -1
  312. package/dist/i18n/locales/ro.json +4 -1
  313. package/dist/i18n/locales/ru.json +4 -1
  314. package/dist/i18n/locales/sv.json +4 -1
  315. package/dist/i18n/locales/tr.json +4 -1
  316. package/dist/i18n/locales/uk.json +4 -1
  317. package/dist/i18n/locales/zh-cn.json +4 -1
  318. package/dist/index.d.ts +7 -2
  319. package/dist/index.js +69 -67
  320. package/dist/llms-full.txt +3997 -1458
  321. package/dist/llms-medium.txt +140 -73
  322. package/dist/llms.txt +7 -6
  323. package/dist/locale-blueprint.json +4 -1
  324. package/dist/nuxt-auto-imports.d.ts +100 -0
  325. package/dist/nuxt-auto-imports.js +55 -0
  326. package/dist/nuxt-module.d.ts +22 -1
  327. package/dist/nuxt.js +22 -8
  328. package/dist/plugin.d.ts +10 -1
  329. package/dist/plugin.js +20 -19
  330. package/dist/runtime/nuxt-plugin.js +28 -21
  331. package/dist/styles.css +1 -1
  332. package/dist/utilities/misc/listboxMetrics.d.ts +3 -3
  333. package/dist/utilities/misc/listboxMetrics.js +2 -2
  334. package/dist/utilities/misc/ssrStateInjectionKey.d.ts +42 -0
  335. package/dist/utilities/misc/ssrStateInjectionKey.js +4 -0
  336. package/dist/validated/BbForm.vue_vue_type_script_setup_true_lang.js +45 -27
  337. package/dist/validated/BbSelect.vue.d.ts +2 -0
  338. package/dist/validated/BbSelect.vue_vue_type_script_setup_true_lang.js +1 -0
  339. package/dist/validated/useValidatedField.js +25 -23
  340. package/dist/vite.js +7 -3
  341. package/llms.txt +8 -7
  342. package/package.json +2 -2
  343. package/scripts/lib/eslint-plugin.d.ts +19 -1
  344. package/scripts/lib/eslint-plugin.mjs +155 -14
  345. package/scripts/lib/html-attributes.mjs +91 -0
  346. package/scripts/lib/validate-bb-markup.mjs +59 -11
  347. package/dist/assets/svgs/sort.svg_raw.js +0 -4
  348. package/dist/components/BbBadge/BadgeAppendIcon.vue.d.ts +0 -3
  349. package/dist/components/BbBadge/BadgeAppendIcon.vue.js +0 -5
  350. package/dist/components/BbBadge/BadgeAppendIcon.vue_vue_type_script_setup_true_lang.js +0 -22
@@ -461,7 +461,6 @@ export function useInvoicesWorkspace(): InvoicesWorkspaceContext {
461
461
 
462
462
  <BbTable
463
463
  id="invoices-table"
464
- actions
465
464
  caption="Invoices"
466
465
  :columns="columns"
467
466
  compact
@@ -735,7 +734,11 @@ const statusGroup: BbDropdownItem = {
735
734
 
736
735
  // Pipeline facet: `prefill: true` resolves a picked customer's name eagerly,
737
736
  // so a chip never sits on a bare id while this group's own submenu (inside
738
- // the Filters menu) has never been opened.
737
+ // the Filters menu) has never been opened. The eager flag belongs HERE, on
738
+ // the menu's copy only — the chip derives its own copy with
739
+ // `prefill: 'interaction'` (see FilterChip.vue), because a second dropdown
740
+ // redeclaring `prefill: true` would fetch every seeded facet twice on page
741
+ // load for nothing.
739
742
  const customerGroup: BbDropdownItem = {
740
743
  key: 'customer',
741
744
  label: 'Customer',
@@ -787,10 +790,10 @@ const menu = computed<BbDropdownItem[]>(() => [
787
790
  component sitting between `BbBadge` and `BbBadgeButton` breaks the
788
791
  badge's direct-child vnode scan (the companion must be a literal
789
792
  child). This IS "the chip is itself a dropdown onto the same filter
790
- group": `group` is the exact descriptor FilterRail declared, reused
791
- rather than redeclared, so this scoped picker and the Filters menu's
792
- own submenu can never drift apart. -->
793
- <BbDropdown :activator="chipRef" :items="[group]" :width="220">
793
+ group": `chipGroup` is derived from the exact descriptor FilterRail
794
+ declared (spread, one override — never redeclared), so this scoped
795
+ picker and the Filters menu's own submenu can never drift apart. -->
796
+ <BbDropdown :activator="chipRef" :items="[chipGroup]" :width="220">
794
797
  <BbDropdownGroup
795
798
  :id="groupKey"
796
799
  :model-value="modelValue"
@@ -824,9 +827,24 @@ const emit = defineEmits<{ 'update:modelValue': [value: unknown] }>();
824
827
 
825
828
  const chipRef = useTemplateRef('chipRef');
826
829
 
830
+ // The chip's own copy of the shared descriptor, one override: `prefill:
831
+ // 'interaction'`. BbDropdown mounts a pipeline resolver for every group it
832
+ // declares at its own root, independent of the panel ever opening — so if
833
+ // this second dropdown repeated the menu's `prefill: true` verbatim, each
834
+ // seeded pipeline facet would be fetched TWICE on page load, and the chip's
835
+ // copy of the result would feed nothing (the label below comes from the
836
+ // menu's resolution via context). `'interaction'` defers this copy's fetch
837
+ // to the moment the chip's dropdown is actually opened. For static array
838
+ // facets the override is inert — arrays resolve synchronously either way.
839
+ const chipGroup = computed<BbDropdownItem>(() => ({
840
+ ...props.group,
841
+ prefill: 'interaction',
842
+ }));
843
+
827
844
  // Reads the Filters menu's already-resolved selection — no twin fetch. A
828
- // pipeline group needs `prefill: true` (set on `group` by FilterRail) so this
829
- // never sits on a bare id/value while the menu's own submenu is unopened.
845
+ // pipeline group needs `prefill: true` (set on the MENU's copy of `group` by
846
+ // FilterRail) so this never sits on a bare id/value while the menu's own
847
+ // submenu is unopened.
830
848
  const dropdownFilters = useBbDropdownContext('invoice-filters');
831
849
  const chipText = computed(() => {
832
850
  const options =
@@ -603,7 +603,6 @@ export function useUploadCenter(): UploadCenterContext {
603
603
 
604
604
  <BbTable
605
605
  id="receipts-table"
606
- actions
607
606
  caption="Expense receipts"
608
607
  :columns="columns"
609
608
  compact
@@ -190,7 +190,16 @@ export type BbAlertEvents =
190
190
 
191
191
  /** Props exposed by the `title` slot. */
192
192
  export type BbAlertTitleSlotProps = {
193
- /** The `title` prop value. */
193
+ /**
194
+ * The `title` prop's value — despite the scope being named `text`.
195
+ *
196
+ * Both slots name their payload `text` (each meaning "the text of THIS
197
+ * slot"), so `#title="{ text }"` gives you the title and
198
+ * `#text="{ text }"` gives you the body. Worth stating because the v2 bug
199
+ * this replaced was the opposite mix-up: v2's `#text` slot passed the
200
+ * *title*. Renaming the scope now would be another break, so the rule is
201
+ * simply: the payload belongs to the slot you are in.
202
+ */
194
203
  text: BbAlertProps['title'];
195
204
  };
196
205
 
@@ -290,9 +299,23 @@ export type BbAlertSlots = {
290
299
  }
291
300
  }
292
301
 
302
+ /*
303
+ * Q17.1 — the body is the danger colour at FULL strength, not a mix.
304
+ *
305
+ * The 75%-of-main formula the quiet variants use holds for `outline` and
306
+ * `primary`, whose `--main-color` is already a text colour. It does not hold
307
+ * for a STATUS colour: 75% of `--bb-danger` measures 3.18:1 light / 3.17:1
308
+ * dark against the panel, under the 4.5:1 budget real message text carries.
309
+ *
310
+ * Dropping the mix fixes that without changing what the variant IS: 4.55:1
311
+ * in both schemes, and the body stays red — which is also what shadcn does,
312
+ * colouring title and description alike. (A neutral grey body was tried and
313
+ * reverted: it cleared contrast comfortably but read as a different
314
+ * component.) Hierarchy comes from the title's font-weight, as before.
315
+ */
293
316
  &--destructive {
294
317
  --main-color: var(--bb-danger);
295
- --muted-color: color-mix(in oklab, var(--main-color) 75%, transparent);
318
+ --muted-color: var(--main-color);
296
319
  background-color: transparent;
297
320
  border-color: var(--bb-border);
298
321
 
@@ -316,6 +339,31 @@ export type BbAlertSlots = {
316
339
  }
317
340
  }
318
341
 
342
+ /*
343
+ * Warning keeps the shadcn amber it has always had — the owner's call, and
344
+ * the palette is deliberate. What changed is HOW the two schemes are
345
+ * selected (Q4.1).
346
+ *
347
+ * The old rule paired a light block with `:where(.dark) &--warning`. Because
348
+ * `:where()` contributes no specificity, that tied the light rule at (0,1,0)
349
+ * and won on source order — so it matched through ANY `.dark` ancestor. A
350
+ * `.light` island inside a dark page (the docs theme builder's light preview
351
+ * pane is exactly this) flipped every other component back to light and left
352
+ * the warning Alert dark on a white panel. No scope class could beat it at
353
+ * any nesting depth.
354
+ *
355
+ * `light-dark()` keys off the element's computed `color-scheme`, which
356
+ * variables.css already sets on `.light` / `.dark`. That makes the choice
357
+ * INHERITED rather than selector-matched, so the nearest scheme scope wins
358
+ * — a dark card inside a light island inside a dark page resolves correctly,
359
+ * which is the case a second selector can never get right.
360
+ *
361
+ * The two rules below it are the pre-`light-dark()` fallback, kept exactly
362
+ * as they shipped: on a browser without it (pre-Chrome 123 / Safari 17.5 /
363
+ * Firefox 120) the `@supports` block simply does not apply and behaviour is
364
+ * identical to before, island leak included. Nothing regresses; modern
365
+ * browsers just stop leaking.
366
+ */
319
367
  &--warning {
320
368
  --main-color: #7b3306;
321
369
  --muted-color: #737373;
@@ -349,6 +397,16 @@ export type BbAlertSlots = {
349
397
  border-color: #7c5f1f;
350
398
  }
351
399
 
400
+ /* Wins over both of the above wherever it is understood. */
401
+ @supports (color: light-dark(red, blue)) {
402
+ &--warning {
403
+ --main-color: light-dark(#7b3306, #facc15);
404
+ --muted-color: light-dark(#737373, #d6d3d1);
405
+ background-color: light-dark(#fffbea, #2a2112);
406
+ border-color: light-dark(#fee685, #7c5f1f);
407
+ }
408
+ }
409
+
352
410
  .bb-alert__inner-container {
353
411
  align-items: start;
354
412
  display: grid;
@@ -36,22 +36,22 @@
36
36
  import { computed, onMounted, ref, watch } from 'vue';
37
37
  import { parseSize } from '@/utilities/functions/parseSize';
38
38
  import { wait } from '@/utilities/functions/wait';
39
- import { config } from 'virtual:bitboss-ui/config';
39
+ import { useConfig } from '@/composables/useConfig';
40
40
  import { useLogger } from '@/composables/useLogger';
41
41
  import { removedPropsFor } from '@/deprecation/removedProps';
42
42
  import { warnRemovedAttrs } from '@/utilities/functions/warnRemovedAttrs';
43
43
  import BbIcon from '../BbIcon/BbIcon.vue';
44
44
  import defaultFallbackIcon from '@/assets/svgs/user.svg?raw';
45
45
  import type { BbAvatarProps, BbAvatarSlots } from './types';
46
- export type { BbAvatarProps, BbAvatarSlots };
47
46
 
48
47
  const props = withDefaults(defineProps<BbAvatarProps>(), {
49
48
  alt: '',
50
49
  timeout: 400,
51
50
  size: 'md',
52
51
  });
53
-
54
52
  defineSlots<BbAvatarSlots>();
53
+ const config = useConfig();
54
+ export type { BbAvatarProps, BbAvatarSlots };
55
55
 
56
56
  if (process.env.NODE_ENV !== 'production')
57
57
  warnRemovedAttrs('BbAvatar', removedPropsFor('BbAvatar'));
@@ -19,7 +19,17 @@
19
19
  The append icon joins it here so the two can share the hover swap; on a
20
20
  non-clearable badge it renders inside the body instead. -->
21
21
  <span v-if="props.clearable" class="bb-badge__trailing">
22
- <BadgeAppendIcon v-if="!props.icon" />
22
+ <template v-if="!props.icon">
23
+ <BbSpinner
24
+ v-if="props.loading && spinnerTrails()"
25
+ class="bb-badge__append-icon"
26
+ />
27
+ <BbIcon
28
+ v-else-if="props['append:icon']"
29
+ class="bb-badge__append-icon"
30
+ :icon="props['append:icon']"
31
+ />
32
+ </template>
23
33
  <button
24
34
  :id="`${badgeId}__clear`"
25
35
  :aria-label="props.clearableLabel || t('badge.clearLabel').value"
@@ -45,7 +55,7 @@ import { useLogger } from '@/composables/useLogger';
45
55
  import { removedPropsFor } from '@/deprecation/removedProps';
46
56
  import { warnRemovedAttrs } from '@/utilities/functions/warnRemovedAttrs';
47
57
  import BbIcon from '../BbIcon/BbIcon.vue';
48
- import BadgeAppendIcon from './BadgeAppendIcon.vue';
58
+ import BbSpinner from '../BbSpinner/BbSpinner.vue';
49
59
  import BadgeBodyContent from './BadgeBodyContent.vue';
50
60
  import BbBadgeButton from './BbBadgeButton.vue';
51
61
  import { provideBadgeHost } from './badgeButtonContext';
@@ -80,9 +90,7 @@ const normalizedSize = computed(() => {
80
90
  });
81
91
 
82
92
  /** The spinner overlays the append slot only when the append icon is the sole icon. */
83
- const spinnerTrails = computed(
84
- () => !!props['append:icon'] && !props['prepend:icon']
85
- );
93
+ const spinnerTrails = () => !!props['append:icon'] && !props['prepend:icon'];
86
94
 
87
95
  /* ── BbBadgeButton detection ─────────────────────────────── */
88
96
 
@@ -106,15 +114,46 @@ const scanForButton = (nodes: unknown): boolean =>
106
114
  const detectButton = () => scanForButton(slots.default?.({}));
107
115
 
108
116
  // Published to the subtree: BadgeBodyContent — ours or the one inside a
109
- // slotted BbBadgeButton — renders the leading side from this state.
117
+ // slotted BbBadgeButton — renders the leading side from this state. Plain
118
+ // getters, not `computed()`: see `HostValue`. Every entry is a bare prop read,
119
+ // so there is nothing for a computed to memoize — and seven reactive effects
120
+ // per badge is a real per-row tax in a table cell that carries three of them.
110
121
  provideBadgeHost({
111
- icon: computed(() => props.icon),
112
- prependIcon: computed(() => props['prepend:icon']),
113
- appendIcon: computed(() => props['append:icon']),
114
- loading: computed(() => !!props.loading),
115
- spinnerLeads: computed(() => !!props.loading && !spinnerTrails.value),
116
- spinnerTrails: computed(() => !!props.loading && spinnerTrails.value),
117
- clearable: computed(() => !!props.clearable),
122
+ icon: {
123
+ get value() {
124
+ return props.icon;
125
+ },
126
+ },
127
+ prependIcon: {
128
+ get value() {
129
+ return props['prepend:icon'];
130
+ },
131
+ },
132
+ appendIcon: {
133
+ get value() {
134
+ return props['append:icon'];
135
+ },
136
+ },
137
+ loading: {
138
+ get value() {
139
+ return !!props.loading;
140
+ },
141
+ },
142
+ spinnerLeads: {
143
+ get value() {
144
+ return !!props.loading && !spinnerTrails();
145
+ },
146
+ },
147
+ spinnerTrails: {
148
+ get value() {
149
+ return !!props.loading && spinnerTrails();
150
+ },
151
+ },
152
+ clearable: {
153
+ get value() {
154
+ return !!props.clearable;
155
+ },
156
+ },
118
157
  });
119
158
 
120
159
  const badgeClasses = computed(() => [
@@ -202,8 +241,14 @@ export type BbBadgeProps = {
202
241
  */
203
242
  clearable?: boolean;
204
243
  /**
205
- * Accessible label for the clear button. Falls back to the localized
206
- * `badge.clearLabel` key.
244
+ * Accessible label for the clear button.
245
+ *
246
+ * Rarely needed: unset, the name is **composed** from the localized
247
+ * `badge.clearLabel` verb and the badge's own text — "Remove Italy", not a
248
+ * bare "Remove" — which is already the right name in almost every case.
249
+ * Composition is skipped when a `BbBadgeButton` owns the body (the verb
250
+ * then stands alone, so the two controls do not both announce the label).
251
+ * Set this only to override that composed name outright.
207
252
  */
208
253
  clearableLabel?: string;
209
254
  /**
@@ -105,8 +105,14 @@ export type BbBadgeProps = {
105
105
  */
106
106
  clearable?: boolean;
107
107
  /**
108
- * Accessible label for the clear button. Falls back to the localized
109
- * `badge.clearLabel` key.
108
+ * Accessible label for the clear button.
109
+ *
110
+ * Rarely needed: unset, the name is **composed** from the localized
111
+ * `badge.clearLabel` verb and the badge's own text — "Remove Italy", not a
112
+ * bare "Remove" — which is already the right name in almost every case.
113
+ * Composition is skipped when a `BbBadgeButton` owns the body (the verb
114
+ * then stands alone, so the two controls do not both announce the label).
115
+ * Set this only to override that composed name outright.
110
116
  */
111
117
  clearableLabel?: string;
112
118
  /**
@@ -47,7 +47,7 @@ import RouterComponent from './RouterComponent.vue';
47
47
  import { useFrameworkDetection } from '@/composables/useFrameworkDetection';
48
48
  import { useHydrated } from '@/composables/useHydrated';
49
49
  import { useInertiaPage } from '@/composables/useInertiaPage';
50
- import { config } from 'virtual:bitboss-ui/config';
50
+ import { useConfig } from '@/composables/useConfig';
51
51
  import type { BbBaseButtonProps, BbBaseButtonSlots } from './types';
52
52
 
53
53
  const props = withDefaults(defineProps<BbBaseButtonProps>(), {
@@ -56,6 +56,8 @@ const props = withDefaults(defineProps<BbBaseButtonProps>(), {
56
56
 
57
57
  defineSlots<BbBaseButtonSlots>();
58
58
 
59
+ const config = useConfig();
60
+
59
61
  const { isInertia, isNuxt } = useFrameworkDetection();
60
62
  const { isHydrated } = useHydrated();
61
63
  const { getPageUrl } = useInertiaPage();
@@ -109,6 +109,8 @@ useOnTruthy(active, () => emit('active'));
109
109
 
110
110
  const {
111
111
  getter,
112
+ clientReproducible,
113
+ hydratedFromSsr,
112
114
  items: internalItems,
113
115
  loading,
114
116
  } = useItemsGetter({
@@ -122,6 +124,8 @@ const alignToCoherenceSettings = () => {
122
124
  };
123
125
 
124
126
  const { hasPrefilled } = usePrefill({
127
+ alreadyLoaded: hydratedFromSsr,
128
+ clientReproducible,
125
129
  trigger: true,
126
130
  currentValue: props.modelValue,
127
131
  multiple: props.multiple,
@@ -287,7 +291,7 @@ export type BaseCheckboxGroupProps<T = any> = {
287
291
  /**
288
292
  * Enforces that `modelValue` contains only values present in `items`.
289
293
  * Incoherent values are removed and `update:modelValue` is emitted with a
290
- * coherent array. Please check out {@link https://ui-components-docs.vercel.app/it/guides/coherence | the docs} for more information.
294
+ * coherent array. Please check out {@link https://ui-components.bitboss.it/it/guides/coherence | the docs} for more information.
291
295
  * @defaultValue `false`
292
296
  */
293
297
  enforceCoherence?: boolean;
@@ -402,7 +406,7 @@ export type BaseCheckboxGroupEvents = {
402
406
  */
403
407
  (e: 'blur', event: FocusEvent): void;
404
408
  /**
405
- * Emitted when a checkbox option is toggled.
409
+ * Emitted when an option is toggled.
406
410
  * Forwards the original DOM `Event` from the checkbox input.
407
411
  */
408
412
  (e: 'change', event: Event): void;
@@ -176,7 +176,7 @@ import MonthSelector from './BbBaseDatePickerMonthSelector.vue';
176
176
  import ScaleFadeTransition from '@/components/Transitions/ScaleFade.vue';
177
177
  import YearSelector from './BbBaseDatePickerYearSelector.vue';
178
178
  import { useLocale } from '@/composables/useLocale';
179
- import { config } from 'virtual:bitboss-ui/config';
179
+ import { useConfig } from '@/composables/useConfig';
180
180
  import { normalizeSearchToken, useTypeahead } from './typeahead';
181
181
  import {
182
182
  provideDatePickerContext,
@@ -199,6 +199,8 @@ import type {
199
199
  BaseDatePickerSlots,
200
200
  } from './types';
201
201
 
202
+ const config = useConfig();
203
+
202
204
  const { t } = useLocale();
203
205
 
204
206
  const globalId = props.id || useId().id;
@@ -175,7 +175,7 @@
175
175
  </template>
176
176
 
177
177
  <script setup lang="ts">
178
- import { config } from 'virtual:bitboss-ui/config';
178
+ import { useConfig } from '@/composables/useConfig';
179
179
  import { computed, onBeforeUnmount, ref, watch, watchEffect } from 'vue';
180
180
  import type { Dayjs } from 'dayjs';
181
181
  import { default as dayjs } from 'dayjs';
@@ -230,7 +230,11 @@ const props = withDefaults(defineProps<BaseDatePickerInputProps>(), {
230
230
  });
231
231
 
232
232
  const emit = defineEmits<BaseDatePickerInputEvents>();
233
+
233
234
  defineSlots<BaseDatePickerInputSlots>();
235
+
236
+ const config = useConfig();
237
+
234
238
  /**
235
239
  * Time affordances belong to one member of the union. Reading the type through
236
240
  * these keeps the old `props.datetime` branches intact while the union stays
@@ -274,8 +274,11 @@ const widths = computed(() => {
274
274
  initial.input = second;
275
275
  }
276
276
  } else {
277
+ // The ratio is CHARACTER COUNT, not numeric value: 'x xx' is 1:2. This
278
+ // message used to name '1 2', which is two one-character tokens — a
279
+ // 50/50 split, and precisely the mistake the warning exists to prevent.
277
280
  logger.warn(
278
- `Invalid direction: "${resolvedDirection.value}". Expected 'auto', 'vertical', 'horizontal', or a two-token ratio like '1 2'. Falling back to 'auto'.`
281
+ `Invalid direction: "${resolvedDirection.value}". Expected 'auto', 'vertical', 'horizontal', or a two-token pattern whose TOKEN LENGTHS are the ratio, like 'x xx' for 1:2. Falling back to 'auto'.`
279
282
  );
280
283
  // `initial` is already the auto shape (label/input: 'auto'), so falling
281
284
  // through here leaves the layout at the safe default.
@@ -657,6 +660,22 @@ export type BaseInputContainerSlots = {
657
660
  display: flex;
658
661
  flex-direction: column;
659
662
 
663
+ /*
664
+ * A field never sizes its own track from its content.
665
+ * -----------------------------------------------------------------
666
+ * As a grid or flex item this container's automatic minimum size is
667
+ * `min-content`, and for a select that is the ENTIRE placeholder string:
668
+ * the trigger paints its placeholder as real `nowrap` text, because a
669
+ * native `::placeholder` only exists on a real `<input>`. So a long
670
+ * placeholder used to widen the column it sat in, while a `BbTextInput`
671
+ * next to it held its own (its `<input>` floors at `min-width: 50px` and
672
+ * `::placeholder` is paint-only). In a `repeat(3, 1fr)` form row that
673
+ * measured 188.9 / 226 / 68px instead of three equal tracks.
674
+ *
675
+ * The floor lives on the control, not here — see `__control` below.
676
+ */
677
+ min-width: 0;
678
+
660
679
  /*
661
680
  * Compact mode
662
681
  * -----------------------------------------------------------------
@@ -961,6 +980,16 @@ export type BaseInputContainerSlots = {
961
980
  */
962
981
  display: grid;
963
982
 
983
+ /* Same reason as the container root: this is a flex item, so its
984
+ automatic minimum would re-introduce the content floor the root just
985
+ dropped. `min-width` has to be 0 on EVERY link between the sized
986
+ ancestor and the element that ellipses, or the chain stops truncating
987
+ at the first link that still says `auto`. The 50px keeps a squeezed
988
+ field usable, mirroring the `min-width: 50px` the native input and
989
+ textarea already carry so a select and a text input degrade
990
+ identically. */
991
+ min-width: min(50px, 100%);
992
+
964
993
  &--left {
965
994
  justify-items: flex-start;
966
995
  }
@@ -972,6 +1001,28 @@ export type BaseInputContainerSlots = {
972
1001
  }
973
1002
  }
974
1003
 
1004
+ /*
1005
+ * Control-first widgets opt OUT of that floor.
1006
+ * -----------------------------------------------------------------
1007
+ * The 50px above buys a squeezed text track a usable minimum. These four
1008
+ * have no track: their control is a fixed-size glyph (a 16px box, a 32px
1009
+ * switch) and `direction: 'auto'` leaves `widths.input` at `auto`, so the
1010
+ * floor was the only thing sizing the column — a 16px checkbox sat in a
1011
+ * 50px cell and its label started 42px away instead of the
1012
+ * `--bb-label-spacing-x` the layout intends. Pinned in BbCheckbox.test.ts.
1013
+ *
1014
+ * Groups are deliberately NOT here: a group's control column holds full
1015
+ * option rows with their own labels, so it still wants a floor.
1016
+ */
1017
+ &.bb-checkbox,
1018
+ &.bb-radio,
1019
+ &.bb-switch,
1020
+ &.bb-rating {
1021
+ .bb-base-input-container__control {
1022
+ min-width: 0;
1023
+ }
1024
+ }
1025
+
975
1026
  &__description {
976
1027
  /*
977
1028
  * Description channel
@@ -134,6 +134,8 @@ useOnTruthy(active, () => emit('active'));
134
134
 
135
135
  const {
136
136
  getter,
137
+ clientReproducible,
138
+ hydratedFromSsr,
137
139
  items: internalItems,
138
140
  loading,
139
141
  } = useItemsGetter({
@@ -147,6 +149,8 @@ const alignToCoherenceSettings = () => {
147
149
  };
148
150
 
149
151
  const { hasPrefilled } = usePrefill({
152
+ alreadyLoaded: hydratedFromSsr,
153
+ clientReproducible,
150
154
  trigger: true,
151
155
  currentValue: props.modelValue,
152
156
  multiple: false,
@@ -95,7 +95,7 @@ import { useOnFalsy } from '@/composables/useOnFalsy';
95
95
  import { useOnTruthy } from '@/composables/useOnTruthy';
96
96
  import { useId } from '@/composables/useId';
97
97
  import { useLogger } from '@/composables/useLogger';
98
- import { config } from 'virtual:bitboss-ui/config';
98
+ import { useConfig } from '@/composables/useConfig';
99
99
 
100
100
  const props = withDefaults(defineProps<BaseRatingProps>(), {
101
101
  clearable: false,
@@ -106,6 +106,8 @@ const emit = defineEmits<BaseRatingEvents>();
106
106
 
107
107
  defineSlots<BaseRatingSlots>();
108
108
 
109
+ const config = useConfig();
110
+
109
111
  const { t } = useLocale();
110
112
  const logger = useLogger();
111
113
 
@@ -115,7 +115,11 @@
115
115
  v-if="usesOverflowCollapse || !isCollapsed"
116
116
  ref="chipsContainerRef"
117
117
  class="bb-base-select__chips-row"
118
- :class="{ 'bb-base-select__chips-row--hidden': isCollapsed }"
118
+ :class="{
119
+ 'bb-base-select__chips-row--hidden': isCollapsed,
120
+ 'bb-base-select__chips-row--chips':
121
+ !comma && !!selectedOptions.length,
122
+ }"
119
123
  >
120
124
  <template v-if="comma">
121
125
  <span
@@ -127,19 +131,40 @@
127
131
  </span>
128
132
  </template>
129
133
  <!-- One badge per selection: removable (clearable) when
130
- deselection is allowed, non-removable otherwise. -->
134
+ deselection is allowed, non-removable otherwise. The `chip`
135
+ slot replaces the badge outright (the badge below is its
136
+ fallback), so a consumer can render their own chip — a colored
137
+ tag, an avatar row — without reaching for `prepend`. No wrapper
138
+ element around it: the row itself supplies the spacing (see
139
+ `--chips` in index.css), so custom content needs none of our
140
+ class names to sit correctly. -->
131
141
  <template v-else>
132
- <BbBadge
142
+ <!-- `v-for` on a `<template>`, not on the `<slot>` itself: a
143
+ `key` bound on a slot outlet is passed through as a slot
144
+ PROP. The template renders no element of its own. -->
145
+ <template
133
146
  v-for="item in selectedOptions"
134
147
  :key="hash(item.value)"
135
- class="bb-base-select__chip"
136
- :clearable="canDeselectChips"
137
- size="lg"
138
- variant="secondary"
139
- @click:clear.stop="onChipUnselected(item)"
140
148
  >
141
- {{ item.text }}
142
- </BbBadge>
149
+ <slot
150
+ :deselect="() => onChipUnselected(item)"
151
+ :disabled="!canDeselectChips"
152
+ :item="item.item"
153
+ name="chip"
154
+ :text="item.text"
155
+ :value="item.value"
156
+ >
157
+ <BbBadge
158
+ class="bb-base-select__chip"
159
+ :clearable="canDeselectChips"
160
+ size="lg"
161
+ variant="secondary"
162
+ @click:clear.stop="onChipUnselected(item)"
163
+ >
164
+ {{ item.text }}
165
+ </BbBadge>
166
+ </slot>
167
+ </template>
143
168
  </template>
144
169
  </span>
145
170
  <span v-if="isCollapsed" class="bb-base-select__max-reached">
@@ -769,6 +794,27 @@ export type BaseSelectPanelSlotProps = {
769
794
  selectedOptions: BbSelectResolvedOption[];
770
795
  };
771
796
 
797
+ /**
798
+ * Props exposed by the `chip` slot — called once per selected value in
799
+ * `multiple` mode, in place of the default badge. Not called in `comma` mode
800
+ * (there are no chips there) nor for the collapsed "+N" summary.
801
+ */
802
+ export type BaseSelectChipSlotProps<Item = any> = {
803
+ /** The selected item, exactly as it was supplied in `items`. */
804
+ item: Item;
805
+ /** The item's resolved display text (what the default badge prints). */
806
+ text: string;
807
+ /** The item's resolved value — what sits in the v-model. */
808
+ value: any;
809
+ /**
810
+ * `true` while the control is disabled or readonly: the chip must not offer
811
+ * a way to remove itself, and `deselect` is a no-op.
812
+ */
813
+ disabled: boolean;
814
+ /** Drops this value from the selection. No-op while `disabled`. */
815
+ deselect: () => void;
816
+ };
817
+
772
818
  export type BaseSelectSlots<Item = any> = {
773
819
  /** Content pinned to the top of the panel, above the search field. */
774
820
  header?: (props: BaseSelectPanelSlotProps) => any;
@@ -784,6 +830,8 @@ export type BaseSelectSlots<Item = any> = {
784
830
  'no-data'?: (props: { query: string; focus: () => void }) => any;
785
831
  option?: (props: BaseSelectOptionSlotProps<Item>) => any;
786
832
  group?: (props: BaseSelectGroupSlotProps<Item>) => any;
833
+ /** Replaces the default badge rendered for each selection in `multiple` mode. */
834
+ chip?: (props: BaseSelectChipSlotProps<Item>) => any;
787
835
  };
788
836
  ```
789
837
 
@@ -885,12 +933,19 @@ export type BaseSelectSlots<Item = any> = {
885
933
  pointer-events: none;
886
934
  visibility: hidden;
887
935
  }
888
- }
889
936
 
890
- &__chip {
891
- flex-shrink: 0;
892
- &:not(:last-child) {
893
- margin-right: 0.25rem;
937
+ /* Chips mode with at least one selection — never comma mode, which
938
+ separates with its own `,` and wants no gap. The `chip` slot lets a
939
+ consumer render their own element in place of our badge, so the layout
940
+ a chip needs (no shrinking, the gap between chips, and the negative
941
+ inset coupling below) lives HERE, on the row, rather than on a
942
+ `__chip` class custom content would have to know to apply. */
943
+ &--chips {
944
+ gap: 0.25rem;
945
+
946
+ > * {
947
+ flex-shrink: 0;
948
+ }
894
949
  }
895
950
  }
896
951
 
@@ -927,7 +982,7 @@ export type BaseSelectSlots<Item = any> = {
927
982
  }
928
983
  /* If there is no prepend icon, add a negative margin to the chips row so it smoothly couples with the border */
929
984
  &:not(:has(.common-input-wrapper__prepend-icon)) {
930
- .bb-base-select__chips-row:has(.bb-base-select__chip) {
985
+ .bb-base-select__chips-row--chips {
931
986
  margin-left: calc(
932
987
  var(--bb-input-px) * var(--compensation-multiplier) * -1
933
988
  );