bitboss-ui 3.0.0-beta.52 → 3.0.0-beta.56

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 (491) hide show
  1. package/README.md +36 -43
  2. package/bin/bitboss-ui-mcp.mjs +20 -11
  3. package/bin/bitboss-ui.mjs +130 -23
  4. package/dist/ai/BbAccordion.md +119 -178
  5. package/dist/ai/BbAlert.md +44 -14
  6. package/dist/ai/BbAsterisk.md +10 -8
  7. package/dist/ai/BbAvatar.md +14 -29
  8. package/dist/ai/BbBadge.md +39 -23
  9. package/dist/ai/BbBaseButton.md +45 -21
  10. package/dist/ai/BbBaseCheckboxIcon.md +4 -4
  11. package/dist/ai/BbBreadcrumbs.md +1 -1
  12. package/dist/ai/BbButton.md +60 -49
  13. package/dist/ai/BbCalendar.md +29 -13
  14. package/dist/ai/BbCheckbox.md +28 -9
  15. package/dist/ai/BbCheckboxGroup.md +19 -8
  16. package/dist/ai/BbCollapsible.md +5 -4
  17. package/dist/ai/BbColorInput.md +9 -7
  18. package/dist/ai/BbColorPalette.md +4 -3
  19. package/dist/ai/BbConfirm.md +85 -113
  20. package/dist/ai/BbConfirmPortal.md +3 -3
  21. package/dist/ai/BbDatePicker.md +34 -27
  22. package/dist/ai/BbDatePickerInput.md +20 -11
  23. package/dist/ai/BbDialog.md +594 -327
  24. package/dist/ai/BbDropdown.md +20 -8
  25. package/dist/ai/BbDropdownButton.md +3 -3
  26. package/dist/ai/BbDropzone.md +88 -44
  27. package/dist/ai/BbForm.md +63 -38
  28. package/dist/ai/BbHost.md +159 -0
  29. package/dist/ai/BbHoverCard.md +13 -13
  30. package/dist/ai/BbHoverCardPortal.md +4 -4
  31. package/dist/ai/BbIndicator.md +41 -14
  32. package/dist/ai/BbNumberInput.md +8 -6
  33. package/dist/ai/BbOffCanvas.md +225 -164
  34. package/dist/ai/BbPagination.md +5 -4
  35. package/dist/ai/BbPopover.md +28 -20
  36. package/dist/ai/BbPopoverPortal.md +4 -4
  37. package/dist/ai/BbProgress.md +3 -3
  38. package/dist/ai/BbPtScope.md +5 -5
  39. package/dist/ai/BbRadio.md +7 -5
  40. package/dist/ai/BbRadioGroup.md +24 -8
  41. package/dist/ai/BbRating.md +13 -7
  42. package/dist/ai/BbSelect.md +67 -35
  43. package/dist/ai/BbSelectPopover.md +47 -23
  44. package/dist/ai/BbSlider.md +35 -12
  45. package/dist/ai/BbSpinner.md +4 -2
  46. package/dist/ai/BbSwitch.md +9 -7
  47. package/dist/ai/BbSwitchGroup.md +14 -13
  48. package/dist/ai/BbTable.md +133 -36
  49. package/dist/ai/BbTabs.md +43 -33
  50. package/dist/ai/BbTag.md +3 -3
  51. package/dist/ai/BbTextInput.md +30 -4
  52. package/dist/ai/BbTextarea.md +15 -7
  53. package/dist/ai/BbTimePicker.md +29 -14
  54. package/dist/ai/BbTimePickerInput.md +4 -4
  55. package/dist/ai/BbToast.md +109 -205
  56. package/dist/ai/BbToastPortal.md +3 -3
  57. package/dist/ai/BbTooltip.md +15 -14
  58. package/dist/ai/BbTree.md +33 -39
  59. package/dist/ai/CommonField.md +4 -4
  60. package/dist/ai/CommonPopover.md +1 -1
  61. package/dist/ai/changelog.json +395 -40
  62. package/dist/ai/components.json +92 -71
  63. package/dist/ai/composables/useBbDialogContext.md +144 -0
  64. package/dist/ai/composables/useBbFormContext.md +7 -6
  65. package/dist/ai/composables/useBbOffCanvasContext.md +64 -0
  66. package/dist/ai/composables/useConfirm.md +25 -25
  67. package/dist/ai/composables/useMobile.md +2 -3
  68. package/dist/ai/composables/useToast.md +24 -24
  69. package/dist/ai/guides/agent-contract.md +9 -9
  70. package/dist/ai/guides/app-layout.md +4 -4
  71. package/dist/ai/guides/component-picker.md +3 -3
  72. package/dist/ai/guides/design-language.md +2 -6
  73. package/dist/ai/guides/design-tokens.md +7 -5
  74. package/dist/ai/guides/eslint-rules.md +67 -0
  75. package/dist/ai/guides/fetch-items-playbook.md +4 -0
  76. package/dist/ai/guides/inertia-helpers.md +188 -130
  77. package/dist/ai/guides/installation-and-plugin-setup.md +99 -97
  78. package/dist/ai/guides/migration/components/bb-collapsible.md +5 -5
  79. package/dist/ai/guides/migration/components/bb-dialog.md +12 -12
  80. package/dist/ai/guides/migration/components/bb-dropzone.md +8 -8
  81. package/dist/ai/guides/migration/components/bb-host.md +41 -0
  82. package/dist/ai/guides/migration/components/bb-offcanvas.md +9 -9
  83. package/dist/ai/guides/migration/components/bb-select-popover.md +2 -2
  84. package/dist/ai/guides/migration/components/bb-select.md +15 -15
  85. package/dist/ai/guides/migration/components/bb-toast.md +23 -17
  86. package/dist/ai/guides/migration/components/bb-tree.md +8 -8
  87. package/dist/ai/guides/migration/components/use-confirm.md +1 -1
  88. package/dist/ai/guides/migration/from-async-validator.md +62 -48
  89. package/dist/ai/guides/migration/v2-to-v3.md +208 -21
  90. package/dist/ai/guides/migration/v3-beta-css-classes.md +11 -0
  91. package/dist/ai/guides/migration/v3-beta-tooling.md +18 -2
  92. package/dist/ai/guides/options-items-playbook.md +13 -6
  93. package/dist/ai/guides/page-shell.md +11 -0
  94. package/dist/ai/guides/passthrough.md +24 -33
  95. package/dist/ai/guides/preset-components.md +32 -5
  96. package/dist/ai/guides/validated-forms.md +69 -35
  97. package/dist/ai/helpers/definePreset.json +26 -0
  98. package/dist/ai/helpers/definePreset.ts +234 -0
  99. package/dist/ai/helpers/inertia/manifest.json +21 -13
  100. package/dist/ai/helpers/inertia/types.ts +18 -7
  101. package/dist/ai/helpers/inertia/useConfirmOnRouteLeave.ts +13 -8
  102. package/dist/ai/helpers/inertia/usePaginatedResponseContext.ts +39 -18
  103. package/dist/ai/helpers/inertia/useQueryObject.ts +68 -33
  104. package/dist/ai/index.md +18 -13
  105. package/dist/ai/manifest/components/BbAccordion.json +6 -2
  106. package/dist/ai/manifest/components/BbAccordion.tree.json +13 -3
  107. package/dist/ai/manifest/components/BbAlert.json +4 -3
  108. package/dist/ai/manifest/components/BbAlert.tree.json +3 -3
  109. package/dist/ai/manifest/components/BbBadge.json +1 -1
  110. package/dist/ai/manifest/components/BbBaseButton.json +1 -1
  111. package/dist/ai/manifest/components/BbBaseCheckboxIcon.tree.json +4 -4
  112. package/dist/ai/manifest/components/BbBreadcrumbs.tree.json +1 -1
  113. package/dist/ai/manifest/components/BbButton.json +1 -1
  114. package/dist/ai/manifest/components/BbCalendar.json +2 -2
  115. package/dist/ai/manifest/components/BbCheckbox.json +3 -2
  116. package/dist/ai/manifest/components/BbCheckbox.tree.json +3 -2
  117. package/dist/ai/manifest/components/BbCheckboxGroup.json +3 -2
  118. package/dist/ai/manifest/components/BbCheckboxGroup.tree.json +4 -1
  119. package/dist/ai/manifest/components/BbCollapsible.json +1 -1
  120. package/dist/ai/manifest/components/BbColorInput.json +4 -3
  121. package/dist/ai/manifest/components/BbColorInput.tree.json +1 -1
  122. package/dist/ai/manifest/components/BbColorPalette.json +2 -2
  123. package/dist/ai/manifest/components/BbColorPalette.tree.json +1 -1
  124. package/dist/ai/manifest/components/BbConfirm.json +3 -4
  125. package/dist/ai/manifest/components/BbConfirm.tree.json +1 -1
  126. package/dist/ai/manifest/components/BbConfirmPortal.json +3 -3
  127. package/dist/ai/manifest/components/BbDatePicker.json +5 -5
  128. package/dist/ai/manifest/components/BbDatePicker.tree.json +1 -1
  129. package/dist/ai/manifest/components/BbDatePickerInput.json +6 -5
  130. package/dist/ai/manifest/components/BbDatePickerInput.tree.json +1 -1
  131. package/dist/ai/manifest/components/BbDialog.json +8 -7
  132. package/dist/ai/manifest/components/BbDialog.tree.json +4 -2
  133. package/dist/ai/manifest/components/BbDropdown.json +3 -3
  134. package/dist/ai/manifest/components/BbDropdown.tree.json +1 -1
  135. package/dist/ai/manifest/components/BbDropdownButton.json +2 -2
  136. package/dist/ai/manifest/components/BbDropdownButton.tree.json +1 -1
  137. package/dist/ai/manifest/components/BbDropzone.json +1 -1
  138. package/dist/ai/manifest/components/BbHost.json +14 -0
  139. package/dist/ai/manifest/components/BbHost.tree.json +9 -0
  140. package/dist/ai/manifest/components/BbHoverCard.json +1 -1
  141. package/dist/ai/manifest/components/BbHoverCardPortal.json +3 -3
  142. package/dist/ai/manifest/components/BbNumberInput.json +4 -3
  143. package/dist/ai/manifest/components/BbOffCanvas.json +8 -7
  144. package/dist/ai/manifest/components/BbOffCanvas.tree.json +3 -1
  145. package/dist/ai/manifest/components/BbPopover.json +2 -2
  146. package/dist/ai/manifest/components/BbPopover.tree.json +1 -1
  147. package/dist/ai/manifest/components/BbPopoverPortal.json +3 -3
  148. package/dist/ai/manifest/components/BbProgress.json +1 -1
  149. package/dist/ai/manifest/components/BbRadio.json +4 -3
  150. package/dist/ai/manifest/components/BbRadio.tree.json +2 -1
  151. package/dist/ai/manifest/components/BbRadioGroup.json +3 -2
  152. package/dist/ai/manifest/components/BbRadioGroup.tree.json +3 -0
  153. package/dist/ai/manifest/components/BbRating.json +3 -2
  154. package/dist/ai/manifest/components/BbRating.tree.json +2 -0
  155. package/dist/ai/manifest/components/BbSelect.json +5 -4
  156. package/dist/ai/manifest/components/BbSelect.tree.json +1 -1
  157. package/dist/ai/manifest/components/BbSelectPopover.json +3 -3
  158. package/dist/ai/manifest/components/BbSelectPopover.tree.json +1 -1
  159. package/dist/ai/manifest/components/BbSlider.json +5 -4
  160. package/dist/ai/manifest/components/BbSwitch.json +5 -4
  161. package/dist/ai/manifest/components/BbSwitch.tree.json +2 -1
  162. package/dist/ai/manifest/components/BbSwitchGroup.json +11 -10
  163. package/dist/ai/manifest/components/BbSwitchGroup.tree.json +3 -0
  164. package/dist/ai/manifest/components/BbTable.json +5 -5
  165. package/dist/ai/manifest/components/BbTable.tree.json +19 -1
  166. package/dist/ai/manifest/components/BbTabs.tree.json +1 -0
  167. package/dist/ai/manifest/components/BbTag.json +3 -2
  168. package/dist/ai/manifest/components/BbTextInput.json +4 -3
  169. package/dist/ai/manifest/components/BbTextarea.json +4 -3
  170. package/dist/ai/manifest/components/BbTimePicker.json +3 -3
  171. package/dist/ai/manifest/components/BbTimePicker.tree.json +1 -1
  172. package/dist/ai/manifest/components/BbTimePickerInput.json +5 -4
  173. package/dist/ai/manifest/components/BbTimePickerInput.tree.json +1 -1
  174. package/dist/ai/manifest/components/BbToast.json +4 -8
  175. package/dist/ai/manifest/components/BbToast.removed.json +1 -1
  176. package/dist/ai/manifest/components/BbToastPortal.json +6 -3
  177. package/dist/ai/manifest/components/BbTooltip.json +1 -1
  178. package/dist/ai/manifest/components/BbTree.json +1 -1
  179. package/dist/ai/manifest/components/CommonField.json +5 -4
  180. package/dist/ai/manifest/components/CommonField.tree.json +76 -1
  181. package/dist/ai/manifest/components/CommonPopover.json +1 -1
  182. package/dist/ai/manifest/index.json +9 -10
  183. package/dist/ai/manifest/meta.json +28 -4
  184. package/dist/ai/manifest/types.advanced.json +15 -7
  185. package/dist/ai/manifest/types.api.json +8 -8
  186. package/dist/ai/manifest/types.wrapper.json +2 -3
  187. package/dist/ai/recipes/inertia/approvals-inbox.md +175 -158
  188. package/dist/ai/recipes/inertia/inline-edit-workspace.md +13 -14
  189. package/dist/ai/recipes/inertia/onboarding.md +15 -18
  190. package/dist/ai/recipes/inertia/ownership-atlas.md +67 -30
  191. package/dist/ai/recipes/inertia/record-form.md +8 -8
  192. package/dist/ai/recipes/inertia/records-workspace.md +122 -97
  193. package/dist/ai/recipes/inertia/settings-workspace.md +89 -96
  194. package/dist/ai/recipes/inertia/upload-center.md +30 -24
  195. package/dist/ai/recipes/inertia/wizard-form.md +9 -7
  196. package/dist/ai/recipes/nuxt/approvals-inbox.md +175 -157
  197. package/dist/ai/recipes/nuxt/inline-edit-workspace.md +11 -13
  198. package/dist/ai/recipes/nuxt/onboarding.md +15 -18
  199. package/dist/ai/recipes/nuxt/ownership-atlas.md +63 -26
  200. package/dist/ai/recipes/nuxt/record-form.md +8 -9
  201. package/dist/ai/recipes/nuxt/records-workspace.md +112 -96
  202. package/dist/ai/recipes/nuxt/settings-workspace.md +91 -101
  203. package/dist/ai/recipes/nuxt/upload-center.md +25 -23
  204. package/dist/ai/recipes/nuxt/wizard-form.md +9 -7
  205. package/dist/ai/recipes/vue/approvals-inbox.md +176 -159
  206. package/dist/ai/recipes/vue/inline-edit-workspace.md +10 -12
  207. package/dist/ai/recipes/vue/onboarding.md +15 -20
  208. package/dist/ai/recipes/vue/ownership-atlas.md +63 -26
  209. package/dist/ai/recipes/vue/record-form.md +8 -9
  210. package/dist/ai/recipes/vue/records-workspace.md +112 -96
  211. package/dist/ai/recipes/vue/settings-workspace.md +91 -101
  212. package/dist/ai/recipes/vue/upload-center.md +25 -23
  213. package/dist/ai/recipes/vue/wizard-form.md +9 -9
  214. package/dist/ai/source/BbAccordion.md +79 -9
  215. package/dist/ai/source/BbAlert.md +34 -12
  216. package/dist/ai/source/BbBadge.md +3 -4
  217. package/dist/ai/source/BbBadgeButton.md +3 -4
  218. package/dist/ai/source/BbBaseButton.md +15 -2
  219. package/dist/ai/source/BbBaseCheckboxIcon.md +4 -0
  220. package/dist/ai/source/BbButton.md +8 -4
  221. package/dist/ai/source/BbCalendar.md +10 -5
  222. package/dist/ai/source/BbCheckbox.md +24 -7
  223. package/dist/ai/source/BbCheckboxGroup.md +23 -5
  224. package/dist/ai/source/BbCollapsible.md +6 -7
  225. package/dist/ai/source/BbColorInput.md +6 -5
  226. package/dist/ai/source/BbColorPalette.md +3 -2
  227. package/dist/ai/source/BbConfirm.md +16 -28
  228. package/dist/ai/source/BbConfirmPortal.md +7 -14
  229. package/dist/ai/source/BbDatePicker.md +70 -3
  230. package/dist/ai/source/BbDatePickerInput.md +16 -15
  231. package/dist/ai/source/BbDialog.md +188 -36
  232. package/dist/ai/source/BbDropdown.md +10 -8
  233. package/dist/ai/source/BbDropdownGroup.md +10 -7
  234. package/dist/ai/source/BbDropzone.md +26 -9
  235. package/dist/ai/source/BbForm.md +7 -1
  236. package/dist/ai/source/BbHost.md +97 -0
  237. package/dist/ai/source/BbHoverCard.md +8 -7
  238. package/dist/ai/source/BbHoverCardPortal.md +10 -9
  239. package/dist/ai/source/BbNumberInput.md +7 -6
  240. package/dist/ai/source/BbOffCanvas.md +183 -37
  241. package/dist/ai/source/BbPopover.md +8 -8
  242. package/dist/ai/source/BbPopoverPortal.md +10 -9
  243. package/dist/ai/source/BbProgress.md +1 -1
  244. package/dist/ai/source/BbRadio.md +23 -6
  245. package/dist/ai/source/BbRadioGroup.md +22 -5
  246. package/dist/ai/source/BbRating.md +19 -5
  247. package/dist/ai/source/BbSelect.md +18 -10
  248. package/dist/ai/source/BbSelectPopover.md +13 -8
  249. package/dist/ai/source/BbSlider.md +40 -7
  250. package/dist/ai/source/BbSwitch.md +20 -3
  251. package/dist/ai/source/BbSwitchGroup.md +18 -1
  252. package/dist/ai/source/BbTable.md +320 -62
  253. package/dist/ai/source/BbTabs.md +33 -3
  254. package/dist/ai/source/BbTabsList.md +16 -3
  255. package/dist/ai/source/BbTabsPanels.md +6 -0
  256. package/dist/ai/source/BbTabsRoot.md +6 -0
  257. package/dist/ai/source/BbTag.md +6 -5
  258. package/dist/ai/source/BbTextInput.md +7 -6
  259. package/dist/ai/source/BbTextarea.md +7 -6
  260. package/dist/ai/source/BbTimePicker.md +27 -3
  261. package/dist/ai/source/BbTimePickerInput.md +11 -19
  262. package/dist/ai/source/BbToast.md +58 -27
  263. package/dist/ai/source/BbToastPortal.md +25 -14
  264. package/dist/ai/source/BbTooltip.md +3 -2
  265. package/dist/ai/source/BbTree.md +21 -12
  266. package/dist/ai/source/CommonField.md +393 -45
  267. package/dist/ai/source/CommonPopover.md +15 -8
  268. package/dist/components/BbAccordion/BbAccordion.vue_vue_type_script_setup_true_lang.js +47 -33
  269. package/dist/components/BbAccordion/types.d.ts +21 -6
  270. package/dist/components/BbAccordion/types.js +2 -0
  271. package/dist/components/BbAlert/BbAlert.vue_vue_type_script_setup_true_lang.js +39 -37
  272. package/dist/components/BbAlert/types.d.ts +11 -4
  273. package/dist/components/BbBadge/types.d.ts +3 -4
  274. package/dist/components/BbBaseButton/types.d.ts +3 -2
  275. package/dist/components/BbButton/BbButton.vue_vue_type_script_setup_true_lang.js +40 -40
  276. package/dist/components/BbButton/types.d.ts +3 -2
  277. package/dist/components/BbCalendar/BbCalendar.vue_vue_type_script_setup_true_lang.js +4 -4
  278. package/dist/components/BbCalendar/types.d.ts +6 -1
  279. package/dist/components/BbCalendar/useDayjsLocale.d.ts +8 -0
  280. package/dist/components/BbCalendar/useDayjsLocale.js +14 -2
  281. package/dist/components/BbCheckbox/BbCheckbox.vue.d.ts +1 -1
  282. package/dist/components/BbCheckbox/BbCheckbox.vue_vue_type_script_setup_true_lang.js +44 -43
  283. package/dist/components/BbCheckbox/types.d.ts +6 -5
  284. package/dist/components/BbCheckboxGroup/types.d.ts +6 -5
  285. package/dist/components/BbCollapsible/BbCollapsible.vue_vue_type_script_setup_true_lang.js +1 -1
  286. package/dist/components/BbCollapsible/types.d.ts +4 -4
  287. package/dist/components/BbColorInput/types.d.ts +6 -5
  288. package/dist/components/BbColorPalette/BbColorPalette.vue_vue_type_script_setup_true_lang.js +0 -1
  289. package/dist/components/BbColorPalette/types.d.ts +3 -1
  290. package/dist/components/BbConfirm/BbConfirm.vue_vue_type_script_setup_true_lang.js +46 -48
  291. package/dist/components/BbConfirm/BbConfirmPortal.vue.d.ts +1 -1
  292. package/dist/components/BbConfirm/BbConfirmPortal.vue_vue_type_script_setup_true_lang.js +1 -1
  293. package/dist/components/BbConfirm/types.d.ts +5 -12
  294. package/dist/components/BbDatePicker/BbDatePicker.vue_vue_type_script_setup_true_lang.js +118 -103
  295. package/dist/components/BbDatePicker/types.d.ts +12 -1
  296. package/dist/components/BbDatePickerInput/BbDatePickerInput.vue_vue_type_script_setup_true_lang.js +312 -319
  297. package/dist/components/BbDatePickerInput/types.d.ts +14 -10
  298. package/dist/components/BbDialog/BbDialog.vue.d.ts +1 -0
  299. package/dist/components/BbDialog/BbDialog.vue_vue_type_script_setup_true_lang.js +193 -151
  300. package/dist/components/BbDialog/types.d.ts +59 -11
  301. package/dist/components/BbDropdown/BbDropdown.vue_vue_type_script_setup_true_lang.js +0 -1
  302. package/dist/components/BbDropdown/BbDropdownList.vue_vue_type_script_setup_true_lang.js +1 -1
  303. package/dist/components/BbDropdown/DropdownPipelineResolver.vue_vue_type_script_setup_true_lang.js +13 -13
  304. package/dist/components/BbDropdown/types.d.ts +10 -7
  305. package/dist/components/BbDropzone/BbDropzone.vue.d.ts +2 -2
  306. package/dist/components/BbDropzone/BbDropzone.vue_vue_type_script_setup_true_lang.js +142 -139
  307. package/dist/components/BbDropzone/types.d.ts +7 -2
  308. package/dist/components/BbForm/BbForm.vue_vue_type_script_setup_true_lang.js +170 -170
  309. package/dist/components/BbForm/bindFormField.d.ts +2 -3
  310. package/dist/components/BbHost/BbHost.vue.d.ts +4 -0
  311. package/dist/components/BbHost/BbHost.vue.js +5 -0
  312. package/dist/components/BbHost/BbHost.vue_vue_type_script_setup_true_lang.js +30 -0
  313. package/dist/components/BbHost/BbHostOpening.d.ts +27 -0
  314. package/dist/components/BbHost/BbHostOpening.js +43 -0
  315. package/dist/components/BbHost/types.d.ts +7 -0
  316. package/dist/components/BbHoverCard/BbHoverCardPortal.vue.d.ts +2 -2
  317. package/dist/components/BbHoverCard/types.d.ts +8 -7
  318. package/dist/components/BbNumberInput/types.d.ts +7 -6
  319. package/dist/components/BbOffCanvas/BbOffCanvas.vue.d.ts +1 -0
  320. package/dist/components/BbOffCanvas/BbOffCanvas.vue_vue_type_script_setup_true_lang.js +249 -222
  321. package/dist/components/BbOffCanvas/types.d.ts +69 -18
  322. package/dist/components/BbPopover/BbPopover.vue_vue_type_script_setup_true_lang.js +0 -1
  323. package/dist/components/BbPopover/BbPopoverPortal.vue.d.ts +2 -2
  324. package/dist/components/BbPopover/types.d.ts +8 -7
  325. package/dist/components/BbProgress/types.d.ts +1 -1
  326. package/dist/components/BbRadio/BbRadio.vue.d.ts +1 -1
  327. package/dist/components/BbRadio/BbRadio.vue_vue_type_script_setup_true_lang.js +65 -64
  328. package/dist/components/BbRadio/types.d.ts +6 -5
  329. package/dist/components/BbRadioGroup/types.d.ts +6 -5
  330. package/dist/components/BbRating/types.d.ts +6 -5
  331. package/dist/components/BbSelect/BbSelect.vue_vue_type_script_setup_true_lang.js +13 -10
  332. package/dist/components/BbSelect/types.d.ts +11 -9
  333. package/dist/components/BbSelectPopover/BbSelectPopover.vue_vue_type_script_setup_true_lang.js +7 -5
  334. package/dist/components/BbSelectPopover/types.d.ts +8 -5
  335. package/dist/components/BbSlider/BbSlider.vue_vue_type_script_setup_true_lang.js +154 -146
  336. package/dist/components/BbSlider/types.d.ts +13 -5
  337. package/dist/components/BbSwitch/BbSwitch.vue.d.ts +1 -1
  338. package/dist/components/BbSwitch/BbSwitch.vue_vue_type_script_setup_true_lang.js +83 -82
  339. package/dist/components/BbSwitch/types.d.ts +2 -1
  340. package/dist/components/BbSwitchGroup/types.d.ts +2 -1
  341. package/dist/components/BbTable/BbTable.vue_vue_type_script_setup_true_lang.js +931 -891
  342. package/dist/components/BbTable/BbTableDataRow.js +76 -78
  343. package/dist/components/BbTable/types.d.ts +26 -9
  344. package/dist/components/BbTable/useRowReorder.js +217 -195
  345. package/dist/components/BbTable/utils.d.ts +21 -0
  346. package/dist/components/BbTable/utils.js +19 -16
  347. package/dist/components/BbTable/warroom/harness.d.ts +7 -0
  348. package/dist/components/BbTabs/BbTabs.vue_vue_type_script_setup_true_lang.js +33 -30
  349. package/dist/components/BbTabs/BbTabsList.vue_vue_type_script_setup_true_lang.js +54 -50
  350. package/dist/components/BbTabs/tablistName.d.ts +4 -0
  351. package/dist/components/BbTabs/tablistName.js +13 -0
  352. package/dist/components/BbTag/types.d.ts +6 -5
  353. package/dist/components/BbTextInput/types.d.ts +7 -6
  354. package/dist/components/BbTextarea/types.d.ts +7 -6
  355. package/dist/components/BbTimePicker/BbTimePicker.vue_vue_type_script_setup_true_lang.js +90 -86
  356. package/dist/components/BbTimePicker/types.d.ts +10 -1
  357. package/dist/components/BbTimePickerInput/BbTimePickerInput.vue_vue_type_script_setup_true_lang.js +145 -151
  358. package/dist/components/BbTimePickerInput/types.d.ts +8 -7
  359. package/dist/components/BbToast/BbToast.vue_vue_type_script_setup_true_lang.js +41 -34
  360. package/dist/components/BbToast/BbToastMessage.vue_vue_type_script_setup_true_lang.js +79 -78
  361. package/dist/components/BbToast/BbToastPortal.vue.d.ts +5 -5
  362. package/dist/components/BbToast/BbToastPortal.vue_vue_type_script_setup_true_lang.js +1 -1
  363. package/dist/components/BbToast/BbToastRegion.vue.d.ts +2 -0
  364. package/dist/components/BbToast/BbToastRegion.vue_vue_type_script_setup_true_lang.js +66 -66
  365. package/dist/components/BbToast/types.d.ts +17 -8
  366. package/dist/components/BbTooltip/types.d.ts +3 -2
  367. package/dist/components/BbTree/BbTree.vue.d.ts +1 -1
  368. package/dist/components/BbTree/BbTree.vue_vue_type_script_setup_true_lang.js +1 -1
  369. package/dist/components/BbTree/types.d.ts +6 -6
  370. package/dist/components/CommonField/CommonField.vue.d.ts +2 -1
  371. package/dist/components/CommonField/CommonField.vue_vue_type_script_setup_true_lang.js +146 -99
  372. package/dist/components/CommonField/types.d.ts +18 -12
  373. package/dist/components/CommonPopover/CommonPopover.vue_vue_type_script_setup_true_lang.js +33 -30
  374. package/dist/components/CommonPopover/types.d.ts +4 -4
  375. package/dist/composables/formSubmitLock.d.ts +35 -0
  376. package/dist/composables/formSubmitLock.js +17 -2
  377. package/dist/composables/hostOpenings.d.ts +82 -0
  378. package/dist/composables/hostOpenings.js +70 -0
  379. package/dist/composables/hostRegistry.d.ts +39 -0
  380. package/dist/composables/hostRegistry.js +21 -0
  381. package/dist/composables/overlayRegistry.d.ts +160 -0
  382. package/dist/composables/overlayRegistry.js +230 -0
  383. package/dist/composables/useBaseOptions.d.ts +3 -3
  384. package/dist/composables/useBaseOptions.js +11 -11
  385. package/dist/composables/useBbDialogContext.d.ts +86 -0
  386. package/dist/composables/useBbDialogContext.js +53 -0
  387. package/dist/composables/useBbOffCanvasContext.d.ts +23 -0
  388. package/dist/composables/useBbOffCanvasContext.js +8 -0
  389. package/dist/composables/useConfig.js +4 -0
  390. package/dist/composables/useConfirm.d.ts +44 -21
  391. package/dist/composables/useConfirm.js +4 -4
  392. package/dist/composables/useItemText.d.ts +5 -0
  393. package/dist/composables/useItemText.js +14 -14
  394. package/dist/composables/useItemValue.js +9 -9
  395. package/dist/composables/useItemsGetter.js +55 -51
  396. package/dist/composables/useOnDemandOpener.d.ts +35 -0
  397. package/dist/composables/useOnDemandOpener.js +30 -0
  398. package/dist/composables/useRefusedCloseAnnouncement.d.ts +13 -0
  399. package/dist/composables/useRefusedCloseAnnouncement.js +15 -0
  400. package/dist/composables/useSegmentedFields.js +6 -1
  401. package/dist/composables/useTableWidthContext.d.ts +6 -0
  402. package/dist/composables/useTableWidthContext.js +2 -1
  403. package/dist/composables/useToast.d.ts +5 -6
  404. package/dist/composables/useToast.js +4 -3
  405. package/dist/deprecation/ai-deprecations.json.d.ts +3 -10
  406. package/dist/deprecation/ai-deprecations.json.js +1 -1
  407. package/dist/directives/bbDate.d.ts +40 -9
  408. package/dist/directives/bbDialog.d.ts +60 -0
  409. package/dist/directives/bbDialog.js +7 -0
  410. package/dist/directives/bbHoverCard.d.ts +3 -3
  411. package/dist/directives/bbHoverCard.js +1 -1
  412. package/dist/directives/bbOffCanvas.d.ts +46 -0
  413. package/dist/directives/bbOffCanvas.js +7 -0
  414. package/dist/directives/bbPopover.d.ts +3 -3
  415. package/dist/directives/bbPopover.js +1 -1
  416. package/dist/directives/bbTime.d.ts +23 -6
  417. package/dist/directives/directivePortal.d.ts +11 -11
  418. package/dist/directives/directivePortal.js +1 -1
  419. package/dist/directives/overlayTrigger.d.ts +28 -0
  420. package/dist/directives/overlayTrigger.js +93 -0
  421. package/dist/i18n/locales/cs.json +2 -1
  422. package/dist/i18n/locales/da.json +2 -1
  423. package/dist/i18n/locales/de-CH.json +2 -1
  424. package/dist/i18n/locales/de.json +2 -1
  425. package/dist/i18n/locales/el.json +2 -1
  426. package/dist/i18n/locales/en-GB.json +2 -1
  427. package/dist/i18n/locales/en.json +2 -1
  428. package/dist/i18n/locales/es-MX.json +2 -1
  429. package/dist/i18n/locales/es.json +2 -1
  430. package/dist/i18n/locales/fi.json +2 -1
  431. package/dist/i18n/locales/fr.json +2 -1
  432. package/dist/i18n/locales/hu.json +2 -1
  433. package/dist/i18n/locales/it.json +2 -1
  434. package/dist/i18n/locales/ja.json +2 -1
  435. package/dist/i18n/locales/ko.json +2 -1
  436. package/dist/i18n/locales/nb.json +2 -1
  437. package/dist/i18n/locales/nl.json +2 -1
  438. package/dist/i18n/locales/pl.json +2 -1
  439. package/dist/i18n/locales/pt-BR.json +2 -1
  440. package/dist/i18n/locales/pt-PT.json +2 -1
  441. package/dist/i18n/locales/ro.json +2 -1
  442. package/dist/i18n/locales/ru.json +2 -1
  443. package/dist/i18n/locales/sv.json +2 -1
  444. package/dist/i18n/locales/tr.json +2 -1
  445. package/dist/i18n/locales/uk.json +2 -1
  446. package/dist/i18n/locales/zh-CN.json +2 -1
  447. package/dist/i18n/locales/zh-HK.json +2 -1
  448. package/dist/i18n/locales/zh-TW.json +2 -1
  449. package/dist/icon-scan.d.ts +21 -0
  450. package/dist/icon-scan.js +29 -26
  451. package/dist/index.d.ts +13 -4
  452. package/dist/index.js +60 -57
  453. package/dist/llms-full.txt +5259 -3559
  454. package/dist/llms-medium.txt +120 -123
  455. package/dist/llms.txt +11 -7
  456. package/dist/locale-blueprint.json +2 -1
  457. package/dist/nuxt-auto-imports.js +3 -1
  458. package/dist/nuxt-module.d.ts +7 -4
  459. package/dist/nuxt.js +23 -20
  460. package/dist/plugin.js +27 -24
  461. package/dist/project-dts.d.ts +15 -2
  462. package/dist/project-dts.js +16 -10
  463. package/dist/runtime/nuxt-plugin.js +19 -17
  464. package/dist/styles.css +2 -2
  465. package/dist/types/Config.d.ts +33 -7
  466. package/dist/types/ptComponentMap.d.ts +1 -1
  467. package/dist/utilities/functions/responsiveDefault.d.ts +7 -0
  468. package/dist/utilities/functions/responsiveDefault.js +11 -0
  469. package/dist/utils/copyData.d.ts +10 -0
  470. package/dist/utils/copyData.js +29 -0
  471. package/dist/utils/cssLayers.d.ts +10 -0
  472. package/dist/utils/cssLayers.js +23 -18
  473. package/dist/utils/versionCheck.js +1 -1
  474. package/dist/vite-plugin.d.ts +29 -14
  475. package/dist/vite.js +247 -242
  476. package/llms.txt +11 -7
  477. package/package.json +2 -1
  478. package/scripts/lib/agent-manifest.mjs +22 -3
  479. package/scripts/lib/css-class-check.mjs +33 -2
  480. package/scripts/lib/define-preset-copy.mjs +123 -0
  481. package/scripts/lib/eslint-disable.mjs +3 -2
  482. package/scripts/lib/eslint-plugin.d.ts +2 -2
  483. package/scripts/lib/eslint-plugin.mjs +73 -93
  484. package/scripts/lib/hand-roll-hints.mjs +11 -2
  485. package/scripts/lib/portal-names.mjs +198 -28
  486. package/scripts/lib/project-variant-dts.mjs +53 -1
  487. package/scripts/lib/rule-registry.mjs +379 -0
  488. package/scripts/lib/swap-noun.mjs +33 -0
  489. package/scripts/lib/unimported-components.mjs +3 -1
  490. package/scripts/lib/validate-bb-markup.mjs +82 -76
  491. package/scripts/lib/required-in-form.mjs +0 -240
@@ -19,8 +19,9 @@ restyle its root), and it does not read
19
19
  label content, so the marker matches the library's styling (`--bb-danger`).
20
20
 
21
21
  Most consumers never place it by hand: the form controls
22
- render it for you in their `#label` slot when a field is `required`/has rules and
23
- `config.requiredAsterisk` is enabled. Reach for `BbAsterisk` directly only when
22
+ render it for you in their `#label` slot when a field is required (a
23
+ `required` rule or schema key inside a `BbForm`, the `required` prop outside
24
+ one), unless the app turns `requiredAsterisk` off. Reach for `BbAsterisk` directly only when
24
25
  you compose a bespoke label outside those controls.
25
26
 
26
27
  ```vue
@@ -43,9 +44,9 @@ carries mandatoriness to assistive tech is the **control itself**: the native
43
44
  `required` attribute when you set the `required` prop, and
44
45
  `aria-required="true"` when a `BbForm` makes the field mandatory (a `required`
45
46
  rule or the schema). Inside a form the browser never validates, so there the
46
- `required` prop is an error (`bitboss-ui/no-required-in-form`): it would mark
47
- the field with nothing enforcing it; write `rules="required"` or require the
48
- key in the schema.
47
+ `required` prop is a hint: it marks the field and the server does the
48
+ checking; write `rules="required"` or require the key in the schema to check
49
+ on the client too.
49
50
 
50
51
  The practical consequence: the marker is a _visual_ affordance only, and the
51
52
  control's own required state is the real thing. Never ship a field that shows
@@ -53,9 +54,10 @@ the asterisk without one of them (sighted users see a requirement that
53
54
  assistive tech cannot perceive), and never assume the asterisk is doing
54
55
  accessibility work.
55
56
 
56
- `showAsterisk` on the form controls is also gated on the plugin option, so
57
- with `requiredAsterisk: false` there is no way to render the marker through
58
- them at all — placing `BbAsterisk` by hand is then the only route.
57
+ `showAsterisk` on the form controls is also gated on the plugin option
58
+ (`true` by default), so an app that sets `requiredAsterisk: false` has no way
59
+ to render the marker through them at all — placing `BbAsterisk` by hand is then
60
+ the only route.
59
61
 
60
62
  ### Restyling with passthrough
61
63
 
@@ -156,10 +156,9 @@ too, since the dot alone is not announced.
156
156
 
157
157
  An overlapping stack summarizes a group (reviewers, assignees, attendees); the
158
158
  overflow count is just another avatar with the count in its slot. Stacking is
159
- the one place where overriding avatar internals is warranted — the example's
160
- scoped CSS pulls each avatar over the previous one with a negative margin and
161
- separates them with a panel-colored ring (an explicit override of the
162
- `.bb-avatar` root; keep it in one reusable class).
159
+ a class on each avatar: a negative inline margin pulls every avatar after the
160
+ first over the previous one, and a panel-coloured ring keeps the overlapped
161
+ edges readable (see [Restyling with passthrough](#restyling-with-passthrough)).
163
162
 
164
163
  **Reviewers stack with overflow**
165
164
 
@@ -180,11 +179,14 @@ separates them with a panel-colored ring (an explicit override of the
180
179
  </BbButton>
181
180
  </div>
182
181
 
183
- <div class="stack">
182
+ <div class="flex">
184
183
  <BbAvatar
185
- v-for="reviewer in visible"
184
+ v-for="(reviewer, index) in visible"
186
185
  :key="reviewer.name"
187
186
  :alt="reviewer.name"
187
+ :class="
188
+ index ? '-ml-3 ring-2 ring-(--bb-panel)' : 'ring-2 ring-(--bb-panel)'
189
+ "
188
190
  size="40"
189
191
  :src="reviewer.src"
190
192
  >
@@ -193,6 +195,7 @@ separates them with a panel-colored ring (an explicit override of the
193
195
  <BbAvatar
194
196
  v-if="!expanded && hiddenCount > 0"
195
197
  :alt="`${hiddenCount} more reviewers`"
198
+ class="-ml-3 ring-2 ring-(--bb-panel)"
196
199
  size="40"
197
200
  >
198
201
  +{{ hiddenCount }}
@@ -241,25 +244,6 @@ const visible = computed(() =>
241
244
  );
242
245
  const hiddenCount = computed(() => reviewers.length - maxVisible);
243
246
  </script>
244
-
245
- <style scoped>
246
- /*
247
- * Deliberate override of the avatar root: stacking needs the negative margin,
248
- * and the panel-colored ring keeps overlapped edges readable. Keep this in one
249
- * reusable class — never per-avatar inline styles.
250
- */
251
- .stack {
252
- display: flex;
253
- }
254
-
255
- .stack :deep(.bb-avatar) {
256
- box-shadow: 0 0 0 1px var(--bb-panel);
257
- }
258
-
259
- .stack :deep(.bb-avatar + .bb-avatar) {
260
- margin-inline-start: -12px;
261
- }
262
- </style>
263
247
  ```
264
248
 
265
249
  ### Team lists
@@ -584,10 +568,11 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
584
568
  exists for that.
585
569
  - Don't wrap the avatar in a raw `<span @click>` for menus — put it inside
586
570
  `BbBaseButton`/`BbDropdown` so focus and keyboard behavior come for free.
587
- - **The shape is a circle, and it is not configurable.** `border-radius: 50%`
588
- is baked in. A rounded-SQUARE avatar — common in dense tables, where a square
589
- reads as "entity" and a circle as "person" — has no answer here; build that
590
- one yourself rather than fighting the radius.
571
+ - **The frame is a circle (`border-radius: 50%`), and there is no `shape`
572
+ prop.** For a rounded-square entity avatar (dense tables), restyle the frame:
573
+ `class="rounded-(--bb-radius)"` in the layered build (`cssLayers`), or
574
+ `style="border-radius: var(--bb-radius)"` in any build. The image is clipped
575
+ by the frame, so it follows.
591
576
  - Don't pre-crop sources to circles — the component center-crops; ship square
592
577
  or larger originals.
593
578
  - Don't leave `alt` empty for meaningful avatars: fallbacks lose their
@@ -70,7 +70,8 @@ For a small, closed status set (paid / pending / overdue, plan tiers), register
70
70
  the soft palette from
71
71
  [design language guide](./guides/design-language.md) § Using color
72
72
  (`soft-gray` / `soft-blue` / `soft-green` / `soft-amber` / `soft-red`) and style
73
- `.bb-badge--<name>` in your project stylesheet. Never invent `variant="success"`
73
+ `.bb-badge--<name>` in your project stylesheet. Type a status map as
74
+ `Record<Status, BadgeVariantType>`. Never invent `variant="success"`
74
75
  — that name is not built-in and ships no CSS. The example below uses the soft
75
76
  names: in your app it type-checks only after the `badgeVariants` registration
76
77
  and renders styled only with that CSS — both are in the linked section.
@@ -350,22 +351,9 @@ swap the inputs use); and **`icon`** (icon-only) becomes a removable glyph.
350
351
  Active filters are the classic product shape: a chip row, each badge owned by
351
352
  your state, cleared one-by-one or all at once.
352
353
 
353
- **Size rule — match the pair, don't memorise a constant.** Badge scale is not
354
- button scale, so the number that looks right depends on the button standing
355
- next to it. A rail picks **one matched pair** and uses it for every chip:
356
-
357
- | Badge size | Height | Pairs with button |
358
- | -------------- | ------ | ------------------------------- |
359
- | `md` (default) | ≈16px | — (inline token, opens nothing) |
360
- | `lg` | ≈20px | `xs` |
361
- | `xl` | ≈24px | `sm` |
362
- | `2xl` | ≈28px | `md` |
363
-
364
- So a rail whose Filters trigger is a `sm` button wants `xl` chips; drop the
365
- trigger to `xs` and the chips go to `lg`. Copying `sm`/`md` from an inline
366
- example into a rail is what makes chips look toy-sized next to their own
367
- button. Reserve `sm` for dense in-table status pills, and omit `size`
368
- (default `md`) only for a plain inline token that opens nothing.
354
+ Size the chips to the button beside them — see
355
+ [Sizes § Beside a control](#beside-a-control-match-the-button): a rail with a
356
+ `sm` Filters button wants `xl` chips.
369
357
 
370
358
  **A removable filter bar**
371
359
 
@@ -449,7 +437,16 @@ const onReset = () => {
449
437
 
450
438
  A plain badge is inert. To make the badge itself clickable, slot a
451
439
  **`BbBadgeButton`** as a **direct child** — it takes over the badge's body and
452
- renders it as a real `<button>`:
440
+ renders it as a real `<button>`.
441
+
442
+ **Direct child only.** The badge decides what its body is while it renders,
443
+ by looking at the vnodes in its default slot, before any child exists — so
444
+ it sees a `BbBadgeButton` only when it is right there in the slot. Put it
445
+ inside your own component or a wrapping element, or slot a plain `<button>`,
446
+ and the badge renders its normal body around it: the label shows twice and you
447
+ get a button inside a button. Write the `<BbBadgeButton>` in the badge's slot
448
+ itself; to reuse a configured chip, wrap the whole `<BbBadge>` in your
449
+ component, never the companion alone.
453
450
 
454
451
  **A clickable pill**
455
452
 
@@ -609,6 +606,25 @@ const onPick = (option: Status) => {
609
606
  Badges follow the shared `xs → 2xl` scale (default `md`; an invalid size warns
610
607
  in dev and falls back to `md`). Keep one size per cluster.
611
608
 
609
+ #### Beside a control: match the button
610
+
611
+ Badge scale is not button scale: the size that looks right depends on the
612
+ button standing next to the badge (a filter rail, a toolbar, a chip row with
613
+ its trigger). Pick **one matched pair** and use it for every chip:
614
+
615
+ | Badge size | Height | Pairs with button |
616
+ | -------------- | ------ | ------------------------------- |
617
+ | `md` (default) | ≈16px | — (inline token, opens nothing) |
618
+ | `lg` | ≈20px | `xs` |
619
+ | `xl` | ≈24px | `sm` |
620
+ | `2xl` | ≈28px | `md` |
621
+
622
+ So a rail whose Filters trigger is a `sm` button wants `xl` chips; drop the
623
+ trigger to `xs` and the chips go to `lg`. Copying `sm`/`md` from an inline
624
+ example into a rail is what makes chips look toy-sized next to their own
625
+ button. Reserve `sm` for dense in-table status pills, and omit `size`
626
+ (default `md`) only for a plain inline token that opens nothing.
627
+
612
628
  **The size scale**
613
629
 
614
630
  ```vue
@@ -812,10 +828,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
812
828
 
813
829
  - The label lives in the **default slot** — there is no `text`/`content` prop.
814
830
  In button mode it moves to `BbBadgeButton`'s slot; don't write both.
815
- - **`BbBadgeButton` must be a direct child** of the badge's default slot.
816
- Wrapping it in another element or component is undefined behavior — the badge
817
- won't hand over its body, and you'll get a duplicated label. Outside a badge
818
- entirely, it throws.
831
+ - **`BbBadgeButton` must be a direct child** of the badge's default slot:
832
+ inside a wrapper element or your own component, the badge keeps its body —
833
+ a duplicated label and a button inside a button. Wrap the whole `BbBadge`
834
+ instead. Outside a badge entirely, it throws.
819
835
  - One `BbBadgeButton` per badge. There is only one body to take over.
820
836
  - A badge **without** the companion stays inert: no events, no `href`. Only
821
837
  `clearable` adds behavior (the clear button + `click:clear`).
@@ -863,7 +879,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
863
879
  | `loading` | `boolean \| undefined` | `false` | | Shows a spinner in place of the leftmost icon (`icon` or `prepend:icon`; the `append:icon` when it is the only one; else the leading slot), as `BbButton` does, with a hidden loading announcement. |
864
880
  | `prepend:icon` | `string \| undefined` | | | Icon rendered before the label. |
865
881
  | `size` | `'xs'` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'2xl'` | `"md"` | | Preset size of the badge. |
866
- | `variant` | `'outline'` \| `'primary'` \| `'destructive'` \| `'secondary'` \| `'none'` | `"primary"` | | Visual variant: `primary`, `secondary`, `destructive`, or `outline`. Register more via the vite plugin `badgeVariants` option and style `.bb-badge--<variant>` (set `--bg` / `--fg`). `'none'` renders no variant class — an escape hatch for a one-off look set through `--bg` / `--fg` on the element. |
882
+ | `variant` | `'outline'` \| `'primary'` \| `'destructive'` \| `'secondary'` \| `'none'` | `"primary"` | | Visual variant: `primary`, `secondary`, `destructive`, or `outline`. Status colours are a registration (vite plugin `badgeVariants`, the `soft-*` palette in design-language.md) styled as `.bb-badge--<variant>`. `'none'` renders no variant class: set `--bg` / `--fg` on the element. |
867
883
 
868
884
  ## Passthrough parts and states
869
885
 
@@ -73,21 +73,21 @@ primitive brings no look of its own):
73
73
  <div class="flex flex-wrap items-center gap-2 text-sm">
74
74
  <!-- No href/to → a native <button>. -->
75
75
  <BbBaseButton
76
- class="rounded-(--bb-radius) bg-(--bb-primary) px-3 py-1.5 text-(--bb-primary-fg)"
76
+ class="rounded-(--bb-radius) bg-(--bb-primary) px-3 py-1.5 text-(--bb-primary-fg) focus-visible:ring-2 focus-visible:ring-(--bb-ring)"
77
77
  @click="pinged = true"
78
78
  >
79
79
  Native button
80
80
  </BbBaseButton>
81
81
  <!-- Same-origin href → an <a>. -->
82
82
  <BbBaseButton
83
- class="rounded-(--bb-radius) px-3 py-1.5 text-(--bb-primary) underline"
83
+ class="rounded-(--bb-radius) px-3 py-1.5 text-(--bb-primary) underline focus-visible:ring-2 focus-visible:ring-(--bb-ring)"
84
84
  href="#docs"
85
85
  >
86
86
  Anchor link
87
87
  </BbBaseButton>
88
88
  <!-- href + target → a plain <a target="_blank"> with rel secured. -->
89
89
  <BbBaseButton
90
- class="rounded-(--bb-radius) px-3 py-1.5 underline"
90
+ class="rounded-(--bb-radius) px-3 py-1.5 underline focus-visible:ring-2 focus-visible:ring-(--bb-ring)"
91
91
  href="https://example.com"
92
92
  target="_blank"
93
93
  >
@@ -111,7 +111,25 @@ const pinged = ref(false);
111
111
 
112
112
  The only classes it applies are structural: `bb-base-button` (a focus-ring
113
113
  scaffold, `cursor` and transitions), `bb-base-button--block` and
114
- `bb-base-button--disabled`. There is **no padding, background, border, or
114
+ `bb-base-button--disabled`.
115
+
116
+ **It removes the browser's focus ring, on purpose.** It is the base every
117
+ library button, tab, row and menu item draws on, and each of those paints its
118
+ own focus; a native outline would sit on top of all of them. So a bare
119
+ `BbBaseButton` shows **no keyboard focus until you style it**. Every class you
120
+ give it needs a `:focus-visible` style too; the library's own ring is one
121
+ utility pair:
122
+
123
+ ```vue
124
+ <BbBaseButton
125
+ class="rounded-(--bb-radius) px-3 py-1.5 focus-visible:ring-2 focus-visible:ring-(--bb-ring)"
126
+ >
127
+ Save
128
+ </BbBaseButton>
129
+ ```
130
+
131
+ The ring animates in through the base's `box-shadow` transition (that is the
132
+ scaffold). There is **no padding, background, border, or
115
133
  variant appearance** — that is the whole point. It sets **no text color**, so a
116
134
  `text-*` utility on the element just works with no specificity fight; the text
117
135
  inherits from its container (in anchor mode, the browser's blue-and-underlined
@@ -123,12 +141,12 @@ the right base for a clickable card or a bespoke nav item:
123
141
 
124
142
  ```vue
125
143
  <div class="flex items-center gap-2 text-sm">
126
- <!-- Untouched: just text with the reset + focus scaffold. -->
144
+ <!-- Untouched: just text with the reset. No visible focus: style it. -->
127
145
  <BbBaseButton href="#a">Bare</BbBaseButton>
128
146
  <!-- Styled entirely by utility classes — neutral hover chrome. -->
129
147
  <BbBaseButton
130
148
  href="#b"
131
- class="rounded-(--bb-radius) border border-(--bb-border) px-3 py-1 font-medium hover:bg-(--bb-hover)"
149
+ class="rounded-(--bb-radius) border border-(--bb-border) px-3 py-1 font-medium hover:bg-(--bb-hover) focus-visible:ring-2 focus-visible:ring-(--bb-ring)"
132
150
  >
133
151
  Branded pill
134
152
  </BbBaseButton>
@@ -247,15 +265,17 @@ destination onto these props instead of an `@click` handler:
247
265
  - **`replace`** — history replacement (`router.replace` under Vue Router, a
248
266
  replace visit under Inertia).
249
267
  - **Inertia visit options** ride along with `href`: request shape (`method`,
250
- `data`, `headers`, `only`, `query-string-array-format`), history & scroll
251
- (`preserve-scroll`, `preserve-state`), and lifecycle hooks (`on-before`,
252
- `on-start`, `on-progress`, `on-success`, `on-cancel`, `on-finish`,
253
- `on-cancel-token`) — bound as props, not `@` listeners.
254
-
255
- For the full navigation catalog with per-option detail, see the
256
- [`BbButton`](./BbButton.md) guide — the surface is identical because it is this
257
- component's. `to` and Inertia links can't run without their framework, so they
258
- live in static snippets here:
268
+ `data`, `headers`, `only`, `except`, `component`,
269
+ `query-string-array-format`), history & scroll (`preserve-scroll`,
270
+ `preserve-state`, `preserve-url`, `view-transition`), prefetching
271
+ (`prefetch`, `cache-for`, `cache-tags`), and lifecycle hooks (`on-before`,
272
+ `on-start`, `on-progress`, `on-success`, `on-error` (validation errors only),
273
+ `on-cancel`, `on-finish`, `on-cancel-token`, plus `on-prefetching` /
274
+ `on-prefetched`) — bound as props, not `@` listeners.
275
+
276
+ For per-option detail, see the [`BbButton`](./BbButton.md) guide — the surface
277
+ is identical because it is this component's. `to` and Inertia links can't run
278
+ without their framework, so they live in static snippets here:
259
279
 
260
280
  ```vue
261
281
  <!-- Vue Router / Nuxt -->
@@ -403,7 +423,10 @@ When it renders as a native button you can retune the element:
403
423
  Because it defaults to `button`, a `BbBaseButton` in a form never submits by
404
424
  accident; set `type="submit"` for the one that should.
405
425
  - **`block`** — full-width layout (`bb-base-button--block`), for stacked nav
406
- items, mobile CTAs, or list rows.
426
+ items, mobile CTAs, or list rows. A block button centres its label (a plain
427
+ one stays start-aligned, so a wrapped label reads as text), and an anchor
428
+ (`href` / `to`) becomes `display: block` so the width applies; your own
429
+ display classes still win.
407
430
 
408
431
  **Submit type and block width**
409
432
 
@@ -423,7 +446,7 @@ When it renders as a native button you can retune the element:
423
446
  </p>
424
447
  <BbBaseButton
425
448
  block
426
- class="rounded-(--bb-radius) bg-(--bb-primary) px-3 py-1.5 text-sm text-(--bb-primary-fg)"
449
+ class="rounded-(--bb-radius) bg-(--bb-primary) px-3 py-1.5 text-sm text-(--bb-primary-fg) focus-visible:ring-2 focus-visible:ring-(--bb-ring)"
427
450
  type="submit"
428
451
  >
429
452
  Create workspace
@@ -492,9 +515,10 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
492
515
  link can't resolve. Use `href` for router-free contexts.
493
516
  - `tag="div"`/`tag="span"` throws away native button semantics — only do it when a
494
517
  `<button>` is genuinely invalid, and restore keyboard/focus behavior yourself.
495
- - Style the focus state: the base provides only a ring _scaffold_
496
- (`box-shadow`/`outline` transitions). Add a visible `:focus-visible` style in
497
- your class so keyboard users can see focus.
518
+ - Style the focus state: the base removes the browser's ring and provides only
519
+ a _scaffold_ (`box-shadow`/`outline` transitions), so a class without a
520
+ `:focus-visible` style ships an invisible keyboard focus. See "It removes the
521
+ browser's focus ring" above.
498
522
 
499
523
  ### Accessibility
500
524
 
@@ -518,7 +542,7 @@ A `pt` value written in `<script>` (a constant, a preset, a wrapper's
518
542
  | `activeClass` | `string \| undefined` | `'router-link-active'` | | CSS class applied when the component renders as a link and the target of the link is the current route or the url matches partially. Ported for Inertia compatibility. |
519
543
  | `ariaCurrentValue` | `"page" \| "step" \| "location" \| "date" \| "time" \| "true" \| "false" \| undefined` | `'page'` | | Value forwarded to the `aria-current` attribute when the component renders as a router link and the target route is an exact match. Use to communicate the current location to assistive technologies. |
520
544
  | `async` | `boolean \| undefined` | `false` | | Inertia: runs the visit without blocking — the page stays interactive and several async visits can be in flight at once. |
521
- | `block` | `boolean \| undefined` | `false` | | Makes the component take the full available width (block-level layout). Adds the `bb-base-button--block` modifier class. |
545
+ | `block` | `boolean \| undefined` | `false` | | Makes the component take the full available width (block-level layout) and centres its label; an anchor becomes `display: block` so the width applies. Adds the `bb-base-button--block` modifier class. |
522
546
  | `cacheFor` | `string \| number \| (string \| number)[] \| undefined` | | | Inertia: how long a prefetched response stays fresh before it is re-fetched. A single duration, or `[staleAfter, expiresAfter]`. Typed platform-agnostically (matching BbButton) so the library's types never require `@inertiajs/vue3` to be installed. |
523
547
  | `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
524
548
  | `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
@@ -286,14 +286,14 @@ Set these on the element, or on a class you put on it, to retune this component
286
286
 
287
287
  | Property | Default | What it is |
288
288
  | --- | --- | --- |
289
- | `--accent` | `var(--bb-primary)` | |
290
- | `--check-color` | `var(--bb-primary-fg)` | |
291
- | `--size` | `16px` | |
289
+ | `--accent` | `var(--bb-primary)` | Fill and border colour when checked or indeterminate. |
290
+ | `--check-color` | `var(--bb-primary-fg)` | Colour of the checkmark / dash drawn on the accent fill. |
291
+ | `--size` | `16px` | Width and height of the glyph box. |
292
292
  | `--r` | `min(4px, var(--bb-radius))` | The checkbox corner, capped by the master radius so a zero- or small-radius theme reaches it. Not `--bb-radius-sm`: that tier is 4.8px at the shipped radius and this glyph ships at 4px. |
293
293
  | `--ring-color` | `var(--bb-ring)` | The focus ring's colour, re-pointed by errors and warnings. Both ring declarations read it, so a focused glyph grows its ring in its own colour instead of tweening from a different one. |
294
294
  | `--elev` | `var(--bb-elev-sm)` | Resting lift; a no-op until a theme pins `--bb-elev`. |
295
295
  | `--bg` | `var(--bb-panel)` | The glyph plate. DECLARED here, not consumed bare, because this glyph renders inside surfaces that declare `--bg` themselves — a table row or header cell, a dialog, an off-canvas sheet. Without the declaration it would inherit that surface's fill, which happens to match at the shipped default and would diverge the moment anyone writes `.my-table { --bg: … }`. Identical to the raw tokens it replaces at every theme. |
296
- | `--border-color` | `var(--bb-border)` | |
296
+ | `--border-color` | `var(--bb-border)` | Resting border colour of the glyph; re-pointed by error and warning states. |
297
297
 
298
298
  ## See Also
299
299
 
@@ -235,7 +235,7 @@ a status mark, a dynamic icon, or a fixed trail hint — use slots:
235
235
  - `item:prepend` / `item:append` — before/after every crumb's label, inside the
236
236
  link, replacing that side's `prepend:icon` / `append:icon` (as a form
237
237
  control's `prepend` slot replaces its icon); scope is
238
- `{ item, index, text, disabled }`. Keep the content non-interactive — it is
238
+ `{ item, index, label, disabled }`. Keep the content non-interactive — it is
239
239
  inside a link — and mark decorative content `aria-hidden="true"`, or it
240
240
  becomes part of the link's accessible name.
241
241
  - `prepend` / `append` — fixed content on either end of the whole trail; scope
@@ -119,6 +119,41 @@ restate a state:
119
119
  }
120
120
  ```
121
121
 
122
+ **A colour of its own: write all five, picked for that colour.** There is no
123
+ one-colour shorthand on purpose: a yellow and a navy need opposite choices,
124
+ and no colour math serves both. Copy the shape and choose each value:
125
+
126
+ ```css
127
+ /* A light colour (yellow): dark text, and each state goes darker. */
128
+ .bb-button--upgrade {
129
+ --bg: #facc15;
130
+ --bg-hover: #eab308;
131
+ --bg-pressed: #ca8a04;
132
+ --fg: #422006;
133
+ --ring-color: #a16207;
134
+ }
135
+
136
+ /* A dark colour (navy): light text, and each state goes lighter. */
137
+ .bb-button--brand {
138
+ --bg: #1e3a8a;
139
+ --bg-hover: #1e40af;
140
+ --bg-pressed: #1d4ed8;
141
+ --fg: #ffffff;
142
+ --ring-color: #60a5fa;
143
+ }
144
+ ```
145
+
146
+ - **`--fg`** is the text: dark on a light `--bg`, light on a dark one. Check
147
+ it reads at 4.5:1 against `--bg` and both state fills.
148
+ - **`--bg-hover` / `--bg-pressed`** move away from the rest colour, pressed
149
+ the furthest, so each state is visibly different: darker steps on a light
150
+ colour, lighter steps on a dark one.
151
+ - **`--ring-color`** must show against the page around the button, not just
152
+ against the button.
153
+
154
+ Which colours earn a variant at all, and what they should mean, is in
155
+ [design-language § Using color](./guides/design-language.md#using-color).
156
+
122
157
  The primary's hover is one 1.25:1 luminance step away from the panel
123
158
  (darker in light, lighter in dark), turning toward the panel only when the
124
159
  primary has no room left, as the default black in light and white in dark
@@ -371,47 +406,18 @@ detected by the model being defined, **seed the model** (`ref(false)`, not an
371
406
  undefined `state.*`) — an undefined model is not a toggle yet and the first
372
407
  click won't set it.
373
408
 
374
- For an exclusive set, share one `v-model` across the buttons and give each its
375
- own `true-value`. The `false-value` decides the selection policy:
376
-
377
- - `:false-value="null"` — optional: clicking the active button clears the
378
- selection.
379
- - `false-value` **mirroring that same button's own `true-value`** — mandatory:
380
- re-clicking the active button re-emits the same value, so one choice is
381
- always selected.
382
-
383
- **Point every button's `false-value` at its own `true-value`, never at a
384
- sibling's.** Each button independently answers "what do I emit when I'm
385
- clicked while I'm not the active one?" — under the mandatory policy the
386
- answer is always "myself," never "whichever value the other button owns." Get
387
- this backwards and the control inverts silently: the button that is
388
- _currently pressed_ is the one whose click now emits the _other_ button's
389
- value, so clicking the visibly-active segment switches away from it instead
390
- of re-confirming it. Nothing catches this — both strings are legal
391
- `false-value`s, so it passes `vue-tsc`, lint, and `bitboss-ui check`, and it
392
- only shows up when someone clicks the segment that's already selected. A
393
- two-button segmented toggle, written out explicitly rather than looped, is
394
- the shape that trips this up most:
395
-
396
- ```vue
397
- <!-- Mandatory exclusive set — each button's false-value mirrors ITS OWN
398
- true-value. Board's false-value is "board", not "table"; Table's is
399
- "table", not "board". Swapping them makes the pressed segment toggle
400
- away to its sibling instead of staying selected. -->
401
- <BbButton v-model="view" group true-value="board" false-value="board">
402
- Board
403
- </BbButton>
404
- <BbButton v-model="view" group true-value="table" false-value="table">
405
- Table
406
- </BbButton>
407
- ```
409
+ **Exactly one active, always?** That is a radio group, not a set of toggles:
410
+ reach for **`BbRadioGroup`** — a [segmented control](./BbRadioGroup.md#segmented-control)
411
+ or selection tiles, with arrow keys and "2 of 4" for free — or **`BbTabs`**
412
+ (`pill`, the default variant) when the choice switches a view. Neither needs
413
+ a `false-value`.
408
414
 
409
- A `v-for` over an options array gets this correct for free —
410
- `:true-value="option.value"` and `:false-value="option.value"` both read the
411
- _same_ loop item, so every rendered button automatically mirrors itself (the
412
- live example below uses this shape). The mistake above only becomes possible
413
- once that loop is unrolled into separate elements with their own literal
414
- strings.
415
+ Toggles that share one `v-model` fit an **optional** choice: give each button
416
+ its own `true-value` and `:false-value="null"`, so clicking the active one
417
+ clears the selection. If you do hand-roll a mandatory set, each button's
418
+ `false-value` must mirror **its own** `true-value` (`true-value="board"
419
+ false-value="board"`), never a sibling's — swapped, the pressed segment
420
+ switches away when clicked, and nothing catches it.
415
421
 
416
422
  Add `group` to fuse adjacent buttons into one visual segment control (shared
417
423
  borders and radius between siblings). Each button keeps its own semantics: a
@@ -423,7 +429,7 @@ the first / last, and Space / Enter toggle. Disabled and loading buttons are
423
429
  skipped. Any other element between two buttons splits them into two sets, and
424
430
  `group` buttons without a `v-model` keep one Tab stop each.
425
431
 
426
- **Exclusive toggle groups**
432
+ **An optional filter (false-value null) and a mirrored view set**
427
433
 
428
434
  ```vue
429
435
  <template>
@@ -635,8 +641,13 @@ Escape hatches, when the default isn't right:
635
641
  a parent-owned request). While loading, the button exposes
636
642
  `aria-disabled="true"` and leaves the tab order; it is not natively
637
643
  `disabled`.
638
- - `disable-auto-loading` — opts out of promise tracking entirely (e.g. the
639
- handler opens a dialog and you don't want a spinner flash).
644
+ - `disable-auto-loading` — opts out of every spinner the button starts on its
645
+ own: promise tracking (e.g. the handler opens a dialog and you don't want a
646
+ spinner flash) and a `type="submit"` button's spin while its `BbForm` saves.
647
+ Only an explicit `loading` shows the spinner then. A click that awaits a
648
+ dialog (`await useBbDialogContext(id).show()`, `await confirm()`) spins
649
+ until the dialog settles, like any async click: that is where this prop
650
+ goes.
640
651
  - `interactive-while-loading` — keeps the button clickable while it shows the
641
652
  loading state, for controls that must stay interactive (this is how the
642
653
  `BbDropdownButton` caret stays usable while the primary action runs). The
@@ -930,7 +941,7 @@ utility wins. What works in every build:
930
941
  - `BbDropdownButton` — escalate to it when a primary action grows close
931
942
  alternates; it shares this component's `variant`/`size`/loading language.
932
943
  - `useConfirm` — gate every `destructive` button behind a confirm: mount the
933
- `<BbConfirm />` host once (app root), `await confirm(...)` in the handler and
944
+ `<BbHost />` once (app root), `await confirm(...)` in the handler and
934
945
  act only on a yes. The dialog's own buttons are `BbButton` configs (see the
935
946
  composable doc), so the confirm speaks the same `variant`/icon language:
936
947
 
@@ -972,15 +983,15 @@ utility wins. What works in every build:
972
983
 
973
984
  <!--
974
985
  Standalone example: it mounts its own host because it has no app root.
975
- A real app mounts exactly one <BbConfirm /> at the app root, and pages
986
+ A real app mounts exactly one <BbHost /> at the app root, and pages
976
987
  mount none. See ai/guides/agent-contract.md § Global Host Rule.
977
988
  -->
978
- <BbConfirm />
989
+ <BbHost />
979
990
  </div>
980
991
  </template>
981
992
  <script setup lang="ts">
982
993
  import { ref } from 'vue';
983
- import { BbButton, BbConfirm, useConfirm } from 'bitboss-ui';
994
+ import { BbButton, BbHost, useConfirm } from 'bitboss-ui';
984
995
 
985
996
  type ApiKey = { id: string; label: string; masked: string; created: string };
986
997
 
@@ -1122,7 +1133,7 @@ Anti-patterns:
1122
1133
  | `cacheTags` | `string \| string[] \| undefined` | | | Inertia: tags to file this visit's prefetch cache under, so a later request can invalidate the whole tagged group. |
1123
1134
  | `component` | `string \| undefined` | | | Inertia: the page component this visit resolves to. Rarely set by hand — the server normally decides it. |
1124
1135
  | `data` | `object \| undefined` | | | Request payload forwarded to Inertia when navigating via `href` in an Inertia-enabled app. Ignored when not using Inertia. |
1125
- | `disableAutoLoading` | `boolean \| undefined` | `false` | | Disables the automatic loading state that tracks async click handlers (enabled by default). |
1136
+ | `disableAutoLoading` | `boolean \| undefined` | `false` | | Disables every spinner the button starts on its own: the one that tracks an async click handler, and a `type="submit"` button's spin while its `BbForm` saves. Only an explicit `loading` shows the spinner then. |
1126
1137
  | `disabled` | `boolean \| undefined` | `false` | | Disables the component: native `disabled` (or `aria-disabled` on a link), muted paint. Beside `loading`, loading wins the look (spinner and variant colours) and this only adds the native blocking — redundant but harmless. |
1127
1138
  | `download` | `string \| boolean \| undefined` | | | Marks an `href` link as a download: renders a plain `<a download>` doing a native navigation (never an Inertia/router visit), so file downloads work. Pass a string for the suggested filename. A native-anchor signal alongside `target` and `external`. |
1128
1139
  | `exactActiveClass` | `string \| undefined` | | | Class to apply when the link is exact active. |
@@ -1283,4 +1294,4 @@ Set these on the element, or on a class you put on it, to retune this component
1283
1294
  - [BbBaseButton](./BbBaseButton.md) — Unstyled button/link primitive: element resolution (button/anchor/router link) and the full navigation engine, with no visual chrome. Use for any clickable or navigable surface that is not a variant-first BbButton — cards, list rows, custom links.
1284
1295
  - [BbDropdownButton](./BbDropdownButton.md) — A button with primary action and all other actions collected in a dropdown.
1285
1296
  - [BbDropdown](./BbDropdown.md) — Displays contextual action menus and menu content (includes the co-located BbDropdownGroup export, which is how a selectable group is bound).
1286
- - [BbConfirm](./BbConfirm.md) — Prompts users to confirm or cancel critical actions (includes co-located BbConfirmPortal export).
1297
+ - [useConfirm](./composables/useConfirm.md)