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
@@ -34,17 +34,78 @@ declare function setConfig(patch: Partial<DynamicConfig>): void;
34
34
  // DynamicConfig = { locale: 'it' | 'en' }
35
35
  ```
36
36
 
37
- Merges the patch into the live config object. The change is global, immediate,
38
- and reactive — every mounted component that reads the key updates.
39
-
40
- **SSR caveat call it on the client only.** On an SSR server (Nuxt, Inertia
41
- SSR) the config object is a **process-global singleton**, not per-request
42
- state the same rule `ssrViewportWidth` documents: there is no per-request
43
- override. Calling `setConfig` during a server render mutates the config for
44
- the whole process, leaking that visitor's locale into concurrent and
45
- subsequent renders for other visitors. A per-visitor locale that is already
46
- right on the server's first paint is not possible today; the first paint
47
- renders in the build-time `locale` and the client switches after hydration.
37
+ Merges the patch into **this app's** config. The change is immediate and
38
+ reactive — every mounted component in that app which reads the key updates.
39
+
40
+ ### Per-request locale under SSR
41
+
42
+ The config is held **per Vue app**, and SSR gives every request its own app,
43
+ so a per-visitor locale is correct on the server's first paint. Set it where
44
+ the app is created:
45
+
46
+ ```ts
47
+ // server entry one app per request, so this is per-request
48
+ const app = createSSRApp(App);
49
+ app.use(bitbossUiPlugin, { locale: localeFor(request) });
50
+ ```
51
+
52
+ That is the route to prefer. It is right before hydration, so it is what
53
+ crawlers index, what a prerendered search index reads, and what a reader with
54
+ JS disabled keeps.
55
+
56
+ #### Nuxt
57
+
58
+ **Do not call `app.use(bitbossUiPlugin)` in Nuxt** — the `bitboss-ui/nuxt`
59
+ module registers the runtime plugin for you, and that plugin provides the
60
+ per-app config itself. `defineNuxtPlugin` runs per request on the server and
61
+ Nuxt builds one Vue app per request, so your own plugin is the per-request
62
+ seam:
63
+
64
+ ```ts
65
+ // plugins/bitboss-locale.ts
66
+ import { useBbConfig } from 'bitboss-ui';
67
+
68
+ export default defineNuxtPlugin((nuxtApp) => {
69
+ const locale = localeFor(useRequestEvent());
70
+ // A plugin has an APP but no component instance, so hand it the app's
71
+ // injection context — otherwise the write cannot find this app's config
72
+ // and lands on the process-global defaults.
73
+ nuxtApp.vueApp.runWithContext(() => {
74
+ useBbConfig().setConfig({ locale });
75
+ });
76
+ });
77
+ ```
78
+
79
+ Calling `setConfig` from a component's `setup` works in Nuxt too, and is
80
+ per-request for the same reason. `runWithContext` is only needed where no
81
+ component exists yet.
82
+
83
+ > Fixed in 3.0.0-beta.19 (Q20.4). Before that the Nuxt runtime plugin never
84
+ > provided the config, so **every** `setConfig` under Nuxt — including from a
85
+ > component's `setup`, the path this page prescribed — wrote the process-global
86
+ > and leaked across concurrent visitors, silently. If you worked around it,
87
+ > you can stop.
88
+
89
+ #### The rule, and what the dev warning means
90
+
91
+ **`setConfig` during a server render needs an app to address.** From a
92
+ component's `setup` (or a composable a component calls), or inside
93
+ `app.runWithContext`, it resolves the current app and the write is
94
+ per-visitor. With neither — module scope, say — there is no app, the write
95
+ lands on the process-global build-time defaults, and it leaks into other
96
+ visitors being served concurrently.
97
+
98
+ The dev warning fires on exactly that: it compares where the write actually
99
+ landed against the build-time object, rather than guessing from the call site.
100
+ So it stays silent for a correct per-app write, and it still fires for a
101
+ global one made from inside a component — which is what a missing plugin (or,
102
+ before beta.19, Nuxt) produced.
103
+
104
+ On the client none of this matters: one process is one user, and `setConfig`
105
+ from anywhere is fine.
106
+
107
+ _(Changed in 3.0.0-beta.15 — Q18.2. Before it, the config was a single
108
+ process-global object and a per-visitor locale genuinely was impossible.)_
48
109
 
49
110
  ## Usage example
50
111
 
@@ -9,7 +9,9 @@ type: composable
9
9
  ## Summary
10
10
 
11
11
  `useConfirm` opens a modal confirm dialog and returns a promise that resolves
12
- with the user's decision. Dialogs are queued if one is open, the next waits.
12
+ with the user's decision. **A new `confirm()` replaces the open dialog**: the
13
+ superseded promise resolves `false` and no callback runs. Dialogs do not queue,
14
+ so `await` one before opening the next.
13
15
  Per the design language, every `destructive` action must pass through a confirm.
14
16
 
15
17
  **Requires exactly one `<BbConfirm />` host, mounted at the app root** (`App.vue`
@@ -28,7 +30,7 @@ const { confirm, close, dismissAll } = useConfirm();
28
30
 
29
31
  **Ownership** — when called inside a component (any effect scope), the
30
32
  returned `confirm`'s dialogs are tied to that scope: if it is disposed while a
31
- dialog is open or queued (browser Back, route change, the component unmounts),
33
+ dialog is open (browser Back, route change, the component unmounts),
32
34
  the dialog is dismissed quietly — promise resolved `false`, no callback runs.
33
35
  Call `useConfirm()` outside a component scope (app setup, store, module level)
34
36
  for app-lifetime confirms.
@@ -71,7 +73,7 @@ promise pending.
71
73
  declare function dismissAll(): void;
72
74
  ```
73
75
 
74
- Quietly dismisses the open dialog and any queued ones, regardless of owner:
76
+ Quietly dismisses the open dialog, regardless of owner:
75
77
  pending promises resolve `false`, no callback runs. An imperative escape hatch
76
78
  for app-level events — logout, a global error boundary, or router wiring in
77
79
  apps that want route-based dismissal.
@@ -14,13 +14,18 @@ Knowledge base root (installed package):
14
14
  Package export entry: `bitboss-ui/ai` → `dist/ai/index.md`.
15
15
  Subpaths: `bitboss-ui/ai/components.json`, `bitboss-ui/ai/guides/…`, etc.
16
16
 
17
- **Not installed, or can only fetch URLs?** The same files are served from the
18
- published package at `https://cdn.jsdelivr.net/npm/bitboss-ui@beta/dist/ai/…`.
19
- If you can make only one request, fetch
20
- [`…@beta/dist/llms-medium.txt`](https://cdn.jsdelivr.net/npm/bitboss-ui@beta/dist/llms-medium.txt)
17
+ **Not installed, or can only fetch URLs?** The same files are served at
18
+ `https://llms-bitboss-ui.bitboss.it/dist/ai/…`. If you can make only one
19
+ request, fetch
20
+ [`/dist/llms-medium.txt`](https://llms-bitboss-ui.bitboss.it/dist/llms-medium.txt)
21
21
  — this router plus the agent contract, setup, component picker, design language
22
22
  and the full component catalogue, in ~110 KB.
23
23
 
24
+ That host is a thin proxy in front of the published npm tarball. If it is ever
25
+ unreachable, the same paths work directly against
26
+ `https://cdn.jsdelivr.net/npm/bitboss-ui@beta/…` — one hop further from us, and
27
+ pinned to the prerelease channel rather than following it.
28
+
24
29
  ---
25
30
 
26
31
  ## Mandatory order (every UI task)
@@ -231,24 +231,24 @@ a composable you want is not in this corpus's `composables/` folder — it is no
231
231
  here.** Check this list before inventing a name; if the need is genuinely absent,
232
232
  compose it or write it yourself.
233
233
 
234
- | Assumed component or composable | Reality |
235
- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
236
- | `BbColumnManager` — show/hide/reorder columns | Does not exist. Compose `BbPopover` + `BbCheckbox` and persist the ordered visible keys yourself. |
237
- | `BbKanban` / drag-and-drop board | Does not exist. There is no DnD primitive in the library at all — compose the board from `BbTable` (a table/list view of the same data) or hand-roll the drag-and-drop interaction yourself. |
238
- | `BbModal` | It is [BbDialog](../BbDialog.md). |
239
- | `BbDrawer` / `BbSheet` | It is [BbOffCanvas](../BbOffCanvas.md). |
240
- | `BbCombobox` / `BbAutocomplete` | It is [BbSelect](../BbSelect.md) / [BbSelectPopover](../BbSelectPopover.md) — search is built in, see `disable-writing`. |
241
- | `BbToggle` / `BbToggleGroup` | It is [BbButton](../BbButton.md) with `v-model` (+ `true-value` / `false-value`), which owns `aria-pressed` and the active class. |
242
- | `TagChip` / colored, read-only tag chip | It is [BbBadge](../BbBadge.md) — [BbTag](../BbTag.md) is a tags-_input_ only, not a display component. Use `BbBadge` with a registered `soft-*` variant for a fixed palette, or a one-off `--bg`/`--color` override per row for arbitrary/data-driven colors (BbBadge.md § One-off colors) — not a registered variant per distinct color. |
243
- | `BbTab` (singular) | The consumer API is [BbTabs](../BbTabs.md) / `BbTabsRoot`. `BbTab` appears only as the **v2 "before" side** of the migration diffs. |
244
- | `BbCard` | Does not exist — a card is a `<div>` with tokens. See [design-language](./design-language.md). |
245
- | `BbList` / `BbListItem` / `BbDescriptionList` | Do not exist — a list row is an `<li>` with tokens, and [BbBaseButton](../BbBaseButton.md) makes the whole row navigable. See the note under Data Display. |
246
- | `useLiveFeed` / any polling or cross-tab feed helper | Does not exist, and neither does a cross-tab helper — `useBroadcastChannelInstance` was removed (cross-tab messaging is not a UI concern). Use `useBroadcastChannel` from `@vueuse/core`; the polling and the merge are yours. |
247
- | `BbStepper` / `BbWizard` | Does not exist as a component; the wizard-form recipe composes one. |
248
- | `BbSkeleton` (standalone) | Only `BbTable` ships skeletons, via the column `skeleton` field. |
249
- | `BbCommand` / command palette | Does not exist. Compose `BbDialog` + `BbSelectPopover`. |
250
- | `BbCalendar` (month / scheduling view) | Does not exist. [BbDatePicker](../BbDatePicker.md) is a picker, not a calendar surface. |
251
- | `BbChart` / `BbGraph`, `BbCarousel`, `BbTimeline`, `BbDivider` | Do not exist. No charting, carousel or timeline primitive ships here. |
234
+ | Assumed component or composable | Reality |
235
+ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
236
+ | `BbColumnManager` — show/hide/reorder columns | Does not exist as a component. Order is `v-model:order` on `BbTable` (an array of keys any panel can write; `reorderable` adds the built-in header drag + keyboard handle); visibility is `hidden: true` on the column definition (the column stays declared and keeps its slot in the order; header slots get a `hideColumn()` that fires `hide:column`). Compose the panel from `BbPopover` + `BbCheckbox`. |
237
+ | `BbKanban` / drag-and-drop board | Does not exist. There is no reusable DnD primitive in the library (`BbTable`'s header drag is internal to the table) — compose the board from `BbTable` (a table/list view of the same data) or hand-roll the drag-and-drop interaction yourself. |
238
+ | `BbModal` | It is [BbDialog](../BbDialog.md). |
239
+ | `BbDrawer` / `BbSheet` | It is [BbOffCanvas](../BbOffCanvas.md). |
240
+ | `BbCombobox` / `BbAutocomplete` | It is [BbSelect](../BbSelect.md) / [BbSelectPopover](../BbSelectPopover.md) — search is built in, see `disable-writing`. |
241
+ | `BbToggle` / `BbToggleGroup` | It is [BbButton](../BbButton.md) with `v-model` (+ `true-value` / `false-value`), which owns `aria-pressed` and the active class. |
242
+ | `TagChip` / colored, read-only tag chip | It is [BbBadge](../BbBadge.md) — [BbTag](../BbTag.md) is a tags-_input_ only, not a display component. Use `BbBadge` with a registered `soft-*` variant for a fixed palette, or a one-off `--bg`/`--color` override per row for arbitrary/data-driven colors (BbBadge.md § One-off colors) — not a registered variant per distinct color. |
243
+ | `BbTab` (singular) | The consumer API is [BbTabs](../BbTabs.md) / `BbTabsRoot`. `BbTab` appears only as the **v2 "before" side** of the migration diffs. |
244
+ | `BbCard` | Does not exist — a card is a `<div>` with tokens. See [design-language](./design-language.md). |
245
+ | `BbList` / `BbListItem` / `BbDescriptionList` | Do not exist — a list row is an `<li>` with tokens, and [BbBaseButton](../BbBaseButton.md) makes the whole row navigable. See the note under Data Display. |
246
+ | `useLiveFeed` / any polling or cross-tab feed helper | Does not exist, and neither does a cross-tab helper — `useBroadcastChannelInstance` was removed (cross-tab messaging is not a UI concern). Use `useBroadcastChannel` from `@vueuse/core`; the polling and the merge are yours. |
247
+ | `BbStepper` / `BbWizard` | Does not exist as a component; the wizard-form recipe composes one. |
248
+ | `BbSkeleton` (standalone) | Only `BbTable` ships skeletons, via the column `skeleton` field. |
249
+ | `BbCommand` / command palette | Does not exist. Compose `BbDialog` + `BbSelectPopover`. |
250
+ | `BbCalendar` (month / scheduling view) | Does not exist. [BbDatePicker](../BbDatePicker.md) is a picker, not a calendar surface. |
251
+ | `BbChart` / `BbGraph`, `BbCarousel`, `BbTimeline`, `BbDivider` | Do not exist. No charting, carousel or timeline primitive ships here. |
252
252
 
253
253
  App chrome — an app shell, sidebar, page header, selection dock — is
254
254
  deliberately **not** a component: it is yours to own. The per-platform
@@ -53,20 +53,20 @@ naming rules, the emphasis ladder) lives in
53
53
 
54
54
  ### Surfaces & structure
55
55
 
56
- | Token | Meaning |
57
- | --------------------- | ----------------------------------------------------------------- |
58
- | `--bb-panel` | Surface/background color of panels, popovers, dialogs |
59
- | `--bb-muted` | Subtle/disabled surface (derived, neutral) |
60
- | `--bb-hover` | Hover fill for **affordances** (buttons, links, controls) |
61
- | `--bb-surface-hover` | Hover fill for **passive surfaces** (rows, cells, days) — fainter |
62
- | `--bb-pressed` | Neutral pressed/active fill |
63
- | `--bb-border` | Border color; pair with `--bb-border-w` (1px) |
64
- | `--bb-radius` | Corner radius of controls (8px) |
65
- | `--bb-radius-surface` | Corner radius of large surfaces (derived, ×1.8) |
66
- | `--bb-radius-sm` | Corner radius of small nested elements (derived) |
67
- | `--bb-shadow` | Global elevation shadow |
68
- | `--bb-panel-p` | Content padding of large surfaces (dialog, off-canvas) |
69
- | `--bb-z-overlay` | Z-index for overlays (10) |
56
+ | Token | Meaning |
57
+ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
58
+ | `--bb-panel` | Surface/background color of panels, popovers, dialogs |
59
+ | `--bb-muted` | Subtle/disabled surface (derived, neutral) |
60
+ | `--bb-hover` | Hover fill for **affordances** (buttons, links, controls) |
61
+ | `--bb-surface-hover` | Hover fill for **passive surfaces** (rows, cells, days) — fainter |
62
+ | `--bb-pressed` | Neutral pressed/active fill |
63
+ | `--bb-border` | Border color; pair with `--bb-border-w` (1px) |
64
+ | `--bb-radius` | Corner radius of controls (8px) |
65
+ | `--bb-radius-surface` | Corner radius of large surfaces (derived, ×1.8) |
66
+ | `--bb-radius-sm` | Corner radius of small nested elements (derived) |
67
+ | `--bb-shadow` | Global elevation shadow |
68
+ | `--bb-panel-p` | Content padding of large surfaces (dialog, off-canvas); axis split via the locals `--px`/`--py` on `.bb-dialog` / `.bb-offcanvas` |
69
+ | `--bb-z-overlay` | Z-index for overlays (10) |
70
70
 
71
71
  ### Color semantics
72
72
 
@@ -190,11 +190,11 @@ multipliers — never literals.
190
190
 
191
191
  ### Scale
192
192
 
193
- | Token | Default | Notes |
194
- | ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
195
- | `--bb-control-h` | `32px` | Master control height. Inputs are exactly this; buttons/tabs derive their size scale from it via `calc()` offsets |
196
- | `--bb-fs` | `14px` | Master font size. Component font sizes derive via `calc()` offsets |
197
- | `--bb-panel-p` | `16px` | Content padding of large surfaces (dialog, off-canvas; header/footer paddings derive from it) |
193
+ | Token | Default | Notes |
194
+ | ---------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
195
+ | `--bb-control-h` | `32px` | Master control height. Inputs are exactly this; buttons/tabs derive their size scale from it via `calc()` offsets |
196
+ | `--bb-fs` | `14px` | Master font size. Component font sizes derive via `calc()` offsets |
197
+ | `--bb-panel-p` | `16px` | Content padding of large surfaces (dialog, off-canvas; header/footer paddings derive from it). Axis split via the component locals `--px`/`--py` on `.bb-dialog` / `.bb-offcanvas`, each branching off `var(--bb-panel-p)`; set the pair (on the component's class) only when the axes differ |
198
198
 
199
199
  ### Motion
200
200
 
@@ -272,10 +272,13 @@ Rules:
272
272
  component seals itself.
273
273
  3. **Short names are for self-consumption only.** `--h`, `--px`, `--gap`,
274
274
  `--fs`, `--r` are fine while the rules using them target the component's
275
- own boxes. If a value must be read _inside a nested foreign component_
276
- (e.g. dialog padding positioning the close button, which is itself a
277
- button defining `--px`), the token gets a distinctive name (`--dialog-px`)
278
- or better the formula moves to an element the component owns.
275
+ own boxes. If a value must be read _inside a nested foreign component_,
276
+ prefer moving the formula to an element the component owns, or a
277
+ distinctive name. One ruled exception (2026-08-25): the dialog/off-canvas
278
+ padding pair `--px`/`--py` is read by the nested close button's inset
279
+ formula — safe because `BbCloseButton` declares neither, a constraint that
280
+ component must keep (minting `--px`/`--py` there would silently mask the
281
+ surface's value and break the inset).
279
282
  4. **Mint only what varies.** A size variant that overrides four locals is
280
283
  four tokens, not four × six sizes. Per-size lookup tables
281
284
  (`--h-xs … --h-2xl`) are allowed only when a responsive matrix genuinely
@@ -443,19 +446,22 @@ every derivation that mixes it. It is also the trap. Write
443
446
  } /* wrong: not a <percentage> */
444
447
  ```
445
448
 
446
- and nothing errors — not the build, not the console. The computed value is
447
- just `25%`, and every ring paints 1.67× stronger than the `15%` you asked for
448
- (opacity is the ring's strength; its thickness is `--bb-ring-size`).
449
+ and nothing errors — not the build, not the console. The declaration is
450
+ discarded and the token lands on the registered `initial-value: 15%` which
451
+ happens to be the very value this override asked for, so a light page looks
452
+ right by accident. Write `0.4` on a dark page instead and the ring quietly
453
+ drops from the shipped `40%` to `15%` (opacity is the ring's strength; its
454
+ thickness is `--bb-ring-size`).
449
455
  Percentages need the `%`; colors must be a `<color>` (`transparent` and
450
456
  `currentColor` qualify, `none` and a mistyped hex do not). Nothing in the
451
457
  toolchain catches it either: `bitboss-ui check` reads `.vue`/`.md`, never
452
458
  stylesheets.
453
459
 
454
460
  Fail-soft is only soft when the initial value is close to the real one. Every
455
- color knob is registered at its light default, so a rejected color override
456
- renders the library's own light theme. `--bb-ring-opacity` is registered at
457
- `25%`, which matches neither shipped scope (light `15%`, dark `40%`), so a
458
- rejected value there is the one that shows.
461
+ registered knob — `--bb-ring-opacity` included — is registered at its light
462
+ default, so a rejected override renders the library's own light theme. On a
463
+ dark page that is still visible: a rejected `--bb-ring-opacity` lands on the
464
+ light `15%` against the shipped dark `40%`.
459
465
 
460
466
  Typed knobs are also **animatable**. Add `.theme-animated`
461
467
  (main.css) to the element that carries the scheme class or theme overrides:
@@ -609,9 +615,10 @@ escape the host dialog's `overflow: hidden` and centering transform.
609
615
  | `--bb-overlay-color` + `--bb-overlay-opacity` | `--bb-overlay` (one color with alpha) |
610
616
  | `--bb-overlay-z-index` | `--bb-z-overlay` |
611
617
  | inline ring `color-mix()` formulas | `--bb-ring` / `--bb-ring-danger` (strength knob: `--bb-ring-opacity`) |
612
- | `--bb-dialog-px/pt/pb/gap/…` | `--bb-panel-p` (+ local derivations) |
618
+ | `--bb-dialog-px/pt/pb/gap/…` | `--bb-panel-p` + the local axis pair `--px`/`--py` on the surface roots |
613
619
  | `--bb-button-*`, `--bb-tabs-*`, `--bb-checkbox-*`, `--bb-radio-*`, `--bb-switch-*`, `--bb-rating-*`, `--bb-slider-*`, `--bb-table-cell-h`, `--bb-progress-track` | unprefixed locals in each component's CSS |
614
- | `--bb-table-offset-*`, `--bb-table-fill`, `--bb-table-natural-width` (JS plumbing) | unprefixed locals on `.bb-table` (`--offset-*`, `--fill`, `--natural-width`) |
620
+ | `--bb-table-offset-*` (JS plumbing) | unprefixed locals on `.bb-table` (`--offset-*`) |
621
+ | `--bb-table-fill`, `--bb-table-natural-width` | **removed** with the grid substrate — nothing publishes them any more (v3.0) |
615
622
  | `--bb-table-{id}-track-{key}` (parent→nested width bridge) | `--table-{id}-track-{key}` (distinctive cross-component name, rule 3) |
616
623
  | `--bb-select-option-*`, `--bb-primary-base`, all `--x-light`/`--x-dark` shadows | deleted (dead) |
617
624
 
@@ -58,7 +58,7 @@ The corollary: **`prefill` cannot tell you an initial load from a dependency ref
58
58
 
59
59
  ### The `prefill` prop (`BbSelect` / `BbSelectPopover`)
60
60
 
61
- `prefill` controls **when** the initial load happens: `'interaction'` (default) waits for the first user interaction, `true` loads on mount (SSR-friendly — it also runs in `onServerPrefetch`), `false` is **search-first** — nothing loads until the user types, so opening the panel fetches nothing and the list shows a "search to begin" hint until the first query. Groups and tables always load on mount.
61
+ `prefill` controls **when** the initial load happens: `'interaction'` (default) waits for the first user interaction, `true` loads on mount (SSR-friendly — under `bitboss-ui/nuxt` it also runs in `onServerPrefetch` and the result is transferred to the client; see [SSR prefill](./ssr-prefill.md)), `false` is **search-first** — nothing loads until the user types, so opening the panel fetches nothing and the list shows a "search to begin" hint until the first query. Groups and tables always load on mount.
62
62
 
63
63
  Reach for `false` when the result set is too large or expensive to browse and the query is the only sensible entry point. Note that `false` and `'interaction'` differ **only** on this point: both skip the mount load, but `'interaction'` fetches on open and `false` waits for a query.
64
64
 
@@ -36,9 +36,13 @@ The `bitbossUi` Vite plugin (`iconDir` option) — or the Nuxt module (config ke
36
36
  `lucide:<name>` available; removing it makes them all errors. Nothing to
37
37
  configure.
38
38
  - **Dev**: all icons of installed sets are registered. Referencing an
39
- uninstalled prefix or a non-existent name fails loudly with an actionable
40
- message (`"lucide:fo" requires "@iconify-json/lucide" run: npm install -D …`
41
- or `icon "x" does not exist in the lucide icon set`).
39
+ uninstalled prefix or a non-existent name fails loudly in the Vite error
40
+ overlay with an actionable message. A typo inside an installed set reads
41
+ "does not exist in the lucide icon set — did you mean `lucide:…`?"; a set
42
+ that is not installed reads "no installed icon set has the prefix `mdi`
43
+ (installed sets: lucide) … run: `npm install -D @iconify-json/mdi`". Read
44
+ the message: a typo wants a different name, a missing set wants an install,
45
+ never a guess.
42
46
  - **Build**: source files (`.vue`/`.ts`/`.js`/`.tsx`/`.jsx`; tests and stories
43
47
  excluded) are scanned for static `provider:name` literals; each referenced
44
48
  icon is emitted as its own lazy chunk. This is why rule 4 exists — and why an
@@ -235,8 +239,10 @@ markup) yourself:
235
239
  - Decorative icon next to visible text (affixes, button prepend/append,
236
240
  dropdown items): no label — the text already announces it; a label would
237
241
  duplicate.
238
- - Meaningful standalone icon: give `BbIcon` a `label` — it adds `role="img"`,
239
- `aria-label`, and a `title`.
242
+ - Meaningful standalone icon: give `BbIcon` a `label` — it adds `role="img"`
243
+ and `aria-label`. Deliberately **no `title`**: that renders a native browser
244
+ tooltip, which double-tooltips any icon also carrying `v-bb-tooltip` (owner
245
+ ruling 2026-07-30, `BbIcon.vue:200`). For a visible tip, add `v-bb-tooltip`.
240
246
  - Icon-only `BbButton` (the `icon` prop): supply the accessible name through the
241
247
  label (default slot, or `text`) — it renders `sr-only` but is still announced.
242
248
  `aria-label` is only an override; the one hard rule is that the button must
@@ -31,19 +31,16 @@ goes stable, so never reach for it here.
31
31
 
32
32
  Peer dependency: `vue ^3.5.12` — the only required one. `@inertiajs/vue3` is an **optional** peer, needed only in Inertia apps.
33
33
 
34
- `@iconify/collections` is an **optional** peer too, and npm never installs
35
- optional peers automatically install it yourself if you want the dev-time
36
- provider-icon diagnostics:
37
-
38
- ```bash
39
- npm install -D @iconify/collections
40
- ```
41
-
42
- Without it the plugin has no list of valid Iconify prefixes, so the dev-overlay
43
- errors below (the "install `@iconify-json/<prefix>`" hint and the "did you
44
- mean …?" suggestion for a mistyped icon name) never fire — a wrong provider
45
- icon then surfaces only as `BbIcon`'s generic runtime `Icon "…" does not exist.`
46
- Nothing else changes: icons that resolve still render, in dev and in production.
34
+ You do **not** need `@iconify/collections`. It is declared as an optional peer
35
+ for one reason only: when it happens to be installed, the dev-overlay message
36
+ for an unknown icon prefix can say for certain whether that prefix is a real
37
+ Iconify set ("requires `@iconify-json/mdi`, run …") or not ("neither an
38
+ installed set nor a known Iconify prefix"). Without it the same overlay fires
39
+ with a hedged wording ("no installed icon set has the prefix `mdi`; if it is an
40
+ Iconify set, run …"). A mistyped name inside a set you **have** installed
41
+ (`lucide:eye-misspelled`) is diagnosed from the set's own data in both cases,
42
+ with a "did you mean …?" suggestion. Nothing else changes: icons that resolve
43
+ still render, in dev and in production.
47
44
 
48
45
  **Known-good toolchain:** TypeScript **5.x or 6.x** if your build gate runs
49
46
  `vue-tsc`. Both type-check cleanly against the shipped `.d.ts`; the library
@@ -150,6 +147,45 @@ export default defineNuxtConfig({
150
147
 
151
148
  All options below go under the `bitboss` config key. `nuxtLinkName` controls which globally registered component renders router links (default `'NuxtLink'`).
152
149
 
150
+ This module supersedes the standalone `@bitboss-dev/bitboss-ui-nuxt` package, which was the v2 Nuxt integration — uninstall it (see [Migration v2 → v3](./migration/v2-to-v3.md)).
151
+
152
+ ### `autoImport?: boolean | { components?: boolean; composables?: boolean; validated?: boolean }` (default: `false`, Nuxt only)
153
+
154
+ Registers the library's components and composables with Nuxt's auto-import system, so templates write `<BbButton>` and `useToast()` with no import line:
155
+
156
+ ```ts
157
+ // nuxt.config.ts
158
+ export default defineNuxtConfig({
159
+ modules: ['bitboss-ui/nuxt'],
160
+ bitboss: {
161
+ iconDir: './assets/icons',
162
+ autoImport: true,
163
+ },
164
+ });
165
+ ```
166
+
167
+ `true` means `{ components: true, composables: true }`. Pass the object form to
168
+ narrow it, or to add `validated: true` — which resolves the form controls from
169
+ [`bitboss-ui/validated`](./validated-forms.md) instead of `bitboss-ui`, so
170
+ `<BbTextInput>` is the vee-validate-bound wrapper and takes `rules`, and adds
171
+ `BbForm`, `BbAsterisk`, `useBbFormContext` and `useValidatedField`. It needs the
172
+ `vee-validate` peer installed.
173
+
174
+ **It is off by default on purpose, and leaving it off is the better setup.**
175
+ Explicit imports are what make `vueCompilerOptions.checkUnknownComponents` (see
176
+ section 9) able to fail the build on a mistyped or unimported `Bb*` tag; with
177
+ auto-imports on, every `Bb*` tag resolves and that gate goes quiet. Reach for it
178
+ when you are moving an app off `@bitboss-dev/bitboss-ui-nuxt`, whose templates
179
+ were written against auto-imported components, and adding the imports is a
180
+ separate commit from the upgrade.
181
+
182
+ Two things it deliberately does not do. It never overrides your own components:
183
+ a `~/components/BbButton.vue` in the app keeps winning, and the library only
184
+ fills names the app has not claimed. And it never registers the library's
185
+ `useId` — Nuxt already auto-imports Vue's, and shadowing it would silently
186
+ redirect every existing `useId()` call in the app; import that one explicitly if
187
+ you want it.
188
+
153
189
  ## 4) Inertia
154
190
 
155
191
  Inertia apps are Vite apps: configure `bitboss-ui/vite` exactly as in section 2, install `@inertiajs/vue3`, then install the runtime plugin in `createInertiaApp`:
@@ -269,7 +305,7 @@ utilities. (Same trap as the scoped-`<style>` case above, one level up.)
269
305
  ## 6) Icons
270
306
 
271
307
  - `iconDir` (required) is scanned recursively for `.svg` files; each file becomes `local:<basename>`.
272
- - Provider icons (`lucide:pencil`, `mdi:home`, …) require the matching `@iconify-json/<prefix>` package installed in the consumer app. Missing packages/icons produce actionable dev-overlay errors **only when the optional `@iconify/collections` peer is installed** (see [Install](#1-install)); otherwise you get `BbIcon`'s generic runtime error instead. Production builds report neither this is a dev-time aid.
308
+ - Provider icons (`lucide:pencil`, `mdi:home`, …) require the matching `@iconify-json/<prefix>` package installed in the consumer app. In dev, every `prefix:name` the registry does not know produces a Vite error overlay with the fix: a mistyped name inside an installed set gets a "did you mean …?" hint, and an uninstalled prefix gets the list of installed sets plus the `npm install -D @iconify-json/<prefix>` command (the optional `@iconify/collections` peer only sharpens that wording, see [Install](#1-install)). A missing `local:` icon is a missing file in `iconDir` and surfaces as `BbIcon`'s runtime error naming it. Production builds report none of this the scan simply drops what does not resolve, so a wrong name fails at runtime there.
273
309
  - Production builds bundle **only statically referenced** provider icons — write icon names as literal strings (`icon="lucide:trash-2"`), never assemble them dynamically.
274
310
  - The plugin also writes `node_modules/.bitboss-ui/local-icons.json` and (in dev, unless `vscodeSettings: false`) wires `.vscode/settings.json` so the Iconify editor extension previews local icons.
275
311
 
@@ -363,11 +399,12 @@ bitbossUi({
363
399
 
364
400
  This is a **single global default baked in at build time** (it comes from the
365
401
  Vite plugin config), so it is the same for every request — it is _not_ a
366
- per-request value. There is no per-request/per-visitor override today: the
367
- viewport signal is a process-wide singleton, so a mobile layout that must be
368
- correct on the server's first paint (e.g. a modal already open on load) needs a
369
- client adjustment after hydration, or a fixed `ssrViewportWidth` matching your
370
- audience.
402
+ per-request value. There is no per-request/per-visitor override: the viewport
403
+ signal is a process-wide singleton, so a mobile layout that must be correct on
404
+ the server's first paint (e.g. a modal already open on load) needs a client
405
+ adjustment after hydration, or a fixed `ssrViewportWidth` matching your
406
+ audience. (Unlike `locale`, which **is** per-request — see below. A width
407
+ cannot be derived from a request without UA sniffing; a locale can.)
371
408
 
372
409
  ### `defaultInputLabelMode?: 'outside' | 'floating' | 'inside'` (default: `'outside'`)
373
410
 
@@ -385,9 +422,32 @@ labels, screen-reader announcements, confirm buttons, …). The library ships
385
422
  pl, tr, ru, uk, cs, ro, hu, el, sv, da, nb, fi, ja, ko, zh-cn — but shipping ≠
386
423
  bundling: only the **enabled** locales enter your build (next option). Runtime
387
424
  switching: `useBbConfig().setConfig({ locale })` — to a locale you enabled.
388
- `setConfig` is client-only: on an SSR server the config is a process-wide
389
- singleton (same rule as `ssrViewportWidth` no per-request override), so a
390
- per-request call would leak one visitor's locale into other renders.
425
+
426
+ **Per-request locale under SSR** is supported as of 3.0.0-beta.15: the config
427
+ is held per Vue app, and SSR builds one app per request, so pass it where you
428
+ create the app — `app.use(bitbossUiPlugin, { locale: localeFor(request) })`.
429
+ That is correct on the server's first paint, which is what crawlers index and
430
+ what a JS-disabled reader keeps.
431
+
432
+ **In Nuxt, do not call `app.use`** — the module registers the runtime plugin,
433
+ which provides the per-app config itself (fixed in 3.0.0-beta.19, Q20.4;
434
+ before that Nuxt had no per-app config at all and every `setConfig` wrote the
435
+ process-global). Set a per-request locale from your own Nuxt plugin, which
436
+ runs per request on the server:
437
+ `nuxtApp.vueApp.runWithContext(() => useBbConfig().setConfig({ locale }))` —
438
+ the `runWithContext` is what hands the write this app's injection context,
439
+ since a plugin has an app but no component instance.
440
+
441
+ `setConfig` still works for runtime switching; during a server render call it
442
+ from a component's `setup` (or inside `runWithContext`), where it can resolve
443
+ the current app. With neither there is no app to address, the write lands on
444
+ the build-time defaults, and it leaks between concurrent visitors — it warns in
445
+ dev when it sees that, keyed off where the write actually landed rather than
446
+ the call site. See [useBbConfig](../composables/useBbConfig.md).
447
+
448
+ Note this is a **different rule** from `ssrViewportWidth` above, which really
449
+ is a build-time global: a width cannot be known per request without sniffing,
450
+ a locale can.
391
451
 
392
452
  ### `enabledLocales?: BuiltinLocaleKey[]` (default: your `locale` + `'en'`)
393
453
 
@@ -506,7 +566,7 @@ template emits are already styled by the public `bitboss-ui/styles.css`.
506
566
 
507
567
  Add `--mcp` to also register a live MCP server (`npx bitboss-ui@<installed version> mcp`, pinned so npx can never fetch a different version from the registry) the harness launches on demand — it merges the entry (never overwriting other servers) into `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), `.vscode/mcp.json` (VS Code / Copilot), and `~/.codeium/windsurf/mcp_config.json` (Windsurf). **Windsurf's config is global** — it has no per-project scope, so registering it affects every project on the machine; that is why only the explicit `ai-init --mcp` command writes it, while the plugin's `mcp: true` dev-server flag (§7) auto-registers the project-scoped harnesses only. Install the server's optional peers first — `npm i -D @modelcontextprotocol/sdk zod` — they are not dependencies of the library (~12 MB used only by the MCP server); the command warns if they are absent. **`--mcp` is optional and skipping it loses you nothing but the transport** — the server only reads the `dist/ai/` files listed above, so run plain `ai-init` and let the agent read that directory if you cannot add the peers (see `mcp?: boolean` in §7).
508
568
 
509
- For a human-in-the-loop (and agent) safety net, add the `bitboss-ui/eslint-plugin` flat-config plugin (`...bitbossUi.configs.recommended`) so unknown/removed `Bb*` props surface as ESLint errors in the editor and CI — the same manifest checks as `bitboss-ui check`, reusing your `eslint-plugin-vue` parser. Real HTML attributes fall through untouched; escape hatches are the standard `<!-- eslint-disable-next-line bitboss-ui/no-unknown-attributes -->` and the rule's `allowAttributes` / `allowComponents` options. **`eslint --fix` also auto-migrates deprecated v2 props** (renames, boolean-polarity inversions like `allowWriting`→`disableWriting`, value remaps like BbToast `placement`→`position`, and deletion of inert removed props); structural migrations that need a slot/directive/CSS are reported but left by hand. **This library is TS-first (recipes ship `<script setup lang="ts">`, some with `generic="T"`), so wire `@typescript-eslint/parser` for both `.ts` and `.vue` files** — without it `vue-eslint-parser` throws a `Parsing error` on those files, which means no rule (including `no-unknown-attributes`) runs on them at all. See the README "ESLint plugin" section for the full config snippet (both parser blocks + the `npm i -D @typescript-eslint/parser` line) and the fix table. `recommended` also enables `bitboss-ui/no-active-class-on-root-link`: `active-class` on a link-capable `Bb*` component (`BbButton`/`BbBaseButton`/`BbBadgeButton`) matches by path PREFIX, so a link whose target is the literal root (`href="/"` / `to="/"`) reads as "active" on every URL — the rule flags that combination and points you at `exact-active-class` instead.
569
+ For a human-in-the-loop (and agent) safety net, add the `bitboss-ui/eslint-plugin` flat-config plugin (`...bitbossUi.configs.recommended`) so unknown/removed `Bb*` props surface as ESLint errors in the editor and CI — the same manifest checks as `bitboss-ui check`, reusing your `eslint-plugin-vue` parser. Real HTML attributes fall through untouched; escape hatches are the standard `<!-- eslint-disable-next-line bitboss-ui/no-unknown-attributes -->` and the rule's `allowAttributes` / `allowComponents` options. **`eslint --fix` also auto-migrates deprecated v2 props** (renames, boolean-polarity inversions like `allowWriting`→`disableWriting`, value remaps like BbToast `placement`→`position`, and deletion of inert removed props); structural migrations that need a slot/directive/CSS are reported but left by hand. One deliberate boundary: the rule's "did you mean `<prop>`?" hints for a mistyped/unknown attribute are advisory message text, not fixes — `eslint --fix` (including an unattended run in a pre-commit hook) never applies them; only the registered v2→v3 migrations above are auto-fixed. A guess applied blind across a codebase would be a silent behavior change, so acting on a hint is always a per-site decision. **This library is TS-first (recipes ship `<script setup lang="ts">`, some with `generic="T"`), so wire `@typescript-eslint/parser` for both `.ts` and `.vue` files** — without it `vue-eslint-parser` throws a `Parsing error` on those files, which means no rule (including `no-unknown-attributes`) runs on them at all. See the README "ESLint plugin" section for the full config snippet (both parser blocks + the `npm i -D @typescript-eslint/parser` line) and the fix table. `recommended` also enables `bitboss-ui/no-active-class-on-root-link`: `active-class` on a link-capable `Bb*` component (`BbButton`/`BbBaseButton`/`BbBadgeButton`) matches by path PREFIX, so a link whose target is the literal root (`href="/"` / `to="/"`) reads as "active" on every URL — the rule flags that combination and points you at `exact-active-class` instead.
510
570
 
511
571
  **The manifest ships with the package** — `dist/ai/components.json` is inside
512
572
  the tarball, and the rules resolve it relative to their own file, so a normal
@@ -516,6 +576,8 @@ nothing), the rules cannot check anything: they now **warn once** saying they
516
576
  are inactive rather than passing silently. Pass `failClosed: true` to a rule's
517
577
  options if you would rather CI stop than under-check.
518
578
 
579
+ `recommended` also enables **`bitboss-ui/no-reverse-false`**, which covers the one v2 break a rename table cannot: `reverse` on `BbCheckbox` / `BbRadio` / `BbSwitch` kept its NAME and inverted its MEANING in v3, so the v2 spelling `:reverse="false"` (control on the right) is now a no-op that renders the control on the LEFT. Nothing else catches it — it is a declared prop, correctly typed, holding its own default value — and it cannot be expressed as a rename, because a rename entry is keyed by prop name and would rewrite the legitimate v3 spellings too. The rule flags only a LITERAL `:reverse="false"` (a dynamic `:reverse="isRtl"` that evaluates false is left alone) and offers both corrections as editor suggestions; pass `{ assumeV2: true }` to promote the v2-intent rewrite to a real `--fix` for a bulk sweep, then remove it — the two readings produce opposite layouts, so it must never be on by default. See [the migration guide](../guides/migration/components/bb-checkbox.md).
580
+
519
581
  It also enables `bitboss-ui/require-partner-prop`: an opt-in prop set without its documented required partner — BbTable `keyboard-navigation` / `v-model:highlighted` without `row-class` (the shipped tint says "current row"; `row-class` says why, and is how you override it), or `loading-text` without `:loading` bound — compiles and mounts clean and just does nothing; the rule names the missing partner and quotes why.
520
582
 
521
583
  ## 9) Setup Verification Checklist
@@ -20,6 +20,7 @@ The three groups share their surface (`BbSwitchGroup` re-exports
20
20
  | `name: string` required (**BbRadioGroup** only; the other two already optional) | `name?: string` (auto-generated per group when omitted) | relaxation — the generated name is unique per group instance, so options still group and two groups never collide |
21
21
  | — | `legendMode: 'outside' \| 'inside'`, `description` | additive |
22
22
  | `BbSwitchGroup` `multiple: false` silently ignored (always array emit) | honored — emits a bare value in single-select mode | **⚠ behavioral** (bugfix: the prop was advertised but never forwarded; fixed 2026-07-18) |
23
+ | `disabled` / `selectable: false` left a **selected** option interactive | a selected option is disabled like any other | **⚠ behavioral** (bugfix, 2026-08-31 — see below) |
23
24
 
24
25
  `max` (checkbox/switch), `required` (radio), and `multiple` defaults are
25
26
  unchanged.
@@ -54,6 +55,35 @@ The `item.disabled` change is the dangerous one: nothing errors, options that
54
55
  used to render disabled simply become selectable. Grep item-building code for
55
56
  `disabled:` near these groups.
56
57
 
58
+ ## `disabled` now disables the selection too
59
+
60
+ Until 2026-08-31 a **selected** option in a `disabled` (or
61
+ `selectable: false`) group stayed interactive: it rendered without the native
62
+ `disabled` attribute, and clicking it emitted `update:modelValue` with the
63
+ option removed. So a fieldset switched off to prevent edits still let the user
64
+ clear the value it was showing.
65
+
66
+ ```vue
67
+ <!-- before: "a" was clickable, and clicking it emitted [] -->
68
+ <BbCheckboxGroup v-model="picked" disabled :items="items" legend="Plan" />
69
+ ```
70
+
71
+ The resolver short-circuited on `selected` above both checks. That escape
72
+ exists for the **`max` swap affordance** — at the cap, already-selected options
73
+ stay live so the user can trade one for another — and it now sits only above
74
+ the `max` check, where it belongs. Unchanged:
75
+
76
+ ```vue
77
+ <!-- still works: at max, selected options remain tradeable -->
78
+ <BbCheckboxGroup v-model="picked" :max="1" :items="items" legend="Plan" />
79
+ ```
80
+
81
+ **What to check when you upgrade.** If you relied on the old behaviour to let
82
+ someone _remove_ a value from an otherwise locked group, `disabled` is no
83
+ longer the prop for that — it now means what it says. Use `readonly`, which
84
+ keeps the options focusable and announced (`aria-readonly`) while blocking
85
+ every change, or leave the group enabled and gate on your own handler.
86
+
57
87
  ## DOM: the shared `bb-cr-container` block split three ways
58
88
 
59
89
  v2 rendered one prefix for all three groups — `bb-cr-container` ("checkbox /